OpenASIP  2.0
Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
ProGe::VHDLNetlistWriter Class Reference

#include <VHDLNetlistWriter.hh>

Inheritance diagram for ProGe::VHDLNetlistWriter:
Inheritance graph
Collaboration diagram for ProGe::VHDLNetlistWriter:
Collaboration graph

Public Member Functions

 VHDLNetlistWriter (const BaseNetlistBlock &targetBlock)
 
virtual ~VHDLNetlistWriter ()
 
virtual void write (const std::string &dstDirectory)
 
- Public Member Functions inherited from ProGe::NetlistWriter
 NetlistWriter (const BaseNetlistBlock &targetBlock)
 
virtual ~NetlistWriter ()
 

Static Public Member Functions

static void writeGenericDeclaration (const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
 
static void writePortDeclaration (const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
 

Private Types

typedef boost::graph_traits< Netlist >::vertex_descriptor vertex_descriptor
 
typedef boost::graph_traits< Netlist >::edge_descriptor edge_descriptor
 
typedef boost::graph_traits< Netlist >::out_edge_iterator out_edge_iterator
 

Private Member Functions

void writeNetlistParameterPackage (const std::string &dstDirectory) const
 
std::string netlistParameterPkgName () const
 
void writeBlock (const BaseNetlistBlock &block, const std::string &dstDirectory)
 
void writeSignalDeclarations (const BaseNetlistBlock &block, std::ofstream &stream)
 
void writeSignalAssignments (const BaseNetlistBlock &block, std::ofstream &stream) const
 
void writeConnection (const BaseNetlistBlock &block, std::ofstream &stream, edge_descriptor edgeDescriptor, NetlistPort *srcPort, NetlistPort *dstPort) const
 
void writeComponentDeclarations (const BaseNetlistBlock &block, std::ofstream &stream) const
 
void writePortMappings (const BaseNetlistBlock &block, std::ofstream &stream) const
 
std::string indentation (unsigned int level) const
 
TCEString genericMapStringValue (const TCEString &generic) const
 

Static Private Member Functions

static std::string directionString (Direction direction)
 
static std::string generateIndentation (unsigned int level, const std::string &indentation)
 
static bool isNumber (const std::string &formula)
 
static bool usesParameterWidth (const NetlistPort &port)
 
static std::string portSignalName (const NetlistPort &port)
 
static std::string portSignalType (const NetlistPort &port)
 
static TCEString signalRange (int high, int low, bool allowShort=false)
 
static TCEString parameterWidthValue (const NetlistPort &port)
 
static std::string signalAssignment (const NetlistPort &dst, const NetlistPort &src)
 

Private Attributes

int groundWidth_
 Width of the ground signal. More...
 

Additional Inherited Members

- Protected Member Functions inherited from ProGe::NetlistWriter
const BaseNetlistBlocktargetNetlistBlock () const
 

Detailed Description

Writes VHDL files which implement the given netlist block.

Definition at line 52 of file VHDLNetlistWriter.hh.

Member Typedef Documentation

◆ edge_descriptor

typedef boost::graph_traits<Netlist>::edge_descriptor ProGe::VHDLNetlistWriter::edge_descriptor
private

Definition at line 74 of file VHDLNetlistWriter.hh.

◆ out_edge_iterator

Definition at line 76 of file VHDLNetlistWriter.hh.

◆ vertex_descriptor

Definition at line 72 of file VHDLNetlistWriter.hh.

Constructor & Destructor Documentation

◆ VHDLNetlistWriter()

ProGe::VHDLNetlistWriter::VHDLNetlistWriter ( const BaseNetlistBlock targetBlock)

Constructor. Records the input netlist for which it can generate VHDL.

Parameters
netlistThe input netlist.

Definition at line 70 of file VHDLNetlistWriter.cc.

71  : NetlistWriter(targetBlock), groundWidth_(0) {}

◆ ~VHDLNetlistWriter()

ProGe::VHDLNetlistWriter::~VHDLNetlistWriter ( )
virtual

The destructor.

Definition at line 76 of file VHDLNetlistWriter.cc.

76  {
77 }

Member Function Documentation

◆ directionString()

std::string ProGe::VHDLNetlistWriter::directionString ( Direction  direction)
staticprivate

Returns the string that means the same direction as the given one in VHDL.

Returns
The direction string.

Definition at line 688 of file VHDLNetlistWriter.cc.

688  {
689  switch (direction) {
690  case IN:
691  return "in";
692  case OUT:
693  return "out";
694  case BIDIR:
695  return "inout";
696  default:
697  assert(false);
698  }
699 
700  // dummy return
701  assert(false);
702  return "";
703 }

References assert, ProGe::BIDIR, ProGe::IN, and ProGe::OUT.

Referenced by writeComponentDeclarations(), and writePortDeclaration().

◆ generateIndentation()

std::string ProGe::VHDLNetlistWriter::generateIndentation ( unsigned int  indentationLevel,
const std::string &  indentation 
)
staticprivate

Generates an indentation string with the given parameters.

Parameters
indentationLevelThe level of indentation.
indentationThe string used as indentation (one level).
Returns
The indentation of the given level.

Definition at line 751 of file VHDLNetlistWriter.cc.

753  {
754 
755  string generatedInd("");
756  for (size_t i = 0; i < indentationLevel; i++) {
757  generatedInd += indentation;
758  }
759  return generatedInd;
760 }

References indentation().

Referenced by writeGenericDeclaration(), and writePortDeclaration().

Here is the call graph for this function:

◆ genericMapStringValue()

TCEString ProGe::VHDLNetlistWriter::genericMapStringValue ( const TCEString generic) const
private

Tries to determine whether the string generic needs quot marks for generic mapping

If string literal contains '.', or "__" it cannot be a valid VHDL label (i.e. another generic), thus it needs quotation marks.

Parameters
genericString generic value
Returns
Generic mapping string

Definition at line 829 of file VHDLNetlistWriter.cc.

829  {
830 
831  if (generic.startsWith("\"") && generic.endsWith("\"")) {
832  return generic;
833  }
834  std::vector<TCEString> unallowed;
835  unallowed.push_back(".");
836  unallowed.push_back("__");
837  for (size_t i = 0; i < unallowed.size(); i++) {
838  if (generic.find(unallowed.at(i)) != TCEString::npos) {
839  TCEString quoted;
840  quoted << "\"" << generic << "\"";
841  return quoted;
842  }
843  }
844  return generic;
845 }

Referenced by writePortMappings().

◆ indentation()

std::string ProGe::VHDLNetlistWriter::indentation ( unsigned int  level) const
private

Returns a string which makes indetation of the given level.

Parameters
levelThe indentation level.

Definition at line 739 of file VHDLNetlistWriter.cc.

739  {
740  return StringTools::indent(level);
741 }

References StringTools::indent().

Referenced by generateIndentation(), writeBlock(), writeComponentDeclarations(), writeConnection(), writeGenericDeclaration(), writeNetlistParameterPackage(), writePortDeclaration(), writePortMappings(), writeSignalAssignments(), and writeSignalDeclarations().

Here is the call graph for this function:

◆ isNumber()

bool ProGe::VHDLNetlistWriter::isNumber ( const std::string &  formula)
staticprivate

Tells whether the given string is a non-negative integer number.

Parameters
formulaThe string.
Returns
True if the given string is a non-negative integer number.

Definition at line 712 of file VHDLNetlistWriter.cc.

712  {
713  int length = formula.length();
714  for (int i = 0; i < length; i++) {
715  if (!isdigit(formula[i])) {
716  return false;
717  }
718  }
719 
720  return true;
721 }

Referenced by portSignalType(), writeComponentDeclarations(), and writePortDeclaration().

◆ netlistParameterPkgName()

std::string ProGe::VHDLNetlistWriter::netlistParameterPkgName ( ) const
private

Returns the name of the netlist parameter package.

Returns
The name.

Definition at line 128 of file VHDLNetlistWriter.cc.

128  {
129  return targetNetlistBlock().moduleName() + "_params";
130 }

References ProGe::BaseNetlistBlock::moduleName(), and ProGe::NetlistWriter::targetNetlistBlock().

Referenced by writeBlock(), and writeNetlistParameterPackage().

Here is the call graph for this function:

◆ parameterWidthValue()

TCEString ProGe::VHDLNetlistWriter::parameterWidthValue ( const NetlistPort port)
staticprivate

Returns port width value of port that uses parameter as width.

Definition at line 880 of file VHDLNetlistWriter.cc.

880  {
881  return port.parentBlock().parameter(port.widthFormula()).value();
882 }

References ProGe::BaseNetlistBlock::parameter(), ProGe::NetlistPort::parentBlock(), ProGe::Parameter::value(), and ProGe::NetlistPort::widthFormula().

Referenced by portSignalType().

Here is the call graph for this function:

◆ portSignalName()

std::string ProGe::VHDLNetlistWriter::portSignalName ( const NetlistPort port)
staticprivate

Returns the name of the signal mapped to the given port.

Parameters
portThe port.

Definition at line 769 of file VHDLNetlistWriter.cc.

769  {
770  const BaseNetlistBlock* parentBlock = &port.parentBlock();
771  string signalName = "";
772  if (port.hasStaticValue()) {
773  string bit = "";
774  if (port.staticValue().is(StaticSignal::VCC)) {
775  bit = "1";
776  } else {
777  bit = "0";
778  }
779  if (port.dataType() == BIT) {
780  signalName = "'" + bit + "'";
781  } else {
782  signalName = "(others => '" + bit + "')";
783  }
784  } else {
785  signalName = parentBlock->instanceName() + "_" + port.name() +
786  "_wire";
787  }
788  return signalName;
789 }

References ProGe::BIT, ProGe::NetlistPort::dataType(), ProGe::NetlistPort::hasStaticValue(), ProGe::BaseNetlistBlock::instanceName(), ProGe::StaticSignal::is(), ProGe::NetlistPort::name(), ProGe::NetlistPort::parentBlock(), ProGe::NetlistPort::staticValue(), and ProGe::StaticSignal::VCC.

Referenced by signalAssignment(), writeConnection(), writePortMappings(), and writeSignalDeclarations().

Here is the call graph for this function:

◆ portSignalType()

std::string ProGe::VHDLNetlistWriter::portSignalType ( const NetlistPort port)
staticprivate

Returns the type of the signal mapped to the given port.

Parameters
portThe port.

Definition at line 798 of file VHDLNetlistWriter.cc.

798  {
799  if (port.dataType() == BIT) {
800  return "std_logic";
801  } else {
802  if (port.realWidthAvailable()) {
803  int width = port.realWidth();
804  return "std_logic_vector" +
805  signalRange((width ? width - 1 : 0), 0);
806  } else if (isNumber(port.widthFormula()) &&
807  (Conversion::toInt(port.widthFormula()) == 0)) {
808  return "std_logic_vector" + signalRange(0, 0);
809  } else if (usesParameterWidth(port)) {
810  return "std_logic_vector(" + parameterWidthValue(port) +
811  "-1 downto 0)";
812  } else {
813  return "std_logic_vector(" + port.widthFormula() + "-1 downto 0)";
814  }
815  }
816 }

References ProGe::BIT, ProGe::NetlistPort::dataType(), isNumber(), parameterWidthValue(), ProGe::NetlistPort::realWidth(), ProGe::NetlistPort::realWidthAvailable(), signalRange(), Conversion::toInt(), usesParameterWidth(), and ProGe::NetlistPort::widthFormula().

Referenced by writeSignalDeclarations().

Here is the call graph for this function:

◆ signalAssignment()

std::string ProGe::VHDLNetlistWriter::signalAssignment ( const NetlistPort dst,
const NetlistPort src 
)
staticprivate

Writes suitable signal assignment code of two signals.

The written code piece is "dst <= src;" with additional signal indexing in case the data types does not macth (i.e. BIT vs. BIT_VECTOR).

Definition at line 892 of file VHDLNetlistWriter.cc.

893  {
894  using std::string;
895 
896  if (dst.dataType() == src.dataType()) {
897  return string(portSignalName(dst)) + " <= " + portSignalName(src) +
898  ";";
899  } else {
900  // Note assuming that one port is data type of BIT and other is
901  // BIT_VECTOR of width og one.
902  bool indexDst = (dst.dataType() == BIT_VECTOR);
903  return string(portSignalName(dst)) +
904  (indexDst ? string("(0) <= ") : string(" <= ")) +
905  portSignalName(src) +
906  (indexDst ? string(";") : string("(0);"));
907  }
908 }

References ProGe::BIT_VECTOR, ProGe::NetlistPort::dataType(), and portSignalName().

Referenced by writeConnection().

Here is the call graph for this function:

◆ signalRange()

TCEString ProGe::VHDLNetlistWriter::signalRange ( int  high,
int  low,
bool  allowShort = false 
)
staticprivate

Returns signal range i.e. (<high> downto <low>).

Does not -1 the high index! If high == low and allowShort is true, just (<low>) is returned

Parameters
highMSB index
lowLSB index
allowShortIf true, skips 'downto' if high == low
Returns
Signal range string

Definition at line 859 of file VHDLNetlistWriter.cc.

859  {
860  if (high < low) {
861  TCEString msg;
862  msg << "High (" << high << ") boundary is smaller than low (" << low
863  << ") boundary!";
864  throw InvalidData(__FILE__, __LINE__, __func__, msg);
865  }
866 
867  TCEString range = "(";
868  if (allowShort && high == low) {
869  range << low;
870  } else {
871  range << high << " downto " << low;
872  }
873  return range << ")";
874 }

References __func__.

Referenced by portSignalType(), writeConnection(), and writeSignalDeclarations().

◆ usesParameterWidth()

bool ProGe::VHDLNetlistWriter::usesParameterWidth ( const NetlistPort port)
staticprivate

Returns true if port uses single parameter of its parent block as port width.

Definition at line 728 of file VHDLNetlistWriter.cc.

728  {
729  const BaseNetlistBlock& parent = port.parentBlock();
730  return parent.hasParameter(port.widthFormula());
731 }

References ProGe::BaseNetlistBlock::hasParameter(), ProGe::NetlistPort::parentBlock(), and ProGe::NetlistPort::widthFormula().

Referenced by portSignalType().

Here is the call graph for this function:

◆ write()

void ProGe::VHDLNetlistWriter::write ( const std::string &  dstDirectory)
virtual

Generates the VHDL files and writes them to the given directory.

Parameters
dstDirectoryThe destination directory.
Exceptions
IOExceptionIf an IO error occurs.
InvalidDataIf the netlist is invalid.

Implements ProGe::NetlistWriter.

Definition at line 88 of file VHDLNetlistWriter.cc.

88  {
89  if (targetNetlistBlock().netlist().isEmpty()) {
90  string errorMsg = "Empty input netlist.";
91  throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
92  }
93  writeNetlistParameterPackage(dstDirectory);
94  writeBlock(targetNetlistBlock(), dstDirectory);
95 }

References __func__, ProGe::NetlistWriter::targetNetlistBlock(), writeBlock(), and writeNetlistParameterPackage().

Referenced by ProGe::BaseNetlistBlock::writeSelf().

Here is the call graph for this function:

◆ writeBlock()

void ProGe::VHDLNetlistWriter::writeBlock ( const BaseNetlistBlock block,
const std::string &  dstDirectory 
)
private

Writes the given block of the netlist to the given destination directory.

Parameters
blockThe netlist block.
dstDirectoryThe destination directory.
Exceptions
IOExceptionIf the file cannot be created.

Definition at line 141 of file VHDLNetlistWriter.cc.

142  {
143  string fileName = dstDirectory + FileSystem::DIRECTORY_SEPARATOR +
144  block.moduleName() + ".vhdl";
145  if (!FileSystem::fileIsCreatable(fileName) &&
146  !(FileSystem::fileExists(fileName) &&
147  FileSystem::fileIsWritable(fileName))) {
148 
149  string errorMsg = "Unable to create file: " + fileName;
150  throw IOException(__FILE__, __LINE__, __func__, errorMsg);
151  }
152 
153  const string entityName = block.moduleName();
154 
155  ofstream outFile;
156  outFile.open(fileName.c_str(), ofstream::out);
157 
158  outFile << "library IEEE;" << endl;
159  outFile << "use IEEE.std_logic_1164.all;" << endl;
160  outFile << "use IEEE.std_logic_arith.all;" << endl;
161  outFile << "use work.tce_util.all;" << endl;
162 
163  for (size_t i = 0; i < block.packageCount(); i++) {
164  outFile << "use work." << block.package(i) << ".all;" << endl;
165  }
166 
167  if (block.netlist().parameterCount() > 0) {
168  outFile << "use work." << netlistParameterPkgName() << ".all;"
169  << endl;
170  }
171 
172  outFile << endl;
173 
174  // create entity
175  outFile << "entity " + entityName + " is" << endl;
176 
177  // create generics
178  writeGenericDeclaration(block, 1, indentation(1), outFile);
179 
180  // create port declarations
181  outFile << endl;
182  writePortDeclaration(block, 1, indentation(1), outFile);
183 
184  outFile << endl << "end " << entityName << ";" << endl;
185 
186  // create architecture
187  outFile << endl;
188  string architectureName = "structural";
189  outFile << "architecture " << architectureName << " of "
190  << entityName << " is" << endl << endl;
191 
192  writeSignalDeclarations(block, outFile);
193  outFile << endl;
194  writeComponentDeclarations(block, outFile);
195  outFile << endl;
196  outFile << "begin" << endl << endl;
197  writeSignalAssignments(block, outFile);
198  outFile << endl;
199  writePortMappings(block, outFile);
200  outFile << "end " + architectureName + ";" << endl;
201  outFile.close();
202 }

References __func__, FileSystem::DIRECTORY_SEPARATOR, FileSystem::fileExists(), FileSystem::fileIsCreatable(), FileSystem::fileIsWritable(), indentation(), ProGe::BaseNetlistBlock::moduleName(), ProGe::BaseNetlistBlock::netlist(), netlistParameterPkgName(), ProGe::BaseNetlistBlock::package(), ProGe::BaseNetlistBlock::packageCount(), ProGe::Netlist::parameterCount(), writeComponentDeclarations(), writeGenericDeclaration(), writePortDeclaration(), writePortMappings(), writeSignalAssignments(), and writeSignalDeclarations().

Referenced by write().

Here is the call graph for this function:

◆ writeComponentDeclarations()

void ProGe::VHDLNetlistWriter::writeComponentDeclarations ( const BaseNetlistBlock block,
std::ofstream &  stream 
) const
private

Writes the component declarations of the given netlist block to the given stream.

Parameters
blockThe netlist block.
streamThe stream to write.

Definition at line 520 of file VHDLNetlistWriter.cc.

521  {
522  std::set<string> declaredModules;
523  for (size_t i = 0; i < block.subBlockCount(); i++) {
524  const BaseNetlistBlock& component = block.subBlock(i);
525  if (AssocTools::containsKey(declaredModules, component.moduleName())) {
526  continue;
527  }
528  // virtual NetlistBlocks are omitted
529  if (component.isVirtual()) {
530  continue;
531  }
532 
533  declaredModules.insert(component.moduleName());
534  stream << indentation(1) << "component " << component.moduleName()
535  << " is" << endl;
536  if (component.parameterCount() > 0) {
537  stream << indentation(2) << "generic (" << endl;
538  for (size_t i = 0; i < component.parameterCount(); i++) {
539  Parameter param = component.parameter(i);
540  stream << indentation(3) << param.name() << " : "
541  << param.type();
542  if (i + 1 == component.parameterCount()) {
543  stream << ");";
544  } else {
545  stream << ";";
546  }
547  stream << endl;
548  }
549  }
550  stream << indentation(2) << "port (" << endl;
551  for (size_t i = 0; i < component.portCount(); i++) {
552  const NetlistPort& port = component.port(i);
553  stream << indentation(3) << port.name() << " : "
554  << directionString(port.direction()) << " ";
555  if (port.dataType() == BIT) {
556  stream << "std_logic";
557  } else {
558  stream << "std_logic_vector(";
559  stream << port.widthFormula();
560  if ((isNumber(port.widthFormula()) &&
561  (Conversion::toInt(port.widthFormula()) != 0)) ||
562  !isNumber(port.widthFormula())) {
563  stream << "-1";
564  }
565  stream << " downto 0)";
566  }
567  if (i + 1 == component.portCount()) {
568  stream << ");";
569  } else {
570  stream << ";";
571  }
572  stream << endl;
573  }
574  stream << indentation(1) << "end component;" << endl << endl;
575  }
576 }

References ProGe::BIT, AssocTools::containsKey(), ProGe::NetlistPort::dataType(), ProGe::NetlistPort::direction(), directionString(), indentation(), isNumber(), ProGe::BaseNetlistBlock::isVirtual(), ProGe::BaseNetlistBlock::moduleName(), ProGe::Parameter::name(), ProGe::NetlistPort::name(), ProGe::BaseNetlistBlock::parameter(), ProGe::BaseNetlistBlock::parameterCount(), ProGe::BaseNetlistBlock::port(), ProGe::BaseNetlistBlock::portCount(), ProGe::BaseNetlistBlock::subBlock(), ProGe::BaseNetlistBlock::subBlockCount(), Conversion::toInt(), ProGe::Parameter::type(), and ProGe::NetlistPort::widthFormula().

Referenced by writeBlock().

Here is the call graph for this function:

◆ writeConnection()

void ProGe::VHDLNetlistWriter::writeConnection ( const BaseNetlistBlock block,
std::ofstream &  stream,
edge_descriptor  edgeDescriptor,
NetlistPort srcPort,
NetlistPort dstPort 
) const
private

Definition at line 444 of file VHDLNetlistWriter.cc.

447  {
448  PortConnectionProperty property = block.netlist()[edgeDescriptor];
449  if (property.fullyConnected()) {
450  if (&dstPort->parentBlock() == &block) {
451  if (srcPort->direction() == OUT) {
452  stream << indentation(1) << dstPort->name()
453  << " <= " << portSignalName(*srcPort) << ";" << endl;
454  } else {
455  stream << indentation(1) << portSignalName(*srcPort)
456  << " <= " << dstPort->name() << ";" << endl;
457  }
458  } else {
459  if (srcPort->direction() == OUT) {
460  stream << indentation(1)
461  << signalAssignment(*dstPort, *srcPort) << endl;
462  } else {
463  stream << indentation(1)
464  << signalAssignment(*srcPort, *dstPort) << endl;
465  }
466  }
467  } else {
468  string srcPortSignal;
469  if (srcPort->dataType() == BIT) {
470  srcPortSignal = portSignalName(*srcPort);
471  } else {
472  if (dstPort->dataType() == BIT) {
473  srcPortSignal =
474  portSignalName(*srcPort) + "(" +
475  Conversion::toString(property.port1FirstBit()) + ")";
476  } else {
477  int high = property.port1FirstBit() + property.width() - 1;
478  int low = property.port1FirstBit();
479  srcPortSignal =
480  portSignalName(*srcPort) + signalRange(high, low, true);
481  }
482  }
483  string dstPortSignal;
484 
485  if (&dstPort->parentBlock() == &block) {
486  dstPortSignal = dstPort->name();
487  } else {
488  dstPortSignal = portSignalName(*dstPort);
489  }
490  if (dstPort->dataType() != BIT) {
491  if (srcPort->dataType() == BIT) {
492  dstPortSignal +=
493  "(" + Conversion::toString(property.port2FirstBit()) +
494  ")";
495  } else {
496  int high = property.port2FirstBit() + property.width() - 1;
497  int low = property.port2FirstBit();
498  dstPortSignal += signalRange(high, low, true);
499  }
500  }
501 
502  if (srcPort->direction() == OUT) {
503  stream << indentation(1) << dstPortSignal
504  << " <= " << srcPortSignal << ";" << endl;
505  } else {
506  stream << indentation(1) << srcPortSignal
507  << " <= " << dstPortSignal << ";" << endl;
508  }
509  }
510 }

References ProGe::BIT, ProGe::NetlistPort::dataType(), ProGe::NetlistPort::direction(), indentation(), ProGe::NetlistPort::name(), ProGe::BaseNetlistBlock::netlist(), ProGe::OUT, ProGe::NetlistPort::parentBlock(), portSignalName(), signalAssignment(), signalRange(), and Conversion::toString().

Referenced by writeSignalAssignments().

Here is the call graph for this function:

◆ writeGenericDeclaration()

void ProGe::VHDLNetlistWriter::writeGenericDeclaration ( const BaseNetlistBlock block,
unsigned int  indentationLevel,
const std::string &  indentation,
std::ostream &  stream 
)
static

Writes the generic declarations of the given netlist block.

Parameters
blockThe netlist block.
indentationLevelThe indentation level where the generic declaration is written.
indentationThe string used as indentation (one level).
streamThe stream to write.

Definition at line 214 of file VHDLNetlistWriter.cc.

216  {
217  if (block.parameterCount() > 0) {
218  stream << endl;
219  stream << generateIndentation(indentationLevel, indentation)
220  << "generic (" << endl;
221  for (size_t i = 0; i < block.parameterCount(); i++) {
222  Parameter param = block.parameter(i);
223  stream << generateIndentation(indentationLevel + 1, indentation)
224  << param.name() << " : " << param.type();
225  if (param.defaultValue() != "") {
226  stream << " := ";
227  if (param.type().lower() == PARAM_STRING) {
228  // string literal needs quot. marks
229  if (!param.defaultValue().startsWith("\""))
230  stream << "\"";
231  stream << param.value();
232  if (!param.defaultValue().endsWith("\"")) stream << "\"";
233  } else {
234  stream << param.defaultValue();
235  }
236  }
237  if (i + 1 == block.parameterCount()) {
238  stream << ");";
239  } else {
240  stream << ";";
241  }
242  stream << endl;
243  }
244  }
245 }

References ProGe::Parameter::defaultValue(), TCEString::endsWith(), generateIndentation(), indentation(), TCEString::lower(), ProGe::Parameter::name(), PARAM_STRING, ProGe::BaseNetlistBlock::parameter(), ProGe::BaseNetlistBlock::parameterCount(), TCEString::startsWith(), ProGe::Parameter::type(), and ProGe::Parameter::value().

Referenced by writeBlock().

Here is the call graph for this function:

◆ writeNetlistParameterPackage()

void ProGe::VHDLNetlistWriter::writeNetlistParameterPackage ( const std::string &  dstDirectory) const
private

Writes the package that defines parameters of the netlist.

Parameters
dstDirectoryThe destination directory.

Definition at line 103 of file VHDLNetlistWriter.cc.

104  {
105 
106  string fileName = dstDirectory + FileSystem::DIRECTORY_SEPARATOR +
107  netlistParameterPkgName() + "_pkg.vhdl";
108  ofstream outFile;
109  outFile.open(fileName.c_str(), ofstream::out);
110 
111  outFile << "package " << netlistParameterPkgName() << " is" << endl;
112  for (size_t i = 0; i < targetNetlistBlock().netlist().parameterCount();
113  i++) {
114  Parameter param = targetNetlistBlock().netlist().parameter(i);
115  outFile << indentation(1) << "constant " << param.name() << " : "
116  << param.type() << " := " << param.value() << ";" << endl;
117  }
118  outFile << "end " << netlistParameterPkgName() << ";" << endl;
119 }

References FileSystem::DIRECTORY_SEPARATOR, indentation(), ProGe::Parameter::name(), ProGe::BaseNetlistBlock::netlist(), netlistParameterPkgName(), ProGe::Netlist::parameter(), ProGe::Netlist::parameterCount(), ProGe::NetlistWriter::targetNetlistBlock(), ProGe::Parameter::type(), and ProGe::Parameter::value().

Referenced by write().

Here is the call graph for this function:

◆ writePortDeclaration()

void ProGe::VHDLNetlistWriter::writePortDeclaration ( const BaseNetlistBlock block,
unsigned int  indentationLevel,
const std::string &  indentation,
std::ostream &  stream 
)
static

Writes the port declaration of the given netlist block.

Parameters
blockThe netlist block.
indentationLevelThe indentation level where the generic declaration is written.
indentationThe string used as indentation (one level).
streamThe stream to write.

Definition at line 257 of file VHDLNetlistWriter.cc.

259  {
260  stream << generateIndentation(indentationLevel, indentation) << "port ("
261  << endl;
262 
263  for (size_t i = 0; i < block.portCount(); i++) {
264  const NetlistPort& port = block.port(i);
265  string portName = port.name();
266  string direction = directionString(port.direction());
267  stream << generateIndentation(indentationLevel+1, indentation)
268  << portName << " : " << direction << " ";
269  if (port.dataType() == BIT) {
270  stream << "std_logic";
271  } else {
272  stream << "std_logic_vector(";
273  // zero width ports as (0 downto 0)
274  if (isNumber(port.widthFormula()) &&
275  Conversion::toInt(port.widthFormula()) == 0) {
276  stream << "0";
277  } else if (isNumber(port.widthFormula())) {
278  stream << Conversion::toInt(port.widthFormula()) - 1;
279  } else {
280  stream << port.widthFormula() << "-1";
281  }
282  stream << " downto 0)";
283  }
284  if (i + 1 == block.portCount()) {
285  stream << ");";
286  } else {
287  stream << ";";
288  }
289  stream << endl;
290  }
291 }

References ProGe::BIT, ProGe::NetlistPort::dataType(), ProGe::NetlistPort::direction(), directionString(), generateIndentation(), indentation(), isNumber(), ProGe::NetlistPort::name(), ProGe::BaseNetlistBlock::port(), ProGe::BaseNetlistBlock::portCount(), Conversion::toInt(), and ProGe::NetlistPort::widthFormula().

Referenced by writeBlock().

Here is the call graph for this function:

◆ writePortMappings()

void ProGe::VHDLNetlistWriter::writePortMappings ( const BaseNetlistBlock block,
std::ofstream &  stream 
) const
private

Writes the port mappings of the given block to the given stream.

Parameters
blockThe netlist block.
streamThe stream to write.

Definition at line 585 of file VHDLNetlistWriter.cc.

586  {
587  for (size_t i = 0; i < block.subBlockCount(); i++) {
588  const BaseNetlistBlock& component = block.subBlock(i);
589 
590  // virtual NetlistBlocks are omitted
591  if (component.isVirtual()) {
592  continue;
593  }
594 
595  stream << indentation(1) << component.instanceName() << " : "
596  << component.moduleName() << endl;
597 
598  // create generic map
599  if (component.parameterCount() > 0) {
600  stream << indentation(2) << "generic map (" << endl;
601  for (size_t i = 0; i < component.parameterCount(); i++) {
602  Parameter param = component.parameter(i);
603  stream << indentation(3) << param.name() << " => ";
604  if (param.type().lower() == PARAM_STRING) {
605  stream << genericMapStringValue(param.value());
606  } else {
607  stream << param.value();
608  }
609  if (i == component.parameterCount() - 1) {
610  stream << ")" << endl;
611  } else {
612  stream << "," << endl;
613  }
614  }
615  }
616 
617  // create port map
618  stream << indentation(2) << "port map (" << endl;
619  for (size_t i = 0; i < component.portCount(); i++) {
620  const NetlistPort& port = component.port(i);
621  size_t vertexDescriptor = block.netlist().descriptor(port);
622  std::pair<out_edge_iterator, out_edge_iterator> edges =
623  boost::out_edges(vertexDescriptor, block.netlist());
624 
625  string srcConn = port.name();
626  string dstConn = "";
627  if (edges.first != edges.second) {
628  edge_descriptor edgeDescriptor = *edges.first;
629  vertex_descriptor dstVertex =
630  boost::target(edgeDescriptor, block.netlist());
631  const NetlistPort* dstPort = block.netlist()[dstVertex];
632  PortConnectionProperty property =
633  block.netlist()[edgeDescriptor];
634 
635  if (&dstPort->parentBlock() == &block) {
636  if (port.dataType() != dstPort->dataType()) {
637  int index = 0;
638  if (!property.fullyConnected() &&
639  dstPort->dataType() == BIT_VECTOR &&
640  port.dataType() == BIT) {
641  index = property.port2FirstBit();
642  }
643 
644  if (port.dataType() == BIT) {
645  assert(dstPort->dataType() == BIT_VECTOR);
646  dstConn = dstPort->name() + "(" +
647  Conversion::toString(index) + ")";
648  } else {
649  assert(dstPort->dataType() == BIT);
650  if (port.widthFormula() == "1") {
651  srcConn += "(0)";
652  dstConn = dstPort->name();
653  } else {
654  dstConn = portSignalName(port);
655  }
656  }
657  } else {
658  if ((!property.fullyConnected() ||
659  dstPort->direction() == OUT) &&
660  boost::out_degree(
661  vertexDescriptor, block.netlist()) > 1) {
662  dstConn = portSignalName(port);
663  } else {
664  dstConn = dstPort->name();
665  }
666  }
667  } else {
668  dstConn = portSignalName(port);
669  }
670  } else {
671  dstConn = portSignalName(port);
672  }
673  stream << indentation(3) << srcConn << " => " << dstConn;
674  if (i+1 < component.portCount()) {
675  stream << "," << endl;
676  }
677  }
678  stream << ");" << endl << endl;
679  }
680 }

References assert, ProGe::BIT, ProGe::BIT_VECTOR, ProGe::NetlistPort::dataType(), ProGe::Netlist::descriptor(), ProGe::NetlistPort::direction(), genericMapStringValue(), indentation(), ProGe::BaseNetlistBlock::instanceName(), ProGe::BaseNetlistBlock::isVirtual(), TCEString::lower(), ProGe::BaseNetlistBlock::moduleName(), ProGe::Parameter::name(), ProGe::NetlistPort::name(), ProGe::BaseNetlistBlock::netlist(), ProGe::OUT, PARAM_STRING, ProGe::BaseNetlistBlock::parameter(), ProGe::BaseNetlistBlock::parameterCount(), ProGe::NetlistPort::parentBlock(), ProGe::BaseNetlistBlock::port(), ProGe::BaseNetlistBlock::portCount(), portSignalName(), ProGe::BaseNetlistBlock::subBlock(), ProGe::BaseNetlistBlock::subBlockCount(), Conversion::toString(), ProGe::Parameter::type(), ProGe::Parameter::value(), and ProGe::NetlistPort::widthFormula().

Referenced by writeBlock().

Here is the call graph for this function:

◆ writeSignalAssignments()

void ProGe::VHDLNetlistWriter::writeSignalAssignments ( const BaseNetlistBlock block,
std::ofstream &  stream 
) const
private

Writes the signal assignments of the given block to the given stream.

Parameters
blockThe netlist block.
streamThe stream.

Definition at line 368 of file VHDLNetlistWriter.cc.

369  {
370  set<const BaseNetlistBlock*, NetlistBlockNameComparator> subBlocks;
371  for (size_t i = 0; i < block.subBlockCount(); i++) {
372  subBlocks.insert(&block.subBlock(i));
373  }
374 
375  typedef std::vector<edge_descriptor> EdgeTable;
376  EdgeTable handledEdges;
377 
378  for (size_t i = 0; i < block.subBlockCount(); i++) {
379  const BaseNetlistBlock& subBlock = block.subBlock(i);
380  for (size_t i = 0; i < subBlock.portCount(); i++) {
381  const NetlistPort& port = subBlock.port(i);
382  size_t vertexDescriptor = block.netlist().descriptor(port);
383  std::pair<out_edge_iterator, out_edge_iterator> edges =
384  boost::out_edges(vertexDescriptor, block.netlist());
385 
386  while (edges.first != edges.second) {
387  edge_descriptor edgeDescriptor = *edges.first;
388  edges.first++;
390  handledEdges, edgeDescriptor)) {
391  vertex_descriptor srcVertex =
392  boost::source(edgeDescriptor, block.netlist());
393  vertex_descriptor dstVertex =
394  boost::target(edgeDescriptor, block.netlist());
395  NetlistPort* srcPort = block.netlist()[srcVertex];
396  NetlistPort* dstPort = block.netlist()[dstVertex];
397 
398  if (&dstPort->parentBlock() == &block) {
399  if (boost::out_degree(
400  vertexDescriptor, block.netlist()) > 1) {
401  // Handle the rare case of multiple outputs
402  // through a wire signal. This isn't done normally
403  // because there would be an ugly wire signal for
404  // every clk, rstx, etc.
405  if (dstPort->direction() == OUT ||
406  srcPort->dataType() != dstPort->dataType()) {
408  block, stream, edgeDescriptor, srcPort,
409  dstPort);
410  }
411  }
412  continue;
413  }
414 
415  assert(srcPort == &port);
417  subBlocks, &srcPort->parentBlock()) &&
419  subBlocks, &dstPort->parentBlock())) {
420  handledEdges.push_back(edgeDescriptor);
421  // add the opposite edge too
422  std::pair<edge_descriptor, bool> opposite =
423  boost::edge(
424  dstVertex, srcVertex, block.netlist());
425  assert(opposite.second);
426  assert(opposite.first != edgeDescriptor);
427  handledEdges.push_back(opposite.first);
428 
430  block, stream, edgeDescriptor, srcPort, dstPort);
431  }
432  }
433  }
434  }
435  }
436 
437  if (groundWidth_ > 0) {
438  stream << indentation(1) << GROUND_SIGNAL << " <= (others => '0');"
439  << endl;
440  }
441 }

