OpenASIP 2.2
Loading...
Searching...
No Matches
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.
 

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

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

Definition at line 76 of file VHDLNetlistWriter.hh.

◆ vertex_descriptor

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

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) {}
NetlistWriter(const BaseNetlistBlock &targetBlock)
int groundWidth_
Width of the ground signal.

◆ ~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}
#define assert(condition)
@ OUT
Output port.
Definition ProGeTypes.hh:54
@ IN
Input port.
Definition ProGeTypes.hh:53
@ BIDIR
Bidirectional port.
Definition ProGeTypes.hh:55

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}
std::string indentation(unsigned int level) const

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}
bool startsWith(const std::string &str) const
bool endsWith(const std::string &str) const

References TCEString::endsWith(), and TCEString::startsWith().

Referenced by writePortMappings().

Here is the call graph for this function:

◆ 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}
static std::string indent(int level)

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}
const std::string & moduleName() const
const BaseNetlistBlock & targetNetlistBlock() const

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}
@ VCC
All port signals set to high.
@ BIT
One bit.
Definition ProGeTypes.hh:47

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}
static int toInt(const T &source)
static TCEString signalRange(int high, int low, bool allowShort=false)
static TCEString parameterWidthValue(const NetlistPort &port)
static bool usesParameterWidth(const NetlistPort &port)
static bool isNumber(const std::string &formula)

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}
static std::string portSignalName(const NetlistPort &port)
@ BIT_VECTOR
Several bits.
Definition ProGeTypes.hh:48

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}
#define __func__

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}
void writeNetlistParameterPackage(const std::string &dstDirectory) const
void writeBlock(const BaseNetlistBlock &block, const std::string &dstDirectory)

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}
static const std::string DIRECTORY_SEPARATOR
static bool fileIsWritable(const std::string fileName)
static bool fileIsCreatable(const std::string fileName)
static bool fileExists(const std::string fileName)
static void writePortDeclaration(const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
void writeComponentDeclarations(const BaseNetlistBlock &block, std::ofstream &stream) const
void writeSignalDeclarations(const BaseNetlistBlock &block, std::ofstream &stream)
static void writeGenericDeclaration(const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
void writePortMappings(const BaseNetlistBlock &block, std::ofstream &stream) const
std::string netlistParameterPkgName() const
void writeSignalAssignments(const BaseNetlistBlock &block, std::ofstream &stream) const

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}
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
static std::string directionString(Direction direction)

References ProGe::BIT, AssocTools::containsKey(), ProGe::NetlistPort::dataType(), ProGe::NetlistPort::direction(), directionString(), indentation(), isNumber(), ProGe::BaseNetlistBlock::isVirtual(), ProGe::BaseNetlistBlock::moduleName(), ProGe::NetlistPort::name(), ProGe::Parameter::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}
static std::string toString(const T &source)
static std::string signalAssignment(const NetlistPort &dst, const NetlistPort &src)

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}
const std::string PARAM_STRING
static std::string generateIndentation(unsigned int level, const std::string &indentation)

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(), DefaultDecoderGenerator::writeInstructionDecoder(), and DefaultICGenerator::writeInterconnectionNetwork().

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}
virtual const Netlist & netlist() const
size_t parameterCount() const
Definition Netlist.cc:422
Parameter parameter(size_t index) const
Definition Netlist.cc:434
const TCEString & name() const
Definition Parameter.cc:133

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(), DefaultDecoderGenerator::writeInstructionDecoder(), and DefaultICGenerator::writeInterconnectionNetwork().

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}
boost::graph_traits< Netlist >::edge_descriptor edge_descriptor
boost::graph_traits< Netlist >::vertex_descriptor vertex_descriptor
TCEString genericMapStringValue(const TCEString &generic) const

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::NetlistPort::name(), ProGe::Parameter::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}
const std::string GROUND_SIGNAL
static bool containsValue(const ContainerType &aContainer, const ElementType &aKey)
void writeConnection(const BaseNetlistBlock &block, std::ofstream &stream, edge_descriptor edgeDescriptor, NetlistPort *srcPort, NetlistPort *dstPort) const

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}
static std::string portSignalType(const NetlistPort &port)

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: