torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PrimitiveStructure.cpp
Go to the documentation of this file.
1 // Torc - Copyright 2011-2013 University of Southern California. All Rights Reserved.
2 // $HeadURL$
3 // $Id$
4 
5 // This program is free software: you can redistribute it and/or modify it under the terms of the
6 // GNU General Public License as published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 // the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program. If
14 // not, see <http://www.gnu.org/licenses/>.
15 
16 /// \file
17 /// \brief Source for the PrimitiveStructure class.
18 
20 #include <iostream>
21 
22 namespace torc {
23 namespace packer {
24 
25  using namespace torc::architecture;
26 
27  boost::regex PrimitiveStructure::sRoutethroughRegEx("^_ROUTETHROUGH.*");
28  boost::regex PrimitiveStructure::sPrincipalRegEx("^(PAD)$");
29  boost::regex PrimitiveStructure::sLUTRegEx("^(#LUT:|#RAM:|#ROM:)?<eqn>$");
30  boost::regex PrimitiveStructure::sFlopRegEx("^(#FF|#LATCH)$");
31  boost::regex PrimitiveStructure::sPowerRegEx("^.*(VCC|VDD|POWER).*$");
32  boost::regex PrimitiveStructure::sGroundRegEx("^.*(GND|GROUND).*$");
33  boost::regex PrimitiveStructure::sInvertingInputRegEx("^.*_B$");
34 
35 
37  return mPreclassified.find(inElement.getName()) != mPreclassified.end();
38  }
39 
41  return inElement.getName() == mPrimitiveDefPtr->getName()
42  || regex_match(inElement.getName(), sPrincipalRegEx);
43  }
44 
46  if(inElement.getPins().getSize() != 1) return false;
47  return !mPrimitiveDefPtr->findPinIndexByName(inElement.getName()).isUndefined();
48  }
49 
51  return inElement.getPins().getSize() == 0;
52  }
53 
54  bool PrimitiveStructure::isMux(const PrimitiveElement& inElement, bool& outIsSwitch) {
55  outIsSwitch = false;
56  // look up information about the primitive
57  const PrimitiveElement::StringSet& cfgs = inElement.getCfgs();
58  PrimitiveElement::StringSet::size_type cfgsCount = cfgs.size();
59  const PrimitiveElementPinArray& elementPins = inElement.getPins();
60  boost::uint32_t elementPinsCount = elementPins.getSize();
61 
62  // if the configuration set is empty, this cannot be a mux
63  if(cfgsCount == 0) return false;
64 
65  // configurable muxes will have cfgsCount input pins plus one output pin
66  if(elementPinsCount != cfgsCount + 1) return false;
67  // copy the input pins into a set
71  while(pp < pe) { if(pp->isInput()) inputs.insert(pp->getName()); pp++; }
72  PrimitiveElement::StringSet::size_type inputCount = inputs.size();
73 
74  // compare the implicitly sorted cfgs and input pins sets for equality
75  PrimitiveElement::StringSet::const_iterator ip = inputs.begin();
76  PrimitiveElement::StringSet::const_iterator ie = inputs.end();
77  PrimitiveElement::StringSet::const_iterator cp = cfgs.begin();
78  while(ip != ie) if(*ip++ != *cp++) return false;
79 
80  // now that we know this is a mux, make note of all the inverting inputs
81  ip = inputs.begin();
82  while(ip != ie) {
83  const std::string& input = *ip++;
84  if(regex_match(input, sInvertingInputRegEx)) {
85  torc::architecture::xilinx::PinIndex pinIndex = inElement.findPinIndexByName(input);
86  mInvertedInputs.insert(&elementPins[pinIndex]);
87  }
88  }
89 
90  // if we got this far, the element is a mux (and it may also be a switch)
91  if(inputCount == 1) outIsSwitch = true;
92  return true;
93  }
94 
96  const PrimitiveElementPinArray& elementPins = inElement.getPins();
97  return elementPins.getSize() == 1 && elementPins[0].getName() == "1"
98  && regex_match(inElement.getName(), sPowerRegEx);
99  }
100 
102  const PrimitiveElementPinArray& elementPins = inElement.getPins();
103  return elementPins.getSize() == 1 && elementPins[0].getName() == "0"
104  && regex_match(inElement.getName(), sGroundRegEx);
105  }
106 
107  bool PrimitiveStructure::isLUT(const PrimitiveElement& inElement, const string& inConfig) {
108  return regex_match(inConfig, sLUTRegEx);
109  }
110 
111  bool PrimitiveStructure::isFlop(const PrimitiveElement& inElement, const string& inConfig) {
112  return regex_match(inConfig, sFlopRegEx);
113  }
114 
116  return regex_match(inElement.getName(), sRoutethroughRegEx);
117  }
118 
120  // look up the primitive's pins
121  const PrimitivePinArray& primitivePins = mPrimitiveDefPtr->getPins();
122  const std::string& primitiveDefName = mPrimitiveDefPtr->getName();
123  (void) primitivePins;
124  (void) primitiveDefName;
125 //std::cout << primitiveDefName << ": " << primitivePins.getSize() << " pins" << std::endl;
126 
127  // iterate over the elements
128  const PrimitiveElementArray& elements = mPrimitiveDefPtr->getElements();
131  while(ep < ee) {
132 
133  // look up the current element
134  const PrimitiveElement& primitiveElement = *ep++;
135  const std::string& elementName = primitiveElement.getName();
136 
137  // add the element to the comprehensive list
138  mElements[elementName] = &primitiveElement;
139 
140  // skip elements that have been preclassified
141  if(isPreclassified(primitiveElement)) {
142  continue;
143  }
144 
145  // identify principals
146  if(isPrincipal(primitiveElement)) {
147  mPrincipals[elementName] = &primitiveElement;
148  continue;
149  }
150 
151  // identify terminals
152  if(isTerminal(primitiveElement)) {
153  mTerminals[elementName] = &primitiveElement;
154  continue;
155  }
156 
157  // identify orphans
158  if(isOrphan(primitiveElement)) {
159  mOrphans[elementName] = &primitiveElement;
160  continue;
161  }
162 
163  // for all remaining elements, it's easier to track status with a flag
164  bool processed = false;
165 
166  // identify muxes
167  bool isSwitch = false;
168  if(isMux(primitiveElement, isSwitch)) {
169  // mark this element as a mux (and also as a switch if it has a single input)
170  mMuxes[elementName] = &primitiveElement;
171  if(isSwitch) mSwitches[elementName] = &primitiveElement;
172  processed = true;
173  continue;
174  }
175 
176  // identify power sources
177  if(isPower(primitiveElement)) {
178  mPower[elementName] = &primitiveElement;
179  processed = true;
180  continue;
181  }
182  // identify ground sources
183  if(isGround(primitiveElement)) {
184  mGround[elementName] = &primitiveElement;
185  processed = true;
186  continue;
187  }
188 
189  // identify LUTs and flops
190  const PrimitiveElement::StringSet& cfgs = primitiveElement.getCfgs();
191  PrimitiveElement::StringSet::const_iterator cp = cfgs.begin();
192  PrimitiveElement::StringSet::const_iterator ce = cfgs.end();
193  while(cp != ce) {
194  const std::string& config = *cp++;
195  // identify LUTs
196  if(regex_match(config, sLUTRegEx)) {
197  mLUTs[elementName] = &primitiveElement;
198  processed = true;
199  break;
200  }
201  // identify flops
202  if(isFlop(primitiveElement, config)) {
203  mFlops[elementName] = &primitiveElement;
204  processed = true;
205  break;
206  }
207  }
208  if(processed) continue;
209 
210  // ignore routethroughs
211  if(isRoutethrough(primitiveElement)) {
212  mRoutethroughs[elementName] = &primitiveElement;
213  processed = true;
214  continue;
215  }
216 
217  // note all unprocessed elements
218  mUnprocessed[elementName] = &primitiveElement;
219 //std::cout << " Unprocessed element " << elementName << std::endl;
220 debug(primitiveElement);
221  }
222  }
223 
224  void PrimitiveStructure::debug(const PrimitiveElement& inPrimitiveElement) {
225  const PrimitiveElementPinArray& elementPins = inPrimitiveElement.getPins();
228  //std::cout << " pins: ";
229  while(pp < pe) {
230  break;//std::cout << (*pp++).getName() << " ";
231  }
232  //std::cout << std::endl;
233 
234  const PrimitiveElement::StringSet& cfgs = inPrimitiveElement.getCfgs();
235  PrimitiveElement::StringSet::const_iterator cp = cfgs.begin();
236  PrimitiveElement::StringSet::const_iterator ce = cfgs.end();
237  //std::cout << " configs: ";
238  while(cp != ce) {
239  break;//std::cout << *cp++ << " ";
240  }
241  //std::cout << std::endl;
242  }
243 
244 } // namespace architecture
245 } // namespace torc
static boost::regex sInvertingInputRegEx
Regular expression for inverting input pins.
const const PrimitiveElementPin * const_iterator
Constant T iterator type.
Definition: Array.hpp:83
static boost::regex sLUTRegEx
Regular expression for LUTs.
static boost::regex sPowerRegEx
Regular expression for power sources.
static boost::regex sGroundRegEx
Regular expression for ground sources.
PinIndex findPinIndexByName(const string &inName) const
Returns the pin index corresponding to the given pin name, or PinIndex::undefined() if the pin name d...
virtual bool isOrphan(const PrimitiveElement &inElement)
Return true if the element is an orphan.
virtual bool isPreclassified(const PrimitiveElement &inElement)
Return true if the element has been preclassified (typically by a subclass).
T * end(void)
Returns the non-constant end iterator.
Definition: Array.hpp:97
virtual bool isRoutethrough(const PrimitiveElement &inElementPtr)
Return true if the element is a routethrough.
Header for the PrimitiveStructure class.
static boost::regex sRoutethroughRegEx
Regular expression for routethroughs.
Encapsulation of a pin index in an unsigned 32-bit integer.
virtual bool isGround(const PrimitiveElement &inElement)
Return true if the element is a ground source.
std::string string
const string & getName(void) const
Returns the name of the element.
void debug(const PrimitiveElement &inPrimitiveElement)
Prints out debugging information for the specified element.
PrimitiveElementPinArray & getPins(void)
Returns a non-constant array of element pins. This function should only be used by the Sites class d...
virtual bool isTerminal(const PrimitiveElement &inElement)
Return true if the element is a terminal.
virtual void initialize(void)
Initialize this object based on the PrimitiveDef information.
virtual bool isPower(const PrimitiveElement &inElement)
Return true if the element is a power source.
static boost::regex sPrincipalRegEx
Regular expression for additional principal elements.
static boost::regex sFlopRegEx
Regular expression for flops.
Encapsulation of a primitive site element. Primitive elements are subcomponents of logic primitive s...
virtual bool isFlop(const PrimitiveElement &inElement, const string &inConfig)
Return true if the element is a flop.
T * begin(void)
Returns the non-constant begin iterator.
Definition: Array.hpp:95
std::set< std::string > StringSet
A set of configuration values.
virtual bool isPrincipal(const PrimitiveElement &inElement)
Return true if the element is the principal element (a parent to the orphans).
const StringSet & getCfgs(void) const
Returns the set of allowable configuration values.
virtual bool isMux(const PrimitiveElement &inElement, bool &outIsSwitch)
Return true if the element is a configurable mux.
virtual bool isLUT(const PrimitiveElement &inElement, const string &inConfig)
Return true if the element is a LUT.
uint32_t getSize(void) const
Returns the array size.
Definition: Array.hpp:104