References assert, AssocTools::containsKey(), ContainerTools::containsValue(), ProGe::NetlistPort::dataType(), ProGe::Netlist::descriptor(), ProGe::NetlistPort::direction(), GROUND_SIGNAL, groundWidth_, indentation(), ProGe::BaseNetlistBlock::netlist(), ProGe::OUT, ProGe::NetlistPort::parentBlock(), ProGe::BaseNetlistBlock::port(), ProGe::BaseNetlistBlock::portCount(), ProGe::BaseNetlistBlock::subBlock(), ProGe::BaseNetlistBlock::subBlockCount(), and writeConnection().

Referenced by writeBlock().

Here is the call graph for this function:

◆ writeSignalDeclarations()

void ProGe::VHDLNetlistWriter::writeSignalDeclarations ( const BaseNetlistBlock block,
std::ofstream &  stream 
)
private

Writes the VHDL signal declarations to the given stream.

Parameters
blockThe block of which the signals are written.
streamThe stream to write.

Definition at line 300 of file VHDLNetlistWriter.cc.

301  {
302  // collect all the sub blocks to a set, lexicographical sort.
303  typedef std::set<const BaseNetlistBlock*, NetlistBlockNameComparator>
304  BlockSet;
305  BlockSet subBlocks;
306  for (size_t i = 0; i < block.subBlockCount(); i++) {
307  // ports belonging to virtual blocks have static values, thus they are
308  // excluded
309  if (!block.subBlock(i).isVirtual()) {
310  subBlocks.insert(&block.subBlock(i));
311  }
312  }
313 
314  // create a signal for each port in the sub-blocks
315  for (BlockSet::const_iterator iter = subBlocks.begin();
316  iter != subBlocks.end(); iter++) {
317  const BaseNetlistBlock* subBlock = *iter;
318 
319  for (size_t i = 0; i < subBlock->portCount(); i++) {
320  const NetlistPort& port = subBlock->port(i);
321 
322  size_t vertexDescriptor = block.netlist().descriptor(port);
323  std::pair<out_edge_iterator, out_edge_iterator> edges =
324  boost::out_edges(vertexDescriptor, block.netlist());
325 
326  if (edges.first != edges.second) {
327  edge_descriptor edgeDescriptor = *edges.first;
328  vertex_descriptor dstVertex =
329  boost::target(edgeDescriptor, block.netlist());
330  const NetlistPort* dstPort = block.netlist()[dstVertex];
331 
332  if (&dstPort->parentBlock() != &block ||
333  boost::out_degree(vertexDescriptor, block.netlist()) >
334  1) {
335  stream << indentation(1) << "signal "
336  << portSignalName(port) << " : "
337  << portSignalType(port) << ";" << endl;
338  }
339  } else if (!port.hasStaticValue()) {
340  // assume the port is connected to ground if is is
341  // unconnected in the netlist
342  if (port.realWidthAvailable()) {
343  groundWidth_ =
344  std::max(port.realWidth(), groundWidth_);
345  }
346  stream << indentation(1) << "signal "
347  << portSignalName(port) << " : "
348  << portSignalType(port) << ";" << endl;
349  }
350  }
351  }
352 
353  // create a ground signal
354  if (groundWidth_ > 0) {
355  stream << indentation(1) << "signal " << GROUND_SIGNAL
356  << " : std_logic_vector" << signalRange(groundWidth_ - 1, 0)
357  << ";" << endl;
358  }
359 }

