OpenASIP  2.0
DefaultICGenerator.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2011 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 DefaultICGenerator.cc
26  *
27  * Implementation of DefaultICGenerator class.
28  *
29  * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30  * @author Otto Esko 2008 (otto.esko-no.spam-tut.fi)
31  * @author Pekka Jääskeläinen 2011
32  * @author Vinogradov Viacheslav(added Verilog generating) 2012
33  * @author Henry Linjamäki 2014-2017 (henry.linjamaki-no.spam-tut.fi)
34  * @note rating: red
35  */
36 
37 #include <string>
38 #include <fstream>
39 #include <iostream>
40 #include <boost/format.hpp>
41 
42 #include "DefaultICGenerator.hh"
43 #include "HDBTypes.hh"
44 
45 #include "NetlistBlock.hh"
46 #include "Netlist.hh"
47 #include "NetlistPort.hh"
48 #include "NetlistGenerator.hh"
49 #include "VHDLNetlistWriter.hh"
50 #include "VerilogNetlistWriter.hh"
51 
52 #include "Machine.hh"
53 #include "Socket.hh"
54 #include "Segment.hh"
55 #include "ControlUnit.hh"
56 #include "SpecialRegisterPort.hh"
57 
58 #include "Conversion.hh"
59 #include "FileSystem.hh"
60 #include "MathTools.hh"
61 #include "MapTools.hh"
62 #include "AssocTools.hh"
63 
64 using namespace ProGe;
65 using namespace TTAMachine;
66 using std::string;
67 using std::endl;
68 
69 const string INPUT_SOCKET_DATAW_GENERIC = "DATAW";
70 const string INPUT_SOCKET_DATA_PORT = "data";
71 const string SOCKET_BUS_CONTROL_PORT = "databus_cntrl";
72 const string SOCKET_DATA_CONTROL_PORT = "data_cntrl";
73 
74 /**
75  * The constructor.
76  *
77  * Generates the inteconnection network of the given machine.
78  *
79  * @param machine The machine.
80  */
82  : machine_(machine),
83  icBlock_(NULL),
84  generateBusTrace_(false),
85  exportBustrace_(false),
86  busTraceStartingCycle_(0) {}
87 
88 /**
89  * The destructor.
90  */
92  for (BusAltSignalMap::iterator iter = altSignalMap_.begin();
93  iter != altSignalMap_.end(); iter++) {
94  delete (*iter).second;
95  }
96 }
97 
98 /**
99  * Set HDL
100  * @param language
101  */
102 void
104  language_= language;
105 }
106 /**
107  * Adds the interconnection network block under the given netlist block
108  * representing the TTA core and connects it to the FUs, RFs and IUs.
109  *
110  * @param generator The netlist generator which generated the netlist block.
111  * @param coreBlock The netlist block.
112  */
113 void
115  const ProGe::NetlistGenerator& generator,
116  ProGe::NetlistBlock& coreBlock) {
117  entityNameStr_ = coreBlock.moduleName();
118  NetlistBlock* icBlock =
119  new NetlistBlock(entityNameStr_ + "_" + "interconn", "ic");
120  icBlock_ = icBlock;
121  coreBlock.addSubBlock(icBlock);
123 
124  // Add clock, reset port and glock port
125  NetlistPort* tlClkPort =
126  coreBlock.port(NetlistGenerator::DECODER_CLOCK_PORT);
127  NetlistPort* icClkPort = new NetlistPort(
128  NetlistGenerator::DECODER_CLOCK_PORT, "1", BIT, ProGe::IN, *icBlock);
129  coreBlock.netlist().connect(*icClkPort, *tlClkPort);
130 
131  NetlistPort* tlResetPort =
132  coreBlock.port(NetlistGenerator::DECODER_RESET_PORT);
133  NetlistPort* icResetPort = new NetlistPort(
134  NetlistGenerator::DECODER_RESET_PORT, "1", BIT, ProGe::IN, *icBlock);
135  coreBlock.netlist().connect(*icResetPort, *tlResetPort);
136 
137  NetlistPort* icGlockPort =
138  new NetlistPort("glock", "1", BIT, ProGe::IN, *icBlock);
139  setGlockPort(*icGlockPort);
140 
141  // add data ports and control ports for sockets
143  for (int i = 0; i < socketNav.count(); i++) {
144  Socket* socket = socketNav.item(i);
145  if (socket->segmentCount() == 0 || socket->portCount() == 0) {
146  continue;
147  }
148 
149  ProGe::Direction socketDirection =
150  convertDirection(socket->direction());
151 
152  // add the data port(s)
153  if (socket->direction() == Socket::INPUT) {
154  int width = inputSocketDataPortWidth(*socket);
155  if (width == 0) {
157  (boost::format(
158  "data port of the input socket %s is zero!\n") %
159  socket->name())
160  .str());
161  }
162  NetlistPort* socketDataPort = NULL;
163 
164  // connect the data port to the units
165  for (int i = 0; i < socket->portCount(); i++) {
166  Port* port = socket->port(i);
167  NetlistPort* unitPort;
168  // RISCV must have 32b pc port due to APC operation
169  if (machine_.isRISCVMachine() && port == gcu->triggerPort()) {
170  socketDataPort = new NetlistPort(
171  this->inputSocketDataPort(socket->name()),
173  socketDirection, *icBlock);
174  }
175  // gcu ports pc and ra must use IMEMADDRWIDTH as width
176  else if (
177  isGcuPort(port) && (port == gcu->triggerPort() ||
178  port == gcu->returnAddressPort())) {
179  socket->setDataPortWidth("IMEMADDRWIDTH");
180  socketDataPort = new NetlistPort(
181  this->inputSocketDataPort(socket->name()),
182  "IMEMADDRWIDTH", ProGe::BIT_VECTOR,
183  socketDirection, *icBlock);
184  } else {
185  socketDataPort = new NetlistPort(
186  this->inputSocketDataPort(socket->name()),
188  socketDirection, *icBlock);
189  }
190 
191  // RA port of GCU is special case
192  if (gcu->hasReturnAddressPort() &&
193  port == gcu->returnAddressPort()) {
194  unitPort = &generator.gcuReturnAddressInPort();
195  } else {
196  unitPort = &generator.netlistPort(*port, ProGe::IN);
197  }
198  coreBlock.netlist().connect(*socketDataPort, *unitPort);
199  }
200  } else {
201  for (int i = 0; i < socket->portCount(); i++) {
202  int width = outputSocketDataPortWidth(*socket, i);
203  assert(width > 0);
204  NetlistPort* socketDataPort = NULL;
205 
206  // connect the data port to the unit
207  Port* port = socket->port(i);
208  NetlistPort* unitPort;
209  // gcu ports are treated differently
210  if (isGcuPort(port) && port == gcu->returnAddressPort()) {
211  socket->setDataPortWidth("IMEMADDRWIDTH");
212  socketDataPort = new NetlistPort(
213  outputSocketDataPort(socket->name(), i),
214  "IMEMADDRWIDTH", ProGe::BIT_VECTOR,
215  socketDirection, *icBlock);
216  } else {
217  socketDataPort = new NetlistPort(
218  outputSocketDataPort(socket->name(), i),
220  socketDirection, *icBlock);
221  }
222 
223  // RA port of GCU is special case
224  if (gcu->hasReturnAddressPort() &&
225  port == gcu->returnAddressPort()) {
226  unitPort = &generator.gcuReturnAddressOutPort();
227  } else {
228  unitPort = &generator.netlistPort(*port, ProGe::OUT);
229  }
230  coreBlock.netlist().connect(*socketDataPort, *unitPort);
231  }
232  }
233 
234  // add control ports
235  if (busControlWidth(
236  socket->direction(), socket->segmentCount()) > 0) {
237  int cntrlWidth = busControlWidth(
238  socket->direction(), socket->segmentCount());
239  assert(cntrlWidth > 0);
240  NetlistPort* icSocketCntrlPort = new NetlistPort(
241  socketBusControlPort(socket->name()),
242  Conversion::toString(cntrlWidth), cntrlWidth,
243  ProGe::BIT_VECTOR, ProGe::IN, *icBlock);
244  mapBusCntrlPortOfSocket(socket->name(), *icSocketCntrlPort);
245  }
246  if (dataControlWidth(socket->direction(), socket->portCount()) > 0) {
247  int cntrlWidth = dataControlWidth(
248  socket->direction(), socket->portCount());
249  assert(cntrlWidth > 0);
250  NetlistPort* icSocketCntrlPort = new NetlistPort(
251  socketDataControlPort(socket->name()),
252  Conversion::toString(cntrlWidth), cntrlWidth,
253  ProGe::BIT_VECTOR, ProGe::IN, *icBlock);
254  mapDataCntrlPortOfSocket(socket->name(), *icSocketCntrlPort);
255  }
256  }
257 
258  // add ports for short immediates to IC
260  for (int i = 0; i < busNav.count(); i++) {
261  Bus* bus = busNav.item(i);
262  if (bus->immediateWidth() > 0) {
263  NetlistPort* icSimmPort = new NetlistPort(
264  simmDataPort(bus->name()),
266  simmPortWidth(*bus), ProGe::BIT_VECTOR, ProGe::IN, *icBlock);
267  mapSImmDataPort(bus->name(), *icSimmPort);
268  NetlistPort* icSimmCntrlPort = new NetlistPort(
269  simmControlPort(bus->name()), "1", 1, ProGe::BIT_VECTOR,
270  ProGe::IN, *icBlock);
271  mapSImmCntrlPort(bus->name(), *icSimmCntrlPort);
272  }
273  }
274 }
275 
276 /**
277  * Generates the interconnection network to the given destination directory.
278  *
279  * @param dstDirectory The destination directory.
280  * @exception IOException If an IO error occurs.
281  */
282 void
284  const std::string& dstDirectory) {
285  generateSocketsAndMuxes(dstDirectory);
286 
287  // generate interconnection network
288  string icFile = dstDirectory + FileSystem::DIRECTORY_SEPARATOR +
289  ((language_==Verilog)?"ic.v":"ic.vhdl");
290  bool icCreated = FileSystem::createFile(icFile);
291  if (!icCreated) {
292  string errorMsg = "Unable to create file " + icFile;
293  throw IOException(__FILE__, __LINE__, __func__, errorMsg);
294  }
295  std::ofstream icStream(icFile.c_str(), std::ofstream::out);
296  writeInterconnectionNetwork(icStream);
297  icStream.close();
298 }
299 
300 /**
301  * Verifies that the IC generator is compatible with the machine.
302  *
303  * @exception InvalidData If the generator is incompatible.
304  */
305 void
307  // check that the machine does not use segments or bridges
309  for (int i = 0; i < busNav.count(); i++) {
310  Bus* bus = busNav.item(i);
311  if (bus->segmentCount() > 1) {
312  throw InvalidData(
313  __FILE__, __LINE__, __func__,
314  "IC generator does not support segmented buses.");
315  }
316  }
317 
319  if (bridgeNav.count() > 0) {
320  throw InvalidData(
321  __FILE__, __LINE__, __func__,
322  "IC generator does not support bridges.");
323  }
324 }
325 
326 void
328  exportBustrace_ = export_bt;
329 }
330 
331 /**
332  * Enables or disables generating bus trace code.
333  *
334  * @param generate Tells whether to generate the bus tracing code.
335  */
336 void
338  generateBusTrace_ = generate;
339 }
340 
341 
342 /**
343  * Sets the starting cycle to be generated to the bus trace.
344  *
345  * @param cycle The cycle.
346  */
347 void
349  busTraceStartingCycle_ = cycle;
350 }
351 
352 
353 /**
354  * Returns the pin of the socket control port that control the given segment
355  * connection.
356  *
357  * @param socket The socket.
358  * @param segment The segment.
359  * @return The pin of the control port.
360  * @exception NotAvailable If the socket is not output socket or if it is not
361  * connected to the given segment.
362  */
363 int
365  const TTAMachine::Socket& socket,
366  const TTAMachine::Segment& segment) const {
367  if (socket.direction() != Socket::OUTPUT) {
368  throw NotAvailable(__FILE__, __LINE__, __func__);
369  }
370 
371  for (int i = 0; i < socket.segmentCount(); i++) {
372  Segment* seg = socket.segment(i);
373  if (seg == &segment) {
374  return i;
375  }
376  }
377 
378  throw NotAvailable(__FILE__, __LINE__, __func__);
379 }
380 
381 /**
382  * Generates sockets needed in the machine to the given directory.
383  *
384  * @param dstDirectory The destination directory.
385  * @exception IOException If an IO error occurs.
386  */
387 void
388 DefaultICGenerator::generateSocketsAndMuxes(const std::string& dstDirectory) {
389  bool needSimmSocket = true;
391  for (int i = 0; i < socketNav.count(); i++) {
392  Socket* socket = socketNav.item(i);
393  if (socket->portCount() > 0 && socket->segmentCount() > 0 &&
394  !socketIsGenerated(*socket)) {
396  socket->direction(), socket->portCount(),
397  socket->segmentCount(), dstDirectory);
398 
399  if (socket->portCount() == 1 && socket->segmentCount() == 1 &&
400  socket->direction() == TTAMachine::Socket::OUTPUT) {
401  needSimmSocket = false;
402  }
403  if (socket->direction() == TTAMachine::Socket::OUTPUT) {
404  generatedOutputSockets_.emplace(
405  socket->portCount(), socket->segmentCount());
406  } else {
407  generatedInputSockets_.emplace(
408  socket->portCount(), socket->segmentCount());
409  }
410  }
411  }
412 
413  // generate short immediate sockets if needed
414  if (needSimmSocket) {
416  for (int i = 0; i < busNav.count(); i++) {
417  Bus* bus = busNav.item(i);
418  if (bus->immediateWidth() > 0) {
419  generateSocket(Socket::OUTPUT, 1, 1, dstDirectory);
420  generatedOutputSockets_.emplace(1, 1);
421  }
422  }
423  }
424 }
425 
426 /**
427  * Tests if the given port belongs to GCU
428  *
429  * @param port The port to be tested
430  */
431 bool
434  for (int i = 0; i < gcu->portCount(); i++) {
435  TTAMachine::Port* gcuPort = gcu->port(i);
436  if (gcuPort == port) {
437  return true;
438  }
439  }
440  return false;
441 }
442 
443 /**
444  * Generates the given socket to a VHDL file in the given directory.
445  *
446  * @param direction Direction of the socket.
447  * @param portConns The number of port connections.
448  * @param segmentConns The number of segment connections.
449  * @param dstDirectory The destination directory.
450  * @exception IOException If the file cannot be created.
451  */
452 void
454  TTAMachine::Socket::Direction direction, int portConns, int segmentConns,
455  const std::string& dstDirectory) const {
456  string fileName = socketFileName(language_,
457  direction, portConns, segmentConns);
458  string pathToFile = dstDirectory + FileSystem::DIRECTORY_SEPARATOR +
459  fileName;
460  bool created = FileSystem::createFile(pathToFile);
461  if (!created) {
462  string errorMsg = "Unable to create file " + pathToFile;
463  throw IOException(__FILE__, __LINE__, __func__, errorMsg);
464  }
465 
466  std::ofstream stream(pathToFile.c_str(), std::ofstream::out);
467  if (language_ == VHDL) {
468  stream << "library IEEE;" << endl;
469  stream << "use IEEE.std_logic_1164.all;" << endl;
470  stream << "use IEEE.std_logic_arith.all;" << endl;
471  stream << "use work.tce_util.all;" << endl;
472  } else {
473  //nothing for verilog
474  }
475  stream << endl;
476  if (direction == Socket::INPUT) {
477  generateInputMux(segmentConns, stream);
478  } else if (direction == Socket::OUTPUT) {
479  generateOutputSocket(portConns, segmentConns, stream);
480  } else {
481  assert(false);
482  }
483  stream.close();
484 }
485 
486 /**
487  * Generates the given input socket to the given stream.
488  *
489  * @param segmentConns The number of segment connections.
490  * @param stream The stream.
491  */
492 void
494  int segmentConns, std::ofstream& stream) const {
495  assert(segmentConns > 0);
496  if (language_ == VHDL) {
497  string entityName = inputMuxEntityName(segmentConns);
498  stream << "entity " << entityName << " is" << endl << endl;
499  writeInputSocketComponentDeclaration(VHDL,segmentConns, 1, stream);
500  stream << endl << "end " << entityName << ";" << endl << endl;
501 
502  stream << "architecture rtl of " << entityName << " is" << endl
503  << "begin" << endl
504  << endl;
505  stream << indentation(2)
506  << "-- If width of input bus is greater than width of output,"
507  << endl;
508  stream << indentation(2) << "-- using the LSB bits." << endl;
509  stream << indentation(2)
510  << "-- If width of input bus is smaller than width of output,"
511  << endl;
512  stream << indentation(2)
513  << "-- using zero extension to generate extra bits." << endl;
514  stream << endl;
515 
516  if (segmentConns > 1) {
517  stream << indentation(1) << "sel : process ("
518  << SOCKET_BUS_CONTROL_PORT << ", ";
519 
520  for (int i = 0; i < segmentConns; i++) {
521  stream << inputSocketBusPort(i);
522  if (i + 1 < segmentConns) {
523  stream << ", ";
524  } else {
525  stream << ")" << endl;
526  }
527  }
528 
529  stream << indentation(1) << "begin" << endl;
530  stream << indentation(2) << INPUT_SOCKET_DATA_PORT
531  << " <= (others => '0');" << endl;
532  stream << indentation(2) << "case " << SOCKET_BUS_CONTROL_PORT
533  << " is" << endl;
534 
535  for (int i = 0; i < segmentConns; i++) {
536  if (i+1 < segmentConns) {
537  stream << indentation(3) << "when \""
539  i, busControlWidth(Socket::INPUT, segmentConns))
540  << "\" =>" << endl;
541  } else {
542  stream << indentation(3) << "when others =>" << endl;
543  }
544  generateInputSocketRuleForBus(i, 4, stream);
545  }
546 
547  stream << indentation(2) << "end case;" << endl;
548  stream << indentation(1) << "end process sel;" << endl;
549 
550  } else {
551  stream << indentation(1) << "process (" << inputSocketBusPort(0)
552  << ")" << endl;
553  stream << indentation(1) << "begin" << endl;
554  stream << indentation(2) << INPUT_SOCKET_DATA_PORT
555  << " <= (others => '0');" << endl;
556  generateInputSocketRuleForBus(0, 2, stream);
557  stream << indentation(1) << "end process;" << endl;
558  }
559 
560  stream << "end rtl;" << endl;
561  } else {
562  string entityName = inputMuxEntityName(segmentConns);
563  stream << "`timescale 10ns/1ns" << endl
564  << "module " << entityName << "" << endl << endl;
565  writeInputSocketComponentDeclaration(Verilog,segmentConns, 1, stream);
566  stream << indentation(2)
567  << "// If width of input bus is greater than width of output,"
568  << endl
569  << indentation(2) << "// using the LSB bits." << endl
570  << indentation(2)
571  << "// If width of input bus is smaller than width of output,"
572  << endl
573  << indentation(2)
574  << "// using zero extension to generate extra bits." << endl
575  << endl;
576  if (segmentConns > 1) {
577  stream << indentation(1) << "always@("
578  << SOCKET_BUS_CONTROL_PORT << ", ";
579 
580  for (int i = 0; i < segmentConns; i++) {
581  stream << inputSocketBusPort(i);
582  if (i + 1 < segmentConns) {
583  stream << ", ";
584  } else {
585  stream << ")" << endl;
586  }
587  }
588  stream << indentation(1) << "begin" << endl
589  << indentation(2) << "case(" << SOCKET_BUS_CONTROL_PORT
590  << ")" << endl;
591  for (int i = 0; i < segmentConns; i++) {
592  if (i+1 < segmentConns) {
593  stream << indentation(3)
594  << i << " :" << endl;
595  } else {
596  stream << indentation(3) << "default:" << endl;
597  }
598  generateInputSocketRuleForBus(i, 4, stream);
599  }
600  stream << indentation(2) << "endcase" << endl
601  << indentation(1) << "end" << endl;
602  } else {
603  stream << indentation(1) << "always@(" << inputSocketBusPort(0)
604  << ")" << endl
605  << indentation(1) << "begin" << endl;
606  generateInputSocketRuleForBus(0, 2, stream);
607  stream << indentation(1) << "end" << endl;
608  }
609  stream << "endmodule" << endl;
610  }
611 }
612 
613 /**
614  * Generates rule in VHDL for an input socket for the given bus number.
615  *
616  * @param bus The bus.
617  * @param ind Indentation level.
618  * @param stream The stream to write.
619  */
620 void
622  int bus, int ind, std::ofstream& stream) const {
623  if (language_ == VHDL) {
624  stream << indentation(ind) << INPUT_SOCKET_DATA_PORT << " <= tce_ext("
625  << inputSocketBusPort(bus) << ", " << INPUT_SOCKET_DATA_PORT
626  << "'length);" << endl;
627  } else {
628  stream << indentation(ind) << "if (" << busWidthGeneric(bus) << " < "
629  << INPUT_SOCKET_DATAW_GENERIC << ")" << endl
630  << indentation(ind+1) << INPUT_SOCKET_DATA_PORT << " <= $unsigned("
631  << inputSocketBusPort(bus) << ");"<< endl
632  << indentation(ind) << "else if (" << busWidthGeneric(bus)
633  << " > " << INPUT_SOCKET_DATAW_GENERIC << ")" << endl
634  << indentation(ind+1) << INPUT_SOCKET_DATA_PORT << " <= "
636  << "-1 : 0];" << endl
637  << indentation(ind) << "else" << endl
638  << indentation(ind+1) << INPUT_SOCKET_DATA_PORT << " <= "
639  << inputSocketBusPort(bus) << "[" << busWidthGeneric(bus)
640  << "-1 : 0];" << endl;
641  }
642 }
643 
644 
645 /**
646  * Generates the output socket to the given stream.
647  *
648  * @param socket The socket.
649  * @param stream The stream.
650  */
651 void
653  int portConns,
654  int segmentConns,
655  std::ofstream& stream) const {
656  string entityName = outputSocketEntityName(segmentConns, portConns);
657  if (language_ == VHDL) {
658  stream << "entity " << entityName << " is" << endl;
660  portConns, segmentConns, 1, stream);
661  stream << "end " << entityName << ";" << endl << endl << endl;
662 
663  stream << "architecture output_socket_andor of " << entityName
664  << " is" << endl
665  << endl;
666 
667  if (portConns > 1) {
668  stream << indentation(1) << "constant data_widths : integer_array("
669  << portConns - 1 << " downto 0) := (";
670  for (int i = 0; i < portConns; i++) {
671  stream << dataWidthGeneric(i);
672  if (i+1 < portConns) {
673  stream << ", ";
674  }
675  }
676  stream << ");" << endl;
677 
678  for (int i = 0; i < segmentConns; i++) {
679  stream << indentation(1) << "signal databus_" << i
680  << "_temp : std_logic_vector(return_highest(data_widths, "
681  << portConns << ")-1 downto 0);" << endl;
682  }
683 
684  stream << indentation(1)
685  << "signal data : std_logic_vector(return_highest(data_widths, "
686  << portConns << ")-1 downto 0);" << endl;
687  } else {
688  for (int i = 0; i < segmentConns; i++) {
689  stream << indentation(1) << "signal databus_" << i
690  << "_temp : std_logic_vector(" << dataWidthGeneric(0)
691  << "-1 downto 0);" << endl;
692  }
693  stream << indentation(1) << "signal data : std_logic_vector("
694  << dataWidthGeneric(0) << "-1 downto 0);" << endl;
695  }
696 
697  stream << endl;
698  stream << "begin -- output_socket_andor" << endl << endl;
699 
700  if (portConns > 1) {
701  stream << indentation(1) << "data_sel : process(";
702  for (int i = 0; i < portConns; i++) {
703  stream << outputSocketDataPort(i) << ", ";
704  }
705  stream << SOCKET_DATA_CONTROL_PORT << ")" << endl;
706  stream << indentation(1) << "begin -- process data_sel" << endl;
707  for (int i = 0; i < portConns; i++) {
708  stream << indentation(2);
709  if (i == 0) {
710  stream << "if conv_integer(unsigned("
711  << SOCKET_DATA_CONTROL_PORT << ")) = 0 then"
712  << endl;
713  } else if (i < portConns-1) {
714  stream << "elsif conv_integer(unsignd("
715  << SOCKET_DATA_CONTROL_PORT << ")) = " << i
716  << endl;
717  } else {
718  stream << "else" << endl;
719  }
720  stream << indentation(3) << "data <= tce_sxt("
721  << outputSocketDataPort(i) << ", data'length);"
722  << endl;
723  }
724  stream << indentation(2) << "end if;" << endl;
725  stream << indentation(1) << "end process data_sel;" << endl
726  << endl;
727  } else {
728  stream << indentation(1) << "data <= " << outputSocketDataPort(0)
729  << ";" << endl << endl;
730  }
731 
732  stream << indentation(1) << "internal_signal : process(data, "
733  << SOCKET_BUS_CONTROL_PORT << ")" << endl;
734  stream << indentation(1) << "begin -- process internal_signal"
735  << endl;
736 
737  for (int i = 0; i < segmentConns; i++) {
738  stream << indentation(2) << "databus_" << i
739  << "_temp <= data and tce_sxt(" << SOCKET_BUS_CONTROL_PORT
740  << "(" << i << " downto " << i << "), data'length);"
741  << endl;
742  }
743 
744  stream << indentation(1) << "end process internal_signal;" << endl
745  << endl;
746 
747  stream << indentation(1) << "output : process (";
748 
749  for (int i = 0; i < segmentConns; i++) {
750  stream << "databus_" << i << "_temp";
751  if (i+1 < segmentConns) {
752  stream << ",";
753  } else {
754  stream << ")" << endl;
755  }
756  }
757 
758  stream << indentation(1) << "begin -- process output" << endl;
759 
760  for (int i = 0; i < segmentConns; i++) {
761  stream << indentation(2) << outputSocketBusPort(i)
762  << " <= tce_ext(databus_" << i << "_temp, "
763  << outputSocketBusPort(i) << "'length);" << endl;
764  }
765  stream << indentation(1) << "end process output;" << endl << endl;
766  stream << "end output_socket_andor;" << endl;
767  } else { // language_ == Verilog
768  stream << "`timescale 10ns/1ns" << endl
769  << "module " << entityName << endl;
771  portConns, segmentConns, 1, stream);
772 
773  //for avoiding absence of length attribute in verilog 2001
774  std::string data_length = dataWidthGeneric(0);
775 
776  stream << "//architecture output_socket_andor of " << entityName
777  << endl << endl;
778  if (portConns > 1) {
779 #if 1
780  assert(false &&
781  "Case portConns > 1 not supported by Verilog backend!");
782 #else
783 //!!!!!!!!!!!!!!!!!!!!!!!!!not finished here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
784  // stream << indentation(1) << "constant data_widths : integer_array("
785  // << portConns - 1 << " : 0] := (";
786  // for (int i = 0; i < portConns; i++) {
787  // stream << dataWidthGeneric(i);
788  // if (i+1 < portConns) {
789  // stream << ", ";
790  // }
791  // }
792  // stream << ");" << endl;
793 
794  // for (int i = 0; i < segmentConns; i++) {
795  // stream << indentation(1) << "signal databus_" << i
796  // << "_temp : std_logic_vector(return_highest(data_widths, "
797  // << portConns << ")-1 downto 0);" << endl;
798  // }
799 
800  // stream << indentation(1)
801  // << "signal data : std_logic_vector(return_highest(data_widths, "
802  // << portConns << ")-1 downto 0);" << endl;
803 #endif
804  } else {
805  for (int i = 0; i < segmentConns; i++) {
806  stream << indentation(1)
807  << "reg["<< dataWidthGeneric(0)
808  << "-1 : 0] "
809  <<" databus_" << i << "_temp;" << endl;
810  }
811  stream << indentation(1)
812  << "reg["<< dataWidthGeneric(0)
813  << "-1 : 0] "
814  << "data;" << endl;
815  }
816 
817  stream << endl;
818 
819  if (portConns > 1) {
820  stream << indentation(1) << "always@(";
821  // for (int i = 0; i < portConns; i++) {
822  // stream << outputSocketDataPort(i) << ", ";
823  // }
824  // stream << SOCKET_DATA_CONTROL_PORT << ")" << endl;
825  stream << "*" << ")" << endl;
826  stream << indentation(1) << "begin // process data_sel" << endl;
827  for (int i = 0; i < portConns; i++) {
828  stream << indentation(2);
829  if (i == 0) {
830  stream << "if("
831  << SOCKET_DATA_CONTROL_PORT << "== 0)"
832  << endl;
833  } else if (i < portConns-1) {
834  stream << "else if("
835  << SOCKET_DATA_CONTROL_PORT << "== " << i
836  << ")"
837  << endl;
838  } else {
839  stream << "else" << endl;
840  }
841  stream << indentation(3) << "data = $signed("
842  << outputSocketDataPort(i) << ");"
843  << endl;
844  }
845  stream << indentation(1) << "end //process data_sel;" << endl
846  << endl;
847  } else {
848  stream << indentation(1)
849  << "always@(*)" << "data = " << outputSocketDataPort(0)
850  << ";" << endl << endl;
851  }
852 
853  // stream << indentation(1) << "always@(data, "
854  // << SOCKET_BUS_CONTROL_PORT << ")" << endl;
855  stream << indentation(1) << "always@(*)" << endl;
856  stream << indentation(1) << "begin //process internal_signal"
857  << endl;
858 
859  for (int i = 0; i < segmentConns; i++) {
860  stream << indentation(2)
861  << "databus_" << i << "_temp"
862  << "= data & {" << dataWidthGeneric(0) << "{"
864  << "[" << i << " : " << i << "]}};"
865  << endl;
866  }
867 
868  stream << indentation(1) << "end //process internal_signal;" << endl
869  << endl;
870 
871  stream << indentation(1) << "always@(*)" << endl;
872  // stream << indentation(1) << "always@(";
873  // for (int i = 0; i < segmentConns; i++) {
874  // stream << "databus_" << i << "_temp";
875  // if (i+1 < segmentConns) {
876  // stream << ",";
877  // } else {
878  // stream << ")" << endl;
879  // }
880  // }
881 
882  stream << indentation(1) << "begin // process output" << endl;
883 
884  for (int i = 0; i < segmentConns; i++) {
885  stream << indentation(2) << "if(" << busWidthGeneric(i)
886  << " < " << data_length << ")" << endl;
887  stream << indentation(3) << outputSocketBusPort(i)
888  << " = databus_" << i << "_temp;" << endl;
889  //"[" << busWidthGeneric(i) << "-1 : 0];" << endl;
890  stream << indentation(2) << "else" << endl;
891  stream << indentation(3) << outputSocketBusPort(i)
892  << " = $unsigned(databus_" << i << "_temp);"
893  << endl;
894  }
895  stream << indentation(1) << "end //process output;" << endl << endl;
896  stream << "endmodule //output_socket_andor;" << endl;
897  }
898 }
899 
900 /**
901  * Writes the bus dump lines required by the HW debugger.
902  *
903  * @param stream The stream.
904  */
905 void
906 DefaultICGenerator::writeBustraceExportCode(std::ostream& stream) const {
907  stream << indentation(1) << "db_bustraces <= " << endl;
908 
910 
911  for (int i = 0; i < busNav.count(); i++) {
912  if (i % 4 == 0) {
913  stream << indentation(2);
914  }
915 
916  // Reverse order
917  int idx = busNav.count() - 1 - i;
918  int busWidth = busNav.item(idx)->width();
919 
920  if (busWidth % 32 !=
921  0) { // Pad busses to multiple of 32b with zeroes
922  stream << "\"" << string(32 - busWidth, '0') << "\"&";
923  }
924 
925  stream << busSignal(*busNav.item(idx));
926 
927  if (i != busNav.count() - 1) {
928  stream << " & ";
929 
930  if (i % 4 == 3) {
931  stream << endl;
932  }
933  } else {
934  stream << ";";
935  }
936 
937  }
938  stream << endl;
939 }
940 
941 /**
942  * Writes the interconnection network to the given stream.
943  *
944  * @param stream The stream.
945  */
946 void
948  if (language_ == VHDL) {
949  stream << "library IEEE;" << endl;
950  stream << "use IEEE.std_logic_1164.all;" << endl;
951  stream << "use IEEE.std_logic_arith.ext;" << endl;
952  stream << "use IEEE.std_logic_arith.sxt;" << endl;
953  if (generateBusTrace_) {
954  stream << "use IEEE.numeric_std.all;" << endl;
955  stream << "use IEEE.math_real.all;" << endl;
956  stream << "use STD.textio.all;" << endl;
957  stream << "use IEEE.std_logic_textio.all;" << endl;
958  }
959  stream << "use work." << entityNameStr_ << "_globals.all;" << endl
960  << "use work.tce_util.all;" << endl
961  << endl;
962 
963  string entityName = entityNameStr_ + "_interconn";
964  stream << "entity " << entityName << " is" << endl << endl;
965 
966  if (exportBustrace_ && (icBlock_->port("db_bustraces") == NULL)) {
967  new NetlistPort(
968  "db_bustraces", "BUSTRACE_WIDTH", ProGe::BIT_VECTOR,
969  ProGe::OUT, *icBlock_);
970  }
971 
972  VHDLNetlistWriter::writeGenericDeclaration(
973  *icBlock_, 1, indentation(1), stream);
974  VHDLNetlistWriter::writePortDeclaration(
975  *icBlock_, 1, indentation(1), stream);
976 
977  stream << endl << "end " << entityName << ";" << endl << endl;
978 
979  // create architecture
980  stream << "architecture comb_andor of " << entityName << " is" << endl
981  << endl;
982  createSignalsForIC(stream);
983  stream << endl;
984  declareSocketEntities(stream);
985  stream << endl;
986  stream << "begin -- comb_andor" << endl << endl;
987 
988  if (generateBusTrace_) {
989  writeBusDumpCode(stream);
990  stream << endl;
991  }
992 
993  if (exportBustrace_) {
994  writeBustraceExportCode(stream);
995  stream << endl;
996  }
997 
998  // Sort sockets by name to get deterministic order in HDL.
1000  std::set<Socket*, Component::ComponentNameComparator> socketsToWrite;
1001  for (int i = 0; i < socketNav.count(); i++) {
1002  socketsToWrite.insert(socketNav.item(i));
1003  }
1004  for (std::set<Socket*,
1005  Component::ComponentNameComparator>::const_iterator iter =
1006  socketsToWrite.begin();
1007  iter != socketsToWrite.end(); iter++) {
1008  Socket* socket = *iter;
1009  int segmentCount = socket->segmentCount();
1010  if (segmentCount == 0 || socket->portCount() == 0) {
1011  continue;
1012  }
1013  stream << indentation(1) << socket->name() << " : "
1014  << socketEntityName(*socket) << endl;
1015  stream << indentation(2) << "generic map (" << endl;
1016  for (int i = 0; i < segmentCount; i++) {
1017  int actualGenericWidth = 0;
1018  if (socket->direction() == Socket::OUTPUT) {
1019  actualGenericWidth = maxOutputSocketDataPortWidth(*socket);
1020  } else if (socket->direction() == Socket::INPUT) {
1021  actualGenericWidth =
1022  socket->segment(i)->parentBus()->width();
1023  }
1024  stream << indentation(3) << busWidthGeneric(i) << " => "
1025  << actualGenericWidth << "," << endl;
1026  }
1027  if (socket->direction() == Socket::OUTPUT) {
1028  for (int i = 0; i < socket->portCount(); i++) {
1029  string socketWidth = "";
1030  if (socket->hasDataPortWidth()) {
1031  socketWidth = socket->dataPortWidth();
1032  } else {
1033  socketWidth =
1034  Conversion::toString(socket->port(i)->width());
1035  }
1036  if (socket->portCount() > 0
1037  && machine_.isRISCVMachine()) {
1038  ControlUnit* gcu = machine_.controlUnit();
1039  if (isGcuPort(socket->port(0)) &&
1040  socket->port(0) == gcu->triggerPort()) {
1041  socketWidth = Conversion::toString(32);
1042  }
1043  }
1044  stream << indentation(3) << dataWidthGeneric(i)
1045  << " => " << socketWidth;
1046  if (i+1 == socket->portCount()) {
1047  stream << ")" << endl;
1048  } else {
1049  stream << "," << endl;
1050  }
1051  }
1052  } else { // socket->direction() == Socket::INPUT
1053  string socketWidth;
1054  if (socket->hasDataPortWidth()) {
1055  socketWidth = socket->dataPortWidth();
1056  } else {
1057  socketWidth = Conversion::toString(
1058  inputSocketDataPortWidth(*socket));
1059  }
1060  stream << indentation(3) << INPUT_SOCKET_DATAW_GENERIC
1061  << " => " << socketWidth << ")"
1062  << endl;
1063  }
1064  stream << indentation(2) << "port map (" << endl;
1065  for (int i = 0; i < segmentCount; i++) {
1066  Bus* bus = socket->segment(i)->parentBus();
1067  stream << indentation(3);
1068  if (socket->direction() == Socket::INPUT) {
1069  stream << inputSocketBusPort(i) << " => "
1070  << busSignal(*bus) << "," << endl;
1071  } else {
1072  stream << outputSocketBusPort(i) << " => "
1073  << busAltSignal(*bus, *socket) << "," << endl;
1074  }
1075  }
1076 
1077  if (socket->direction() == Socket::OUTPUT) {
1078  for (int i = 0; i < socket->portCount(); i++) {
1079  stream << indentation(3) << outputSocketDataPort(i)
1080  << " => "
1081  << outputSocketDataPort(socket->name(), i);
1082  if (i+1 < socket->portCount()) {
1083  stream << "," << endl;
1084  }
1085  }
1086  } else {
1087  stream << indentation(3) << INPUT_SOCKET_DATA_PORT << " => "
1088  << inputSocketDataPort(socket->name());
1089  }
1090  if (busControlWidth(
1091  socket->direction(), socket->segmentCount()) > 0) {
1092  stream << "," << endl;
1093  stream << indentation(3) << SOCKET_BUS_CONTROL_PORT << " => "
1094  << socketBusControlPort(socket->name());
1095  }
1096  if (dataControlWidth(socket->direction(), socket->portCount()) > 0) {
1097  stream << "," << endl;
1098  stream << indentation(3) << SOCKET_DATA_CONTROL_PORT << " => "
1099  << socketDataControlPort(socket->name());
1100  }
1101  stream << ");" << endl << endl;
1102  }
1103 
1104  // add the sockets for short immediates
1106  for (int i = 0; i < busNav.count(); i++) {
1107  Bus* bus = busNav.item(i);
1108  if (bus->immediateWidth() > 0) {
1109  stream << indentation(1) << simmSocket(*bus) << " : "
1110  << outputSocketEntityName(1, 1) << endl;
1111  stream << indentation(2) << "generic map (" << endl;
1112  stream << indentation(3) << busWidthGeneric(0) << " => "
1113  << simmPortWidth(*bus) << "," << endl;
1114  stream << indentation(3) << dataWidthGeneric(0) << " => "
1115  << simmPortWidth(*bus) << ")" << endl;
1116  stream << indentation(2) << "port map (" << endl;
1117  stream << indentation(3) << outputSocketBusPort(0) << " => "
1118  << simmSignal(*bus) << "," << endl;
1119  stream << indentation(3) << outputSocketDataPort(0) << " => "
1120  << simmDataPort(bus->name()) << "," << endl;
1121  stream << indentation(3) << SOCKET_BUS_CONTROL_PORT << " => "
1122  << simmControlPort(bus->name()) << ");" << endl
1123  << endl;
1124  }
1125  }
1126 
1127  // add assignments to data buses
1128  for (int i = 0; i < busNav.count(); i++) {
1129  Bus* bus = busNav.item(i);
1130  std::set<Socket*> outputSockets = this->outputSockets(*bus);
1131  if (outputSockets.size() == 0 && bus->immediateWidth() == 0) {
1132  stream << indentation(1) << busSignal(*bus)
1133  << " <= (others=>'0');" << endl;
1134  continue;
1135  }
1136  // Sort sockets by name to get deterministic HDL output.
1137  std::set<Socket*, Component::ComponentNameComparator> socketsToWrite;
1138  for (std::set<Socket*>::iterator iter = outputSockets.begin();
1139  iter != outputSockets.end(); iter++) {
1140  socketsToWrite.insert(*iter);
1141  }
1142 
1143  stream << indentation(1) << busSignal(*bus) << " <= ";
1144  for (auto iter = socketsToWrite.begin();
1145  iter != socketsToWrite.end();) {
1146  Socket* socket = *iter;
1147  stream << "tce_ext(" << busAltSignal(*bus, *socket) << ", "
1148  << busSignal(*bus) << "'length)";
1149  iter++;
1150  if (iter != socketsToWrite.end()) {
1151  stream << " or ";
1152  }
1153  }
1154  if (bus->immediateWidth() > 0) {
1155  if (socketsToWrite.begin() != socketsToWrite.end()) {
1156  stream << " or ";
1157  }
1158  if (bus->signExtends()) {
1159  stream << "tce_sxt(";
1160  } else if (bus->zeroExtends()) {
1161  stream << "tce_ext(";
1162  } else {
1163  assert(false && "Unknown extension policy.");
1164  }
1165  stream << simmSignal(*bus)
1166  << ", " << busSignal(*bus) << "'length)";
1167  }
1168  stream << ";" << endl;
1169  }
1170 
1171  stream << endl;
1172  stream << "end comb_andor;" << endl;
1173 
1174  } else { // language_ == Verilog
1175  const std::string DS = FileSystem::DIRECTORY_SEPARATOR;
1176  string entityName = entityNameStr_ + "_interconn";
1177  stream << "`timescale 1ns/1ns" << endl
1178  << "module " << entityName << endl
1179  //include parameters here
1180  << "#(" << endl
1181  << "`include \""
1182  << entityNameStr_ << "_globals_pkg.vh\"" << endl
1183  << ")" << endl;
1184 
1185  VerilogNetlistWriter::writePortDeclaration(
1186  *icBlock_, 1, indentation(1), stream);
1187  VerilogNetlistWriter::writeGenericDeclaration(
1188  *icBlock_, 1, indentation(1), stream);
1189 
1190  // create architecture
1191  createSignalsForIC(stream);
1192  stream << endl;
1193 
1194  if (generateBusTrace_) {
1195  writeBusDumpCode(stream);
1196  stream << endl;
1197  }
1198 
1199  // Sort sockets by name to get deterministic HDL output.
1201  std::set<Socket*, Component::ComponentNameComparator> socketsToWrite;
1202  for (int i = 0; i < socketNav.count(); i++) {
1203  socketsToWrite.insert(socketNav.item(i));
1204  }
1205  for (std::set<Socket*,
1206  Component::ComponentNameComparator>::const_iterator iter =
1207  socketsToWrite.begin(); iter != socketsToWrite.end(); iter++) {
1208  Socket* socket = *iter;
1209  int segmentCount = socket->segmentCount();
1210  if (segmentCount == 0 || socket->portCount() == 0) {
1211  continue;
1212  }
1213  stream << indentation(1) << socketEntityName(*socket) << endl;
1214 
1215  //parameters(generics)
1216  stream << indentation(2) << "#(" << endl;
1217  for (int i = 0; i < segmentCount; i++) {
1218  stream << indentation(3) << "." << busWidthGeneric(i) << "("
1219  << socket->segment(i)->parentBus()->width() << "),"
1220  << endl;
1221  }
1222 
1223  if (socket->direction() == Socket::OUTPUT) {
1224  for (int i = 0; i < socket->portCount(); i++) {
1225  string socketWidth = "";
1226  if (socket->hasDataPortWidth()) {
1227  socketWidth = socket->dataPortWidth();
1228  } else {
1229  socketWidth =
1230  Conversion::toString(socket->port(i)->width());
1231  }
1232  stream << indentation(3) << "." << dataWidthGeneric(i)
1233  << "(" << socketWidth;
1234  if (i+1 == socket->portCount()) {
1235  stream << ")" << endl;
1236  } else {
1237  stream << ")," << endl;
1238  }
1239  }
1240  } else {
1241  string socketWidth;
1242  if (socket->hasDataPortWidth()) {
1243  socketWidth = socket->dataPortWidth();
1244  } else {
1245  socketWidth =
1247  }
1248  stream << indentation(3) << "." << INPUT_SOCKET_DATAW_GENERIC
1249  << "(" << socketWidth << ")"
1250  << endl;
1251  }
1252  stream << indentation(2) << ")" << endl
1253  << indentation(2) << socket->name() << endl
1254  << indentation(2) << "(" << endl;
1255  for (int i = 0; i < segmentCount; i++) {
1256  Bus* bus = socket->segment(i)->parentBus();
1257  stream << indentation(3);
1258  if (socket->direction() == Socket::INPUT) {
1259  stream << "." << inputSocketBusPort(i) << "("
1260  << busSignal(*bus) << ")," << endl;
1261  } else {
1262  stream << "." << outputSocketBusPort(i) << "("
1263  << busAltSignal(*bus, *socket) << ")," << endl;
1264  }
1265  }
1266 
1267  if (socket->direction() == Socket::OUTPUT) {
1268  for (int i = 0; i < socket->portCount(); i++) {
1269  stream << indentation(3) << "." << outputSocketDataPort(i)
1270  << "("
1271  << outputSocketDataPort(socket->name(), i);
1272  if (i+1 < socket->portCount()) {
1273  stream << ")," << endl;
1274  }
1275  }
1276  } else {
1277  stream << indentation(3) << "." << INPUT_SOCKET_DATA_PORT << "("
1278  << inputSocketDataPort(socket->name());
1279  }
1280  if (busControlWidth(
1281  socket->direction(), socket->segmentCount()) > 0) {
1282  stream << ")," << endl;
1283  stream << indentation(3) << "." << SOCKET_BUS_CONTROL_PORT << "("
1284  << socketBusControlPort(socket->name());
1285  }
1286  if (dataControlWidth(socket->direction(), socket->portCount()) > 0) {
1287  stream << ")," << endl;
1288  stream << indentation(3) << "." << SOCKET_DATA_CONTROL_PORT << "("
1289  << socketDataControlPort(socket->name());
1290  }
1291  stream << "));" << endl << endl;
1292  }
1293 
1294  // add the sockets for short immediates
1296  for (int i = 0; i < busNav.count(); i++) {
1297  Bus* bus = busNav.item(i);
1298  if (bus->immediateWidth() > 0) {
1299  stream << indentation(1)
1300  << outputSocketEntityName(1, 1)
1301  << " "
1302  << endl
1303 
1304  << indentation(2) << "#(" << endl
1305  << indentation(3) << "." << busWidthGeneric(0) << "("
1306  << bus->width() << ")," << endl
1307  << indentation(3) << "." << dataWidthGeneric(0) << "("
1308  << simmPortWidth(*bus) << ")" << endl
1309  << indentation(2) << ")" << endl
1310  << indentation(2) << simmSocket(*bus) << endl
1311  << indentation(2) << "(" << endl
1312  << indentation(3) << "." << outputSocketBusPort(0) << "("
1313  << simmSignal(*bus) << ")," << endl
1314  << indentation(3) << "." << outputSocketDataPort(0) << "("
1315  << simmDataPort(bus->name()) << ")," << endl
1316  << indentation(3) << "." << SOCKET_BUS_CONTROL_PORT << "("
1317  << simmControlPort(bus->name()) << "));" << endl << endl;
1318  }
1319  }
1320 
1321  // add assignments to data buses
1322  for (int i = 0; i < busNav.count(); i++) {
1323  Bus* bus = busNav.item(i);
1324  std::set<Socket*> outputSockets = this->outputSockets(*bus);
1325  stream << indentation(1) << "assign " << busSignal(*bus) << " = ";
1326  // Sort sockets by name to get deterministic HDL output.
1327  std::set<Socket*, Component::ComponentNameComparator> socketsToWrite;
1328  for (std::set<Socket*>::iterator iter = outputSockets.begin();
1329  iter != outputSockets.end(); iter++) {
1330  socketsToWrite.insert(*iter);
1331  }
1332 
1333  for (std::set<Socket*,
1334  Component::ComponentNameComparator>::const_iterator iter =
1335  socketsToWrite.begin(); iter != socketsToWrite.end();) {
1336  Socket* socket = *iter;
1337  stream << busAltSignal(*bus, *socket);
1338  iter++;
1339  if (iter != socketsToWrite.end()) {
1340  stream << " | ";
1341  }
1342  }
1343  if (bus->immediateWidth() > 0) {
1344  if (socketsToWrite.begin() != socketsToWrite.end()) {
1345  stream << " | ";
1346  }
1347  stream << simmSignal(*bus);
1348  }
1349  stream << ";" << endl;
1350  }
1351  stream << endl;
1352  stream << "endmodule"<< endl;
1353  }
1354 }
1355 
1356 
1357 /**
1358  * Writes the signal declarations of interconnection network to the
1359  * given stream.
1360  *
1361  * @param stream The stream.
1362  */
1363 void
1366  if (language_ == VHDL){
1367  for (int i = 0; i < busNav.count(); i++) {
1368  Bus* bus = busNav.item(i);
1369 
1370  if (isBusConnected(*bus)) {
1371  // create signal for the bus
1372  stream << indentation(1) << "signal " << busSignal(*bus)
1373  << " : std_logic_vector(" << bus->width() - 1
1374  << " downto 0);" << endl;
1375  }
1376 
1377  // create a signal for all the output sockets connected to the
1378  // bus
1379  // Sort alphabetically to get deterministic HDL output.
1380  std::set<Socket*> outputSockets = this->outputSockets(*bus);
1381  std::set<Socket*, Component::ComponentNameComparator>
1382  socketsToWrite;
1383  for (std::set<Socket*>::iterator iter = outputSockets.begin();
1384  iter != outputSockets.end(); iter++) {
1385  socketsToWrite.insert(*iter);
1386  }
1387 
1388  for (std::set<Socket*, Component::ComponentNameComparator>::
1389  iterator iter = socketsToWrite.begin();
1390  iter != socketsToWrite.end(); iter++) {
1391  stream << indentation(1) << "signal "
1392  << busAltSignal(*bus, **iter) << " : std_logic_vector("
1393  << maxOutputSocketDataPortWidth(**iter) - 1
1394  << " downto 0);" << endl;
1395  }
1396 
1397  // create additional signal for short immediate
1398  if (bus->immediateWidth() > 0) {
1399  stream << indentation(1) << "signal " << simmSignal(*bus)
1400  << " : std_logic_vector(" << simmPortWidth(*bus) - 1
1401  << " downto 0);" << endl;
1402  }
1403  }
1404  } else { // language_ == Verilog
1405  for (int i = 0; i < busNav.count(); i++) {
1406  Bus* bus = busNav.item(i);
1407  // create wire for the bus
1408  stream << indentation(1) << "wire[" << bus->width() - 1 << ":0] "
1409  << busSignal(*bus) << ";"<< endl;
1410 
1411  // create a wires for all the output sockets connected to the bus
1412  // Sort alphabetically to get deterministic HDL output.
1413  std::set<Socket*> outputSockets = this->outputSockets(*bus);
1414  std::set<Socket*, Component::ComponentNameComparator> socketsToWrite;
1415  for (std::set<Socket*>::iterator iter = outputSockets.begin();
1416  iter != outputSockets.end(); iter++) {
1417  socketsToWrite.insert(*iter);
1418  }
1419 
1420  for (std::set<Socket*, Component::ComponentNameComparator>::iterator
1421  iter = socketsToWrite.begin(); iter != socketsToWrite.end();
1422  iter++) {
1423  stream << indentation(1) << "wire[" << bus->width() - 1 <<":0] "
1424  << busAltSignal(*bus, **iter)<<";"<< endl;
1425  }
1426 
1427  // create additional wire for short immediate
1428  if (bus->immediateWidth() > 0) {
1429  stream << indentation(1) << "wire[" << bus->width() - 1 << ":0] "
1430  << simmSignal(*bus) << ";" << endl;
1431  }
1432  }
1433  }
1434 }
1435 
1436 
1437 /**
1438  * Declares the socket entities used in the IC.
1439  *
1440  * @param stream The stream to write.
1441  */
1442 void
1443 DefaultICGenerator::declareSocketEntities(std::ostream& stream) const {
1444  for (auto iter = generatedInputSockets_.begin();
1445  iter != generatedInputSockets_.end(); iter++) {
1446  int segmentCount = iter->second;
1447  string entityName = inputMuxEntityName(segmentCount);
1448  stream << indentation(1) << "component " << entityName << " is"
1449  << endl;
1450  writeInputSocketComponentDeclaration(VHDL, segmentCount, 2, stream);
1451  stream << indentation(1) << "end component;" << endl << endl;
1452  }
1453 
1454  for (auto iter = generatedOutputSockets_.begin();
1455  iter != generatedOutputSockets_.end(); iter++) {
1456  int portCount = iter->first;
1457  int segmentCount = iter->second;
1458  string entityName = outputSocketEntityName(segmentCount, portCount);
1459  stream << indentation(1) << "component " << entityName << " is"
1460  << endl;
1462  VHDL, portCount, segmentCount, 2, stream);
1463  stream << indentation(1) << "end component;" << endl << endl;
1464  }
1465 }
1466 
1467 
1468 /**
1469  * Writes the component interface declaration of the given output socket to
1470  * the given stream.
1471  *
1472  * @param portConns The number of port connections.
1473  * @param segmentConns The number of segment connections.
1474  * @param ind The indentation level.
1475  * @param stream The stream to write.
1476  */
1477 void
1479  const ProGe::HDL language,
1480  int portConns,
1481  int segmentConns,
1482  int ind,
1483  std::ostream& stream) {
1484 
1485  if (language == VHDL) {
1486  stream << indentation(ind) << "generic (" << endl;
1487 
1488  for (int i = 0; i < segmentConns; i++) {
1489  stream << indentation(ind+1) << busWidthGeneric(i)
1490  << " : integer := 32;" << endl;
1491  }
1492 
1493  for (int i = 0; i < portConns; i++) {
1494  stream << indentation(ind+1) << dataWidthGeneric(i)
1495  << " : integer := 32";
1496  if (i+1 == portConns) {
1497  stream << ");" << endl;
1498  } else {
1499  stream << ";" << endl;
1500  }
1501  }
1502 
1503  stream << indentation(ind) << "port (" << endl;
1504  for (int i = 0; i < segmentConns; i++) {
1505  stream << indentation(ind+1) << outputSocketBusPort(i)
1506  << " : out std_logic_vector(" << busWidthGeneric(i)
1507  << "-1 downto 0);" << endl;
1508  }
1509  for (int i = 0; i < portConns; i++) {
1510  stream << indentation(ind+1) << outputSocketDataPort(i)
1511  << " : in std_logic_vector(" << dataWidthGeneric(i)
1512  << "-1 downto 0);" << endl;
1513  }
1514 
1515  const int busControlWidth = segmentConns;
1516  stream << indentation(ind+1) << SOCKET_BUS_CONTROL_PORT
1517  << " : in std_logic_vector(" << busControlWidth - 1
1518  << " downto 0)";
1519 
1520  if (portConns > 1) {
1521  stream << ";" << endl;
1523  Socket::OUTPUT, portConns);
1524  stream << indentation(ind+1) << SOCKET_DATA_CONTROL_PORT
1525  << " : in std_logic_vector(" << dataControlWidth - 1
1526  << " downto 0));" << endl;
1527  } else {
1528  stream << ");" << endl;
1529  }
1530  } else {
1531  stream << indentation(ind) << "#( parameter " << endl;
1532 
1533  for (int i = 0; i < segmentConns; i++) {
1534  stream << indentation(ind+1) << busWidthGeneric(i)
1535  << " = 32," << endl;
1536  }
1537 
1538  for (int i = 0; i < portConns; i++) {
1539  stream << indentation(ind+1) << dataWidthGeneric(i)
1540  << " = 32";
1541  if (i+1 == portConns) {
1542  stream << ")" << endl;
1543  } else {
1544  stream << "," << endl;
1545  }
1546  }
1547 
1548  stream << indentation(ind) << "(" << endl;
1549  for (int i = 0; i < segmentConns; i++) {
1550  stream << indentation(ind+1)
1551  << "output reg[" << busWidthGeneric(i)
1552  << "-1 : 0] "
1553  << outputSocketBusPort(i)
1554  << "," << endl;
1555  }
1556  for (int i = 0; i < portConns; i++) {
1557  stream << indentation(ind+1)
1558  << "input[" << dataWidthGeneric(i)
1559  << "-1 : 0] "
1560  << outputSocketDataPort(i)
1561  << "," << endl;
1562  }
1563 
1564  const int busControlWidth = segmentConns;
1565  stream << indentation(ind+1)
1566  << "input [" << busControlWidth - 1
1567  << " : 0]"
1569 
1570  if (portConns > 1) {
1571  stream << "," << endl;
1573  Socket::OUTPUT, portConns);
1574  stream << indentation(ind+1) << SOCKET_DATA_CONTROL_PORT
1575  << "input [" << dataControlWidth - 1
1576  << " : 0]);" << endl;
1577  } else {
1578  stream << ");" << endl;
1579  }
1580  }
1581 }
1582 
1583 
1584 /**
1585  * Writes the component interface declaration of the given input socket to
1586  * the given stream.
1587  *
1588  * @param segmentConns The number of segment connections.
1589  * @param ind The indentation level.
1590  * @param stream The stream to write.
1591  */
1592 void
1594  const ProGe::HDL language,
1595  int segmentConns,
1596  int ind,
1597  std::ostream& stream) {
1598 
1599  if (language == VHDL) {
1600  stream << indentation(ind) << "generic (" << endl;
1601 
1602  for (int i = 0; i < segmentConns; i++) {
1603  stream << indentation(ind+1) << busWidthGeneric(i) <<
1604  " : integer := 32;" << endl;
1605  }
1606 
1607  stream << indentation(ind+1) << INPUT_SOCKET_DATAW_GENERIC
1608  << " : integer := 32);" << endl;
1609  stream << indentation(ind) << "port (" << endl;
1610 
1611  for (int i = 0; i < segmentConns; i++) {
1612  stream << indentation(ind+1) << inputSocketBusPort(i)
1613  << " : in std_logic_vector(" << busWidthGeneric(i)
1614  << "-1 downto 0);" << endl;
1615  }
1616 
1617  stream << indentation(ind+1) << INPUT_SOCKET_DATA_PORT
1618  << " : out std_logic_vector(" << INPUT_SOCKET_DATAW_GENERIC
1619  << "-1 downto 0)";
1620  int controlWidth = MathTools::bitLength(segmentConns - 1);
1621  if (segmentConns > 1) {
1622  stream << ";" << endl;
1623  stream << indentation(ind+1) << SOCKET_BUS_CONTROL_PORT
1624  << " : in std_logic_vector(" << controlWidth - 1
1625  << " downto 0));" << endl;
1626  } else {
1627  stream << ");" << endl;
1628  }
1629  } else {
1630  stream << indentation(ind) << "#( parameter " << endl;
1631 
1632  for (int i = 0; i < segmentConns; i++) {
1633  stream << indentation(ind+1) << busWidthGeneric(i) <<
1634  " = 32," << endl;
1635  }
1636 
1637  stream << indentation(ind+1) << INPUT_SOCKET_DATAW_GENERIC
1638  << " = 32)" << endl;
1639  stream << indentation(ind) << "(" << endl;
1640 
1641  for (int i = 0; i < segmentConns; i++) {
1642  stream << indentation(ind+1)
1643  << "input[" << busWidthGeneric(i)
1644  << "-1 : 0] " << inputSocketBusPort(i) << ","
1645  << endl;
1646  }
1647 
1648  stream << indentation(ind+1)
1649  << "output reg[" << INPUT_SOCKET_DATAW_GENERIC
1650  << "-1 : 0] "
1652  int controlWidth = MathTools::bitLength(segmentConns - 1);
1653  if (segmentConns > 1) {
1654  stream << "," << endl;
1655  stream << indentation(ind+1)
1656  << "input[" << controlWidth - 1
1657  << " : 0] "
1659  }
1660  stream << ");" << endl;
1661  }
1662 }
1663 
1664 
1665 /**
1666  * Writes the code that dumps the bus contents to an output file.
1667  *
1668  * @param stream The stream to write.
1669  */
1670 void
1671 DefaultICGenerator::writeBusDumpCode(std::ostream& stream) const {
1672  if (language_ == VHDL) {
1673 
1674  const std::string vhdlFunctionCeil4 =
1675  " -- Rounds integer up to next multiple of four.\n"
1676  " function ceil4 (\n"
1677  " constant val : natural)\n"
1678  " return natural is\n"
1679  " begin -- function ceil4\n"
1680  " return natural(ceil(real(val)/real(4)))*4;\n"
1681  " end function ceil4;\n";
1682 
1683  const std::string vhdlFunctionExt4 =
1684  " -- Extends std_logic_vector to multiple of four.\n"
1685  " function ext_to_multiple_of_4 (\n"
1686  " constant slv : std_logic_vector)\n"
1687  " return std_logic_vector is\n"
1688  " begin\n"
1689  " return std_logic_vector(resize(\n"
1690  " unsigned(slv), ceil4(slv'length)));\n"
1691  " end function ext_to_multiple_of_4;\n";
1692 
1693  const std::string vhdlFunctionToHex =
1694  " function to_unsigned_hex (\n"
1695  " constant slv : std_logic_vector) return string is\n"
1696  " variable resized_slv : std_logic_vector(ceil4(slv'length)"
1697  "-1 downto 0);\n"
1698  " variable result : string(1 to ceil4(slv'length)/4)\n"
1699  " := (others => ' ');\n"
1700  " subtype digit_t is std_logic_vector(3 downto 0);\n"
1701  " variable digit : digit_t := \"0000\";\n"
1702  " begin\n"
1703  " resized_slv := ext_to_multiple_of_4(slv);\n"
1704  " for i in result'range loop\n"
1705  " digit := resized_slv(\n"
1706  " resized_slv'length-((i-1)*4)-1 downto "
1707  "resized_slv'length-(i*4));\n"
1708  " case digit is\n"
1709  " when \"0000\" => result(i) := '0';\n"
1710  " when \"0001\" => result(i) := '1';\n"
1711  " when \"0010\" => result(i) := '2';\n"
1712  " when \"0011\" => result(i) := '3';\n"
1713  " when \"0100\" => result(i) := '4';\n"
1714  " when \"0101\" => result(i) := '5';\n"
1715  " when \"0110\" => result(i) := '6';\n"
1716  " when \"0111\" => result(i) := '7';\n"
1717  " when \"1000\" => result(i) := '8';\n"
1718  " when \"1001\" => result(i) := '9';\n"
1719  " when \"1010\" => result(i) := 'a';\n"
1720  " when \"1011\" => result(i) := 'b';\n"
1721  " when \"1100\" => result(i) := 'c';\n"
1722  " when \"1101\" => result(i) := 'd';\n"
1723  " when \"1110\" => result(i) := 'e';\n"
1724  " when \"1111\" => result(i) := 'f';\n"
1725  "\n"
1726  " -- For TTAsim bustrace compatibility\n"
1727  " when others => \n"
1728  " result := (others => '0');\n"
1729  " return result;\n"
1730  " end case;\n"
1731  " end loop; -- i in result'range\n"
1732  " return result;\n"
1733  " end function to_unsigned_hex;\n";
1734 
1735  stream << indentation(1)
1736  << "-- Dump the value on the buses into a file once in clock cycle"
1737  << endl;
1738  stream << indentation(1)
1739  << "-- setting DUMP false will disable dumping" << endl << endl;
1740  stream << indentation(1) << "-- Do not synthesize this process!" << endl;
1741  stream << indentation(1) << "-- pragma synthesis_off" << endl;
1742  stream << indentation(1) << "-- pragma translate_off" << endl;
1743 
1744  stream << indentation(1) << "file_output : process" << endl << endl;
1745  stream << indentation(2)
1746  << "file regularfileout : text;" << endl;
1747  stream << indentation(2)
1748  << "file executionfileout : text;" << endl << endl;
1749  stream << indentation(2) << "variable lineout : line;" << endl;
1750  stream << indentation(2) << "variable start : boolean := true;" << endl;
1751  stream << indentation(2) << "variable cyclecount : integer := 0;"
1752  << endl;
1753  stream << indentation(2) << "variable executioncount : integer := 0;"
1754  << endl << endl;
1755  stream << indentation(2) << "constant DUMP : boolean := true;" << endl;
1756  stream << indentation(2)
1757  << "constant REGULARDUMPFILE : string := \"bus.dump\";"
1758  << endl;
1759  stream << indentation(2)
1760  << "constant EXECUTIONDUMPFILE : string := \"execbus.dump\";"
1761  << endl << endl;
1762  stream << vhdlFunctionCeil4 << endl;
1763  stream << vhdlFunctionExt4 << endl;
1764  stream << vhdlFunctionToHex << endl;
1765  stream << indentation(1) << "begin" << endl;
1766  stream << indentation(2) << "if DUMP = true then" << endl;
1767  stream << indentation(3) << "if start = true then" << endl;
1768  stream << indentation(4)
1769  << "file_open(regularfileout, REGULARDUMPFILE, write_mode);"
1770  << endl;
1771  stream << indentation(4)
1772  << "file_open(executionfileout, EXECUTIONDUMPFILE, write_mode);"
1773  << endl;
1774  stream << indentation(4) << "start := false;" << endl;
1775  stream << indentation(3) << "end if;" << endl << endl;
1776 
1777  stream << indentation(3) << "-- wait until rising edge of clock"
1778  << endl;
1779  stream << indentation(3)
1780  << "wait on clk until clk = '1' and clk'last_value = '0';"
1781  << endl;
1782  int ind = 3;
1783  if (busTraceStartingCycle_ > 0) {
1784  stream << indentation(3) << "if (cyclecount > "
1785  << busTraceStartingCycle_ - 1
1786  << ") then" << endl;
1787  ind++;
1788  }
1789  stream << indentation(ind) << "write(lineout, cyclecount-"
1790  << busTraceStartingCycle_ << ");"
1791  << endl;
1792 
1794  for (int i = 0; i < busNav.count(); i++) {
1795  stream << indentation(ind) << "write(lineout, string'(\",\"));"
1796  << endl;
1797  stream << indentation(ind)
1798  << "write(lineout, to_unsigned_hex("
1799  << busSignal(*busNav.item(i)) << "));" << endl;
1800  }
1801 
1802  stream << endl << indentation(ind)
1803  << "writeline(regularfileout, lineout);" << endl;
1804 
1805  stream << indentation(ind) << "if glock = '0' then" << endl;
1806  stream << indentation(ind+1) << "write(lineout, executioncount" << ");"
1807  << endl;
1808 
1809  for (int i = 0; i < busNav.count(); i++) {
1810  stream << indentation(ind+1) << "write(lineout, string'(\",\"));"
1811  << endl;
1812  stream << indentation(ind+1)
1813  << "write(lineout, to_unsigned_hex("
1814  << busSignal(*busNav.item(i)) << "));" << endl;
1815  }
1816  stream << endl << indentation(ind+1)
1817  << "writeline(executionfileout, lineout);" << endl;
1818  stream << indentation(ind+1) << "executioncount := executioncount + 1;"
1819  << endl;
1820  stream << indentation(ind) << "end if;" << endl;
1821 
1822  if (busTraceStartingCycle_ > 0) {
1823  stream << indentation(3) << "end if;" << endl;
1824  }
1825  stream << indentation(3) << "cyclecount := cyclecount + 1;" << endl;
1826  stream << indentation(2) << "end if;" << endl;
1827  stream << indentation(1) << "end process file_output;" << endl;
1828  stream << indentation(1) << "-- pragma translate_on" << endl;
1829  stream << indentation(1) << "-- pragma synthesis_on" << endl;
1830 
1831  } else { // language_ == Verilog
1832  stream << indentation(1)
1833  << "// Dump the value on the buses into a file once in clock cycle"
1834  << endl
1835  << indentation(1)
1836  << "// setting DUMP false will disable dumping" << endl << endl
1837  << indentation(1) << "// Do not synthesize!" << endl
1838  << indentation(1) << "//synthesis translate_off" << endl
1839  << indentation(1) << "integer regularfileout;" << endl << endl
1840  << indentation(1) << "integer executionfileout;" << endl << endl
1841  << indentation(1) << "integer count=0;" << endl
1842  << indentation(1) << "integer executioncount=0;" << endl << endl
1843  << indentation(1) << "`define REGULARDUMPFILE \"bus.dump\""
1844  << indentation(1)
1845  << "`define EXECUTIONDUMPFILE \"execbus.dump\""
1846  << endl << endl
1847 
1848  << indentation(1) << "initial" << endl
1849  << indentation(1) << "begin" << endl
1850  << indentation(2)
1851  << "regularfileout = $fopen(`REGULARDUMPFILE,\"w\");" << endl
1852  << indentation(2) << "$fclose(regularfileout);" << endl
1853  << indentation(2)
1854  << "executionfileout = $fopen(`EXECUTIONDUMPFILE,\"w\");"
1855  << endl
1856  << indentation(2) << "$fclose(executionfileout);" << endl
1857  << indentation(2) << "forever" << endl
1858  << indentation(2) << "begin" << endl
1859  << indentation(3) << "#PERIOD;" << endl;
1860  if (busTraceStartingCycle_ > 0) {
1861  stream << indentation(3) << "if(count > "
1862  << busTraceStartingCycle_ - 1
1863  << ")" << endl;
1864  }
1865  std::string format_string = "%0d";
1866  std::string count_string = "count - " +
1868  std::string variable_list = "";
1869 
1871  for (int i = 0; i < busNav.count(); i++) {
1872  const Bus& bus = *busNav.item(i);
1873  format_string += ",%0"
1874  + Conversion::toString((bus.width()+3)/4) + "h";
1875  variable_list += ", $unsigned(" +
1876  Conversion::toString(busSignal(bus))+")";
1877  }
1878 
1879  stream << indentation(3) << "begin" << endl
1880  << indentation(4) << "regularfileout = "
1881  "$fopen(`REGULARDUMPFILE,\"a\");" << endl
1882  << indentation(4) << "$fwrite(regularfileout,"
1883  << "\"" << format_string << "\\n\"" << ", "
1884  << count_string << variable_list << ");" << endl
1885  << indentation(4) << "$fclose(regularfileout);" << endl
1886  << indentation(4) << "if(glock == 0)" << endl
1887  << indentation(4) << "begin" << endl
1888  << indentation(5) << "executionfileout = "
1889  "$fopen(`EXECUTIONDUMPFILE,\"a\");" << endl
1890  << indentation(5) << "$fwrite(executionfileout,"
1891  << "\"" << format_string << "\\n\"" << ", executioncount"
1892  << variable_list << ");" << endl
1893  << indentation(5) << "$fclose(executionfileout);" << endl
1894  << indentation(5) << "executioncount = executioncount + 1;"
1895  << endl
1896  << indentation(4) << "end" << endl
1897  << indentation(3) << "end" << endl
1898  << indentation(3) << "count = count + 1;" << endl
1899  << indentation(2) << "end" << endl
1900  << indentation(1) << "end" << endl
1901  << indentation(1) << "//synthesis translate_on" << endl;
1902  }
1903 }
1904 
1905 /**
1906  * Checks if given bus is connected to at least one socket.
1907  *
1908  * @param bus The bus.
1909  * @return True if bus is connected to some socket, false if bus is
1910  * unconnected.
1911  */
1912 bool
1914  std::set<Socket*> inputSockets;
1915  for (int i = 0; i < bus.segmentCount(); i++) {
1916  Segment* segment = bus.segment(i);
1917  if (segment->connectionCount() > 0) {
1918  return true;
1919  }
1920  }
1921  return false;
1922 }
1923 
1924 /**
1925  * Returns a set of all the input sockets that are connected to the
1926  * given bus.
1927  *
1928  * @param bus The bus.
1929  * @return The socket set.
1930  */
1931 std::set<Socket*>
1933  std::set<Socket*> inputSockets;
1934  for (int i = 0; i < bus.segmentCount(); i++) {
1935  Segment* segment = bus.segment(i);
1936  for (int i = 0; i < segment->connectionCount(); i++) {
1937  Socket* socket = segment->connection(i);
1938  if (socket->direction() == Socket::INPUT) {
1939  inputSockets.insert(socket);
1940  }
1941  }
1942  }
1943  return inputSockets;
1944 }
1945 
1946 /**
1947  * Returns a set of all the output sockets that are connected to the
1948  * given bus.
1949  *
1950  * @param bus The bus.
1951  * @return The socket set.
1952  */
1953 std::set<Socket*>
1955  std::set<Socket*> outputSockets;
1956  for (int i = 0; i < bus.segmentCount(); i++) {
1957  Segment* segment = bus.segment(i);
1958  for (int i = 0; i < segment->connectionCount(); i++) {
1959  Socket* socket = segment->connection(i);
1960  if (socket->direction() == Socket::OUTPUT) {
1961  outputSockets.insert(socket);
1962  }
1963  }
1964  }
1965  return outputSockets;
1966 }
1967 
1968 
1969 /**
1970  * Tells whether the given socket set contains similar socket to the
1971  * given one.
1972  *
1973  * @param set The socket set.
1974  * @param socket The socket.
1975  * @return True if the set contains similar socket, otherwise false.
1976  */
1977 bool
1979  return socketIsGenerated(
1980  socket.segmentCount(), socket.portCount(), socket.direction());
1981 }
1982 
1983 /**
1984  * Tells whether the given socket set contains similar socket to the
1985  * given one.
1986  *
1987  * @param set The socket set.
1988  * @param socket The socket.
1989  * @return True if the set contains similar socket, otherwise false.
1990  */
1991 bool
1993  int segmentConns, int portConns, Socket::Direction direction) {
1994  auto test_pair = std::make_pair(portConns, segmentConns);
1995 
1996  if (direction == Socket::INPUT) {
1997  return generatedInputSockets_.count(test_pair) == 1;
1998  } else if (direction == Socket::OUTPUT) {
1999  return generatedOutputSockets_.count(test_pair) == 1;
2000  } else {
2001  assert(false);
2002  }
2003 }
2004 
2005 /**
2006  * Returns the control value that selects the given port if the socket
2007  * is connected to several ports.
2008  *
2009  * @param socket The socket.
2010  * @param port The port.
2011  * @return The control value.
2012  * @exception NotAvailable If the given socket does not need data control or if the
2013  * given port is not attached to the socket.
2014  */
2015 int
2017  const TTAMachine::Socket& socket, const TTAMachine::Port& port) const {
2018  if (socket.direction() != Socket::OUTPUT) {
2019  throw NotAvailable(__FILE__, __LINE__, __func__);
2020  }
2021 
2022  for (int i = 0; i < socket.portCount(); i++) {
2023  if (socket.port(i) == &port) {
2024  return i;
2025  }
2026  }
2027 
2028  throw NotAvailable(__FILE__, __LINE__, __func__);
2029 }
2030 
2031 /**
2032  * Returns the control value that selects the given segment if the given input
2033  * socket is connected to several segments.
2034  *
2035  * @param socket The socket.
2036  * @param segment The segment.
2037  * @return The control value.
2038  * @exception NotAvailable If the socket does not need control or if it is not
2039  * connected to the given segment.
2040  */
2041 int
2043  const TTAMachine::Socket& socket,
2044  const TTAMachine::Segment& segment) const {
2045  if (busControlWidth(socket.direction(), socket.segmentCount()) < 1) {
2046  throw NotAvailable(__FILE__, __LINE__, __func__);
2047  }
2048 
2049  for (int i = 0; i < socket.segmentCount(); i++) {
2050  Segment* seg = socket.segment(i);
2051  if (seg == &segment) {
2052  return i;
2053  }
2054  }
2055 
2056  throw NotAvailable(__FILE__, __LINE__, __func__);
2057 }
2058 
2061  return busConnections;
2062 }
2063 /**
2064  * Calculates the width of the data port of the given input socket.
2065  *
2066  * @param socket The socket.
2067  * @return The width of the data port.
2068  */
2069 int
2071  assert(socket.direction() == Socket::INPUT);
2072  int width = 0;
2073  for (int i = 0; i < socket.portCount(); i++) {
2074  Port* port = socket.port(i);
2075  if (width < port->width()) {
2076  width = port->width();
2077  }
2078  }
2079  return width;
2080 }
2081 
2082 
2083 /**
2084  * Returns the width of the data port of the given output socket.
2085  *
2086  * @param socket The socket.
2087  * @param port The port.
2088  */
2089 int
2091  const TTAMachine::Socket& socket,
2092  int port) {
2093 
2094  assert(socket.direction() == Socket::OUTPUT);
2095  assert(port < socket.portCount());
2096  return socket.port(port)->width();
2097 }
2098 
2099 
2100 /**
2101  * Returns the maximum width of the data ports of the given output socket.
2102  *
2103  * @param socket The socket.
2104  */
2105 int
2107  const TTAMachine::Socket& socket) {
2108  int maxPortWidth = 0;
2109  assert(socket.direction() == Socket::OUTPUT);
2110  for (int i = 0; i < socket.portCount(); i++) {
2111  Port* port = socket.port(i);
2112  if (maxPortWidth < port->width()) {
2113  maxPortWidth = port->width();
2114  }
2115  }
2116  return maxPortWidth;
2117 }
2118 
2119 
2120 /**
2121  * Returns the number of bits required to control the bus connections of
2122  * the given socket.
2123  *
2124  * @param direction Direction of the socket.
2125  * @param busConns The number of bus connections.
2126  * @return The control width.
2127  */
2128 int
2131  int busConns) {
2132 
2133  assert(busConns >= 1);
2134 
2135  if (direction == Socket::INPUT) {
2136  return MathTools::bitLength(busConns - 1);
2137  } else {
2138  return busConns;
2139  }
2140 }
2141 
2142 
2143 /**
2144  * Returns the number of bits required to control from which port the
2145  * data is written to the bus.
2146  *
2147  * @param socket Direction of the socket,
2148  * @param portConns The number of port connections.
2149  * @return The control width.
2150  */
2151 int
2154  int portConns) {
2155  if (direction == Socket::OUTPUT) {
2156  return MathTools::bitLength(portConns - 1);
2157  } else {
2158  return 0;
2159  }
2160 }
2161 
2162 
2163 /**
2164  * Returns the required width of the short immediate port of the given bus.
2165  *
2166  * @param bus The bus.
2167  * @return The width of the port.
2168  */
2169 int
2171  if (bus.signExtends()) {
2172  return bus.width();
2173  } else if (bus.zeroExtends()) {
2174  return bus.immediateWidth();
2175  } else {
2176  assert(false && "Unknown extension policy.");
2177  return -1;
2178  }
2179 }
2180 
2181 
2182 /**
2183  * Returns the name of the data port of the given input socket in the
2184  * interconnection network.
2185  *
2186  * @param socket The socket.
2187  * @return The name of the data port.
2188  */
2189 std::string
2190 DefaultICGenerator::inputSocketDataPort(const std::string& socket) {
2191  return "socket_" + socket + "_data";
2192 }
2193 
2194 
2195 /**
2196  * Returns the name of the data port of the given output socket in the
2197  * interconnection network.
2198  *
2199  * @param socket The socket name.
2200  * @param port The data port number.
2201  * @return The name of the data port.
2202  */
2203 std::string
2205  const std::string& socket,
2206  int port) {
2207 
2208  return "socket_" + socket + "_data" + Conversion::toString(port);
2209 }
2210 
2211 
2212 /**
2213  * Returns the name of the bus connection control port of the given
2214  * socket.
2215  *
2216  * @param name Name of the socket.
2217  * @return The name of the control port.
2218  */
2219 std::string
2221  return "socket_" + name + "_bus_cntrl";
2222 }
2223 
2224 
2225 /**
2226  * Returns the name of the data control port of the given socket.
2227  *
2228  * @param name Name of the socket.
2229  * @return The name of the control port.
2230  */
2231 std::string
2233  return "socket_" + name + "_data_cntrl";
2234 }
2235 
2236 
2237 /**
2238  * Returns the name of the data port for short immediate of the given bus.
2239  *
2240  * @param busName Name of the bus.
2241  * @return The name of the port.
2242  */
2243 std::string
2244 DefaultICGenerator::simmDataPort(const std::string& busName) {
2245  return "simm_" + busName;
2246 }
2247 
2248 
2249 /**
2250  * Returns the name of the control port for short immediate of the given
2251  * bus.
2252  *
2253  * @param busName Name of the bus.
2254  * @return The name of the port.
2255  */
2256 std::string
2257 DefaultICGenerator::simmControlPort(const std::string& busName) {
2258  return "simm_cntrl_" + busName;
2259 }
2260 
2261 
2262 /**
2263  * Returns the name of the data bus port in input socket.
2264  *
2265  * @param bus The bus number.
2266  * @return The name of the port.
2267  */
2268 std::string
2270  return "databus" + Conversion::toString(bus);
2271 }
2272 
2273 
2274 /**
2275  * Returns the name of the data bus port in output socket.
2276  *
2277  * @param bus The bus number.
2278  * @return The name of the port.
2279  */
2280 std::string
2282  return "databus" + Conversion::toString(bus) + "_alt";
2283 }
2284 
2285 
2286 /**
2287  * Returns the name of the data port in output socket.
2288  *
2289  * @param port The port number.
2290  * @return The name of the port.
2291  */
2292 std::string
2294  return "data" + Conversion::toString(port);
2295 }
2296 
2297 std::string
2299  return bus.name() + "_data_" + Conversion::toString(index) + "_in";
2300 }
2301 
2302 std::string
2304  return bus.name() + "_mux_ctrl_in";
2305 }
2306 
2307 std::string
2309  return bus.name() + "_mux_enable_in";
2310 }
2311 
2312 /**
2313  * Returns the name of the signal of the given bus.
2314  *
2315  * @param bus The bus.
2316  * @return The name of the signal.
2317  */
2318 std::string
2320  return "databus_" + bus.name();
2321 }
2322 
2323 
2324 /**
2325  * Returns the signal name of the given bus for the given output socket.
2326  *
2327  * @param bus The bus.
2328  * @param socket The socket.
2329  * @return The signal name.
2330  */
2331 std::string
2333  const TTAMachine::Bus& bus,
2334  const TTAMachine::Socket& socket) {
2335  assert(socket.direction() == Socket::OUTPUT);
2336  if (!MapTools::containsKey(altSignalMap_, &bus)) {
2337  SocketSignalMap* newMap = new SocketSignalMap;
2338  altSignalMap_.emplace(&bus, newMap);
2339  }
2340 
2341  SocketSignalMap* signalMap = altSignalMap_[&bus];
2342  if (!MapTools::containsKey(*signalMap, &socket)) {
2343  int maxValue = -1;
2344  for (auto iter = signalMap->begin(); iter != signalMap->end();
2345  iter++) {
2346  if ((*iter).second > maxValue) {
2347  maxValue = (*iter).second;
2348  }
2349  }
2350  maxValue++;
2351  signalMap->emplace(&socket, maxValue);
2352  }
2353 
2354  int value = signalMap->at(&socket);
2355  return busSignal(bus) + "_alt" + Conversion::toString(value);
2356 }
2357 
2358 
2359 /**
2360  * Returns the generic name for width of the given bus.
2361  *
2362  * @param bus The bus number.
2363  * @return The generic name.
2364  */
2365 std::string
2367  return "BUSW_" + Conversion::toString(bus);
2368 }
2369 
2370 
2371 /**
2372  * Returns the generic name for width of the given port.
2373  *
2374  * @param port The port number.
2375  * @return The generic name.
2376  */
2377 std::string
2379  return "DATAW_" + Conversion::toString(port);
2380 }
2381 
2382 
2383 /**
2384  * Returns the name of the socket for short immediate of the given bus.
2385  *
2386  * @param bus The bus.
2387  * @return The name of the socket.
2388  */
2389 std::string
2391  return "simm_socket_" + bus.name();
2392 }
2393 
2394 
2395 /**
2396  * Returns the name of the signal of short immediate of the given bus.
2397  *
2398  * @param bus The bus.
2399  * @return The name of the signal.
2400  */
2401 std::string
2403  return "databus_" + bus.name() + "_simm";
2404 }
2405 
2406 
2407 /**
2408  * Converts the given socket direction to direction of the corresponding
2409  * data port in the IC block.
2410  *
2411  * @param direction The socket direction.
2412  * @return The direction of the corresponding socket data port in IC
2413  * block.
2414  */
2417  TTAMachine::Socket::Direction direction) {
2418  switch (direction) {
2419  case Socket::INPUT:
2420  return ProGe::OUT;
2421  case Socket::OUTPUT:
2422  return ProGe::IN;
2423  case Socket::UNKNOWN:
2424  assert(false);
2425  }
2426 
2427  assert(false);
2428 }
2429 
2430 /**
2431  * Generates file where to write VHDL definition of the given socket.
2432  *
2433  * @param direction Direction of the socket.
2434  * @param portConns Number of port connections.
2435  * @param segmentConns Number of segment connections.
2436  * @return The file name.
2437  */
2438 std::string
2440  const ProGe::HDL language,
2442  int portConns,
2443  int segmentConns) {
2444 
2445  if (direction == Socket::INPUT) {
2446  return "input_mux_" + Conversion::toString(segmentConns) +
2447  ((language == VHDL) ? ".vhdl" : ".v");
2448  } else if (direction == Socket::OUTPUT) {
2449  return "output_socket_" +
2450  Conversion::toString(segmentConns) + "_" +
2451  Conversion::toString(portConns) + ((language==VHDL)?".vhdl":".v");
2452  } else {
2453  assert(false);
2454  }
2455 }
2456 
2457 /**
2458  * Generates VHDL entity name for the given socket.
2459  *
2460  * @param direction Direction of the socket.
2461  * @return The entity name.
2462  */
2463 std::string
2465  if (socket.direction() == Socket::INPUT) {
2466  return inputMuxEntityName(socket.segmentCount());
2467  } else if (socket.direction() == Socket::OUTPUT) {
2468  return outputSocketEntityName(
2469  socket.segmentCount(), socket.portCount());
2470  } else {
2471  assert(false);
2472  }
2473 }
2474 
2475 /**
2476  * Returns the entity name of the input socket which has the given number
2477  * of connections.
2478  *
2479  * @param conns The number of connections.
2480  * @return The name of the entity.
2481  */
2482 std::string
2484  return entityNameStr_ + "_input_mux_" + Conversion::toString(conns);
2485 }
2486 
2487 /**
2488  * Returns the entity name of the output socket which has the given number
2489  * of connections.
2490  *
2491  * @param busConns The number of bus connections.
2492  * @param portConns The number of port connections.
2493  * @return The name of the entity.
2494  */
2495 std::string
2496 DefaultICGenerator::outputSocketEntityName(int busConns, int portConns) const {
2497  return entityNameStr_ + "_output_socket_cons_" +
2498  Conversion::toString(busConns) + "_" +
2499  Conversion::toString(portConns);
2500 }
2501 
2502 std::string
2504  return bus.name() + "_bus_mux_inst";
2505 }
2506 
2507 /**
2508  * Generates an indentation of the given level.
2509  *
2510  * @param level The level.
2511  */
2512 std::string
2513 DefaultICGenerator::indentation(unsigned int level) {
2514  string indentation("");
2515  for (unsigned int i = 0; i < level; i++) {
2516  indentation += " ";
2517  }
2518  return indentation;
2519 }
2520 
TTAMachine::Bus::immediateWidth
int immediateWidth() const
Definition: Bus.cc:160
DefaultICGenerator::dataWidthGeneric
static std::string dataWidthGeneric(int port)
Definition: DefaultICGenerator.cc:2378
Netlist.hh
ProGe::NetlistBlock::netlist
virtual const Netlist & netlist() const
Definition: BaseNetlistBlock.cc:348
HDBTypes.hh
DefaultICGenerator::busAltSignal
std::string busAltSignal(const TTAMachine::Bus &bus, const TTAMachine::Socket &socket)
Definition: DefaultICGenerator.cc:2332
INPUT_SOCKET_DATAW_GENERIC
const string INPUT_SOCKET_DATAW_GENERIC
Definition: DefaultICGenerator.cc:69
DefaultICGenerator::generateSocket
void generateSocket(TTAMachine::Socket::Direction direction, int portConns, int segmentConns, const std::string &dstDirectory) const
Definition: DefaultICGenerator.cc:453
DefaultICGenerator::outputSocketEntityName
std::string outputSocketEntityName(int busConns, int portConns) const
Definition: DefaultICGenerator.cc:2496
FileSystem.hh
DefaultICGenerator::busMuxEnablePort
static std::string busMuxEnablePort(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:2308
TTAMachine::Socket::port
Port * port(int index) const
Definition: Socket.cc:266
TTAMachine::Socket::portCount
int portCount() const
DefaultICGenerator.hh
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
ProGe::NetlistBlock
Definition: NetlistBlock.hh:61
ProGe::Verilog
@ Verilog
Verilog.
Definition: ProGeTypes.hh:42
TTAMachine::Machine::isRISCVMachine
bool isRISCVMachine() const
Definition: Machine.cc:1063
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
TTAMachine::Socket::OUTPUT
@ OUTPUT
Data goes from port to bus.
Definition: Socket.hh:60
DefaultICGenerator::simmSignal
static std::string simmSignal(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:2402
TTAMachine::Bus::zeroExtends
bool zeroExtends() const
Definition: Bus.cc:182
ProGe::BIT_VECTOR
@ BIT_VECTOR
Several bits.
Definition: ProGeTypes.hh:48
DefaultICGenerator::declareSocketEntities
void declareSocketEntities(std::ostream &stream) const
Definition: DefaultICGenerator.cc:1443
DefaultICGenerator::dataControlWidth
static int dataControlWidth(TTAMachine::Socket::Direction direction, int portConns)
Definition: DefaultICGenerator.cc:2152
TTAMachine::Segment
Definition: Segment.hh:54
TTAMachine::Bus::width
int width() const
Definition: Bus.cc:149
DefaultICGenerator::addICToNetlist
void addICToNetlist(const ProGe::NetlistGenerator &generator, ProGe::NetlistBlock &netlistBlock)
Definition: DefaultICGenerator.cc:114
DefaultICGenerator::writeBustraceExportCode
void writeBustraceExportCode(std::ostream &stream) const
Definition: DefaultICGenerator.cc:906
DefaultICGenerator::simmControlPort
static std::string simmControlPort(const std::string &busName)
Definition: DefaultICGenerator.cc:2257
TTAMachine::FunctionUnit::triggerPort
virtual BaseFUPort * triggerPort() const
Definition: FunctionUnit.cc:267
MapTools.hh
TTAMachine::Bus
Definition: Bus.hh:53
DefaultICGenerator::busMuxEntityName
static std::string busMuxEntityName(TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:2503
TTAMachine::Port::width
virtual int width() const =0
DefaultICGenerator::SocketSignalMap
std::map< const TTAMachine::Socket *, int > SocketSignalMap
Definition: DefaultICGenerator.hh:98
DefaultICGenerator::getBusConnections
virtual const BusSocketMap getBusConnections() const
Definition: DefaultICGenerator.cc:2060
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
CentralizedControlICGenerator::mapDataCntrlPortOfSocket
void mapDataCntrlPortOfSocket(const std::string &socketName, ProGe::NetlistPort &port)
Definition: CentralizedControlICGenerator.cc:208
DefaultICGenerator::socketFileName
static std::string socketFileName(const ProGe::HDL language, TTAMachine::Socket::Direction direction, int portConns, int segmentConns)
Definition: DefaultICGenerator.cc:2439
TTAMachine::Socket::segment
Segment * segment(int index) const
Definition: Socket.cc:401
TTAMachine::Socket::Direction
Direction
Definition: Socket.hh:58
DefaultICGenerator::busConnections
BusSocketMap busConnections
Definition: DefaultICGenerator.hh:217
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::Socket::direction
Direction direction() const
TTAMachine::Bus::segment
virtual Segment * segment(int index) const
Definition: Bus.cc:329
SOCKET_DATA_CONTROL_PORT
const string SOCKET_DATA_CONTROL_PORT
Definition: DefaultICGenerator.cc:72
DefaultICGenerator::outputSocketDataPort
static std::string outputSocketDataPort(const std::string &socket, int port)
Definition: DefaultICGenerator.cc:2204
DefaultICGenerator::socketIsGenerated
bool socketIsGenerated(const TTAMachine::Socket &socket)
Definition: DefaultICGenerator.cc:1978
Socket.hh
Conversion::toString
static std::string toString(const T &source)
NotAvailable
Definition: Exception.hh:728
DefaultICGenerator::socketDataControlPort
static std::string socketDataControlPort(const std::string &name)
Definition: DefaultICGenerator.cc:2232
DefaultICGenerator::generateBusTrace_
bool generateBusTrace_
Tells whether to generate bus tracing code.
Definition: DefaultICGenerator.hh:210
DefaultICGenerator::exportBustrace_
bool exportBustrace_
Tells whether to export bustraces to debugger.
Definition: DefaultICGenerator.hh:212
TTAMachine::Bus::signExtends
bool signExtends() const
Definition: Bus.cc:171
DefaultICGenerator::socketEntityName
std::string socketEntityName(TTAMachine::Socket &socket) const
Definition: DefaultICGenerator.cc:2464
DefaultICGenerator::generateInputSocketRuleForBus
void generateInputSocketRuleForBus(int bus, int ind, std::ofstream &stream) const
Definition: DefaultICGenerator.cc:621
ProGe::Netlist::connect
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition: Netlist.cc:83
DefaultICGenerator::inputSocketControlValue
virtual int inputSocketControlValue(const TTAMachine::Socket &socket, const TTAMachine::Segment &segment) const
Definition: DefaultICGenerator.cc:2042
assert
#define assert(condition)
Definition: Application.hh:86
DefaultICGenerator::createSignalsForIC
void createSignalsForIC(std::ostream &stream)
Definition: DefaultICGenerator.cc:1364
TTAMachine::Segment::connectionCount
int connectionCount() const
ProGe::NetlistGenerator::gcuReturnAddressOutPort
NetlistPort & gcuReturnAddressOutPort() const
Definition: NetlistGenerator.cc:567
DefaultICGenerator::writeBusDumpCode
void writeBusDumpCode(std::ostream &stream) const
Definition: DefaultICGenerator.cc:1671
Conversion::toBinary
static std::string toBinary(unsigned int source, unsigned int stringWidth=0)
Definition: Conversion.cc:155
Segment.hh
DefaultICGenerator::busMuxControlPort
static std::string busMuxControlPort(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:2303
CentralizedControlICGenerator::mapBusCntrlPortOfSocket
void mapBusCntrlPortOfSocket(const std::string &socketName, ProGe::NetlistPort &port)
Definition: CentralizedControlICGenerator.cc:191
TTAMachine::Socket::dataPortWidth
const std::string & dataPortWidth() const
Definition: Socket.cc:415
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
DefaultICGenerator::busSignal
static std::string busSignal(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:2319
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
ProGe::VHDL
@ VHDL
VHDL.
Definition: ProGeTypes.hh:41
DefaultICGenerator::generateInputMux
void generateInputMux(int segmentConns, std::ofstream &stream) const
Definition: DefaultICGenerator.cc:493
DefaultICGenerator::BusSocketMap
std::map< const TTAMachine::Bus *, std::set< TTAMachine::Socket * > > BusSocketMap
Definition: DefaultICGenerator.hh:65
InvalidData
Definition: Exception.hh:149
TTAMachine::Machine::bridgeNavigator
virtual BridgeNavigator bridgeNavigator() const
Definition: Machine.cc:404
DefaultICGenerator::setGenerateBusTrace
void setGenerateBusTrace(bool generate)
Definition: DefaultICGenerator.cc:337
TTAMachine::ControlUnit
Definition: ControlUnit.hh:50
DefaultICGenerator::isGcuPort
bool isGcuPort(const TTAMachine::Port *port) const
Definition: DefaultICGenerator.cc:432
SOCKET_BUS_CONTROL_PORT
const string SOCKET_BUS_CONTROL_PORT
Definition: DefaultICGenerator.cc:71
Conversion.hh
DefaultICGenerator::inputSocketDataPortWidth
static int inputSocketDataPortWidth(const TTAMachine::Socket &socket)
Definition: DefaultICGenerator.cc:2070
DefaultICGenerator::DefaultICGenerator
DefaultICGenerator(const TTAMachine::Machine &machine)
Definition: DefaultICGenerator.cc:81
ProGe::NetlistGenerator::gcuReturnAddressInPort
NetlistPort & gcuReturnAddressInPort() const
Definition: NetlistGenerator.cc:551
TTAMachine::Segment::parentBus
Bus * parentBus() const
TTAMachine::Port
Definition: Port.hh:54
DefaultICGenerator::simmDataPort
static std::string simmDataPort(const std::string &busName)
Definition: DefaultICGenerator.cc:2244
DefaultICGenerator::generateOutputSocket
void generateOutputSocket(int portConns, int segmentConns, std::ofstream &stream) const
Definition: DefaultICGenerator.cc:652
NetlistPort.hh
DefaultICGenerator::inputSocketBusPort
static std::string inputSocketBusPort(int bus)
Definition: DefaultICGenerator.cc:2269
__func__
#define __func__
Definition: Application.hh:67
DefaultICGenerator::simmSocket
static std::string simmSocket(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:2390
TTAMachine::Socket
Definition: Socket.hh:53
NetlistBlock.hh
DefaultICGenerator::altSignalMap_
BusAltSignalMap altSignalMap_
Signal numbers for controlling sockets.
Definition: DefaultICGenerator.hh:208
DefaultICGenerator::busMuxDataPort
static std::string busMuxDataPort(const TTAMachine::Bus &bus, int index)
Definition: DefaultICGenerator.cc:2298
ProGe::BIT
@ BIT
One bit.
Definition: ProGeTypes.hh:47
VHDLNetlistWriter.hh
DefaultICGenerator::busWidthGeneric
static std::string busWidthGeneric(int bus)
Definition: DefaultICGenerator.cc:2366
DefaultICGenerator::generatedInputSockets_
std::set< std::pair< int, int > > generatedInputSockets_
Definition: DefaultICGenerator.hh:221
Machine.hh
TTAMachine::Machine::socketNavigator
virtual SocketNavigator socketNavigator() const
Definition: Machine.cc:368
DefaultICGenerator::outputSockets
static std::set< TTAMachine::Socket * > outputSockets(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:1954
TTAMachine::Segment::connection
const Connection & connection(const Socket &socket) const
Definition: Segment.cc:250
FileSystem::createFile
static bool createFile(const std::string &file)
Definition: FileSystem.cc:468
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
VerilogNetlistWriter.hh
DefaultICGenerator::writeInputSocketComponentDeclaration
static void writeInputSocketComponentDeclaration(const ProGe::HDL language, int segmentConns, int ind, std::ostream &stream)
Definition: DefaultICGenerator.cc:1593
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
ProGe::OUT
@ OUT
Output port.
Definition: ProGeTypes.hh:54
DefaultICGenerator::socketBusControlPort
static std::string socketBusControlPort(const std::string &name)
Definition: DefaultICGenerator.cc:2220
DefaultICGenerator::~DefaultICGenerator
virtual ~DefaultICGenerator()
Definition: DefaultICGenerator.cc:91
DefaultICGenerator::generateSocketsAndMuxes
void generateSocketsAndMuxes(const std::string &dstDirectory)
Definition: DefaultICGenerator.cc:388
CentralizedControlICGenerator::setGlockPort
void setGlockPort(ProGe::NetlistPort &glockPort)
Definition: CentralizedControlICGenerator.cc:224
TTAMachine::Component::ComponentNameComparator
Definition: MachinePart.hh:127
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
DefaultICGenerator::icBlock_
ProGe::NetlistBlock * icBlock_
The netlist block of IC.
Definition: DefaultICGenerator.hh:206
DefaultICGenerator::SetHDL
void SetHDL(ProGe::HDL language)
Definition: DefaultICGenerator.cc:103
ProGe::NetlistGenerator
Definition: NetlistGenerator.hh:84
DefaultICGenerator::writeInterconnectionNetwork
void writeInterconnectionNetwork(std::ostream &stream)
Definition: DefaultICGenerator.cc:947
DefaultICGenerator::isBusConnected
static bool isBusConnected(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:1913
DefaultICGenerator::convertDirection
static ProGe::Direction convertDirection(TTAMachine::Socket::Direction direction)
Definition: DefaultICGenerator.cc:2416
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
ProGe::NetlistBlock::addSubBlock
void addSubBlock(BaseNetlistBlock *subBlock, const std::string &instanceName="")
Definition: BaseNetlistBlock.cc:405
CentralizedControlICGenerator::mapSImmDataPort
void mapSImmDataPort(const std::string &busName, ProGe::NetlistPort &port)
Definition: CentralizedControlICGenerator.cc:156
ProGe
Definition: FUGen.hh:54
DefaultICGenerator::writeOutputSocketComponentDeclaration
static void writeOutputSocketComponentDeclaration(const ProGe::HDL language, int portConns, int segmentConns, int ind, std::ostream &stream)
Definition: DefaultICGenerator.cc:1478
DefaultICGenerator::generatedOutputSockets_
std::set< std::pair< int, int > > generatedOutputSockets_
Definition: DefaultICGenerator.hh:220
AssocTools.hh
INPUT_SOCKET_DATA_PORT
const string INPUT_SOCKET_DATA_PORT
Definition: DefaultICGenerator.cc:70
DefaultICGenerator::setBusTraceStartingCycle
void setBusTraceStartingCycle(unsigned int cycle)
Definition: DefaultICGenerator.cc:348
DefaultICGenerator::machine_
const TTAMachine::Machine & machine_
The machine.
Definition: DefaultICGenerator.hh:204
MathTools::bitLength
static unsigned int bitLength(long unsigned int number)
ControlUnit.hh
UNKNOWN
@ UNKNOWN
Definition: MemoryGenerator.hh:58
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
SpecialRegisterPort.hh
TTAMachine::Socket::hasDataPortWidth
bool hasDataPortWidth() const
Definition: Socket.cc:410
DefaultICGenerator::entityNameStr_
TCEString entityNameStr_
Definition: DefaultICGenerator.hh:215
DefaultICGenerator::verifyCompatibility
void verifyCompatibility() const
Definition: DefaultICGenerator.cc:306
DefaultICGenerator::simmPortWidth
static int simmPortWidth(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:2170
DefaultICGenerator::indentation
static std::string indentation(unsigned int level)
Definition: DefaultICGenerator.cc:2513
ProGe::HDL
HDL
HDLs supported by ProGe.
Definition: ProGeTypes.hh:40
ProGe::NetlistPort
Definition: NetlistPort.hh:70
ProGe::NetlistGenerator::netlistPort
NetlistPort & netlistPort(const TTAMachine::Port &port, Direction dir=IN) const
Definition: NetlistGenerator.cc:247
ProGe::BaseNetlistBlock::moduleName
const std::string & moduleName() const
Definition: BaseNetlistBlock.cc:140
DefaultICGenerator::language_
ProGe::HDL language_
Definition: DefaultICGenerator.hh:216
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
DefaultICGenerator::outputSocketCntrlPinForSegment
virtual int outputSocketCntrlPinForSegment(const TTAMachine::Socket &socket, const TTAMachine::Segment &segment) const
Definition: DefaultICGenerator.cc:364
CentralizedControlICGenerator::mapSImmCntrlPort
void mapSImmCntrlPort(const std::string &busName, ProGe::NetlistPort &port)
Definition: CentralizedControlICGenerator.cc:174
IOException
Definition: Exception.hh:130
TTAMachine::Socket::segmentCount
int segmentCount() const
DefaultICGenerator::maxOutputSocketDataPortWidth
static int maxOutputSocketDataPortWidth(const TTAMachine::Socket &socket)
Definition: DefaultICGenerator.cc:2106
MathTools.hh
TTAMachine
Definition: Assembler.hh:48
TTAMachine::ControlUnit::returnAddressPort
SpecialRegisterPort * returnAddressPort() const
Definition: ControlUnit.cc:307
DefaultICGenerator::outputSocketDataControlValue
virtual int outputSocketDataControlValue(const TTAMachine::Socket &socket, const TTAMachine::Port &port) const
Definition: DefaultICGenerator.cc:2016
DefaultICGenerator::generateInterconnectionNetwork
void generateInterconnectionNetwork(const std::string &dstDirectory)
Definition: DefaultICGenerator.cc:283
DS
#define DS
Definition: LLVMBackend.cc:124
DefaultICGenerator::outputSocketBusPort
static std::string outputSocketBusPort(int bus)
Definition: DefaultICGenerator.cc:2281
DefaultICGenerator::busControlWidth
static int busControlWidth(TTAMachine::Socket::Direction direction, int busConns)
Definition: DefaultICGenerator.cc:2129
DefaultICGenerator::inputMuxEntityName
std::string inputMuxEntityName(int conns) const
Definition: DefaultICGenerator.cc:2483
DefaultICGenerator::inputSockets
static std::set< TTAMachine::Socket * > inputSockets(const TTAMachine::Bus &bus)
Definition: DefaultICGenerator.cc:1932
ProGe::Direction
Direction
Direction of the port.
Definition: ProGeTypes.hh:52
DefaultICGenerator::setExportBustrace
void setExportBustrace(bool export_bt)
Definition: DefaultICGenerator.cc:327
DefaultICGenerator::busTraceStartingCycle_
unsigned int busTraceStartingCycle_
The starting cycle for bus tracing.
Definition: DefaultICGenerator.hh:214
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
ProGe::NetlistBlock::port
virtual NetlistPort * port(const std::string &portName, bool partialMatch=true)
Definition: NetlistBlock.cc:97
TTAMachine::Bus::segmentCount
virtual int segmentCount() const
Definition: Bus.cc:385
ProGe::IN
@ IN
Input port.
Definition: ProGeTypes.hh:53
TTAMachine::ControlUnit::hasReturnAddressPort
bool hasReturnAddressPort() const
Definition: ControlUnit.cc:295
DefaultICGenerator::inputSocketDataPort
static std::string inputSocketDataPort(const std::string &socket)
Definition: DefaultICGenerator.cc:2190
NetlistGenerator.hh
TTAMachine::Socket::setDataPortWidth
void setDataPortWidth(const std::string &width)
Definition: Socket.cc:420
TTAMachine::Machine
Definition: Machine.hh:73
DefaultICGenerator::outputSocketDataPortWidth
static int outputSocketDataPortWidth(const TTAMachine::Socket &socket, int port)
Definition: DefaultICGenerator.cc:2090