BlifReader
This file provides support for parsing and emitting BLIF (Berkeley Logic Interchange Format) files, enabling their conversion to and from a LogicNetwork
data structure. It allows importing circuits into the Dynamatic framework, analyzing them, and exporting them back.
The core responsibilities include:
-
Parsing .BLIF files into a LogicNetwork
-
Computing and obtaining the topological order
-
Writing a LogicNetwork back to .BLIF format
Implementation Overview
The core data structure of this code is LogicNetwork
. This class contains the logic network represented inside a BLIF file.
The pseudo-function for parsing a BLIF file (parseBlifFile
) is the following:
LogicNetwork *BlifParser::parseBlifFile(filename) {
LogicNetwork data;
string line;
while(open(filename, line)){
str type = line.split(0);
switch(type){
".input" or ".output":
data->addIONode(type, line);
".latch":
data->addLatch(type, line);
".names":
data->addLogicGate(type, line);
".end":
break;
}
}
data->generateTopologicalOrder();
return data;
}
This function iterates over the lines of the BLIF file and it adds to the logic network the different nodes. The node type added depends on the type
variable. This variable exclusively depends on the first word of the line
variable. This follows the expected structure of BLIF files.
After filling in the logic network, the function generateTopologicalOrder
saves the topological order of the network in the vector nodesTopologicalOrder
.
The pseudo-function for exporting a logic network in a BLIF file (writeToFile
) is the following one:
void BlifWriter::writeToFile(LogicNetwork network, string filename) {
FILE file = open(filename);
file.write(".inputs");
for(i : network.getInputs()){
file.write(i);
}
file.write(".outputs");
for(i : network.getOutputs()){
file.write(i);
}
file.write(".latch");
for(i : network.getLatches()){
file.write(i);
}
for(node : network.getNodesInTopologicalOrder()){
file.write(node);
}
file.close();
}
This function iterates over the different parts of a network and it writes them in the output file.
Key Classes
There are two main classes:
LogicNetwork
: it represents the logic network expressed in a BLIF fileNode
: it represents a node in the logic network
Key Variables
LogicNetwork
std::vector<std::pair<Node *, Node *>> latches
is a vector containing pairs of the input and output nodes of a latch (register).std::unordered_map<std::string, Node *> nodes
is a map where the keys are the names of the nodes and the values are objects of theNode
class. This map contains all the nodes in the logic network.std::vector<Node *> nodesTopologicalOrder
is a vector of objects of theNode
class placed in topological order.
Node
MILPVarsSubjectGraph *gurobiVars
is a struct containing the Gurobi variables that will be used in the Buffer Placement pass.std::set<Node *> fanins
is a set containing objects of theNode
class representing the fanins of the node.std::set<Node *> fanouts
:is a set containing objects of theNode
class representing the fanouts of the node.std::string function
is a string containing the function of the node.std::string name
is a string representing the name of the node.
Key Functions
LogicNetwork Class
Node Creation and Addition
-
void addIONode(const std::string &name, const std::string &type)
: adds input/output nodes to the circuit where type specifies input or output. -
void addLatch(const std::string &inputName, const std::string &outputName)
adds latch nodes to the circuit by specifying input and output node. -
void addConstantNode(const std::vector<std::string> &nodes, const std::string &function)
adds constant nodes to the circuit with function specified in the string. -
void addLogicGate(const std::vector<std::string> &nodes, const std::string &function)
adds a logic gate to the circuit with function specified in the string. -
Node *addNode(Node *node)
adds a node to the circuit with conflict resolution (renaming if needed). -
Node *createNode(const std::string &name)
creates a node by name.
Querying the Circuit
-
std::set<Node *> getAllNodes()
returns all nodes in the circuit. -
std::set<Node *> getChannels()
returns nodes corresponding to dataflow graph channel edges. -
std::vector<std::pair<Node *, Node *>> getLatches() const
returns the list of latches. -
std::set<Node *> getPrimaryInputs()
returns all primary input nodes. -
std::set<Node *> getPrimaryOutputs()
returns all primary output nodes. -
std::vector<Node *> getNodesInTopologicalOrder()
returns nodes in topological order (precomputed). -
std::set<Node *> getInputs()
returns declared inputs of the BLIF file. -
std::set<Node *> getOutputs()
returns declared outputs of the BLIF file.
Graph Analysis
std::vector<Node *> findPath(Node *start, Node *end)
finds a path from start to end using BFS.
Node Class
void addFanin(Node *node)
adds a new fanin.void addFanout(Node *node)
adds a new fanout.static void addEdge(Node *fanin, Node *fanout)
adds an edge between fanin and fanout.static void configureLatch(Node *regInputNode, Node *regOutputNode)
configures the node as a latch based on the input and output nodes.void replaceFanin(Node *oldFanin, Node *newFanin)
replaces an existing fanin with a new one.static void connectNodes(Node *currentNode, Node *previousNode)
connects two nodes by setting the pointer of current node to the previous node.void configureIONode(const std::string &type)
configures the node based on the type of I/O node.void configureConstantNode()
configures the node as a constant node based on the functionbool isPrimaryInput()
returns if the node is a primary inputbool isPrimaryOutput()
returns if the node is a primary outputvoid convertIOToChannel()
used to merge I/O nodes. I/O is set false and isChannelEdge is set to true so that the node can be considered as a dataflow graph edge.