OpenASIP 2.2
Loading...
Searching...
No Matches
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
51namespace ProGe {
52
53/**
54 * The constructor.
55 */
56Netlist::Netlist() : coreEntityName_("") {
57}
58
59
60/**
61 * The destructor.
62 */
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 */
82bool
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 */
116bool
117Netlist::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 */
134void
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 */
148bool
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 */
181bool
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 */
208bool
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 */
237bool
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 */
272bool
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 */
287bool
289 return boost::num_vertices(*this) == 0;
290}
291
292/**
293 * Returns true if there are some connections between ports.
294 */
295bool
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 */
308size_t
310 assert(
312 "The port is already registered");
313 size_t descriptor = boost::add_vertex(&port, *this);
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 */
324size_t
329
330/**
331 * Returns true if the netlist has the given port.
332 */
333bool
337
338/**
339 * Removes port from the netlist and all connections related to it.
340 */
341void
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 */
361void
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
375void
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 */
385void
386Netlist::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 */
402bool
403Netlist::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 */
421size_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 */
434Netlist::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
454 return boost::edges(*this).first;
455}
456
459 return boost::edges(*this).second;
460}
461
466
471
474 return vertexDescriptorMap_.begin();
475}
476
479 return vertexDescriptorMap_.end();
480}
481
482void
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
510void
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 */
#define __func__
#define assert(condition)
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
virtual const BaseNetlistBlock & subBlock(size_t index) const
virtual std::vector< const NetlistPort * > portsBy(SignalType type) const
virtual size_t subBlockCount() const
virtual const Netlist & netlist() const
bool hasPortBySignal(SignalType type) const
const NetlistPort & portBySignal(SignalType type) const
Signal assignedSignal() const
DataType dataType() const
static void connectResets(NetlistBlock &block)
Definition Netlist.cc:511
bool isEmpty() const
Definition Netlist.cc:288
virtual ~Netlist()
Definition Netlist.cc:63
descriptor_iterator descriptorBegin()
Definition Netlist.cc:463
iterator end()
Definition Netlist.cc:448
boost::graph_traits< constNetlist >::edge_iterator const_iterator
Definition Netlist.hh:126
ParameterTable parameters_
Parameters of the netlist.
Definition Netlist.hh:148
size_t parameterCount() const
Definition Netlist.cc:422
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition Netlist.cc:83
size_t descriptor(const NetlistPort &port) const
Definition Netlist.cc:325
void setParameter(const std::string &name, const std::string &type, const std::string &value)
Definition Netlist.cc:362
void removeParameter(const std::string &name)
Definition Netlist.cc:386
Parameter parameter(size_t index) const
Definition Netlist.cc:434
bool connectBy(SignalType byType, const NetlistPortGroup &group1, const NetlistPortGroup &group2)
Definition Netlist.cc:182
boost::graph_traits< Netlist >::edge_iterator iterator
Definition Netlist.hh:125
size_t registerPort(NetlistPort &port)
Definition Netlist.cc:309
bool isRegistered(const NetlistPort &port) const
Definition Netlist.cc:334
bool hasConnections() const
Definition Netlist.cc:296
bool isPortConnected(const NetlistPort &port) const
Definition Netlist.cc:273
static void connectClocks(NetlistBlock &block)
Definition Netlist.cc:483
void disconnectPorts(const NetlistPort &port1, const NetlistPort &port2)
Definition Netlist.cc:135
DescriptorMap::const_iterator const_descriptor_iterator
Definition Netlist.hh:133
bool connectGroupByName(const NetlistPortGroup &group1, const NetlistPortGroup &group2)
Definition Netlist.cc:238
void unregisterPort(NetlistPort &port)
Definition Netlist.cc:342
iterator begin()
Definition Netlist.cc:443
bool hasParameter(const std::string &name) const
Definition Netlist.cc:403
DescriptorMap::iterator descriptor_iterator
Definition Netlist.hh:132
DescriptorMap vertexDescriptorMap_
Vertex descriptor map.
Definition Netlist.hh:146
descriptor_iterator descriptorEnd()
Definition Netlist.cc:468
const TCEString & value() const
Definition Parameter.cc:143
const TCEString & type() const
Definition Parameter.cc:138
const TCEString & name() const
Definition Parameter.cc:133
ActiveState activeState() const
Definition Signal.cc:63
Definition FUGen.hh:54
@ UNDEFINED
Signal does not have specified usage.
@ OPEN
Signal is left to unconnected.
@ RESET
Reset signal.
@ CLOCK
Clock signal.