OpenASIP  2.0
Classes | Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
FUGen Class Reference

#include <FUGen.hh>

Collaboration diagram for FUGen:
Collaboration graph

Classes

struct  BaseOperation
 
struct  DAGConstant
 
struct  OperandConnection
 
struct  OperationSchedule
 
struct  OutputConnection
 

Public Member Functions

 FUGen ()=delete
 
 FUGen (const FUGen &)=delete
 
FUGenoperator= (const FUGen &)=delete
 
 FUGen (const ProGeOptions &options, std::vector< std::string > globalOptions, IDF::FUGenerated &fug, const TTAMachine::Machine &machine, ProGe::NetlistBlock *core)
 

Static Public Member Functions

static void implement (const ProGeOptions &options, std::vector< std::string > globalOptions, const std::vector< IDF::FUGenerated > &generatetFUs, const TTAMachine::Machine &machine, ProGe::NetlistBlock *core)
 

Private Types

typedef std::pair< std::string, std::string > Replace
 

Private Member Functions

void createOutputPipeline ()
 
void addRegisterIfMissing (std::string name, int width, HDLGenerator::WireType wt=HDLGenerator::WireType::Auto)
 
std::string findAbsolutePath (std::string file)
 
void createFUHeaderComment ()
 
void createMandatoryPorts ()
 
void checkForValidity ()
 
void createExternalInterfaces (bool genIntegrator)
 
void createOperationResources ()
 
void buildOperations ()
 
void finalizeHDL ()
 
void createImplementationFiles ()
 
void copyImplementation (std::string file, std::string format, bool isSynthesizable)
 
void parseOperations ()
 
void scheduleOperations ()
 
void createPortPipeline ()
 
void createShadowRegisters ()
 
OperandConnection subOpConnection (OperationDAG *dag, OperationDAGEdge *edge, bool isOutput)
 
int DAGNodeOperandWidth (OperationDAGNode &node, int id, OperationDAG *dag)
 
void readImplementation (std::string filename, std::string opName, std::deque< std::string > &sink)
 
void prepareSnippet (std::string name, std::deque< std::string > statements, HDLGenerator::CodeBlock &sink, std::set< std::string > &addedStatements)
 
std::deque< std::string > readFile (std::string filename)
 
std::vector< ReplacebuildReplaces (std::string opName)
 
std::string replaceToken (std::string line, Replace replace)
 
bool hasToken (std::string line, std::string token)
 
HDLGenerator::Language selectedLanguage ()
 
std::string opcodeSignal (int stage)
 
std::string triggerSignal (int stage)
 
std::string opcodeConstant (std::string operation)
 
std::string operandSignal (std::string operation, int id)
 
std::string operandPlaceholder (int id)
 
std::string pipelineName (std::string port, int cycle)
 
std::string pipelineValid (std::string port, int cycle)
 
std::string subOpName (OperationNode *node)
 
std::string constantName (ConstantNode *node, OperationDAG *dag)
 
std::string constantName (DAGConstant dag)
 
bool isLSUDataPort (const std::string &portName)
 
ProGe::Signal inferLSUSignal (const std::string &portName) const
 

Private Attributes

int maxLatency_
 
int minLatency_
 
const ProGeOptionsoptions_
 
std::vector< std::string > globalOptions_
 
IDF::FUGeneratedfug_
 
ProGe::NetlistBlockcore_
 
HDLGenerator::Module fu_
 
TTAMachine::FunctionUnitadfFU_
 
std::vector< std::string > operations_
 
int opcodeWidth_
 
std::string moduleName_
 
ProGe::NetlistBlocknetlistBlock_
 
std::unordered_map< std::string, BaseOperationbaseOperations_
 
std::unordered_map< std::string, OperationSchedulescheduledOperations_
 
std::unordered_map< std::string, std::vector< Replace > > replacesPerOp_
 
std::unordered_map< std::string, int > operationCycles_
 
std::unordered_map< std::string, int > implLatency_
 
std::unordered_map< std::string, OperationDAG * > implementapleDAGs_
 
std::unordered_map< std::string, int > subOpCount_
 
std::unordered_map< std::string, int > dagConstantCount_
 
std::unordered_map< std::string, int > resourceCount_
 
std::unordered_map< std::string, int > pipelineLength_
 
std::unordered_map< std::string, ProGe::DirectionportDirection_
 
std::unordered_multimap< std::string, OutputConnectionportInputs_
 
std::unordered_map< int, int > nodeImplementations_
 
std::unordered_map< int, DAGConstantdagConstants_
 
std::vector< std::string > resourceInputs_
 
std::vector< std::string > resourceOutputs_
 
std::unordered_set< std::string > extIfaces_
 
std::set< std::pair< std::string, std::string > > extOutputs_
 
std::unordered_set< std::string > extInputs_
 
std::vector< HDB::VariablerenamedVariables_
 
std::vector< HDB::VariablerenamedGlobalSignals_
 
std::string triggerPort_
 
std::vector< std::string > registers_
 
bool useGlockRequest_ = false
 
bool useGlock_ = false
 
HDLGenerator::Behaviour behaviour_
 
bool frontRegistered_ = false
 
bool middleRegistered_ = false
 
bool backRegistered_ = false
 
int addressWidth_ = 0
 
bool isLSU_ = false
 

Detailed Description

Definition at line 58 of file FUGen.hh.

Member Typedef Documentation

◆ Replace

typedef std::pair<std::string, std::string> FUGen::Replace
private

Definition at line 98 of file FUGen.hh.

Constructor & Destructor Documentation

◆ FUGen() [1/3]

FUGen::FUGen ( )
delete

◆ FUGen() [2/3]

FUGen::FUGen ( const FUGen )
delete

◆ FUGen() [3/3]

FUGen::FUGen ( const ProGeOptions options,
std::vector< std::string >  globalOptions,
IDF::FUGenerated fug,
const TTAMachine::Machine machine,
ProGe::NetlistBlock core 
)
inline

Definition at line 63 of file FUGen.hh.

65  :
67  globalOptions_(globalOptions),
68  fug_(fug),
69  core_(core),
70  fu_(StringTools::stringToLower("fu_" + fug.name())),
72  operations_(),
74  moduleName_("fu_" + fug_.name()) {
75 
76  // Find the netlistblock
77  for (size_t i = 0; i < core_->subBlockCount(); ++i) {
78  std::string name = core_->subBlock(i).moduleName();
81  break;
82  }
83  }
84 
85  if (adfFU_->hasAddressSpace()) {
86  auto as = adfFU_->addressSpace();
88  }
89  }

References TTAMachine::FunctionUnit::addressSpace(), addressWidth_, adfFU_, core_, TTAMachine::FunctionUnit::hasAddressSpace(), ProGe::BaseNetlistBlock::moduleName(), moduleName_, netlistBlock_, MathTools::requiredBits(), StringTools::stringToLower(), ProGe::NetlistBlock::subBlock(), and ProGe::NetlistBlock::subBlockCount().

Here is the call graph for this function:

Member Function Documentation

◆ addRegisterIfMissing()

void FUGen::addRegisterIfMissing ( std::string  name,
int  width,
HDLGenerator::WireType  wt = HDLGenerator::WireType::Auto 
)
private

Definition at line 1377 of file FUGen.cc.

1377  {
1379  fu_ << Register(name, width, wt, ResetOption::Optional);
1380  registers_.emplace_back(name);
1381  }
1382 }

References ContainerTools::containsValue(), and HDLGenerator::Optional.

Here is the call graph for this function:

◆ buildOperations()

void FUGen::buildOperations ( )
private

Definition at line 672 of file FUGen.cc.

672  {
673  Asynchronous operationCp("operations_actual_cp");
674  CodeBlock defaultValues;
675  CodeBlock defaultSnippets;
676  CodeBlock triggeredSnippets;
677 
678  for (auto&& d : extOutputs_) {
679  operationCp << DefaultAssign(d.first, d.second);
680  }
681 
682  for (std::string signal : resourceInputs_) {
683  // Zero initialize this configuration to avoid simulation warnings
684  if (isLSU_ && minLatency_ < 3) {
685  operationCp << DefaultAssign(signal, "0");
686  } else {
687  operationCp << DefaultAssign(signal, "-");
688  }
689  }
690 
691  for (auto&& pair : dagConstants_) {
692  auto spec = pair.second;
693  std::string name = constantName(spec);
694  int width = MathTools::requiredBitsSigned(spec.value);
695  fu_ << BinaryConstant(name, width, spec.value);
696  }
697 
698  for (std::string signal : resourceOutputs_) {
699  operationCp.reads(signal);
700  }
701 
702  for (std::string signal : extInputs_) {
703  operationCp.reads(signal);
704  }
705 
706  std::set<std::string> defaultStatements;
707  for (auto&& pair : scheduledOperations_) {
708  auto schedule = pair.second;
709  std::string name = pair.first;
710 
711  for (int id : schedule.results) {
712  std::string source = operandSignal(name, id);
713  // Zero initialize this configuration to avoid simulation warnings
714  if (isLSU_ && minLatency_ < 3) {
715  defaultValues.append(DefaultAssign(source, "0"));
716  } else {
717  defaultValues.append(DefaultAssign(source, "-"));
718  }
719  }
720 
721  for (auto&& operand : schedule.operands) {
722  int id = operand.id;
723 
724  std::string source = operand.signalName;
725  std::string destination = operandSignal(name, id);
726  if (operand.portWidth > operand.operandWidth) {
727  defaultValues.append(Assign(
728  destination,
729  Splice(source, operand.operandWidth - 1, 0)));
730  } else if (operand.portWidth < operand.operandWidth) {
731  defaultValues.append(Assign(
732  destination,
733  Ext(source, operand.operandWidth, operand.portWidth)));
734  } else {
735  defaultValues.append(Assign(destination, LHSSignal(source)));
736  }
737 
738  if (!operand.isOutput) {
739  operationCp.reads(destination);
740  }
741  }
742 
743  replacesPerOp_[name] = buildReplaces(name);
744 
745  std::string baseOp = schedule.baseOp;
746  auto& initial = baseOperations_[baseOp].initial;
747  if (!initial.empty()) {
748  prepareSnippet(name, initial, defaultSnippets, defaultStatements);
749  }
750  }
751 
752  for (int cycle = 0; cycle <= maxLatency_; ++cycle) {
753  Switch opSwitch(LHSSignal(opcodeSignal(cycle)));
754  bool emptySwitch = true;
755 
756  for (std::string op : operations_) {
757  CodeBlock onTrigger;
758  bool emptyBlock = true;
759  auto schedule = scheduledOperations_[op];
760 
761  std::vector<std::string> schedules = schedule.subOperations;
762  schedules.push_back(op);
763 
764  for (std::string subop : schedules) {
765  auto schedule = scheduledOperations_[subop];
766  std::string baseOp = schedule.baseOp;
767  if (schedule.initialCycle == cycle) {
768  auto& impl = baseOperations_[baseOp].implementation;
769  if (!impl.empty()) {
770  std::set<std::string> statements;
771  prepareSnippet(subop, impl, onTrigger, statements);
772  }
773  emptyBlock = false;
774  }
775 
776  if (schedule.finalCycle == cycle) {
777  auto& postOp = baseOperations_[baseOp].postOp;
778  if (!postOp.empty()) {
779  std::set<std::string> statements;
780  prepareSnippet(subop, postOp, onTrigger, statements);
781  }
782  emptyBlock = false;
783  }
784  }
785 
786  if (emptyBlock) {
787  continue;
788  }
789 
790  if (operations_.size() > 1) {
791  Case opCase(opcodeConstant(op));
792  opCase << onTrigger;
793  opSwitch.addCase(opCase);
794  emptySwitch = false;
795  } else {
796  If opIf(
797  Equals(
798  LHSSignal(triggerSignal(cycle)), BinaryLiteral("1")),
799  onTrigger);
800  triggeredSnippets.append(opIf);
801  }
802  }
803 
804  if (!emptySwitch) {
805  opSwitch.addCase(DefaultCase());
806  If opIf(
808  opSwitch);
809  triggeredSnippets.append(opIf);
810  }
811  }
812 
813  if (useGlock_) {
814  operationCp.reads("glock_in");
815  }
816 
817  if (useGlockRequest_) {
818  defaultValues.append(Assign("glockreq", BinaryLiteral("0")));
819  }
820 
821  for (auto&& v : renamedVariables_) {
822  int w = std::stoi(v.width);
823  if (v.type == "Logic") {
824  operationCp.addVariable(LogicVariable(v.name, w));
825  } else if (v.type == "Unsigned") {
826  operationCp.addVariable(UnsignedVariable(v.name, w));
827  } else {
828  operationCp.addVariable(SignedVariable(v.name, w));
829  }
830  // Zero initialize this configuration to avoid simulation warnings
831  if (isLSU_ && minLatency_ < 3) {
832  operationCp << DefaultAssign(v.name, "0");
833  } else {
834  operationCp << DefaultAssign(v.name, "-");
835  }
836  }
837  for (auto&& s : renamedGlobalSignals_) {
838  int w = std::stoi(s.width);
839  fu_ << Wire(s.name, w); // creates the signal declaration
840  operationCp.reads(s.name); // adds it to sensitivity list
841  // Zero initialize this configuration to avoid simulation warnings
842  if (isLSU_ && minLatency_ < 3) {
843  operationCp << DefaultAssign(s.name, "0");
844  } else {
845  operationCp << DefaultAssign(s.name, "-");
846  }
847  }
848 
849  operationCp << defaultValues << defaultSnippets << triggeredSnippets;
850  behaviour_ << operationCp;
851 }

