start adding memory circuit to Switch blocks

This commit is contained in:
tangxifan 2019-09-27 18:08:37 -06:00
parent 167778cf57
commit 1e187f3d15
9 changed files with 97 additions and 100 deletions

View File

@ -1875,7 +1875,7 @@ void CircuitLibrary::build_submodels() {
/* Build a unique list */ /* Build a unique list */
for (const auto& cand : candidates) { for (const auto& cand : candidates) {
/* Make sure the model id is unique in the list */ /* Make sure the model id is unique in the list */
if (true == is_unique_submodel(model,cand)) { if (true == is_unique_submodel(model, cand)) {
sub_models_[model].push_back(cand); sub_models_[model].push_back(cand);
} }
} }

View File

@ -453,8 +453,8 @@ class CircuitLibrary {
void link_buffer_model(const CircuitModelId& model_id); void link_buffer_model(const CircuitModelId& model_id);
void link_pass_gate_logic_model(const CircuitModelId& model_id); void link_pass_gate_logic_model(const CircuitModelId& model_id);
bool is_unique_submodel(const CircuitModelId& model_id, const CircuitModelId& submodel_id); bool is_unique_submodel(const CircuitModelId& model_id, const CircuitModelId& submodel_id);
void build_submodels();
void build_model_timing_graph(const CircuitModelId& model_id); void build_model_timing_graph(const CircuitModelId& model_id);
void build_submodels();
public: /* Public Mutators: builders */ public: /* Public Mutators: builders */
void build_model_links(); void build_model_links();
void build_timing_graphs(); void build_timing_graphs();

View File

@ -9,6 +9,7 @@
#include "sides.h" #include "sides.h"
#include "fpga_x2p_utils.h" #include "fpga_x2p_utils.h"
#include "circuit_library_utils.h"
#include "fpga_x2p_naming.h" #include "fpga_x2p_naming.h"
/************************************************ /************************************************
@ -18,8 +19,8 @@
* Case 1 : If there is NO intermediate buffer followed by, * Case 1 : If there is NO intermediate buffer followed by,
* the node name will be mux_l<node_level>_in * the node name will be mux_l<node_level>_in
***********************************************/ ***********************************************/
std::string generate_verilog_mux_node_name(const size_t& node_level, std::string generate_mux_node_name(const size_t& node_level,
const bool& add_buffer_postfix) { const bool& add_buffer_postfix) {
/* Generate the basic node_name */ /* Generate the basic node_name */
std::string node_name = "mux_l" + std::to_string(node_level) + "_in"; std::string node_name = "mux_l" + std::to_string(node_level) + "_in";
@ -38,10 +39,10 @@ std::string generate_verilog_mux_node_name(const size_t& node_level,
* 1. LUTs are named as <model_name>_mux * 1. LUTs are named as <model_name>_mux
* 2. MUXes are named as <model_name>_size<num_inputs> * 2. MUXes are named as <model_name>_size<num_inputs>
***********************************************/ ***********************************************/
std::string generate_verilog_mux_subckt_name(const CircuitLibrary& circuit_lib, std::string generate_mux_subckt_name(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const size_t& mux_size, const size_t& mux_size,
const std::string& postfix) { const std::string& postfix) {
std::string module_name = circuit_lib.model_name(circuit_model); std::string module_name = circuit_lib.model_name(circuit_model);
/* Check the model type and give different names */ /* Check the model type and give different names */
if (SPICE_MODEL_MUX == circuit_lib.model_type(circuit_model)) { if (SPICE_MODEL_MUX == circuit_lib.model_type(circuit_model)) {
@ -64,11 +65,11 @@ std::string generate_verilog_mux_subckt_name(const CircuitLibrary& circuit_lib,
* Generate the module name of a branch for a * Generate the module name of a branch for a
* multiplexer in Verilog format * multiplexer in Verilog format
***********************************************/ ***********************************************/
std::string generate_verilog_mux_branch_subckt_name(const CircuitLibrary& circuit_lib, std::string generate_mux_branch_subckt_name(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const size_t& mux_size, const size_t& mux_size,
const size_t& branch_mux_size, const size_t& branch_mux_size,
const std::string& postfix) { const std::string& postfix) {
/* If the tgate spice model of this MUX is a MUX2 standard cell, /* If the tgate spice model of this MUX is a MUX2 standard cell,
* the mux_subckt name will be the name of the standard cell * the mux_subckt name will be the name of the standard cell
*/ */
@ -79,7 +80,7 @@ std::string generate_verilog_mux_branch_subckt_name(const CircuitLibrary& circui
} }
std::string branch_postfix = postfix + "_size" + std::to_string(branch_mux_size); std::string branch_postfix = postfix + "_size" + std::to_string(branch_mux_size);
return generate_verilog_mux_subckt_name(circuit_lib, circuit_model, mux_size, branch_postfix); return generate_mux_subckt_name(circuit_lib, circuit_model, mux_size, branch_postfix);
} }
/************************************************ /************************************************
@ -473,7 +474,7 @@ std::string generate_mux_input_bus_port_name(const CircuitLibrary& circuit_lib,
const size_t& mux_size, const size_t& mux_size,
const size_t& mux_instance_id) { const size_t& mux_instance_id) {
std::string postfix = std::string("_") + std::to_string(mux_instance_id) + std::string("_inbus"); std::string postfix = std::string("_") + std::to_string(mux_instance_id) + std::string("_inbus");
return generate_verilog_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix); return generate_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix);
} }
/********************************************************************* /*********************************************************************
@ -492,7 +493,7 @@ std::string generate_mux_config_bus_port_name(const CircuitLibrary& circuit_lib,
postfix += std::string("_b"); postfix += std::string("_b");
} }
return generate_verilog_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix); return generate_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix);
} }
/********************************************************************* /*********************************************************************
@ -516,6 +517,6 @@ std::string generate_mux_sram_port_name(const CircuitLibrary& circuit_lib,
postfix += std::string("outb"); postfix += std::string("outb");
} }
return generate_verilog_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix); return generate_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix);
} }

View File

@ -13,19 +13,19 @@
#include "circuit_library.h" #include "circuit_library.h"
#include "vpr_types.h" #include "vpr_types.h"
std::string generate_verilog_mux_node_name(const size_t& node_level, std::string generate_mux_node_name(const size_t& node_level,
const bool& add_buffer_postfix); const bool& add_buffer_postfix);
std::string generate_verilog_mux_subckt_name(const CircuitLibrary& circuit_lib, std::string generate_mux_subckt_name(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const size_t& mux_size, const size_t& mux_size,
const std::string& posfix) ; const std::string& posfix) ;
std::string generate_verilog_mux_branch_subckt_name(const CircuitLibrary& circuit_lib, std::string generate_mux_branch_subckt_name(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const size_t& mux_size, const size_t& mux_size,
const size_t& branch_mux_size, const size_t& branch_mux_size,
const std::string& posfix); const std::string& posfix);
std::string generate_mux_local_decoder_subckt_name(const size_t& addr_size, std::string generate_mux_local_decoder_subckt_name(const size_t& addr_size,
const size_t& data_size); const size_t& data_size);

View File

@ -3179,6 +3179,10 @@ void config_circuit_models_sram_port_to_default_sram_model(CircuitLibrary& circu
} }
} }
} }
/* TODO: this should be done right after XML parsing!!!
* Rebuild the submodels for circuit_library, because we have created links for ports
*/
circuit_lib.build_model_links();
} }
void determine_sb_port_coordinator(t_sb cur_sb_info, int side, void determine_sb_port_coordinator(t_sb cur_sb_info, int side,

View File

@ -299,7 +299,7 @@ void print_verilog_submodule_lut(ModuleManager& module_manager,
/* Instanciate the multiplexing structure for the LUT */ /* Instanciate the multiplexing structure for the LUT */
print_verilog_comment(fp, std::string("---- BEGIN Instanciation of LUT multiplexer module -----")); print_verilog_comment(fp, std::string("---- BEGIN Instanciation of LUT multiplexer module -----"));
/* Find the name of LUT MUX: no need to provide a mux size, just give an invalid number (=-1) */ /* Find the name of LUT MUX: no need to provide a mux size, just give an invalid number (=-1) */
std::string lut_mux_module_name = generate_verilog_mux_subckt_name(circuit_lib, circuit_model, size_t(-1), std::string("")); std::string lut_mux_module_name = generate_mux_subckt_name(circuit_lib, circuit_model, size_t(-1), std::string(""));
/* Find the module id of LUT MUX in the module manager */ /* Find the module id of LUT MUX in the module manager */
ModuleId lut_mux_module_id = module_manager.find_module(lut_mux_module_name); ModuleId lut_mux_module_id = module_manager.find_module(lut_mux_module_name);
/* We must have a valid id */ /* We must have a valid id */

View File

@ -14,6 +14,7 @@
#include "module_manager.h" #include "module_manager.h"
#include "physical_types.h" #include "physical_types.h"
#include "vpr_types.h" #include "vpr_types.h"
#include "circuit_library_utils.h"
#include "mux_utils.h" #include "mux_utils.h"
/* FPGA-X2P context header files */ /* FPGA-X2P context header files */
@ -217,6 +218,7 @@ void print_verilog_memory_module(ModuleManager& module_manager,
/* TODO: Wire the memory cells into a chain, when Configuration-chain style is selected!!! */ /* TODO: Wire the memory cells into a chain, when Configuration-chain style is selected!!! */
} }
/* TODO: Add local decoders here if required */
/* Put an end to the Verilog module */ /* Put an end to the Verilog module */
print_verilog_module_end(fp, module_name); print_verilog_module_end(fp, module_name);
@ -245,21 +247,18 @@ void print_verilog_mux_memory_module(ModuleManager& module_manager,
switch (circuit_lib.design_tech_type(mux_model)) { switch (circuit_lib.design_tech_type(mux_model)) {
case SPICE_MODEL_DESIGN_CMOS: { case SPICE_MODEL_DESIGN_CMOS: {
/* Generate module name */ /* Generate module name */
std::string module_name = generate_verilog_mux_subckt_name(circuit_lib, mux_model, std::string module_name = generate_mux_subckt_name(circuit_lib, mux_model,
find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()), find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()),
std::string(verilog_mem_posfix)); std::string(verilog_mem_posfix));
/* Get the sram ports from the mux */ /* Get the sram ports from the mux */
std::vector<CircuitPortId> mux_sram_ports = circuit_lib.model_ports_by_type(mux_model, SPICE_MODEL_PORT_SRAM, true); std::vector<CircuitModelId> sram_models = get_circuit_sram_models(circuit_lib, mux_model);
VTR_ASSERT( 1 == mux_sram_ports.size() ); VTR_ASSERT( 1 == sram_models.size() );
/* Get the circuit model for the memory circuit used by the multiplexer */
CircuitModelId sram_model = circuit_lib.port_tri_state_model(mux_sram_ports[0]);
VTR_ASSERT(CircuitModelId::INVALID() != sram_model);
/* Find the number of SRAMs in the module, this is also the port width */ /* Find the number of SRAMs in the module, this is also the port width */
size_t num_mems = mux_graph.num_memory_bits(); size_t num_mems = mux_graph.num_memory_bits();
print_verilog_memory_module(module_manager, circuit_lib, fp, module_name, sram_model, num_mems); print_verilog_memory_module(module_manager, circuit_lib, fp, module_name, sram_models[0], num_mems);
break; break;
} }
case SPICE_MODEL_DESIGN_RRAM: case SPICE_MODEL_DESIGN_RRAM:

View File

@ -691,7 +691,7 @@ void generate_verilog_mux_branch_module(ModuleManager& module_manager,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const size_t& mux_size, const size_t& mux_size,
const MuxGraph& mux_graph) { const MuxGraph& mux_graph) {
std::string module_name = generate_verilog_mux_branch_subckt_name(circuit_lib, circuit_model, mux_size, mux_graph.num_inputs(), verilog_mux_basis_posfix); std::string module_name = generate_mux_branch_subckt_name(circuit_lib, circuit_model, mux_size, mux_graph.num_inputs(), verilog_mux_basis_posfix);
/* Multiplexers built with different technology is in different organization */ /* Multiplexers built with different technology is in different organization */
switch (circuit_lib.design_tech_type(circuit_model)) { switch (circuit_lib.design_tech_type(circuit_model)) {
@ -760,13 +760,13 @@ void generate_verilog_cmos_mux_module_mux2_multiplexing_structure(ModuleManager&
/* Print local wires which are the nodes in the mux graph */ /* Print local wires which are the nodes in the mux graph */
for (size_t level = 0; level < mux_graph.num_levels(); ++level) { for (size_t level = 0; level < mux_graph.num_levels(); ++level) {
/* Print the internal wires located at this level */ /* Print the internal wires located at this level */
BasicPort internal_wire_port(generate_verilog_mux_node_name(level, false), mux_graph.num_nodes_at_level(level)); BasicPort internal_wire_port(generate_mux_node_name(level, false), mux_graph.num_nodes_at_level(level));
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_port) << ";" << std::endl; fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_port) << ";" << std::endl;
/* Identify if an intermediate buffer is needed */ /* Identify if an intermediate buffer is needed */
if (false == inter_buffer_location_map[level]) { if (false == inter_buffer_location_map[level]) {
continue; continue;
} }
BasicPort internal_wire_buffered_port(generate_verilog_mux_node_name(level, true), mux_graph.num_nodes_at_level(level)); BasicPort internal_wire_buffered_port(generate_mux_node_name(level, true), mux_graph.num_nodes_at_level(level));
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_buffered_port) << std::endl; fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_buffered_port) << std::endl;
} }
print_verilog_comment(fp, std::string("---- END Internal wires of a CMOS MUX module -----")); print_verilog_comment(fp, std::string("---- END Internal wires of a CMOS MUX module -----"));
@ -832,7 +832,7 @@ void generate_verilog_cmos_mux_module_mux2_multiplexing_structure(ModuleManager&
/* Generate the port info of each input node */ /* Generate the port info of each input node */
size_t input_node_level = mux_graph.node_level(input_node); size_t input_node_level = mux_graph.node_level(input_node);
size_t input_node_index_at_level = mux_graph.node_index_at_level(input_node); size_t input_node_index_at_level = mux_graph.node_index_at_level(input_node);
BasicPort instance_input_port(generate_verilog_mux_node_name(input_node_level, inter_buffer_location_map[input_node_level]), input_node_index_at_level, input_node_index_at_level); BasicPort instance_input_port(generate_mux_node_name(input_node_level, inter_buffer_location_map[input_node_level]), input_node_index_at_level, input_node_index_at_level);
/* Link nodes to input ports for the branch module */ /* Link nodes to input ports for the branch module */
std::string module_input_port_name = circuit_lib.port_lib_name(std_cell_input_ports[&input_node - &input_nodes[0]]); std::string module_input_port_name = circuit_lib.port_lib_name(std_cell_input_ports[&input_node - &input_nodes[0]]);
@ -841,7 +841,7 @@ void generate_verilog_cmos_mux_module_mux2_multiplexing_structure(ModuleManager&
/* Build the link between output_node[0] and std_cell_output_port[0] */ /* Build the link between output_node[0] and std_cell_output_port[0] */
{ /* Create a code block to accommodate the local variables */ { /* Create a code block to accommodate the local variables */
BasicPort instance_output_port(generate_verilog_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level); BasicPort instance_output_port(generate_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level);
std::string module_output_port_name = circuit_lib.port_lib_name(std_cell_output_ports[0]); std::string module_output_port_name = circuit_lib.port_lib_name(std_cell_output_ports[0]);
port2port_name_map[module_output_port_name] = instance_output_port; port2port_name_map[module_output_port_name] = instance_output_port;
} }
@ -876,8 +876,8 @@ void generate_verilog_cmos_mux_module_mux2_multiplexing_structure(ModuleManager&
/* We must have a valid model id */ /* We must have a valid model id */
VTR_ASSERT(CircuitModelId::INVALID() != buffer_model); VTR_ASSERT(CircuitModelId::INVALID() != buffer_model);
BasicPort buffer_instance_input_port(generate_verilog_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level); BasicPort buffer_instance_input_port(generate_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level);
BasicPort buffer_instance_output_port(generate_verilog_mux_node_name(output_node_level, true), output_node_index_at_level, output_node_index_at_level); BasicPort buffer_instance_output_port(generate_mux_node_name(output_node_level, true), output_node_index_at_level, output_node_index_at_level);
print_verilog_buffer_instance(fp, module_manager, circuit_lib, module_id, buffer_model, buffer_instance_input_port, buffer_instance_output_port); print_verilog_buffer_instance(fp, module_manager, circuit_lib, module_id, buffer_model, buffer_instance_input_port, buffer_instance_output_port);
@ -934,13 +934,13 @@ void generate_verilog_cmos_mux_module_tgate_multiplexing_structure(ModuleManager
/* Print local wires which are the nodes in the mux graph */ /* Print local wires which are the nodes in the mux graph */
for (size_t level = 0; level < mux_graph.num_levels(); ++level) { for (size_t level = 0; level < mux_graph.num_levels(); ++level) {
/* Print the internal wires located at this level */ /* Print the internal wires located at this level */
BasicPort internal_wire_port(generate_verilog_mux_node_name(level, false), mux_graph.num_nodes_at_level(level)); BasicPort internal_wire_port(generate_mux_node_name(level, false), mux_graph.num_nodes_at_level(level));
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_port) << ";" << std::endl; fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_port) << ";" << std::endl;
/* Identify if an intermediate buffer is needed */ /* Identify if an intermediate buffer is needed */
if (false == inter_buffer_location_map[level]) { if (false == inter_buffer_location_map[level]) {
continue; continue;
} }
BasicPort internal_wire_buffered_port(generate_verilog_mux_node_name(level, true), mux_graph.num_nodes_at_level(level)); BasicPort internal_wire_buffered_port(generate_mux_node_name(level, true), mux_graph.num_nodes_at_level(level));
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_buffered_port) << std::endl; fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_buffered_port) << std::endl;
} }
print_verilog_comment(fp, std::string("---- END Internal wires of a CMOS MUX module -----")); print_verilog_comment(fp, std::string("---- END Internal wires of a CMOS MUX module -----"));
@ -982,7 +982,7 @@ void generate_verilog_cmos_mux_module_tgate_multiplexing_structure(ModuleManager
/* Instanciate the branch module which is a tgate-based module /* Instanciate the branch module which is a tgate-based module
*/ */
std::string branch_module_name= generate_verilog_mux_branch_subckt_name(circuit_lib, circuit_model, mux_size, branch_size, verilog_mux_basis_posfix); std::string branch_module_name= generate_mux_branch_subckt_name(circuit_lib, circuit_model, mux_size, branch_size, verilog_mux_basis_posfix);
/* Get the moduleId for the submodule */ /* Get the moduleId for the submodule */
ModuleId branch_module_id = module_manager.find_module(branch_module_name); ModuleId branch_module_id = module_manager.find_module(branch_module_name);
/* We must have one */ /* We must have one */
@ -998,13 +998,13 @@ void generate_verilog_cmos_mux_module_tgate_multiplexing_structure(ModuleManager
/* Generate the port info of each input node */ /* Generate the port info of each input node */
size_t input_node_level = mux_graph.node_level(input_node); size_t input_node_level = mux_graph.node_level(input_node);
size_t input_node_index_at_level = mux_graph.node_index_at_level(input_node); size_t input_node_index_at_level = mux_graph.node_index_at_level(input_node);
BasicPort branch_node_input_port(generate_verilog_mux_node_name(input_node_level, inter_buffer_location_map[input_node_level]), input_node_index_at_level, input_node_index_at_level); BasicPort branch_node_input_port(generate_mux_node_name(input_node_level, inter_buffer_location_map[input_node_level]), input_node_index_at_level, input_node_index_at_level);
branch_node_input_ports.push_back(branch_node_input_port); branch_node_input_ports.push_back(branch_node_input_port);
} }
/* Create the port info for the input */ /* Create the port info for the input */
/* TODO: the naming could be more flexible? */ /* TODO: the naming could be more flexible? */
BasicPort instance_input_port = generate_verilog_bus_port(branch_node_input_ports, std::string(generate_verilog_mux_node_name(output_node_level, false) + "_in")); BasicPort instance_input_port = generate_verilog_bus_port(branch_node_input_ports, std::string(generate_mux_node_name(output_node_level, false) + "_in"));
/* If we have more than 1 port in the combined instance ports , /* If we have more than 1 port in the combined instance ports ,
* output a local wire */ * output a local wire */
if (1 < combine_verilog_ports(branch_node_input_ports).size()) { if (1 < combine_verilog_ports(branch_node_input_ports).size()) {
@ -1023,7 +1023,7 @@ void generate_verilog_cmos_mux_module_tgate_multiplexing_structure(ModuleManager
port2port_name_map[module_input_port.get_name()] = instance_input_port; port2port_name_map[module_input_port.get_name()] = instance_input_port;
/* Link nodes to output ports for the branch module */ /* Link nodes to output ports for the branch module */
BasicPort instance_output_port(generate_verilog_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level); BasicPort instance_output_port(generate_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level);
ModulePortId module_output_port_id = module_manager.find_module_port(branch_module_id, "out"); ModulePortId module_output_port_id = module_manager.find_module_port(branch_module_id, "out");
VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id); VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id);
/* Get the port from module */ /* Get the port from module */
@ -1040,7 +1040,7 @@ void generate_verilog_cmos_mux_module_tgate_multiplexing_structure(ModuleManager
/* Create the port info for the input */ /* Create the port info for the input */
/* TODO: the naming could be more flexible? */ /* TODO: the naming could be more flexible? */
BasicPort instance_mem_port = generate_verilog_bus_port(branch_node_mem_ports, std::string(generate_verilog_mux_node_name(output_node_level, false) + "_mem")); BasicPort instance_mem_port = generate_verilog_bus_port(branch_node_mem_ports, std::string(generate_mux_node_name(output_node_level, false) + "_mem"));
/* If we have more than 1 port in the combined instance ports , /* If we have more than 1 port in the combined instance ports ,
* output a local wire */ * output a local wire */
if (1 < combine_verilog_ports(branch_node_mem_ports).size()) { if (1 < combine_verilog_ports(branch_node_mem_ports).size()) {
@ -1070,7 +1070,7 @@ void generate_verilog_cmos_mux_module_tgate_multiplexing_structure(ModuleManager
/* Create the port info for the input */ /* Create the port info for the input */
/* TODO: the naming could be more flexible? */ /* TODO: the naming could be more flexible? */
BasicPort instance_mem_inv_port = generate_verilog_bus_port(branch_node_mem_inv_ports, std::string(generate_verilog_mux_node_name(output_node_level, false) + "_mem_inv")); BasicPort instance_mem_inv_port = generate_verilog_bus_port(branch_node_mem_inv_ports, std::string(generate_mux_node_name(output_node_level, false) + "_mem_inv"));
/* If we have more than 1 port in the combined instance ports , /* If we have more than 1 port in the combined instance ports ,
* output a local wire */ * output a local wire */
if (1 < combine_verilog_ports(branch_node_mem_inv_ports).size()) { if (1 < combine_verilog_ports(branch_node_mem_inv_ports).size()) {
@ -1110,8 +1110,8 @@ void generate_verilog_cmos_mux_module_tgate_multiplexing_structure(ModuleManager
/* We must have a valid model id */ /* We must have a valid model id */
VTR_ASSERT(CircuitModelId::INVALID() != buffer_model); VTR_ASSERT(CircuitModelId::INVALID() != buffer_model);
BasicPort buffer_instance_input_port(generate_verilog_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level); BasicPort buffer_instance_input_port(generate_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level);
BasicPort buffer_instance_output_port(generate_verilog_mux_node_name(output_node_level, true), output_node_index_at_level, output_node_index_at_level); BasicPort buffer_instance_output_port(generate_mux_node_name(output_node_level, true), output_node_index_at_level, output_node_index_at_level);
print_verilog_buffer_instance(fp, module_manager, circuit_lib, module_id, buffer_model, buffer_instance_input_port, buffer_instance_output_port); print_verilog_buffer_instance(fp, module_manager, circuit_lib, module_id, buffer_model, buffer_instance_input_port, buffer_instance_output_port);
@ -1167,7 +1167,7 @@ void generate_verilog_cmos_mux_module_input_buffers(ModuleManager& module_manage
BasicPort instance_input_port(module_input_port.get_name(), size_t(input_index), size_t(input_index)); BasicPort instance_input_port(module_input_port.get_name(), size_t(input_index), size_t(input_index));
/* Create the port information of the MUX graph input, which is the output of buffer instance */ /* Create the port information of the MUX graph input, which is the output of buffer instance */
BasicPort instance_output_port(generate_verilog_mux_node_name(input_node_level, false), input_node_index_at_level, input_node_index_at_level); BasicPort instance_output_port(generate_mux_node_name(input_node_level, false), input_node_index_at_level, input_node_index_at_level);
/* For last input: /* For last input:
* Add a constant value to the last input, if this MUX needs a constant input * Add a constant value to the last input, if this MUX needs a constant input
@ -1261,7 +1261,7 @@ void generate_verilog_cmos_mux_module_output_buffers(ModuleManager& module_manag
VTR_ASSERT(MuxNodeId::INVALID() != mux_graph.node_id(output_node_level, output_node_index_at_level)); VTR_ASSERT(MuxNodeId::INVALID() != mux_graph.node_id(output_node_level, output_node_index_at_level));
/* Create the port information of the MUX input, which is the input of buffer instance */ /* Create the port information of the MUX input, which is the input of buffer instance */
BasicPort instance_input_port(generate_verilog_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level); BasicPort instance_input_port(generate_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level);
/* Create the port information of the module output at the given pin range, which is the output of buffer instance */ /* Create the port information of the module output at the given pin range, which is the output of buffer instance */
BasicPort instance_output_port(module_output_port.get_name(), pin, pin); BasicPort instance_output_port(module_output_port.get_name(), pin, pin);
@ -1467,13 +1467,13 @@ void generate_verilog_rram_mux_module_multiplexing_structure(ModuleManager& modu
/* Print local wires which are the nodes in the mux graph */ /* Print local wires which are the nodes in the mux graph */
for (size_t level = 0; level < mux_graph.num_levels(); ++level) { for (size_t level = 0; level < mux_graph.num_levels(); ++level) {
/* Print the internal wires located at this level */ /* Print the internal wires located at this level */
BasicPort internal_wire_port(generate_verilog_mux_node_name(level, false), mux_graph.num_nodes_at_level(level)); BasicPort internal_wire_port(generate_mux_node_name(level, false), mux_graph.num_nodes_at_level(level));
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_port) << ";" << std::endl; fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_port) << ";" << std::endl;
/* Identify if an intermediate buffer is needed */ /* Identify if an intermediate buffer is needed */
if (false == inter_buffer_location_map[level]) { if (false == inter_buffer_location_map[level]) {
continue; continue;
} }
BasicPort internal_wire_buffered_port(generate_verilog_mux_node_name(level, true), mux_graph.num_nodes_at_level(level)); BasicPort internal_wire_buffered_port(generate_mux_node_name(level, true), mux_graph.num_nodes_at_level(level));
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_buffered_port) << std::endl; fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, internal_wire_buffered_port) << std::endl;
} }
print_verilog_comment(fp, std::string("---- END Internal wires of a RRAM-based MUX module -----")); print_verilog_comment(fp, std::string("---- END Internal wires of a RRAM-based MUX module -----"));
@ -1515,7 +1515,7 @@ void generate_verilog_rram_mux_module_multiplexing_structure(ModuleManager& modu
/* Instanciate the branch module which is a tgate-based module /* Instanciate the branch module which is a tgate-based module
*/ */
std::string branch_module_name= generate_verilog_mux_branch_subckt_name(circuit_lib, circuit_model, mux_size, branch_size, verilog_mux_basis_posfix); std::string branch_module_name= generate_mux_branch_subckt_name(circuit_lib, circuit_model, mux_size, branch_size, verilog_mux_basis_posfix);
/* Get the moduleId for the submodule */ /* Get the moduleId for the submodule */
ModuleId branch_module_id = module_manager.find_module(branch_module_name); ModuleId branch_module_id = module_manager.find_module(branch_module_name);
/* We must have one */ /* We must have one */
@ -1531,13 +1531,13 @@ void generate_verilog_rram_mux_module_multiplexing_structure(ModuleManager& modu
/* Generate the port info of each input node */ /* Generate the port info of each input node */
size_t input_node_level = mux_graph.node_level(input_node); size_t input_node_level = mux_graph.node_level(input_node);
size_t input_node_index_at_level = mux_graph.node_index_at_level(input_node); size_t input_node_index_at_level = mux_graph.node_index_at_level(input_node);
BasicPort branch_node_input_port(generate_verilog_mux_node_name(input_node_level, inter_buffer_location_map[input_node_level]), input_node_index_at_level, input_node_index_at_level); BasicPort branch_node_input_port(generate_mux_node_name(input_node_level, inter_buffer_location_map[input_node_level]), input_node_index_at_level, input_node_index_at_level);
branch_node_input_ports.push_back(branch_node_input_port); branch_node_input_ports.push_back(branch_node_input_port);
} }
/* Create the port info for the input */ /* Create the port info for the input */
/* TODO: the naming could be more flexible? */ /* TODO: the naming could be more flexible? */
BasicPort instance_input_port = generate_verilog_bus_port(branch_node_input_ports, std::string(generate_verilog_mux_node_name(output_node_level, false) + "_in")); BasicPort instance_input_port = generate_verilog_bus_port(branch_node_input_ports, std::string(generate_mux_node_name(output_node_level, false) + "_in"));
/* If we have more than 1 port in the combined instance ports , /* If we have more than 1 port in the combined instance ports ,
* output a local wire */ * output a local wire */
if (1 < combine_verilog_ports(branch_node_input_ports).size()) { if (1 < combine_verilog_ports(branch_node_input_ports).size()) {
@ -1556,7 +1556,7 @@ void generate_verilog_rram_mux_module_multiplexing_structure(ModuleManager& modu
port2port_name_map[module_input_port.get_name()] = instance_input_port; port2port_name_map[module_input_port.get_name()] = instance_input_port;
/* Link nodes to output ports for the branch module */ /* Link nodes to output ports for the branch module */
BasicPort instance_output_port(generate_verilog_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level); BasicPort instance_output_port(generate_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level);
ModulePortId module_output_port_id = module_manager.find_module_port(branch_module_id, "out"); ModulePortId module_output_port_id = module_manager.find_module_port(branch_module_id, "out");
VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id); VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id);
/* Get the port from module */ /* Get the port from module */
@ -1589,7 +1589,7 @@ void generate_verilog_rram_mux_module_multiplexing_structure(ModuleManager& modu
/* Create the port info for the input */ /* Create the port info for the input */
/* TODO: the naming could be more flexible? */ /* TODO: the naming could be more flexible? */
BasicPort instance_blb_port = generate_verilog_bus_port(branch_node_blb_ports, std::string(generate_verilog_mux_node_name(output_node_level, false) + "_blb")); BasicPort instance_blb_port = generate_verilog_bus_port(branch_node_blb_ports, std::string(generate_mux_node_name(output_node_level, false) + "_blb"));
/* If we have more than 1 port in the combined instance ports , /* If we have more than 1 port in the combined instance ports ,
* output a local wire */ * output a local wire */
if (1 < combine_verilog_ports(branch_node_blb_ports).size()) { if (1 < combine_verilog_ports(branch_node_blb_ports).size()) {
@ -1630,7 +1630,7 @@ void generate_verilog_rram_mux_module_multiplexing_structure(ModuleManager& modu
/* Create the port info for the WL */ /* Create the port info for the WL */
/* TODO: the naming could be more flexible? */ /* TODO: the naming could be more flexible? */
BasicPort instance_wl_port = generate_verilog_bus_port(branch_node_wl_ports, std::string(generate_verilog_mux_node_name(output_node_level, false) + "_wl")); BasicPort instance_wl_port = generate_verilog_bus_port(branch_node_wl_ports, std::string(generate_mux_node_name(output_node_level, false) + "_wl"));
/* If we have more than 1 port in the combined instance ports , /* If we have more than 1 port in the combined instance ports ,
* output a local wire */ * output a local wire */
if (1 < combine_verilog_ports(branch_node_wl_ports).size()) { if (1 < combine_verilog_ports(branch_node_wl_ports).size()) {
@ -1669,8 +1669,8 @@ void generate_verilog_rram_mux_module_multiplexing_structure(ModuleManager& modu
/* We must have a valid model id */ /* We must have a valid model id */
VTR_ASSERT(CircuitModelId::INVALID() != buffer_model); VTR_ASSERT(CircuitModelId::INVALID() != buffer_model);
BasicPort buffer_instance_input_port(generate_verilog_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level); BasicPort buffer_instance_input_port(generate_mux_node_name(output_node_level, false), output_node_index_at_level, output_node_index_at_level);
BasicPort buffer_instance_output_port(generate_verilog_mux_node_name(output_node_level, true), output_node_index_at_level, output_node_index_at_level); BasicPort buffer_instance_output_port(generate_mux_node_name(output_node_level, true), output_node_index_at_level, output_node_index_at_level);
print_verilog_buffer_instance(fp, module_manager, circuit_lib, module_id, buffer_model, buffer_instance_input_port, buffer_instance_output_port); print_verilog_buffer_instance(fp, module_manager, circuit_lib, module_id, buffer_model, buffer_instance_input_port, buffer_instance_output_port);
@ -1825,9 +1825,9 @@ void generate_verilog_mux_module(ModuleManager& module_manager,
std::fstream& fp, std::fstream& fp,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const MuxGraph& mux_graph) { const MuxGraph& mux_graph) {
std::string module_name = generate_verilog_mux_subckt_name(circuit_lib, circuit_model, std::string module_name = generate_mux_subckt_name(circuit_lib, circuit_model,
find_mux_num_datapath_inputs(circuit_lib, circuit_model, mux_graph.num_inputs()), find_mux_num_datapath_inputs(circuit_lib, circuit_model, mux_graph.num_inputs()),
std::string("")); std::string(""));
/* Multiplexers built with different technology is in different organization */ /* Multiplexers built with different technology is in different organization */
switch (circuit_lib.design_tech_type(circuit_model)) { switch (circuit_lib.design_tech_type(circuit_model)) {

View File

@ -2348,7 +2348,7 @@ void print_verilog_unique_switch_box_mux(ModuleManager& module_manager,
const MuxGraph& mux_graph = mux_lib.mux_graph(mux_id); const MuxGraph& mux_graph = mux_lib.mux_graph(mux_id);
/* Find the module name of the multiplexer and try to find it in the module manager */ /* Find the module name of the multiplexer and try to find it in the module manager */
std::string mux_module_name = generate_verilog_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string("")); std::string mux_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(""));
ModuleId mux_module = module_manager.find_module(mux_module_name); ModuleId mux_module = module_manager.find_module(mux_module_name);
VTR_ASSERT (true == module_manager.valid_module_id(mux_module)); VTR_ASSERT (true == module_manager.valid_module_id(mux_module));
@ -2440,35 +2440,28 @@ void print_verilog_unique_switch_box_mux(ModuleManager& module_manager,
*/ */
module_manager.add_child_module(sb_module, mux_module); module_manager.add_child_module(sb_module, mux_module);
/* TODO: Instanciate memory modules */ /* Instanciate memory modules */
switch (circuit_lib.design_tech_type(mux_model)) { /* Find the name and module id of the memory module */
case SPICE_MODEL_DESIGN_CMOS: std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(verilog_mem_posfix));
/* Call the memory module defined for this SRAM-based MUX! */ ModuleId mem_module = module_manager.find_module(mem_module_name);
/* VTR_ASSERT (true == module_manager.valid_module_id(mem_module));
mem_subckt_name = generate_verilog_mux_subckt_name(verilog_model, mux_size, verilog_mem_posfix);
dump_verilog_mem_sram_submodule(fp, cur_sram_orgz_info, /* Create port-to-port map */
verilog_model, mux_size, mem_model, std::map<std::string, BasicPort> mem_port2port_name_map;
cur_num_sram, cur_num_sram + num_mux_conf_bits - 1,
is_explicit_mapping); /* Link input port to Switch block configuration bus */
*/
break; /* Link output port to MUX configuration port */
case SPICE_MODEL_DESIGN_RRAM:
/* RRAM-based MUX does not need any SRAM dumping /* Print an instance of the MUX Module */
* But we have to get the number of configuration bits required by this MUX print_verilog_comment(fp, std::string("----- BEGIN Instanciation of memory cells for a routing multiplexer -----"));
* and update the number of memory bits print_verilog_module_instance(fp, module_manager, sb_module, mem_module, mem_port2port_name_map, use_explicit_mapping);
*/ print_verilog_comment(fp, std::string("----- END Instanciation of memory cells for a routing multiplexer -----"));
/* fp << std::endl;
update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits); /* IMPORTANT: this update MUST be called after the instance outputting!!!!
update_sram_orgz_info_num_blwl(cur_sram_orgz_info, * update the module manager with the relationship between the parent and child modules
cur_bl + num_mux_conf_bits, */
cur_wl + num_mux_conf_bits); module_manager.add_child_module(sb_module, mem_module);
*/
break;
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File:%s,[LINE%d])Invalid design technology for circuit model (%s)!\n",
__FILE__, __LINE__, circuit_lib.model_name(mux_model).c_str());
}
/* Create the path of the input of multiplexer in the hierarchy /* Create the path of the input of multiplexer in the hierarchy
* TODO: this MUST be deprecated later because module manager is created to handle these problems!!! * TODO: this MUST be deprecated later because module manager is created to handle these problems!!!