refactored shared config bits calculation
This commit is contained in:
parent
393f0b0ac3
commit
1e183e7885
|
@ -73,6 +73,14 @@ std::vector<size_t> MuxGraph::levels() const {
|
|||
return graph_levels;
|
||||
}
|
||||
|
||||
std::vector<size_t> MuxGraph::node_levels() const {
|
||||
std::vector<size_t> graph_levels;
|
||||
for (size_t lvl = 0; lvl < num_node_levels(); ++lvl) {
|
||||
graph_levels.push_back(lvl);
|
||||
}
|
||||
return graph_levels;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Public Accessors: Data query
|
||||
*************************************************/
|
||||
|
@ -261,6 +269,43 @@ std::vector<size_t> MuxGraph::branch_sizes() const {
|
|||
return branch;
|
||||
}
|
||||
|
||||
/* Find the sizes of each branch of a MUX at a given level */
|
||||
std::vector<size_t> MuxGraph::branch_sizes(const size_t& level) const {
|
||||
std::vector<size_t> branch;
|
||||
/* 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;
|
||||
}
|
||||
/* Bypass nodes that is not at the level */
|
||||
if ( level != node_levels_[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));
|
||||
|
||||
/* Nodes with the same number of incoming edges, indicate the same size of branch circuit */
|
||||
std::vector<size_t>::iterator it;
|
||||
it = std::find(branch.begin(), branch.end(), branch_size);
|
||||
/* if already exists a branch with the same size, skip updating the vector */
|
||||
if (it != branch.end()) {
|
||||
continue;
|
||||
}
|
||||
branch.push_back(branch_size);
|
||||
}
|
||||
|
||||
/* Sort the branch by size */
|
||||
std::sort(branch.begin(), branch.end());
|
||||
|
||||
return branch;
|
||||
}
|
||||
|
||||
|
||||
/* Build a subgraph from the given node
|
||||
* The strategy is very simple, we just
|
||||
* extract a 1-level graph from here
|
||||
|
|
|
@ -62,7 +62,10 @@ class MuxGraph {
|
|||
std::vector<MuxNodeId> non_input_nodes() const;
|
||||
edge_range edges() const;
|
||||
mem_range memories() const;
|
||||
/* Find the number of levels in terms of the multiplexer */
|
||||
std::vector<size_t> levels() const;
|
||||
/* Find the actual number of levels in the graph */
|
||||
std::vector<size_t> node_levels() const;
|
||||
public: /* Public accessors: Data query */
|
||||
/* Find the number of inputs in the MUX graph */
|
||||
size_t num_inputs() const;
|
||||
|
@ -95,6 +98,8 @@ class MuxGraph {
|
|||
bool is_edge_use_inv_mem(const MuxEdgeId& edge) const;
|
||||
/* Find the sizes of each branch of a MUX */
|
||||
std::vector<size_t> branch_sizes() const;
|
||||
/* Find the sizes of each branch of a MUX at a given level */
|
||||
std::vector<size_t> branch_sizes(const size_t& level) const;
|
||||
/* Generate MUX graphs for its branches */
|
||||
MuxGraph subgraph(const MuxNodeId& node) const;
|
||||
std::vector<MuxGraph> build_mux_branch_graphs() const;
|
||||
|
|
|
@ -386,3 +386,109 @@ size_t find_mux_num_config_bits(const CircuitLibrary& circuit_lib,
|
|||
|
||||
return num_config_bits;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Find the number of shared configuration bits for a CMOS multiplexer
|
||||
* Currently, all the supported CMOS multiplexers
|
||||
* do NOT require any shared configuration bits
|
||||
*************************************************/
|
||||
static
|
||||
size_t find_cmos_mux_num_shared_config_bits(const e_sram_orgz& sram_orgz_type) {
|
||||
size_t num_shared_config_bits = 0;
|
||||
|
||||
switch (sram_orgz_type) {
|
||||
case SPICE_SRAM_MEMORY_BANK:
|
||||
case SPICE_SRAM_SCAN_CHAIN:
|
||||
case SPICE_SRAM_STANDALONE:
|
||||
num_shared_config_bits = 0;
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return num_shared_config_bits;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Find the number of shared configuration bits for a ReRAM multiplexer
|
||||
*************************************************/
|
||||
static
|
||||
size_t find_rram_mux_num_shared_config_bits(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& mux_model,
|
||||
const MuxGraph& mux_graph,
|
||||
const e_sram_orgz& sram_orgz_type) {
|
||||
size_t num_shared_config_bits = 0;
|
||||
switch (sram_orgz_type) {
|
||||
case SPICE_SRAM_MEMORY_BANK: {
|
||||
/* In memory bank, the number of shared configuration bits is
|
||||
* the sum of largest branch size at each level
|
||||
*/
|
||||
for (auto lvl : mux_graph.node_levels()) {
|
||||
/* Find the maximum branch size:
|
||||
* Note that branch_sizes() returns a sorted vector
|
||||
* The last one is the maximum
|
||||
*/
|
||||
num_shared_config_bits += mux_graph.branch_sizes(lvl).back();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPICE_SRAM_SCAN_CHAIN:
|
||||
case SPICE_SRAM_STANDALONE:
|
||||
/* Currently we DO NOT SUPPORT THESE, given an invalid number */
|
||||
num_shared_config_bits = size_t(-1);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (true == circuit_lib.mux_use_local_encoder(mux_model)) {
|
||||
/* TODO: this is a to-do work for ReRAM-based multiplexers and FPGAs
|
||||
* The number of states of a local decoder only depends on how many
|
||||
* memory bits that the multiplexer will have
|
||||
* This may NOT be correct!!!
|
||||
* If local encoders are introduced, zero shared configuration bits are required
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
return num_shared_config_bits;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Find the number of shared configuration bits for
|
||||
* a routing multiplexer
|
||||
* Two cases are considered here.
|
||||
* They are placed in different branches (sub-functions)
|
||||
* in order to be easy in extending to new technology!
|
||||
*
|
||||
* Note: currently, shared configuration bits are demanded
|
||||
* by ReRAM-based multiplexers only
|
||||
*************************************************/
|
||||
size_t find_mux_num_shared_config_bits(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& mux_model,
|
||||
const MuxGraph& mux_graph,
|
||||
const e_sram_orgz& sram_orgz_type) {
|
||||
size_t num_shared_config_bits = size_t(-1);
|
||||
|
||||
switch (circuit_lib.design_tech_type(mux_model)) {
|
||||
case SPICE_MODEL_DESIGN_CMOS:
|
||||
num_shared_config_bits = find_cmos_mux_num_shared_config_bits(sram_orgz_type);
|
||||
break;
|
||||
case SPICE_MODEL_DESIGN_RRAM:
|
||||
num_shared_config_bits = find_rram_mux_num_shared_config_bits(circuit_lib, mux_model, mux_graph, sram_orgz_type);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n",
|
||||
__FILE__, __LINE__, circuit_lib.model_name(mux_model).c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return num_shared_config_bits;
|
||||
}
|
||||
|
|
|
@ -46,4 +46,9 @@ size_t find_mux_num_config_bits(const CircuitLibrary& circuit_lib,
|
|||
const MuxGraph& mux_graph,
|
||||
const e_sram_orgz& sram_orgz_type);
|
||||
|
||||
size_t find_mux_num_shared_config_bits(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& mux_model,
|
||||
const MuxGraph& mux_graph,
|
||||
const e_sram_orgz& sram_orgz_type);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -256,3 +256,82 @@ size_t find_switch_block_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
return num_conf_bits;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Find the number of shared configuration bits of a Connection Block
|
||||
********************************************************************/
|
||||
size_t find_connection_block_num_shared_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const MuxLibrary& mux_lib,
|
||||
const std::vector<t_switch_inf>& rr_switches,
|
||||
const RRGSB& rr_gsb,
|
||||
const t_rr_type& cb_type) {
|
||||
size_t num_shared_conf_bits = 0;
|
||||
|
||||
std::vector<enum e_side> cb_ipin_sides = rr_gsb.get_cb_ipin_sides(cb_type);
|
||||
for (size_t iside = 0; iside < cb_ipin_sides.size(); ++iside) {
|
||||
enum e_side cb_ipin_side = cb_ipin_sides[iside];
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
|
||||
/* Find the size of routing multiplexers driving this IPIN node */
|
||||
int mux_size = rr_gsb.get_ipin_node(cb_ipin_side, inode)->fan_in;
|
||||
/* Bypass fan_in == 1 or 0, they are not considered as routing multiplexers */
|
||||
if (2 > mux_size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the circuit model id of the routing multiplexer */
|
||||
size_t switch_index = rr_gsb.get_ipin_node(cb_ipin_side, inode)->drive_switches[DEFAULT_SWITCH_ID];
|
||||
CircuitModelId mux_model = rr_switches[switch_index].circuit_model;
|
||||
|
||||
/* Find the input size of the implementation of a routing multiplexer */
|
||||
size_t datapath_mux_size = rr_gsb.get_ipin_node(cb_ipin_side, inode)->fan_in;
|
||||
/* Get the multiplexing graph from the Mux Library */
|
||||
MuxId mux_id = mux_lib.mux_graph(mux_model, datapath_mux_size);
|
||||
const MuxGraph& mux_graph = mux_lib.mux_graph(mux_id);
|
||||
num_shared_conf_bits += find_mux_num_shared_config_bits(circuit_lib, mux_model, mux_graph, cur_sram_orgz_info->type);
|
||||
}
|
||||
}
|
||||
|
||||
return num_shared_conf_bits;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Find the number of shared configuration bits of a Switch Block
|
||||
********************************************************************/
|
||||
size_t find_switch_block_num_shared_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const MuxLibrary& mux_lib,
|
||||
const std::vector<t_switch_inf>& rr_switches,
|
||||
const RRGSB& rr_gsb) {
|
||||
size_t num_shared_conf_bits = 0;
|
||||
|
||||
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
|
||||
Side side_manager(side);
|
||||
for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) {
|
||||
if (OUT_PORT != rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||
continue;
|
||||
}
|
||||
/* Check if this node is just a passing wire */
|
||||
if (true == rr_gsb.is_sb_node_passing_wire(side_manager.get_side(), itrack)) {
|
||||
continue;
|
||||
}
|
||||
/* Check if this node has more than 2 drivers */
|
||||
if (2 > rr_gsb.get_chan_node(side_manager.get_side(), itrack)->num_drive_rr_nodes) {
|
||||
continue;
|
||||
}
|
||||
/* Get the circuit model id of the routing multiplexer */
|
||||
size_t switch_index = rr_gsb.get_chan_node(side_manager.get_side(), itrack)->drive_switches[DEFAULT_SWITCH_ID];
|
||||
CircuitModelId mux_model = rr_switches[switch_index].circuit_model;
|
||||
|
||||
/* Find the input size of the implementation of a routing multiplexer */
|
||||
size_t datapath_mux_size = rr_gsb.get_chan_node(side_manager.get_side(), itrack)->num_drive_rr_nodes;
|
||||
/* Get the multiplexing graph from the Mux Library */
|
||||
MuxId mux_id = mux_lib.mux_graph(mux_model, datapath_mux_size);
|
||||
const MuxGraph& mux_graph = mux_lib.mux_graph(mux_id);
|
||||
num_shared_conf_bits += find_mux_num_shared_config_bits(circuit_lib, mux_model, mux_graph, cur_sram_orgz_info->type);
|
||||
}
|
||||
}
|
||||
|
||||
return num_shared_conf_bits;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,4 +38,17 @@ size_t find_switch_block_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
const std::vector<t_switch_inf>& rr_switches,
|
||||
const RRGSB& rr_gsb);
|
||||
|
||||
size_t find_connection_block_num_shared_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const MuxLibrary& mux_lib,
|
||||
const std::vector<t_switch_inf>& rr_switches,
|
||||
const RRGSB& rr_gsb,
|
||||
const t_rr_type& cb_type);
|
||||
|
||||
size_t find_switch_block_num_shared_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const MuxLibrary& mux_lib,
|
||||
const std::vector<t_switch_inf>& rr_switches,
|
||||
const RRGSB& rr_gsb);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2780,7 +2780,7 @@ void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manage
|
|||
/* Count the number of configuration bits to be consumed by this Switch block */
|
||||
int num_conf_bits = find_switch_block_num_conf_bits(cur_sram_orgz_info, circuit_lib, mux_lib, rr_switches, rr_sb);
|
||||
/* Count the number of reserved configuration bits to be consumed by this Switch block */
|
||||
int num_reserved_conf_bits = count_verilog_switch_box_reserved_conf_bits(cur_sram_orgz_info, rr_sb);
|
||||
int num_reserved_conf_bits = find_switch_block_num_shared_conf_bits(cur_sram_orgz_info, circuit_lib, mux_lib, rr_switches, rr_sb);
|
||||
/* Estimate the sram_verilog_model->cnt */
|
||||
int cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info);
|
||||
RRGSB rr_gsb = rr_sb; /* IMPORTANT: this copy will be removed when the config ports are initialized when created!!! */
|
||||
|
@ -4566,7 +4566,7 @@ void print_verilog_routing_connection_box_unique_module(ModuleManager& module_ma
|
|||
/* Count the number of configuration bits to be consumed by this Switch block */
|
||||
int num_conf_bits = (int)find_connection_block_num_conf_bits(cur_sram_orgz_info, circuit_lib, mux_lib, rr_switches, rr_gsb, cb_type);
|
||||
/* Count the number of reserved configuration bits to be consumed by this Switch block */
|
||||
int num_reserved_conf_bits = count_verilog_connection_box_reserved_conf_bits(cur_sram_orgz_info, rr_gsb, cb_type);
|
||||
int num_reserved_conf_bits = (int)find_connection_block_num_shared_conf_bits(cur_sram_orgz_info, circuit_lib, mux_lib, rr_switches, rr_gsb, cb_type);
|
||||
/* Estimate the sram_verilog_model->cnt */
|
||||
int cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info);
|
||||
/* Record index */
|
||||
|
|
Loading…
Reference in New Issue