References HDLGenerator::Switch::addCase(), HDLGenerator::Asynchronous::addVariable(), HDLGenerator::CodeBlock::append(), HDLGenerator::Asynchronous::reads(), and MathTools::requiredBitsSigned().

Referenced by implement().

Here is the call graph for this function:

◆ buildReplaces()

std::vector< FUGen::Replace > FUGen::buildReplaces ( std::string  opName)
private

Definition at line 395 of file FUGen.cc.

395  {
396  OperationSchedule& schedule = scheduledOperations_[name];
397  std::string op = schedule.baseOp;
398  std::vector<FUGen::Replace> replaces;
399 
400  replaces.emplace_back("glock", "glock_in");
401  replaces.emplace_back("trigger", triggerSignal(schedule.initialCycle));
402 
403  for (auto&& operand : schedule.operands) {
404  int id = operand.id;
405  replaces.emplace_back(
406  operandPlaceholder(id), operandSignal(name, id));
407  }
408  for (int id : schedule.results) {
409  replaces.emplace_back(
410  operandPlaceholder(id), operandSignal(name, id));
411  }
412 
413  if (!baseOperations_.count(op)) {
414  return replaces;
415  }
416 
417  // Resources
418  for (auto&& r : baseOperations_[op].resources) {
419  std::string rName = StringTools::stringToLower(r.name);
420  if (!schedule.resourceOffsets.count(rName)) {
421  assert(false && "Couldn't find resource offset.");
422  }
423  int offset = schedule.resourceOffsets[rName];
424 
425  for (int i = 0; i < r.count; ++i) {
426  int portID = i + 1;
427  int resID = i + offset + 1;
428  std::string file = findAbsolutePath(r.ipxact);
430  for (auto&& p : resource.ports) {
431  std::string pName = StringTools::stringToLower(p.name);
432  std::string replace = pName + "_" + std::to_string(portID);
433  std::string with =
434  rName + "_" + std::to_string(resID) + "_" + pName;
435 
436  replaces.emplace_back(replace, with);
437  }
438  }
439  }
440 
441  // Variables
442  for (auto&& v : baseOperations_[op].variables) {
443  std::string replica;
444  if (v.rename) {
445  replica = name + "_" + v.name;
446  replaces.emplace_back(v.name, replica);
447  } else {
448  bool nameFound = false;
449  for (auto&& old_var : renamedVariables_) {
450  if (old_var.name == v.name) {
451  nameFound = true;
452  }
453  }
454  if (nameFound) {
455  continue;
456  }
457  replica = v.name;
458  }
459  HDB::Variable var = {replica, v.width, v.type, v.rename};
460  renamedVariables_.emplace_back(var);
461  }
462  // Global signals
463  for (auto&& s : baseOperations_[op].globalsignals) {
464  std::string replica;
465  // Not renaming the signals allows them to be directly shared between
466  // ops
467  if (s.rename) {
468  replica = name + "_" + s.name;
469  replaces.emplace_back(s.name, replica);
470  } else {
471  // don't add the same signal multiple times
472  bool nameFound = false;
473  for (auto&& old_var : renamedGlobalSignals_) {
474  if (old_var.name == s.name) {
475  nameFound = true;
476  }
477  }
478  if (nameFound) {
479  continue;
480  }
481  replica = s.name;
482  }
483 
484  HDB::Variable var = {replica, s.width, s.type, s.rename};
485  renamedGlobalSignals_.emplace_back(var);
486  }
487 
488  return replaces;
489 }

References assert, FUGen::OperationSchedule::baseOp, FUGen::OperationSchedule::initialCycle, FUGen::OperationSchedule::operands, ipxact::parseComponent(), ipxact::ModuleInfo::ports, FUGen::OperationSchedule::resourceOffsets, FUGen::OperationSchedule::results, StringTools::stringToLower(), and HDB::Variable::width.

Here is the call graph for this function:

◆ checkForValidity()

void FUGen::checkForValidity ( )
private

Definition at line 365 of file FUGen.cc.

365  {
366  // Check that we can implement the FU.
367  // Cannot implement if FU has multioutput operation that has
368  // different latencies for the outputs.
369  for (auto&& op : operations_) {
371  int hwOpOperands = hwOp->operandCount();
372  int prevLatency = -1;
373  for (int operand = 0; operand < hwOpOperands; ++operand) {
374  TTAMachine::FUPort* fuPort = hwOp->port(operand + 1);
375 
376  if (!fuPort->isOutput()) {
377  continue;
378  }
379 
380  int latency = hwOp->latency(operand + 1);
381  if (prevLatency == -1) {
382  prevLatency = latency;
383  } else if (prevLatency != latency) {
384  // TODO: probably not true anymore, but needs to be tested
385  throw std::runtime_error(
386  "FUGen cannot implement multioutput operations (" + op +
387  ") which have different latencies for"
388  " its outputs.");
389  }
390  }
391  }
392 }

References TTAMachine::Port::isOutput(), TTAMachine::HWOperation::latency(), TTAMachine::HWOperation::operandCount(), and TTAMachine::HWOperation::port().

Referenced by implement().

Here is the call graph for this function:

◆ constantName() [1/2]

std::string FUGen::constantName ( ConstantNode node,
OperationDAG dag 
)
private

Definition at line 178 of file FUGen.cc.

178  {
179  int id;
180  std::string op = dag->operation().name();
182  if (dagConstants_.count(node->nodeID())) {
183  id = dagConstants_[node->nodeID()].id;
184  } else {
185  if (!dagConstantCount_.count(op)) {
186  dagConstantCount_[op] = 0;
187  }
188  id = dagConstantCount_[op];
189  dagConstantCount_[op] += 1;
190  dagConstants_[node->nodeID()] = {op, node->value(), id};
191  }
192  return constantName(dagConstants_[node->nodeID()]);
193 }

References OperationPimpl::name(), GraphNode::nodeID(), OperationDAG::operation(), StringTools::stringToLower(), and ConstantNode::value().

Here is the call graph for this function:

◆ constantName() [2/2]

std::string FUGen::constantName ( DAGConstant  dag)
private

Definition at line 196 of file FUGen.cc.

196  {
197  return "dag_" + dagc.operation + "_" + std::to_string(dagc.id) + "_c";
198 }

References FUGen::DAGConstant::id, and FUGen::DAGConstant::operation.

◆ copyImplementation()

void FUGen::copyImplementation ( std::string  file,
std::string  format,
bool  isSynthesizable 
)
private

Definition at line 267 of file FUGen.cc.

268  {
269  file = findAbsolutePath(file);
270  const std::string DS = FileSystem::DIRECTORY_SEPARATOR;
271  std::string dir = options_.outputDirectory + DS;
272  if (isSynthesizable) {
273  dir += format == "VHDL" ? "vhdl" : "verilog";
274  } else {
275  dir += "blackbox" + DS;
276  dir += format == "VHDL simulation" ? "vhdl" : "verilog";
277  }
278  std::string target =
280  if (!FileSystem::fileExists(target)) {
282  FileSystem::copy(file, target);
283  }
284 }

References FileSystem::copy(), FileSystem::createDirectory(), FileSystem::DIRECTORY_SEPARATOR, DS, FileSystem::fileExists(), and FileSystem::fileOfPath().

Here is the call graph for this function:

◆ createExternalInterfaces()

void FUGen::createExternalInterfaces ( bool  genIntegrator)
private

Definition at line 568 of file FUGen.cc.

568  {
569  std::set<std::pair<ProGe::NetlistPort*, ProGe::NetlistPort*>> lsuPorts;
570  Replace replaceAddress = {"addrw_c", std::to_string(addressWidth_)};
571  for (auto&& ei : extIfaces_) {
573  for (auto&& port : info.ports) {
574  std::string width = port.width;
575  if (addressWidth_ > 0) {
576  width = replaceToken(width, replaceAddress);
577  }
578  ProGe::Direction dir;
579  if (port.direction == "out") {
580  fu_ << OutPort(
581  port.name, width, HDLGenerator::WireType::Vector);
582  extOutputs_.emplace(port.name, port.defaultValue);
583  dir = ProGe::Direction::OUT;
584  } else {
585  fu_ << InPort(
586  port.name, width, HDLGenerator::WireType::Vector);
587  extInputs_.emplace(port.name);
588  dir = ProGe::Direction::IN;
589  }
590 
591  std::string extName = moduleName_ + "_" + port.name;
592  ProGe::NetlistPort* ext = NULL;
593  ProGe::NetlistPort* internal = new ProGe::NetlistPort(
594  port.name, width, ProGe::DataType::BIT_VECTOR, dir,
595  *netlistBlock_);
596  if (isLSUDataPort(extName) && !genIntegrator) {
597  ext = new ProGe::NetlistPort(
598  extName, width, ProGe::DataType::BIT_VECTOR, dir, *core_,
599  inferLSUSignal(extName));
600  lsuPorts.insert(std::make_pair(internal, ext));
601  } else {
602  ext = new ProGe::NetlistPort(
603  extName, width, ProGe::DataType::BIT_VECTOR, dir, *core_);
604  core_->netlist().connect(*ext, *internal);
605  }
606  }
607  }
608  if (lsuPorts.empty()) {
609  return;
610  }
611  // Handle LSU data ports.
612  TCEString asName("");
613  if (adfFU_->hasAddressSpace()) {
614  asName = adfFU_->addressSpace()->name();
615  }
616 
617  ProGe::NetlistPortGroup* dmemPortGroup = nullptr;
618  for (auto portPair : lsuPorts) {
619  dmemPortGroup =
620  dmemPortGroup
621  ? dmemPortGroup
624  dmemPortGroup->addPort(*portPair.second);
625  core_->netlist().connect(*portPair.first, *portPair.second);
626  }
627  if (dmemPortGroup != nullptr) {
628  core_->addPortGroup(dmemPortGroup);
629  dmemPortGroup = nullptr;
630  }
631 }

References ProGe::NetlistPortGroup::addPort(), ProGe::BIT_VECTOR, ProGe::BYTEMASKED_SRAM_PORT, HDB::IN, HDB::OUT, ipxact::parseBus(), ipxact::BusInfo::ports, and HDLGenerator::Vector.

Referenced by implement().

Here is the call graph for this function:

◆ createFUHeaderComment()

void FUGen::createFUHeaderComment ( )
private

Creates the header comment for fu.

Definition at line 228 of file FUGen.cc.

