developed subgraph extraction and start refactoring mux generation
This commit is contained in:
parent
bee070d7cc
commit
69039aa742
|
@ -3,6 +3,7 @@
|
||||||
* data structures in mux_graph.h
|
* data structures in mux_graph.h
|
||||||
*************************************************/
|
*************************************************/
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -15,7 +16,7 @@
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
* Constructor
|
* Public Constructors
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
/* Create an object based on a Circuit Model which is MUX */
|
/* Create an object based on a Circuit Model which is MUX */
|
||||||
|
@ -26,6 +27,14 @@ MuxGraph::MuxGraph(const CircuitLibrary& circuit_lib,
|
||||||
build_mux_graph(circuit_lib, circuit_model, mux_size);
|
build_mux_graph(circuit_lib, circuit_model, mux_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Private Constructors
|
||||||
|
*************************************************/
|
||||||
|
/* Create an empty graph */
|
||||||
|
MuxGraph::MuxGraph() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
* Public Accessors : Aggregates
|
* Public Accessors : Aggregates
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
@ -93,7 +102,7 @@ std::vector<size_t> MuxGraph::branch_sizes() const {
|
||||||
std::vector<size_t>::iterator it;
|
std::vector<size_t>::iterator it;
|
||||||
it = std::find(branch.begin(), branch.end(), branch_size);
|
it = std::find(branch.begin(), branch.end(), branch_size);
|
||||||
/* if already exists a branch with the same size, skip updating the vector */
|
/* if already exists a branch with the same size, skip updating the vector */
|
||||||
if (it == branch.end()) {
|
if (it != branch.end()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
branch.push_back(branch_size);
|
branch.push_back(branch_size);
|
||||||
|
@ -105,6 +114,117 @@ std::vector<size_t> MuxGraph::branch_sizes() const {
|
||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build a subgraph from the given node
|
||||||
|
* The strategy is very simple, we just
|
||||||
|
* extract a 1-level graph from here
|
||||||
|
*/
|
||||||
|
MuxGraph MuxGraph::subgraph(const MuxNodeId& root_node) const {
|
||||||
|
/* Validate the node */
|
||||||
|
VTR_ASSERT_SAFE(this->valid_node_id(root_node));
|
||||||
|
|
||||||
|
/* Generate an empty graph */
|
||||||
|
MuxGraph mux_graph;
|
||||||
|
|
||||||
|
/* A map to record node-to-node mapping from origin graph to subgraph */
|
||||||
|
std::map<MuxNodeId, MuxNodeId> node2node_map;
|
||||||
|
|
||||||
|
/* A map to record edge-to-edge mapping from origin graph to subgraph */
|
||||||
|
std::map<MuxEdgeId, MuxEdgeId> edge2edge_map;
|
||||||
|
|
||||||
|
/* Add output nodes to subgraph */
|
||||||
|
MuxNodeId to_node_subgraph = mux_graph.add_node(MUX_OUTPUT_NODE);
|
||||||
|
mux_graph.node_levels_[to_node_subgraph] = 0;
|
||||||
|
/* Update the node-to-node map */
|
||||||
|
node2node_map[root_node] = to_node_subgraph;
|
||||||
|
|
||||||
|
/* Add input nodes and edges to subgraph */
|
||||||
|
size_t input_cnt = 0;
|
||||||
|
for (auto edge_origin : this->node_in_edges_[root_node]) {
|
||||||
|
VTR_ASSERT_SAFE(1 == edge_src_nodes_[edge_origin].size());
|
||||||
|
/* Add nodes */
|
||||||
|
MuxNodeId from_node_origin = this->edge_src_nodes_[edge_origin][0];
|
||||||
|
MuxNodeId from_node_subgraph = mux_graph.add_node(MUX_INPUT_NODE);
|
||||||
|
/* Configure the nodes */
|
||||||
|
mux_graph.node_levels_[from_node_subgraph] = 0;
|
||||||
|
mux_graph.node_input_ids_[from_node_subgraph] = MuxInputId(input_cnt);
|
||||||
|
input_cnt++;
|
||||||
|
/* Update the node-to-node map */
|
||||||
|
node2node_map[from_node_origin] = from_node_subgraph;
|
||||||
|
|
||||||
|
/* Add edges */
|
||||||
|
MuxEdgeId edge_subgraph = mux_graph.add_edge(node2node_map[from_node_origin], node2node_map[root_node]);
|
||||||
|
edge2edge_map[edge_origin] = edge_subgraph;
|
||||||
|
/* Configure edges */
|
||||||
|
mux_graph.edge_types_[edge_subgraph] = this->edge_types_[edge_origin];
|
||||||
|
mux_graph.edge_inv_mem_[edge_subgraph] = this->edge_inv_mem_[edge_origin];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A map to record mem-to-mem mapping from origin graph to subgraph */
|
||||||
|
std::map<MuxMemId, MuxMemId> mem2mem_map;
|
||||||
|
|
||||||
|
/* Add memory bits and configure edges */
|
||||||
|
for (auto edge_origin : this->node_in_edges_[root_node]) {
|
||||||
|
MuxMemId mem_origin = this->edge_mem_ids_[edge_origin];
|
||||||
|
/* Try to find if the mem is already in the list */
|
||||||
|
std::map<MuxMemId, MuxMemId>::iterator it = mem2mem_map.find(mem_origin);
|
||||||
|
if (it != mem2mem_map.end()) {
|
||||||
|
/* Found, we skip mem addition. But make sure we have a valid one */
|
||||||
|
VTR_ASSERT_SAFE(MuxMemId::INVALID() != mem2mem_map[mem_origin]);
|
||||||
|
/* configure the edge */
|
||||||
|
mux_graph.edge_mem_ids_[edge2edge_map[edge_origin]] = mem2mem_map[mem_origin];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Not found, we add a memory bit and record in the mem-to-mem map */
|
||||||
|
MuxMemId mem_subgraph = mux_graph.add_mem();
|
||||||
|
mem2mem_map[mem_origin] = mem_subgraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mux_graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate MUX graphs for its branches
|
||||||
|
* Similar to the branch_sizes() method,
|
||||||
|
* we search all the internal nodes and
|
||||||
|
* find out what are the input sizes of
|
||||||
|
* the branches.
|
||||||
|
* Then we extract unique subgraphs and return
|
||||||
|
*/
|
||||||
|
std::vector<MuxGraph> MuxGraph::build_mux_branch_graphs() const {
|
||||||
|
std::map<size_t, bool> branch_done; /* A map showing the status of graph generation */
|
||||||
|
|
||||||
|
std::vector<MuxGraph> branch_graphs;
|
||||||
|
|
||||||
|
/* Visit each internal nodes/output nodes and find the the number of incoming edges */
|
||||||
|
for (auto node : node_ids_ ) {
|
||||||
|
/* Bypass input nodes */
|
||||||
|
if ( (MUX_OUTPUT_NODE != node_types_[node])
|
||||||
|
&& (MUX_INTERNAL_NODE != node_types_[node]) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t branch_size = node_in_edges_[node].size();
|
||||||
|
|
||||||
|
/* make sure the branch size is valid */
|
||||||
|
VTR_ASSERT_SAFE(valid_mux_implementation_num_inputs(branch_size));
|
||||||
|
|
||||||
|
/* check if the branch have been done in sub-graph extraction! */
|
||||||
|
std::map<size_t, bool>::iterator it = branch_done.find(branch_size);
|
||||||
|
/* if it is done, we can skip */
|
||||||
|
if (it != branch_done.end()) {
|
||||||
|
VTR_ASSERT(branch_done[branch_size]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate a subgraph and push back */
|
||||||
|
branch_graphs.push_back(subgraph(node));
|
||||||
|
|
||||||
|
/* Mark it is done for this branch size */
|
||||||
|
branch_done[branch_size] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return branch_graphs;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the node id of a given input */
|
/* Get the node id of a given input */
|
||||||
MuxNodeId MuxGraph::node_id(const MuxInputId& input_id) const {
|
MuxNodeId MuxGraph::node_id(const MuxInputId& input_id) const {
|
||||||
/* Use the node_lookup to accelerate the search */
|
/* Use the node_lookup to accelerate the search */
|
||||||
|
|
|
@ -48,11 +48,14 @@ class MuxGraph {
|
||||||
typedef vtr::Range<node_iterator> node_range;
|
typedef vtr::Range<node_iterator> node_range;
|
||||||
typedef vtr::Range<edge_iterator> edge_range;
|
typedef vtr::Range<edge_iterator> edge_range;
|
||||||
typedef vtr::Range<mem_iterator> mem_range;
|
typedef vtr::Range<mem_iterator> mem_range;
|
||||||
public: /* Constructors */
|
public: /* Public Constructors */
|
||||||
/* Create an object based on a Circuit Model which is MUX */
|
/* Create an object based on a Circuit Model which is MUX */
|
||||||
MuxGraph(const CircuitLibrary& circuit_lib,
|
MuxGraph(const CircuitLibrary& circuit_lib,
|
||||||
const CircuitModelId& circuit_model,
|
const CircuitModelId& circuit_model,
|
||||||
const size_t& mux_size);
|
const size_t& mux_size);
|
||||||
|
private: /* Private Constructors*/
|
||||||
|
/* Create an empty graph */
|
||||||
|
MuxGraph();
|
||||||
public: /* Public accessors: Aggregates */
|
public: /* Public accessors: Aggregates */
|
||||||
node_range nodes() const;
|
node_range nodes() const;
|
||||||
edge_range edges() const;
|
edge_range edges() const;
|
||||||
|
@ -66,6 +69,9 @@ class MuxGraph {
|
||||||
size_t num_memory_bits() const;
|
size_t num_memory_bits() const;
|
||||||
/* Find the sizes of each branch of a MUX */
|
/* Find the sizes of each branch of a MUX */
|
||||||
std::vector<size_t> branch_sizes() const;
|
std::vector<size_t> branch_sizes() const;
|
||||||
|
/* Generate MUX graphs for its branches */
|
||||||
|
MuxGraph subgraph(const MuxNodeId& node) const;
|
||||||
|
std::vector<MuxGraph> build_mux_branch_graphs() const;
|
||||||
/* Get the node id of a given input */
|
/* Get the node id of a given input */
|
||||||
MuxNodeId node_id(const MuxInputId& input_id) const;
|
MuxNodeId node_id(const MuxInputId& input_id) const;
|
||||||
/* Decode memory bits based on an input id */
|
/* Decode memory bits based on an input id */
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
* Member functions for the class MuxLibrary
|
* Member functions for the class MuxLibrary
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Public accessors: aggregates
|
||||||
|
*************************************************/
|
||||||
|
MuxLibrary::mux_range MuxLibrary::muxes() const {
|
||||||
|
return vtr::make_range(mux_ids_.begin(), mux_ids_.end());
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
* Public accessors: data query
|
* Public accessors: data query
|
||||||
|
@ -31,6 +37,12 @@ const MuxGraph& MuxLibrary::mux_graph(const MuxId& mux_id) const {
|
||||||
return mux_graphs_[mux_id];
|
return mux_graphs_[mux_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get a mux circuit model id */
|
||||||
|
CircuitModelId MuxLibrary::mux_circuit_model(const MuxId& mux_id) const {
|
||||||
|
VTR_ASSERT_SAFE(valid_mux_id(mux_id));
|
||||||
|
return mux_circuit_models_[mux_id];
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
* Private mutators:
|
* Private mutators:
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
@ -47,6 +59,8 @@ void MuxLibrary::add_mux(const CircuitLibrary& circuit_lib, const CircuitModelId
|
||||||
mux_ids_.push_back(mux);
|
mux_ids_.push_back(mux);
|
||||||
/* Add a mux graph */
|
/* Add a mux graph */
|
||||||
mux_graphs_.push_back(MuxGraph(circuit_lib, circuit_model, mux_size));
|
mux_graphs_.push_back(MuxGraph(circuit_lib, circuit_model, mux_size));
|
||||||
|
/* Recorde mux cirucit model id */
|
||||||
|
mux_circuit_models_.push_back(circuit_model);
|
||||||
|
|
||||||
/* update mux_lookup*/
|
/* update mux_lookup*/
|
||||||
mux_lookup_[circuit_model][mux_size] = mux;
|
mux_lookup_[circuit_model][mux_size] = mux;
|
||||||
|
|
|
@ -15,10 +15,18 @@
|
||||||
#include "mux_library_fwd.h"
|
#include "mux_library_fwd.h"
|
||||||
|
|
||||||
class MuxLibrary {
|
class MuxLibrary {
|
||||||
|
public: /* Types and ranges */
|
||||||
|
typedef vtr::vector<MuxId, MuxId>::const_iterator mux_iterator;
|
||||||
|
|
||||||
|
typedef vtr::Range<mux_iterator> mux_range;
|
||||||
|
public: /* Public accessors: Aggregates */
|
||||||
|
mux_range muxes() const;
|
||||||
public: /* Public accessors */
|
public: /* Public accessors */
|
||||||
/* Get a MUX graph (read-only) */
|
/* Get a MUX graph (read-only) */
|
||||||
MuxId mux_graph(const CircuitModelId& circuit_model, const size_t& mux_size) const;
|
MuxId mux_graph(const CircuitModelId& circuit_model, const size_t& mux_size) const;
|
||||||
const MuxGraph& mux_graph(const MuxId& mux_id) const;
|
const MuxGraph& mux_graph(const MuxId& mux_id) const;
|
||||||
|
/* Get a mux circuit model id */
|
||||||
|
CircuitModelId mux_circuit_model(const MuxId& mux_id) const;
|
||||||
public: /* Public mutators */
|
public: /* Public mutators */
|
||||||
/* Add a mux to the library */
|
/* Add a mux to the library */
|
||||||
void add_mux(const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, const size_t& mux_size);
|
void add_mux(const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, const size_t& mux_size);
|
||||||
|
@ -35,6 +43,7 @@ class MuxLibrary {
|
||||||
/* MUX graph-based desription */
|
/* MUX graph-based desription */
|
||||||
vtr::vector<MuxId, MuxId> mux_ids_; /* Unique identifier for each mux graph */
|
vtr::vector<MuxId, MuxId> mux_ids_; /* Unique identifier for each mux graph */
|
||||||
vtr::vector<MuxId, MuxGraph> mux_graphs_; /* Graphs describing MUX internal structures */
|
vtr::vector<MuxId, MuxGraph> mux_graphs_; /* Graphs describing MUX internal structures */
|
||||||
|
vtr::vector<MuxId, CircuitModelId> mux_circuit_models_; /* circuit model id in circuit library */
|
||||||
|
|
||||||
/* Local encoder description */
|
/* Local encoder description */
|
||||||
//vtr::vector<MuxLocalDecoderId, Decoder> mux_local_encoders_; /* Graphs describing MUX internal structures */
|
//vtr::vector<MuxLocalDecoderId, Decoder> mux_local_encoders_; /* Graphs describing MUX internal structures */
|
||||||
|
|
|
@ -156,4 +156,3 @@ MuxLibrary convert_mux_arch_to_library(const CircuitLibrary& circuit_lib, t_llis
|
||||||
|
|
||||||
return mux_lib;
|
return mux_lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/***********************************************
|
||||||
|
* This file includes functions to generate
|
||||||
|
* Verilog submodules for multiplexers.
|
||||||
|
* including both fundamental submodules
|
||||||
|
* such as a branch in a multiplexer
|
||||||
|
* and the full multiplexer
|
||||||
|
**********************************************/
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
|
||||||
|
#include "verilog_submodule_mux.h"
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************
|
||||||
|
* Generate Verilog codes modeling an branch circuit
|
||||||
|
* for a multiplexer with the given size
|
||||||
|
**********************************************/
|
||||||
|
static
|
||||||
|
void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& circuit_model,
|
||||||
|
const MuxGraph& mux_graph) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************
|
||||||
|
* Generate Verilog codes modeling an branch circuit
|
||||||
|
* for a multiplexer with the given size
|
||||||
|
**********************************************/
|
||||||
|
void generate_verilog_mux_branch_module(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& circuit_model,
|
||||||
|
const MuxGraph& mux_graph) {
|
||||||
|
/* Multiplexers built with different technology is in different organization */
|
||||||
|
switch (circuit_lib.design_tech_type(circuit_model)) {
|
||||||
|
case SPICE_MODEL_DESIGN_CMOS:
|
||||||
|
if (true == circuit_lib.dump_structural_verilog(circuit_model)) {
|
||||||
|
generate_verilog_cmos_mux_branch_module_structural(fp, circuit_lib, circuit_model, mux_graph);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
dump_verilog_cmos_mux_one_basis_module(fp, mux_basis_subckt_name,
|
||||||
|
mux_size,
|
||||||
|
num_input_basis_subckt,
|
||||||
|
cur_spice_model,
|
||||||
|
special_basis);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SPICE_MODEL_DESIGN_RRAM:
|
||||||
|
/* If requested, we can dump structural verilog for basis module */
|
||||||
|
/*
|
||||||
|
if (true == circuit_lib.dump_structural_verilog(circuit_model)) {
|
||||||
|
dump_verilog_rram_mux_one_basis_module_structural(fp, mux_basis_subckt_name,
|
||||||
|
num_input_basis_subckt,
|
||||||
|
cur_spice_model);
|
||||||
|
} else {
|
||||||
|
dump_verilog_rram_mux_one_basis_module(fp, mux_basis_subckt_name,
|
||||||
|
num_input_basis_subckt,
|
||||||
|
cur_spice_model);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(FILE:%s,LINE[%d]) Invalid design technology of multiplexer (name: %s)\n",
|
||||||
|
__FILE__, __LINE__, circuit_lib.circuit_model_name(circuit_model));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/***********************************************
|
||||||
|
* Header file for verilog_submodule_mux.cpp
|
||||||
|
**********************************************/
|
||||||
|
|
||||||
|
#ifndef VERILOG_SUBMODULE_MUX_H
|
||||||
|
#define VERILOG_SUBMODULE_MUX_H
|
||||||
|
|
||||||
|
/* Include other header files which are dependency on the function declared below */
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "circuit_library.h"
|
||||||
|
#include "mux_graph.h"
|
||||||
|
#include "mux_library.h"
|
||||||
|
|
||||||
|
void generate_verilog_mux_branch_module(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& circuit_model,
|
||||||
|
const MuxGraph& mux_graph);
|
||||||
|
|
||||||
|
#endif
|
|
@ -39,6 +39,7 @@
|
||||||
#include "verilog_submodules.h"
|
#include "verilog_submodules.h"
|
||||||
|
|
||||||
#include "mux_utils.h"
|
#include "mux_utils.h"
|
||||||
|
#include "verilog_submodule_mux.h"
|
||||||
|
|
||||||
/***** Subroutines *****/
|
/***** Subroutines *****/
|
||||||
|
|
||||||
|
@ -2765,9 +2766,6 @@ void dump_verilog_submodule_muxes(t_sram_orgz_info* cur_sram_orgz_info,
|
||||||
/* Alloc the muxes*/
|
/* Alloc the muxes*/
|
||||||
muxes_head = stats_spice_muxes(num_switch, switches, spice, routing_arch);
|
muxes_head = stats_spice_muxes(num_switch, switches, spice, routing_arch);
|
||||||
|
|
||||||
/* TODO: this is temporary. Will be removed after code reconstruction */
|
|
||||||
MuxLibrary mux_lib = convert_mux_arch_to_library(spice->circuit_lib, muxes_head);
|
|
||||||
|
|
||||||
/* Print the muxes netlist*/
|
/* Print the muxes netlist*/
|
||||||
fp = fopen(verilog_name, "w");
|
fp = fopen(verilog_name, "w");
|
||||||
if (NULL == fp) {
|
if (NULL == fp) {
|
||||||
|
@ -2831,6 +2829,40 @@ void dump_verilog_submodule_muxes(t_sram_orgz_info* cur_sram_orgz_info,
|
||||||
temp = temp->next;
|
temp = temp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate modules into a .bak file now. Rename after it is verified */
|
||||||
|
std::string verilog_fname(my_strcat(submodule_dir, muxes_verilog_file_name));
|
||||||
|
verilog_fname += ".bak";
|
||||||
|
|
||||||
|
/* Create the file stream */
|
||||||
|
std::fstream sfp;
|
||||||
|
sfp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
|
||||||
|
|
||||||
|
/* Print out debugging information for if the file is not opened/created properly */
|
||||||
|
vpr_printf(TIO_MESSAGE_INFO,
|
||||||
|
"Creating Verilog netlist for Multiplexers (%s) ...\n",
|
||||||
|
verilog_fname.c_str());
|
||||||
|
check_file_handler(sfp);
|
||||||
|
|
||||||
|
/* TODO: this conversion is temporary. Will be removed after code reconstruction */
|
||||||
|
MuxLibrary mux_lib = convert_mux_arch_to_library(spice->circuit_lib, muxes_head);
|
||||||
|
|
||||||
|
/* Generate basis sub-circuit for unique branches shared by the multiplexers */
|
||||||
|
for (auto mux : mux_lib.muxes()) {
|
||||||
|
const MuxGraph& mux_graph = mux_lib.mux_graph(mux);
|
||||||
|
CircuitModelId mux_circuit_model = mux_lib.mux_circuit_model(mux);
|
||||||
|
/* Create a mux graph for the branch circuit */
|
||||||
|
std::vector<MuxGraph> branch_mux_graphs = mux_graph.build_mux_branch_graphs();
|
||||||
|
/* Create branch circuits, which are N:1 one-level or 2:1 tree-like MUXes */
|
||||||
|
for (auto branch_mux_graph : branch_mux_graphs) {
|
||||||
|
generate_verilog_mux_branch_module(sfp, spice->circuit_lib, mux_circuit_model, branch_mux_graph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dump MUX graph one by one */
|
||||||
|
|
||||||
|
/* Close the file steam */
|
||||||
|
sfp.close();
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* Scan-chain configuration circuit does not need any BLs/WLs!
|
* Scan-chain configuration circuit does not need any BLs/WLs!
|
||||||
* SRAM MUX does not need any reserved BL/WLs!
|
* SRAM MUX does not need any reserved BL/WLs!
|
||||||
|
|
|
@ -144,6 +144,17 @@ void dump_include_user_defined_verilog_netlists(FILE* fp,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_file_handler(const std::fstream& fp) {
|
||||||
|
/* Make sure we have a valid file handler*/
|
||||||
|
/* Print out debugging information for if the file is not opened/created properly */
|
||||||
|
if (!fp.is_open() || !fp.good()) {
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(FILE:%s,LINE[%d])Failure in create file!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dump_verilog_file_header(FILE* fp,
|
void dump_verilog_file_header(FILE* fp,
|
||||||
char* usage) {
|
char* usage) {
|
||||||
if (NULL == fp) {
|
if (NULL == fp) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef VERILOG_UTILS_H
|
#ifndef VERILOG_UTILS_H
|
||||||
#define VERILOG_UTILS_H
|
#define VERILOG_UTILS_H
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
void init_list_include_verilog_netlists(t_spice* spice);
|
void init_list_include_verilog_netlists(t_spice* spice);
|
||||||
|
|
||||||
void init_include_user_defined_verilog_netlists(t_spice spice);
|
void init_include_user_defined_verilog_netlists(t_spice spice);
|
||||||
|
@ -8,6 +10,8 @@ void init_include_user_defined_verilog_netlists(t_spice spice);
|
||||||
void dump_include_user_defined_verilog_netlists(FILE* fp,
|
void dump_include_user_defined_verilog_netlists(FILE* fp,
|
||||||
t_spice spice);
|
t_spice spice);
|
||||||
|
|
||||||
|
void check_file_handler(const std::fstream& fp);
|
||||||
|
|
||||||
void dump_verilog_file_header(FILE* fp,
|
void dump_verilog_file_header(FILE* fp,
|
||||||
char* usage);
|
char* usage);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue