start refactoring instanciation of memory modules

This commit is contained in:
tangxifan 2019-09-29 18:20:56 -06:00
parent 3726e691f4
commit b082e60c10
7 changed files with 222 additions and 17 deletions

View File

@ -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

View File

@ -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();

View File

@ -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;
}

View File

@ -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

View File

@ -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++;
}

View File

@ -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:

View File

@ -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 -----"));