228  {
229  fu_.appendToHeader("Function Unit: " + fug_.name());
230  fu_.appendToHeader("");
231  fu_.appendToHeader("Operations:");
232 
233  if (adfFU_->operationCount() > 1) {
234  size_t maxOpNameLen = 0;
235  for (int i = 0; i < adfFU_->operationCount(); ++i) {
237  maxOpNameLen = std::max(maxOpNameLen, hwop->name().size());
238  }
239  int opDigits =
240  static_cast<int>(std::ceil(std::log10(adfFU_->operationCount())));
241  for (int i = 0; i < adfFU_->operationCount(); ++i) {
243  operations_.emplace_back(hwop->name());
244  }
245  std::sort(operations_.begin(), operations_.end());
246  int opcode = 0;
247  for (auto&& op : operations_) {
249  std::ostringstream comment;
250  comment << boost::format(
251  " %-" + std::to_string(maxOpNameLen) + "s : %" +
252  std::to_string(opDigits) + "s") %
253  op % std::to_string(opcode);
254  fu_.appendToHeader(comment.str());
255  opcode++;
256  }
257 
258  } else {
260  operations_.emplace_back(hwop->name());
261  fu_.appendToHeader(" " + hwop->name() + " : 0");
262  }
263  fu_.appendToHeader("");
264 }

References TTAMachine::HWOperation::name().

Referenced by implement().

Here is the call graph for this function:

◆ createImplementationFiles()

void FUGen::createImplementationFiles ( )
private

Definition at line 290 of file FUGen.cc.

290  {
292  Path dir = Path(options_.outputDirectory) / "vhdl";
293  FileSystem::createDirectory(dir.string());
294  Path file = dir / (fu_.name() + ".vhd");
295  std::ofstream ofs(file);
297  } else if (options_.language == ProGe::HDL::Verilog) {
298  Path dir = Path(options_.outputDirectory) / "verilog";
299  FileSystem::createDirectory(dir.string());
300  Path file = dir / (fu_.name() + ".v");
301  std::ofstream ofs(file);
303  }
304 
305  // Copy synthesis files and simulation models.
306  for (auto&& opInfo : fug_.operations()) {
307  std::string hdb = opInfo.hdb;
308  hdb = findAbsolutePath(hdb);
311  manager.OperationImplementationByID(opInfo.id);
312  for (auto&& r : opImpl.resources) {
313  for (size_t i = 0; i < r.simFiles.size(); ++i) {
314  copyImplementation(r.simFiles[i], r.simFormats[i], false);
315  }
316  for (size_t i = 0; i < r.synFiles.size(); ++i) {
317  copyImplementation(r.synFiles[i], r.synFormats[i], true);
318  }
319  }
320  }
321 }

References FileSystem::createDirectory(), HDB::CachedHDBManager::instance(), HDB::HDBManager::OperationImplementationByID(), HDB::OperationImplementation::resources, HDLGenerator::Verilog, ProGe::Verilog, HDLGenerator::VHDL, and ProGe::VHDL.

Referenced by implement().

Here is the call graph for this function:

◆ createMandatoryPorts()

void FUGen::createMandatoryPorts ( )
private

Definition at line 327 of file FUGen.cc.

327  {
328  std::string resetPort;
329  if (ProGeTools::findInOptionList("active low reset", globalOptions_)) {
330  resetPort = "rstx";
331  } else {
332  resetPort = "rst";
333  }
334 
335  fu_ << InPort("clk") << InPort(resetPort) << InPort("glock_in")
336  << OutPort("glockreq_out");
337 
338  if (adfFU_->operationCount() > 1) {
339  fu_ << InPort("operation_in", opcodeWidth_, WireType::Vector);
340  }
341 
342  // operand ports.
343  for (int i = 0; i < adfFU_->portCount(); ++i) {
344  TTAMachine::FUPort* adfPort =
345  static_cast<TTAMachine::FUPort*>(adfFU_->port(i));
346 
347  if (adfPort->isInput()) {
348  fu_ << InPort(
349  "data_" + adfPort->name() + "_in", adfPort->width(),
350  WireType::Vector);
351  fu_ << InPort("load_" + adfPort->name() + "_in");
352  } else {
353  fu_ << OutPort(
354  "data_" + adfPort->name() + "_out", adfPort->width(),
355  WireType::Vector);
356  }
357  }
358 
359  if (addressWidth_ > 0) {
360  fu_ << IntegerConstant("addrw_c", addressWidth_);
361  }
362 }

References ProGeTools::findInOptionList(), TTAMachine::Port::isInput(), TTAMachine::Port::name(), HDLGenerator::Vector, and TTAMachine::BaseFUPort::width().

Referenced by implement().

Here is the call graph for this function:

◆ createOperationResources()

void FUGen::createOperationResources ( )
private

Definition at line 634 of file FUGen.cc.

634  {
635  std::map<std::string, int> instantiatedResources;
636  for (auto&& rs : baseOperations_) {
637  for (auto&& r : rs.second.resources) {
638  if (!instantiatedResources.count(r.name)) {
639  instantiatedResources[r.name] = 0;
640  }
641  std::string file = findAbsolutePath(r.ipxact);
642  std::string rName = StringTools::stringToLower(r.name);
643  int rCount = resourceCount_[rName];
644 
645  for (int i = instantiatedResources[r.name]; i < rCount; ++i) {
646  auto module = ipxact::parseComponent(file);
647  Module resource(module, i + 1);
648  resource.set_prefix(rName);
649  fu_ << resource;
650  for (auto&& p : module.ports) {
651  std::string wName = StringTools::stringToLower(
652  rName + "_" + std::to_string(i + 1) + "_" + p.name);
653  if (p.vector) {
654  fu_ << Wire(wName, p.width);
655  } else {
656  fu_ << Wire(wName);
657  }
658 
659  if (p.direction == "in") {
660  resourceInputs_.emplace_back(wName);
661  } else {
662  resourceOutputs_.emplace_back(wName);
663  }
664  }
665  }
666  instantiatedResources[r.name] = rCount;
667  }
668  }
669 }

References ipxact::parseComponent(), HDLGenerator::Module::set_prefix(), and StringTools::stringToLower().

Referenced by implement().

Here is the call graph for this function:

◆ createOutputPipeline()

void FUGen::createOutputPipeline ( )
private

Definition at line 1385 of file FUGen.cc.

1385  {
1386  CodeBlock outputPipeline;
1387  CodeBlock lastStage;
1388 
1389  for (int i = 0; i < adfFU_->portCount(); ++i) {
1390  auto port = adfFU_->port(i);
1391  int length = pipelineLength_[port->name()];
1392  int width = port->width();
1393  if (portDirection_[port->name()] != ProGe::Direction::OUT) {
1394  continue;
1395  }
1396 
1397  auto inputs = portInputs_.equal_range(port->name());
1398  for (int cycle = length; cycle >= 0; --cycle) {
1399  bool cycleActive = false;
1400 
1401  std::string nextReg = pipelineName(port->name(), cycle);
1402  std::string prevReg = pipelineName(port->name(), cycle + 1);
1403  std::string valid = pipelineValid(port->name(), cycle);
1404 
1405  if (cycle == 0) {
1406  fu_ << Wire(nextReg, width, WireType::Vector);
1407  } else {
1408  outputPipeline.append(Assign(valid, BinaryLiteral("1")));
1409  addRegisterIfMissing(nextReg, width, WireType::Vector);
1410  addRegisterIfMissing(valid, 1);
1411  }
1412 
1413  // TODO: build a mux if all operations come from the same cycle
1414  If validOperations(BinaryLiteral("1"), DefaultAssign("dummy"));
1415  for (auto it = inputs.first; it != inputs.second; ++it) {
1416  auto connection = it->second;
1417  if (connection.pipelineStage != cycle) {
1418  continue;
1419  }
1420 
1421  Equals triggered(
1422  LHSSignal(triggerSignal(connection.sourceCycle)),
1423  BinaryLiteral("1"));
1424  LogicalAnd active(
1425  Equals(
1426  LHSSignal(opcodeSignal(connection.sourceCycle)),
1427  LHSSignal(opcodeConstant(connection.operation))),
1428  triggered);
1429 
1430  Ext source(
1431  operandSignal(connection.operation, connection.operandID),
1432  width, connection.operandWidth);
1433 
1434  if (cycleActive) {
1435  if (operations_.size() == 1) {
1436  validOperations.elseIfClause(
1437  triggered, Assign(nextReg, source));
1438  } else {
1439  validOperations.elseIfClause(
1440  active, Assign(nextReg, source));
1441  }
1442  } else {
1443  if (operations_.size() == 1) {
1444  validOperations =
1445  If(triggered, Assign(nextReg, source));
1446  } else {
1447  validOperations = If(active, Assign(nextReg, source));
1448  }
1449  }
1450  cycleActive = true;
1451  }
1452 
1453  bool skip_last_assign = false;
1454  // No need for this on first cycle
1455  if (cycle != length) {
1456  std::string prevValid =
1457  pipelineValid(port->name(), cycle + 1);
1458 
1459  Equals isValid(LHSSignal(prevValid), BinaryLiteral("1"));
1460  if (cycleActive) {
1461  validOperations.elseIfClause(
1462  isValid, Assign(nextReg, LHSSignal(prevReg)));
1463  } else {
1464  if (cycle == 0) {
1465  skip_last_assign = true;
1466  lastStage.append(Assign(nextReg, LHSSignal(prevReg)));
1467  } else {
1468  validOperations =
1469  If(isValid, Assign(nextReg, LHSSignal(prevReg)));
1470  }
1471  }
1472  cycleActive = true;
1473  }
1474 
1475  if (cycle == 0) {
1476  std::string outReg = nextReg + "_r";
1477  addRegisterIfMissing(outReg, width, WireType::Vector);
1478  outputPipeline.append(Assign(outReg, LHSSignal(nextReg)));
1479 
1480  Assign finalStep(nextReg, LHSSignal(outReg));
1481  if (!skip_last_assign) {
1482  if (cycleActive) {
1483  validOperations.elseClause(finalStep);
1484  lastStage.append(validOperations);
1485  } else {
1486  lastStage.append(finalStep);
1487  }
1488  }
1489  } else {
1490  validOperations.elseClause(Assign(valid, BinaryLiteral("0")));
1491  outputPipeline.append(validOperations);
1492  }
1493  }
1494  lastStage.append(Assign(
1495  "data_" + port->name() + "_out",
1496  LHSSignal(pipelineName(port->name(), 0))));
1497  }
1498 
1499  Synchronous sync("output_pipeline_sp");
1500  sync << If(
1501  Equals(LHSSignal("glock_in"), BinaryLiteral("0")), outputPipeline);
1502  behaviour_ << sync;
1503 
1504  Asynchronous async("output_pipeline_cp");
1505  async << lastStage;
1506  behaviour_ << async;
1507 }

References HDLGenerator::CodeBlock::append(), HDLGenerator::If::elseClause(), HDLGenerator::If::elseIfClause(), HDB::OUT, HDLGenerator::Vector, and HDLGenerator::Generatable::width().

Referenced by implement().

Here is the call graph for this function:

◆ createPortPipeline()

void FUGen::createPortPipeline ( )
private

Definition at line 1317 of file FUGen.cc.

1317  {
1318  CodeBlock pipelineAssignments;
1319  CodeBlock firstStage;
1320 
1321  // Pipeline for opcode and trigger
1322  // TODO: This might generate some unnecessary registers for some FUs,
1323  // but these should be removed by the synthesis tool
1324  for (int i = 0; i < maxLatency_; ++i) {
1325  if (operations_.size() > 1) {
1326  std::string prevOpcode = opcodeSignal(i);
1327  std::string nextOpcode = opcodeSignal(i + 1);
1328  addRegisterIfMissing(nextOpcode, opcodeWidth_, WireType::Vector);
1329  if (i == 0) {
1330  firstStage.append(Assign(nextOpcode, LHSSignal(prevOpcode)));
1331  } else {
1332  pipelineAssignments.append(
1333  Assign(nextOpcode, LHSSignal(prevOpcode)));
1334  }
1335  }
1336  std::string prevTrigger = triggerSignal(i);
1337  std::string nextTrigger = triggerSignal(i + 1);
1338  addRegisterIfMissing(nextTrigger, 1);
1339  pipelineAssignments.append(
1340  Assign(nextTrigger, LHSSignal(prevTrigger)));
1341  }
1342 
1343  // Pipelines for operand data
1344  for (int i = 0; i < adfFU_->portCount(); ++i) {
1345  auto port = adfFU_->port(i);
1346  int length = pipelineLength_[port->name()];
1347  int width = port->width();
1348  if (portDirection_[port->name()] != ProGe::Direction::IN) {
1349  continue;
1350  }
1351 
1352  for (int i = 0; i < length; ++i) {
1353  std::string prevReg = pipelineName(port->name(), i);
1354  std::string nextReg = pipelineName(port->name(), i + 1);
1355  addRegisterIfMissing(nextReg, width, WireType::Vector);
1356  if (i == 0) {
1357  firstStage.append(Assign(nextReg, LHSSignal(prevReg)));
1358  } else {
1359  pipelineAssignments.append(
1360  Assign(nextReg, LHSSignal(prevReg)));
1361  }
1362  }
1363  }
1364 
1365  If operationTrigger(
1366  Equals(LHSSignal(triggerSignal(0)), BinaryLiteral("1")), firstStage);
1367  pipelineAssignments.append(operationTrigger);
1368  If glock_low(
1369  Equals(LHSSignal("glock_in"), BinaryLiteral("0")),
1370  pipelineAssignments);
1371  Synchronous pipeline("input_pipeline_sp");
1372  pipeline << glock_low;
1373  behaviour_ << pipeline;
1374 }