References ProGe::Netlist::descriptor(), GROUND_SIGNAL, groundWidth_, ProGe::NetlistPort::hasStaticValue(), indentation(), ProGe::BaseNetlistBlock::isVirtual(), ProGe::BaseNetlistBlock::netlist(), ProGe::NetlistPort::parentBlock(), ProGe::BaseNetlistBlock::port(), ProGe::BaseNetlistBlock::portCount(), portSignalName(), portSignalType(), ProGe::NetlistPort::realWidth(), ProGe::NetlistPort::realWidthAvailable(), signalRange(), ProGe::BaseNetlistBlock::subBlock(), and ProGe::BaseNetlistBlock::subBlockCount().

Referenced by writeBlock().

Here is the call graph for this function:

Member Data Documentation

◆ groundWidth_

int ProGe::VHDLNetlistWriter::groundWidth_
private

Width of the ground signal.

Definition at line 122 of file VHDLNetlistWriter.hh.

Referenced by writeSignalAssignments(), and writeSignalDeclarations().


The documentation for this class was generated from the following files:
PARAM_STRING
const std::string PARAM_STRING
Definition: VHDLNetlistWriter.cc:61
ProGe::VHDLNetlistWriter::writeGenericDeclaration
static void writeGenericDeclaration(const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
Definition: VHDLNetlistWriter.cc:214
ProGe::VHDLNetlistWriter::writeConnection
void writeConnection(const BaseNetlistBlock &block, std::ofstream &stream, edge_descriptor edgeDescriptor, NetlistPort *srcPort, NetlistPort *dstPort) const
Definition: VHDLNetlistWriter.cc:444
ProGe::VHDLNetlistWriter::generateIndentation
static std::string generateIndentation(unsigned int level, const std::string &indentation)
Definition: VHDLNetlistWriter.cc:751
ProGe::BIT_VECTOR
@ BIT_VECTOR
Several bits.
Definition: ProGeTypes.hh:48
ProGe::VHDLNetlistWriter::parameterWidthValue
static TCEString parameterWidthValue(const NetlistPort &port)
Definition: VHDLNetlistWriter.cc:880
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
ProGe::VHDLNetlistWriter::vertex_descriptor
boost::graph_traits< Netlist >::vertex_descriptor vertex_descriptor
Definition: VHDLNetlistWriter.hh:72
ProGe::VHDLNetlistWriter::directionString
static std::string directionString(Direction direction)
Definition: VHDLNetlistWriter.cc:688
ProGe::BIDIR
@ BIDIR
Bidirectional port.
Definition: ProGeTypes.hh:55
StringTools::indent
static std::string indent(int level)
Definition: StringTools.cc:319
ProGe::StaticSignal::VCC
@ VCC
All port signals set to high.
Definition: NetlistPort.hh:51
ProGe::VHDLNetlistWriter::writeSignalAssignments
void writeSignalAssignments(const BaseNetlistBlock &block, std::ofstream &stream) const
Definition: VHDLNetlistWriter.cc:368
ProGe::BaseNetlistBlock::netlist
virtual const Netlist & netlist() const
Definition: BaseNetlistBlock.cc:348
Conversion::toString
static std::string toString(const T &source)
FileSystem::fileIsCreatable
static bool fileIsCreatable(const std::string fileName)
Definition: FileSystem.cc:123
assert
#define assert(condition)
Definition: Application.hh:86
ProGe::Netlist::parameterCount
size_t parameterCount() const
Definition: Netlist.cc:422
ProGe::VHDLNetlistWriter::groundWidth_
int groundWidth_
Width of the ground signal.
Definition: VHDLNetlistWriter.hh:122
InvalidData
Definition: Exception.hh:149
FileSystem::fileIsWritable
static bool fileIsWritable(const std::string fileName)
ProGe::VHDLNetlistWriter::isNumber
static bool isNumber(const std::string &formula)
Definition: VHDLNetlistWriter.cc:712
ProGe::VHDLNetlistWriter::indentation
std::string indentation(unsigned int level) const
Definition: VHDLNetlistWriter.cc:739
ProGe::VHDLNetlistWriter::portSignalType
static std::string portSignalType(const NetlistPort &port)
Definition: VHDLNetlistWriter.cc:798
ProGe::VHDLNetlistWriter::writePortMappings
void writePortMappings(const BaseNetlistBlock &block, std::ofstream &stream) const
Definition: VHDLNetlistWriter.cc:585
ProGe::VHDLNetlistWriter::portSignalName
static std::string portSignalName(const NetlistPort &port)
Definition: VHDLNetlistWriter.cc:769
__func__
#define __func__
Definition: Application.hh:67
GROUND_SIGNAL
const std::string GROUND_SIGNAL
Definition: VHDLNetlistWriter.cc:60
ProGe::VHDLNetlistWriter::netlistParameterPkgName
std::string netlistParameterPkgName() const
Definition: VHDLNetlistWriter.cc:128
ProGe::BIT
@ BIT
One bit.
Definition: ProGeTypes.hh:47
ProGe::VHDLNetlistWriter::usesParameterWidth
static bool usesParameterWidth(const NetlistPort &port)
Definition: VHDLNetlistWriter.cc:728
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
ProGe::OUT
@ OUT
Output port.
Definition: ProGeTypes.hh:54
ProGe::VHDLNetlistWriter::genericMapStringValue
TCEString genericMapStringValue(const TCEString &generic) const
Definition: VHDLNetlistWriter.cc:829
ProGe::VHDLNetlistWriter::writeBlock
void writeBlock(const BaseNetlistBlock &block, const std::string &dstDirectory)
Definition: VHDLNetlistWriter.cc:141
ProGe::NetlistWriter::targetNetlistBlock
const BaseNetlistBlock & targetNetlistBlock() const
Definition: NetlistWriter.cc:64
FileSystem::fileExists
static bool fileExists(const std::string fileName)
ProGe::NetlistWriter::NetlistWriter
NetlistWriter(const BaseNetlistBlock &targetBlock)
Definition: NetlistWriter.cc:46
TCEString
Definition: TCEString.hh:53
ProGe::Netlist::parameter
Parameter parameter(size_t index) const
Definition: Netlist.cc:434
ProGe::VHDLNetlistWriter::writePortDeclaration
static void writePortDeclaration(const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
Definition: VHDLNetlistWriter.cc:257
ProGe::VHDLNetlistWriter::writeComponentDeclarations
void writeComponentDeclarations(const BaseNetlistBlock &block, std::ofstream &stream) const
Definition: VHDLNetlistWriter.cc:520
ProGe::VHDLNetlistWriter::signalRange
static TCEString signalRange(int high, int low, bool allowShort=false)
Definition: VHDLNetlistWriter.cc:859
ProGe::VHDLNetlistWriter::signalAssignment
static std::string signalAssignment(const NetlistPort &dst, const NetlistPort &src)
Definition: VHDLNetlistWriter.cc:892
ProGe::BaseNetlistBlock::moduleName
const std::string & moduleName() const
Definition: BaseNetlistBlock.cc:140
ContainerTools::containsValue
static bool containsValue(const ContainerType &aContainer, const ElementType &aKey)
Conversion::toInt
static int toInt(const T &source)
IOException
Definition: Exception.hh:130
ProGe::VHDLNetlistWriter::writeNetlistParameterPackage
void writeNetlistParameterPackage(const std::string &dstDirectory) const
Definition: VHDLNetlistWriter.cc:103
ProGe::VHDLNetlistWriter::edge_descriptor
boost::graph_traits< Netlist >::edge_descriptor edge_descriptor
Definition: VHDLNetlistWriter.hh:74
ProGe::IN
@ IN
Input port.
Definition: ProGeTypes.hh:53
ProGe::VHDLNetlistWriter::writeSignalDeclarations
void writeSignalDeclarations(const BaseNetlistBlock &block, std::ofstream &stream)
Definition: VHDLNetlistWriter.cc:300