OpenASIP  2.0
Netlist.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2015 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file Netlist.cc
26  *
27  * Implementation of the Netlist class.
28  *
29  * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30  * @author Otto Esko 2010 (otto.esko-no.spam-tut.fi)
31  * @author Henry Linjamäki 2015 (henry.linjamaki-no.spam-tut.fi)
32  * @note rating: red
33  */
34 
35 #include <cstdlib>
36 #include <string>
37 #include <map>
38 #include <utility>
39 
40 #include "Netlist.hh"
41 #include "NetlistPort.hh"
42 #include "NetlistPortGroup.hh"
43 #include "NetlistBlock.hh"
44 #include "SignalTypes.hh"
45 
46 #include "MapTools.hh"
47 #include "Application.hh"
48 #include "Conversion.hh"
49 #include "AssocTools.hh"
50 
51 namespace ProGe {
52 
53 /**
54  * The constructor.
55  */
56 Netlist::Netlist() : coreEntityName_("") {
57 }
58 
59 
60 /**
61  * The destructor.
62  */
64 }
65 
66 /**
67  * Partially connects two netlist ports.
68  *
69  * Connects two given subsets of bits of two netlist ports. The bit subsets
70  * have equal cardinality and represent an ordered range of adjacent bits.
71  * The bits are connected in the same order (the first bit of the subset of
72  * the first port is connected to the first bit of the subset of the second
73  * port).
74  *
75  * @param port1 The first port to connect.
76  * @param port2 The second port to connect.
77  * @param port1FirstBit The first bit of the first port to connect.
78  * @param port2FirstBit The first bit of the second port to connect.
79  * @param width The width of the connection.
80  * @param Return true, if connection was successful.
81  */
82 bool
84  const NetlistPort& port1, const NetlistPort& port2, int port1FirstBit,
85  int port2FirstBit, int width) {
86  // PortConnectionProperty regards width 0 as fully connected
87  if (width == 0 && (port1.dataType() != port2.dataType())) {
88  // BIT to/from BIT_VECTOR connection needs partial connectivity
89  width = 1;
90  }
91 
92  size_t port1Descriptor = descriptor(port1);
93  size_t port2Descriptor = descriptor(port2);
94 
95  // create first edge
96  PortConnectionProperty property1(port1FirstBit, port2FirstBit, width);
97  boost::add_edge(port1Descriptor, port2Descriptor, property1, *this);
98 
99  // create the opposite edge
100  PortConnectionProperty property2(port2FirstBit, port1FirstBit, width);
101  boost::add_edge(port2Descriptor, port1Descriptor, property2, *this);
102  return true;
103 }
104 
105 /**
106  * Connects two netlist ports completely.
107  *
108  * Each bit of the first port is connected to a bit of the second port. The
109  * bits are connected in the same order (the first bit of the first port is
110  * connected to the first bit of the second port).
111  *
112  * @param port1 The first port to connect.
113  * @param port2 The second port to connect.
114  * @param Return true, if connection was successful.
115  */
116 bool
117 Netlist::connect(const NetlistPort& port1, const NetlistPort& port2) {
118  size_t port1Descriptor = descriptor(port1);
119  size_t port2Descriptor = descriptor(port2);
120  bool needsInversion = port1.assignedSignal().activeState() !=
121  port2.assignedSignal().activeState();
122  PortConnectionProperty property(needsInversion);
123 
124  // create first edge
125  boost::add_edge(port1Descriptor, port2Descriptor, property, *this);
126  // create the opposite edge
127  boost::add_edge(port2Descriptor, port1Descriptor, property, *this);
128  return true;
129 }
130 
131 /**
132  * Removes connection between two ports.
133  */
134 void
135 Netlist::disconnectPorts(const NetlistPort& port1, const NetlistPort& port2) {
136  size_t port1Descriptor = descriptor(port1);
137  size_t port2Descriptor = descriptor(port2);
138 
139  boost::remove_edge(port1Descriptor, port2Descriptor, *this);
140  boost::remove_edge(port2Descriptor, port1Descriptor, *this);
141 }
142 
143 /**
144  * Trivially connect ports of the groups together by their signal types.
145  *
146  * @param Return true, if connection was successful.
147  */
148 bool
150  const NetlistPortGroup& group1, const NetlistPortGroup& group2) {
151  if (group1.portCount() != group2.portCount()) {
152  return false;
153  }
154 
155  std::map<SignalType, const NetlistPort*> portsOfGroup2;
156  for (const NetlistPort* port : group2) {
157  assert(
159  portsOfGroup2, port->assignedSignal().type()) &&
160  "Netlist::Connect(): Currently cannot handle groups with "
161  "multiply of same signal type");
162  portsOfGroup2.insert(
163  std::make_pair(port->assignedSignal().type(), port));
164  }
165 
166  for (const NetlistPort* from : group1) {
167  SignalType matchingType = from->assignedSignal().type();
168  assert(AssocTools::containsKey(portsOfGroup2, matchingType) && "");
169  const NetlistPort* to = portsOfGroup2.at(matchingType);
170  connect(*from, *to);
171  }
172 
173  return true;
174 }
175 
176 /**
177  * Make single port connection by given signal type.
178  *
179  * Signal type is assumed to be unique within the both port groups.
180  */
181 bool
183  SignalType byType, const NetlistPortGroup& group1,
184  const NetlistPortGroup& group2) {
185  assert(group1.hasPortBySignal(byType));
186  assert(group2.hasPortBySignal(byType));
187 
188  const NetlistPort& port1 = group1.portBySignal(byType);
189  const NetlistPort& port2 = group2.portBySignal(byType);
190 
191  connect(port1, port2);
192 
193  return true;
194 }
195 
196 /**
197  * Makes connection between two different netlist port group by connection map
198  * using their SignalTypes.
199  *
200  * The connections are made from the first group to the second group by using
201  * the connection map. todo...
202  *
203  * @param group1 The first port group.
204  * @param group2 The second port group.
205  * @param connectionMap The connection rules.
206  *
207  */
208 bool
210  const NetlistPortGroup& group1, const NetlistPortGroup& group2,
211  std::map<SignalType, SignalType> connectionMap) {
212  for (const NetlistPort* port1 : group1) {
213  SignalType type1 = port1->assignedSignal().type();
215  if (connectionMap.count(type1)) {
216  type2 = connectionMap.at(type1);
217  } else {
218  continue;
219  }
220  if (type2 == SignalType::OPEN) {
221  continue;
222  }
223  const NetlistPort& port2 = group2.portBySignal(type2);
224 
225  connect(*port1, port2);
226  }
227 
228  return true;
229 }
230 
231 /**
232  * Trivially connect ports of the groups together by their port names.
233  * Useful for exporting e.g. bus connections to higher-level netlist block
234  *
235  * @param Return true, if connection was successful.
236  */
237 bool
239  const NetlistPortGroup& group1, const NetlistPortGroup& group2) {
240  if (group1.portCount() != group2.portCount()) {
241  return false;
242  }
243 
244  std::map<std::string, const NetlistPort*> portsOfGroup2;
245  for (const NetlistPort* port : group2) {
246  assert(
247  !AssocTools::containsKey(portsOfGroup2, port->name()) &&
248  "Netlist::Connect(): group2 has multiple ports "
249  "with the same name");
250  portsOfGroup2.insert(std::make_pair(port->name(), port));
251  }
252 
253  for (const NetlistPort* from : group1) {
254  std::string matchingName = from->name();
255  assert(
256  AssocTools::containsKey(portsOfGroup2, matchingName) &&
257  "Netlist::connectByName: The two port groups' names "
258  "do not match");
259  const NetlistPort* to = portsOfGroup2.at(matchingName);
260  connect(*from, *to);
261  }
262 
263  return true;
264 }
265 
266 /**
267  * Tells whether the netlist port is connected in this netlist instance
268  *
269  * @param port The netlist port
270  * @return True if port is connected
271  */
272 bool
274 
275  size_t vertDesc = descriptor(port);
276  boost::graph_traits<Netlist>::degree_size_type edges =
277  boost::out_degree(vertDesc, *this);
278  return edges != 0;
279 }
280 
281 
282 /**
283  * Tells whether the netlist is empty.
284  *
285  * @return True if the netlist is empty, otherwise false.
286  */
287 bool
289  return boost::num_vertices(*this) == 0;
290 }
291 
292 /**
293  * Returns true if there are some connections between ports.
294  */
295 bool
297  return boost::num_edges(*this) != 0;
298 }
299 
300 /**
301  * Registers given port to the netlist to make connection possible.
302  *
303  * This method does not need to be called by clients.
304  *
305  * @param port The port.
306  * @return Descriptor to the port.
307  */
308 size_t
310  assert(
312  "The port is already registered");
313  size_t descriptor = boost::add_vertex(&port, *this);
314  vertexDescriptorMap_.insert(
315  std::pair<const NetlistPort*, size_t>(&port, descriptor));
316  return descriptor;
317 }
318 
319 /**
320  * Returns descriptor for the given port.
321  *
322  * @return Descriptor for the given port.
323  */
324 size_t
325 Netlist::descriptor(const NetlistPort& port) const {
327  return MapTools::valueForKey<size_t>(vertexDescriptorMap_, &port);
328 }
329 
330 /**
331  * Returns true if the netlist has the given port.
332  */
333 bool
334 Netlist::isRegistered(const NetlistPort& port) const {
336 }
337 
338 /**
339  * Removes port from the netlist and all connections related to it.
340  */
341 void
344  boost::clear_vertex(this->descriptor(port), *this);
345  boost::remove_vertex(this->descriptor(port), *this);
346  vertexDescriptorMap_.erase(&port);
347  }
348 }
349 
350 /**
351  * [DEPRECATED]
352  * Adds a parameter for the netlist.
353  *
354  * If the netlist already has a parameter with the given name, it is replaced
355  * by the new parameter.
356  *
357  * @param name Name of the parameter.
358  * @param type Type of the parameter.
359  * @param value Value of the parameter.
360  */
361 void
363  const std::string& name,
364  const std::string& type,
365  const std::string& value) {
366 
367  if (hasParameter(name)) {
368  removeParameter(name);
369  }
370 
371  Parameter param = {name, type, value};
372  parameters_.push_back(param);
373 }
374 
375 void
377  setParameter(param.name(), param.type(), param.value());
378 }
379 
380 /**
381  * Removes the given parameter from the netlist.
382  *
383  * @param name Name of the parameter.
384  */
385 void
386 Netlist::removeParameter(const std::string& name) {
387  for (ParameterTable::iterator iter = parameters_.begin();
388  iter != parameters_.end(); iter++) {
389  if (iter->name() == name) {
390  parameters_.erase(iter);
391  break;
392  }
393  }
394 }
395 
396 
397 /**
398  * Tells whether the netlist has the given parameter.
399  *
400  * @param name Name of the parameter.
401  */
402 bool
403 Netlist::hasParameter(const std::string& name) const {
404 
405  for (ParameterTable::const_iterator iter = parameters_.begin();
406  iter != parameters_.end(); iter++) {
407  if (iter->name() == name) {
408  return true;
409  }
410  }
411 
412  return false;
413 }
414 
415 
416 /**
417  * Returns the number of parameters in the netlist.
418  *
419  * @return The number of parameters.
420  */
421 size_t
423  return parameters_.size();
424 }
425 
426 /**
427  * Returns the parameter at the given position.
428  *
429  * @param index The position.
430  * @exception OutOfRange If the given index is negative or not smaller than
431  * the number of parameters.
432  */
433 Parameter
434 Netlist::parameter(size_t index) const {
435  if (index >= parameterCount()) {
436  throw OutOfRange(__FILE__, __LINE__, __func__);
437  }
438 
439  return parameters_[index];
440 }
441 
444  return boost::edges(*this).first;
445 }
446 
449  return boost::edges(*this).second;
450 }
451 
453 Netlist::begin() const {
454  return boost::edges(*this).first;
455 }
456 
458 Netlist::end() const {
459  return boost::edges(*this).second;
460 }
461 
464  return vertexDescriptorMap_.begin();
465 }
466 
469  return vertexDescriptorMap_.end();
470 }
471 
473 Netlist::descriptorBegin() const {
474  return vertexDescriptorMap_.begin();
475 }
476 
478 Netlist::descriptorEnd() const {
479  return vertexDescriptorMap_.end();
480 }
481 
482 void
484  const NetlistPort* topClock = nullptr;
485  {
486  std::vector<const NetlistPort*> clockOfBlock;
487  clockOfBlock = block.portsBy(SignalType::CLOCK);
488  assert(clockOfBlock.size() < 2);
489  if (clockOfBlock.empty()) {
490  return;
491  } else {
492  topClock = clockOfBlock.at(0);
493  }
494  }
495 
496  for (size_t i = 0; i < block.subBlockCount(); i++) {
497  std::vector<const NetlistPort*> clockOfSubBlock;
498  const BaseNetlistBlock& cblock = block;
499  clockOfSubBlock = cblock.subBlock(i).portsBy(SignalType::CLOCK);
500  assert(clockOfSubBlock.size() < 2);
501  if (clockOfSubBlock.empty() ||
502  block.netlist().isPortConnected(*clockOfSubBlock.at(0))) {
503  continue;
504  } else {
505  block.netlist().connect(*topClock, *clockOfSubBlock.at(0));
506  }
507  }
508 }
509 
510 void
512  const NetlistPort* topClock = nullptr;
513  {
514  std::vector<const NetlistPort*> clockOfBlock;
515  clockOfBlock = block.portsBy(SignalType::RESET);
516  assert(clockOfBlock.size() < 2);
517  if (clockOfBlock.empty()) {
518  return;
519  } else {
520  topClock = clockOfBlock.at(0);
521  }
522  }
523 
524  for (size_t i = 0; i < block.subBlockCount(); i++) {
525  std::vector<const NetlistPort*> clockOfSubBlock;
526  const BaseNetlistBlock& cblock = block;
527  clockOfSubBlock = cblock.subBlock(i).portsBy(SignalType::RESET);
528  assert(clockOfSubBlock.size() < 2);
529  if (clockOfSubBlock.empty() ||
530  block.netlist().isPortConnected(*clockOfSubBlock.at(0))) {
531  continue;
532  } else {
533  block.netlist().connect(*topClock, *clockOfSubBlock.at(0));
534  }
535  }
536 }
537 
538 } /* namespace ProGe */
ProGe::BaseNetlistBlock
Definition: BaseNetlistBlock.hh:59
Netlist.hh
ProGe::NetlistBlock::netlist
virtual const Netlist & netlist() const
Definition: BaseNetlistBlock.cc:348
ProGe::Signal::activeState
ActiveState activeState() const
Definition: Signal.cc:63
ProGe::Netlist::removeParameter
void removeParameter(const std::string &name)
Definition: Netlist.cc:386
ProGe::Netlist::unregisterPort
void unregisterPort(NetlistPort &port)
Definition: Netlist.cc:342
ProGe::NetlistBlock
Definition: NetlistBlock.hh:61
ProGe::Netlist::parameters_
ParameterTable parameters_
Parameters of the netlist.
Definition: Netlist.hh:148
ProGe::Netlist::isPortConnected
bool isPortConnected(const NetlistPort &port) const
Definition: Netlist.cc:273
ProGe::Parameter::type
const TCEString & type() const
Definition: Parameter.cc:138
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
OutOfRange
Definition: Exception.hh:320
MapTools.hh
ProGe::SignalType::RESET
@ RESET
Reset signal.
ProGe::Netlist::disconnectPorts
void disconnectPorts(const NetlistPort &port1, const NetlistPort &port2)
Definition: Netlist.cc:135
ProGe::SignalType::UNDEFINED
@ UNDEFINED
Signal does not have specified usage.
ProGe::BaseNetlistBlock::portsBy
virtual std::vector< const NetlistPort * > portsBy(SignalType type) const
Definition: BaseNetlistBlock.cc:264
ProGe::Netlist::end
iterator end()
Definition: Netlist.cc:448
ProGe::Netlist::descriptorEnd
descriptor_iterator descriptorEnd()
Definition: Netlist.cc:468
ProGe::Netlist::~Netlist
virtual ~Netlist()
Definition: Netlist.cc:63
ProGe::Netlist::connect
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition: Netlist.cc:83
ProGe::Netlist::connectGroupByName
bool connectGroupByName(const NetlistPortGroup &group1, const NetlistPortGroup &group2)
Definition: Netlist.cc:238
NetlistPortGroup.hh
assert
#define assert(condition)
Definition: Application.hh:86
ProGe::NetlistPortGroup
Definition: NetlistPortGroup.hh:53
ProGe::Netlist::parameterCount
size_t parameterCount() const
Definition: Netlist.cc:422
ProGe::Netlist::hasParameter
bool hasParameter(const std::string &name) const
Definition: Netlist.cc:403
ProGe::Netlist::descriptor_iterator
DescriptorMap::iterator descriptor_iterator
Definition: Netlist.hh:132
ProGe::Netlist::descriptorBegin
descriptor_iterator descriptorBegin()
Definition: Netlist.cc:463
ProGe::Netlist::const_descriptor_iterator
DescriptorMap::const_iterator const_descriptor_iterator
Definition: Netlist.hh:133
Conversion.hh
SignalTypes.hh
ProGe::Parameter
Definition: Parameter.hh:62
NetlistPort.hh
Application.hh
ProGe::Parameter::name
const TCEString & name() const
Definition: Parameter.cc:133
ProGe::Netlist::iterator
boost::graph_traits< Netlist >::edge_iterator iterator
Definition: Netlist.hh:125
__func__
#define __func__
Definition: Application.hh:67
NetlistBlock.hh
ProGe::Netlist::connectClocks
static void connectClocks(NetlistBlock &block)
Definition: Netlist.cc:483
ProGe::Netlist::descriptor
size_t descriptor(const NetlistPort &port) const
Definition: Netlist.cc:325
ProGe::Parameter::value
const TCEString & value() const
Definition: Parameter.cc:143
ProGe::Netlist::connectResets
static void connectResets(NetlistBlock &block)
Definition: Netlist.cc:511
ProGe::SignalType::OPEN
@ OPEN
Signal is left to unconnected.
ProGe::SignalType::CLOCK
@ CLOCK
Clock signal.
ProGe::PortConnectionProperty
Definition: PortConnectionProperty.hh:51
ProGe::NetlistPort::dataType
DataType dataType() const
Definition: NetlistPort.cc:362
ProGe::SignalType
SignalType
Definition: SignalTypes.hh:42
ProGe::Netlist::isRegistered
bool isRegistered(const NetlistPort &port) const
Definition: Netlist.cc:334
ProGe::Netlist::Netlist
Netlist()
Definition: Netlist.cc:56
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
ProGe::Netlist::registerPort
size_t registerPort(NetlistPort &port)
Definition: Netlist.cc:309
ProGe::Netlist::isEmpty
bool isEmpty() const
Definition: Netlist.cc:288
ProGe
Definition: FUGen.hh:54
AssocTools.hh
ProGe::Netlist::hasConnections
bool hasConnections() const
Definition: Netlist.cc:296
ProGe::Netlist::parameter
Parameter parameter(size_t index) const
Definition: Netlist.cc:434
ProGe::NetlistPortGroup::portBySignal
const NetlistPort & portBySignal(SignalType type) const
Definition: NetlistPortGroup.cc:111
ProGe::Netlist::const_iterator
boost::graph_traits< const Netlist >::edge_iterator const_iterator
Definition: Netlist.hh:126
ProGe::NetlistPort
Definition: NetlistPort.hh:70
ProGe::NetlistPortGroup::portCount
size_t portCount() const
Definition: NetlistPortGroup.cc:78
ProGe::BaseNetlistBlock::subBlock
virtual const BaseNetlistBlock & subBlock(size_t index) const
Definition: BaseNetlistBlock.cc:155
ProGe::NetlistPort::assignedSignal
Signal assignedSignal() const
Definition: NetlistPort.cc:455
ProGe::Netlist::setParameter
void setParameter(const std::string &name, const std::string &type, const std::string &value)
Definition: Netlist.cc:362
ProGe::NetlistBlock::subBlockCount
virtual size_t subBlockCount() const
Definition: BaseNetlistBlock.cc:150
ProGe::Netlist::vertexDescriptorMap_
DescriptorMap vertexDescriptorMap_
Vertex descriptor map.
Definition: Netlist.hh:146
ProGe::NetlistPortGroup::hasPortBySignal
bool hasPortBySignal(SignalType type) const
Definition: NetlistPortGroup.cc:98
ProGe::Netlist::begin
iterator begin()
Definition: Netlist.cc:443
ProGe::Netlist::connectBy
bool connectBy(SignalType byType, const NetlistPortGroup &group1, const NetlistPortGroup &group2)
Definition: Netlist.cc:182