References HDLGenerator::CodeBlock::append(), HDB::IN, and HDLGenerator::Vector.

Referenced by implement().

Here is the call graph for this function:

◆ createShadowRegisters()

void FUGen::createShadowRegisters ( )
private

Definition at line 1243 of file FUGen.cc.

1243  {
1244  std::vector<std::string> inOperands;
1245  std::unordered_set<std::string> registeredInOperands;
1246  std::unordered_map<std::string, std::string> currentName;
1247  std::unordered_map<std::string, int> portWidth;
1248 
1249  for (int i = 0; i < adfFU_->portCount(); ++i) {
1250  TTAMachine::FUPort* adfPort =
1251  static_cast<TTAMachine::FUPort*>(adfFU_->port(i));
1252  portWidth[adfPort->name()] = adfPort->width();
1253 
1254  if (adfPort->isInput()) {
1255  currentName[adfPort->name()] = "data_" + adfPort->name() + "_in";
1256 
1257  if (adfPort->isTriggering()) {
1258  triggerPort_ = adfPort->name();
1259  }
1260 
1261  inOperands.emplace_back(adfPort->name());
1262  if (!adfPort->noRegister()) {
1263  registeredInOperands.emplace(adfPort->name());
1264  }
1265 
1266  std::string name = pipelineName(adfPort->name(), 0);
1267  fu_ << Wire(name, adfPort->width());
1268  } else {
1269  currentName[adfPort->name()] = "data_" + adfPort->name() + "_out";
1270  }
1271  }
1272 
1274  for (auto&& p : inOperands) {
1275  std::string newName = "data_" + p + "_gated";
1276  auto gate = LHSSignal(currentName[p]) &
1277  Sext("load_" + p + "_in", portWidth[p], 1);
1278  behaviour_ << Assign(newName, gate);
1279  currentName[p] = newName;
1280  fu_ << Wire(newName, portWidth[p]);
1281  }
1282  }
1283 
1284  for (auto&& p : inOperands) {
1285  std::string dataPort = currentName[p];
1286  std::string output = pipelineName(p, 0);
1287  if (p != triggerPort_ &&
1288  registeredInOperands.find(p) != registeredInOperands.end()) {
1289  std::string loadPort = "load_" + p + "_in";
1290  std::string shadowReg = "shadow_" + p + "_r";
1291 
1292  fu_ << Register(shadowReg, portWidth[p], ResetOption::Optional);
1293 
1294  auto noLock = Equals(LHSSignal("glock_in"), BinaryLiteral("0"));
1295  auto portLoad = Equals(LHSSignal(loadPort), BinaryLiteral("1"));
1296  If iffi(
1297  noLock && portLoad, Assign(shadowReg, LHSSignal(dataPort)));
1298 
1299  behaviour_ << (Synchronous("shadow_" + p + "_sp") << iffi);
1300 
1301  auto triggerLoad = Equals(
1302  LHSSignal("load_" + triggerPort_ + "_in"),
1303  BinaryLiteral("1"));
1304  If cpIf(
1305  triggerLoad && portLoad,
1306  Assign(output, LHSSignal("data_" + p + "_in")));
1307  cpIf.elseClause(Assign(output, LHSSignal(shadowReg)));
1308 
1309  behaviour_ << (Asynchronous("shadow_" + p + "_cp") << cpIf);
1310  } else {
1311  behaviour_ << Assign(output, LHSSignal(dataPort));
1312  }
1313  }
1314 }

References HDLGenerator::If::elseClause(), ProGeTools::findInOptionList(), TTAMachine::Port::isInput(), TTAMachine::FUPort::isTriggering(), TTAMachine::Port::name(), TTAMachine::FUPort::noRegister(), HDLGenerator::Optional, and TTAMachine::BaseFUPort::width().

Referenced by implement().

Here is the call graph for this function:

◆ DAGNodeOperandWidth()

int FUGen::DAGNodeOperandWidth ( OperationDAGNode node,
int  id,
OperationDAG dag 
)
private

Definition at line 201 of file FUGen.cc.

202  {
203  auto operation = dynamic_cast<OperationNode*>(&node);
204  auto terminal = dynamic_cast<TerminalNode*>(&node);
205  auto constant = dynamic_cast<ConstantNode*>(&node);
206 
207  OperationPool opPool;
208  std::string opName;
209  if (operation) {
210  opName = operation->referencedOperation().name();
211  } else if (terminal) {
212  opName = dag->operation().name();
213  } else if (constant) {
214  return MathTools::requiredBitsSigned(constant->value());
215  } else {
216  assert(false && "Shouldn't be possible to get here.");
217  }
218 
219  opName = StringTools::stringToLower(opName);
220  Operation& op = opPool.operation(opName.c_str());
221  return op.operand(id).width();
222 }

References assert, OperationPimpl::name(), Operation::operand(), OperationPool::operation(), OperationDAG::operation(), MathTools::requiredBitsSigned(), StringTools::stringToLower(), and Operand::width().

Here is the call graph for this function:

◆ finalizeHDL()

void FUGen::finalizeHDL ( )
private

Definition at line 889 of file FUGen.cc.

889  {
890  // Create lock request wires
891  if (useGlockRequest_) {
892  fu_ << Wire("glockreq");
893  behaviour_ << Assign("glockreq_out", LHSSignal("glockreq"));
894  } else {
895  behaviour_ << Assign("glockreq_out", BinaryLiteral("0"));
896  }
897 
898  // Finalize and set global options.
899  fu_ << behaviour_;
900  for (auto&& option : globalOptions_) {
901  fu_ << Option(option);
902  }
903 }

Referenced by implement().

◆ findAbsolutePath()

std::string FUGen::findAbsolutePath ( std::string  file)
private

Searches for file in TCE folders and makes the path absolute.

Definition at line 101 of file FUGen.cc.

101  {
102  if (file.length() > 4 && file.substr(0, 4) == "tce:") {
103  file = file.substr(4);
104  }
105  std::vector<std::string> paths = Environment::hdbPaths();
106  for (auto file : options_.hdbList) {
107  paths.emplace_back(FileSystem::directoryOfPath(file));
108  }
109  return FileSystem::findFileInSearchPaths(paths, file);
110 }

References FileSystem::directoryOfPath(), FileSystem::findFileInSearchPaths(), and Environment::hdbPaths().

Here is the call graph for this function:

◆ hasToken()

bool FUGen::hasToken ( std::string  line,
std::string  token 
)
private

Definition at line 61 of file FUGen.cc.

61  {
62  auto regex = std::regex("\\b" + token + "\\b");
63  return std::regex_search(line, regex);
64 }

◆ implement()

void FUGen::implement ( const ProGeOptions options,
std::vector< std::string >  globalOptions,
const std::vector< IDF::FUGenerated > &  generatetFUs,
const TTAMachine::Machine machine,
ProGe::NetlistBlock core 
)
static

Generate all FUGen FUs.

Definition at line 1515 of file FUGen.cc.

1518  {
1519  // Generate FU innards.
1520  for (auto fug : generatetFUs) {
1521  FUGen fugen(options, globalOptions, fug, machine, core);
1522 
1523  // Some repetition to have named FUs override an "all"
1524  // e.g. --fu-front-register=all --fu-back-register=lsu
1526  fug.name(), options.fuFrontRegistered, false)) {
1527  fugen.frontRegistered_ = true;
1528  } else if (ProGeTools::findInOptionList(
1529  fug.name(), options.fuMiddleRegistered, false)) {
1530  fugen.middleRegistered_ = true;
1531  } else if (ProGeTools::findInOptionList(
1532  fug.name(), options.fuBackRegistered, false)) {
1533  fugen.backRegistered_ = true;
1534  } else if (ProGeTools::findInOptionList(
1535  fug.name(), options.fuFrontRegistered)) {
1536  fugen.frontRegistered_ = true;
1537  } else if (ProGeTools::findInOptionList(
1538  fug.name(), options.fuMiddleRegistered)) {
1539  fugen.middleRegistered_ = true;
1540  } else { // Default to back-register
1541  fugen.backRegistered_ = true;
1542  }
1543 
1544  fugen.createFUHeaderComment();
1545  fugen.checkForValidity();
1546 
1547  fugen.parseOperations();
1548  fugen.scheduleOperations();
1549  fugen.createMandatoryPorts();
1550  fugen.createExternalInterfaces(!options.integratorName.empty());
1551  fugen.createOperationResources();
1552 
1553  fugen.createShadowRegisters();
1554  fugen.createPortPipeline();
1555  fugen.buildOperations();
1556  fugen.createOutputPipeline();
1557 
1558  fugen.finalizeHDL();
1559  fugen.createImplementationFiles();
1560  }
1561 }

References backRegistered_, buildOperations(), checkForValidity(), createExternalInterfaces(), createFUHeaderComment(), createImplementationFiles(), createMandatoryPorts(), createOperationResources(), createOutputPipeline(), createPortPipeline(), createShadowRegisters(), finalizeHDL(), ProGeTools::findInOptionList(), frontRegistered_, machine, middleRegistered_, options, parseOperations(), and scheduleOperations().

Referenced by ProGe::ProcessorGenerator::generateProcessor().

Here is the call graph for this function:

◆ inferLSUSignal()

ProGe::Signal FUGen::inferLSUSignal ( const std::string &  portName) const
private

(Ugly) heuristics for mapping FUGen generated LSU signal types

Parameters
portNameName of the port
Returns
SignalType

Definition at line 542 of file FUGen.cc.

542  {
543  size_t pos = 0;
544  using SigT = ProGe::SignalType;
545  if (((pos = portName.find("avalid")) != std::string::npos)) {
546  return SigT::AVALID;
547  } else if (((pos = portName.find("aready")) != std::string::npos)) {
548  return SigT::AREADY;
549  } else if (((pos = portName.find("aaddr")) != std::string::npos)) {
550  return SigT::AADDR;
551  } else if (((pos = portName.find("awren")) != std::string::npos)) {
552  return SigT::AWREN;
553  } else if (((pos = portName.find("astrb")) != std::string::npos)) {
554  return SigT::ASTRB;
555  } else if (((pos = portName.find("rvalid")) != std::string::npos)) {
556  return SigT::RVALID;
557  } else if (((pos = portName.find("rready")) != std::string::npos)) {
558  return SigT::RREADY;
559  } else if (((pos = portName.find("rdata")) != std::string::npos)) {
560  return SigT::RDATA;
561  } else if (((pos = portName.find("adata")) != std::string::npos)) {
562  return SigT::ADATA;
563  }
564  return SigT::UNDEFINED;
565 }

◆ isLSUDataPort()

bool FUGen::isLSUDataPort ( const std::string &  portName)
private

(Ugly) heuristics for identifying an LSU data memory port.

The identification is made by partial match of the port's name.

Parameters
portNameThe port name given in HDB.
Returns
True if the port is LSU data memory port.

Definition at line 516 of file FUGen.cc.

