refactoring the configuration bus Verilog generation for MUXes
This commit is contained in:
parent
091bbd4d9c
commit
ead014e7d8
|
@ -471,11 +471,12 @@ class CircuitLibrary {
|
||||||
public: /* Internal mutators: build fast look-ups */
|
public: /* Internal mutators: build fast look-ups */
|
||||||
void build_model_lookup();
|
void build_model_lookup();
|
||||||
void build_model_port_lookup();
|
void build_model_port_lookup();
|
||||||
private: /* Internal invalidators/validators */
|
public: /* Public invalidators/validators */
|
||||||
/* Validators */
|
|
||||||
bool valid_model_id(const CircuitModelId& model_id) const;
|
bool valid_model_id(const CircuitModelId& model_id) const;
|
||||||
bool valid_circuit_port_id(const CircuitPortId& circuit_port_id) const;
|
bool valid_circuit_port_id(const CircuitPortId& circuit_port_id) const;
|
||||||
bool valid_circuit_pin_id(const CircuitPortId& circuit_port_id, const size_t& pin_id) const;
|
bool valid_circuit_pin_id(const CircuitPortId& circuit_port_id, const size_t& pin_id) const;
|
||||||
|
private: /* Internal invalidators/validators */
|
||||||
|
/* Validators */
|
||||||
bool valid_edge_id(const CircuitEdgeId& edge_id) const;
|
bool valid_edge_id(const CircuitEdgeId& edge_id) const;
|
||||||
bool valid_delay_type(const CircuitModelId& model_id, const enum spice_model_delay_type& delay_type) const;
|
bool valid_delay_type(const CircuitModelId& model_id, const enum spice_model_delay_type& delay_type) const;
|
||||||
bool valid_circuit_edge_id(const CircuitEdgeId& circuit_edge_id) const;
|
bool valid_circuit_edge_id(const CircuitEdgeId& circuit_edge_id) const;
|
||||||
|
|
|
@ -365,7 +365,7 @@ size_t find_mux_num_config_bits(const CircuitLibrary& circuit_lib,
|
||||||
|
|
||||||
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:
|
||||||
num_config_bits = find_rram_mux_num_config_bits(circuit_lib, mux_model, mux_graph, sram_orgz_type);
|
num_config_bits = find_cmos_mux_num_config_bits(circuit_lib, mux_model, mux_graph, sram_orgz_type);
|
||||||
break;
|
break;
|
||||||
case SPICE_MODEL_DESIGN_RRAM:
|
case SPICE_MODEL_DESIGN_RRAM:
|
||||||
num_config_bits = find_rram_mux_num_config_bits(circuit_lib, mux_model, mux_graph, sram_orgz_type);
|
num_config_bits = find_rram_mux_num_config_bits(circuit_lib, mux_model, mux_graph, sram_orgz_type);
|
||||||
|
|
|
@ -475,3 +475,47 @@ std::string generate_mux_input_bus_port_name(const CircuitLibrary& circuit_lib,
|
||||||
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_verilog_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Generate the name of a bus port which is wired to the configuration
|
||||||
|
* ports of a routing multiplexer
|
||||||
|
* This port is supposed to be used locally inside a Verilog/SPICE module
|
||||||
|
*********************************************************************/
|
||||||
|
std::string generate_mux_config_bus_port_name(const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& mux_model,
|
||||||
|
const size_t& mux_size,
|
||||||
|
const size_t& bus_id,
|
||||||
|
const bool& inverted) {
|
||||||
|
std::string postfix = std::string("_configbus") + std::to_string(bus_id);
|
||||||
|
/* Add a bar to the end of the name for inverted bus ports */
|
||||||
|
if (true == inverted) {
|
||||||
|
postfix += std::string("_b");
|
||||||
|
}
|
||||||
|
|
||||||
|
return generate_verilog_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Generate the port name for a SRAM port of a routing multiplexer
|
||||||
|
* This name is used for local wires that connecting SRAM ports
|
||||||
|
* of routing multiplexers inside a Verilog/SPICE module
|
||||||
|
* Note that the SRAM ports of routing multiplexers share the same naming
|
||||||
|
* convention regardless of their configuration style
|
||||||
|
*********************************************************************/
|
||||||
|
std::string generate_mux_sram_port_name(const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& mux_model,
|
||||||
|
const size_t& mux_size,
|
||||||
|
const size_t& mux_instance_id,
|
||||||
|
const e_spice_model_port_type& port_type) {
|
||||||
|
std::string postfix = std::string("_") + std::to_string(mux_instance_id) + std::string("_");
|
||||||
|
|
||||||
|
if (SPICE_MODEL_PORT_INPUT == port_type) {
|
||||||
|
postfix += std::string("out");
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT( SPICE_MODEL_PORT_OUTPUT == port_type );
|
||||||
|
postfix += std::string("outb");
|
||||||
|
}
|
||||||
|
|
||||||
|
return generate_verilog_mux_subckt_name(circuit_lib, mux_model, mux_size, postfix);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,4 +87,16 @@ 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 generate_mux_config_bus_port_name(const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& mux_model,
|
||||||
|
const size_t& mux_size,
|
||||||
|
const size_t& bus_id,
|
||||||
|
const bool& inverted);
|
||||||
|
|
||||||
|
std::string generate_mux_sram_port_name(const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& mux_model,
|
||||||
|
const size_t& mux_size,
|
||||||
|
const size_t& mux_instance_id,
|
||||||
|
const e_spice_model_port_type& port_type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
* | |
|
* | |
|
||||||
* v v
|
* v v
|
||||||
* +------------------------------------+
|
* +------------------------------------+
|
||||||
* | Multiplexer Configuration port |
|
* | Memory Module Configuration port |
|
||||||
* +------------------------------------+
|
* +------------------------------------+
|
||||||
* | | |
|
* | | |
|
||||||
* v v v
|
* v v v
|
||||||
|
@ -133,7 +133,14 @@ void print_verilog_memory_module(ModuleManager& module_manager,
|
||||||
BasicPort global_port(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
|
BasicPort global_port(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
|
||||||
module_manager.add_port(module_id, global_port, ModuleManager::MODULE_GLOBAL_PORT);
|
module_manager.add_port(module_id, global_port, ModuleManager::MODULE_GLOBAL_PORT);
|
||||||
}
|
}
|
||||||
/* Add each input port: port width should match the number of memories */
|
/* TODO: when Configuration-chain style is selected, the port map should be different!
|
||||||
|
* It should have only a head as input, a tail as output and other regular output ports
|
||||||
|
*/
|
||||||
|
/* Add each input port: port width should match the number of memories
|
||||||
|
* The number of inputs will not match the number of memory bits of a multiplexer
|
||||||
|
* when local decoders are used.
|
||||||
|
* It should be calculated by the decoder builders!
|
||||||
|
*/
|
||||||
for (const auto& port : sram_input_ports) {
|
for (const auto& port : sram_input_ports) {
|
||||||
BasicPort input_port(circuit_lib.port_lib_name(port), num_mems);
|
BasicPort input_port(circuit_lib.port_lib_name(port), num_mems);
|
||||||
module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
|
module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
@ -206,8 +213,11 @@ void print_verilog_memory_module(ModuleManager& module_manager,
|
||||||
* update the module manager with the relationship between the parent and child modules
|
* update the module manager with the relationship between the parent and child modules
|
||||||
*/
|
*/
|
||||||
module_manager.add_child_module(module_id, sram_module_id);
|
module_manager.add_child_module(module_id, sram_module_id);
|
||||||
|
|
||||||
|
/* TODO: Wire the memory cells into a chain, when Configuration-chain style is selected!!! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2376,7 +2376,7 @@ void print_verilog_unique_switch_box_mux(ModuleManager& module_manager,
|
||||||
/* Generate input ports that are wired to the input bus of the routing multiplexer */
|
/* Generate input ports that are wired to the input bus of the routing multiplexer */
|
||||||
std::vector<BasicPort> mux_input_ports = generate_switch_block_input_ports(rr_sb, drive_rr_nodes);
|
std::vector<BasicPort> mux_input_ports = generate_switch_block_input_ports(rr_sb, drive_rr_nodes);
|
||||||
/* Connect input ports to bus */
|
/* Connect input ports to bus */
|
||||||
fp << generate_verilog_local_wire(inbus_port, mux_input_ports);
|
fp << generate_verilog_local_wire(inbus_port, mux_input_ports) << std::endl;
|
||||||
|
|
||||||
/* Find the number of reserved configuration bits for the routing multiplexer */
|
/* Find the number of reserved configuration bits for the routing multiplexer */
|
||||||
size_t mux_num_reserved_config_bits = find_mux_num_reserved_config_bits(circuit_lib, mux_model, mux_graph);
|
size_t mux_num_reserved_config_bits = find_mux_num_reserved_config_bits(circuit_lib, mux_model, mux_graph);
|
||||||
|
@ -2384,11 +2384,10 @@ void print_verilog_unique_switch_box_mux(ModuleManager& module_manager,
|
||||||
/* Find the number of configuration bits for the routing multiplexer */
|
/* Find the number of configuration bits for the routing multiplexer */
|
||||||
size_t mux_num_config_bits = find_mux_num_config_bits(circuit_lib, mux_model, mux_graph, cur_sram_orgz_info->type);
|
size_t mux_num_config_bits = find_mux_num_config_bits(circuit_lib, mux_model, mux_graph, cur_sram_orgz_info->type);
|
||||||
|
|
||||||
/* Print the configuration port bus */
|
/* Print the configuration bus for the routing multiplexers */
|
||||||
/* TODO: Print the configuration bus for the routing multiplexers
|
print_verilog_mux_config_bus(fp, circuit_lib, mux_model, cur_sram_orgz_info->type,
|
||||||
dump_verilog_mux_config_bus(fp, verilog_model, cur_sram_orgz_info,
|
datapath_mux_size, mux_instance_id,
|
||||||
mux_size, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits);
|
mux_num_reserved_config_bits, mux_num_config_bits);
|
||||||
*/
|
|
||||||
|
|
||||||
/* Dump ports visible only during formal verification */
|
/* Dump ports visible only during formal verification */
|
||||||
fp << std::endl;
|
fp << std::endl;
|
||||||
|
|
|
@ -769,3 +769,301 @@ void print_verilog_local_sram_wires(std::fstream& fp,
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Print a number of bus ports which are wired to the configuration
|
||||||
|
* ports of a CMOS (SRAM-based) routing multiplexer
|
||||||
|
* This port is supposed to be used locally inside a Verilog/SPICE module
|
||||||
|
*
|
||||||
|
* For standalone configuration style:
|
||||||
|
* ------------------------------------
|
||||||
|
* No bus needed
|
||||||
|
*
|
||||||
|
* For configuration-chain configuration style:
|
||||||
|
* --------------------------------------------
|
||||||
|
*
|
||||||
|
* Module Port
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* bus_port --------+----------------+----> ...
|
||||||
|
* | |
|
||||||
|
* sram_outputs v v
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | Memory | | Memory |
|
||||||
|
* | Module[0] | | Module[1] | ...
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | Routing | | Routing |
|
||||||
|
* | MUX [0] | | MUX[1] | ...
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
*
|
||||||
|
* For memory-bank configuration style:
|
||||||
|
* ------------------------------------
|
||||||
|
*
|
||||||
|
* Module Port
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* bus_port --------+----------------+----> ...
|
||||||
|
* | |
|
||||||
|
* bl/wl/../sram_ports v v
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | Memory | | Memory |
|
||||||
|
* | Module[0] | | Module[1] | ...
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | Routing | | Routing |
|
||||||
|
* | MUX [0] | | MUX[1] | ...
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
*
|
||||||
|
*********************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_cmos_mux_config_bus(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& mux_model,
|
||||||
|
const e_sram_orgz& sram_orgz_type,
|
||||||
|
const size_t& mux_size,
|
||||||
|
const size_t& mux_instance_id,
|
||||||
|
const size_t& num_conf_bits) {
|
||||||
|
/* Make sure we have a valid file handler*/
|
||||||
|
check_file_handler(fp);
|
||||||
|
|
||||||
|
switch(sram_orgz_type) {
|
||||||
|
case SPICE_SRAM_STANDALONE:
|
||||||
|
/* Not need for configuration bus
|
||||||
|
* The configuration ports of SRAM are directly wired to the ports of modules
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN: {
|
||||||
|
/* To support chain-like configuration protocol, two configuration buses should be outputted
|
||||||
|
* One for the regular SRAM ports of a routing multiplexer
|
||||||
|
* The other for the inverted SRAM ports of a routing multiplexer
|
||||||
|
*/
|
||||||
|
BasicPort config_port(generate_mux_sram_port_name(circuit_lib, mux_model, mux_size, mux_instance_id, SPICE_MODEL_PORT_INPUT),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, config_port) << ";" << std::endl;
|
||||||
|
BasicPort inverted_config_port(generate_mux_sram_port_name(circuit_lib, mux_model, mux_size, mux_instance_id, SPICE_MODEL_PORT_OUTPUT),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, inverted_config_port) << ";" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPICE_SRAM_MEMORY_BANK: {
|
||||||
|
/* To support memory-bank configuration, SRAM outputs are supposed to be exposed to the upper level as buses
|
||||||
|
* In addition, the BL/WL ports should be grouped and be exposed to the upper level as buses
|
||||||
|
*/
|
||||||
|
/* Print configuration bus to group BL/WLs */
|
||||||
|
BasicPort bl_bus(generate_mux_config_bus_port_name(circuit_lib, mux_model, mux_size, 0, false),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, bl_bus) << ";" << std::endl;
|
||||||
|
BasicPort wl_bus(generate_mux_config_bus_port_name(circuit_lib, mux_model, mux_size, 1, false),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, wl_bus) << ";" << std::endl;
|
||||||
|
|
||||||
|
/* Print bus to group SRAM outputs, this is to interface memory cells to routing multiplexers */
|
||||||
|
BasicPort sram_output_bus(generate_mux_sram_port_name(circuit_lib, mux_model, mux_size, mux_instance_id, SPICE_MODEL_PORT_INPUT),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, sram_output_bus) << ";" << std::endl;
|
||||||
|
BasicPort inverted_sram_output_bus(generate_mux_sram_port_name(circuit_lib, mux_model, mux_size, mux_instance_id, SPICE_MODEL_PORT_OUTPUT),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, inverted_sram_output_bus) << ";" << std::endl;
|
||||||
|
|
||||||
|
/* TODO: This should be handled as a function */
|
||||||
|
/* Get the SRAM model of the mux_model */
|
||||||
|
std::vector<CircuitPortId> sram_ports = circuit_lib.model_ports_by_type(mux_model, SPICE_MODEL_PORT_SRAM);
|
||||||
|
/* This may be too strict for a multiplexer, what if a routing multiplexer has a mode select port? */
|
||||||
|
VTR_ASSERT( 1 == sram_ports.size() );
|
||||||
|
CircuitModelId sram_model = circuit_lib.port_tri_state_model(sram_ports[0]);
|
||||||
|
VTR_ASSERT( true == circuit_lib.valid_model_id(sram_model) );
|
||||||
|
std::vector<CircuitPortId> blb_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_BLB);
|
||||||
|
std::vector<CircuitPortId> wlb_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_WLB);
|
||||||
|
|
||||||
|
/* Connect SRAM BL/WLs to bus */
|
||||||
|
BasicPort mux_bl_wire(generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_BL),
|
||||||
|
num_conf_bits);
|
||||||
|
print_verilog_wire_connection(fp, bl_bus, mux_bl_wire, false);
|
||||||
|
BasicPort mux_wl_wire(generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_WL),
|
||||||
|
num_conf_bits);
|
||||||
|
print_verilog_wire_connection(fp, wl_bus, mux_wl_wire, false);
|
||||||
|
|
||||||
|
/* Print configuration bus to group BLBs, if the ports are available in SRAM models */
|
||||||
|
if (0 < blb_ports.size()) {
|
||||||
|
BasicPort blb_bus(generate_mux_config_bus_port_name(circuit_lib, mux_model, mux_size, 0, true),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, blb_bus) << ";" << std::endl;
|
||||||
|
/* Connect SRAM BLBs to bus */
|
||||||
|
BasicPort mux_blb_wire(generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_BLB),
|
||||||
|
num_conf_bits);
|
||||||
|
print_verilog_wire_connection(fp, blb_bus, mux_blb_wire, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print configuration bus to group WLBs, if the ports are available in SRAM models */
|
||||||
|
if (0 < wlb_ports.size()) {
|
||||||
|
BasicPort wlb_bus(generate_mux_config_bus_port_name(circuit_lib, mux_model, mux_size, 1, true),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, wlb_bus) << ";" << std::endl;
|
||||||
|
/* Connect SRAM WLBs to bus */
|
||||||
|
BasicPort mux_wlb_wire(generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_WLB),
|
||||||
|
num_conf_bits);
|
||||||
|
print_verilog_wire_connection(fp, wlb_bus, mux_wlb_wire, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid SRAM organization!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Print a number of bus ports which are wired to the configuration
|
||||||
|
* ports of a ReRAM-based routing multiplexer
|
||||||
|
* This port is supposed to be used locally inside a Verilog/SPICE module
|
||||||
|
*
|
||||||
|
* Currently support:
|
||||||
|
* For memory-bank configuration style:
|
||||||
|
* ------------------------------------
|
||||||
|
* Different than CMOS routing multiplexers, ReRAM multiplexers require
|
||||||
|
* reserved BL/WLs to be grouped in buses
|
||||||
|
*
|
||||||
|
* Module Port
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* regular/reserved bus_port --+----------------+----> ...
|
||||||
|
* | |
|
||||||
|
* bl/wl/../sram_ports v v
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | Memory | | Memory |
|
||||||
|
* | Module[0] | | Module[1] | ...
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
* | Routing | | Routing |
|
||||||
|
* | MUX [0] | | MUX[1] | ...
|
||||||
|
* +-----------+ +-----------+
|
||||||
|
*
|
||||||
|
*********************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_rram_mux_config_bus(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& mux_model,
|
||||||
|
const e_sram_orgz& sram_orgz_type,
|
||||||
|
const size_t& mux_size,
|
||||||
|
const size_t& mux_instance_id,
|
||||||
|
const size_t& num_reserved_conf_bits,
|
||||||
|
const size_t& num_conf_bits) {
|
||||||
|
/* Make sure we have a valid file handler*/
|
||||||
|
check_file_handler(fp);
|
||||||
|
|
||||||
|
switch(sram_orgz_type) {
|
||||||
|
case SPICE_SRAM_STANDALONE:
|
||||||
|
/* Not need for configuration bus
|
||||||
|
* The configuration ports of SRAM are directly wired to the ports of modules
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN: {
|
||||||
|
/* Not supported yet.
|
||||||
|
* Configuration chain may be only applied to ReRAM-based multiplexers with local decoders
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPICE_SRAM_MEMORY_BANK: {
|
||||||
|
/* This is currently most used in ReRAM FPGAs */
|
||||||
|
/* Print configuration bus to group reserved BL/WLs */
|
||||||
|
BasicPort reserved_bl_bus(generate_reserved_sram_port_name(SPICE_MODEL_PORT_BL),
|
||||||
|
num_reserved_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, reserved_bl_bus) << ";" << std::endl;
|
||||||
|
BasicPort reserved_wl_bus(generate_reserved_sram_port_name(SPICE_MODEL_PORT_WL),
|
||||||
|
num_reserved_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, reserved_wl_bus) << ";" << std::endl;
|
||||||
|
|
||||||
|
/* Print configuration bus to group BL/WLs */
|
||||||
|
BasicPort bl_bus(generate_mux_config_bus_port_name(circuit_lib, mux_model, mux_size, 0, false),
|
||||||
|
num_conf_bits + num_reserved_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, bl_bus) << ";" << std::endl;
|
||||||
|
BasicPort wl_bus(generate_mux_config_bus_port_name(circuit_lib, mux_model, mux_size, 1, false),
|
||||||
|
num_conf_bits + num_reserved_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, wl_bus) << ";" << std::endl;
|
||||||
|
|
||||||
|
/* Print bus to group SRAM outputs, this is to interface memory cells to routing multiplexers */
|
||||||
|
BasicPort sram_output_bus(generate_mux_sram_port_name(circuit_lib, mux_model, mux_size, mux_instance_id, SPICE_MODEL_PORT_INPUT),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, sram_output_bus) << ";" << std::endl;
|
||||||
|
BasicPort inverted_sram_output_bus(generate_mux_sram_port_name(circuit_lib, mux_model, mux_size, mux_instance_id, SPICE_MODEL_PORT_OUTPUT),
|
||||||
|
num_conf_bits);
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, inverted_sram_output_bus) << ";" << std::endl;
|
||||||
|
|
||||||
|
/* TODO: This should be handled as a function */
|
||||||
|
/* Get the SRAM model of the mux_model */
|
||||||
|
std::vector<CircuitPortId> sram_ports = circuit_lib.model_ports_by_type(mux_model, SPICE_MODEL_PORT_SRAM);
|
||||||
|
/* This may be too strict for a multiplexer, what if a routing multiplexer has a mode select port? */
|
||||||
|
VTR_ASSERT( 1 == sram_ports.size() );
|
||||||
|
CircuitModelId sram_model = circuit_lib.port_tri_state_model(sram_ports[0]);
|
||||||
|
VTR_ASSERT( true == circuit_lib.valid_model_id(sram_model) );
|
||||||
|
|
||||||
|
/* Wire the reserved configuration bits to part of bl/wl buses */
|
||||||
|
BasicPort bl_bus_reserved_bits(bl_bus.get_name(), num_reserved_conf_bits);
|
||||||
|
print_verilog_wire_connection(fp, bl_bus_reserved_bits, reserved_bl_bus, false);
|
||||||
|
BasicPort wl_bus_reserved_bits(wl_bus.get_name(), num_reserved_conf_bits);
|
||||||
|
print_verilog_wire_connection(fp, wl_bus_reserved_bits, reserved_wl_bus, false);
|
||||||
|
|
||||||
|
/* Connect SRAM BL/WLs to bus */
|
||||||
|
BasicPort mux_bl_wire(generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_BL),
|
||||||
|
num_conf_bits);
|
||||||
|
BasicPort bl_bus_regular_bits(bl_bus.get_name(), num_reserved_conf_bits, num_reserved_conf_bits + num_conf_bits - 1);
|
||||||
|
print_verilog_wire_connection(fp, bl_bus_regular_bits, mux_bl_wire, false);
|
||||||
|
BasicPort mux_wl_wire(generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_WL),
|
||||||
|
num_conf_bits);
|
||||||
|
BasicPort wl_bus_regular_bits(wl_bus.get_name(), num_reserved_conf_bits, num_reserved_conf_bits + num_conf_bits - 1);
|
||||||
|
print_verilog_wire_connection(fp, wl_bus_regular_bits, mux_wl_wire, false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid SRAM organization!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Print a number of bus ports which are wired to the configuration
|
||||||
|
* ports of a routing multiplexer
|
||||||
|
*********************************************************************/
|
||||||
|
void print_verilog_mux_config_bus(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& mux_model,
|
||||||
|
const e_sram_orgz& sram_orgz_type,
|
||||||
|
const size_t& mux_size,
|
||||||
|
const size_t& mux_instance_id,
|
||||||
|
const size_t& num_reserved_conf_bits,
|
||||||
|
const size_t& num_conf_bits) {
|
||||||
|
/* Depend on the design technology of this MUX:
|
||||||
|
* bus connections are different
|
||||||
|
* SRAM MUX: bus is connected to the output ports of SRAM
|
||||||
|
* RRAM MUX: bus is connected to the BL/WL of MUX
|
||||||
|
* TODO: Maybe things will become even more complicated,
|
||||||
|
* the bus connections may depend on the type of configuration circuit...
|
||||||
|
* Currently, this is fine.
|
||||||
|
*/
|
||||||
|
switch (circuit_lib.design_tech_type(mux_model)) {
|
||||||
|
case SPICE_MODEL_DESIGN_CMOS:
|
||||||
|
print_verilog_cmos_mux_config_bus(fp, circuit_lib, mux_model, sram_orgz_type, mux_size, mux_instance_id, num_conf_bits);
|
||||||
|
break;
|
||||||
|
case SPICE_MODEL_DESIGN_RRAM:
|
||||||
|
print_verilog_rram_mux_config_bus(fp, circuit_lib, mux_model, sram_orgz_type, mux_size, mux_instance_id, num_reserved_conf_bits, num_conf_bits);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid design technology for routing multiplexer!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,4 +90,14 @@ void print_verilog_local_sram_wires(std::fstream& fp,
|
||||||
const e_sram_orgz sram_orgz_type,
|
const e_sram_orgz sram_orgz_type,
|
||||||
const size_t& port_size);
|
const size_t& port_size);
|
||||||
|
|
||||||
|
void print_verilog_mux_config_bus(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& mux_model,
|
||||||
|
const e_sram_orgz& sram_orgz_type,
|
||||||
|
const size_t& mux_size,
|
||||||
|
const size_t& mux_instance_id,
|
||||||
|
const size_t& num_reserved_conf_bits,
|
||||||
|
const size_t& num_conf_bits);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue