start refactoring instanciation of memory modules
This commit is contained in:
parent
3726e691f4
commit
b082e60c10
|
@ -332,6 +332,22 @@ std::string generate_configuration_chain_tail_name() {
|
|||
return std::string("ccff_tail");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the memory output port name of a configuration chain
|
||||
* TODO: This could be replaced as a constexpr string
|
||||
*********************************************************************/
|
||||
std::string generate_configuration_chain_data_out_name() {
|
||||
return std::string("mem_out");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the inverted memory output port name of a configuration chain
|
||||
* TODO: This could be replaced as a constexpr string
|
||||
*********************************************************************/
|
||||
std::string generate_configuration_chain_inverted_data_out_name() {
|
||||
return std::string("mem_outb");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the addr port (input) for a local decoder of a multiplexer
|
||||
* TODO: This could be replaced as a constexpr string
|
||||
|
|
|
@ -76,6 +76,10 @@ std::string generate_configuration_chain_head_name();
|
|||
|
||||
std::string generate_configuration_chain_tail_name();
|
||||
|
||||
std::string generate_configuration_chain_data_out_name();
|
||||
|
||||
std::string generate_configuration_chain_inverted_data_out_name();
|
||||
|
||||
std::string generate_mux_local_decoder_addr_port_name();
|
||||
|
||||
std::string generate_mux_local_decoder_data_port_name();
|
||||
|
|
|
@ -209,3 +209,151 @@ void add_sram_ports_to_module_manager(ModuleManager& module_manager,
|
|||
module_manager.add_port(module_id, module_port, module_port_types[iport]);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Create a port-to-port map for a CMOS memory module
|
||||
*
|
||||
* Configuration Chain
|
||||
* -------------------
|
||||
*
|
||||
* config_bus (head) config_bus (tail)
|
||||
* | ^
|
||||
* v |
|
||||
* +-------------------------------------+
|
||||
* | CMOS-based Memory Module |
|
||||
* +-------------------------------------+
|
||||
* | |
|
||||
* v v
|
||||
* sram_out sram_outb
|
||||
*
|
||||
*
|
||||
* Memory bank
|
||||
* -----------
|
||||
*
|
||||
* config_bus (BL) config_bus (WL)
|
||||
* | |
|
||||
* v v
|
||||
* +-------------------------------------+
|
||||
* | CMOS-based Memory Module |
|
||||
* +-------------------------------------+
|
||||
* | |
|
||||
* v v
|
||||
* sram_out sram_outb
|
||||
*
|
||||
**********************************************************************/
|
||||
static
|
||||
std::map<std::string, BasicPort> generate_cmos_mem_module_port2port_map(const ModuleManager& module_manager,
|
||||
const ModuleId& mem_module,
|
||||
const std::vector<BasicPort>& config_bus_ports,
|
||||
const std::vector<BasicPort>& mem_output_bus_ports,
|
||||
const e_sram_orgz& sram_orgz_type) {
|
||||
std::map<std::string, BasicPort> port2port_name_map;
|
||||
|
||||
switch (sram_orgz_type) {
|
||||
case SPICE_SRAM_STANDALONE:
|
||||
/* Nothing to do */
|
||||
break;
|
||||
case SPICE_SRAM_SCAN_CHAIN: {
|
||||
/* Link the head port of the memory module:
|
||||
* the LSB of config bus port is the head port index
|
||||
*/
|
||||
VTR_ASSERT( 1 == config_bus_ports.size() );
|
||||
BasicPort head_port(config_bus_ports[0].get_name(), config_bus_ports[0].get_lsb(), config_bus_ports[0].get_lsb());
|
||||
port2port_name_map[generate_configuration_chain_head_name()] = head_port;
|
||||
|
||||
/* Link the tail port of the memory module:
|
||||
* the MSB of config bus port is the tail port index
|
||||
*/
|
||||
BasicPort tail_port(config_bus_ports[0].get_name(), config_bus_ports[0].get_msb(), config_bus_ports[0].get_msb());
|
||||
port2port_name_map[generate_configuration_chain_tail_name()] = tail_port;
|
||||
|
||||
/* Link the SRAM output ports of the memory module */
|
||||
VTR_ASSERT( 2 == mem_output_bus_ports.size() );
|
||||
port2port_name_map[generate_configuration_chain_data_out_name()] = mem_output_bus_ports[0];
|
||||
port2port_name_map[generate_configuration_chain_inverted_data_out_name()] = mem_output_bus_ports[1];
|
||||
break;
|
||||
}
|
||||
case SPICE_SRAM_MEMORY_BANK:
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File:%s,[LINE%d])Invalid type of SRAM organization!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return port2port_name_map;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Create a port-to-port map for a ReRAM-based memory module
|
||||
* Memory bank
|
||||
* -----------
|
||||
*
|
||||
* config_bus (BL) config_bus (WL)
|
||||
* | |
|
||||
* v v
|
||||
* +-------------------------------------+
|
||||
* | ReRAM-based Memory Module |
|
||||
* +-------------------------------------+
|
||||
* | |
|
||||
* v v
|
||||
* Mem_out Mem_outb
|
||||
**********************************************************************/
|
||||
static
|
||||
std::map<std::string, BasicPort> generate_rram_mem_module_port2port_map(const ModuleManager& module_manager,
|
||||
const ModuleId& mem_module,
|
||||
const e_sram_orgz& sram_orgz_type) {
|
||||
std::map<std::string, BasicPort> port2port_name_map;
|
||||
|
||||
switch (sram_orgz_type) {
|
||||
case SPICE_SRAM_STANDALONE:
|
||||
/* Not supported */
|
||||
break;
|
||||
case SPICE_SRAM_SCAN_CHAIN:
|
||||
/* TODO: to be supported */
|
||||
break;
|
||||
case SPICE_SRAM_MEMORY_BANK:
|
||||
/* TODO: link BL/WL/Reserved Ports to the inputs of a memory module */
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File:%s,[LINE%d])Invalid type of SRAM organization!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return port2port_name_map;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Create a port-to-port map for a memory module
|
||||
* The content of the port-to-port map will depend not only
|
||||
* the design technology of the memory cells but also the
|
||||
* configuration styles of FPGA fabric.
|
||||
* Here we will branch on the design technology
|
||||
**********************************************************************/
|
||||
std::map<std::string, BasicPort> generate_mem_module_port2port_map(const ModuleManager& module_manager,
|
||||
const ModuleId& mem_module,
|
||||
const std::vector<BasicPort>& config_bus_ports,
|
||||
const std::vector<BasicPort>& mem_output_bus_ports,
|
||||
const e_spice_model_design_tech& mem_design_tech,
|
||||
const e_sram_orgz& sram_orgz_type) {
|
||||
std::map<std::string, BasicPort> port2port_name_map;
|
||||
|
||||
switch (mem_design_tech) {
|
||||
case SPICE_MODEL_DESIGN_CMOS:
|
||||
port2port_name_map = generate_cmos_mem_module_port2port_map(module_manager, mem_module, config_bus_ports, mem_output_bus_ports, sram_orgz_type);
|
||||
break;
|
||||
case SPICE_MODEL_DESIGN_RRAM:
|
||||
port2port_name_map = generate_rram_mem_module_port2port_map(module_manager, mem_module, sram_orgz_type);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File:%s,[LINE%d])Invalid type of memory design technology !\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return port2port_name_map;
|
||||
}
|
||||
|
|
|
@ -38,5 +38,12 @@ void add_sram_ports_to_module_manager(ModuleManager& module_manager,
|
|||
const e_sram_orgz sram_orgz_type,
|
||||
const size_t& port_size);
|
||||
|
||||
std::map<std::string, BasicPort> generate_mem_module_port2port_map(const ModuleManager& module_manager,
|
||||
const ModuleId& mem_module,
|
||||
const std::vector<BasicPort>& config_bus_ports,
|
||||
const std::vector<BasicPort>& mem_output_bus_ports,
|
||||
const e_spice_model_design_tech& mem_design_tech,
|
||||
const e_sram_orgz& sram_orgz_type);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -77,10 +77,14 @@ size_t find_switch_block_number_of_muxes(const RRGSB& rr_gsb) {
|
|||
if (OUT_PORT != rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||
continue;
|
||||
}
|
||||
/* Check if this node is driven by a multiplexer */
|
||||
/* 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;
|
||||
}
|
||||
/* This means we need a multiplexer, update the counter */
|
||||
num_muxes++;
|
||||
}
|
||||
|
|
|
@ -155,6 +155,8 @@ void print_verilog_memory_chain_module(ModuleManager& module_manager,
|
|||
VTR_ASSERT( 1 == sram_input_ports.size() );
|
||||
/* Get the output ports from the SRAM */
|
||||
std::vector<CircuitPortId> sram_output_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_OUTPUT, true);
|
||||
/* Should have only 1 or 2 output port */
|
||||
VTR_ASSERT( (1 == sram_output_ports.size()) || ( 2 == sram_output_ports.size()) );
|
||||
|
||||
/* Add module ports: the ports come from the SRAM modules */
|
||||
/* Add each global port */
|
||||
|
@ -180,8 +182,15 @@ void print_verilog_memory_chain_module(ModuleManager& module_manager,
|
|||
circuit_lib.port_size(sram_output_ports[0]));
|
||||
module_manager.add_port(module_id, chain_tail_port, ModuleManager::MODULE_INPUT_PORT);
|
||||
/* Add each output port: port width should match the number of memories */
|
||||
for (const auto& port : sram_output_ports) {
|
||||
BasicPort output_port(circuit_lib.port_lib_name(port), num_mems);
|
||||
for (size_t iport = 0; iport < sram_output_ports.size(); ++iport) {
|
||||
std::string port_name;
|
||||
if (0 == iport) {
|
||||
port_name = generate_configuration_chain_data_out_name();
|
||||
} else {
|
||||
VTR_ASSERT( 1 == iport);
|
||||
port_name = generate_configuration_chain_inverted_data_out_name();
|
||||
}
|
||||
BasicPort output_port(port_name, num_mems);
|
||||
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||
}
|
||||
|
||||
|
@ -202,9 +211,16 @@ void print_verilog_memory_chain_module(ModuleManager& module_manager,
|
|||
port2port_name_map[circuit_lib.port_lib_name(port)] = instance_input_port;
|
||||
}
|
||||
/* Map instance outputs [i] to SRAM module input */
|
||||
for (const auto& port : sram_output_ports) {
|
||||
BasicPort instance_output_port(circuit_lib.port_lib_name(port), i, i);
|
||||
port2port_name_map[circuit_lib.port_lib_name(port)] = instance_output_port;
|
||||
for (size_t iport = 0; iport < sram_output_ports.size(); ++iport) {
|
||||
std::string port_name;
|
||||
if (0 == iport) {
|
||||
port_name = generate_configuration_chain_data_out_name();
|
||||
} else {
|
||||
VTR_ASSERT( 1 == iport);
|
||||
port_name = generate_configuration_chain_inverted_data_out_name();
|
||||
}
|
||||
BasicPort instance_output_port(port_name, i, i);
|
||||
port2port_name_map[circuit_lib.port_lib_name(sram_output_ports[iport])] = instance_output_port;
|
||||
}
|
||||
|
||||
/* Output an instance of the module */
|
||||
|
@ -223,11 +239,11 @@ void print_verilog_memory_chain_module(ModuleManager& module_manager,
|
|||
BasicPort first_ccff_input_port(circuit_lib.port_lib_name(sram_input_ports[0]), 0, 0);
|
||||
print_verilog_wire_connection(fp, first_ccff_input_port, chain_head_port, false);
|
||||
|
||||
BasicPort last_ccff_output_port(circuit_lib.port_lib_name(sram_output_ports[0]), num_mems - 1, num_mems - 1);
|
||||
BasicPort last_ccff_output_port(generate_configuration_chain_data_out_name(), num_mems - 1, num_mems - 1);
|
||||
print_verilog_wire_connection(fp, chain_tail_port, last_ccff_output_port, false);
|
||||
|
||||
BasicPort chain_output_port(circuit_lib.port_lib_name(sram_output_ports[0]), 1, num_mems - 1);
|
||||
BasicPort chain_input_port(circuit_lib.port_lib_name(sram_input_ports[0]), 0, num_mems - 2);
|
||||
BasicPort chain_output_port(generate_configuration_chain_data_out_name(), 0, num_mems - 2);
|
||||
BasicPort chain_input_port(circuit_lib.port_lib_name(sram_input_ports[0]), 1, num_mems - 1);
|
||||
print_verilog_wire_connection(fp, chain_input_port, chain_output_port, false);
|
||||
|
||||
/* Put an end to the Verilog module */
|
||||
|
@ -433,6 +449,10 @@ void print_verilog_mux_memory_module(ModuleManager& module_manager,
|
|||
std::fstream& fp,
|
||||
const CircuitModelId& mux_model,
|
||||
const MuxGraph& mux_graph) {
|
||||
/* Find the actual number of configuration bits, based on the mux graph
|
||||
* Due to the use of local decoders inside mux, this may be
|
||||
*/
|
||||
size_t num_config_bits = find_mux_num_config_bits(circuit_lib, mux_model, mux_graph, sram_orgz_type);
|
||||
/* Multiplexers built with different technology is in different organization */
|
||||
switch (circuit_lib.design_tech_type(mux_model)) {
|
||||
case SPICE_MODEL_DESIGN_CMOS: {
|
||||
|
@ -445,10 +465,7 @@ void print_verilog_mux_memory_module(ModuleManager& module_manager,
|
|||
std::vector<CircuitModelId> sram_models = find_circuit_sram_models(circuit_lib, mux_model);
|
||||
VTR_ASSERT( 1 == sram_models.size() );
|
||||
|
||||
/* Find the number of SRAMs in the module, this is also the port width */
|
||||
size_t num_mems = mux_graph.num_memory_bits();
|
||||
|
||||
print_verilog_memory_module(module_manager, circuit_lib, sram_orgz_type, fp, module_name, sram_models[0], num_mems);
|
||||
print_verilog_memory_module(module_manager, circuit_lib, sram_orgz_type, fp, module_name, sram_models[0], num_config_bits);
|
||||
break;
|
||||
}
|
||||
case SPICE_MODEL_DESIGN_RRAM:
|
||||
|
|
|
@ -66,7 +66,8 @@ void print_verilog_switch_block_local_sram_wires(std::fstream& fp,
|
|||
const size_t& port_size) {
|
||||
size_t local_port_size = port_size;
|
||||
if (SPICE_SRAM_SCAN_CHAIN == sram_orgz_type) {
|
||||
local_port_size = find_switch_block_number_of_muxes(rr_gsb);
|
||||
/* Plus 1 for the wire size to connect to the tail of the configuration chain */
|
||||
local_port_size = find_switch_block_number_of_muxes(rr_gsb) + 1;
|
||||
}
|
||||
print_verilog_local_sram_wires(fp, circuit_lib, sram_model, sram_orgz_type, local_port_size);
|
||||
}
|
||||
|
@ -2449,9 +2450,17 @@ void print_verilog_unique_switch_box_mux(ModuleManager& module_manager,
|
|||
/* Create port-to-port map */
|
||||
std::map<std::string, BasicPort> mem_port2port_name_map;
|
||||
|
||||
/* TODO: Link input port to Switch block configuration bus */
|
||||
|
||||
/* TODO: Link output port to MUX configuration port */
|
||||
/* TODO: Make the port2port map generation more generic!!! */
|
||||
std::vector<BasicPort> config_ports;
|
||||
config_ports.push_back(BasicPort(generate_local_config_bus_port_name(), mux_instance_id - 1, mux_instance_id));
|
||||
std::vector<BasicPort> mem_output_ports;
|
||||
mem_output_ports.push_back(mux_config_port);
|
||||
mem_output_ports.push_back(mux_config_inv_port);
|
||||
mem_port2port_name_map = generate_mem_module_port2port_map(module_manager, mem_module,
|
||||
config_ports,
|
||||
mem_output_ports,
|
||||
circuit_lib.design_tech_type(mux_model),
|
||||
cur_sram_orgz_info->type);
|
||||
|
||||
/* Print an instance of the MUX Module */
|
||||
print_verilog_comment(fp, std::string("----- BEGIN Instanciation of memory cells for a routing multiplexer -----"));
|
||||
|
|
Loading…
Reference in New Issue