516  {
517  if (!adfFU_->hasAddressSpace()) {
518  return false;
519  }
520 
521  static const std::set<std::string> magicWords{
522  "avalid", "aready", "aaddr", "awren", "astrb",
523  "rvalid", "rready", "rdata", "adata"};
524 
525  for (auto magicWord : magicWords) {
526  if (portName.find(magicWord) != std::string::npos) {
527  //Assume the FU is an LSU
528  isLSU_ = true;
529  return true;
530  }
531  }
532 
533  return false;
534 }

◆ opcodeConstant()

std::string FUGen::opcodeConstant ( std::string  operation)
private

Definition at line 131 of file FUGen.cc.

131  {
132  return "op_" + operation + "_c";
133 }

◆ opcodeSignal()

std::string FUGen::opcodeSignal ( int  stage)
private

Definition at line 113 of file FUGen.cc.

113  {
114  if (stage == 0) {
115  return "operation_in";
116  } else {
117  return "operation_" + std::to_string(stage) + "_r";
118  }
119 }

◆ operandPlaceholder()

std::string FUGen::operandPlaceholder ( int  id)
private

Definition at line 141 of file FUGen.cc.

141  {
142  return "op" + std::to_string(id);
143 }

◆ operandSignal()

std::string FUGen::operandSignal ( std::string  operation,
int  id 
)
private

Definition at line 136 of file FUGen.cc.

136  {
137  return operation + "_op" + std::to_string(id);
138 }

◆ operator=()

FUGen& FUGen::operator= ( const FUGen )
delete

◆ parseOperations()

void FUGen::parseOperations ( )
private

Definition at line 906 of file FUGen.cc.

906  {
907  OperationPool opPool;
908  std::vector<std::string> dagOperations;
909 
910  for (auto&& op : fug_.operations()) {
911  BaseOperation opInfo;
912  opInfo.name = op.operationName;
913  opInfo.latency = op.latency;
914 
915  std::string opHDB = findAbsolutePath(op.hdb);
916  HDB::CachedHDBManager& manager =
919  manager.OperationImplementationByID(op.id);
920 
921  std::string implFile;
923  opInfo.variables = opImpl.vhdlVariables;
924  opInfo.globalsignals = opImpl.vhdlGlobalSignals;
925  opInfo.implementation = readFile(opImpl.implFileVhdl);
926  opInfo.initial = readFile(opImpl.initialImplFileVhdl);
927  opInfo.postOp = readFile(opImpl.postOpImplFileVhdl);
928  } else {
929  if (opImpl.implFileVerilog == "") {
930  const std::string msg =
931  "Cannot generate operation \"" + opInfo.name +
932  "\" due to missing verilog operation implementation";
933  throw std::runtime_error(msg);
934  }
935  opInfo.variables = opImpl.verilogVariables;
936  opInfo.globalsignals = opImpl.verilogGlobalSignals;
937  opInfo.implementation = readFile(opImpl.implFileVerilog);
938  opInfo.initial = readFile(opImpl.initialImplFileVerilog);
939  opInfo.postOp = readFile(opImpl.postOpImplFileVerilog);
940  }
941  opInfo.resources = opImpl.resources;
942 
943  implLatency_[opInfo.name] = op.latency;
944 
945  baseOperations_.emplace(opInfo.name, opInfo);
946 
947  std::string ifPath = opImpl.absBusDefFile;
948  if (!ifPath.empty()) {
949  extIfaces_.insert(findAbsolutePath(ifPath));
950  }
951  }
952 
953  maxLatency_ = 0;
954  minLatency_ = INT_MAX;
955  for (auto&& op : operations_) {
957  int hwOpOperands = hwOp->operandCount();
958  OperationPool opPool;
959 
960  for (int operand = 0; operand < hwOpOperands; ++operand) {
961  TTAMachine::FUPort* fuPort = hwOp->port(operand + 1);
962 
963  if (fuPort->isOutput()) {
964  std::string portName = fuPort->name();
965  int latency = hwOp->latency(operand + 1);
966 
967  auto search = operationCycles_.find(op);
968  if (search != operationCycles_.end()) {
969  operationCycles_[op] = std::max(search->second, latency);
970  } else {
971  operationCycles_[op] = latency;
972  }
973  maxLatency_ = std::max(maxLatency_, latency);
974  minLatency_ = std::min(minLatency_, latency);
975  }
976  }
977 
978  if (baseOperations_.find(op) == baseOperations_.end()) {
979  dagOperations.emplace_back(op);
980  }
981  }
982 
983  for (auto&& op : dagOperations) {
984  int dagCount;
985  {
986  OperationPool opPool;
987  Operation& osalOp = opPool.operation(op.c_str());
988  dagCount = osalOp.dagCount();
989  }
990 
991  if (dagCount < 1) {
992  throw std::runtime_error(op + " has no dags to implement.");
993  }
994 
995  bool implementable = false;
996  for (int i = 0; i < dagCount; ++i) {
997  OperationDAG* dagPtr;
998  {
999  OperationPool opPool;
1000  OperationIndex& index = opPool.index();
1001  Operation* osalOp = index.effectiveOperation(op);
1002  dagPtr = &osalOp->dag(i);
1003  }
1004 
1006  *dagPtr, fug_.operations(), nullptr)) {
1007  continue;
1008  } else {
1009  implementable = true;
1010  implementapleDAGs_[op] = dagPtr;
1011  implLatency_[op] =
1013  break;
1014  }
1015  }
1016 
1017  if (!implementable) {
1018  throw std::runtime_error(op + " has no valid dags to implement.");
1019  }
1020  }
1021 }

References HDB::OperationImplementation::absBusDefFile, ProGeTools::canGenerateFromDAG(), Operation::dag(), Operation::dagCount(), ProGeTools::dagLatency(), OperationIndex::effectiveOperation(), FUGen::BaseOperation::globalsignals, FUGen::BaseOperation::implementation, HDB::OperationImplementation::implFileVerilog, HDB::OperationImplementation::implFileVhdl, OperationPool::index(), FUGen::BaseOperation::initial, HDB::OperationImplementation::initialImplFileVerilog, HDB::OperationImplementation::initialImplFileVhdl, HDB::CachedHDBManager::instance(), TTAMachine::Port::isOutput(), TTAMachine::HWOperation::latency(), FUGen::BaseOperation::latency, TTAMachine::Port::name(), FUGen::BaseOperation::name, TTAMachine::HWOperation::operandCount(), OperationPool::operation(), HDB::HDBManager::OperationImplementationByID(), TTAMachine::HWOperation::port(), FUGen::BaseOperation::postOp, HDB::OperationImplementation::postOpImplFileVerilog, HDB::OperationImplementation::postOpImplFileVhdl, HDB::OperationImplementation::resources, FUGen::BaseOperation::resources, FUGen::BaseOperation::variables, HDB::OperationImplementation::verilogGlobalSignals, HDB::OperationImplementation::verilogVariables, ProGe::VHDL, HDB::OperationImplementation::vhdlGlobalSignals, and HDB::OperationImplementation::vhdlVariables.

Referenced by implement().

Here is the call graph for this function:

◆ pipelineName()

std::string FUGen::pipelineName ( std::string  port,
int  cycle 
)
private

Definition at line 146 of file FUGen.cc.

146  {
147  if (cycle == 0) {
148  return "data_" + port;
149  } else {
150  return "data_" + port + "_" + std::to_string(cycle) + "_r";
151  }
152 }

◆ pipelineValid()

std::string FUGen::pipelineValid ( std::string  port,
int  cycle 
)
private

Definition at line 155 of file FUGen.cc.

155  {
156  return "data_" + port + "_" + std::to_string(cycle) + "_valid_r";
157 }

◆ prepareSnippet()

void FUGen::prepareSnippet ( std::string  name,
std::deque< std::string >  statements,
HDLGenerator::CodeBlock sink,
std::set< std::string > &  addedStatements 
)
private

Definition at line 854 of file FUGen.cc.

856  {
857  std::deque<std::string> snippet;
858  std::set<std::string> lines;
859  for (std::string line : statements) {
860  std::string replaced = StringTools::stringToLower(line);
861  for (Replace rep : replacesPerOp_[name]) {
862  replaced = replaceToken(replaced, rep);
863  }
864 
865  // Cosmetic improvement: do not repeat statements in the same context
866  if (addedStatements.count(replaced)) {
867  continue;
868  }
869  lines.insert(replaced);
870 
871  snippet.push_back(replaced);
872 
873  if (hasToken(line, "glockreq")) {
874  useGlockRequest_ = true;
875  }
876  if (hasToken(line, "glock")) {
877  useGlock_ = true;
878  }
879  }
880 
881  for (std::string line : lines) {
882  addedStatements.insert(line);
883  }
884 
885  sink.append(HDLOperation(name, snippet, selectedLanguage()));
886 }

References HDLGenerator::CodeBlock::append(), and StringTools::stringToLower().

Here is the call graph for this function:

◆ readFile()

std::deque< std::string > FUGen::readFile ( std::string  filename)
private

Definition at line 82 of file FUGen.cc.

82  {
83  std::deque<std::string> file;
84  // replace temps in operation implmentations and keep track of
85  // read temps.
86  if (filename == "") {
87  return file;
88  }
89 
90  std::ifstream implStream(findAbsolutePath(filename));
91  for (std::string line; std::getline(implStream, line);) {
92  file.emplace_back(StringTools::stringToLower(line));
93  }
94  return file;
95 }

References StringTools::stringToLower().

Here is the call graph for this function:

◆ readImplementation()

void FUGen::readImplementation ( std::string  filename,
std::string  opName,
std::deque< std::string > &  sink 
)
private

Definition at line 492 of file FUGen.cc.

493  {
494  // replace temps in operation implmentations and keep track of
495  // read temps.
496  std::ifstream implStream(findAbsolutePath(filename));
497  for (std::string line; std::getline(implStream, line);) {
498  line = StringTools::stringToLower(line);
499  for (auto&& p : replacesPerOp_[opName]) {
500  line = replaceToken(line, p);
501  }
502 
503  sink.emplace_back(line);
504  }
505 }

References StringTools::stringToLower().

Here is the call graph for this function:

◆ replaceToken()

std::string FUGen::replaceToken ( std::string  line,
Replace  replace 
)
private

Definition at line 67 of file FUGen.cc.

67  {
68  auto regex = std::regex("\\b" + replace.first + "\\b");
69  return std::regex_replace(line, regex, replace.second);
70 }

◆ scheduleOperations()

void FUGen::scheduleOperations ( )
private

Definition at line 1064 of file FUGen.cc.

