OpenASIP  2.0
DefaultDecoderGenerator.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 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 DefaultDecoderGenerator.cc
26  *
27  * Implementation of DefaultDecoderGenerator class.
28  *
29  * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30  * @author Vinogradov Viacheslav(added Verilog generating) 2012
31  * @note rating: red
32  */
33 #include <string>
34 #include <fstream>
35 #include <iostream>
36 #include <algorithm>
37 #include <set>
38 #include <boost/format.hpp>
39 
42 
43 #include "NetlistBlock.hh"
44 #include "NetlistGenerator.hh"
45 #include "NetlistPort.hh"
46 #include "Netlist.hh"
47 #include "VHDLNetlistWriter.hh"
48 #include "VerilogNetlistWriter.hh"
49 #include "CUOpcodeGenerator.hh"
50 
51 #include "Machine.hh"
52 #include "MachineInfo.hh"
53 #include "Bus.hh"
54 #include "Segment.hh"
55 #include "Socket.hh"
56 #include "Guard.hh"
57 #include "FUPort.hh"
58 #include "SpecialRegisterPort.hh"
59 #include "ControlUnit.hh"
60 #include "HWOperation.hh"
61 
62 #include "BinaryEncoding.hh"
63 #include "LImmDstRegisterField.hh"
64 #include "MoveSlot.hh"
65 #include "SourceField.hh"
66 #include "DestinationField.hh"
67 #include "GuardField.hh"
68 #include "SocketEncoding.hh"
69 #include "ImmediateEncoding.hh"
70 #include "SocketCodeTable.hh"
71 #include "ImmediateSlotField.hh"
72 #include "ImmediateControlField.hh"
73 #include "GPRGuardEncoding.hh"
74 #include "FUGuardEncoding.hh"
76 #include "FUPortCode.hh"
77 #include "RFPortCode.hh"
78 #include "IUPortCode.hh"
79 #include "NOPEncoding.hh"
80 #include "BEMTools.hh"
81 
82 #include "FUEntry.hh"
83 #include "FUImplementation.hh"
84 
85 #include "RFEntry.hh"
86 #include "RFImplementation.hh"
87 
88 #include "FileSystem.hh"
89 #include "MathTools.hh"
90 #include "AssocTools.hh"
91 #include "StringTools.hh"
92 #include "TCEString.hh"
93 #include "Conversion.hh"
94 #include "MapTools.hh"
95 
96 using namespace ProGe;
97 using namespace TTAMachine;
98 using namespace HDB;
99 
100 using std::string;
101 using std::endl;
102 using std::set;
103 using boost::format;
104 
105 const string LIMM_TAG_SIGNAL = "limm_tag";
106 const string GLOCK_PORT_NAME = "glock";
107 const string LOCK_REQ_PORT_NAME = "lock_req";
108 const string INTERNAL_MERGED_GLOCK_REQ_SIGNAL = "merged_glock_req";
109 const string PRE_DECODE_MERGED_GLOCK_SIGNAL = "pre_decode_merged_glock";
110 const string POST_DECODE_MERGED_GLOCK_SIGNAL = "post_decode_merged_glock";
111 const string POST_DECODE_MERGED_GLOCK_OUTREG = "post_decode_merged_glock_r";
112 const string PIPELINE_FILL_LOCK_SIGNAL = "decode_fill_lock_reg";
113 
114 const string JUMP = "jump";
115 const string CALL = "call";
116 const string BZ = "bz";
117 const string BNZ = "bnz";
118 const string BZ1 = "bz1";
119 const string BNZ1 = "bnz1";
120 const string BEQ = "beq";
121 const string BGE = "bge";
122 const string BGEU = "bgeu";
123 const string BGT = "bgt";
124 const string BGTU = "bgtu";
125 const string BLE = "ble";
126 const string BLEU = "bleu";
127 const string BLT = "blt";
128 const string BLTU = "bltu";
129 const string BNE = "bne";
130 const string JUMPR = "jumpr";
131 const string CALLR = "callr";
132 const string CALLA = "calla";
133 const string BEQR = "beqr";
134 const string BNER = "bner";
135 const string BGTR = "bgtr";
136 const string BLTR = "bltr";
137 const string BGTUR = "bgtur";
138 const string BLTUR = "bltur";
139 const string BLER = "bler";
140 const string BGER = "bger";
141 const string BLEUR = "bleur";
142 const string BGEUR = "bgeur";
143 const string APC = "apc";
144 
145 const string DefaultDecoderGenerator::RISCV_SIMM_PORT_IN_NAME = "simm_in";
146 const string DefaultDecoderGenerator::GLOCK_PORT_NAME = "glock";
147 
148 /**
149  * The constructor.
150  *
151  * @param machine The machine.
152  * @param bem The binary encoding map.
153  * @param icGenerator The IC generator.
154  */
156  const TTAMachine::Machine& machine, const BinaryEncoding& bem,
157  const CentralizedControlICGenerator& icGenerator)
158  : machine_(machine),
159  bem_(bem),
160  icGenerator_(icGenerator),
161  nlGenerator_(NULL),
162  decoderBlock_(NULL),
163  generateLockTrace_(false),
164  language_(VHDL),
165  generateDebugger_(false),
166  lockTraceStartingCycle_(1),
167  generateAlternateGlockReqHandling_(false),
168  unitGlockBitMap_(),
169  unitGlockReqBitMap_() {}
170 
171 /**
172  * SetHDL.
173  *
174  * @param language The HDL language.
175  */
176 void
178  language_=language;
179 }
180 
181 void
183  generateDebugger_ = generate;
184 }
185 
186 void
188  syncReset_ = value;
189 }
190 
191 void
193  generateBusEnable_ = value;
194 }
195 
196 /**
197  * Generates alternate global lock wiring where FU will not receive global
198  * lock back if the FU did request the lock unless there are other FUs
199  * requesting global lock.
200  *
201  * @param generate Set to true enables the feature.
202  */
203 void
206 }
207 
208 /**
209  * The destructor.
210  */
212 }
213 
214 /**
215  * Completes the decoder block in the given netlist block representing the
216  * TTA core by adding the IC-interface and connecting the decoder to the
217  * interconnection network and machine building units.
218  *
219  * @param nlGenerator The netlist generator that generated the netlist.
220  * @param coreBlock The netlist block that contains the decoder.
221  */
222 void
224  const ProGe::NetlistGenerator& nlGenerator,
225  ProGe::NetlistBlock& coreBlock) {
226  nlGenerator_ = &nlGenerator;
227  NetlistBlock& decoder = nlGenerator.instructionDecoder();
228  decoderBlock_ = &decoder;
229 
230  entityNameStr_ = coreBlock.moduleName();
231 
232  // add ports for short immediates to decoder and connect them to IC
234  for (int i = 0; i < busNav.count(); i++) {
235  Bus* bus = busNav.item(i);
236  if (bus->immediateWidth() > 0) {
237  NetlistPort& icSimmPort = icGenerator_.simmDataPort(
238  bus->name());
239  NetlistPort& icSimmCntrlPort = icGenerator_.
240  simmCntrlPort(bus->name());
241  NetlistPort* decSimmPort = new NetlistPort(
242  simmDataPort(bus->name()),
244  simmPortWidth(*bus), ProGe::BIT_VECTOR, ProGe::OUT, decoder);
245  coreBlock.netlist().connect(*decSimmPort, icSimmPort);
246  NetlistPort* decSimmCntrlPort = new NetlistPort(
247  simmControlPort(bus->name()), "1", 1, ProGe::BIT_VECTOR,
248  ProGe::OUT, decoder);
249  coreBlock.netlist().connect(*decSimmCntrlPort, icSimmCntrlPort);
250  }
251  }
252 
253  // add socket control ports to decoder and connect them to IC
255  for (int i = 0; i < socketNav.count(); i++) {
256  Socket* socket = socketNav.item(i);
257  if ((socket->portCount() == 0 || socket->segmentCount() == 0) &&
258  (socket->direction() == Socket::OUTPUT)) {
259  continue;
260  }
261  if (needsBusControl(*socket)) {
262  NetlistPort* busCntrlPort = new NetlistPort(
263  socketBusControlPort(socket->name()),
266  decoder);
268  socket->name());
269  coreBlock.netlist().connect(icBusCntrlPort, *busCntrlPort);
270  }
271  if (needsDataControl(*socket)) {
272  NetlistPort* dataCntrlPort = new NetlistPort(
273  socketDataControlPort(socket->name()),
276  decoder);
277  NetlistPort& icDataCntrlPort =
279  coreBlock.netlist().connect(icDataCntrlPort, *dataCntrlPort);
280  }
281  }
282 
283  // add FU control ports to decoder and connect them to the FUs
286  for (int i = 0; i < fuNav.count(); i++) {
287  FunctionUnit* fu = fuNav.item(i);
288  for (int i = 0; i < fu->portCount(); i++) {
289  BaseFUPort* port = fu->port(i);
290  NetlistPort& nlPort = nlGenerator.netlistPort(*port);
291  if (nlPort.direction() == ProGe::IN) {
292  NetlistPort& loadPort = nlGenerator.loadPort(nlPort);
293  NetlistPort* loadCntrlPort = new NetlistPort(
294  fuLoadCntrlPort(fu->name(), port->name()), "1", 1,
295  ProGe::BIT, ProGe::OUT, decoder);
296  coreBlock.netlist().connect(*loadCntrlPort, loadPort);
297  }
298  }
299 
300  if (opcodeWidth(*fu) > 0) {
301  const NetlistBlock& fuBlock = nlGenerator.netlistBlock(*fu);
302  NetlistPort& opcodePort = nlGenerator.fuOpcodePort(fuBlock);
303  NetlistPort* opcodeCntrlPort = new NetlistPort(
304  fuOpcodeCntrlPort(fu->name()),
306  ProGe::BIT_VECTOR, ProGe::OUT, decoder);
307  coreBlock.netlist().connect(opcodePort, *opcodeCntrlPort);
308  }
309  }
310  // Add GCU control ports for operand ports (other than RA ports).
312  for (int i = 0; i < gcu->portCount(); i++) {
313  BaseFUPort* port = gcu->port(i);
314  if (!port->isInput() ||
315  port->name() == gcu->returnAddressPort()->name() ||
316  port->isTriggering()) {
317  continue;
318  }
319  NetlistPort& nlPort = nlGenerator.netlistPort(*port);
320  NetlistPort& loadPort = nlGenerator.loadPort(nlPort);
321  NetlistPort* loadCntrlPort = new NetlistPort(
322  fuLoadCntrlPort(gcu->name(), port->name()), "1", 1, ProGe::BIT,
323  ProGe::OUT, decoder);
324  coreBlock.netlist().connect(*loadCntrlPort, loadPort);
325  }
326 
327  // add RF control ports to decoder and connect them to the RFs
330  for (int i = 0; i < rfNav.count(); i++) {
331  RegisterFile* rf = rfNav.item(i);
332  for (int i = 0; i < rf->portCount(); i++) {
333  RFPort* port = rf->port(i);
334  NetlistPort& nlPort = nlGenerator.netlistPort(*port);
335  NetlistPort& loadPort = nlGenerator.loadPort(nlPort);
336 
337  NetlistPort* loadCntrlPort = new NetlistPort(
338  rfLoadCntrlPort(rf->name(), port->name()),
339  loadPort.widthFormula(), 1, ProGe::BIT, ProGe::OUT, decoder);
340 
341  coreBlock.netlist().connect(loadPort, *loadCntrlPort);
342 
343  int opcodeWidth = rfOpcodeWidth(*rf);
344  assert(!(!nlGenerator.hasOpcodePort(nlPort) &&
345  opcodeWidth > 1));
346  if (nlGenerator.hasOpcodePort(nlPort) && opcodeWidth >= 0) {
347  NetlistPort& opcodePort = nlGenerator.rfOpcodePort(nlPort);
348  NetlistPort* opcodeCntrlPort = new NetlistPort(
349  rfOpcodeCntrlPort(rf->name(), port->name()),
351  ProGe::BIT_VECTOR, ProGe::OUT, decoder);
352  coreBlock.netlist().connect(opcodePort, *opcodeCntrlPort);
353  }
354  }
355  }
356 
357  // add IU control ports to decoder and connect them to the IU's
360  for (int i = 0; i < iuNav.count(); i++) {
361  ImmediateUnit* iu = iuNav.item(i);
362 
363  // add control ports for read ports
364  for (int i = 0; i < iu->portCount(); i++) {
365  RFPort* port = iu->port(i);
366  NetlistPort& iuDataPort = nlGenerator.netlistPort(*port);
367  NetlistPort& loadPort = nlGenerator.loadPort(iuDataPort);
368  std::string portName =
369  iuReadLoadCntrlPort(iu->name(), port->name());
370  NetlistPort* loadCntrlPort = new NetlistPort(
371  portName, "1", 1, ProGe::BIT, ProGe::OUT, decoder);
372  coreBlock.netlist().connect(loadPort, *loadCntrlPort);
373 
374  int opcodeWidth = rfOpcodeWidth(*iu);
375  assert(!(!nlGenerator.hasOpcodePort(iuDataPort) &&
376  opcodeWidth > 1));
377  if (nlGenerator.hasOpcodePort(iuDataPort) && opcodeWidth >= 0) {
378  NetlistPort& opcodePort = nlGenerator.rfOpcodePort(
379  iuDataPort);
380  portName = iuReadOpcodeCntrlPort(iu->name(), port->name());
381  NetlistPort* opcodeCntrlPort = new NetlistPort(
383  ProGe::BIT_VECTOR, ProGe::OUT, decoder);
384  coreBlock.netlist().connect(opcodePort, *opcodeCntrlPort);
385  }
386  }
387 
388  // add IU data write port and control ports
389  NetlistPort& iuDataPort = nlGenerator.immediateUnitWritePort(*iu);
390  NetlistPort* decIUDataPort = new NetlistPort(
392  iu->width(), ProGe::BIT_VECTOR, ProGe::OUT, decoder);
393  coreBlock.netlist().connect(iuDataPort, *decIUDataPort);
394  NetlistPort& loadPort = nlGenerator.loadPort(iuDataPort);
395  NetlistPort* loadCntrlPort = new NetlistPort(
397  decoder);
398  coreBlock.netlist().connect(loadPort, *loadCntrlPort);
399 
400  int opcodeWidth = rfOpcodeWidth(*iu);
401  if (nlGenerator.hasOpcodePort(iuDataPort) && opcodeWidth >= 0) {
402  NetlistPort& opcodePort = nlGenerator.rfOpcodePort(iuDataPort);
403  NetlistPort* opcodeCntrlPort = new NetlistPort(
406  ProGe::BIT_VECTOR, ProGe::OUT, decoder);
407  coreBlock.netlist().connect(opcodePort, *opcodeCntrlPort);
408  }
409  }
410 
411  // add guard ports to decoder and connect them to RF's and FU's
412  std::set<PortGuard*> generatedPortGuards;
413  std::set<RegisterGuard*> generatedRegGuards;
414  for (int i = 0; i < busNav.count(); i++) {
415  Bus* bus = busNav.item(i);
416  for (int i = 0; i < bus->guardCount(); i++) {
417  Guard* guard = bus->guard(i);
418  PortGuard* portGuard = dynamic_cast<PortGuard*>(guard);
419  RegisterGuard* regGuard = dynamic_cast<RegisterGuard*>(guard);
420  if (portGuard != NULL) {
422  generatedPortGuards, *portGuard)) {
423  continue;
424  }
425  FUPort* port = portGuard->port();
426  NetlistPort& nlPort = nlGenerator.netlistPort(*port);
427  NetlistPort& nlGuardPort = nlGenerator.fuGuardPort(
428  nlPort);
429  NetlistPort* decGuardPort = new NetlistPort(
430  guardPortName(*guard), "1", 1, ProGe::BIT, ProGe::IN,
431  decoder);
432  coreBlock.netlist().connect(nlGuardPort, *decGuardPort);
433  generatedPortGuards.insert(portGuard);
434  } else if (regGuard != NULL) {
436  generatedRegGuards, *regGuard)) {
437  continue;
438  }
439  const RegisterFile* rf = regGuard->registerFile();
440  assert(rf->portCount() > 0);
441  const NetlistBlock& nlRf = nlGenerator.netlistBlock(*rf);
442  NetlistPort& nlGuardPort = nlGenerator.rfGuardPort(nlRf);
443  NetlistPort* decGuardPort = new NetlistPort(
444  guardPortName(*guard), "1", 1, ProGe::BIT, ProGe::IN,
445  decoder);
446  coreBlock.netlist().connect(
447  nlGuardPort, *decGuardPort, regGuard->registerIndex(), 0,
448  1);
449  generatedRegGuards.insert(regGuard);
450  }
451  }
452  }
453 
456 
457  if (generateDebugger_) {
458  /*NetlistPort* dbgResetPort = */ new NetlistPort(
459  "db_tta_nreset", "1", 1, ProGe::BIT, ProGe::IN, decoder);
460  }
461 }
462 
463 /**
464  * Adds the lock request input port to decoder and connects the global lock
465  * request ports of FU's to it.
466  */
467 void
469 
470  int lockReqWidth = glockRequestWidth();
471 
472  if (lockReqWidth == 0) {
473  return;
474  }
475 
477  Netlist& netlist = decoderBlock_->parentBlock().netlist();
478 
479  // add lock request port to decoder
480  NetlistPort* lockReqPort = new NetlistPort(
481  LOCK_REQ_PORT_NAME, Conversion::toString(lockReqWidth), lockReqWidth,
483 
484  // connect the glock request ports of FUs to the lock request port
485  int bitToConnect(0);
486  for (int i = 0; i < fuNav.count(); i++) {
487  FunctionUnit* fu = fuNav.item(i);
488  if (fu->portCount() == 0) {
489  continue;
490  }
491  const NetlistBlock& fuBlock = nlGenerator_->netlistBlock(*fu);
492  if (nlGenerator_->hasGlockReqPort(fuBlock)) {
493  NetlistPort& glockReqPort = nlGenerator_->glockReqPort(fuBlock);
494  netlist.connect(*lockReqPort, glockReqPort, bitToConnect, 0, 1);
495  unitGlockReqBitMap_[fu] = bitToConnect;
496  bitToConnect++;
497  }
498  }
499 }
500 
501 /**
502  * Adds the global lock port to decoder and connects it to the glock ports
503  * of units.
504  *
505  * Precondition: addLockReqPortToDecoder() must be called before this.
506  */
507 void
509  int glockWidth = glockPortWidth();
510 
511  if (glockWidth == 0) {
512  return;
513  }
514  int bitToConnect = 0;
515 
517  Netlist& netlist = decoderBlock_->parentBlock().netlist();
518  NetlistPort* decGlockPort = new NetlistPort(
519  GLOCK_PORT_NAME, Conversion::toString(glockWidth), glockWidth,
521 
523  for (int i = 0; i < fuNav.count(); i++) {
524  FunctionUnit* fu = fuNav.item(i);
525  if (fu->portCount() == 0) {
526  continue;
527  }
528  const NetlistBlock& fuBlock = nlGenerator_->netlistBlock(*fu);
529  if (nlGenerator_->hasGlockPort(fuBlock)) {
530  NetlistPort& glockPort = nlGenerator_->glockPort(fuBlock);
531  assert(bitToConnect < glockWidth);
532  netlist.connect(*decGlockPort, glockPort, bitToConnect, 0, 1);
533  unitGlockBitMap_[bitToConnect] = fu;
534  bitToConnect++;
535  }
536  }
537 
539  for (int i = 0; i < rfNav.count(); i++) {
540  RegisterFile* rf = rfNav.item(i);
541  if (rf->portCount() == 0) {
542  continue;
543  }
544  const NetlistBlock& rfBlock = nlGenerator_->netlistBlock(*rf);
545  if (nlGenerator_->hasGlockPort(rfBlock)) {
546  NetlistPort& glockPort = nlGenerator_->glockPort(rfBlock);
547  assert(bitToConnect < glockWidth);
548  netlist.connect(*decGlockPort, glockPort, bitToConnect, 0, 1);
549  unitGlockBitMap_[bitToConnect] = rf;
550  bitToConnect++;
551  }
552  }
553 
555  for (int i = 0; i < iuNav.count(); i++) {
556  ImmediateUnit* iu = iuNav.item(i);
557  if (iu->portCount() == 0) {
558  continue;
559  }
560  const NetlistBlock& iuBlock = nlGenerator_->netlistBlock(*iu);
561  if (nlGenerator_->hasGlockPort(iuBlock)) {
562  NetlistPort& glockPort = nlGenerator_->glockPort(iuBlock);
563  assert(bitToConnect < glockWidth);
564  netlist.connect(*decGlockPort, glockPort, bitToConnect, 0, 1);
565  unitGlockBitMap_[bitToConnect] = iu;
566  bitToConnect++;
567  }
568  }
569 
570  // If IC requests glock port.
571  if (icGenerator_.hasGlockPort()) {
572  netlist.connect(
573  *decGlockPort, icGenerator_.glockPort(), bitToConnect, 0, 1);
574  bitToConnect++;
575  }
576 }
577 
578 
579 /**
580  * Returns the width of the global lock request port.
581  *
582  * @return The bit width.
583  */
584 int
586 
588 
589  int lockReqWidth(0);
590  for (int i = 0; i < fuNav.count(); i++) {
591  FunctionUnit* fu = fuNav.item(i);
592  if (fu->portCount() == 0) {
593  continue;
594  }
595  const NetlistBlock& fuBlock = nlGenerator_->netlistBlock(*fu);
596  if (nlGenerator_->hasGlockReqPort(fuBlock)) {
597  lockReqWidth++;
598  }
599  }
600  if (generateDebugger_) {
601  lockReqWidth++;
602  }
603 
604  return lockReqWidth;
605 }
606 
607 /**
608  * Returns the width of the global lock port.
609  *
610  * @return The bit width.
611  */
612 int
614  int glockWidth = 0;
615 
617  for (int i = 0; i < fuNav.count(); i++) {
618  FunctionUnit* fu = fuNav.item(i);
619  if (fu->portCount() == 0) {
620  continue;
621  }
622  const NetlistBlock& fuBlock = nlGenerator_->netlistBlock(*fu);
623  if (nlGenerator_->hasGlockPort(fuBlock)) {
624  glockWidth++;
625  }
626  }
627 
629  for (int i = 0; i < rfNav.count(); i++) {
630  RegisterFile* rf = rfNav.item(i);
631  if (rf->portCount() == 0) {
632  continue;
633  }
634  const NetlistBlock& rfBlock = nlGenerator_->netlistBlock(*rf);
635  if (nlGenerator_->hasGlockPort(rfBlock)) {
636  glockWidth++;
637  }
638  }
639 
641  for (int i = 0; i < iuNav.count(); i++) {
642  ImmediateUnit* iu = iuNav.item(i);
643  if (iu->portCount() == 0) {
644  continue;
645  }
646  const NetlistBlock& iuBlock = nlGenerator_->netlistBlock(*iu);
647  if (nlGenerator_->hasGlockPort(iuBlock)) {
648  glockWidth++;
649  }
650  }
651 
652  if (icGenerator_.hasGlockPort()) {
653  glockWidth++;
654  }
655 
656  return glockWidth;
657 }
658 
659 /**
660  * Writes the instruction decoder to the given destination directory.
661  *
662  * @param dstDirectory The destination directory.
663  * @exception IOException If an IO error occurs.
664  */
665 void
667  const ProGe::NetlistGenerator& nlGenerator,
668  const std::string& dstDirectory) {
669  nlGenerator_ = &nlGenerator;
670 
671  string iDecoderFile = dstDirectory
673  + ((language_==Verilog)?"decoder.v":"decoder.vhdl");
674  bool decCreated = FileSystem::createFile(iDecoderFile);
675  if (!decCreated) {
676  string errorMsg = "Unable to create file " + iDecoderFile;
677  throw IOException(__FILE__, __LINE__, __func__, errorMsg);
678  }
679  std::ofstream decoderStream(
680  iDecoderFile.c_str(), std::ofstream::out);
681  writeInstructionDecoder(decoderStream);
682  decoderStream.close();
683 }
684 
685 /**
686  * Returns the set of acceptable latencies of the hardware implementation
687  * of the given immediate unit.
688  *
689  * @param iu The immediate unit.
690  */
691 std::set<int>
693  const TTAMachine::ImmediateUnit& /*iu*/) const {
694  int acceptableLatencies[] = {0, 1};
695  return std::set<int>(acceptableLatencies, acceptableLatencies + 2);
696 }
697 
698 /**
699  * Verifies that the decoder generator is compatible with the machine.
700  *
701  * @exception InvalidData If the decoder generator is incompatible.
702  */
703 void
705  // check that the GCU does not have other operations than the ones
706  // specified below.
708  assert(cu != NULL);
710  MachineInfo::OperationSet supportedOps{JUMP, CALL};
712  BLTUR, BGER, BGEUR, APC, CALLR};
713  MachineInfo::OperationSet unsupportedOps;
714  if (machine_.isRISCVMachine()) {
715  supportedOps.insert(riscvOps.begin(), riscvOps.end());
716  }
717  std::set_difference(
718  cuOps.begin(), cuOps.end(), supportedOps.begin(), supportedOps.end(),
719  std::inserter(unsupportedOps, unsupportedOps.begin()));
720  if (!unsupportedOps.empty()) {
721  format errorMsg(
722  "Decoder generator does not support operation %1% in CU.");
723  errorMsg % TCEString::makeString(unsupportedOps, ", ");
724  THROW_EXCEPTION(InvalidData, errorMsg.str());
725  }
726 
727  if (machine_.hasOperation(APC) &&
729  string errorMsg =
730  TCEString("APC operation requires an output port in the GCU");
731  throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
732  }
733  // check that there are 3 delay slots in the transport pipeline
734  // RISC-V supports 2 "delay slots"
735  if (cu->delaySlots() != 3 &&
736  (!(cu->delaySlots() == 2 && machine_.isRISCVMachine()))) {
737  throw InvalidData(
738  __FILE__, __LINE__, __func__,
739  TCEString("Decoder generator supports only 4-stage transport ") +
740  "pipeline of CU. Given machine has " +
741  Conversion::toString(cu->delaySlots() + 1) + " stages");
742  }
743 
744  // check that global guard latency is 1
745  if (!(cu->globalGuardLatency() == 0 || (cu->globalGuardLatency() == 1))) {
746  string errorMsg = TCEString("Decoder generator supports only ") +
747  "global guard latency of 1. Given machine has " +
749  throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
750  }
751 }
752 
753 /**
754  * Controls whenever global lock trace dump process will be generated.
755  *
756  * @param generate Generate lock trace process if true.
757  */
758 void
760  generateLockTrace_ = generate;
761 }
762 
763 /**
764  * Sets starting cycle to begin global lock tracing.
765  *
766  * @param startCycle nth cycle to begin tracing.
767  */
768 void
770  lockTraceStartingCycle_ = startCycle;
771 }
772 
773 void
775  std::ostream& stream, ProGe::DataType type, std::string sigName,
776  int width) const {
777  if (language_ == VHDL) {
778  stream << indentation(1) << "signal " << sigName;
779  if (type == ProGe::BIT_VECTOR) {
780  stream << " : std_logic_vector(" << width - 1 << " downto 0);"
781  << endl;
782  } else { // BIT
783  stream << " : std_logic;" << endl;
784  }
785  } else { // Verilog
786  stream << indentation(1) << "reg";
787  if (type == ProGe::BIT_VECTOR) {
788  stream << "[" << width - 1 << ":0]";
789  }
790  stream << " " << sigName << ";" << endl;
791  }
792 }
793 
794 void
796  std::ostream& stream, int indent, std::string comment) const {
797  std::string delim = language_ == VHDL ? "-- " : "// ";
798  stream << indentation(indent) << delim << comment << endl;
799 }
800 
801 /**
802  * Writes the instruction decoder to the given stream.
803  *
804  * @param stream The stream.
805  */
806 void
808  if (language_ == VHDL) {
809  stream << "library IEEE;" << endl;
810  stream << "use IEEE.std_logic_1164.all;" << endl;
811  stream << "use IEEE.std_logic_arith.all;" << endl;
812  if (generateLockTrace_) {
813  stream << "use STD.textio.all;" << endl;
814  }
815  stream << "use work." << entityNameStr_ << "_globals.all;" << endl;
816  stream << "use work." << entityNameStr_ << "_gcu_opcodes.all;"
817  << endl;
818  stream << "use work.tce_util.all;" << endl << endl;
819 
820  string entityName = entityNameStr_ + "_decoder";
821  stream << "entity " << entityName << " is" << endl << endl;
822 
823  // create generic and port declarations
824  VHDLNetlistWriter::writeGenericDeclaration(
825  *decoderBlock_, 1, indentation(1), stream);
826  VHDLNetlistWriter::writePortDeclaration(
827  *decoderBlock_, 1, indentation(1), stream);
828 
829  stream << endl;
830  stream << "end " << entityName << ";" << endl << endl;
831  string architectureName = "rtl_andor";
832  stream << "architecture " << architectureName << " of " << entityName
833  << " is" << endl << endl;
834 
835  writeMoveFieldSignals(stream);
836  stream << endl;
838  stream << endl;
840  stream << endl;
841  writeSquashSignals(stream);
842  stream << endl;
843  writeSocketCntrlSignals(stream);
844  stream << endl;
845  writeFUCntrlSignals(stream);
846  stream << endl;
847  writeRFCntrlSignals(stream);
848  stream << endl;
850  stream << endl;
851  writePipelineFillSignals(stream);
852 
853  stream << "begin" << endl << endl;
854 
855  if (generateLockTrace_) {
856  writeLockDumpCode(stream);
857  stream << endl;
858  }
859 
861  stream << endl;
863  stream << endl;
865  stream << endl;
867  stream << endl;
869  stream << endl;
870  writeMainDecodingProcess(stream);
871  stream << endl;
872  writeGlockMapping(stream);
873  stream << endl;
874  writePipelineFillProcess(stream);
875 
876  stream << endl << "end " << architectureName << ";" << endl;
877  } else { //language_ == Verilog
878  const std::string DS = FileSystem::DIRECTORY_SEPARATOR;
879  string entityName = entityNameStr_ + "_decoder";
880  stream << "`timescale 1ns/1ns" << endl
881  << "module " << entityName << endl
882  << "#(" << endl
883  << "`include \""
884  << entityNameStr_ << "_globals_pkg.vh\"" << endl
885  << "," << endl
886  << "`include \"" << "gcu_opcodes_pkg.vh\"" << endl
887  << ")" << endl;
888 
889  VerilogNetlistWriter::writePortDeclaration(
890  *decoderBlock_, 1, indentation(1), stream);
891 
892  // create generic and port declarations
893  VerilogNetlistWriter::writeGenericDeclaration(
894  *decoderBlock_, 1, indentation(1), stream);
895 
896  stream << endl;
897 
898  writeMoveFieldSignals(stream);
899  stream << endl;
901  stream << endl;
903  stream << endl;
904  writeSquashSignals(stream);
905  stream << endl;
906  writeSocketCntrlSignals(stream);
907  stream << endl;
908  writeFUCntrlSignals(stream);
909  stream << endl;
910  writeRFCntrlSignals(stream);
911  stream << endl;
912 
913  if (generateLockTrace_) {
914  writeLockDumpCode(stream);
915  stream << endl;
916  }
917 
919  stream << endl;
921  stream << endl;
923  stream << endl;
925  stream << endl;
927  stream << endl;
928  writeMainDecodingProcess(stream);
929  stream << endl;
930 
931  int lockReqWidth = glockRequestWidth();
932  stream << indentation(1) << "assign "
933  << NetlistGenerator::DECODER_LOCK_REQ_OUT_PORT << "=";
934  if (lockReqWidth > 0) {
935  for (int i = 0; i < lockReqWidth; i++) {
936  stream << LOCK_REQ_PORT_NAME << "[" << i << "]";
937  if (i+1 < lockReqWidth) {
938  stream << " | ";
939  }
940  }
941  stream << ";" << endl;
942  } else {
943  stream << "1'b0;" << endl;
944  }
945 
946  const int glockWidth = glockPortWidth();
947  stream << indentation(1) << "assign " << GLOCK_PORT_NAME << " = {"
948  << Conversion::toString(glockWidth) << "{"
949  << NetlistGenerator::DECODER_LOCK_REQ_IN_PORT << "}};" << endl
950  << endl;
951  stream << endl << "endmodule" << endl;
952  }
953 }
954 
955 /**
956  * Writes process that captures state of global lock per clock cycle.
957  *
958  * The captured contents are dumped into an output file.
959  *
960  * @param stream The stream to write.
961  */
962 void
963 DefaultDecoderGenerator::writeLockDumpCode(std::ostream& stream) const {
964  if (language_==VHDL){
965  stream << indentation(1)
966  << "-- Dump the status of global lock into a file once "
967  "in clock cycle"
968  << endl
969  << indentation(1)
970  << "-- setting DUMP false will disable dumping"
971  << endl << endl;
972 
973  stream << indentation(1)
974  << "-- Do not synthesize this process!"
975  << endl
976  << indentation(1)
977  << "-- pragma synthesis_off"
978  << endl << endl;
979 
980  stream << indentation(1)
981  << "file_output : process" << endl;
982  stream << indentation(2)
983  << "file fileout : text;" << endl << endl
984  << indentation(2)
985  << "variable lineout : line;" << endl
986  << indentation(2)
987  << "variable start : boolean := true;" << endl
988  << indentation(2)
989  << "variable count : integer := 0;" << endl
990  << indentation(2)
991  << "constant SEPARATOR : string := \" | \";" << endl
992  << indentation(2)
993  << "constant DUMP : boolean := true;" << endl
994  << indentation(2)
995  << "constant DUMPFILE : string := \"lock.dump\";" << endl;
996 
997  stream << indentation(1)
998  << "begin" << endl;
999 
1000  stream << indentation(2)
1001  << "if DUMP = true then" << endl;
1002 
1003  stream << indentation(3)
1004  << "if start = true then" << endl;
1005 
1006  stream << indentation(4)
1007  << "file_open(fileout, DUMPFILE, write_mode);" << endl
1008  << indentation(4)
1009  << "start := false;" << endl;
1010 
1011  stream << indentation(3)
1012  << "end if;" << endl;
1013 
1014  stream << indentation(3)
1015  << "wait on clk until clk = '1' and clk'last_value = '0';"
1016  << endl;
1017 
1018  stream << indentation(3)
1019  << "if count > " << (lockTraceStartingCycle_ - 1)
1020  << " then" << endl;
1021 
1022  stream << indentation(4) << "write(lineout, count-"
1023  << lockTraceStartingCycle_ << ", right, 12);" << endl
1024  << indentation(4) << "write(lineout, SEPARATOR);" << endl
1025  << indentation(4)
1026  << "write(lineout, conv_integer(unsigned'(\"\" & "
1027  << POST_DECODE_MERGED_GLOCK_SIGNAL << ")), right, 12);" << endl
1028  << indentation(4) << "write(lineout, SEPARATOR);" << endl
1029  << indentation(4) << "writeline(fileout, lineout);" << endl;
1030 
1031  stream << indentation(3)
1032  << "end if;" << endl;
1033  stream << indentation(3)
1034  << "count := count + 1;" << endl;
1035 
1036  stream << indentation(2)
1037  << "end if;" << endl;
1038 
1039  stream << indentation(1)
1040  << "end process file_output;" << endl;
1041 
1042  stream << indentation(1)
1043  << "-- pragma synthesis_on"
1044  << endl;
1045 
1046  } else { // language_==Verilog
1047  stream << indentation(1)
1048  << "// Dump the status of global lock into a file once "
1049  << "in clock cycle"
1050  << endl
1051  << indentation(1)
1052  << "// setting DUMP false will disable dumping"
1053  << endl << endl
1054  << indentation(1) << "// Do not synthesize!" << endl
1055  << indentation(1) << "//synthesis translate_off" << endl
1056  << indentation(1) << "integer fileout;" << endl << endl
1057  << indentation(1) << "integer count=0;" << endl << endl
1058  << indentation(1) << "`define DUMPFILE \"lock.dump\""
1059  << endl << endl
1060 
1061  << indentation(1) << "initial" << endl
1062  << indentation(1) << "begin" << endl
1063  << indentation(2) << "fileout = $fopen(`DUMPFILE,\"w\");"
1064  << endl
1065  << indentation(2) << "$fclose(fileout);" << endl
1066  << indentation(2) << "forever" << endl
1067  << indentation(2) << "begin" << endl
1068  << indentation(3) << "#PERIOD;" << endl
1069  << indentation(3) << "if ( count > "
1070  << (lockTraceStartingCycle_ - 1) << ")" << endl;
1071 
1072  stream << indentation(3) << "begin" << endl
1073  << indentation(4) << "fileout = $fopen(`DUMPFILE,\"a\");"
1074  << endl
1075  << indentation(4) << "$fwrite(fileout," << "\""
1076  << " %11d | %11d | \\n\"" << ", count - "
1077  << lockTraceStartingCycle_ << ", "
1078  << NetlistGenerator::DECODER_LOCK_REQ_IN_PORT << ");"
1079  << endl
1080  << indentation(4) << "$fclose(fileout);" << endl
1081  << indentation(3) << "end" << endl
1082  << indentation(3) << "count = count + 1;" << endl
1083  << indentation(2) << "end" << endl
1084  << indentation(1) << "end" << endl
1085  << indentation(1) << "//synthesis translate_on" << endl;
1086  }
1087 }
1088 
1089 /**
1090  * Writes the signals for source, destination and guard fields to the
1091  * given stream.
1092  *
1093  * @param stream The stream.
1094  */
1095 void
1097  writeComment(
1098  stream, 1, "signals for source, destination and guard fields");
1099 
1100  for (int i = 0; i < bem_.moveSlotCount(); i++) {
1101  MoveSlot& slot = bem_.moveSlot(i);
1102  if (slot.width() > 0) {
1104  stream, ProGe::BIT_VECTOR, moveFieldSignal(slot.name()),
1105  slot.width());
1106  }
1107  if (slot.hasSourceField() && slot.sourceField().width() != 0) {
1108  SourceField& srcField = slot.sourceField();
1110  stream, ProGe::BIT_VECTOR, srcFieldSignal(slot.name()),
1111  srcField.width());
1112  }
1113  if (slot.hasDestinationField() &&
1114  slot.destinationField().width() != 0) {
1115  DestinationField& dstField = slot.destinationField();
1117  stream, ProGe::BIT_VECTOR, dstFieldSignal(slot.name()),
1118  dstField.width());
1119  }
1120  if (slot.hasGuardField()) {
1121  GuardField& grdField = slot.guardField();
1123  stream, ProGe::BIT_VECTOR, guardFieldSignal(slot.name()),
1124  grdField.width());
1125  }
1126  }
1127 }
1128 
1129 /**
1130  * Writes the signals for dedicated immediate slots to the given stream.
1131  *
1132  * @param stream The stream.
1133  */
1134 void
1136  std::ostream& stream) const {
1137  writeComment(stream, 1, "signals for dedicated immediate slots");
1138  for (int i = 0; i < bem_.immediateSlotCount(); i++) {
1141  stream, ProGe::BIT_VECTOR, immSlotSignal(slot.name()),
1142  slot.width());
1143  }
1144 }
1145 
1146 /**
1147  * Writes the signal for long immediate tag to the given stream.
1148  *
1149  * @param stream The stream.
1150  */
1151 void
1153  std::ostream& stream) const {
1155  writeComment(stream, 1, "signal for long immediate tag");
1156 
1160  }
1161 }
1162 
1163 /**
1164  * Writes the squash signals of guards to the given stream.
1165  *
1166  * @param stream The stream.
1167  */
1168 void
1170  std::ostream& stream) const {
1171 
1172  TCEString comment = language_ == VHDL ? "-- " : "// ";
1174  stream << indentation(1) << comment << "squash signals" << endl;
1175  for (int i = 0; i < busNav.count(); i++) {
1176  Bus* bus = busNav.item(i);
1177  stream << indentation(1);
1178  if (language_ == VHDL) {
1179  stream << "signal " << squashSignal(bus->name())
1180  << " : std_logic;" << endl;
1181  } else {
1182  assert(bem_.hasMoveSlot(bus->name()));
1183  MoveSlot& slot = bem_.moveSlot(bus->name());
1184  if (slot.hasGuardField()) {
1185  stream << "reg ";
1186  } else {
1187  // Declare guard signal as wire for constant assignment
1188  stream << "wire ";
1189  }
1190  stream << squashSignal(bus->name()) << ";" << endl;
1191  }
1192  }
1193 }
1194 
1195 
1196 /**
1197  * Writes the socket control signals to the given stream.
1198  *
1199  * @param stream The stream to write.
1200  */
1201 void
1203  writeComment(stream, 1, "socket control signals");
1204 
1206  for (int i = 0; i < socketNav.count(); i++) {
1207  Socket* socket = socketNav.item(i);
1208  if (socket->portCount() == 0 || socket->segmentCount() == 0) {
1209  continue;
1210  }
1211 
1212  if (needsBusControl(*socket)) {
1213  std::string sigName = socketBusCntrlSignalName(socket->name());
1215  stream, ProGe::BIT_VECTOR, sigName, busControlWidth(*socket));
1216  registerVectors.push_back(sigName);
1217  }
1218  if (needsDataControl(*socket)) {
1219  std::string sigName = socketDataCntrlSignalName(socket->name());
1221  stream, ProGe::BIT_VECTOR, sigName,
1222  dataControlWidth(*socket));
1223  registerVectors.push_back(sigName);
1224  }
1225  }
1226 
1227  // write signals for short immediate sockets (not visible in ADF)
1229  for (int i = 0; i < busNav.count(); i++) {
1230  Bus* bus = busNav.item(i);
1231  if (bus->immediateWidth() > 0) {
1233  stream, ProGe::BIT_VECTOR, simmDataSignalName(bus->name()),
1234  simmPortWidth(*bus));
1235  registerVectors.push_back(simmDataSignalName(bus->name()));
1237  stream, ProGe::BIT_VECTOR, simmCntrlSignalName(bus->name()),
1238  1);
1239  registerVectors.push_back(simmCntrlSignalName(bus->name()));
1240  }
1241 
1242  if (generateBusEnable_) {
1244  stream, ProGe::BIT, busMuxEnableRegister(*bus), 1);
1245  registerBits.push_back(busMuxEnableRegister(*bus));
1246  }
1247  }
1248 }
1249 
1250 /**
1251  * Writes the FU control signals to the given stream.
1252  *
1253  * @param stream The stream.
1254  */
1255 void
1257  writeComment(stream, 1, "FU control signals");
1258 
1260  functionUnitNavigator();
1261  for (int i = 0; i < fuNav.count(); i++) {
1262  FunctionUnit* fu = fuNav.item(i);
1263  writeFUCntrlSignals(*fu, stream);
1264  }
1265 
1266  if (machine_.controlUnit() != NULL) {
1267  ControlUnit* gcu = machine_.controlUnit();
1268  writeFUCntrlSignals(*gcu, stream);
1269  }
1270 }
1271 
1272 /**
1273  * Writes the control signals of the given FU to the given stream.
1274  *
1275  * @param fu The FU.
1276  * @param stream The stream to write.
1277  */
1278 void
1280  const TTAMachine::FunctionUnit& fu, std::ostream& stream) {
1281  for (int i = 0; i < fu.portCount(); i++) {
1282  BaseFUPort* port = fu.port(i);
1283 
1284  if (port->inputSocket() != NULL) {
1285  // if input port
1286  std::string sigName = fuLoadSignalName(fu.name(), port->name());
1287  writeSignalDeclaration(stream, ProGe::BIT, sigName, 1);
1288  registerBits.push_back(sigName);
1289  }
1290  }
1291 
1292  // write opcode signal if the FU needs opcode
1293  int opcWidth = opcodeWidth(fu);
1294  if (opcWidth > 0) {
1295  std::string sigName = fuOpcodeSignalName(fu.name());
1296  writeSignalDeclaration(stream, ProGe::BIT_VECTOR, sigName, opcWidth);
1297  registerVectors.push_back(sigName);
1298  }
1299 }
1300 
1301 /**
1302  * Writes the RF control signals to the given stream.
1303  *
1304  * @param stream The stream.
1305  */
1306 void
1308  writeComment(stream, 1, "RF control signals");
1309 
1311  registerFileNavigator();
1312  for (int i = 0; i < rfNav.count(); i++) {
1313  RegisterFile* rf = rfNav.item(i);
1314 
1315  for (int i = 0; i < rf->portCount(); i++) {
1316  RFPort* port = rf->port(i);
1317  bool async_signal = sacEnabled(rf->name())
1318  && port->outputSocket() != NULL;
1319 
1320  // load signal
1321  std::string sigName =
1322  rfLoadSignalName(rf->name(), port->name(), async_signal);
1323  writeSignalDeclaration(stream, ProGe::BIT, sigName, 1);
1324  if (!async_signal) registerBits.push_back(sigName);
1325 
1326  // opcode signal
1327  if (0 < rfOpcodeWidth(*rf)) {
1328  std::string sigName = rfOpcodeSignalName(
1329  rf->name(), port->name(), async_signal);
1331  stream, ProGe::BIT_VECTOR, sigName, rfOpcodeWidth(*rf));
1332 
1333  if (!async_signal) registerVectors.push_back(sigName);
1334  }
1335  }
1336  }
1337 
1339  for (int i = 0; i < iuNav.count(); i++) {
1340  ImmediateUnit* iu = iuNav.item(i);
1341  for (int i = 0; i < iu->portCount(); i++) {
1342  RFPort* port = iu->port(i);
1343  if (port->isOutput()) {
1344  if (language_ == VHDL) {
1345  registerBits.push_back(
1346  iuReadLoadCntrlPort(iu->name(), port->name()));
1347  if (0 < rfOpcodeWidth(*iu)) {
1348  registerVectors.push_back(
1349  iuReadOpcodeCntrlPort(iu->name(), port->name()));
1350  }
1351  } else {
1352  std::string sigName =
1353  iuReadLoadCntrlSignal(iu->name(), port->name());
1354  writeSignalDeclaration(stream, ProGe::BIT, sigName, 1);
1355  registerBits.push_back(sigName);
1356 
1357  if (0 < rfOpcodeWidth(*iu)) {
1358  sigName =
1359  iuReadOpcodeCntrlSignal(iu->name(), port->name());
1361  stream, ProGe::BIT_VECTOR, sigName,
1362  rfOpcodeWidth(*iu));
1363  registerVectors.push_back(sigName);
1364  }
1365  }
1366  }
1367  }
1368  if (language_ == Verilog) {
1369  stream << indentation(1) << "reg[" << iu->width()-1 << ":0] "
1370  << iuWriteSignal(iu->name())
1371  << ";" << endl;
1372  stream << indentation(1) << "reg "
1373  << iuWriteLoadCntrlSignal(iu->name())
1374  << ";" << endl;
1375  if (0 < rfOpcodeWidth(*iu)) {
1376  stream << indentation(1) << "reg["
1377  << rfOpcodeWidth(*iu) - 1 << ":0] "
1378  << iuWriteOpcodeCntrlSignal(iu->name())
1379  << ";" << endl;
1380  }
1381  }
1382  }
1383 }
1384 
1385 void
1387  std::ostream& stream) const {
1388  assert(language_ == VHDL && "Support for other HDL not yet implemented.");
1397 }
1398 
1399 /**
1400  * Writes signals used in decode pipeline fill process.
1401  */
1402 void
1404  std::ostream& stream) const {
1406 }
1407 
1408 /**
1409  * Writes dismembering of instruction word to signals to the given stream.
1410  *
1411  * @param stream The stream.
1412  */
1413 void
1415  std::ostream& stream) const {
1416  std::string instructionPort = NetlistGenerator::DECODER_INSTR_WORD_PORT;
1417 
1418  if (language_ == VHDL) {
1419  stream << indentation(1) << "-- dismembering of instruction" << endl;
1420  stream << indentation(1) << "process (" << instructionPort << ")"
1421  << endl;
1422  stream << indentation(1) << "begin --process" << endl;
1423 
1424  for (int i = 0; i < bem_.moveSlotCount(); i++) {
1425  MoveSlot& slot = bem_.moveSlot(i);
1426  int slotPosition = slot.bitPosition();
1427 
1428  if (slot.width() > 0) {
1429  stream << indentation(2) << moveFieldSignal(slot.name())
1430  << " <= " << instructionPort << "("
1431  << slotPosition + slot.width() << "-1 downto "
1432  << slotPosition << ");" << endl;
1433  }
1434  if (slot.hasSourceField() && slot.sourceField().width() != 0) {
1435  SourceField& srcField = slot.sourceField();
1436  stream << indentation(2) << srcFieldSignal(slot.name())
1437  << " <= " << instructionPort << "("
1438  << slotPosition + srcField.bitPosition() +
1439  srcField.width() - 1
1440  << " downto " << slotPosition + srcField.bitPosition()
1441  << ");" << endl;
1442  }
1443  if (slot.hasDestinationField() &&
1444  slot.destinationField().width() != 0) {
1445  DestinationField& dstField = slot.destinationField();
1446  stream << indentation(2) << dstFieldSignal(slot.name())
1447  << " <= " << instructionPort << "("
1448  << slotPosition + dstField.bitPosition() +
1449  dstField.width() - 1
1450  << " downto " << slotPosition + dstField.bitPosition()
1451  << ");" << endl;
1452  }
1453  if (slot.hasGuardField()) {
1454  GuardField& grdField = slot.guardField();
1455  stream << indentation(2) << guardFieldSignal(slot.name())
1456  << " <= " << instructionPort << "("
1457  << slotPosition + grdField.bitPosition() +
1458  grdField.width() - 1
1459  << " downto " << slotPosition + grdField.bitPosition()
1460  << ");" << endl;
1461  }
1462  }
1463  stream << endl;
1464  for (int i = 0; i < bem_.immediateSlotCount(); i++) {
1466  stream << indentation(2) << immSlotSignal(slot.name())
1467  << " <= " << instructionPort << "("
1468  << slot.bitPosition() + slot.width() - 1 << " downto "
1469  << slot.bitPosition() << ");" << endl;
1470  }
1473  stream << indentation(2) << LIMM_TAG_SIGNAL
1474  << " <= " << instructionPort << "("
1475  << icField.bitPosition() + icField.width() - 1
1476  << " downto " << icField.bitPosition() << ");" << endl;
1477  }
1478  stream << indentation(1) << "end process;" << endl;
1479  } else { // language == Verilog
1480  stream << indentation(1) << "// dismembering of instruction" << endl;
1481  stream << indentation(1) << "always@(*)" << endl;
1482  stream << indentation(1) << "begin //process" << endl;
1483 
1484  for (int i = 0; i < bem_.moveSlotCount(); i++) {
1485  MoveSlot& slot = bem_.moveSlot(i);
1486  int slotPosition = slot.bitPosition();
1487 
1488  if (slot.width() > 0) {
1489  stream << indentation(2) << moveFieldSignal(slot.name())
1490  << " = " << instructionPort << "["
1491  << slotPosition + slot.width() - 1 << " : "
1492  << slotPosition << "];" << endl;
1493  }
1494  if (slot.hasSourceField() && slot.sourceField().width() != 0) {
1495  SourceField& srcField = slot.sourceField();
1496  stream << indentation(2) << srcFieldSignal(slot.name())
1497  << " = " << instructionPort << "["
1498  << slotPosition + srcField.bitPosition() +
1499  srcField.width() - 1
1500  << " : " << slotPosition + srcField.bitPosition()
1501  << "];" << endl;
1502  }
1503  if (slot.hasDestinationField() &&
1504  slot.destinationField().width() != 0) {
1505  DestinationField& dstField = slot.destinationField();
1506  stream << indentation(2) << dstFieldSignal(slot.name())
1507  << " = " << instructionPort << "["
1508  << slotPosition + dstField.bitPosition() +
1509  dstField.width() - 1
1510  << " : " << slotPosition + dstField.bitPosition()
1511  << "];" << endl;
1512  }
1513  if (slot.hasGuardField()) {
1514  GuardField& grdField = slot.guardField();
1515  stream << indentation(2) << guardFieldSignal(slot.name())
1516  << " = " << instructionPort << "["
1517  << slotPosition + grdField.bitPosition() +
1518  grdField.width() - 1
1519  << " : " << slotPosition + grdField.bitPosition()
1520  << "];" << endl;
1521  }
1522  }
1523  stream << endl;
1524  for (int i = 0; i < bem_.immediateSlotCount(); i++) {
1526  stream << indentation(2) << immSlotSignal(slot.name()) << " = "
1527  << instructionPort << "["
1528  << slot.bitPosition() + slot.width() - 1 << " : "
1529  << slot.bitPosition() << "];" << endl;
1530  }
1533  stream << indentation(2) << LIMM_TAG_SIGNAL << " = "
1534  << instructionPort << "["
1535  << icField.bitPosition() + icField.width() - 1 << " : "
1536  << icField.bitPosition() << "];" << endl;
1537  }
1538  stream << indentation(1) << "end" << endl;
1539  }
1540 }
1541 
1542 /**
1543  * Writes the generation processes of squash signals to the given stream.
1544  *
1545  * @param stream The stream.
1546  */
1547 void
1549  std::ostream& stream) const {
1550 
1552  for (int i = 0; i < busNav.count(); i++) {
1553  Bus* bus = busNav.item(i);
1554  writeSquashSignalGenerationProcess(*bus, stream);
1555  }
1556 }
1557 
1558 
1559 /**
1560  * Writes the generation process of squash signal for the given bus.
1561  *
1562  * @param bus The bus.
1563  * @param stream The stream to write.
1564  */
1565 void
1567  const TTAMachine::Bus& bus,
1568  std::ostream& stream) const {
1569  if(language_==VHDL){
1570  assert(bem_.hasMoveSlot(bus.name()));
1571  MoveSlot& slot = bem_.moveSlot(bus.name());
1572  GuardField* grdField = nullptr;
1573  std::set<InstructionTemplate*> affectingInstTemplates =
1575  bool ifClauseStarted = false;
1576 
1577  if (!slot.hasGuardField() && affectingInstTemplates.size() == 0) {
1578  // the bus contains always true guard so squash has static value
1579  // Synthesis software should optimize it away
1580  string squashName = squashSignal(bus.name());
1581  stream << indentation(1) << "-- generate signal " << squashName
1582  << endl;
1583  stream << indentation(1) << squashName << " <= '0';" << endl;
1584  return;
1585  }
1586 
1587  std::set<string> sensitivyList;
1588  for (int i = 0; i < bus.guardCount(); i++) {
1589  sensitivyList.insert(guardPortName(*bus.guard(i)));
1590  }
1591  if (slot.hasGuardField()) {
1592  sensitivyList.insert(guardFieldSignal(slot.name()));
1593  grdField = &slot.guardField();
1594  }
1595 
1596  if (affectingInstTemplates.size() > 0) {
1597  sensitivyList.insert(LIMM_TAG_SIGNAL);
1598  }
1599 
1600  stream << indentation(1) << "-- generate signal "
1601  << squashSignal(slot.name()) << endl;
1602  stream << indentation(1) << "process (";
1603  string listStr;
1604  for (const string& signal : sensitivyList) {
1605  TCEString::appendToNonEmpty(listStr, ", ");
1606  listStr += signal;
1607  }
1608  assert(!listStr.empty());
1609  stream << listStr << ")" << endl;
1610  if (slot.hasGuardField()) {
1611  stream << indentation(2) << "variable sel : integer;" << endl;
1612  }
1613  stream << indentation(1) << "begin --process" << endl;
1614  int indLevel = 2;
1615  if (affectingInstTemplates.size() > 0) {
1616  ifClauseStarted = true;
1617  stream << indentation(indLevel) << "if (";
1618  for (set<InstructionTemplate*>::const_iterator iter =
1619  affectingInstTemplates.begin();
1620  iter != affectingInstTemplates.end(); iter++) {
1621  if (iter != affectingInstTemplates.begin()) {
1622  stream << " or " << endl
1623  << indentation(indLevel) << " ";
1624  }
1626  InstructionTemplate* affectingTemp = *iter;
1627  stream << "conv_integer(unsigned(" << LIMM_TAG_SIGNAL
1628  << ")) = "
1629  << icField.templateEncoding(affectingTemp->name());
1630  stream << ") then" << endl;
1631  stream << indentation(indLevel+1) << squashSignal(bus.name())
1632  << " <= '1';" << endl;
1633  }
1634  }
1635 
1636  if (ifClauseStarted) {
1637  stream << indentation(indLevel) << "else" << endl;
1638  indLevel += 1;
1639  }
1640  if (grdField != nullptr) {
1641  stream << indentation(indLevel) << "sel := conv_integer(unsigned("
1642  << guardFieldSignal(slot.name()) << "));" << endl;
1643  stream << indentation(indLevel) << "case sel is" << endl;
1644  indLevel++;
1645  for (int i = 0; i < grdField->gprGuardEncodingCount(); i++) {
1646  GPRGuardEncoding& enc = grdField->gprGuardEncoding(i);
1647  RegisterGuard& regGuard = findGuard(enc);
1649  bus, enc, regGuard, stream, indLevel);
1650  }
1651 
1652  for (int i = 0; i < grdField->fuGuardEncodingCount(); i++) {
1653  FUGuardEncoding& enc = grdField->fuGuardEncoding(i);
1654  PortGuard& portGuard = findGuard(enc);
1656  bus, enc, portGuard, stream, indLevel);
1657  }
1658 
1659  if (grdField->hasUnconditionalGuardEncoding(true)) {
1661  grdField->unconditionalGuardEncoding(true);
1662  stream << indentation(indLevel) << "when " << enc.encoding()
1663  << " => " << endl;
1664  stream << indentation(indLevel + 1)
1665  << squashSignal(slot.name()) << " <= '1';" << endl;
1666  }
1667 
1668  stream << indentation(indLevel) << "when others =>" << endl;
1669  stream << indentation(indLevel + 1) << squashSignal(slot.name())
1670  << " <= '0';" << endl;
1671  stream << indentation(indLevel-1) << "end case;" << endl;
1672  } else {
1673  stream << indentation(indLevel) << squashSignal(slot.name())
1674  << " <= '0';" << endl;
1675  }
1676 
1677  if (ifClauseStarted) {
1678  ifClauseStarted = false;
1679  stream << indentation(2) << "end if;" << endl;
1680  indLevel -= 1;
1681  assert(indLevel >= 0);
1682  }
1683  stream << indentation(1) << "end process;" << endl << endl;
1684  } else { // language == Verilog
1685  std::set<InstructionTemplate*> affectingInstTemplates =
1687  bool ifClauseStarted = false;
1688 
1689  assert(bem_.hasMoveSlot(bus.name()));
1690  MoveSlot& slot = bem_.moveSlot(bus.name());
1691  if (slot.hasGuardField() || affectingInstTemplates.size() > 0) {
1692  GuardField& grdField = slot.guardField();
1693 
1694  std::set<string> sensitivyList;
1695  for (int i = 0; i < bus.guardCount(); i++) {
1696  sensitivyList.insert(guardPortName(*bus.guard(i)));
1697  }
1698  if (slot.hasGuardField()) {
1699  sensitivyList.insert(guardFieldSignal(slot.name()));
1700  }
1701 
1702  if (affectingInstTemplates.size() > 0) {
1703  sensitivyList.insert(LIMM_TAG_SIGNAL);
1704  }
1705 
1706  stream << indentation(1) << "// generate signal "
1707  << squashSignal(slot.name()) << endl;
1708  stream << indentation(1) << "always@(";
1709  string listStr;
1710  for (const string& signal : sensitivyList) {
1711  TCEString::appendToNonEmpty(listStr, ", ");
1712  listStr += signal;
1713  }
1714  assert(!listStr.empty());
1715  stream << listStr << ")" << endl;
1716  stream << indentation(1) << "begin" << endl;
1717  int indLevel = 2;
1718 
1719  if (affectingInstTemplates.size() > 0) {
1720  ifClauseStarted = true;
1721  stream << indentation(indLevel) << "if (";
1722  for (set<InstructionTemplate*>::const_iterator iter =
1723  affectingInstTemplates.begin();
1724  iter != affectingInstTemplates.end(); iter++) {
1725  if (iter != affectingInstTemplates.begin()) {
1726  stream << " || ";
1727  }
1728  ImmediateControlField& icField =
1730  InstructionTemplate* affectingTemp = *iter;
1731  stream << LIMM_TAG_SIGNAL
1732  << " == "
1733  << icField.templateEncoding(affectingTemp->name());
1734  }
1735  stream << ")" << endl;
1736  stream << indentation(indLevel+1) << squashSignal(bus.name())
1737  << " <= 1'b1;" << endl;
1738  }
1739 
1740  if (ifClauseStarted) {
1741  stream << indentation(indLevel) << "else" << endl;
1742  indLevel++;
1743  }
1744  if (slot.hasGuardField()) {
1745  stream << indentation(indLevel) << "case("
1746  << guardFieldSignal(slot.name()) << ")" << endl;
1747  indLevel++;
1748  for (int i = 0; i < grdField.gprGuardEncodingCount(); i++) {
1749  GPRGuardEncoding& enc = grdField.gprGuardEncoding(i);
1750  RegisterGuard& regGuard = findGuard(enc);
1752  Verilog, bus, enc, regGuard, stream, indLevel);
1753  }
1754 
1755  for (int i = 0; i < grdField.fuGuardEncodingCount(); i++) {
1756  FUGuardEncoding& enc = grdField.fuGuardEncoding(i);
1757  PortGuard& portGuard = findGuard(enc);
1759  Verilog, bus, enc, portGuard, stream, indLevel);
1760  }
1761 
1762  if (grdField.hasUnconditionalGuardEncoding(true)) {
1764  grdField.unconditionalGuardEncoding(true);
1765  stream << indentation(indLevel) << enc.encoding() << " :"
1766  << endl;
1767  stream << indentation(indLevel + 1)
1768  << squashSignal(slot.name()) << " <= 1'b1;"
1769  << endl;
1770  }
1771 
1772  stream << indentation(indLevel) << "default:" << endl;
1773  stream << indentation(indLevel + 1)
1774  << squashSignal(slot.name()) << " <= 1'b0;" << endl;
1775  stream << indentation(indLevel - 1) << "endcase" << endl;
1776  } else {
1777  string squashName = squashSignal(bus.name());
1778  stream << indentation(indLevel) << squashName << " <= 1'b0;"
1779  << endl;
1780  }
1781  stream << indentation(1) << "end" << endl << endl;
1782  } else {
1783  // the bus contains always true guard so squash has static value
1784  // Synthesis software should optimize it away
1785  string squashName = squashSignal(bus.name());
1786  stream << indentation(1) << "// generate signal " << squashName
1787  << endl;
1788  stream << indentation(1) << "assign " << squashName
1789  << " = 1'b0;" << endl;
1790  }
1791  }
1792 }
1793 
1794 
1795 /**
1796  * Writes the process that writes long immediates to immediate units.
1797  *
1798  * @param stream The stream to write.
1799  */
1800 void
1802  std::ostream& stream) const {
1803 
1806  if (itNav.count() == 0 || (itNav.count() == 1 &&
1807  itNav.item(0)->isEmpty())) {
1808  return;
1809  }
1810 
1811  string resetPort = NetlistGenerator::DECODER_RESET_PORT;
1812  string clockPort = NetlistGenerator::DECODER_CLOCK_PORT;
1813  // If bypass decoder registers, implement combinatorial process
1814  string listStr;
1815  if (language_ == VHDL) {
1816  int indentLevel = 1;
1817  stream << indentation(indentLevel) << "--long immediate write process"
1818  << endl;
1819  stream << indentation(indentLevel) << "process (";
1820  stream << clockPort;
1821  if (!syncReset_) {
1822  stream << ", " << resetPort;
1823  }
1824  stream << ")" << endl;
1825  stream << indentation(indentLevel) << "begin --process" << endl;
1826  // reset
1827  indentLevel += 1;
1828  if (syncReset_) {
1829  stream << indentation(indentLevel)
1830  << "if (clk'event and clk = '1') then" << endl;
1831  indentLevel += 1;
1832  }
1833  stream << indentation(indentLevel) << "if (" << resetPort
1834  << " = '0') then" << endl;
1835  indentLevel += 1;
1838 
1839  for (int i = 0; i < iuNav.count(); i++) {
1840  ImmediateUnit* iu = iuNav.item(i);
1841  stream << indentation(indentLevel)
1842  << iuWriteLoadCntrlPort(iu->name()) << " <= '0';" << endl;
1843  stream << indentation(indentLevel) << iuWritePort(iu->name())
1844  << " <= (others => '0');" << endl;
1845  if (rfOpcodeWidth(*iu) != 0)
1846  stream << indentation(indentLevel)
1847  << iuWriteOpcodeCntrlPort(iu->name())
1848  << " <= (others => '0');" << endl;
1849  }
1850  // else
1851  stream << indentation(indentLevel - 1) << "elsif ";
1852  if (!syncReset_) {
1853  stream << "(clk'event and clk = '1') then" << endl
1854  << indentation(indentLevel) << "if ";
1855  indentLevel += 1;
1856  }
1857  // global lock test
1858  stream << PRE_DECODE_MERGED_GLOCK_SIGNAL << " = '0' then" << endl;
1859  for (int i = 0; i < itNav.count(); i++) {
1860  InstructionTemplate* iTemp = itNav.item(i);
1862  if (i == 0) {
1863  stream << indentation(indentLevel) << "if ("
1865  VHDL, iTemp->name())
1866  << ") then" << endl;
1867  } else if (i+1 < itNav.count()) {
1868  stream << indentation(indentLevel) << "elsif ("
1870  VHDL, iTemp->name())
1871  << ") then" << endl;
1872  } else {
1873  stream << indentation(indentLevel) << "else" << endl;
1874  }
1875  }
1877  VHDL, *iTemp, indentLevel + 1, stream);
1878  }
1879 
1881  stream << indentation(indentLevel) << "end if;" << endl;
1882  }
1883  // global lock test endif
1884  stream << indentation(3) << "end if;" << endl;
1885  // reset (async) or clk edge (sync) endif
1886  stream << indentation(2) << "end if;" << endl;
1887  stream << indentation(1) << "end process;" << endl;
1888  } else { // language_ == Verilog
1889  stream << indentation(1) << "//long immediate write process" << endl
1890  << indentation(1) << "always@(posedge "
1891  << clockPort << " or negedge " << resetPort << ")" << endl
1892  // reset
1893  << indentation(2) << "if (" << resetPort << " == 0)"
1894  << endl
1895  << indentation(2) << "begin" << endl;
1898 
1899  for (int i = 0; i < iuNav.count(); i++) {
1900  ImmediateUnit* iu = iuNav.item(i);
1901  stream << indentation(3) << iuWriteLoadCntrlSignal(iu->name())
1902  << " <= 1'b0;" << endl
1903  << indentation(3) << iuWriteSignal(iu->name())
1904  << " <= 0;" << endl;
1905  if (rfOpcodeWidth(*iu) != 0)
1906  stream << indentation(3) << iuWriteOpcodeCntrlSignal(iu->name())
1907  << " <= 0;" << endl;
1908  }
1909  stream << indentation(2) << "end" << endl
1910  << indentation(2) << "else" << endl
1911  << indentation(2) << "begin" << endl
1912  << indentation(3) << "if ("
1913  << NetlistGenerator::DECODER_LOCK_REQ_IN_PORT << " == 0)"
1914  << endl
1915  << indentation(3) << "begin" << endl;
1916  for (int i = 0; i < itNav.count(); i++) {
1917  InstructionTemplate* iTemp = itNav.item(i);
1918  int indLevel = 4;
1920  indLevel = 5;
1921  if (i == 0) {
1922  stream << indentation(4) << "if ("
1924  Verilog, iTemp->name())
1925  << ")" << endl;
1926  } else if (i+1 < itNav.count()) {
1927  stream << indentation(4) << "else if ("
1929  Verilog, iTemp->name())
1930  << ")" << endl;
1931  } else {
1932  stream << indentation(4) << "else" << endl;
1933  }
1934  }
1935  stream << indentation(4) << "begin" << endl;
1937  Verilog, *iTemp, indLevel, stream);
1938  stream << indentation(4) << "end" << endl;
1939  }
1940  stream << indentation(3) << "end" << endl
1941  << indentation(2) << "end" << endl;
1942  }
1943 }
1944 
1945 
1946 /**
1947  * Writes the procedures required if the instruction is of the given
1948  * instruction template.
1949  *
1950  * @param iTemp The instruction template.
1951  * @param indLevel The indentation level.
1952  * @param stream The stream to write.
1953  */
1954 void
1956  const ProGe::HDL language,
1957  const TTAMachine::InstructionTemplate& iTemp,
1958  int indLevel,
1959  std::ostream& stream) const {
1960 
1963  if (language == VHDL) {
1964  if (iTemp.slotCount() == 0) {
1965  for (int i = 0; i < iuNav.count(); i++) {
1966  ImmediateUnit* iu = iuNav.item(i);
1967  stream << indentation(indLevel)
1968  << iuWriteLoadCntrlPort(iu->name()) << " <= '0';"
1969  << endl;
1970 
1971  stream << indentation(indLevel) << iuWritePort(iu->name())
1972  << "(" << (iu->width() - 1) << " downto 0"
1973  << ") <= tce_sxt(\"0\", " << iu->width() << ");"
1974  << endl;
1975  }
1976  } else {
1977  for (int i = 0; i < iuNav.count(); i++) {
1978  ImmediateUnit* iu = iuNav.item(i);
1979  if (iTemp.isOneOfDestinations(*iu)) {
1980  int msb = iu->width() - 1;
1981  int lsb = iTemp.supportedWidth(*iu) -
1982  iTemp.supportedWidth(iTemp.slotOfDestination(*iu, 0));
1983  for (int j = 0; j < iTemp.numberOfSlots(*iu); j++) {
1984  string slot = iTemp.slotOfDestination(*iu, j);
1985  if (j != 0) {
1986  msb = lsb-1;
1987  lsb = msb - iTemp.supportedWidth(slot) + 1;
1988  }
1989 
1990  int immPartWidth = msb - lsb + 1;
1991  stream << indentation(indLevel)
1992  << iuWritePort(iu->name())
1993  << "(" << msb << " downto " << lsb << ") <= ";
1994  if (j == 0) {
1995  if (iu->extensionMode() == Machine::SIGN) {
1996  stream << "tce_sxt(";
1997  } else {
1998  stream << "tce_ext(";
1999  }
2000  }
2001 
2002  if (machine_.busNavigator().hasItem(slot)) {
2003  MoveSlot& mSlot = bem_.moveSlot(slot);
2004  stream << NetlistGenerator::DECODER_INSTR_WORD_PORT
2005  << "(" << mSlot.bitPosition() +
2006  iTemp.supportedWidth(slot) - 1
2007  << " downto " << mSlot.bitPosition() << ")";
2008  } else {
2009  ImmediateSlotField& iSlot =
2010  bem_.immediateSlot(slot);
2011  stream << NetlistGenerator::DECODER_INSTR_WORD_PORT
2012  << "(" << iSlot.bitPosition() +
2013  iTemp.supportedWidth(slot) - 1
2014  << " downto " << iSlot.bitPosition() << ")";
2015  }
2016 
2017  if (j == 0) {
2018  stream << ", " << immPartWidth << ");" << endl;
2019  } else {
2020  stream << ";" << endl;
2021  }
2022 
2023  }
2024  if (iu->numberOfRegisters() > 1) {
2025  LImmDstRegisterField& field =
2027  iTemp.name(), iu->name());
2028  stream << indentation(indLevel)
2029  << iuWriteOpcodeCntrlPort(iu->name()) << " <= "
2030  << "tce_ext("
2031  << NetlistGenerator::DECODER_INSTR_WORD_PORT
2032  << "("
2033  << field.bitPosition() + rfOpcodeWidth(*iu) - 1
2034  << " downto " << field.bitPosition() << "), "
2035  << iuWriteOpcodeCntrlPort(iu->name())
2036  << "'length);" << endl;
2037  }
2038  stream << indentation(indLevel)
2039  << iuWriteLoadCntrlPort(iu->name()) << " <= '1';"
2040  << endl;
2041  } else {
2042  stream << indentation(indLevel)
2043  << iuWriteLoadCntrlPort(iu->name()) << " <= '0';"
2044  << endl;
2045  }
2046  }
2047  }
2048  } else { // language == Verilog
2049  if (iTemp.slotCount() == 0) {
2050  for (int i = 0; i < iuNav.count(); i++) {
2051  ImmediateUnit* iu = iuNav.item(i);
2052  stream << indentation(indLevel)
2053  << iuWriteLoadCntrlSignal(iu->name())
2054  << " <= 1'b0;" << endl;
2055 
2056  stream << indentation(indLevel)
2057  << iuWriteSignal(iu->name())
2058  << "[" << (iu->width() - 1) << " : 0"
2059  << "] <= {" << iu->width() <<"{1'b0}};" << endl;
2060  }
2061  } else {
2062  for (int i = 0; i < iuNav.count(); i++) {
2063  ImmediateUnit* iu = iuNav.item(i);
2064  if (iTemp.isOneOfDestinations(*iu)) {
2065  int msb = iu->width() - 1;
2066  int lsb = iTemp.supportedWidth(*iu) -
2067  iTemp.supportedWidth(iTemp.slotOfDestination(*iu, 0));
2068  for (int j = 0; j < iTemp.numberOfSlots(*iu); j++) {
2069  string slot = iTemp.slotOfDestination(*iu, j);
2070  if (j != 0) {
2071  msb = lsb-1;
2072  lsb = msb - iTemp.supportedWidth(slot) + 1;
2073  }
2074 
2075  stream << indentation(indLevel)
2076  << iuWriteSignal(iu->name())
2077  << "[" << msb << " : " << lsb << "] <= ";
2078  if (j == 0) {
2079  if (iu->extensionMode() == Machine::SIGN) {
2080  stream << "$signed(";
2081  } else {
2082  stream << "$unsigned(";
2083  }
2084  }
2085 
2086  if (machine_.busNavigator().hasItem(slot)) {
2087  MoveSlot& mSlot = bem_.moveSlot(slot);
2088  stream << NetlistGenerator::DECODER_INSTR_WORD_PORT
2089  << "[" << mSlot.bitPosition() +
2090  iTemp.supportedWidth(slot) - 1
2091  << " : " << mSlot.bitPosition() << "]";
2092  } else {
2093  ImmediateSlotField& iSlot =
2094  bem_.immediateSlot(slot);
2095  stream << NetlistGenerator::DECODER_INSTR_WORD_PORT
2096  << "[" << iSlot.bitPosition() +
2097  iTemp.supportedWidth(slot) - 1
2098  << " : " << iSlot.bitPosition() << "]";
2099  }
2100 
2101  if (j == 0) {
2102  stream << ");" << endl;
2103  } else {
2104  stream << ";" << endl;
2105  }
2106  }
2107  if (iu->numberOfRegisters() > 1) {
2108  LImmDstRegisterField& field =
2110  iTemp.name(), iu->name());
2111  stream << indentation(indLevel)
2112  << iuWriteOpcodeCntrlSignal(iu->name())
2113  << " <= " << "$unsigned("
2114  << NetlistGenerator::DECODER_INSTR_WORD_PORT
2115  << "["
2116  << field.bitPosition() + rfOpcodeWidth(*iu) - 1
2117  << " : " << field.bitPosition() << "]);"
2118  << endl;
2119  }
2120  stream << indentation(indLevel)
2121  << iuWriteLoadCntrlSignal(iu->name()) << " <= 1'b1;"
2122  << endl;
2123  } else {
2124  stream << indentation(indLevel)
2125  << iuWriteLoadCntrlSignal(iu->name()) << " <= 1'b0;"
2126  << endl;
2127  }
2128  }
2129  }
2130  }
2131 }
2132 
2133 /**
2134  * Writes separate combinational decoding process for SRAM register files.
2135  *
2136  * @param stream The stream to write.
2137  */
2138 void
2140 const {
2141 
2142  set<const RegisterFile*> sramRFset;
2143  set<const RegisterFile*>::const_iterator sramrf_it;
2144 
2145  // Write only when there is SRAM RFs.
2146  bool hasSramRFs = false;
2147  const Machine::RegisterFileNavigator& rfNav =
2149  for (int i = 0; i < rfNav.count(); i++) {
2150  if(sacEnabled(rfNav.item(i)->name())) {
2151  hasSramRFs = true;
2152  sramRFset.insert(rfNav.item(i));
2153  }
2154  }
2155 
2156  if(!hasSramRFs) {
2157  return;
2158  }
2159 
2160  if (language_ == VHDL) {
2161  string resetPort = NetlistGenerator::DECODER_RESET_PORT;
2162 
2163  // Begin process //
2164  stream << indentation(1)
2165  << "-- separate SRAM RF read decoding process" << endl;
2166  stream << indentation(1) << "process (" << resetPort;
2167 
2168  // Sensitivity list //
2169  BusSet connectedToSramRFs;
2170  for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2171  sramrf_it++) {
2172  const RegisterFile& rf = **sramrf_it;
2173  assert(sacEnabled(rf.name()));
2174  for (int ip = 0; ip < rf.portCount(); ip++) {
2175  const RFPort& port = *rf.port(ip);
2176  if (port.outputSocket() != NULL) {
2177  BusSet tmp = connectedBuses(*port.outputSocket());
2178  connectedToSramRFs.insert(tmp.begin(), tmp.end());
2179  }
2180  }
2181  }
2182 
2183  BusSet::const_iterator busSet_it;
2184  for (busSet_it = connectedToSramRFs.begin();
2185  busSet_it != connectedToSramRFs.end();
2186  busSet_it++) {
2187  string busName = (*busSet_it)->name();
2188  stream << ", " << srcFieldSignal(busName)
2189  << ", " << squashSignal(busName);
2190  }
2191  stream << ")" << endl;
2192  stream << indentation(1) << "begin" << endl;
2193 
2194  // Signal resets //
2195  stream << indentation(2) << "if (" << resetPort << " = '0') then"
2196  << endl;
2197  for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2198  sramrf_it++) {
2199  const RegisterFile& rf = **sramrf_it;
2200  assert(sacEnabled(rf.name()));
2201  for (int i = 0; i < rf.portCount(); i++) {
2202  const RFPort& port = *rf.port(i);
2203  if (port.outputSocket() == NULL) {
2204  continue;
2205  }
2206 
2207  stream << indentation(3)
2208  << rfLoadSignalName(rf.name(), port.name(), true)
2209  << " <= '0';" << endl;
2210  if (0 < rfOpcodeWidth(rf)) {
2211  stream << indentation(3)
2212  << rfOpcodeSignalName(rf.name(), port.name(), true)
2213  << " <= (others => '0');" << endl;
2214  }
2215  }
2216  }
2217 
2218  // Write decoding rules //
2219  stream << endl << indentation(2) << "else" << endl;
2220  for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2221  sramrf_it++) {
2222  const RegisterFile& rf = **sramrf_it;
2223  assert(sacEnabled(rf.name()));
2224  for(int i = 0; i < rf.portCount(); i++) {
2225  const RFPort& port = *rf.port(i);
2226  if (port.outputSocket() != NULL) {
2227  writeControlRulesOfRFReadPort(port, stream);
2228  }
2229  }
2230  }
2231  stream << indentation(2) << "end if;" << endl;
2232 
2233  // End process //
2234  stream << indentation(1) << "end process;" << endl;
2235 
2236  } else { // language_ == VERILOG
2237  // Begin process //
2238  string resetPort = NetlistGenerator::DECODER_RESET_PORT;
2239 
2240  stream << indentation(1)
2241  << "// separate SRAM RF read decoding process" << endl;
2242  stream << indentation(1) << "always@(" << resetPort;
2243 
2244  // Sensitivity list //
2245  BusSet connectedToSramRFs;
2246  for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2247  sramrf_it++) {
2248  const RegisterFile& rf = **sramrf_it;
2249  assert(sacEnabled(rf.name()));
2250  for (int ip = 0; ip < rf.portCount(); ip++) {
2251  const RFPort& port = *rf.port(ip);
2252  if (port.outputSocket() != NULL) {
2253  BusSet tmp = connectedBuses(*port.outputSocket());
2254  connectedToSramRFs.insert(tmp.begin(), tmp.end());
2255  }
2256  }
2257  }
2258 
2259  BusSet::const_iterator busSet_it;
2260  for (busSet_it = connectedToSramRFs.begin();
2261  busSet_it != connectedToSramRFs.end();
2262  busSet_it++) {
2263  string busName = (*busSet_it)->name();
2264  stream << ", " << srcFieldSignal(busName)
2265  << ", " << squashSignal(busName);
2266  }
2267  stream << ")" << endl;
2268  stream << indentation(1) << "begin" << endl;
2269 
2270  // Signal resets //
2271  stream << indentation(2) << "if (" << resetPort << " == 0)" << endl
2272  << indentation(2) << "begin" << endl;
2273 
2274  for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2275  sramrf_it++) {
2276  const RegisterFile& rf = **sramrf_it;
2277  assert(sacEnabled(rf.name()));
2278  for (int i = 0; i < rf.portCount(); i++) {
2279  const RFPort& port = *rf.port(i);
2280  if (port.outputSocket() == NULL) {
2281  continue;
2282  }
2283 
2284  stream << indentation(3)
2285  << rfLoadSignalName(rf.name(), port.name(), true)
2286  << " <= 1'b0;" << endl;
2287  if (0 < rfOpcodeWidth(rf)) {
2288  stream << indentation(3)
2289  << rfOpcodeSignalName(rf.name(), port.name(), true)
2290  << " <= 0;" << endl;
2291  }
2292  }
2293  }
2294  stream << indentation(2) << "end" << endl;
2295 
2296  // Decoding rules //
2297  stream << indentation(2) << "else" << endl;
2298  stream << indentation(2) << "begin" << endl;
2299  for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2300  sramrf_it++) {
2301  const RegisterFile& rf = **sramrf_it;
2302  assert(sacEnabled(rf.name()));
2303  for(int i = 0; i < rf.portCount(); i++) {
2304  const RFPort& port = *rf.port(i);
2305  if (port.outputSocket() != NULL) {
2306  writeControlRulesOfRFReadPort(port, stream);
2307  }
2308  }
2309  }
2310  stream << indentation(2) << "end" << endl;
2311 
2312  // End process //
2313  stream << indentation(1) << "end // process" << endl;
2314  }
2315 }
2316 
2317 /**
2318  * Writes the main decoding process to the given stream.
2319  *
2320  * @param stream The stream to write.
2321  */
2322 void
2324  std::ostream& stream) const {
2325  if(language_==VHDL){
2326  string resetPort = NetlistGenerator::DECODER_RESET_PORT;
2327  string clockPort = NetlistGenerator::DECODER_CLOCK_PORT;
2328 
2329  stream << indentation(1) << "-- main decoding process" << endl;
2330  string listStr;
2331  stream << indentation(1) << "process (";
2332  stream << clockPort;
2333  if (!syncReset_) {
2334  stream << ", " << resetPort;
2335  }
2336  stream << ")" << endl;
2337  stream << indentation(1) << "begin" << endl;
2338 
2339  // if reset is active
2340  if (syncReset_) {
2341  stream << indentation(2) << "if (clk'event and clk = '1') then"
2342  << endl
2343  << indentation(2) << "if (" << resetPort << " = '0') then"
2344  << endl;
2346  stream << endl << indentation(2) << "else" << endl;
2347  } else {
2348  stream << indentation(2) << "if (" << resetPort << " = '0') then"
2349  << endl;
2351  stream << endl
2352  << indentation(2)
2353  << "elsif (clk'event and clk = '1') then "
2354  << "-- rising clock edge" << endl;
2355  }
2356  if (generateDebugger_) {
2357  string softResetPort = "db_tta_nreset";
2358  stream << indentation(3) << "if (" << softResetPort
2359  << " = '0') then"
2360  << endl;
2362  stream << indentation(3) << "elsif ("
2363  << PRE_DECODE_MERGED_GLOCK_SIGNAL << " = '0') then" << endl
2364  << endl;
2365  } else {
2366  stream << indentation(2) << "if ("
2368  stream << " = '0')";
2369  stream << " then" << endl << endl;
2370  }
2371 
2372  writeInstructionDecoding(stream);
2373  stream << indentation(3) << "end if;" << endl;
2374  stream << indentation(2) << "end if;" << endl;
2375  stream << indentation(1) << "end process;" << endl;
2376  } else {
2377  string resetPort = NetlistGenerator::DECODER_RESET_PORT;
2378  string clockPort = NetlistGenerator::DECODER_CLOCK_PORT;
2379 
2380  stream << indentation(1) << "// main decoding process" << endl
2381  << indentation(1) << "always@(posedge " << clockPort
2382  << " or negedge " << resetPort << ")" << endl
2383  // if reset is active
2384  << indentation(2) << "if (" << resetPort << " == 0)" << endl
2385  << indentation(2) <<"begin" << endl;
2387  stream << indentation(2) << "end" << endl
2388  << indentation(2) << "else" << endl
2389  << indentation(3) << "begin"<< endl
2390  << indentation(3) << "if ("
2391  << NetlistGenerator::DECODER_LOCK_REQ_IN_PORT
2392  << " == 0)" << endl << endl
2393  << indentation(3) << "begin"<< endl;
2394  writeInstructionDecoding(stream);
2395  stream << indentation(3) << "end" << endl
2396  << indentation(2) << "end" << endl;
2397  }
2398 }
2399 
2400 /**
2401  * Generates global lock and lock request wiring.
2402  */
2403 void
2404 DefaultDecoderGenerator::writeGlockMapping(std::ostream& stream) const {
2405  assert(
2406  language_ == VHDL &&
2407  "writeGlockMapping() is not yet implemented "
2408  "for other HDLs.");
2409 
2410  // Generate output register for core lock status signal //
2411  string propagateGlock(
2413  " <= " + POST_DECODE_MERGED_GLOCK_SIGNAL + ";");
2414  string assertGlock(POST_DECODE_MERGED_GLOCK_OUTREG + " <= '1'" + ";");
2415  if (syncReset_) {
2416  stream << " lock_reg_proc : process (clk)\n"
2417  << " begin\n"
2418  << " if (clk'event and clk = '1') then\n"
2419  << " if (rstx = '0') then\n"
2420  << " -- Locked during active reset"
2421  << " " << assertGlock << "\n"
2422  << " else\n"
2423  << " " << propagateGlock << "\n"
2424  << " end if;\n"
2425  << " end if;\n"
2426  << " end process lock_reg_proc;\n\n";
2427  } else {
2428  stream << " lock_reg_proc : process (clk, rstx)\n"
2429  << " begin\n"
2430  << " if (rstx = '0') then\n"
2431  << " -- Locked during active reset"
2432  << " " << assertGlock << "\n"
2433  << " elsif (clk'event and clk = '1') then\n"
2434  << " " << propagateGlock << "\n"
2435  << " end if;\n"
2436  << " end process lock_reg_proc;\n\n";
2437  }
2438 
2439  // Generate global lock request wiring //
2440  int lockReqWidth = glockRequestWidth();
2441  stream << indentation(1) << NetlistGenerator::DECODER_LOCK_REQ_OUT_PORT
2442  << " <= " << INTERNAL_MERGED_GLOCK_REQ_SIGNAL << ";" << endl;
2443  stream << indentation(1) << INTERNAL_MERGED_GLOCK_REQ_SIGNAL << " <= ";
2444  if (lockReqWidth > 0) {
2445  for (int i = 0; i < lockReqWidth; i++) {
2446  stream << LOCK_REQ_PORT_NAME << "(" << i << ")";
2447  if (i + 1 < lockReqWidth) {
2448  stream << " or ";
2449  }
2450  }
2451  stream << ";" << endl;
2452  } else {
2453  stream << "'0';" << endl;
2454  }
2455 
2457  << " <= " << NetlistGenerator::DECODER_LOCK_REQ_IN_PORT;
2458  if (lockReqWidth > 0) {
2459  stream << " or " << INTERNAL_MERGED_GLOCK_REQ_SIGNAL << ";" << endl;
2460  } else {
2461  stream << ";" << endl;
2462  }
2464  << " <= " << PRE_DECODE_MERGED_GLOCK_SIGNAL << " or "
2465  << PIPELINE_FILL_LOCK_SIGNAL << ";" << endl;
2466  stream << indentation(1) << NetlistGenerator::DECODER_LOCK_STATUS_PORT
2467  << " <= " << POST_DECODE_MERGED_GLOCK_OUTREG << ";" << endl;
2468 
2469  // Generate global lock wiring //
2470  const int glockWidth = glockPortWidth();
2471  for (GlockBitType glockBitToConnect = 0; glockBitToConnect < glockWidth;
2472  glockBitToConnect++) {
2473  stream << indentation(1) << GLOCK_PORT_NAME << "("
2474  << Conversion::toString(glockBitToConnect) << ") <= ";
2475 
2476  // If the feature for alternate glock wiring is enabled and current
2477  // glock signal to be wired for the TTA Unit has glock request port.
2479  MapTools::containsKey(unitGlockBitMap_, glockBitToConnect) &&
2482  unitGlockBitMap_.find(glockBitToConnect)->second)) {
2483  // Specialized global lock port map to avoid self-locking of FU.
2484  // Each FU that has global lock request will not receive
2485  // global lock signal unless another FU request global lock.
2486  const Unit* associatedToGlockReq =
2487  unitGlockBitMap_.find(glockBitToConnect)->second;
2488  UnitGlockReqBitMapType::const_iterator gr_it;
2489  for (gr_it = unitGlockReqBitMap_.begin();
2490  gr_it != unitGlockReqBitMap_.end(); gr_it++) {
2491  if (gr_it->first == associatedToGlockReq) {
2492  continue;
2493  }
2494  GlockReqBitType glockReqBitToConnect = gr_it->second;
2495  stream << LOCK_REQ_PORT_NAME << "("
2496  << Conversion::toString(glockReqBitToConnect)
2497  << ") or ";
2498  }
2499  stream << NetlistGenerator::DECODER_LOCK_REQ_IN_PORT << ";";
2500  } else {
2501  // Regular global lock port map.
2502  stream << POST_DECODE_MERGED_GLOCK_SIGNAL << ";";
2503  }
2504  if (MapTools::containsKey(unitGlockBitMap_, glockBitToConnect)) {
2505  stream
2506  << " -- to "
2507  << unitGlockBitMap_.find(glockBitToConnect)->second->name();
2508  }
2509  stream << endl;
2510  }
2511 }
2512 
2513 /**
2514  * Writes process that keeps machine locked until first decoded instruction is
2515  * available.
2516  */
2517 void
2519  std::ostream& stream) const {
2520  auto indstream = [&](unsigned level) -> std::ostream& {
2521  stream << indentation(level);
2522  return stream;
2523  };
2524  if (language_ == VHDL) {
2525  if (syncReset_) {
2526  indstream(1) << "decode_pipeline_fill_lock: process (clk)"
2527  << endl;
2528  indstream(1) << "begin" << endl;
2529  indstream(2) << "if clk'event and clk = '1' then" << endl;
2530  indstream(3) << "if rstx = '0' then" << endl;
2531  indstream(4) << PIPELINE_FILL_LOCK_SIGNAL << " <= '1';" << endl;
2532  indstream(3) << "elsif lock = '0' then" << endl;
2533  } else {
2534  indstream(1) << "decode_pipeline_fill_lock: process (clk, rstx)"
2535  << endl;
2536  indstream(1) << "begin" << endl;
2537  indstream(2) << "if rstx = '0' then" << endl;
2538  indstream(3) << PIPELINE_FILL_LOCK_SIGNAL << " <= '1';" << endl;
2539  indstream(2) << "elsif clk'event and clk = '1' then" << endl;
2540  indstream(3) << "if lock = '0' then" << endl;
2541  }
2542  indstream(4) << "decode_fill_lock_reg <= '0';" << endl;
2543  indstream(3) << "end if;" << endl;
2544  indstream(2) << "end if;" << endl;
2545  indstream(1) << "end process decode_pipeline_fill_lock;" << endl;
2546 
2547  } else { // language_ == Verilog
2548  // todo
2549  }
2550 }
2551 
2552 /**
2553  * Writes resetting of all the control registers to the given stream.
2554  *
2555  * @param stream The stream.
2556  */
2557 void
2559  std::ostream& stream) const {
2560  std::string vector_reset = " <= (others => '0');";
2561  std::string bit_reset = " <= '0';";
2562  if (language_ == Verilog) {
2563  vector_reset = " <= 0;";
2564  bit_reset = " <= 1'b0;";
2565  }
2566 
2567  for (auto const& signal : registerVectors) {
2568  stream << indentation(3) << signal << vector_reset << endl;
2569  }
2570  stream << endl;
2571  for (auto const& signal : registerBits) {
2572  stream << indentation(3) << signal << bit_reset << endl;
2573  }
2574  stream << endl;
2575 }
2576 
2577 /**
2578  * Writes the instruction decoding section to the main process in decoder.
2579  *
2580  * @param stream The stream to write.
2581  */
2582 void
2584  std::ostream& stream) const {
2585 
2587  stream << endl;
2589 }
2590 
2591 
2592 /**
2593  * Writes the rules for source control signals to the instruction
2594  * decoding section.
2595  *
2596  * @param stream The stream to write.
2597  */
2598 void
2600  std::ostream& stream) const {
2601  int indent;
2602  indent = 4;
2603 
2605  for (int i = 0; i < socketNav.count(); i++) {
2606  Socket* socket = socketNav.item(i);
2607  if (socket->direction() == Socket::OUTPUT &&
2608  socket->segmentCount() > 0 && socket->portCount() > 0) {
2609  writeBusControlRulesOfOutputSocket(*socket, stream);
2610  }
2611 
2612  writeComment(
2613  stream, indent,
2614  "bus control signals for short immediate sockets");
2616  for (int i = 0; i < busNav.count(); i++) {
2617  Bus* bus = busNav.item(i);
2618  if (bus->immediateWidth() > 0) {
2620  }
2621  }
2622  }
2623 
2624  writeComment(
2625  stream, indent,
2626  "data control signals for output sockets connected to FUs");
2628  for (int i = 0; i < fuNav.count(); i++) {
2629  FunctionUnit* fu = fuNav.item(i);
2630  for (int i = 0; i < fu->portCount(); i++) {
2631  BaseFUPort* port = fu->port(i);
2632  if (port->outputSocket() != NULL &&
2633  port->outputSocket()->portCount() > 1) {
2634  writeControlRulesOfFUOutputPort(*port, stream);
2635  }
2636  }
2637  }
2638 
2639  ControlUnit* gcu = machine_.controlUnit();
2640  for (int i = 0; i < gcu->portCount(); i++) {
2641  BaseFUPort* port = gcu->port(i);
2642  if (port->outputSocket() != NULL &&
2643  port->outputSocket()->portCount() > 1) {
2644  writeControlRulesOfFUOutputPort(*port, stream);
2645  }
2646  }
2647 
2648  writeComment(stream, indent, "control signals for RF read ports");
2650  for (int i = 0; i < rfNav.count(); i++) {
2651  RegisterFile* rf = rfNav.item(i);
2652  // Skip RFs with separate address cycle flag enabled.
2653  if (sacEnabled(rf->name())) {
2654  continue;
2655  }
2656  for (int i = 0; i < rf->portCount(); i++) {
2657  RFPort* port = rf->port(i);
2658  if (port->outputSocket() != NULL) {
2659  writeControlRulesOfRFReadPort(*port, stream);
2660  }
2661  }
2662  }
2663 
2664  stream << endl
2665  << indentation(indent) << ((language_ == VHDL) ? "--" : "//")
2666  << "control signals for IU read ports" << endl;
2667  writeComment(stream, indent, "control signals for IU read ports");
2670  for (int i = 0; i < iuNav.count(); i++) {
2671  ImmediateUnit* iu = iuNav.item(i);
2672  for (int i = 0; i < iu->portCount(); i++) {
2673  RFPort* port = iu->port(i);
2674  if (port->outputSocket() != NULL) {
2675  writeControlRulesOfRFReadPort(*port, stream);
2676  }
2677  }
2678  }
2679 }
2680 
2681 
2682 /**
2683  * Writes the rules for destination control signals to the instruction
2684  * decoding section.
2685  *
2686  * @param stream The stream to write.
2687  */
2688 void
2690  std::ostream& stream) const {
2691  writeComment(stream, 4, "control signals for FU inputs");
2693  for (int i = 0; i < fuNav.count(); i++) {
2694  FunctionUnit* fu = fuNav.item(i);
2695  for (int i = 0; i < fu->portCount(); i++) {
2696  BaseFUPort* port = fu->port(i);
2697  if (port->inputSocket() != NULL) {
2698  writeControlRulesOfFUInputPort(*port, stream);
2699  }
2700  }
2701  }
2702 
2703  ControlUnit* gcu = machine_.controlUnit();
2704  for (int i = 0; i < gcu->portCount(); i++) {
2705  BaseFUPort* port = gcu->port(i);
2706  if (port->inputSocket() != NULL) {
2707  writeControlRulesOfFUInputPort(*port, stream);
2708  }
2709  }
2710 
2711  writeComment(stream, 4, "control signals for RF inputs");
2713  for (int i = 0; i < rfNav.count(); i++) {
2714  RegisterFile* rf = rfNav.item(i);
2715  for (int i = 0; i < rf->portCount(); i++) {
2716  RFPort* port = rf->port(i);
2717  if (port->inputSocket() != NULL) {
2718  writeControlRulesOfRFWritePort(*port, stream);
2719  }
2720  }
2721  }
2722 }
2723 
2724 /**
2725  * Writes the control signal rules of the given output socket.
2726  *
2727  * @param socket The socket.
2728  * @param stream The stream to write.
2729  */
2730 void
2732  const TTAMachine::Socket& socket,
2733  std::ostream& stream) const {
2734 
2735  assert(socket.direction() == Socket::OUTPUT);
2736  if(language_==VHDL){
2737  int indent;
2738  indent = 4;
2739  // collect to a set all the buses the socket is connected to
2741  for (BusSet::const_iterator iter = connectedBuses.begin();
2742  iter != connectedBuses.end(); iter++) {
2743  Bus* bus = *iter;
2744  MoveSlot& slot = bem_.moveSlot(bus->name());
2745  SourceField& srcField = slot.sourceField();
2746  stream << indentation(indent) << "if ("
2747  << squashSignal(bus->name()) << " = '0' and ";
2748  stream << socketEncodingCondition(VHDL, srcField, socket.name());
2749  stream << ") then" << endl;
2750  string busCntrlPin = busCntrlSignalPinOfSocket(socket, *bus);
2751  stream << indentation(indent + 1) << busCntrlPin << " <= '1';"
2752  << endl;
2753 
2754  stream << indentation(indent) << "else" << endl;
2755  stream << indentation(indent + 1) << busCntrlPin << " <= '0';"
2756  << endl;
2757  stream << indentation(indent) << "end if;" << endl;
2758  }
2759  } else{
2760  // collect to a set all the buses the socket is connected to
2762  for (BusSet::const_iterator iter = connectedBuses.begin();
2763  iter != connectedBuses.end(); iter++) {
2764  Bus* bus = *iter;
2765  MoveSlot& slot = bem_.moveSlot(bus->name());
2766  SourceField& srcField = slot.sourceField();
2767  stream << indentation(4) << "if ("
2768  << squashSignal(bus->name()) << " == 0 && "
2769  << socketEncodingCondition(Verilog, srcField, socket.name()) << ")"
2770  << endl;
2771  string busCntrlPin = busCntrlSignalPinOfSocket(socket, *bus);
2772  stream << indentation(5) << busCntrlPin << " <= 1'b1;" << endl
2773  << indentation(4) << "else" << endl
2774  << indentation(5) << busCntrlPin << " <= 1'b0;" << endl << endl;
2775  }
2776  }
2777 }
2778 
2779 void
2781  const TTAMachine::Bus& bus, std::ostream& stream) const {
2782  int indent;
2783  indent = 4;
2784  SourceField& srcField = bem_.moveSlot(bus.name()).sourceField();
2785  ImmediateEncoding& enc = srcField.immediateEncoding();
2786  stream << indentation(indent) << simmDataSignalName(bus.name()) << " <= ";
2787  if (bus.signExtends()) {
2788  stream << "tce_sxt(";
2789  } else {
2790  stream << "tce_ext(";
2791  }
2792  stream << srcFieldSignal(bus.name()) << "("
2793  << enc.immediatePosition() + enc.immediateWidth() - 1 << " downto "
2794  << enc.immediatePosition() << "), "
2795  << simmDataSignalName(bus.name()) << "'length);" << endl;
2796 }
2797 
2798 /**
2799  * Writes the control signal rules for the socket that transports the short
2800  * immediate to the given bus.
2801  *
2802  * @param bus The bus.
2803  * @param stream The stream to write.
2804  */
2805 void
2807  const TTAMachine::Bus& bus,
2808  std::ostream& stream) const {
2809 
2810  assert(bus.immediateWidth() > 0);
2811  MoveSlot& slot = bem_.moveSlot(bus.name());
2812  SourceField& srcField = slot.sourceField();
2813  assert(srcField.hasImmediateEncoding());
2814  ImmediateEncoding& enc = srcField.immediateEncoding();
2815 
2816  if(language_==VHDL){
2817  int indent = 4;
2818  stream << indentation(indent) << "if (" << squashSignal(bus.name())
2819  << " = '0'";
2820  if (enc.encodingWidth() > 0) {
2821  stream << " and ";
2822  stream << "conv_integer(unsigned(" << srcFieldSignal(bus.name())
2823  << "(" << enc.encodingPosition() + enc.encodingWidth() - 1
2824  << " downto " << enc.encodingPosition()
2825  << "))) = " << enc.encoding();
2826  }
2827 
2828  stream << ") then" << endl;
2829  stream << indentation(indent + 1) << simmCntrlSignalName(bus.name())
2830  << "(0) <= '1';" << endl;
2831  writeSimmDataSignal(bus, stream);
2832  stream << indentation(indent) << "else" << endl;
2833  stream << indentation(indent + 1) << simmCntrlSignalName(bus.name())
2834  << "(0) <= '0';" << endl;
2835  stream << indentation(4) << "end if;" << endl;
2836  } else {
2837  stream << indentation(4) << "if ("
2838  << squashSignal(bus.name()) << " == 0";
2839  if (enc.encodingWidth() > 0) {
2840  stream << " && "
2841  << srcFieldSignal(bus.name()) << "["
2842  << enc.encodingPosition() + enc.encodingWidth() - 1 << " : "
2843  << enc.encodingPosition() << "] == " << enc.encoding();
2844  }
2845  stream << ")" << endl << indentation(4) << "begin" << endl;
2846  stream << indentation(5) << simmCntrlSignalName(bus.name())
2847  << "[0] <= 1'b1;" << endl;
2848  stream << indentation(5) << simmDataSignalName(bus.name()) << " <= ";
2849 
2850  if (bus.signExtends()) {
2851  stream << "$signed(";
2852  } else {
2853  stream << "$unsigned(";
2854  }
2855  stream << srcFieldSignal(bus.name()) << "["
2856  << enc.immediatePosition() + enc.immediateWidth() - 1
2857  << " : " << enc.immediatePosition() << "]);" << endl
2858  << indentation(4) << "end" << endl
2859  << indentation(4) << "else" << endl
2860  << indentation(4) << "begin" << endl
2861  << indentation(5) << simmCntrlSignalName(bus.name())
2862  << "[0] <= 1'b0;" << endl
2863  << indentation(4) << "end" << endl;
2864  }
2865 }
2866 
2867 
2868 /**
2869  * Writes the data control signal rules of the socket connected to the given
2870  * FU output port.
2871  *
2872  * @param port The port.
2873  * @param stream The stream to write.
2874  */
2875 void
2877  const TTAMachine::BaseFUPort& port,
2878  std::ostream& stream) const {
2879  int indent = 4;
2880 
2881  Socket* socket = port.outputSocket();
2882  assert(socket != NULL);
2884  if(language_==VHDL){
2885  for (BusSet::const_iterator iter = connectedBuses.begin();
2886  iter != connectedBuses.end(); iter++) {
2887  Bus* bus = *iter;
2888  MoveSlot& slot = bem_.moveSlot(bus->name());
2889  SourceField& srcField = slot.sourceField();
2890  SocketEncoding& enc = srcField.socketEncoding(socket->name());
2891  stream << indentation(indent) << "if ("
2892  << squashSignal(bus->name()) << " = '0' and ";
2893  stream << socketEncodingCondition(VHDL, srcField, socket->name());
2894  if (enc.hasSocketCodes()) {
2895  SocketCodeTable& scTable = enc.socketCodes();
2896  FUPortCode& code = scTable.fuPortCode(
2897  port.parentUnit()->name(), port.name());
2898  stream << " and " << portCodeCondition(VHDL, enc, code)
2899  << ") then" << endl;
2900  } else {
2901  stream << ") then" << endl;
2902  }
2903  stream << indentation(indent + 1)
2904  << socketDataCntrlSignalName(socket->name()) << " <= "
2905  << "conv_std_logic_vector("
2906  << icGenerator_.outputSocketDataControlValue(*socket, port)
2907  << ", " << socketDataCntrlSignalName(socket->name())
2908  << "'length);" << endl;
2909  stream << indentation(indent) << "end if;" << endl;
2910  }
2911  } else {
2912  for (BusSet::const_iterator iter = connectedBuses.begin();
2913  iter != connectedBuses.end(); iter++) {
2914  Bus* bus = *iter;
2915  MoveSlot& slot = bem_.moveSlot(bus->name());
2916  SourceField& srcField = slot.sourceField();
2917  SocketEncoding& enc = srcField.socketEncoding(socket->name());
2918  stream << indentation(indent) << "if ("
2919  << squashSignal(bus->name()) << " == 0 && "
2921  Verilog, srcField, socket->name());
2922  if (enc.hasSocketCodes()) {
2923  SocketCodeTable& scTable = enc.socketCodes();
2924  FUPortCode& code = scTable.fuPortCode(
2925  port.parentUnit()->name(), port.name());
2926  stream << " && " << portCodeCondition(Verilog, enc, code) << ")"
2927  << endl;
2928  } else {
2929  stream << ")" << endl;
2930  }
2931  stream << indentation(indent)
2932  << socketDataCntrlSignalName(socket->name()) << " <= "
2933  << icGenerator_.outputSocketDataControlValue(*socket, port)
2934  << ";" << endl;
2935  }
2936  }
2937 }
2938 
2939 
2940 /**
2941  * Writes the control signal rules related to the given RF read port.
2942  *
2943  * @param port The RF read port.
2944  * @param stream The stream to write.
2945  */
2946 void
2948  const TTAMachine::RFPort& port,
2949  std::ostream& stream) const {
2950  int indent = 4;
2951  assert(port.outputSocket() != NULL);
2952 
2953  // Do not write load signal when port is bidirectional
2954  // (where load = write enable)
2955  bool writeLoadSignal = true;
2956  if (port.inputSocket() != NULL) {
2957  writeLoadSignal = false;
2958  }
2959 
2960  Socket* socket = port.outputSocket();
2961  BaseRegisterFile* rf = port.parentUnit();
2962  bool async_signal = sacEnabled(rf->name());
2963 
2964  // collect to a set all the buses the socket is connected to
2966  string opcodeString = "";
2967  if (language_ == VHDL) {
2968  for (BusSet::const_iterator iter = connectedBuses.begin();
2969  iter != connectedBuses.end();iter++) {
2970  BusSet::const_iterator nextIter = iter;
2971  nextIter++;
2972  if (iter == connectedBuses.begin()) {
2973  stream << indentation(indent) << "if (";
2974  } else {
2975  stream << indentation(indent) << "elsif (";
2976  }
2977 
2978  Bus* bus = *iter;
2979  MoveSlot& slot = bem_.moveSlot(bus->name());
2980  SourceField& srcField = slot.sourceField();
2981  SocketEncoding& enc = srcField.socketEncoding(socket->name());
2982  SocketCodeTable* scTable = NULL;
2983  if (enc.hasSocketCodes()) {
2984  scTable = &enc.socketCodes();
2985  }
2986 
2987  PortCode* code = NULL;
2988  if (scTable != NULL) {
2989  if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
2990  code = &scTable->iuPortCode(rf->name());
2991  } else {
2992  code = &scTable->rfPortCode(rf->name());
2993  }
2994  }
2995  stream << squashSignal(bus->name()) << " = '0' and ";
2996  stream << socketEncodingCondition(VHDL, srcField, socket->name());
2997  if (code != NULL && code->hasEncoding()) {
2998  stream << " and " << portCodeCondition(VHDL, enc, *code);
2999  }
3000  stream << ") then" << endl;
3001 
3002  string loadSignalName;
3003  string opcodeSignalName;
3004  if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3005  loadSignalName =
3006  iuReadLoadCntrlPort(rf->name(), port.name());
3007  opcodeSignalName =
3008  iuReadOpcodeCntrlPort(rf->name(), port.name());
3009  } else {
3010  loadSignalName = rfLoadSignalName(rf->name(), port.name(),
3011  async_signal);
3012  opcodeSignalName = rfOpcodeSignalName(rf->name(), port.name(),
3013  async_signal);
3014  }
3015  if (writeLoadSignal) {
3016  stream << indentation(indent + 1) << loadSignalName
3017  << " <= '1';" << endl;
3018  }
3019  if (code != NULL) {
3020  opcodeString = indentation(indent + 1) + opcodeSignalName +
3021  " <= tce_ext(" +
3022  rfOpcodeFromSrcOrDstField(VHDL, enc, *code) +
3023  ", " + opcodeSignalName + "'length);";
3024  stream << opcodeString << endl;
3025  }
3026 
3027  if (needsDataControl(*socket)) {
3028  stream << indentation(indent)
3029  << socketDataCntrlSignalName(socket->name())
3030  << " <= conv_std_logic_vector("
3032  *socket, port)
3033  << ", " << socketDataCntrlSignalName(socket->name())
3034  << "'length);" << endl;
3035  }
3036  }
3037 
3038  if (writeLoadSignal) {
3039  stream << indentation(indent) << "else" << endl;
3040  stream << indentation(indent + 1);
3041  if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3042  stream << iuReadLoadCntrlPort(rf->name(), port.name());
3043  } else {
3044  stream << rfLoadSignalName(
3045  rf->name(), port.name(), async_signal);
3046  }
3047  stream << " <= '0';" << endl;
3048  }
3049  stream << indentation(indent) << "end if;" << endl;
3050  } else { // language_ == Verilog
3051  for (BusSet::const_iterator iter = connectedBuses.begin();
3052  iter != connectedBuses.end();iter++) {
3053  BusSet::const_iterator nextIter = iter;
3054  nextIter++;
3055  if (iter == connectedBuses.begin()) {
3056  stream << indentation(4) << "if (";
3057  } else {
3058  stream << indentation(4) << "else if(";
3059  }
3060 
3061  Bus* bus = *iter;
3062  MoveSlot& slot = bem_.moveSlot(bus->name());
3063  SourceField& srcField = slot.sourceField();
3064  SocketEncoding& enc = srcField.socketEncoding(socket->name());
3065  SocketCodeTable* scTable = NULL;
3066  if (enc.hasSocketCodes()) {
3067  scTable = &enc.socketCodes();
3068  }
3069 
3070  PortCode* code = NULL;
3071  if (scTable != NULL) {
3072  if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3073  code = &scTable->iuPortCode(rf->name());
3074  } else {
3075  code = &scTable->rfPortCode(rf->name());
3076  }
3077  }
3078  stream << squashSignal(bus->name()) << " == 0 && "
3079  << socketEncodingCondition(Verilog, srcField, socket->name());
3080  if (code != NULL && code->hasEncoding()) {
3081  stream << " && " << portCodeCondition(Verilog, enc, *code);
3082  }
3083  stream << ")" << endl
3084  << indentation(4) << "begin" << endl;
3085 
3086  string loadSignalName;
3087  string opcodeSignalName;
3088  if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3089  loadSignalName =
3090  iuReadLoadCntrlSignal(rf->name(), port.name());
3091  opcodeSignalName =
3092  iuReadOpcodeCntrlSignal(rf->name(), port.name());
3093  } else {
3094  loadSignalName = rfLoadSignalName(rf->name(), port.name(),
3095  async_signal);
3096  opcodeSignalName = rfOpcodeSignalName(rf->name(), port.name(),
3097  async_signal);
3098  }
3099 
3100  stream << indentation(5) << loadSignalName << " <= 1'b1;" << endl;
3101  if (code != NULL) {
3102  stream << indentation(5) << opcodeSignalName
3103  << " <= $unsigned("
3104  << rfOpcodeFromSrcOrDstField(Verilog, enc, *code)
3105  << ");" << endl;
3106  }
3107 
3108  if (needsDataControl(*socket)) {
3109  stream << indentation(5)
3110  << socketDataCntrlSignalName(socket->name())
3111  << " <= "
3112  << icGenerator_.outputSocketDataControlValue(*socket, port)
3113  << ";" << endl;
3114  }
3115  stream << indentation(4) << "end" << endl;
3116  }
3117  stream << indentation(4) << "else" << endl
3118  << indentation(4) << "begin" << endl
3119  << indentation(5);
3120  if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3121  stream << iuReadLoadCntrlSignal(rf->name(), port.name());
3122  } else {
3123  stream << rfLoadSignalName(rf->name(), port.name(), async_signal);
3124  }
3125  stream << " <= 1'b0;" << endl
3126  << indentation(4) << "end" << endl;
3127  }
3128 }
3129 
3130 
3131 /**
3132  * Writes the rules for control signals related to the given FU input port.
3133  *
3134  * @param port The port.
3135  * @param stream The stream to write.
3136  */
3137 void
3139  const TTAMachine::BaseFUPort& port,
3140  std::ostream& stream) const {
3141  int indent = 4;
3142  FunctionUnit* fu = port.parentUnit();
3143  Socket* socket = port.inputSocket();
3144  assert(socket != NULL);
3145  BusSet buses = connectedBuses(*socket);
3146  stream << indentation(indent) << "if (";
3147  if(language_==VHDL){
3148  string opcodeAssignString = "";
3149  string cntrlSignalString = "";
3150  for (BusSet::const_iterator iter = buses.begin(); iter != buses.end();
3151  iter++) {
3152  Bus* bus = *iter;
3153  MoveSlot& moveSlot = bem_.moveSlot(bus->name());
3154  DestinationField& dstField = moveSlot.destinationField();
3155  SocketEncoding& enc = dstField.socketEncoding(socket->name());
3156  stream << squashSignal(bus->name()) << " = '0' and ";
3157  stream << socketEncodingCondition(VHDL, dstField, socket->name());
3158  if (enc.hasSocketCodes()) {
3159  SocketCodeTable& scTable = enc.socketCodes();
3160  if (port.isOpcodeSetting()) {
3161  stream << ") then" << endl;
3162 
3163  ControlUnit* gcu = dynamic_cast<ControlUnit*>(fu);
3164 
3165  // Check
3166  bool ordered=true;
3167  for (int i = 0; i < fu->operationCount(); i++) {
3168  HWOperation* operation = fu->operation(i);
3169  FUPortCode& code = scTable.fuPortCode(
3170  fu->name(), port.name(), operation->name());
3171  if ((int)(code.encoding()) != (int)(opcode(*operation))) {
3172  ordered=false;
3173  break;
3174  }
3175  }
3176  if (!ordered) {
3177  stream << indentation(indent + 1) << "if (";
3178  for (int i = 0; i < fu->operationCount(); i++) {
3179  HWOperation* operation = fu->operation(i);
3180  FUPortCode& code = scTable.fuPortCode(
3181  fu->name(), port.name(), operation->name());
3182  stream << portCodeCondition(VHDL, enc, code) << ") then"
3183  << endl;
3184  stream
3185  << indentation(indent + 2)
3186  << fuLoadSignalName(fu->name(), port.name())
3187  << " <= '1';" << endl;
3188  if (gcu != nullptr) {
3189  if (operation->name() == JUMP) {
3190  stream << indentation(indent + 2)
3191  << fuOpcodeSignalName(fu->name())
3192  << " <= "
3193  "std_logic_vector(conv_"
3194  "unsigned(IFE_JUMP, "
3195  << fuOpcodeSignalName(fu->name())
3196  << "'length));" << endl;
3197  } else if (operation->name() == CALL) {
3198  stream << indentation(indent + 2)
3199  << fuOpcodeSignalName(fu->name())
3200  << " <= "
3201  "std_logic_vector(conv_"
3202  "unsigned(IFE_CALL, "
3203  << fuOpcodeSignalName(fu->name())
3204  << "'length));" << endl;
3205  }
3206  } else {
3207  stream << indentation(indent + 2)
3208  << fuOpcodeSignalName(fu->name())
3209  << " <= conv_std_logic_vector("
3210  << opcode(*operation) << ", "
3211  << fuOpcodeSignalName(fu->name())
3212  << "'length);" << endl;
3213  }
3214  if (i+1 < fu->operationCount()) {
3215  stream << indentation(indent + 1)
3216  << "elsif (";
3217  }
3218  }
3219  stream << indentation(indent + 1) << "else" << endl;
3220  stream << indentation(indent + 2)
3221  << fuLoadSignalName(fu->name(), port.name())
3222  << " <= '0';" << endl;
3223  stream << indentation(indent + 1) << "end if;"
3224  << endl;
3225  } else {
3226  FUPortCode& code = scTable.fuPortCode(
3227  fu->name(), port.name(), fu->operation(0)->name());
3228  SlotField* parent = enc.parent();
3229  string signalName;
3230  if (dynamic_cast<SourceField*>(parent) != NULL) {
3231  signalName = srcFieldSignal(parent->parent()->name());
3232  } else {
3233  signalName = dstFieldSignal(parent->parent()->name());
3234  }
3235 
3236  int codeStart;
3237  if (parent->componentIDPosition() == BinaryEncoding::RIGHT) {
3238  codeStart = enc.socketIDWidth() + code.indexWidth();
3239  } else {
3240  codeStart = code.indexWidth();
3241  }
3242  int codeEnd = codeStart + code.encodingWidth() - 1;
3243  assert(codeEnd >= codeStart);
3244  stream << indentation(indent + 1)
3245  << fuLoadSignalName(fu->name(), port.name())
3246  << " <= '1';" << endl;
3247  opcodeAssignString =
3248  indentation(indent + 1) +
3249  fuOpcodeSignalName(fu->name()) +
3250  " <= " + signalName + "(" +
3251  Conversion::toString(codeEnd) + " downto " +
3252  Conversion::toString(codeStart) + ")" + ";";
3253  stream << opcodeAssignString << endl;
3254  }
3255  } else {
3256  FUPortCode& code = scTable.fuPortCode(
3257  fu->name(), port.name());
3258  stream << " and " << portCodeCondition(VHDL, enc, code) << ") then"
3259  << endl;
3260  stream << indentation(indent + 1)
3261  << fuLoadSignalName(fu->name(), port.name())
3262  << " <= '1';" << endl;
3263  }
3264 
3265  } else {
3266  stream << ") then" << endl;
3267  stream << indentation(indent + 1)
3268  << fuLoadSignalName(fu->name(), port.name())
3269  << " <= '1';" << endl;
3270  }
3271  if (needsBusControl(*socket)) {
3272  cntrlSignalString =
3273  indentation(indent + 1) +
3274  socketBusCntrlSignalName(socket->name()) +
3275  " <= conv_std_logic_vector(" +
3277  *socket, *bus->segment(0))) +
3278  ", " + socketBusCntrlSignalName(socket->name()) +
3279  "'length);";
3280  stream << cntrlSignalString << endl;
3281  }
3282 
3283  BusSet::const_iterator nextIter = iter;
3284  nextIter++;
3285  if (nextIter != buses.end()) {
3286  stream << indentation(indent) << "elsif (";
3287  };
3288  }
3289 
3290  stream << indentation(indent) << "else" << endl;
3291  stream << indentation(indent + 1)
3292  << fuLoadSignalName(fu->name(), port.name()) << " <= '0';"
3293  << endl;
3294  stream << indentation(indent) << "end if;" << endl;
3295  } else { // language == Verilog
3296  for (BusSet::const_iterator iter = buses.begin(); iter != buses.end();
3297  iter++) {
3298  Bus* bus = *iter;
3299  MoveSlot& moveSlot = bem_.moveSlot(bus->name());
3300  DestinationField& dstField = moveSlot.destinationField();
3301  SocketEncoding& enc = dstField.socketEncoding(socket->name());
3302  stream << squashSignal(bus->name()) << " == 0 && "
3303  << socketEncodingCondition(Verilog, dstField, socket->name());
3304  if (enc.hasSocketCodes()) {
3305  SocketCodeTable& scTable = enc.socketCodes();
3306  if (port.isOpcodeSetting()) {
3307  stream << ")" << endl
3308  << indentation(4) << "begin" << endl
3309  << indentation(5) << "if (";
3310  for (int i = 0; i < fu->operationCount(); i++) {
3311  HWOperation* operation = fu->operation(i);
3312  FUPortCode& code = scTable.fuPortCode(
3313  fu->name(), port.name(), operation->name());
3314  stream << portCodeCondition(Verilog, enc, code) << ")"
3315  << endl
3316  << indentation(5) << "begin" << endl
3317  << indentation(6)
3318  << fuLoadSignalName(fu->name(), port.name())
3319  << " <= 1'b1;" << endl;
3320  ControlUnit* gcu = dynamic_cast<ControlUnit*>(fu);
3321  if (gcu != NULL) {
3322  if (operation->name() == JUMP) {
3323  stream << indentation(5)
3324  << fuOpcodeSignalName(fu->name())
3325  << " <= IFE_JUMP;" << endl;
3326  } else if (operation->name() == CALL) {
3327  stream << indentation(5)
3328  << fuOpcodeSignalName(fu->name())
3329  << " <= IFE_CALL;" << endl;
3330  }
3331  } else {
3332  stream << indentation(6)
3333  << fuOpcodeSignalName(fu->name())
3334  << " <= "
3335  << opcode(*operation)
3336  << ";"
3337  << endl;
3338  }
3339  if (i+1 < fu->operationCount()) {
3340  stream << indentation(5) << "end" << endl
3341  << indentation(5) << "else if (";
3342  }
3343  }
3344  stream << indentation(5) << "end" << endl
3345  << indentation(5) << "else" << endl
3346  << indentation(6)
3347  << fuLoadSignalName(fu->name(), port.name())
3348  << " <= 1'b0;"
3349  << endl;
3350  } else {
3351  FUPortCode& code = scTable.fuPortCode(
3352  fu->name(), port.name());
3353  stream << " && " << portCodeCondition(Verilog, enc, code) << ")"
3354  << endl
3355  << indentation(4) << "begin" << endl
3356  << indentation(5)
3357  << fuLoadSignalName(fu->name(), port.name())
3358  << " <= 1'b1;" << endl;
3359  }
3360  } else {
3361  stream << ")" << endl
3362  << indentation(4) << "begin" << endl
3363  << indentation(5)
3364  << fuLoadSignalName(fu->name(), port.name()) << " <= 1'b1;"
3365  << endl;
3366  ControlUnit* gcu = dynamic_cast<ControlUnit*>(fu);
3367  if (gcu != NULL) {
3368  if (gcu->hasOperation(JUMP)) {
3369  HWOperation* jumpOp = gcu->operation(JUMP);
3370  if (&port == jumpOp->port(1)) {
3371  stream << indentation(5)
3372  << fuOpcodeSignalName(fu->name())
3373  << " <= IFE_JUMP;" << endl;
3374  }
3375  }
3376  if (gcu->hasOperation(CALL)) {
3377  HWOperation* callOp = gcu->operation(CALL);
3378  if (&port == callOp->port(1)) {
3379  stream << indentation(5)
3380  << fuOpcodeSignalName(fu->name())
3381  << " <= IFE_CALL;" << endl;
3382  }
3383  }
3384  }
3385  }
3386  if (needsBusControl(*socket)) {
3387  stream << indentation(5)
3388  << socketBusCntrlSignalName(socket->name())
3389  << " <= "
3391  *socket, *bus->segment(0)) << ";"
3392  << endl;
3393  }
3394 
3395  BusSet::const_iterator nextIter = iter;
3396  nextIter++;
3397  stream << indentation(4) << "end" << endl;
3398  if (nextIter != buses.end()) {
3399  stream << indentation(4) << "else if(";
3400  };
3401  }
3402 
3403  stream << indentation(4) << "else" << endl;
3404  stream << indentation(5) << fuLoadSignalName(fu->name(), port.name())
3405  << " <= 1'b0;" << endl;
3406  }
3407 }
3408 
3409 
3410 /**
3411  * Writes the rules for control signals related to the given RF write port.
3412  *
3413  * @param port The port.
3414  * @param stream The stream to write.
3415  */
3416 void
3418  const TTAMachine::RFPort& port,
3419  std::ostream& stream) const {
3420  int indent = 4;
3421  BaseRegisterFile* rf = port.parentUnit();
3422  Socket* socket = port.inputSocket();
3423  assert(socket != NULL);
3424  BusSet buses = connectedBuses(*socket);
3425  stream << indentation(indent) << "if (";
3426  if(language_==VHDL){
3427  string opcodeSignalString = "";
3428  string controlSignalString = "";
3429  for (BusSet::const_iterator iter = buses.begin(); iter != buses.end();
3430  iter++) {
3431  Bus* bus = *iter;
3432  MoveSlot& moveSlot = bem_.moveSlot(bus->name());
3433  DestinationField& dstField = moveSlot.destinationField();
3434  SocketEncoding& enc = dstField.socketEncoding(socket->name());
3435  stream << squashSignal(bus->name()) << " = '0' and ";
3436  stream << socketEncodingCondition(VHDL, dstField, socket->name());
3437  if (enc.hasSocketCodes()) {
3438  SocketCodeTable& scTable = enc.socketCodes();
3439  RFPortCode& code = scTable.rfPortCode(rf->name());
3440  if (code.hasEncoding()) {
3441  stream << " and " << portCodeCondition(VHDL, enc, code);
3442 
3443  }
3444  stream << ") then" << endl;
3445  stream << indentation(indent + 1)
3446  << rfLoadSignalName(rf->name(), port.name())
3447  << " <= '1';" << endl;
3448  opcodeSignalString =
3449  indentation(indent + 1) +
3450  rfOpcodeSignalName(rf->name(), port.name()) +
3451  " <= " + rfOpcodeFromSrcOrDstField(VHDL, enc, code) + ";";
3452  stream << opcodeSignalString << endl;
3453 
3454  } else {
3455  stream << ") then" << endl;
3456  stream << indentation(indent + 1)
3457  << rfLoadSignalName(rf->name(), port.name())
3458  << " <= '1';" << endl;
3459  }
3460 
3461  if (needsBusControl(*socket)) {
3462  controlSignalString =
3463  indentation(indent + 1) +
3464  socketBusCntrlSignalName(socket->name()) +
3465  " <= conv_std_logic_vector(" +
3467  *socket, *bus->segment(0))) +
3468  ", " + socketBusCntrlSignalName(socket->name()) +
3469  "'length);";
3470 
3471  stream << controlSignalString << endl;
3472  }
3473 
3474  BusSet::const_iterator nextIter = iter;
3475  nextIter++;
3476  if (nextIter != buses.end()) {
3477  stream << indentation(indent) << "elsif (";
3478  }
3479  }
3480  stream << indentation(indent) << "else" << endl;
3481  stream << indentation(indent + 1)
3482  << rfLoadSignalName(rf->name(), port.name()) << " <= '0';"
3483  << endl;
3484  stream << indentation(indent) << "end if;" << endl;
3485  } else {
3486  for (BusSet::const_iterator iter = buses.begin(); iter != buses.end();
3487  iter++) {
3488  Bus* bus = *iter;
3489  MoveSlot& moveSlot = bem_.moveSlot(bus->name());
3490  DestinationField& dstField = moveSlot.destinationField();
3491  SocketEncoding& enc = dstField.socketEncoding(socket->name());
3492  stream << squashSignal(bus->name()) << " == 0 && "
3493  << socketEncodingCondition(Verilog, dstField, socket->name());
3494  if (enc.hasSocketCodes()) {
3495  SocketCodeTable& scTable = enc.socketCodes();
3496  RFPortCode& code = scTable.rfPortCode(rf->name());
3497  if (code.hasEncoding()) {
3498  stream << " && " << portCodeCondition(Verilog, enc, code);
3499 
3500  }
3501  stream << ")" << endl
3502  << indentation(4) << "begin" << endl
3503  << indentation(5)
3504  << rfLoadSignalName(rf->name(), port.name()) << " <= 1'b1;"
3505  << endl
3506  << indentation(5)
3507  << rfOpcodeSignalName(rf->name(), port.name()) << " <= "
3508  << rfOpcodeFromSrcOrDstField(Verilog, enc, code) << ";" << endl;
3509  } else {
3510  stream << ")" << endl
3511  << indentation(4) << "begin" << endl
3512  << indentation(5)
3513  << rfLoadSignalName(rf->name(), port.name()) << " <= 1'b1;"
3514  << endl;
3515  }
3516 
3517  if (needsBusControl(*socket)) {
3518  stream << indentation(5)
3519  << socketBusCntrlSignalName(socket->name())
3520  << " <= "
3522  *socket, *bus->segment(0)) << ";"
3523  << endl;
3524  }
3525 
3526  BusSet::const_iterator nextIter = iter;
3527  nextIter++;
3528  stream << indentation(4) << "end" << endl;
3529  if (nextIter != buses.end()) {
3530  stream << indentation(4) << "else if (";
3531  }
3532  }
3533  stream << indentation(4) << "else" << endl
3534  << indentation(5) << rfLoadSignalName(rf->name(), port.name())
3535  << " <= 1'b0;" << endl;
3536  }
3537 }
3538 
3539 
3540 /**
3541  * Writes the mappings of control registers to control ports to the given
3542  * stream.
3543  *
3544  * @param stream The stream.
3545  */
3546 void
3548  std::ostream& stream) const {
3549  if(language_==VHDL){
3550  stream << indentation(1) << "-- map control registers to outputs"
3551  << endl;
3552 
3553  // map FU control signals
3555  functionUnitNavigator();
3556  for (int i = 0; i < fuNav.count(); i++) {
3557  FunctionUnit* fu = fuNav.item(i);
3558  for (int i = 0; i < fu->portCount(); i++) {
3559  BaseFUPort* port = fu->port(i);
3560  if (port->inputSocket() != NULL) {
3561  // map load signal
3562  stream << indentation(1)
3563  << fuLoadCntrlPort(fu->name(), port->name())
3564  << " <= "
3565  << fuLoadSignalName(fu->name(), port->name())
3566  << ";" << endl;
3567  }
3568  }
3569 
3570  // map opcode signal
3571  if (fu->operationCount() > 1) {
3572  stream << indentation(1) << fuOpcodeCntrlPort(fu->name())
3573  << " <= " << fuOpcodeSignalName(fu->name()) << ";"
3574  << endl;
3575  }
3576  stream << endl;
3577  }
3578 
3579  // map pc_load and ra_load signals
3580  ControlUnit* gcu = machine_.controlUnit();
3581  if (gcu->hasReturnAddressPort()) {
3582  SpecialRegisterPort* raPort = gcu->returnAddressPort();
3583  stream << indentation(1) << NetlistGenerator::DECODER_RA_LOAD_PORT
3584  << " <= " << fuLoadSignalName(gcu->name(), raPort->name())
3585  << ";" << endl;
3586  }
3587 
3588  // find the PC port
3589  BaseFUPort* pcPort = gcu->triggerPort();
3590  if (pcPort != NULL) {
3591  stream << indentation(1) << NetlistGenerator::DECODER_PC_LOAD_PORT
3592  << " <= " << fuLoadSignalName(gcu->name(), pcPort->name())
3593  << ";" << endl;
3594  }
3595 
3596  // map pc_opcode signal
3597  if (gcu->hasOperation(JUMP) || gcu->hasOperation(CALL)) {
3598  stream << indentation(1)
3599  << NetlistGenerator::DECODER_PC_OPCODE_PORT
3600  << " <= " << fuOpcodeSignalName(gcu->name()) << ";"
3601  << endl;
3602  }
3603 
3604  // map other GCU's load signals
3605  for (int i = 0; i < gcu->portCount(); i++) {
3606  BaseFUPort* port = gcu->port(i);
3607  if (!port->isInput() ||
3608  port->name() == gcu->returnAddressPort()->name() ||
3609  port->isTriggering()) {
3610  continue;
3611  }
3612  stream << indentation(1)
3613  << fuLoadCntrlPort(gcu->name(), port->name())
3614  << " <= " << fuLoadSignalName(gcu->name(), port->name())
3615  << ";" << endl;
3616  }
3617 
3618  // map other GCU's load signals
3619  for (int i = 0; i < gcu->portCount(); i++) {
3620  BaseFUPort* port = gcu->port(i);
3621  if (!port->isInput() ||
3622  port->name() == gcu->returnAddressPort()->name() ||
3623  port->isTriggering()) {
3624  continue;
3625  }
3626  stream << indentation(1)
3627  << fuLoadCntrlPort(gcu->name(), port->name())
3628  << " <= " << fuLoadSignalName(gcu->name(), port->name())
3629  << ";" << endl;
3630  }
3631 
3632  // map RF control signals
3634  registerFileNavigator();
3635  for (int i = 0; i < rfNav.count(); i++) {
3636  RegisterFile* rf = rfNav.item(i);
3637 
3638  for (int i = 0; i < rf->portCount(); i++) {
3639  RFPort* port = rf->port(i);
3640  bool async_signal = sacEnabled(rf->name())
3641  && port->outputSocket() != NULL;
3642 
3643  // map load signal
3644  stream << indentation(1)
3645  << rfLoadCntrlPort(rf->name(), port->name()) << " <= "
3646  << rfLoadSignalName(rf->name(), port->name(),
3647  async_signal) << ";"
3648  << endl;
3649 
3650  // map opcode signal
3651  bool OpcodePortExists = decoderBlock_->port(
3652  rfOpcodeCntrlPort(rf->name(), port->name()));
3653  if (OpcodePortExists) {
3654  stream << indentation(1)
3655  << rfOpcodeCntrlPort(rf->name(), port->name())
3656  << " <= "
3657  << (rfOpcodeWidth(*rf) == 0 ? "\"0\"" :
3658  rfOpcodeSignalName(rf->name(), port->name(),
3659  async_signal))
3660  << ";"
3661  << endl;
3662  }
3663  }
3664  }
3665 
3666  // map IU write/read opcode signals (only 0 downto 0) to 0
3667  // TODO: mapping of these ports should probably be elsewhere
3670  for (int i = 0; i < iuNav.count(); i++) {
3671  ImmediateUnit* iu = iuNav.item(i);
3672  for (int i = 0; i < iu->portCount(); i++) {
3673  RFPort* port = iu->port(i);
3674  bool readOpcodePortExists = decoderBlock_->port(
3675  iuReadOpcodeCntrlPort(iu->name(), port->name()));
3676  bool writeOpcodePortExists =
3678  assert(readOpcodePortExists == writeOpcodePortExists);
3679  if (rfOpcodeWidth(*iu) == 0 and readOpcodePortExists and
3680  writeOpcodePortExists) {
3681 
3682  stream << indentation(1)
3683  << iuReadOpcodeCntrlPort(iu->name(), port->name())
3684  << " <= \"0\";"
3685  << endl;
3686 
3687  stream << indentation(1)
3688  << iuWriteOpcodeCntrlPort(iu->name())
3689  << " <= \"0\";"
3690  << endl;
3691  }
3692  }
3693  }
3694 
3695 
3696  // map socket control signals
3698  for (int i = 0; i < socketNav.count(); i++) {
3699  Socket* socket = socketNav.item(i);
3700  if (socket->portCount() == 0 || socket->segmentCount() == 0) {
3701  continue;
3702  }
3703 
3704  if (needsBusControl(*socket)) {
3705  stream << indentation(1) << socketBusControlPort(socket->name())
3706  << " <= " << socketBusCntrlSignalName(socket->name())
3707  << ";" << endl;
3708  }
3709  if (needsDataControl(*socket)) {
3710  stream << indentation(1) << socketDataControlPort(socket->name())
3711  << " <= " << socketDataCntrlSignalName(socket->name())
3712  << ";" << endl;
3713  }
3714  }
3715  // map short immediate signals
3717  for (int i = 0; i < busNav.count(); i++) {
3718  Bus* bus = busNav.item(i);
3719  if (bus->immediateWidth() > 0) {
3720  stream << indentation(1) << simmControlPort(bus->name())
3721  << " <= " << simmCntrlSignalName(bus->name()) << ";"
3722  << endl;
3723  if (!machine_.isRISCVMachine()) {
3724  stream << indentation(1) << simmDataPort(bus->name())
3725  << " <= " << simmDataSignalName(bus->name()) << ";"
3726  << endl;
3727  } else {
3728  stream << indentation(1) << simmDataPort(bus->name())
3729  << " <= " << RISCV_SIMM_PORT_IN_NAME << ";"
3730  << endl;
3731  }
3732  }
3733  }
3734  } else {
3735  stream << indentation(1) << "// map control registers to outputs"
3736  << endl;
3737 
3738  // map FU control signals
3740  functionUnitNavigator();
3741  for (int i = 0; i < fuNav.count(); i++) {
3742  FunctionUnit* fu = fuNav.item(i);
3743  for (int i = 0; i < fu->portCount(); i++) {
3744  BaseFUPort* port = fu->port(i);
3745  if (port->inputSocket() != NULL) {
3746  // map load signal
3747  stream << indentation(1)
3748  << "assign "
3749  << fuLoadCntrlPort(fu->name(), port->name())
3750  << " = "
3751  << fuLoadSignalName(fu->name(), port->name())
3752  << ";" << endl;
3753  }
3754  }
3755 
3756  // map opcode signal
3757  if (fu->operationCount() > 1) {
3758  stream << indentation(1)
3759  << "assign "
3760  << fuOpcodeCntrlPort(fu->name())
3761  << " = " << fuOpcodeSignalName(fu->name()) << ";"
3762  << endl;
3763  }
3764  stream << endl;
3765  }
3766 
3767  // map pc_load and ra_load signals
3768  ControlUnit* gcu = machine_.controlUnit();
3769  if (gcu->hasReturnAddressPort()) {
3770  SpecialRegisterPort* raPort = gcu->returnAddressPort();
3771  stream << indentation(1)
3772  << "assign "
3773  << NetlistGenerator::DECODER_RA_LOAD_PORT
3774  << " = " << fuLoadSignalName(gcu->name(), raPort->name())
3775  << ";" << endl;
3776  }
3777 
3778  // find the PC port
3779  FUPort* pcPort = NULL;
3780  if (gcu->hasOperation(CALL)) {
3781  HWOperation* callOp = gcu->operation(CALL);
3782  pcPort = callOp->port(1);
3783  } else if (gcu->hasOperation(JUMP)) {
3784  HWOperation* jumpOp = gcu->operation(JUMP);
3785  pcPort = jumpOp->port(1);
3786  }
3787  if (pcPort != NULL) {
3788  stream << indentation(1)
3789  << "assign "
3790  << NetlistGenerator::DECODER_PC_LOAD_PORT
3791  << " = " << fuLoadSignalName(gcu->name(), pcPort->name())
3792  << ";" << endl;
3793  }
3794 
3795  // map pc_opcode signal
3796  if (gcu->hasOperation(JUMP) || gcu->hasOperation(CALL)) {
3797  stream << indentation(1)
3798  << "assign "
3799  << NetlistGenerator::DECODER_PC_OPCODE_PORT
3800  << " = " << fuOpcodeSignalName(gcu->name()) << ";" << endl;
3801  }
3802 
3803  // map RF control signals
3805  registerFileNavigator();
3806  for (int i = 0; i < rfNav.count(); i++) {
3807  RegisterFile* rf = rfNav.item(i);
3808  for (int i = 0; i < rf->portCount(); i++) {
3809  RFPort* port = rf->port(i);
3810  bool async_signal = sacEnabled(rf->name())
3811  && port->outputSocket() != NULL;
3812 
3813  // map load signal
3814  stream << indentation(1)
3815  << "assign "
3816  << rfLoadCntrlPort(rf->name(), port->name()) << " = "
3817  << rfLoadSignalName(rf->name(), port->name(),
3818  async_signal) << ";"
3819  << endl;
3820  // map opcode signal
3821  stream << indentation(1)
3822  << "assign "
3823  << rfOpcodeCntrlPort(rf->name(), port->name())
3824  << " = "
3825  << (rfOpcodeWidth(*rf) == 0 ? "\"0\"" :
3826  rfOpcodeSignalName(rf->name(), port->name(),
3827  async_signal))
3828  << ";"
3829  << endl;
3830  }
3831  }
3832 
3835  for (int i = 0; i < iuNav.count(); i++) {
3836  ImmediateUnit* iu = iuNav.item(i);
3837  for (int i = 0; i < iu->portCount(); i++) {
3838  RFPort* port = iu->port(i);
3839 
3840  stream << indentation(1) << "assign "
3841  << iuReadLoadCntrlPort(iu->name(), port->name())
3842  << " = "
3843  << iuReadLoadCntrlSignal(iu->name(), port->name())
3844  << ";" << endl;
3845  if (rfOpcodeWidth(*iu) == 0) {
3846  stream << indentation(1) << "assign "
3847  << iuReadOpcodeCntrlPort(iu->name(), port->name())
3848  << " = 1'b0;"
3849  << endl;
3850 
3851  } else {
3852  stream << indentation(1) << "assign "
3853  << iuReadOpcodeCntrlPort(iu->name(), port->name())
3854  << " = "
3855  << iuReadOpcodeCntrlSignal(iu->name(), port->name())
3856  << ";" << endl;
3857 
3858  }
3859  } // Loop for IU ports
3860  stream << indentation(1) << "assign "
3861  << iuWritePort(iu->name()) << " = "
3862  << iuWriteSignal(iu->name()) << ";" << endl;
3863  stream << indentation(1) << "assign "
3864  << iuWriteLoadCntrlPort(iu->name()) << " = "
3865  << iuWriteLoadCntrlSignal(iu->name()) << ";" << endl;
3866  if (rfOpcodeWidth(*iu) == 0) {
3867  stream << indentation(1) << "assign "
3868  << iuWriteOpcodeCntrlPort(iu->name())
3869  << " = 1'b0;" << endl;
3870  } else {
3871  stream << indentation(1) << "assign "
3872  << iuWriteOpcodeCntrlPort(iu->name())
3873  << " = "
3874  << iuWriteOpcodeCntrlSignal(iu->name())
3875  << ";" << endl;
3876  }
3877  } // Loop for IUs
3878 
3879 
3880  // map socket control signals
3882  for (int i = 0; i < socketNav.count(); i++) {
3883  Socket* socket = socketNav.item(i);
3884  if (socket->portCount() == 0 || socket->segmentCount() == 0) {
3885  continue;
3886  }
3887 
3888  if (needsBusControl(*socket)) {
3889  stream << indentation(1)
3890  << "assign "
3891  << socketBusControlPort(socket->name())
3892  << " = " << socketBusCntrlSignalName(socket->name())
3893  << ";" << endl;
3894  }
3895  if (needsDataControl(*socket)) {
3896  stream << indentation(1)
3897  << "assign "
3898  << socketDataControlPort(socket->name())
3899  << " = " << socketDataCntrlSignalName(socket->name())
3900  << ";" << endl;
3901  }
3902  }
3903 
3904  // map short immediate signals
3906  for (int i = 0; i < busNav.count(); i++) {
3907  Bus* bus = busNav.item(i);
3908  if (bus->immediateWidth() > 0) {
3909  stream << indentation(1)
3910  << "assign "
3911  << simmControlPort(bus->name())
3912  << " = " << simmCntrlSignalName(bus->name()) << ";"
3913  << endl
3914  << indentation(1)
3915  << "assign "
3916  << simmDataPort(bus->name()) << " = "
3917  << simmDataSignalName(bus->name()) << ";" << endl;
3918  }
3919  }
3920  }
3921 }
3922 
3923 
3924 /**
3925  * Writes substitution of guard value to the squash signal of the given
3926  * bus.
3927  *
3928  * @param bus The bus.
3929  * @param enc The guard encoding.
3930  * @param guard The guard.
3931  * @param stream The stream to write.
3932  * @param indLevel The indentation level.
3933  */
3934 void
3936  const ProGe::HDL language,
3937  const TTAMachine::Bus& bus,
3938  const GuardEncoding& enc,
3939  const TTAMachine::Guard& guard,
3940  std::ostream& stream,
3941  int indLevel) {
3942  if(language==VHDL){
3943  stream << indentation(indLevel) << "when " << enc.encoding()
3944  << " =>" << endl;
3945  stream << indentation(indLevel+1) << squashSignal(bus.name()) << " <= ";
3946  if (!guard.isInverted()) {
3947  stream << "not ";
3948  }
3949  stream << guardPortName(guard) << ";" << endl;
3950  } else {
3951  stream << indentation(indLevel) << enc.encoding() << " : "
3952  << squashSignal(bus.name()) << " = ";
3953  if (!guard.isInverted()) {
3954  stream << " !";
3955  }
3956  stream << guardPortName(guard) << ";" << endl;
3957  }
3958 }
3959 
3960 
3961 /**
3962  * Tells whether the given guard set contains similar guard to the given
3963  * one. Similar means the guard refers to the same FU port.
3964  *
3965  * @param guardSet The guard set.
3966  * @param guard The guard.
3967  * @return True if the set contains similar guard, otherwise false.
3968  */
3969 bool
3971  const std::set<TTAMachine::PortGuard*>& guardSet,
3972  const TTAMachine::PortGuard& guard) {
3973 
3974  for (std::set<PortGuard*>::const_iterator iter = guardSet.begin();
3975  iter != guardSet.end(); iter++) {
3976  PortGuard* containedGuard = *iter;
3977  if (containedGuard->port() == guard.port()) {
3978  return true;
3979  }
3980  }
3981 
3982  return false;
3983 }
3984 
3985 
3986 /**
3987  * Tells whether the given guard set contains similar guard to the given
3988  * one. Similar means the guard refers to the same register.
3989  *
3990  * @param guardSet The guard set.
3991  * @param guard The guard.
3992  * @return True if the set contains similar guard, otherwise false.
3993  */
3994 bool
3996  const std::set<TTAMachine::RegisterGuard*>& guardSet,
3997  const TTAMachine::RegisterGuard& guard) {
3998 
3999  for (std::set<RegisterGuard*>::const_iterator iter = guardSet.begin();
4000  iter != guardSet.end(); iter++) {
4001  RegisterGuard* containedGuard = *iter;
4002  if (containedGuard->registerFile() == guard.registerFile() &&
4003  containedGuard->registerIndex() == guard.registerIndex()) {
4004  return true;
4005  }
4006  }
4007 
4008  return false;
4009 }
4010 
4011 
4012 /**
4013  * Tells whether the given socket needs controlling from which bus data is
4014  * read or to which it is written.
4015  *
4016  * @param socket The socket.
4017  * @return True if the socket needs controlling, otherwise false.
4018  */
4019 bool
4021  if (socket.segmentCount() == 0 || socket.portCount() == 0) {
4022  return false;
4023  }
4024  if (socket.segmentCount() > 1 ||
4025  (socket.segmentCount() == 1 &&
4026  socket.direction() == Socket::OUTPUT)) {
4027  return true;
4028  } else {
4029  return false;
4030  }
4031 }
4032 
4033 
4034 /**
4035  * Tells whether the given output socket needs controlling from which
4036  * port the data should be written to a bus.
4037  */
4038 bool
4040  if (socket.direction() == Socket::OUTPUT && socket.portCount() > 1) {
4041  return true;
4042  } else {
4043  return false;
4044  }
4045 }
4046 
4047 
4048 /**
4049  * Finds the guard that is referred to by the given register guard
4050  * encoding.
4051  *
4052  * @param encoding The encoding.
4053  * @return The guard.
4054  */
4057 
4058  GuardField* parent = encoding.parent();
4059  string busName = parent->parent()->name();
4060 
4062  Bus* bus = busNav.item(busName);
4063  for (int i = 0; i < bus->guardCount(); i++) {
4064  Guard* guard = bus->guard(i);
4065  RegisterGuard* regGuard = dynamic_cast<RegisterGuard*>(guard);
4066  if (regGuard != NULL) {
4067  if (encoding.registerFile() == regGuard->registerFile()->name()
4068  && encoding.registerIndex() == regGuard->registerIndex() &&
4069  encoding.isGuardInverted() == regGuard->isInverted()) {
4070  return *regGuard;
4071  }
4072  }
4073  }
4074 
4075  assert(false);
4076 }
4077 
4078 
4079 /**
4080  * Finds the guard that is referred to by the given port guard encoding.
4081  *
4082  * @param encoding The encoding.
4083  * @return The guard.
4084  */
4087 
4088  GuardField* parent = encoding.parent();
4089  string busName = parent->parent()->name();
4090 
4092  Bus* bus = busNav.item(busName);
4093  for (int i = 0; i < bus->guardCount(); i++) {
4094  Guard* guard = bus->guard(i);
4095  PortGuard* portGuard = dynamic_cast<PortGuard*>(guard);
4096  if (portGuard != NULL) {
4097  if (encoding.functionUnit() ==
4098  portGuard->port()->parentUnit()->name() &&
4099  encoding.port() == portGuard->port()->name() &&
4100  encoding.isGuardInverted() == portGuard->isInverted()) {
4101  return *portGuard;
4102  }
4103  }
4104  }
4105 
4106  assert(false);
4107 }
4108 
4109 
4110 /**
4111  * Returns the name of the data port for short immediate of the given bus.
4112  *
4113  * @param busName Name of the bus.
4114  * @return The name of the port.
4115  */
4116 std::string
4117 DefaultDecoderGenerator::simmDataPort(const std::string& busName) {
4118  return "simm_" + busName;
4119 }
4120 
4121 
4122 /**
4123  * Returns the name of the control port for short immediate of the given
4124  * bus.
4125  *
4126  * @param busName Name of the bus.
4127  * @return The name of the port.
4128  */
4129 std::string
4130 DefaultDecoderGenerator::simmControlPort(const std::string& busName) {
4131  return "simm_cntrl_" + busName;
4132 }
4133 
4134 
4135 /**
4136  * Returns the required width of the short immediate port of the given bus.
4137  *
4138  * @param bus The bus.
4139  * @return The width of the port.
4140  */
4141 int
4143  if (bus.signExtends()) {
4144  return bus.width();
4145  } else if (bus.zeroExtends()) {
4146  return bus.immediateWidth();
4147  } else {
4148  assert(false && "Unknown extension policy.");
4149  return -1;
4150  }
4151 }
4152 
4153 
4154 /**
4155  * Returns the name of the short immediate data signal.
4156  *
4157  * @param busName Name of the bus that transports the short immediate.
4158  * @return The name of the signal.
4159  */
4160 std::string
4161 DefaultDecoderGenerator::simmDataSignalName(const std::string& busName) {
4162  return "simm_" + busName + "_reg";
4163 }
4164 
4165 
4166 /**
4167  * Returns the name of the short immediate control signal of the given bus.
4168  *
4169  * @param busName Name of the bus.
4170  * @return The name of the signal.
4171  */
4172 std::string
4174  return "simm_cntrl_" + busName + "_reg";
4175 }
4176 
4177 
4178 /**
4179  * Returns the name of the load control port for the given FU port.
4180  *
4181  * @param fuName Name of the FU.
4182  * @param portName Name of the FU data port.
4183  * @return The name of the load control port in decoder.
4184  */
4185 std::string
4187  const std::string& fuName,
4188  const std::string& portName) {
4189 
4190  return "fu_" + fuName + "_" + portName + "_load";
4191 }
4192 
4193 
4194 /**
4195  * Returns the name for the signal of load control port of the given FU
4196  * port.
4197  *
4198  * @param fuName Name of the FU.
4199  * @param portName Name of the FU data port.
4200  * @return The name of the signal.
4201  */
4202 std::string
4204  const std::string& fuName,
4205  const std::string& portName) {
4206 
4207  return fuLoadCntrlPort(fuName, portName) + "_reg";
4208 }
4209 
4210 
4211 /**
4212  * Returns the name of the opcode control port for the given FU.
4213  *
4214  * @param fu Name of the FU.
4215  * @return The name of the opcode control port in decoder.
4216  */
4217 std::string
4219  return "fu_" + fu + "_opc";
4220 }
4221 
4222 
4223 /**
4224  * Returns the name for the signal of opcode control port of the given FU.
4225  *
4226  * @param fu Name of the FU.
4227  * @return The name of the opcode control signal.
4228  */
4229 std::string
4231  return fuOpcodeCntrlPort(fu) + "_reg";
4232 }
4233 
4234 
4235 /**
4236  * Returns the name of the load control port of the given RF data port.
4237  *
4238  * @param rfName Name of the RF.
4239  * @param portName Name of the RF data port.
4240  * @return The name of the load control port in decoder.
4241  */
4242 std::string
4244  const std::string& rfName,
4245  const std::string& portName) {
4246 
4247  return "rf_" + rfName + "_" + portName + "_load";
4248 }
4249 
4250 
4251 /**
4252  * Returns the name for the load control signal for the given RF port.
4253  *
4254  * @param rfName Name of the RF.
4255  * @param portName Name of the RF data port.
4256  * @param async Flag to generate name for asynchronous signal. Default value
4257  * is false.
4258  * @return The name of the signal.
4259  */
4260 std::string
4262  const std::string& rfName,
4263  const std::string& portName,
4264  bool async) {
4265 
4266  if (async) {
4267  return rfLoadCntrlPort(rfName, portName) + "_wire";
4268  } else {
4269  return rfLoadCntrlPort(rfName, portName) + "_reg";
4270  }
4271 }
4272 
4273 
4274 /**
4275  * Returns the name for the signal of opcode control port of the given
4276  * RF port.
4277  *
4278  * @param rfName Name of the register file.
4279  * @param portName Name of the RF data port.
4280  * @param async Flag to generate name for asynchronous signal. Default value
4281  * is false.
4282  * @return The name of the signal.
4283  */
4284 std::string
4286  const std::string& rfName,
4287  const std::string& portName,
4288  bool async) {
4289 
4290  if (async) {
4291  return rfOpcodeCntrlPort(rfName, portName) + "_wire";
4292  } else {
4293  return rfOpcodeCntrlPort(rfName, portName) + "_reg";
4294  }
4295 }
4296 
4297 /**
4298  * Returns the name of the opcode control port of the given RF port.
4299  *
4300  * @param rfName Name of the RF.
4301  * @param portName Name of the RF data port.
4302  * @return The opcode control port in decoder.
4303  */
4304 std::string
4306  const std::string& rfName,
4307  const std::string& portName) {
4308 
4309  return "rf_" + rfName + "_" + portName + "_opc";
4310 }
4311 
4312 
4313 /**
4314  * Returns the name of the opcode control port of the given IU read port
4315  * in decoder.
4316  *
4317  * @param unitName Name of the IU.
4318  * @param portName Name of the read port.
4319  * @return The name of the opcode control port.
4320  */
4321 std::string
4323  const std::string& unitName,
4324  const std::string& portName) {
4325 
4326  return "iu_" + unitName + "_" + portName + "_read_opc";
4327 }
4328 
4329 
4330 /**
4331  * Returns the name of the opcode control signal of the given IU read port
4332  * in decoder.
4333  *
4334  * @param unitName Name of the IU.
4335  * @param portName Name of the read port.
4336  * @return The name of the opcode control port.
4337  */
4338 std::string
4340  const std::string& unitName,
4341  const std::string& portName) {
4342 
4343  return iuReadOpcodeCntrlPort(unitName, portName) + "_reg";
4344 }
4345 
4346 
4347 /**
4348  * Returns the name of the load control port of the given IU read port in
4349  * in decoder.
4350  *
4351  * @param unitName Name of the IU.
4352  * @param portName Name of the read port.
4353  * @return The name of the load control port.
4354  */
4355 std::string
4357  const std::string& unitName,
4358  const std::string& portName) {
4359 
4360  return "iu_" + unitName + "_" + portName + "_read_load";
4361 }
4362 
4363 
4364 /**
4365  * Returns the name of the load control signal of the given IU read port in
4366  * in decoder.
4367  *
4368  * @param unitName Name of the IU.
4369  * @param portName Name of the read port.
4370  * @return The name of the load control port.
4371  */
4372 std::string
4374  const std::string& unitName,
4375  const std::string& portName) {
4376 
4377  return iuReadLoadCntrlPort(unitName, portName) + "_reg";
4378 }
4379 
4380 
4381 /**
4382  * Returns the name of the IU write port of the given IU in decoder.
4383  *
4384  * @param iuName Name of the IU.
4385  * @return The name of the port.
4386  */
4387 std::string
4388 DefaultDecoderGenerator::iuWritePort(const std::string& iuName) {
4389  return "iu_" + iuName + "_write";
4390 }
4391 
4392 
4393 /**
4394  * Returns the name of the IU write signal of the given IU in decoder.
4395  *
4396  * @param iuName Name of the IU.
4397  * @return The name of the port.
4398  */
4399 std::string
4400 DefaultDecoderGenerator::iuWriteSignal(const std::string& iuName) {
4401  return iuWritePort(iuName) + "_reg";
4402 }
4403 
4404 
4405 /**
4406  * Returns the name of the opcode control port of the write port of the given
4407  * IU in decoder.
4408  *
4409  * @param unitName Name of the IU.
4410  * @return The name of the opcode control port.
4411  */
4412 std::string
4414  return iuWritePort(unitName) + "_opc";
4415 }
4416 
4417 
4418 /**
4419  * Returns the name of the opcode control signal of the write port of the given
4420  * IU in decoder.
4421  *
4422  * @param unitName Name of the IU.
4423  * @return The name of the opcode control port.
4424  */
4425 std::string
4427  const std::string& unitName) {
4428  return iuWriteOpcodeCntrlPort(unitName) + "_reg";
4429 }
4430 
4431 
4432 /**
4433  * Returns the name of the load control port of the write port of the given
4434  * IU in decoder.
4435  *
4436  * @param unitName Name of the IU.
4437  * @return The name of the load control port.
4438  */
4439 std::string
4441  return iuWritePort(unitName) + "_load";
4442 }
4443 
4444 
4445 /**
4446  * Returns the name of the load control Signal of the write port of the given
4447  * IU in decoder.
4448  *
4449  * @param unitName Name of the IU.
4450  * @return The name of the load control port.
4451  */
4452 std::string
4454  return iuWriteLoadCntrlPort(unitName) + "_reg";
4455 }
4456 
4457 std::string
4459  return bus.name() + "_src_sel";
4460 }
4461 
4462 std::string
4464  return busMuxCntrlSignal(bus) + "_reg";
4465 }
4466 
4467 std::string
4469  return bus.name() + "_src_ena";
4470 }
4471 
4472 std::string
4474  return busMuxEnableSignal(bus) + "_reg";
4475 }
4476 
4477 /**
4478  * Returns the name of the signal for the move field of the given bus.
4479  */
4480 std::string
4481 DefaultDecoderGenerator::moveFieldSignal(const std::string& busName) {
4482  return "move_" + busName;
4483 }
4484 
4485 /**
4486  * Returns the name of the guard port in decoder for the given guard.
4487  *
4488  * @param guard The guard.
4489  * @return The name of the port.
4490  */
4491 std::string
4493  const PortGuard* portGuard = dynamic_cast<const PortGuard*>(&guard);
4494  const RegisterGuard* regGuard = dynamic_cast<const RegisterGuard*>(
4495  &guard);
4496  if (portGuard != NULL) {
4497  FUPort* port = portGuard->port();
4498  FunctionUnit* fu = port->parentUnit();
4499  return "fu_guard_" + fu->name() + "_" + port->name();
4500  } else if (regGuard != NULL) {
4501  const RegisterFile* rf = regGuard->registerFile();
4502  return "rf_guard_" + rf->name() + "_" +
4503  Conversion::toString(regGuard->registerIndex());
4504  } else {
4505  return "";
4506  }
4507 }
4508 
4509 
4510 /**
4511  * Returns the name of the bus connection control port of the given
4512  * socket.
4513  *
4514  * @param name Name of the socket.
4515  * @return The name of the control port.
4516  */
4517 std::string
4519  return "socket_" + name + "_bus_cntrl";
4520 }
4521 
4522 
4523 /**
4524  * Returns the name of the data control port of the given socket.
4525  *
4526  * @param name Name of the socket.
4527  * @return The name of the control port.
4528  */
4529 std::string
4531  return "socket_" + name + "_data_cntrl";
4532 }
4533 
4534 
4535 /**
4536  * Returns the name of the signal for the source field of the given bus.
4537  *
4538  * @param busName Name of the bus.
4539  * @return The name of the signal.
4540  */
4541 std::string
4542 DefaultDecoderGenerator::srcFieldSignal(const std::string& busName) {
4543  return "src_" + busName;
4544 }
4545 
4546 
4547 /**
4548  * Returns the name of the signal for the destination field of the given
4549  * bus.
4550  *
4551  * @param busName Name of the bus.
4552  * @return The name of the signal.
4553  */
4554 std::string
4555 DefaultDecoderGenerator::dstFieldSignal(const std::string& busName) {
4556  return "dst_" + busName;
4557 }
4558 
4559 
4560 /**
4561  * Returns the name of the signal for the guard field of the given bus.
4562  *
4563  * @param busName Name of the bus.
4564  * @return The name of the signal.
4565  */
4566 std::string
4567 DefaultDecoderGenerator::guardFieldSignal(const std::string& busName) {
4568  return "grd_" + busName;
4569 }
4570 
4571 
4572 /**
4573  * Returns the name of the signal for the given immediate slot.
4574  *
4575  * @param immSlot Name of the immediate slot.
4576  * @return The name of the signal.
4577  */
4578 std::string
4579 DefaultDecoderGenerator::immSlotSignal(const std::string& immSlot) {
4580  return "limmslot_" + immSlot;
4581 }
4582 
4583 
4584 /**
4585  * Returns the name of the squash signal for the given bus.
4586  *
4587  * @param busName Name of the bus.
4588  * @return The name of the signal.
4589  */
4590 std::string
4591 DefaultDecoderGenerator::squashSignal(const std::string& busName) {
4592  return "squash_" + busName;
4593 }
4594 
4595 
4596 /**
4597  * Returns the name of the bus connection control signal for the socket
4598  * of the given name.
4599  *
4600  * @param name Name of the socket.
4601  * @return The name of the control signal.
4602  */
4603 std::string
4605  return socketBusControlPort(name) + "_reg";
4606 }
4607 
4608 
4609 /**
4610  * Returns the name of the data control signal for the socket of the
4611  * given name.
4612  *
4613  * @param name Name of the socket.
4614  * @return The name of the control signal.
4615  */
4616 std::string
4618  return socketDataControlPort(name) + "_reg";
4619 }
4620 
4621 
4622 /**
4623  * Returns the real name of the GCU data port that has the given name in ADF.
4624  *
4625  * @param nameInADF Name of the port in ADF.
4626  */
4627 std::string
4628 DefaultDecoderGenerator::gcuDataPort(const std::string& nameInADF) {
4629  return nameInADF;
4630 }
4631 
4632 
4633 /**
4634  * Returns the width of the opcode of the given FU.
4635  *
4636  * @param fu The FU.
4637  * @return The width of the operation code.
4638  */
4639 int
4641  const TTAMachine::FunctionUnit& fu) const {
4642 
4643  if (&fu == machine_.controlUnit()) {
4644  // Derive port width initially set by NetlistGenerator
4645  const NetlistBlock& gcuBlock = nlGenerator_->instructionDecoder();
4646  return gcuBlock.port(NetlistGenerator::DECODER_PC_OPCODE_PORT)
4647  ->realWidth();
4648  } else {
4649  int ops = fu.operationCount();
4650  return ops > 1 ? static_cast<int>(std::ceil(std::log2(ops))) : 0;
4651  }
4652 }
4653 
4654 
4655 /**
4656  * Returns the number of bits required to control the bus connections of
4657  * the given socket.
4658  *
4659  * @param socket The socket.
4660  * @return The control width.
4661  */
4662 int
4664  if (socket.direction() == Socket::INPUT) {
4665  return MathTools::bitLength(socket.segmentCount() - 1);
4666  } else {
4667  return socket.segmentCount();
4668  }
4669 }
4670 
4671 
4672 /**
4673  * Returns the number of bits required to control from which port the
4674  * data is written to the bus.
4675  *
4676  * @param socket The socket.
4677  * @return The control width.
4678  */
4679 int
4681  if (socket.direction() == Socket::OUTPUT) {
4682  return MathTools::bitLength(socket.portCount() - 1);
4683  } else {
4684  return 0;
4685  }
4686 }
4687 
4688 
4689 /**
4690  * Returns the width of the opcode port in the given RF.
4691  *
4692  * @param rf The register file.
4693  * @return The bit width of the opcode port.
4694  */
4695 int
4697  return MathTools::bitLength(rf.numberOfRegisters() - 1);
4698 }
4699 
4700 
4701 /**
4702  * Returns a set of buses connected to the given socket.
4703  *
4704  * @param socket The socket.
4705  * @return The bus set.
4706  */
4709  BusSet set;
4710  int segmentCount = socket.segmentCount();
4711  for (int i = 0; i < segmentCount; i++) {
4712  set.insert(socket.segment(i)->parentBus());
4713  }
4714  return set;
4715 }
4716 
4717 
4718 /**
4719  * Returns the condition when data is transferred by the given socket in the
4720  * given source field.
4721  *
4722  * @param srcField The source field.
4723  * @param socketName Name of the socket.
4724  * @return The conditional clause.
4725  */
4726 std::string
4728  const ProGe::HDL language,
4729  const SlotField& slotField,
4730  const std::string& socketName) {
4731 
4732  string signalName;
4733  if (dynamic_cast<const SourceField*>(&slotField) != NULL) {
4734  signalName = srcFieldSignal(slotField.parent()->name());
4735  } else {
4736  signalName = dstFieldSignal(slotField.parent()->name());
4737  }
4738  SocketEncoding& enc = slotField.socketEncoding(socketName);
4739  int start = enc.socketIDPosition();
4740  int end = start + enc.socketIDWidth() - 1;
4741  if (language == VHDL) {
4742  if (enc.socketIDWidth() == 0) {
4743  return "true";
4744  } else {
4745  return "conv_integer(unsigned(" + signalName + "("
4746  + Conversion::toString(end) + " downto "
4747  + Conversion::toString(start)
4748  + "))) = " + Conversion::toString(enc.encoding());
4749  }
4750  } else {
4751  if (enc.socketIDWidth() == 0) {
4752  return "1";
4753  } else {
4754  return signalName + "["
4755  + Conversion::toString(end) + " : "
4756  + Conversion::toString(start)
4757  + "] == " + Conversion::toString(enc.encoding());
4758  }
4759  }
4760 }
4761 
4762 
4763 /**
4764  * Returns the condition when given port code of the given socket encoding is
4765  * true.
4766  *
4767  * @param socketEnc The socket encoding;
4768  * @param code The RF port code.
4769  * @return The condition.
4770  */
4771 std::string
4773  const ProGe::HDL language,
4774  const SocketEncoding& socketEnc,
4775  const PortCode& code) {
4776 
4777  // empty encoding is always true
4778  if (!code.encodingWidth()) {
4779  if (language==VHDL) {
4780  return "true";
4781  } else {
4782  return "1";
4783  }
4784  }
4785  SlotField* parent = socketEnc.parent();
4786  string signalName;
4787  if (dynamic_cast<SourceField*>(parent) != NULL) {
4788  signalName = srcFieldSignal(parent->parent()->name());
4789  } else {
4790  signalName = dstFieldSignal(parent->parent()->name());
4791  }
4792 
4793  int codeStart;
4794  if (parent->componentIDPosition() == BinaryEncoding::RIGHT) {
4795  codeStart = socketEnc.socketIDWidth() + code.indexWidth();
4796  } else {
4797  codeStart = code.indexWidth();
4798  }
4799  int codeEnd = codeStart + code.encodingWidth() - 1;
4800  assert(codeEnd >= codeStart);
4801 
4802  if(language==VHDL)
4803  return "conv_integer(unsigned(" + signalName + "(" +
4804  Conversion::toString(codeEnd) + " downto " +
4805  Conversion::toString(codeStart) + "))) = " +
4807  else
4808  return signalName + "[" +
4809  Conversion::toString(codeEnd) + " : " +
4810  Conversion::toString(codeStart) + "] == " +
4811  Conversion::toString(code.encoding());
4812 }
4813 
4814 
4815 /**
4816  * Returns the condition when the instruction is of the given template.
4817  *
4818  * @param iTempName Name of the instruction template.
4819  * @return The condition.
4820  */
4821 std::string
4823  const ProGe::HDL language,
4824  const std::string& iTempName) const {
4825 
4828  assert(field.hasTemplateEncoding(iTempName));
4829  if(language==VHDL)
4830  return "conv_integer(unsigned(" + LIMM_TAG_SIGNAL + ")) = "
4831  + Conversion::toString(field.templateEncoding(iTempName));
4832  else
4833  return LIMM_TAG_SIGNAL + " == "
4834  + Conversion::toString(field.templateEncoding(iTempName));
4835 }
4836 
4837 
4838 /**
4839  * Returns the part of the source or destination field signal that contains the
4840  * opcode of the given RF port code.
4841  *
4842  * @param socketEnc The socket encoding.
4843  * @param code The RF port code.
4844  * @return The part of the source or destination field signal.
4845  */
4846 std::string
4848  const ProGe::HDL language,
4849  const SocketEncoding& socketEnc,
4850  const PortCode& code) {
4851 
4852  SlotField* slotField = socketEnc.parent();
4853  string signalName;
4854  if (dynamic_cast<SourceField*>(slotField) != NULL) {
4855  signalName = srcFieldSignal(slotField->parent()->name());
4856  } else {
4857  signalName = dstFieldSignal(slotField->parent()->name());
4858  }
4859 
4860  int opcStart;
4861  SocketCodeTable& table = socketEnc.socketCodes();
4862  if (slotField->componentIDPosition() == BinaryEncoding::RIGHT) {
4863  opcStart = slotField->width() - table.width();
4864  } else {
4865  opcStart = 0;
4866  }
4867  int opcEnd = opcStart + code.indexWidth() - 1;
4868  if(language==VHDL)
4869  return signalName + "(" + Conversion::toString(opcEnd) + " downto " +
4870  Conversion::toString(opcStart) + ")";
4871  else
4872  return signalName + "[" + Conversion::toString(opcEnd) + " : " +
4873  Conversion::toString(opcStart) + "]";
4874 }
4875 
4876 
4877 /**
4878  * Returns the signal pin that controls the bus of the given output socket.
4879  *
4880  * @param socket The socket.
4881  * @param bus The bus.
4882  * @return The signal pin.
4883  */
4884 std::string
4886  const TTAMachine::Socket& socket,
4887  const TTAMachine::Bus& bus) const {
4888 
4889  assert(socket.direction() == Socket::OUTPUT);
4891  socket, *bus.segment(0));
4892  return socketBusCntrlSignalName(socket.name())
4893  + ((language_==VHDL)?"(":"[")
4894  + Conversion::toString(pin)
4895  + ((language_==VHDL)?")":"]");
4896 }
4897 
4898 
4899 /**
4900  * Returns the opcode of the given operation.
4901  *
4902  * @param operation The operation.
4903  * @return The opcode.
4904  */
4905 int
4907  const TTAMachine::HWOperation& operation) const {
4908 
4909  string fuName = operation.parentUnit()->name();
4910  if (fuName == machine_.controlUnit()->name()) {
4911  return CUOpcodeGenerator(machine_).encoding(operation.name());
4912  } else {
4913  // This will make all opcodes based on their alphabetical order!
4914  FunctionUnit* fu =
4915  dynamic_cast<FunctionUnit*>(operation.parentUnit());
4916  std::vector<std::string> operations;
4917  for (int i = 0; i < fu->operationCount(); ++i) {
4918  operations.emplace_back(fu->operation(i)->name());
4919  }
4920  std::sort(operations.begin(), operations.end());
4921  for (size_t i = 0; i < operations.size(); ++i) {
4922  if (operations[i] == operation.name()) {
4923  return i;
4924  }
4925  }
4926  }
4927  assert(false && "should not get here");
4928  return -1; //
4929 }
4930 
4931 /**
4932  * Generates an indentation of the given level.
4933  *
4934  * @param level The level.
4935  */
4936 std::string
4938  string indentation("");
4939  for (unsigned int i = 0; i < level; i++) {
4940  indentation += " ";
4941  }
4942  return indentation;
4943 }
4944 
4945 /**
4946  * Queries if given register file by name has separate address cycle (SAC)
4947  * flag enabled.
4948  *
4949  * @param rfName Name of register file in ADF.
4950  * @return Status of the SAC flag.
4951  */
4952 bool
4953 DefaultDecoderGenerator::sacEnabled(const string& rfName) const
4954 {
4955  assert(nlGenerator_ != NULL);
4956  const RFEntry& rfEntry = nlGenerator_->rfEntry(rfName);
4957  return rfEntry.implementation().separateAddressCycleParameter();
4958 }
CentralizedControlICGenerator::busCntrlPortOfSocket
ProGe::NetlistPort & busCntrlPortOfSocket(const std::string &socketName) const
Definition: CentralizedControlICGenerator.cc:98
TTAMachine::Bus::immediateWidth
int immediateWidth() const
Definition: Bus.cc:160
DefaultDecoderGenerator::requiredRFLatencies
std::set< int > requiredRFLatencies(const TTAMachine::ImmediateUnit &iu) const
Definition: DefaultDecoderGenerator.cc:692
TTAMachine::Guard
Definition: Guard.hh:55
DefaultDecoderGenerator::socketDataCntrlSignalName
static std::string socketDataCntrlSignalName(const std::string &name)
Definition: DefaultDecoderGenerator.cc:4617
JUMPR
const string JUMPR
Definition: DefaultDecoderGenerator.cc:130
DefaultDecoderGenerator::setGenerateLockTrace
void setGenerateLockTrace(bool generate)
Definition: DefaultDecoderGenerator.cc:759
DefaultDecoderGenerator::opcode
int opcode(const TTAMachine::HWOperation &operation) const
Definition: DefaultDecoderGenerator.cc:4906
DefaultDecoderGenerator::machine_
const TTAMachine::Machine & machine_
The machine.
Definition: DefaultDecoderGenerator.hh:319
DefaultDecoderGenerator::writeSquashSignalGenerationProcesses
void writeSquashSignalGenerationProcesses(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1548
Netlist.hh
DefaultDecoderGenerator::setLockTraceStartingCycle
void setLockTraceStartingCycle(unsigned int startCycle)
Definition: DefaultDecoderGenerator.cc:769
MachineInfo::templatesUsingSlot
static std::set< TTAMachine::InstructionTemplate * > templatesUsingSlot(const TTAMachine::Machine &mach, const std::string &slotName)
Definition: MachineInfo.cc:365
UnconditionalGuardEncoding.hh
ProGe::NetlistBlock::netlist
virtual const Netlist & netlist() const
Definition: BaseNetlistBlock.cc:348
BinaryEncoding::immediateSlot
ImmediateSlotField & immediateSlot(int index) const
Definition: BinaryEncoding.cc:234
DefaultDecoderGenerator::writeRFCntrlSignals
void writeRFCntrlSignals(std::ostream &stream)
Definition: DefaultDecoderGenerator.cc:1307
ProGe::NetlistGenerator::hasGlockReqPort
bool hasGlockReqPort(const NetlistBlock &block) const
Definition: NetlistGenerator.cc:497
DefaultDecoderGenerator::simmPortWidth
static int simmPortWidth(const TTAMachine::Bus &bus)
Definition: DefaultDecoderGenerator.cc:4142
DefaultDecoderGenerator::busCntrlSignalPinOfSocket
std::string busCntrlSignalPinOfSocket(const TTAMachine::Socket &socket, const TTAMachine::Bus &bus) const
Definition: DefaultDecoderGenerator.cc:4885
DefaultDecoderGenerator::socketDataControlPort
static std::string socketDataControlPort(const std::string &name)
Definition: DefaultDecoderGenerator.cc:4530
TTAMachine::InstructionTemplate::slotOfDestination
virtual std::string slotOfDestination(const ImmediateUnit &dstUnit, int index) const
Definition: InstructionTemplate.cc:395
DefaultDecoderGenerator::icGenerator_
const CentralizedControlICGenerator & icGenerator_
The IC generator.
Definition: DefaultDecoderGenerator.hh:323
BinaryEncoding
Definition: BinaryEncoding.hh:61
DefaultDecoderGenerator::entityNameStr_
TCEString entityNameStr_
Definition: DefaultDecoderGenerator.hh:330
TTAMachine::Port::inputSocket
virtual Socket * inputSocket() const
Definition: Port.cc:261
MoveSlot::name
std::string name() const
Definition: MoveSlot.cc:136
IUPortCode.hh
DefaultDecoderGenerator::rfLoadCntrlPort
static std::string rfLoadCntrlPort(const std::string &rfName, const std::string &portName)
Definition: DefaultDecoderGenerator.cc:4243
TTAMachine::Machine::hasOperation
bool hasOperation(const TCEString &opName) const
Definition: Machine.cc:1048
JUMP
const string JUMP
Definition: DefaultDecoderGenerator.cc:114
FileSystem.hh
TTAMachine::Socket::portCount
int portCount() const
BinaryEncoding::hasMoveSlot
bool hasMoveSlot(const std::string &name) const
Definition: BinaryEncoding.cc:138
DefaultDecoderGenerator::iuWriteOpcodeCntrlPort
static std::string iuWriteOpcodeCntrlPort(const std::string &unitName)
Definition: DefaultDecoderGenerator.cc:4413
InstructionField::bitPosition
int bitPosition() const
Definition: InstructionField.cc:132
DefaultDecoderGenerator::completeDecoderBlock
void completeDecoderBlock(const ProGe::NetlistGenerator &nlGenerator, ProGe::NetlistBlock &coreBlock)
Definition: DefaultDecoderGenerator.cc:223
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
ProGe::NetlistBlock
Definition: NetlistBlock.hh:61
HDB
Definition: CostDatabase.hh:49
ProGe::Verilog
@ Verilog
Verilog.
Definition: ProGeTypes.hh:42
DefaultDecoderGenerator::writeLongImmediateWriteProcess
void writeLongImmediateWriteProcess(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1801
DefaultDecoderGenerator::writeSocketCntrlSignals
void writeSocketCntrlSignals(std::ostream &stream)
Definition: DefaultDecoderGenerator.cc:1202
PortCode
Definition: PortCode.hh:45
TTAMachine::PortGuard::port
FUPort * port() const
DestinationField
Definition: DestinationField.hh:44
MoveSlot
Definition: MoveSlot.hh:60
DefaultDecoderGenerator::dstFieldSignal
static std::string dstFieldSignal(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4555
TTAMachine::Machine::isRISCVMachine
bool isRISCVMachine() const
Definition: Machine.cc:1063
DefaultDecoderGenerator::writeImmediateSlotSignals
void writeImmediateSlotSignals(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1135
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
DefaultDecoderGenerator::decoderBlock_
ProGe::NetlistBlock * decoderBlock_
The instruction decoder block in the netlist.
Definition: DefaultDecoderGenerator.hh:327
DefaultDecoderGenerator::srcFieldSignal
static std::string srcFieldSignal(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4542
TTAMachine::HWOperation
Definition: HWOperation.hh:52
DefaultDecoderGenerator::generateInstructionDecoder
void generateInstructionDecoder(const ProGe::NetlistGenerator &nlGenerator, const std::string &dstDirectory)
Definition: DefaultDecoderGenerator.cc:666
TTAMachine::Bus::zeroExtends
bool zeroExtends() const
Definition: Bus.cc:182
DefaultDecoderGenerator::BusSet
std::set< TTAMachine::Bus * > BusSet
Set type for buses.
Definition: DefaultDecoderGenerator.hh:121
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
ProGe::BIT_VECTOR
@ BIT_VECTOR
Several bits.
Definition: ProGeTypes.hh:48
TTAMachine::BaseFUPort::parentUnit
FunctionUnit * parentUnit() const
Definition: BaseFUPort.cc:96
APC
const string APC
Definition: DefaultDecoderGenerator.cc:143
GuardField::fuGuardEncoding
FUGuardEncoding & fuGuardEncoding(int index) const
Definition: GuardField.cc:387
BGTUR
const string BGTUR
Definition: DefaultDecoderGenerator.cc:137
DefaultDecoderGenerator::unitGlockReqBitMap_
UnitGlockReqBitMapType unitGlockReqBitMap_
Maps TTA Units to associated glock request port bits.
Definition: DefaultDecoderGenerator.hh:346
GPRGuardEncoding::registerFile
std::string registerFile() const
Definition: GPRGuardEncoding.cc:122
DefaultDecoderGenerator::connectedBuses
static BusSet connectedBuses(const TTAMachine::Socket &socket)
Definition: DefaultDecoderGenerator.cc:4708
TTAMachine::Bus::width
int width() const
Definition: Bus.cc:149
DefaultDecoderGenerator::busMuxEnableSignal
static std::string busMuxEnableSignal(const TTAMachine::Bus &bus)
Definition: DefaultDecoderGenerator.cc:4468
DefaultDecoderGenerator::addLockReqPortToDecoder
void addLockReqPortToDecoder()
Definition: DefaultDecoderGenerator.cc:468
SocketCodeTable::fuPortCode
FUPortCode & fuPortCode(int index) const
Definition: SocketCodeTable.cc:308
ProGe::NetlistGenerator::rfEntry
HDB::RFEntry & rfEntry(const std::string &rfName) const
Definition: NetlistGenerator.cc:676
GuardField.hh
TTAMachine::FunctionUnit::triggerPort
virtual BaseFUPort * triggerPort() const
Definition: FunctionUnit.cc:267
DefaultDecoderGenerator::writeMoveFieldSignals
void writeMoveFieldSignals(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1096
SourceField::hasImmediateEncoding
bool hasImmediateEncoding() const
Definition: SourceField.cc:279
MapTools.hh
TTAMachine::Bus
Definition: Bus.hh:53
TTAMachine::BaseFUPort
Definition: BaseFUPort.hh:44
HDB::RFEntry
Definition: RFEntry.hh:47
ProGe::NetlistPort::widthFormula
std::string widthFormula() const
Definition: NetlistPort.cc:316
GuardEncoding::isGuardInverted
bool isGuardInverted() const
Definition: GuardEncoding.cc:101
DefaultDecoderGenerator::iuWriteLoadCntrlSignal
static std::string iuWriteLoadCntrlSignal(const std::string &unitName)
Definition: DefaultDecoderGenerator.cc:4453
POST_DECODE_MERGED_GLOCK_SIGNAL
const string POST_DECODE_MERGED_GLOCK_SIGNAL
Definition: DefaultDecoderGenerator.cc:110
ProGe::NetlistPort::direction
Direction direction() const
Definition: NetlistPort.cc:373
BinaryEncoding::hasImmediateControlField
bool hasImmediateControlField() const
Definition: BinaryEncoding.cc:334
MachineInfo.hh
BEQ
const string BEQ
Definition: DefaultDecoderGenerator.cc:120
MoveSlot::hasGuardField
bool hasGuardField() const
Definition: MoveSlot.cc:202
ProGe::NetlistGenerator::fuGuardPort
NetlistPort & fuGuardPort(const NetlistPort &fuPort) const
Definition: NetlistGenerator.cc:402
SocketCodeTable.hh
ImmediateSlotField.hh
DefaultDecoderGenerator::iuWritePort
static std::string iuWritePort(const std::string &iuName)
Definition: DefaultDecoderGenerator.cc:4388
SocketCodeTable::rfPortCode
RFPortCode & rfPortCode(int index) const
Definition: SocketCodeTable.cc:484
RFPortCode.hh
RFPortCode
Definition: RFPortCode.hh:44
FUPortCode
Definition: FUPortCode.hh:47
GuardField
Definition: GuardField.hh:55
BGTR
const string BGTR
Definition: DefaultDecoderGenerator.cc:135
DefaultDecoderGenerator::gcuDataPort
static std::string gcuDataPort(const std::string &nameInADF)
Definition: DefaultDecoderGenerator.cc:4628
ImmediateEncoding.hh
ProGe::CUOpcodeGenerator
Definition: CUOpcodeGenerator.hh:57
DefaultDecoderGenerator::lockTraceStartingCycle_
unsigned int lockTraceStartingCycle_
The starting cycle for bus tracing.
Definition: DefaultDecoderGenerator.hh:339
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
GuardField::unconditionalGuardEncoding
UnconditionalGuardEncoding & unconditionalGuardEncoding(bool inverted) const
Definition: GuardField.cc:490
BLTUR
const string BLTUR
Definition: DefaultDecoderGenerator.cc:138
BNZ
const string BNZ
Definition: DefaultDecoderGenerator.cc:117
ProGe::NetlistBlock::parentBlock
virtual const NetlistBlock & parentBlock() const override
Definition: NetlistBlock.cc:126
DefaultDecoderGenerator::writeInstructionTemplateProcedures
void writeInstructionTemplateProcedures(const ProGe::HDL language, const TTAMachine::InstructionTemplate &iTemp, int indLevel, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1955
TTAMachine::Socket::segment
Segment * segment(int index) const
Definition: Socket.cc:401
ProGe::NetlistGenerator::glockReqPort
NetlistPort & glockReqPort(const NetlistBlock &block) const
Definition: NetlistGenerator.cc:510
SourceField.hh
ProGe::NetlistGenerator::glockPort
NetlistPort & glockPort(const NetlistBlock &block) const
Definition: NetlistGenerator.cc:477
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::Socket::direction
Direction direction() const
BLER
const string BLER
Definition: DefaultDecoderGenerator.cc:139
TTAMachine::Bus::segment
virtual Segment * segment(int index) const
Definition: Bus.cc:329
DefaultDecoderGenerator::verifyCompatibility
void verifyCompatibility() const
Definition: DefaultDecoderGenerator.cc:704
ProGe::Netlist
Definition: Netlist.hh:63
FUGuardEncoding
Definition: FUGuardEncoding.hh:47
SlotField::socketEncoding
SocketEncoding & socketEncoding(int index) const
Definition: SlotField.cc:170
ProGe::NetlistGenerator::loadPort
NetlistPort & loadPort(const NetlistPort &port) const
Definition: NetlistGenerator.cc:304
TTAMachine::InstructionTemplate::slotCount
virtual int slotCount() const
Definition: InstructionTemplate.cc:236
ProGe::NetlistGenerator::netlistBlock
NetlistBlock & netlistBlock(const TTAMachine::Unit &unit) const
Definition: NetlistGenerator.cc:283
BLTU
const string BLTU
Definition: DefaultDecoderGenerator.cc:128
MoveSlot.hh
BNER
const string BNER
Definition: DefaultDecoderGenerator.cc:134
Socket.hh
DefaultDecoderGenerator::addGlockPortToDecoder
void addGlockPortToDecoder()
Definition: DefaultDecoderGenerator.cc:508
DefaultDecoderGenerator::writeInstructionDecoder
void writeInstructionDecoder(std::ostream &stream)
Definition: DefaultDecoderGenerator.cc:807
Conversion::toString
static std::string toString(const T &source)
DefaultDecoderGenerator::busMuxEnableRegister
static std::string busMuxEnableRegister(const TTAMachine::Bus &bus)
Definition: DefaultDecoderGenerator.cc:4473
BLE
const string BLE
Definition: DefaultDecoderGenerator.cc:125
DefaultDecoderGenerator::writeControlRulesOfFUOutputPort
void writeControlRulesOfFUOutputPort(const TTAMachine::BaseFUPort &port, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2876
ImmediateSlotField
Definition: ImmediateSlotField.hh:44
TTAMachine::RFPort
Definition: RFPort.hh:45
TTAMachine::Bus::signExtends
bool signExtends() const
Definition: Bus.cc:171
TTAMachine::BaseFUPort::isOpcodeSetting
virtual bool isOpcodeSetting() const =0
ProGe::Netlist::connect
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition: Netlist.cc:83
BGEUR
const string BGEUR
Definition: DefaultDecoderGenerator.cc:142
SocketCodeTable
Definition: SocketCodeTable.hh:68
ImmediateControlField::hasTemplateEncoding
bool hasTemplateEncoding(const std::string &name) const
Definition: ImmediateControlField.cc:167
TTAMachine::BaseRegisterFile::numberOfRegisters
virtual int numberOfRegisters() const
DefaultDecoderGenerator::writeControlRulesOfFUInputPort
void writeControlRulesOfFUInputPort(const TTAMachine::BaseFUPort &port, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:3138
DefaultDecoderGenerator::indentation
static std::string indentation(unsigned int level)
Definition: DefaultDecoderGenerator.cc:4937
DefaultDecoderGenerator::iuWriteLoadCntrlPort
static std::string iuWriteLoadCntrlPort(const std::string &unitName)
Definition: DefaultDecoderGenerator.cc:4440
TCEString.hh
TTAMachine::InstructionTemplate
Definition: InstructionTemplate.hh:49
ProGe::BaseNetlistBlock::hasParentBlock
virtual bool hasParentBlock() const
Definition: BaseNetlistBlock.cc:353
StringTools.hh
CentralizedControlICGenerator
Definition: CentralizedControlICGenerator.hh:52
DefaultDecoderGenerator::fuOpcodeCntrlPort
static std::string fuOpcodeCntrlPort(const std::string &fu)
Definition: DefaultDecoderGenerator.cc:4218
assert
#define assert(condition)
Definition: Application.hh:86
DefaultDecoderGenerator::socketBusControlPort
static std::string socketBusControlPort(const std::string &name)
Definition: DefaultDecoderGenerator.cc:4518
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
DefaultDecoderGenerator::writeSimmDataSignal
void writeSimmDataSignal(const TTAMachine::Bus &bus, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2780
TTAMachine::HWOperation::port
virtual FUPort * port(int operand) const
Definition: HWOperation.cc:320
GuardField::gprGuardEncoding
GPRGuardEncoding & gprGuardEncoding(int index) const
Definition: GuardField.cc:290
DefaultDecoderGenerator::registerBits
std::vector< std::string > registerBits
Definition: DefaultDecoderGenerator.hh:350
MoveSlot::hasSourceField
bool hasSourceField() const
Definition: MoveSlot.cc:264
TTAMachine::FUPort
Definition: FUPort.hh:46
DefaultDecoderGenerator::instructionTemplateCondition
std::string instructionTemplateCondition(const ProGe::HDL language, const std::string &iTempName) const
Definition: DefaultDecoderGenerator.cc:4822
CentralizedControlICGenerator::simmDataPort
ProGe::NetlistPort & simmDataPort(const std::string &busName) const
Definition: CentralizedControlICGenerator.cc:64
DefaultDecoderGenerator.hh
FUGuardEncoding::functionUnit
std::string functionUnit() const
Definition: FUGuardEncoding.cc:121
Segment.hh
DefaultDecoderGenerator::generateDebugger_
bool generateDebugger_
Generate debugger signals?
Definition: DefaultDecoderGenerator.hh:333
TTAMachine::BaseRegisterFile
Definition: BaseRegisterFile.hh:48
FUGuardEncoding.hh
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
DefaultDecoderGenerator::writeBusControlRulesOfOutputSocket
void writeBusControlRulesOfOutputSocket(const TTAMachine::Socket &socket, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2731
ProGe::VHDL
@ VHDL
VHDL.
Definition: ProGeTypes.hh:41
HWOperation.hh
ImmediateControlField
Definition: ImmediateControlField.hh:57
TTAMachine::Unit
Definition: Unit.hh:51
GuardEncoding
Definition: GuardEncoding.hh:45
TTAMachine::SpecialRegisterPort
Definition: SpecialRegisterPort.hh:48
TTAMachine::InstructionTemplate::numberOfSlots
virtual int numberOfSlots(const ImmediateUnit &dstUnit) const
Definition: InstructionTemplate.cc:367
DefaultDecoderGenerator::rfOpcodeFromSrcOrDstField
static std::string rfOpcodeFromSrcOrDstField(const ProGe::HDL language, const SocketEncoding &socketEnc, const PortCode &code)
Definition: DefaultDecoderGenerator.cc:4847
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
ImmediateControlField::width
virtual int width() const
Definition: ImmediateControlField.cc:243
InvalidData
Definition: Exception.hh:149
DefaultDecoderGenerator::guardFieldSignal
static std::string guardFieldSignal(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4567
DefaultDecoderGenerator::unitGlockBitMap_
UnitGlockBitMapType unitGlockBitMap_
Maps connected glock port bits to associated TTA Units.
Definition: DefaultDecoderGenerator.hh:344
RFImplementation.hh
PortCode::indexWidth
int indexWidth() const
Definition: PortCode.cc:215
MoveSlot::guardField
GuardField & guardField() const
Definition: MoveSlot.cc:215
LIMM_TAG_SIGNAL
const string LIMM_TAG_SIGNAL
Definition: DefaultDecoderGenerator.cc:105
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
TTAMachine::ControlUnit
Definition: ControlUnit.hh:50
THROW_EXCEPTION
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition: Exception.hh:39
Conversion.hh
TTAMachine::RegisterGuard
Definition: Guard.hh:137
DefaultDecoderGenerator::findGuard
TTAMachine::RegisterGuard & findGuard(const GPRGuardEncoding &encoding) const
Definition: DefaultDecoderGenerator.cc:4056
BinaryEncoding.hh
TTAMachine::Segment::parentBus
Bus * parentBus() const
SourceField::immediateEncoding
ImmediateEncoding & immediateEncoding() const
Definition: SourceField.cc:293
DefaultDecoderGenerator::writeSquashSignalSubstitution
static void writeSquashSignalSubstitution(const ProGe::HDL language, const TTAMachine::Bus &bus, const GuardEncoding &enc, const TTAMachine::Guard &guard, std::ostream &stream, int indLevel)
Definition: DefaultDecoderGenerator.cc:3935
MoveSlot::hasDestinationField
bool hasDestinationField() const
Definition: MoveSlot.cc:327
DefaultDecoderGenerator::simmControlPort
static std::string simmControlPort(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4130
GuardField::parent
MoveSlot * parent() const
Definition: GuardField.cc:117
POST_DECODE_MERGED_GLOCK_OUTREG
const string POST_DECODE_MERGED_GLOCK_OUTREG
Definition: DefaultDecoderGenerator.cc:111
DefaultDecoderGenerator::iuReadOpcodeCntrlSignal
static std::string iuReadOpcodeCntrlSignal(const std::string &unitName, const std::string &portName)
Definition: DefaultDecoderGenerator.cc:4339
DefaultDecoderGenerator::busMuxCntrlSignal
static std::string busMuxCntrlSignal(const TTAMachine::Bus &bus)
Definition: DefaultDecoderGenerator.cc:4458
TTAMachine::Machine::Navigator::hasItem
bool hasItem(const std::string &name) const
NetlistPort.hh
DefaultDecoderGenerator::rfOpcodeCntrlPort
static std::string rfOpcodeCntrlPort(const std::string &rfName, const std::string &portName)
Definition: DefaultDecoderGenerator.cc:4305
SocketCodeTable::iuPortCode
IUPortCode & iuPortCode(int index) const
Definition: SocketCodeTable.cc:600
CentralizedControlICGenerator.hh
CentralizedControlICGenerator::outputSocketDataControlValue
virtual int outputSocketDataControlValue(const TTAMachine::Socket &socket, const TTAMachine::Port &port) const =0
FUEntry.hh
__func__
#define __func__
Definition: Application.hh:67
GLOCK_PORT_NAME
const string GLOCK_PORT_NAME
Definition: DefaultDecoderGenerator.cc:106
DefaultDecoderGenerator::writeControlRulesOfRFWritePort
void writeControlRulesOfRFWritePort(const TTAMachine::RFPort &port, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:3417
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
DefaultDecoderGenerator::fuLoadCntrlPort
static std::string fuLoadCntrlPort(const std::string &fuName, const std::string &portName)
Definition: DefaultDecoderGenerator.cc:4186
SlotField::width
virtual int width() const
Definition: SlotField.cc:307
TTAMachine::Socket
Definition: Socket.hh:53
NetlistBlock.hh
DefaultDecoderGenerator::GlockReqBitType
int GlockReqBitType
Definition: DefaultDecoderGenerator.hh:124
DefaultDecoderGenerator::writeInstructionDismembering
void writeInstructionDismembering(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1414
MachineInfo::getOpset
static OperationSet getOpset(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:65
DefaultDecoderGenerator::guardPortName
static std::string guardPortName(const TTAMachine::Guard &guard)
Definition: DefaultDecoderGenerator.cc:4492
BZ1
const string BZ1
Definition: DefaultDecoderGenerator.cc:118
BNE
const string BNE
Definition: DefaultDecoderGenerator.cc:129
BGTU
const string BGTU
Definition: DefaultDecoderGenerator.cc:124
DefaultDecoderGenerator::writeRulesForSourceControlSignals
void writeRulesForSourceControlSignals(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2599
DefaultDecoderGenerator::GLOCK_PORT_NAME
static const std::string GLOCK_PORT_NAME
Definition: DefaultDecoderGenerator.hh:117
Guard.hh
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
DefaultDecoderGenerator::iuReadLoadCntrlPort
static std::string iuReadLoadCntrlPort(const std::string &unitName, const std::string &portName)
Definition: DefaultDecoderGenerator.cc:4356
DefaultDecoderGenerator::~DefaultDecoderGenerator
virtual ~DefaultDecoderGenerator()
Definition: DefaultDecoderGenerator.cc:211
DefaultDecoderGenerator::writePipelineFillProcess
void writePipelineFillProcess(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2518
SocketEncoding::hasSocketCodes
bool hasSocketCodes() const
Definition: SocketEncoding.cc:177
DefaultDecoderGenerator::needsDataControl
static bool needsDataControl(const TTAMachine::Socket &socket)
Definition: DefaultDecoderGenerator.cc:4039
NOPEncoding.hh
BLT
const string BLT
Definition: DefaultDecoderGenerator.cc:127
DefaultDecoderGenerator::iuWriteOpcodeCntrlSignal
static std::string iuWriteOpcodeCntrlSignal(const std::string &unitName)
Definition: DefaultDecoderGenerator.cc:4426
DefaultDecoderGenerator::iuReadOpcodeCntrlPort
static std::string iuReadOpcodeCntrlPort(const std::string &unitName, const std::string &portName)
Definition: DefaultDecoderGenerator.cc:4322
DefaultDecoderGenerator::socketEncodingCondition
static std::string socketEncodingCondition(const ProGe::HDL language, const SlotField &srcField, const std::string &socketName)
Definition: DefaultDecoderGenerator.cc:4727
SourceField::width
virtual int width() const
Definition: SourceField.cc:308
CentralizedControlICGenerator::outputSocketCntrlPinForSegment
virtual int outputSocketCntrlPinForSegment(const TTAMachine::Socket &socket, const TTAMachine::Segment &segment) const =0
TTAMachine::InstructionTemplate::supportedWidth
virtual int supportedWidth() const
Definition: InstructionTemplate.cc:427
HDB::RFEntry::implementation
RFImplementation & implementation() const
Definition: RFEntry.cc:102
Encoding::encoding
unsigned int encoding() const
Definition: Encoding.cc:108
ProGe::BIT
@ BIT
One bit.
Definition: ProGeTypes.hh:47
VHDLNetlistWriter.hh
GuardField::hasUnconditionalGuardEncoding
bool hasUnconditionalGuardEncoding(bool inverted) const
Definition: GuardField.cc:471
DefaultDecoderGenerator::writeBusControlRulesOfSImmSocketOfBus
void writeBusControlRulesOfSImmSocketOfBus(const TTAMachine::Bus &bus, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2806
SlotField::componentIDPosition
BinaryEncoding::Position componentIDPosition() const
Definition: SlotField.cc:296
TTAMachine::ControlUnit::delaySlots
int delaySlots() const
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
Machine.hh
GuardEncoding::encoding
unsigned int encoding() const
Definition: GuardEncoding.cc:112
Bus.hh
TTAMachine::Machine::socketNavigator
virtual SocketNavigator socketNavigator() const
Definition: Machine.cc:368
MoveSlot::width
virtual int width() const
Definition: MoveSlot.cc:406
MoveSlot::sourceField
SourceField & sourceField() const
Definition: MoveSlot.cc:277
TTAMachine::InstructionTemplate::isOneOfDestinations
virtual bool isOneOfDestinations(const ImmediateUnit &dstUnit) const
Definition: InstructionTemplate.cc:323
ImmediateSlotField::width
virtual int width() const
Definition: ImmediateSlotField.cc:167
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
DefaultDecoderGenerator::busControlWidth
static int busControlWidth(const TTAMachine::Socket &socket)
Definition: DefaultDecoderGenerator.cc:4663
TTAMachine::BaseFUPort::isTriggering
virtual bool isTriggering() const =0
TTAMachine::Port::isOutput
virtual bool isOutput() const
Definition: Port.cc:308
FileSystem::createFile
static bool createFile(const std::string &file)
Definition: FileSystem.cc:468
DefaultDecoderGenerator::fuLoadSignalName
static std::string fuLoadSignalName(const std::string &fuName, const std::string &portName)
Definition: DefaultDecoderGenerator.cc:4203
CUOpcodeGenerator.hh
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
FUImplementation.hh
DefaultDecoderGenerator::glockRequestWidth
int glockRequestWidth() const
Definition: DefaultDecoderGenerator.cc:585
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
SocketEncoding.hh
DefaultDecoderGenerator::writeSquashSignals
void writeSquashSignals(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1169
DefaultDecoderGenerator::nlGenerator_
const ProGe::NetlistGenerator * nlGenerator_
The netlist generator.
Definition: DefaultDecoderGenerator.hh:325
DefaultDecoderGenerator::writeFUCntrlSignals
void writeFUCntrlSignals(std::ostream &stream)
Definition: DefaultDecoderGenerator.cc:1256
DefaultDecoderGenerator::simmCntrlSignalName
static std::string simmCntrlSignalName(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4173
GPRGuardEncoding.hh
VerilogNetlistWriter.hh
DefaultDecoderGenerator::rfOpcodeWidth
static int rfOpcodeWidth(const TTAMachine::BaseRegisterFile &rf)
Definition: DefaultDecoderGenerator.cc:4696
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
ProGe::OUT
@ OUT
Output port.
Definition: ProGeTypes.hh:54
DefaultDecoderGenerator::moveFieldSignal
static std::string moveFieldSignal(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4481
ImmediateControlField.hh
PortCode::encodingWidth
int encodingWidth() const
Definition: PortCode.cc:204
ProGe::CUOpcodeGenerator::encoding
size_t encoding(const std::string &operName) const
Definition: CUOpcodeGenerator.cc:84
DefaultDecoderGenerator::writeMainDecodingProcess
void writeMainDecodingProcess(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2323
TTAMachine::Unit::outputPortCount
virtual int outputPortCount(bool countBidir=false) const
Definition: Unit.cc:145
ImmediateEncoding::immediatePosition
int immediatePosition() const
Definition: ImmediateEncoding.cc:181
ImmediateEncoding::immediateWidth
int immediateWidth() const
Definition: ImmediateEncoding.cc:144
DefaultDecoderGenerator::rfOpcodeSignalName
static std::string rfOpcodeSignalName(const std::string &rfName, const std::string &portName, bool async=false)
Definition: DefaultDecoderGenerator.cc:4285
DefaultDecoderGenerator::SetHDL
void SetHDL(ProGe::HDL language)
Definition: DefaultDecoderGenerator.cc:177
GuardField::gprGuardEncodingCount
int gprGuardEncodingCount() const
Definition: GuardField.cc:276
ProGe::NetlistGenerator::rfGuardPort
NetlistPort & rfGuardPort(const NetlistBlock &rfBlock) const
Definition: NetlistGenerator.cc:357
DefaultDecoderGenerator::bem_
const BinaryEncoding & bem_
The binary encoding map.
Definition: DefaultDecoderGenerator.hh:321
DefaultDecoderGenerator::writeRulesForDestinationControlSignals
void writeRulesForDestinationControlSignals(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2689
DefaultDecoderGenerator::writeSquashSignalGenerationProcess
void writeSquashSignalGenerationProcess(const TTAMachine::Bus &bus, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1566
LOCK_REQ_PORT_NAME
const string LOCK_REQ_PORT_NAME
Definition: DefaultDecoderGenerator.cc:107
TTAMachine::BaseRegisterFile::port
virtual RFPort * port(const std::string &name) const
Definition: BaseRegisterFile.cc:129
BinaryEncoding::immediateSlotCount
int immediateSlotCount() const
Definition: BinaryEncoding.cc:216
CALL
const string CALL
Definition: DefaultDecoderGenerator.cc:115
ProGe::NetlistPort::realWidth
int realWidth() const
Definition: NetlistPort.cc:348
DefaultDecoderGenerator::writeControlRegisterMappings
void writeControlRegisterMappings(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:3547
TTAMachine::RFPort::parentUnit
BaseRegisterFile * parentUnit() const
Definition: RFPort.cc:93
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
BGER
const string BGER
Definition: DefaultDecoderGenerator.cc:140
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
ImmediateSlotField::name
std::string name() const
Definition: ImmediateSlotField.cc:123
CALLR
const string CALLR
Definition: DefaultDecoderGenerator.cc:131
ImmediateEncoding::encodingWidth
int encodingWidth() const
Definition: ImmediateEncoding.cc:155
SocketEncoding::socketIDWidth
int socketIDWidth() const
Definition: SocketEncoding.cc:264
DefaultDecoderGenerator::writeComment
void writeComment(std::ostream &stream, int indent, std::string comment) const
Definition: DefaultDecoderGenerator.cc:795
BLTR
const string BLTR
Definition: DefaultDecoderGenerator.cc:136
SocketEncoding::socketIDPosition
int socketIDPosition() const
Definition: SocketEncoding.cc:249
ProGe::NetlistGenerator
Definition: NetlistGenerator.hh:84
TTAMachine::Guard::isInverted
virtual bool isInverted() const
MachineInfo::OperationSet
TCETools::CIStringSet OperationSet
Definition: MachineInfo.hh:60
DefaultDecoderGenerator::writeInstructionDecoding
void writeInstructionDecoding(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2583
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
ProGe
Definition: FUGen.hh:54
DefaultDecoderGenerator::setSyncReset
void setSyncReset(bool value)
Definition: DefaultDecoderGenerator.cc:187
GuardField::fuGuardEncodingCount
int fuGuardEncodingCount() const
Definition: GuardField.cc:373
TCEString::appendToNonEmpty
static std::string & appendToNonEmpty(std::string &toAppend, stringCRef appender)
Definition: TCEString.cc:201
BinaryEncoding::RIGHT
@ RIGHT
Definition: BinaryEncoding.hh:65
AssocTools.hh
BGE
const string BGE
Definition: DefaultDecoderGenerator.cc:121
DefaultDecoderGenerator::writeLongImmediateTagSignal
void writeLongImmediateTagSignal(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1152
TTAMachine::Port::name
virtual std::string name() const
Definition: Port.cc:141
SlotField
Definition: SlotField.hh:58
ProGe::DataType
DataType
Data types of hardware ports.
Definition: ProGeTypes.hh:46
DefaultDecoderGenerator::setGenerateBusEnable
void setGenerateBusEnable(bool value)
Definition: DefaultDecoderGenerator.cc:192
DefaultDecoderGenerator::RISCV_SIMM_PORT_IN_NAME
static const std::string RISCV_SIMM_PORT_IN_NAME
Definition: DefaultDecoderGenerator.hh:116
ProGe::NetlistGenerator::instructionDecoder
NetlistBlock & instructionDecoder() const
Definition: NetlistGenerator.cc:600
CentralizedControlICGenerator::glockPort
ProGe::NetlistPort & glockPort() const
Definition: CentralizedControlICGenerator.cc:139
TCEString
Definition: TCEString.hh:53
ProGe::NetlistGenerator::fuOpcodePort
NetlistPort & fuOpcodePort(const NetlistBlock &fuBlock) const
Definition: NetlistGenerator.cc:380
DefaultDecoderGenerator::dataControlWidth
static int dataControlWidth(const TTAMachine::Socket &socket)
Definition: DefaultDecoderGenerator.cc:4680
SocketEncoding::parent
SlotField * parent() const
Definition: SocketEncoding.cc:127
FUPort.hh
ProGe::NetlistGenerator::rfOpcodePort
NetlistPort & rfOpcodePort(const NetlistPort &port) const
Definition: NetlistGenerator.cc:334
TTAMachine::HWOperation::parentUnit
FunctionUnit * parentUnit() const
Definition: HWOperation.cc:190
MathTools::bitLength
static unsigned int bitLength(long unsigned int number)
ControlUnit.hh
ImmediateEncoding::encodingPosition
int encodingPosition() const
Definition: ImmediateEncoding.cc:166
DefaultDecoderGenerator::rfLoadSignalName
static std::string rfLoadSignalName(const std::string &rfName, const std::string &portName, bool async=false)
Definition: DefaultDecoderGenerator.cc:4261
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
SpecialRegisterPort.hh
DefaultDecoderGenerator::squashSignal
static std::string squashSignal(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4591
DefaultDecoderGenerator::fuOpcodeSignalName
static std::string fuOpcodeSignalName(const std::string &fu)
Definition: DefaultDecoderGenerator.cc:4230
LImmDstRegisterField
Definition: LImmDstRegisterField.hh:47
DefaultDecoderGenerator::iuReadLoadCntrlSignal
static std::string iuReadLoadCntrlSignal(const std::string &unitName, const std::string &portName)
Definition: DefaultDecoderGenerator.cc:4373
DefaultDecoderGenerator::writeRFSRAMDecodingProcess
void writeRFSRAMDecodingProcess(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2139
DefaultDecoderGenerator::GlockBitType
int GlockBitType
Types for mapping global lock and global lock request signals.
Definition: DefaultDecoderGenerator.hh:123
PRE_DECODE_MERGED_GLOCK_SIGNAL
const string PRE_DECODE_MERGED_GLOCK_SIGNAL
Definition: DefaultDecoderGenerator.cc:109
FUGuardEncoding::port
std::string port() const
Definition: FUGuardEncoding.cc:132
TTAMachine::Port::outputSocket
virtual Socket * outputSocket() const
Definition: Port.cc:281
DefaultDecoderGenerator::writePipelineFillSignals
void writePipelineFillSignals(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1403
DefaultDecoderGenerator::busMuxCntrlRegister
static std::string busMuxCntrlRegister(const TTAMachine::Bus &bus)
Definition: DefaultDecoderGenerator.cc:4463
DefaultDecoderGenerator::socketBusCntrlSignalName
static std::string socketBusCntrlSignalName(const std::string &name)
Definition: DefaultDecoderGenerator.cc:4604
TCEString::makeString
static std::string makeString(const IterableContainer &container, const std::string &separator=", ")
DefaultDecoderGenerator::immSlotSignal
static std::string immSlotSignal(const std::string &immSlot)
Definition: DefaultDecoderGenerator.cc:4579
TTAMachine::Port::isInput
virtual bool isInput() const
Definition: Port.cc:298
DefaultDecoderGenerator::writeResettingOfControlRegisters
void writeResettingOfControlRegisters(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2558
ProGe::HDL
HDL
HDLs supported by ProGe.
Definition: ProGeTypes.hh:40
DefaultDecoderGenerator::setGenerateDebugger
void setGenerateDebugger(bool generate)
Definition: DefaultDecoderGenerator.cc:182
ProGe::NetlistPort
Definition: NetlistPort.hh:70
BinaryEncoding::immediateControlField
ImmediateControlField & immediateControlField() const
Definition: BinaryEncoding.cc:348
ProGe::NetlistGenerator::netlistPort
NetlistPort & netlistPort(const TTAMachine::Port &port, Direction dir=IN) const
Definition: NetlistGenerator.cc:247
BinaryEncoding::moveSlot
MoveSlot & moveSlot(int index) const
Definition: BinaryEncoding.cc:121
PortCode::hasEncoding
bool hasEncoding() const
Definition: PortCode.cc:151
ProGe::BaseNetlistBlock::moduleName
const std::string & moduleName() const
Definition: BaseNetlistBlock.cc:140
DefaultDecoderGenerator::needsBusControl
static bool needsBusControl(const TTAMachine::Socket &socket)
Definition: DefaultDecoderGenerator.cc:4020
INTERNAL_MERGED_GLOCK_REQ_SIGNAL
const string INTERNAL_MERGED_GLOCK_REQ_SIGNAL
Definition: DefaultDecoderGenerator.cc:108
BGT
const string BGT
Definition: DefaultDecoderGenerator.cc:123
RFEntry.hh
DefaultDecoderGenerator::language_
ProGe::HDL language_
Definition: DefaultDecoderGenerator.hh:331
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
MoveSlot::destinationField
DestinationField & destinationField() const
Definition: MoveSlot.cc:341
BLEUR
const string BLEUR
Definition: DefaultDecoderGenerator.cc:141
DefaultDecoderGenerator::sacEnabled
bool sacEnabled(const std::string &rfName) const
Definition: DefaultDecoderGenerator.cc:4953
TTAMachine::PortGuard
Definition: Guard.hh:99
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
PIPELINE_FILL_LOCK_SIGNAL
const string PIPELINE_FILL_LOCK_SIGNAL
Definition: DefaultDecoderGenerator.cc:112
ProGe::NetlistGenerator::immediateUnitWritePort
NetlistPort & immediateUnitWritePort(const TTAMachine::ImmediateUnit &iu) const
Definition: NetlistGenerator.cc:532
ImmediateControlField::templateEncoding
unsigned int templateEncoding(const std::string &name) const
Definition: ImmediateControlField.cc:182
DefaultDecoderGenerator::opcodeWidth
int opcodeWidth(const TTAMachine::FunctionUnit &fu) const
Definition: DefaultDecoderGenerator.cc:4640
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
DestinationField.hh
IOException
Definition: Exception.hh:130
TTAMachine::Socket::segmentCount
int segmentCount() const
MathTools.hh
DefaultDecoderGenerator::writeSignalDeclaration
void writeSignalDeclaration(std::ostream &stream, ProGe::DataType type, std::string sigName, int width) const
Definition: DefaultDecoderGenerator.cc:774
TTAMachine::ImmediateUnit::extensionMode
virtual Machine::Extension extensionMode() const
Definition: ImmediateUnit.cc:143
DefaultDecoderGenerator::writeGlockHandlingSignals
void writeGlockHandlingSignals(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:1386
ImmediateEncoding
Definition: ImmediateEncoding.hh:44
BEQR
const string BEQR
Definition: DefaultDecoderGenerator.cc:133
ProGe::NetlistGenerator::hasOpcodePort
bool hasOpcodePort(const NetlistPort &port) const
Definition: NetlistGenerator.cc:322
TTAMachine
Definition: Assembler.hh:48
TTAMachine::ControlUnit::globalGuardLatency
int globalGuardLatency() const
CentralizedControlICGenerator::hasGlockPort
bool hasGlockPort() const
Definition: CentralizedControlICGenerator.cc:128
BinaryEncoding::moveSlotCount
int moveSlotCount() const
Definition: BinaryEncoding.cc:104
TTAMachine::ControlUnit::returnAddressPort
SpecialRegisterPort * returnAddressPort() const
Definition: ControlUnit.cc:307
BEMTools.hh
GPRGuardEncoding::registerIndex
int registerIndex() const
Definition: GPRGuardEncoding.cc:133
CentralizedControlICGenerator::dataCntrlPortOfSocket
ProGe::NetlistPort & dataCntrlPortOfSocket(const std::string &socketName) const
Definition: CentralizedControlICGenerator.cc:115
DefaultDecoderGenerator::DefaultDecoderGenerator
DefaultDecoderGenerator(const TTAMachine::Machine &machine, const BinaryEncoding &bem, const CentralizedControlICGenerator &icGenerator)
Definition: DefaultDecoderGenerator.cc:155
DS
#define DS
Definition: LLVMBackend.cc:124
DefaultDecoderGenerator::portCodeCondition
static std::string portCodeCondition(const ProGe::HDL language, const SocketEncoding &socketEnc, const PortCode &code)
Definition: DefaultDecoderGenerator.cc:4772
CentralizedControlICGenerator::inputSocketControlValue
virtual int inputSocketControlValue(const TTAMachine::Socket &socket, const TTAMachine::Segment &segment) const =0
SocketEncoding::socketCodes
SocketCodeTable & socketCodes() const
Definition: SocketEncoding.cc:191
SocketEncoding
Definition: SocketEncoding.hh:51
GPRGuardEncoding
Definition: GPRGuardEncoding.hh:47
FUPortCode.hh
DefaultDecoderGenerator::registerVectors
std::vector< std::string > registerVectors
Bookkeeping for reset-needing signals.
Definition: DefaultDecoderGenerator.hh:349
SlotField::parent
MoveSlot * parent() const
Definition: SlotField.cc:98
TTAMachine::Machine::instructionTemplateNavigator
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition: Machine.cc:428
PortCode::encoding
unsigned int encoding() const
Definition: PortCode.cc:164
TTAMachine::BaseRegisterFile::width
virtual int width() const
DefaultDecoderGenerator::writeLockDumpCode
void writeLockDumpCode(std::ostream &stream) const
void writeDecompressSignalsVHDL(std::ostream& stream) const; TBR
Definition: DefaultDecoderGenerator.cc:963
BinaryEncoding::longImmDstRegisterField
LImmDstRegisterField & longImmDstRegisterField(int index) const
Definition: BinaryEncoding.cc:415
DefaultDecoderGenerator::simmDataSignalName
static std::string simmDataSignalName(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4161
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
BNZ1
const string BNZ1
Definition: DefaultDecoderGenerator.cc:119
UnconditionalGuardEncoding
Definition: UnconditionalGuardEncoding.hh:47
DefaultDecoderGenerator::containsSimilarGuard
static bool containsSimilarGuard(const std::set< TTAMachine::PortGuard * > &guardSet, const TTAMachine::PortGuard &guard)
Definition: DefaultDecoderGenerator.cc:3970
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
SocketCodeTable::width
int width() const
Definition: SocketCodeTable.cc:200
ProGe::NetlistBlock::port
virtual NetlistPort * port(const std::string &portName, bool partialMatch=true)
Definition: NetlistBlock.cc:97
DefaultDecoderGenerator::writeGlockMapping
void writeGlockMapping(std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2404
LImmDstRegisterField.hh
HDB::RFImplementation::separateAddressCycleParameter
bool separateAddressCycleParameter() const
Definition: RFImplementation.cc:194
BGEU
const string BGEU
Definition: DefaultDecoderGenerator.cc:122
ProGe::IN
@ IN
Input port.
Definition: ProGeTypes.hh:53
DefaultDecoderGenerator::generateLockTrace_
bool generateLockTrace_
Tells whether to generate global lock tracing code.
Definition: DefaultDecoderGenerator.hh:329
CALLA
const string CALLA
Definition: DefaultDecoderGenerator.cc:132
TTAMachine::ControlUnit::hasReturnAddressPort
bool hasReturnAddressPort() const
Definition: ControlUnit.cc:295
DefaultDecoderGenerator::generateBusEnable_
bool generateBusEnable_
Bus enable signals for bustrace.
Definition: DefaultDecoderGenerator.hh:337
GuardField::width
virtual int width() const
Definition: GuardField.cc:533
DefaultDecoderGenerator::simmDataPort
static std::string simmDataPort(const std::string &busName)
Definition: DefaultDecoderGenerator.cc:4117
BZ
const string BZ
Definition: DefaultDecoderGenerator.cc:116
DefaultDecoderGenerator::generateAlternateGlockReqHandling_
bool generateAlternateGlockReqHandling_
The flag to generate global lock request handling in decoder. False means delegating the lock request...
Definition: DefaultDecoderGenerator.hh:342
NetlistGenerator.hh
DefaultDecoderGenerator::iuWriteSignal
static std::string iuWriteSignal(const std::string &iuName)
Definition: DefaultDecoderGenerator.cc:4400
DefaultDecoderGenerator::glockPortWidth
int glockPortWidth() const
Definition: DefaultDecoderGenerator.cc:613
TTAMachine::Machine
Definition: Machine.hh:73
DefaultDecoderGenerator::writeControlRulesOfRFReadPort
void writeControlRulesOfRFReadPort(const TTAMachine::RFPort &port, std::ostream &stream) const
Definition: DefaultDecoderGenerator.cc:2947
ProGe::NetlistGenerator::hasGlockPort
bool hasGlockPort(const NetlistBlock &block) const
Definition: NetlistGenerator.cc:465
GuardEncoding::parent
GuardField * parent() const
Definition: GuardEncoding.cc:90
DefaultDecoderGenerator::setGenerateNoLoopbackGlock
void setGenerateNoLoopbackGlock(bool generate)
Definition: DefaultDecoderGenerator.cc:204
BLEU
const string BLEU
Definition: DefaultDecoderGenerator.cc:126
DefaultDecoderGenerator::syncReset_
bool syncReset_
Reset synchronously (otherwise asynchronous)
Definition: DefaultDecoderGenerator.hh:335
SourceField
Definition: SourceField.hh:48
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50