1064  {
1065  std::set<std::string> instantiatedWires;
1066  for (auto&& op : operations_) {
1067  OperationSchedule schedule;
1068  schedule.baseOp = op;
1069 
1070  if (frontRegistered_) {
1071  schedule.initialCycle = operationCycles_[op] - implLatency_[op];
1072  schedule.finalCycle = operationCycles_[op];
1073  } else if (middleRegistered_) {
1074  schedule.initialCycle =
1075  operationCycles_[op] - implLatency_[op] - 1;
1076  schedule.finalCycle = schedule.initialCycle + implLatency_[op];
1077  } else { // Back-registered
1078  schedule.initialCycle = 0;
1079  schedule.finalCycle = implLatency_[op];
1080  }
1081  assert(
1082  schedule.initialCycle >= 0 &&
1083  "Failure likely due to mis-selected operation implementation");
1084 
1085  OperationPool opPool;
1086  Operation& osalOp = opPool.operation(op.c_str());
1088  for (int i = 1; i <= hwOp->operandCount(); ++i) {
1089  Operand& osalOperand = osalOp.operand(i);
1090  TTAMachine::FUPort* fuPort = hwOp->port(i);
1091  std::string port = fuPort->name();
1092  int width = osalOperand.width();
1093  int accessCycle;
1094  ProGe::Direction dir;
1095 
1096  OperandConnection oper = {
1097  i, fuPort->width(), width,
1098  pipelineName(port, schedule.initialCycle), false};
1099  if (osalOperand.isInput()) {
1100  accessCycle = schedule.initialCycle;
1101  schedule.operands.push_back(oper);
1102  dir = ProGe::Direction::IN;
1103  } else {
1104  accessCycle = operationCycles_[op] - schedule.finalCycle;
1105  schedule.results.insert(i);
1106  dir = ProGe::Direction::OUT;
1107  OutputConnection out = {
1108  width, i, schedule.finalCycle, accessCycle, op};
1109  portInputs_.emplace(port, out);
1110  }
1111 
1112  assert(
1113  accessCycle >= 0 &&
1114  "Failure likely due to mis-selected operation "
1115  "implementation");
1116 
1117  std::string newWire = operandSignal(op, i);
1118  if (!instantiatedWires.count(newWire)) {
1119  fu_ << Wire(newWire, width);
1120  instantiatedWires.insert(newWire);
1121  }
1122 
1123  if (pipelineLength_.find(port) == pipelineLength_.end()) {
1124  pipelineLength_[port] = accessCycle;
1125  } else {
1126  pipelineLength_[port] =
1127  std::max(accessCycle, pipelineLength_[port]);
1128  }
1129 
1130  if (portDirection_.find(port) == portDirection_.end()) {
1131  portDirection_[port] = dir;
1132  } else {
1133  if (portDirection_[port] != dir) {
1134  throw std::runtime_error(
1135  "Unsupported bidirectional port " + port +
1136  ", aborting.");
1137  }
1138  }
1139  }
1140 
1141  if (baseOperations_.find(op) != baseOperations_.end()) {
1142  // No need to arbitrate between suboperations here,
1143  // just use the first resource
1144  for (auto&& res : baseOperations_[op].resources) {
1145  std::string resName = StringTools::stringToLower(res.name);
1146  schedule.resourceOffsets[resName] = 0;
1147  resourceCount_[res.name] =
1148  std::max(resourceCount_[res.name], res.count);
1149  }
1150  } else {
1151  assert(implementapleDAGs_.find(op) != implementapleDAGs_.end());
1152  auto dag = implementapleDAGs_[op];
1153  std::unordered_map<std::string, int> dagResourceCount;
1154 
1155  for (int n = 0; n < dag->nodeCount(); ++n) {
1156  OperationSchedule subopSchedule;
1157  OperationDAGNode& node = dag->node(n);
1158 
1159  OperationNode* operationNode =
1160  dynamic_cast<OperationNode*>(&node);
1161 
1162  if (!operationNode) {
1163  continue;
1164  }
1165 
1166  std::string subOp =
1167  operationNode->referencedOperation().name();
1168  subOp = StringTools::stringToLower(subOp);
1169 
1170  std::string name = subOpName(operationNode);
1171  schedule.subOperations.push_back(name);
1172  subopSchedule.baseOp = subOp;
1173  // Start counting subopcycles from the upper op's initCycle.
1174  subopSchedule.initialCycle =
1175  schedule.initialCycle +
1177  *dag, node, implLatency_, false);
1178  subopSchedule.finalCycle =
1179  subopSchedule.initialCycle + implLatency_[subOp];
1180 
1181  for (auto&& input : dag->inEdges(node)) {
1182  int dstID = input->dstOperand();
1183  int width = DAGNodeOperandWidth(
1184  dag->headNode(*input), dstID, dag);
1185 
1186  std::string newWire = operandSignal(name, dstID);
1187  if (!instantiatedWires.count(newWire)) {
1188  fu_ << Wire(newWire, width);
1189  instantiatedWires.insert(newWire);
1190  }
1191 
1192  subopSchedule.operands.push_back(
1193  subOpConnection(dag, input, false));
1194  }
1195 
1196  for (auto&& output : dag->outEdges(node)) {
1197  int srcID = output->srcOperand();
1198  int width = DAGNodeOperandWidth(
1199  dag->tailNode(*output), srcID, dag);
1200 
1201  std::string newWire = operandSignal(name, srcID);
1202  if (!instantiatedWires.count(newWire)) {
1203  fu_ << Wire(newWire, width);
1204  instantiatedWires.insert(newWire);
1205  }
1206 
1207  subopSchedule.results.insert(srcID);
1208 
1209  auto terminal =
1210  dynamic_cast<TerminalNode*>(&dag->headNode(*output));
1211 
1212  if (terminal) {
1213  schedule.operands.push_back(
1214  subOpConnection(dag, output, true));
1215  }
1216  }
1217 
1218  // TODO: make sure same resource doesn't get used by different
1219  // operations on _different_ pipeline cycles
1220  for (auto&& r : baseOperations_[subOp].resources) {
1221  std::string resName = StringTools::stringToLower(r.name);
1222  if (!dagResourceCount.count(resName)) {
1223  dagResourceCount[resName] = 0;
1224  }
1225  subopSchedule.resourceOffsets[resName] =
1226  dagResourceCount[resName];
1227  dagResourceCount[resName] += r.count;
1228  }
1229 
1230  scheduledOperations_[name] = subopSchedule;
1231  }
1232 
1233  for (auto&& d : dagResourceCount) {
1234  resourceCount_[d.first] =
1235  std::max(resourceCount_[d.first], d.second);
1236  }
1237  }
1238  scheduledOperations_[op] = schedule;
1239  }
1240 }

References assert, FUGen::OperationSchedule::baseOp, FUGen::OperationSchedule::finalCycle, HDB::IN, FUGen::OperationSchedule::initialCycle, Operand::isInput(), ProGeTools::maxLatencyToNode(), TTAMachine::Port::name(), Operation::name(), Operation::operand(), TTAMachine::HWOperation::operandCount(), FUGen::OperationSchedule::operands, OperationPool::operation(), HDB::OUT, TTAMachine::HWOperation::port(), OperationNode::referencedOperation(), FUGen::OperationSchedule::resourceOffsets, FUGen::OperationSchedule::results, StringTools::stringToLower(), FUGen::OperationSchedule::subOperations, TTAMachine::BaseFUPort::width(), and Operand::width().

Referenced by implement().

Here is the call graph for this function:

◆ selectedLanguage()

Language FUGen::selectedLanguage ( )
private

Definition at line 73 of file FUGen.cc.

73  {
75  return Language::VHDL;
76  } else {
77  return Language::Verilog;
78  }
79 }

References HDLGenerator::Verilog, HDLGenerator::VHDL, and ProGe::VHDL.

◆ subOpConnection()

FUGen::OperandConnection FUGen::subOpConnection ( OperationDAG dag,
OperationDAGEdge edge,
bool  isOutput 
)
private

Definition at line 1024 of file FUGen.cc.

1025  {
1026  OperationDAGNode& srcNode = dag->tailNode(*edge);
1027  int srcID = edge->srcOperand();
1028  int srcWidth = DAGNodeOperandWidth(srcNode, srcID, dag);
1029 
1030  OperationDAGNode& dstNode = dag->headNode(*edge);
1031  int dstID = edge->dstOperand();
1032  int dstWidth = DAGNodeOperandWidth(dstNode, dstID, dag);
1033  auto dstTerminal = dynamic_cast<TerminalNode*>(&dstNode);
1034  if (dstTerminal) {
1035  dstID = dstTerminal->operandIndex();
1036  }
1037 
1038  auto operation = dynamic_cast<OperationNode*>(&srcNode);
1039  auto terminal = dynamic_cast<TerminalNode*>(&srcNode);
1040  auto constant = dynamic_cast<ConstantNode*>(&srcNode);
1041 
1042  std::string signalName;
1043  if (operation) {
1044  std::string srcOp = subOpName(operation);
1045  srcOp = StringTools::stringToLower(srcOp);
1046  signalName = operandSignal(srcOp, srcID);
1047  } else if (terminal) {
1048  std::string srcOp = dag->operation().name();
1049  srcOp = StringTools::stringToLower(srcOp);
1050  srcID = terminal->operandIndex();
1051  signalName = operandSignal(srcOp, srcID);
1052  } else if (constant) {
1053  signalName = constantName(constant, dag);
1054  } else {
1055  assert(false && "It shouldn't be possible to get here.");
1056  }
1057 
1058  FUGen::OperandConnection conn = {
1059  dstID, srcWidth, dstWidth, signalName, isOutput};
1060  return conn;
1061 }

References assert, OperationDAGEdge::dstOperand(), BoostGraph< GraphNode, GraphEdge >::headNode(), OperationPimpl::name(), TerminalNode::operandIndex(), OperationDAG::operation(), OperationDAGEdge::srcOperand(), StringTools::stringToLower(), and BoostGraph< GraphNode, GraphEdge >::tailNode().

Here is the call graph for this function:

◆ subOpName()

std::string FUGen::subOpName ( OperationNode node)
private

Definition at line 160 of file FUGen.cc.

160  {
161  int id;
162  std::string op = node->referencedOperation().name();
164  if (nodeImplementations_.count(node->nodeID())) {
165  id = nodeImplementations_[node->nodeID()];
166  } else {
167  if (!subOpCount_.count(op)) {
168  subOpCount_[op] = 0;
169  }
170  id = subOpCount_[op];
171  subOpCount_[op] += 1;
172  nodeImplementations_[node->nodeID()] = id;
173  }
174  return "subop_" + op + "_" + std::to_string(id);
175 }

References Operation::name(), GraphNode::nodeID(), OperationNode::referencedOperation(), and StringTools::stringToLower().

Here is the call graph for this function:

◆ triggerSignal()

std::string FUGen::triggerSignal ( int  stage)
private

Definition at line 122 of file FUGen.cc.

122  {
123  if (stage == 0) {
124  return "load_" + triggerPort_ + "_in";
125  } else {
126  return "optrig_" + std::to_string(stage) + "_r";
127  }
128 }

Member Data Documentation

◆ addressWidth_

int FUGen::addressWidth_ = 0
private

Definition at line 260 of file FUGen.hh.

Referenced by FUGen().

◆ adfFU_

TTAMachine::FunctionUnit* FUGen::adfFU_
private

Definition at line 211 of file FUGen.hh.

Referenced by FUGen().

◆ backRegistered_

bool FUGen::backRegistered_ = false
private

Definition at line 259 of file FUGen.hh.

Referenced by implement().

◆ baseOperations_

std::unordered_map<std::string, BaseOperation> FUGen::baseOperations_
private

Definition at line 220 of file FUGen.hh.

◆ behaviour_

HDLGenerator::Behaviour FUGen::behaviour_
private

Definition at line 256 of file FUGen.hh.

◆ core_

ProGe::NetlistBlock* FUGen::core_
private

Definition at line 208 of file FUGen.hh.

Referenced by FUGen().

◆ dagConstantCount_

std::unordered_map<std::string, int> FUGen::dagConstantCount_
private

Definition at line 227 of file FUGen.hh.

◆ dagConstants_

std::unordered_map<int, DAGConstant> FUGen::dagConstants_
private

Definition at line 239 of file FUGen.hh.

◆ extIfaces_

std::unordered_set<std::string> FUGen::extIfaces_
private

Definition at line 244 of file FUGen.hh.

◆ extInputs_

std::unordered_set<std::string> FUGen::extInputs_
private

Definition at line 246 of file FUGen.hh.

◆ extOutputs_

std::set<std::pair<std::string, std::string> > FUGen::extOutputs_
private

Definition at line 245 of file FUGen.hh.

◆ frontRegistered_

bool FUGen::frontRegistered_ = false
private

Definition at line 257 of file FUGen.hh.

Referenced by implement().

◆ fu_

HDLGenerator::Module FUGen::fu_
private

Definition at line 210 of file FUGen.hh.

◆ fug_

IDF::FUGenerated& FUGen::fug_
private

Definition at line 207 of file FUGen.hh.

◆ globalOptions_

std::vector<std::string> FUGen::globalOptions_
private

Definition at line 205 of file FUGen.hh.

◆ implementapleDAGs_

std::unordered_map<std::string, OperationDAG*> FUGen::implementapleDAGs_
private

Definition at line 225 of file FUGen.hh.

◆ implLatency_

std::unordered_map<std::string, int> FUGen::implLatency_
private

Definition at line 224 of file FUGen.hh.

◆ isLSU_

bool FUGen::isLSU_ = false
private

Definition at line 261 of file FUGen.hh.

◆ maxLatency_

int FUGen::maxLatency_
private

Definition at line 201 of file FUGen.hh.

◆ middleRegistered_

bool FUGen::middleRegistered_ = false
private

Definition at line 258 of file FUGen.hh.

Referenced by implement().

◆ minLatency_

int FUGen::minLatency_
private

Definition at line 202 of file FUGen.hh.

◆ moduleName_

std::string FUGen::moduleName_
private

Definition at line 216 of file FUGen.hh.

Referenced by FUGen().

◆ netlistBlock_

ProGe::NetlistBlock* FUGen::netlistBlock_
private

Definition at line 217 of file FUGen.hh.

Referenced by FUGen().

◆ nodeImplementations_

std::unordered_map<int, int> FUGen::nodeImplementations_
private

Definition at line 238 of file FUGen.hh.

◆ opcodeWidth_

int FUGen::opcodeWidth_
private

Definition at line 214 of file FUGen.hh.

◆ operationCycles_

std::unordered_map<std::string, int> FUGen::operationCycles_
private

Definition at line 223 of file FUGen.hh.

◆ operations_

std::vector<std::string> FUGen::operations_
private

Definition at line 213 of file FUGen.hh.

◆ options_

const ProGeOptions& FUGen::options_
private

Definition at line 204 of file FUGen.hh.

◆ pipelineLength_

std::unordered_map<std::string, int> FUGen::pipelineLength_
private

Definition at line 233 of file FUGen.hh.

◆ portDirection_

std::unordered_map<std::string, ProGe::Direction> FUGen::portDirection_
private

Definition at line 234 of file FUGen.hh.

◆ portInputs_

std::unordered_multimap<std::string, OutputConnection> FUGen::portInputs_
private

Definition at line 235 of file FUGen.hh.

◆ registers_

std::vector<std::string> FUGen::registers_
private

Definition at line 252 of file FUGen.hh.

◆ renamedGlobalSignals_

std::vector<HDB::Variable> FUGen::renamedGlobalSignals_
private

Definition at line 249 of file FUGen.hh.

◆ renamedVariables_

std::vector<HDB::Variable> FUGen::renamedVariables_
private

Definition at line 248 of file FUGen.hh.

◆ replacesPerOp_

std::unordered_map<std::string, std::vector<Replace> > FUGen::replacesPerOp_
private

Definition at line 222 of file FUGen.hh.

◆ resourceCount_

std::unordered_map<std::string, int> FUGen::resourceCount_
private

Definition at line 230 of file FUGen.hh.

◆ resourceInputs_

std::vector<std::string> FUGen::resourceInputs_
private

Definition at line 241 of file FUGen.hh.

◆ resourceOutputs_

std::vector<std::string> FUGen::resourceOutputs_
private

Definition at line 242 of file FUGen.hh.

◆ scheduledOperations_

std::unordered_map<std::string, OperationSchedule> FUGen::scheduledOperations_
private

Definition at line 221 of file FUGen.hh.

◆ subOpCount_

std::unordered_map<std::string, int> FUGen::subOpCount_
private

Definition at line 226 of file FUGen.hh.

◆ triggerPort_

std::string FUGen::triggerPort_
private

Definition at line 250 of file FUGen.hh.

◆ useGlock_

bool FUGen::useGlock_ = false
private

Definition at line 255 of file FUGen.hh.

◆ useGlockRequest_

bool FUGen::useGlockRequest_ = false
private

Definition at line 254 of file FUGen.hh.


The documentation for this class was generated from the following files:
Operand
Definition: Operand.hh:52
FUGen::isLSU_
bool isLSU_
Definition: FUGen.hh:261
FUGen::adfFU_
TTAMachine::FunctionUnit * adfFU_
Definition: FUGen.hh:211
OperationDAGEdge::dstOperand
int dstOperand() const
Definition: OperationDAGEdge.cc:54
TTAMachine::FUPort::noRegister
bool noRegister() const
Definition: FUPort.cc:469
ProGe::NetlistBlock::netlist
virtual const Netlist & netlist() const
Definition: BaseNetlistBlock.cc:348
FUGen::renamedGlobalSignals_
std::vector< HDB::Variable > renamedGlobalSignals_
Definition: FUGen.hh:249
HDB::OperationImplementation::initialImplFileVerilog
std::string initialImplFileVerilog
Definition: OperationImplementation.hh:55
ProGeOptions::fuIcGateList
std::vector< std::string > fuIcGateList
Definition: ProGeOptions.hh:105
FUGen::pipelineValid
std::string pipelineValid(std::string port, int cycle)
Definition: FUGen.cc:155
Path
Definition: FileSystem.hh:197
OperationPool::operation
Operation & operation(const char *name)
Definition: OperationPool.cc:99
FUGen::fu_
HDLGenerator::Module fu_
Definition: FUGen.hh:210
HDLGenerator::UnsignedVariable
Definition: HDLGenerator.hh:501
FUGen::options_
const ProGeOptions & options_
Definition: FUGen.hh:204
OperationPimpl::name
TCEString name() const
Definition: OperationPimpl.cc:121
FUGen::findAbsolutePath
std::string findAbsolutePath(std::string file)
Definition: FUGen.cc:101
HDLGenerator::BinaryLiteral
Definition: LHSValue.hh:71
HDLGenerator::LogicalAnd
Definition: BinaryOps.hh:51
FUGen::resourceInputs_
std::vector< std::string > resourceInputs_
Definition: FUGen.hh:241
HDLGenerator::CodeBlock
Definition: HDLGenerator.hh:876
ProGe::SignalGroupType::BYTEMASKED_SRAM_PORT
@ BYTEMASKED_SRAM_PORT
Signal group type for one port SRAM having read and write capability and bitmask for writing with sep...
FUGen::selectedLanguage
HDLGenerator::Language selectedLanguage()
Definition: FUGen.cc:73
FUGen::globalOptions_
std::vector< std::string > globalOptions_
Definition: FUGen.hh:205
BoostGraph::tailNode
virtual Node & tailNode(const Edge &edge) const
FUGen::triggerSignal
std::string triggerSignal(int stage)
Definition: FUGen.cc:122
FileSystem::createDirectory
static bool createDirectory(const std::string &path)
Definition: FileSystem.cc:400
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
FUGen::replaceToken
std::string replaceToken(std::string line, Replace replace)
Definition: FUGen.cc:67
ProGe::Verilog
@ Verilog
Verilog.
Definition: ProGeTypes.hh:42
FUGen::extInputs_
std::unordered_set< std::string > extInputs_
Definition: FUGen.hh:246
HDLGenerator::HDLOperation
Definition: HDLGenerator.hh:140
TTAMachine::FunctionUnit::hasAddressSpace
virtual bool hasAddressSpace() const
Definition: FunctionUnit.cc:608
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
BoostGraph::headNode
virtual Node & headNode(const Edge &edge) const
TTAMachine::HWOperation
Definition: HWOperation.hh:52
HDLGenerator::DefaultAssign
Definition: HDLGenerator.hh:366
HDLGenerator::SignedVariable
Definition: HDLGenerator.hh:516
ProGe::BIT_VECTOR
@ BIT_VECTOR
Several bits.
Definition: ProGeTypes.hh:48
FUGen::hasToken
bool hasToken(std::string line, std::string token)
Definition: FUGen.cc:61
FUGen::subOpName
std::string subOpName(OperationNode *node)
Definition: FUGen.cc:160
FUGen::replacesPerOp_
std::unordered_map< std::string, std::vector< Replace > > replacesPerOp_
Definition: FUGen.hh:222
FUGen::subOpCount_
std::unordered_map< std::string, int > subOpCount_
Definition: FUGen.hh:226
HDB::OperationImplementation::initialImplFileVhdl
std::string initialImplFileVhdl
Definition: OperationImplementation.hh:56
FUGen::extOutputs_
std::set< std::pair< std::string, std::string > > extOutputs_
Definition: FUGen.hh:245
HDLGenerator::Module::appendToHeader
void appendToHeader(const std::string &line)
Definition: HDLGenerator.hh:1273
FUGen::portDirection_
std::unordered_map< std::string, ProGe::Direction > portDirection_
Definition: FUGen.hh:234
FUGen::resourceOutputs_
std::vector< std::string > resourceOutputs_
Definition: FUGen.hh:242
FUGen::frontRegistered_
bool frontRegistered_
Definition: FUGen.hh:257
FUGen::dagConstantCount_
std::unordered_map< std::string, int > dagConstantCount_
Definition: FUGen.hh:227
FUGen::addressWidth_
int addressWidth_
Definition: FUGen.hh:260
HDLGenerator::Module
Definition: HDLGenerator.hh:1163
HDLGenerator::CodeBlock::append
void append(SS cc)
Definition: HDLGenerator.hh:881
Operand::width
virtual int width() const
Definition: Operand.cc:318
FUGen::portInputs_
std::unordered_multimap< std::string, OutputConnection > portInputs_
Definition: FUGen.hh:235
HDB::OperationImplementation::postOpImplFileVerilog
std::string postOpImplFileVerilog
Definition: OperationImplementation.hh:54
ipxact::BusInfo
Definition: IPXact.hh:59
GraphNode::nodeID
int nodeID() const
ipxact::parseBus
BusInfo parseBus(std::string file)
Definition: IPXact.cc:39
TerminalNode
Definition: TerminalNode.hh:47
OperationPool::index
OperationIndex & index()
Definition: OperationPool.cc:109
HDB::Variable
Definition: OperationImplementation.hh:40
FUGen::baseOperations_
std::unordered_map< std::string, BaseOperation > baseOperations_
Definition: FUGen.hh:220
HDLGenerator::Sext
Definition: WidthTransformations.hh:82
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
OperationNode::referencedOperation
Operation & referencedOperation() const
Definition: OperationNode.cc:70
TTAMachine::FunctionUnit::addressSpace
virtual AddressSpace * addressSpace() const
Definition: FunctionUnit.cc:580
HDLGenerator::BinaryConstant
Definition: HDLGenerator.hh:244
HDB::Variable::width
std::string width
Definition: OperationImplementation.hh:42
ProGeOptions::outputDirectory
std::string outputDirectory
Definition: ProGeOptions.hh:83
FUGen::extIfaces_
std::unordered_set< std::string > extIfaces_
Definition: FUGen.hh:244
OperationNode
Definition: OperationNode.hh:47
HDLGenerator::Splice
Definition: WidthTransformations.hh:68
TTAMachine::FUPort::isTriggering
virtual bool isTriggering() const
Definition: FUPort.cc:182
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
HDB::OperationImplementation::postOpImplFileVhdl
std::string postOpImplFileVhdl
Definition: OperationImplementation.hh:53
ipxact::ModuleInfo::ports
std::vector< Port > ports
Definition: IPXact.hh:56
FUGen::fug_
IDF::FUGenerated & fug_
Definition: FUGen.hh:207
FileSystem::fileOfPath
static std::string fileOfPath(const std::string pathName)
Definition: FileSystem.cc:101
FUGen::useGlock_
bool useGlock_
Definition: FUGen.hh:255
HDB::CachedHDBManager
Definition: CachedHDBManager.hh:63
ProGe::Netlist::connect
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition: Netlist.cc:83
HDLGenerator::Option
Definition: HDLGenerator.hh:207
HDB::OperationImplementation::verilogVariables
std::vector< Variable > verilogVariables
Definition: OperationImplementation.hh:60
FUGen::registers_
std::vector< std::string > registers_
Definition: FUGen.hh:252
FUGen::dagConstants_
std::unordered_map< int, DAGConstant > dagConstants_
Definition: FUGen.hh:239
HDLGenerator::Wire
Definition: HDLGenerator.hh:315
ProGeTools::dagLatency
int dagLatency(const OperationDAG &dag, const std::unordered_map< std::string, int > &maxOpLatency)
Definition: ProGeTools.cc:234
FUGen::operations_
std::vector< std::string > operations_
Definition: FUGen.hh:213
FUGen::renamedVariables_
std::vector< HDB::Variable > renamedVariables_
Definition: FUGen.hh:248
assert
#define assert(condition)
Definition: Application.hh:86
FUGen::middleRegistered_
bool middleRegistered_
Definition: FUGen.hh:258
FUGen::readFile
std::deque< std::string > readFile(std::string filename)
Definition: FUGen.cc:82
TTAMachine::HWOperation::port
virtual FUPort * port(int operand) const
Definition: HWOperation.cc:320
HDLGenerator::Equals
Definition: BinaryOps.hh:81
TTAMachine::FUPort
Definition: FUPort.hh:46
ProGe::NetlistPortGroup
Definition: NetlistPortGroup.hh:53
HDLGenerator::Case
Definition: HDLGenerator.hh:645
HDB::OperationImplementation::verilogGlobalSignals
std::vector< Variable > verilogGlobalSignals
Definition: OperationImplementation.hh:62
FUGen::nodeImplementations_
std::unordered_map< int, int > nodeImplementations_
Definition: FUGen.hh:238
ProGe::VHDL
@ VHDL
VHDL.
Definition: ProGeTypes.hh:41
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
ProGeOptions::language
ProGe::HDL language
Definition: ProGeOptions.hh:82
OperationDAGEdge::srcOperand
int srcOperand() const
Definition: OperationDAGEdge.cc:49
FUGen::triggerPort_
std::string triggerPort_
Definition: FUGen.hh:250
OperationDAGNode
Definition: OperationDAGNode.hh:45
FUGen::opcodeWidth_
int opcodeWidth_
Definition: FUGen.hh:214
Environment::hdbPaths
static std::vector< std::string > hdbPaths(bool libraryPathsOnly=false)
Definition: Environment.cc:683
FUGen::Replace
std::pair< std::string, std::string > Replace
Definition: FUGen.hh:98
FUGen::core_
ProGe::NetlistBlock * core_
Definition: FUGen.hh:208
HDB::OperationImplementation::implFileVerilog
std::string implFileVerilog
Definition: OperationImplementation.hh:52
IDF::FUGenerated::operations
std::vector< Info > & operations()
Definition: FUGenerated.cc:113
HDLGenerator::OutPort
Definition: HWGen/HDLPort.hh:99
ProGe::MemoryBusInterface
Definition: MemoryBusInterface.hh:46
FUGen::netlistBlock_
ProGe::NetlistBlock * netlistBlock_
Definition: FUGen.hh:217
OperationDAG
Definition: OperationDAG.hh:43
FUGen::behaviour_
HDLGenerator::Behaviour behaviour_
Definition: FUGen.hh:256
FileSystem::directoryOfPath
static std::string directoryOfPath(const std::string fileName)
Definition: FileSystem.cc:79
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
FUGen::DAGNodeOperandWidth
int DAGNodeOperandWidth(OperationDAGNode &node, int id, OperationDAG *dag)
Definition: FUGen.cc:201
ConstantNode
Definition: ConstantNode.hh:43
FUGen::pipelineLength_
std::unordered_map< std::string, int > pipelineLength_
Definition: FUGen.hh:233
FileSystem::copy
static void copy(const std::string &source, const std::string &target)
Definition: FileSystem.cc:524
HDLGenerator::IntegerConstant
Definition: HDLGenerator.hh:287
ProGe::NetlistPortGroup::addPort
void addPort(NetlistPort &port)
Definition: NetlistPortGroup.cc:93
FUGen::resourceCount_
std::unordered_map< std::string, int > resourceCount_
Definition: FUGen.hh:230
FUGen::operandPlaceholder
std::string operandPlaceholder(int id)
Definition: FUGen.cc:141
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
HDLGenerator::Synchronous
Definition: HDLGenerator.hh:982
FUGen::addRegisterIfMissing
void addRegisterIfMissing(std::string name, int width, HDLGenerator::WireType wt=HDLGenerator::WireType::Auto)
Definition: FUGen.cc:1377
FUGen::useGlockRequest_
bool useGlockRequest_
Definition: FUGen.hh:254
MathTools::requiredBits
static int requiredBits(unsigned long int number)
FUGen::opcodeConstant
std::string opcodeConstant(std::string operation)
Definition: FUGen.cc:131
HDLGenerator::Module::implement
void implement(std::ostream &stream, Language lang, int level=0)
Definition: HDLGenerator.hh:1476
FUGen::constantName
std::string constantName(ConstantNode *node, OperationDAG *dag)
Definition: FUGen.cc:178
HDLGenerator::If
Definition: HDLGenerator.hh:786
TTAMachine::Port::isOutput
virtual bool isOutput() const
Definition: Port.cc:308
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
Operation
Definition: Operation.hh:59
FUGen::opcodeSignal
std::string opcodeSignal(int stage)
Definition: FUGen.cc:113
HDB::OperationImplementation::resources
std::vector< OperationImplementationResource > resources
Definition: OperationImplementation.hh:58
FUGen::operationCycles_
std::unordered_map< std::string, int > operationCycles_
Definition: FUGen.hh:223
HDLGenerator::LHSSignal
Definition: LHSValue.hh:66
HDB::OperationImplementation::vhdlVariables
std::vector< Variable > vhdlVariables
Definition: OperationImplementation.hh:59
HDLGenerator::Asynchronous
Definition: HDLGenerator.hh:900
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
options
static MachInfoCmdLineOptions options
Definition: MachInfo.cc:46
HDB::OperationImplementation::absBusDefFile
std::string absBusDefFile
Definition: OperationImplementation.hh:57
TTAMachine::HWOperation::operandCount
int operandCount() const
Definition: HWOperation.cc:306
ProGe::SignalType
SignalType
Definition: SignalTypes.hh:42
ipxact::BusInfo::ports
std::vector< Port > ports
Definition: IPXact.hh:61
HDLGenerator::InPort
Definition: HWGen/HDLPort.hh:110
Operation::operand
virtual Operand & operand(int id) const
Definition: Operation.cc:541
Operation::dagCount
virtual int dagCount() const
Definition: Operation.cc:134
HDLGenerator::Ext
Definition: WidthTransformations.hh:39
FUGen::operandSignal
std::string operandSignal(std::string operation, int id)
Definition: FUGen.cc:136
HDLGenerator::DefaultCase
Definition: HDLGenerator.hh:614
HDB::HDBManager::OperationImplementationByID
OperationImplementation OperationImplementationByID(RowID id) const
Definition: HDBManager.cc:2248
ConstantNode::value
virtual long value() const
Definition: ConstantNode.cc:60
ProGeTools::maxLatencyToNode
int maxLatencyToNode(const OperationDAG &dag, OperationDAGNode &node, const std::unordered_map< std::string, int > &maxOpLatency, bool allowDifference=true)
Definition: ProGeTools.cc:274
FUGen
Definition: FUGen.hh:58
FUGen::minLatency_
int minLatency_
Definition: FUGen.hh:202
FUGen::buildReplaces
std::vector< Replace > buildReplaces(std::string opName)
Definition: FUGen.cc:395
FileSystem::fileExists
static bool fileExists(const std::string fileName)
OperationIndex::effectiveOperation
Operation * effectiveOperation(const TCEString &name)
Definition: OperationIndex.cc:454
HDLGenerator::LogicVariable
Definition: HDLGenerator.hh:482
TTAMachine::Port::name
virtual std::string name() const
Definition: Port.cc:141
ipxact::ModuleInfo
Definition: IPXact.hh:53
TCEString
Definition: TCEString.hh:53
OperationIndex
Definition: OperationIndex.hh:58
FUGen::moduleName_
std::string moduleName_
Definition: FUGen.hh:216
HDB::IN
@ IN
Input port.
Definition: HDBTypes.hh:41
FUGen::isLSUDataPort
bool isLSUDataPort(const std::string &portName)
Definition: FUGen.cc:516
FUGen::OperandConnection
Definition: FUGen.hh:100
ProGe::NetlistBlock::addPortGroup
void addPortGroup(NetlistPortGroup *portGroup)
Definition: BaseNetlistBlock.cc:508
ProGeTools::canGenerateFromDAG
bool canGenerateFromDAG(const OperationDAG &dag, const std::vector< IDF::FUGenerated::Info > infos, std::vector< IDF::FUGenerated::Info > *subops)
Definition: ProGeTools.cc:194
HDLGenerator::Generatable::name
const std::string & name() const noexcept
Definition: Generatable.hh:239
TTAMachine::Port::isInput
virtual bool isInput() const
Definition: Port.cc:298
HDLGenerator::Assign
Definition: HDLGenerator.hh:539
HDLGenerator::WireType::Vector
@ Vector
ProGe::NetlistPort
Definition: NetlistPort.hh:70
HDLGenerator::Register
Definition: HDLRegister.hh:51
ProGe::BaseNetlistBlock::moduleName
const std::string & moduleName() const
Definition: BaseNetlistBlock.cc:140
ContainerTools::containsValue
static bool containsValue(const ContainerType &aContainer, const ElementType &aKey)
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
FUGen::scheduledOperations_
std::unordered_map< std::string, OperationSchedule > scheduledOperations_
Definition: FUGen.hh:221
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
TTAMachine::HWOperation::latency
int latency() const
Definition: HWOperation.cc:216
FUGen::implementapleDAGs_
std::unordered_map< std::string, OperationDAG * > implementapleDAGs_
Definition: FUGen.hh:225
OperationPool
Definition: OperationPool.hh:52
HDLGenerator::Switch
Definition: HDLGenerator.hh:743
IDF::FUGenerated::name
std::string name() const
Definition: FUGenerated.cc:103
DS
#define DS
Definition: LLVMBackend.cc:124
HDB::OperationImplementation::vhdlGlobalSignals
std::vector< Variable > vhdlGlobalSignals
Definition: OperationImplementation.hh:61
Operand::isInput
virtual bool isInput() const
Definition: Operand.cc:145
ProGe::NetlistBlock::subBlockCount
virtual size_t subBlockCount() const
Definition: BaseNetlistBlock.cc:150
FUGen::implLatency_
std::unordered_map< std::string, int > implLatency_
Definition: FUGen.hh:224
ProGe::NetlistBlock::subBlock
NetlistBlock & subBlock(size_t index) override
Definition: NetlistBlock.cc:110
FileSystem::findFileInSearchPaths
static std::string findFileInSearchPaths(const std::vector< std::string > &searchPaths, const std::string &file)
Definition: FileSystem.cc:562
ProGe::Direction
Direction
Direction of the port.
Definition: ProGeTypes.hh:52
FUGen::maxLatency_
int maxLatency_
Definition: FUGen.hh:201
FUGen::copyImplementation
void copyImplementation(std::string file, std::string format, bool isSynthesizable)
Definition: FUGen.cc:267
OperationDAG::operation
const class OperationPimpl & operation() const
Definition: OperationDAG.hh:59
MathTools::requiredBitsSigned
static int requiredBitsSigned(SLongWord number)
FUGen::subOpConnection
OperandConnection subOpConnection(OperationDAG *dag, OperationDAGEdge *edge, bool isOutput)
Definition: FUGen.cc:1024
FUGen::pipelineName
std::string pipelineName(std::string port, int cycle)
Definition: FUGen.cc:146
ipxact::parseComponent
ModuleInfo parseComponent(std::string file)
Definition: IPXact.cc:86
ProGeTools::findInOptionList
bool findInOptionList(const std::string &option, std::vector< std::string > list, bool enableAll=true)
Definition: ProGeTools.cc:124
FUGen::prepareSnippet
void prepareSnippet(std::string name, std::deque< std::string > statements, HDLGenerator::CodeBlock &sink, std::set< std::string > &addedStatements)
Definition: FUGen.cc:854
HDB::OUT
@ OUT
Output port.
Definition: HDBTypes.hh:42
Operation::dag
virtual OperationDAG & dag(int index) const
Definition: Operation.cc:148
FUGen::inferLSUSignal
ProGe::Signal inferLSUSignal(const std::string &portName) const
Definition: FUGen.cc:542
StringTools::stringToLower
static std::string stringToLower(const std::string &source)
Definition: StringTools.cc:160
TerminalNode::operandIndex
virtual int operandIndex() const
Definition: TerminalNode.cc:60
ProGeOptions::hdbList
std::vector< std::string > hdbList
Definition: ProGeOptions.hh:103
HDB::OperationImplementation
Definition: OperationImplementation.hh:47
TTAMachine::BaseFUPort::width
virtual int width() const
Definition: BaseFUPort.cc:109
HDB::OperationImplementation::implFileVhdl
std::string implFileVhdl
Definition: OperationImplementation.hh:51
HDB::CachedHDBManager::instance
static CachedHDBManager & instance(const std::string &hdbFile)
Definition: CachedHDBManager.cc:89