refactorint net addition for configuration signals in module graph
This commit is contained in:
parent
c9950162d1
commit
663b1b7665
|
@ -92,6 +92,25 @@ std::vector<CircuitPortId> find_circuit_regular_sram_ports(const CircuitLibrary&
|
|||
return regular_sram_ports;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Find mode select sram ports of a circuit model
|
||||
*******************************************************************/
|
||||
std::vector<CircuitPortId> find_circuit_mode_select_sram_ports(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model) {
|
||||
std::vector<CircuitPortId> sram_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_SRAM, true);
|
||||
std::vector<CircuitPortId> mode_select_sram_ports;
|
||||
|
||||
for (const auto& port : sram_ports) {
|
||||
if (false == circuit_lib.port_is_mode_select(port)) {
|
||||
continue;
|
||||
}
|
||||
mode_select_sram_ports.push_back(port);
|
||||
}
|
||||
|
||||
return mode_select_sram_ports;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Find the number of shared configuration bits for a ReRAM circuit
|
||||
* TODO: this function is subjected to be changed due to ReRAM-based SRAM cell design!!!
|
||||
|
|
|
@ -17,6 +17,9 @@ std::vector<CircuitModelId> find_circuit_sram_models(const CircuitLibrary& circu
|
|||
std::vector<CircuitPortId> find_circuit_regular_sram_ports(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model);
|
||||
|
||||
std::vector<CircuitPortId> find_circuit_mode_select_sram_ports(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model);
|
||||
|
||||
size_t find_circuit_num_shared_config_bits(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const e_sram_orgz& sram_orgz_type);
|
||||
|
|
|
@ -12,10 +12,12 @@
|
|||
#include "spice_types.h"
|
||||
|
||||
#include "circuit_library.h"
|
||||
#include "circuit_library_utils.h"
|
||||
#include "module_manager.h"
|
||||
|
||||
#include "fpga_x2p_naming.h"
|
||||
#include "fpga_x2p_pbtypes_utils.h"
|
||||
#include "fpga_x2p_mem_utils.h"
|
||||
|
||||
#include "module_manager_utils.h"
|
||||
|
||||
|
@ -397,3 +399,233 @@ void add_primitive_pb_type_module_nets(ModuleManager& module_manager,
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Add the port-to-port connection between a logic module
|
||||
* and a memory module
|
||||
* Create nets to wire SRAM ports between logic module and memory module
|
||||
*
|
||||
* The information about SRAM ports of logic module are stored in the
|
||||
* mem_output_bus_ports, where element [0] denotes the SRAM port while
|
||||
* element [1] denotes the SRAMb port
|
||||
*
|
||||
* +---------+ +--------+
|
||||
* | | regular SRAM port | |
|
||||
* | Logic |-----------------------+ | Memory |
|
||||
* | Module | mode-select SRAM port |->| Module |
|
||||
* | |-----------------------+ | |
|
||||
* +---------+ +--------+
|
||||
*
|
||||
* There could be multiple SRAM ports of logic module, which are wired to
|
||||
* the SRAM ports of memory module
|
||||
*
|
||||
* Note: this function SHOULD be called after the pb_type_module is created
|
||||
* and its child module (logic_module and memory_module) is created!
|
||||
*
|
||||
* Note: this function only handle either SRAM or SRAMb ports.
|
||||
* So, this function may be called twice to complete the wiring
|
||||
*******************************************************************/
|
||||
static
|
||||
void add_module_nets_between_logic_and_memory_sram_ports(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const ModuleId& logic_module,
|
||||
const size_t& logic_instance_id,
|
||||
const ModuleId& memory_module,
|
||||
const size_t& memory_instance_id,
|
||||
const std::vector<ModulePortId>& logic_module_sram_port_ids,
|
||||
const ModulePortId& mem_module_sram_port_id) {
|
||||
/* Find mem_output_bus ports in logic module */
|
||||
std::vector<BasicPort> logic_module_sram_ports;
|
||||
for (const ModulePortId& logic_module_sram_port_id : logic_module_sram_port_ids) {
|
||||
logic_module_sram_ports.push_back(module_manager.module_port(logic_module, logic_module_sram_port_id));
|
||||
}
|
||||
|
||||
/* Create a list of virtual ports to align with the SRAM port of logic module
|
||||
* Physical ports:
|
||||
*
|
||||
* logic_module_sram_port[0] logic_module_sram_port[1]
|
||||
*
|
||||
* LSB[0]------------>MSB[0] LSB------------------>MSB
|
||||
*
|
||||
* memory_sram_port
|
||||
* LSBY---------------------------------------------->MSBY
|
||||
*
|
||||
* Virtual ports:
|
||||
* mem_module_sram_port[0] mem_module_sram_port[1]
|
||||
* LSBY--------------->MSBX MSBX+1------------------>MSBY
|
||||
*
|
||||
*/
|
||||
BasicPort mem_module_port = module_manager.module_port(memory_module, mem_module_sram_port_id);
|
||||
std::vector<BasicPort> virtual_mem_module_ports;
|
||||
|
||||
/* Create a counter for the LSB of virtual ports */
|
||||
size_t port_lsb = 0;
|
||||
for (const BasicPort& logic_module_sram_port : logic_module_sram_ports) {
|
||||
BasicPort virtual_port;
|
||||
virtual_port.set_name(mem_module_port.get_name());
|
||||
virtual_port.set_width(port_lsb, port_lsb + logic_module_sram_port.get_width() - 1);
|
||||
virtual_mem_module_ports.push_back(virtual_port);
|
||||
port_lsb = virtual_port.get_msb() + 1;
|
||||
}
|
||||
/* port_lsb should be aligned with the MSB of memory_sram_port */
|
||||
VTR_ASSERT(port_lsb == mem_module_port.get_msb() + 1);
|
||||
|
||||
/* Wire port to port */
|
||||
for (size_t port_index = 0; port_index < logic_module_sram_ports.size(); ++port_index) {
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < logic_module_sram_ports[port_index].pins().size(); ++pin_id) {
|
||||
ModuleNetId net = module_manager.create_module_net(parent_module);
|
||||
/* Add net source */
|
||||
module_manager.add_module_net_source(parent_module, net, logic_module, logic_instance_id, logic_module_sram_port_ids[port_index], logic_module_sram_ports[port_index].pins()[pin_id]);
|
||||
/* Add net sink */
|
||||
module_manager.add_module_net_sink(parent_module, net, memory_module, memory_instance_id, mem_module_sram_port_id, virtual_mem_module_ports[port_index].pins()[pin_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Add the port-to-port connection between a logic module
|
||||
* and a memory module
|
||||
* Create nets to wire SRAM ports between logic module and memory module
|
||||
*
|
||||
*
|
||||
* +---------+ +--------+
|
||||
* | | SRAM ports | |
|
||||
* | Logic |----------------------->| Memory |
|
||||
* | Module | SRAMb ports | Module |
|
||||
* | |----------------------->| |
|
||||
* +---------+ +--------+
|
||||
*
|
||||
* Note: this function SHOULD be called after the pb_type_module is created
|
||||
* and its child module (logic_module and memory_module) is created!
|
||||
*
|
||||
*******************************************************************/
|
||||
void add_module_nets_between_logic_and_memory_sram_bus(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const ModuleId& logic_module,
|
||||
const size_t& logic_instance_id,
|
||||
const ModuleId& memory_module,
|
||||
const size_t& memory_instance_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& logic_model) {
|
||||
|
||||
/* Connect SRAM port */
|
||||
/* Find SRAM ports in the circuit model for logic module */
|
||||
std::vector<std::string> logic_model_sram_port_names;
|
||||
/* Regular sram port goes first */
|
||||
for (CircuitPortId regular_sram_port : find_circuit_regular_sram_ports(circuit_lib, logic_model)) {
|
||||
logic_model_sram_port_names.push_back(circuit_lib.port_lib_name(regular_sram_port));
|
||||
}
|
||||
/* Mode-select sram port goes first */
|
||||
for (CircuitPortId mode_select_sram_port : find_circuit_mode_select_sram_ports(circuit_lib, logic_model)) {
|
||||
logic_model_sram_port_names.push_back(circuit_lib.port_lib_name(mode_select_sram_port));
|
||||
}
|
||||
/* Find the port ids in the memory */
|
||||
std::vector<ModulePortId> logic_module_sram_port_ids;
|
||||
for (const std::string& logic_model_sram_port_name : logic_model_sram_port_names) {
|
||||
/* Skip non-exist ports */
|
||||
if (ModulePortId::INVALID() == module_manager.find_module_port(logic_module, logic_model_sram_port_name)) {
|
||||
continue;
|
||||
}
|
||||
logic_module_sram_port_ids.push_back(module_manager.find_module_port(logic_module, logic_model_sram_port_name));
|
||||
}
|
||||
|
||||
/* Get the SRAM port name of memory model */
|
||||
/* TODO: this should be a constant expression and it should be the same for all the memory module! */
|
||||
std::string memory_model_sram_port_name = generate_configuration_chain_data_out_name();
|
||||
/* Find the corresponding ports in memory module */
|
||||
ModulePortId mem_module_sram_port_id = module_manager.find_module_port(memory_module, memory_model_sram_port_name);
|
||||
|
||||
/* Do wiring only when we have sram ports */
|
||||
if ( (false == logic_module_sram_port_ids.empty())
|
||||
|| (ModulePortId::INVALID() == mem_module_sram_port_id) ) {
|
||||
add_module_nets_between_logic_and_memory_sram_ports(module_manager, parent_module,
|
||||
logic_module, logic_instance_id,
|
||||
memory_module, memory_instance_id,
|
||||
logic_module_sram_port_ids, mem_module_sram_port_id);
|
||||
}
|
||||
|
||||
/* Connect SRAMb port */
|
||||
/* Find SRAM ports in the circuit model for logic module */
|
||||
std::vector<std::string> logic_model_sramb_port_names;
|
||||
/* Regular sram port goes first */
|
||||
for (CircuitPortId regular_sram_port : find_circuit_regular_sram_ports(circuit_lib, logic_model)) {
|
||||
logic_model_sramb_port_names.push_back(circuit_lib.port_lib_name(regular_sram_port) + std::string("_inv"));
|
||||
}
|
||||
/* Mode-select sram port goes first */
|
||||
for (CircuitPortId mode_select_sram_port : find_circuit_mode_select_sram_ports(circuit_lib, logic_model)) {
|
||||
logic_model_sramb_port_names.push_back(circuit_lib.port_lib_name(mode_select_sram_port) + std::string("_inv"));
|
||||
}
|
||||
/* Find the port ids in the memory */
|
||||
std::vector<ModulePortId> logic_module_sramb_port_ids;
|
||||
for (const std::string& logic_model_sramb_port_name : logic_model_sramb_port_names) {
|
||||
/* Skip non-exist ports */
|
||||
if (ModulePortId::INVALID() == module_manager.find_module_port(logic_module, logic_model_sramb_port_name)) {
|
||||
continue;
|
||||
}
|
||||
logic_module_sramb_port_ids.push_back(module_manager.find_module_port(logic_module, logic_model_sramb_port_name));
|
||||
}
|
||||
|
||||
/* Get the SRAM port name of memory model */
|
||||
std::string memory_model_sramb_port_name = generate_configuration_chain_inverted_data_out_name();
|
||||
/* Find the corresponding ports in memory module */
|
||||
ModulePortId mem_module_sramb_port_id = module_manager.find_module_port(memory_module, memory_model_sramb_port_name);
|
||||
|
||||
/* Do wiring only when we have sramb ports */
|
||||
if ( (false == logic_module_sramb_port_ids.empty())
|
||||
|| (ModulePortId::INVALID() == mem_module_sramb_port_id) ) {
|
||||
add_module_nets_between_logic_and_memory_sram_ports(module_manager, parent_module,
|
||||
logic_module, logic_instance_id,
|
||||
memory_module, memory_instance_id,
|
||||
logic_module_sramb_port_ids, mem_module_sramb_port_id);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* TODO:
|
||||
* Add the port-to-port connection between a logic module
|
||||
* and a memory module inside a primitive module
|
||||
*
|
||||
* Create nets to wire the control signals of memory module to
|
||||
* the configuration ports of primitive module
|
||||
*
|
||||
* Primitive module
|
||||
* +----------------------------+
|
||||
* | +--------+ |
|
||||
* config | | | |
|
||||
* ports --->|--------------->| Memory | |
|
||||
* | | Module | |
|
||||
* | | | |
|
||||
* | +--------+ |
|
||||
* +----------------------------+
|
||||
* The detailed config ports really depend on the type
|
||||
* of SRAM organization.
|
||||
*
|
||||
* Note: this function SHOULD be called after the pb_type_module is created
|
||||
* and its child module (logic_module and memory_module) is created!
|
||||
*******************************************************************/
|
||||
|
||||
/********************************************************************
|
||||
* TODO:
|
||||
* Add the port-to-port connection between a logic module
|
||||
* and a memory module inside a primitive module
|
||||
*
|
||||
* Create nets to wire the formal verification ports of
|
||||
* primitive module to SRAM ports of logic module
|
||||
*
|
||||
* Primitive module
|
||||
*
|
||||
* formal_port_sram
|
||||
* +-----------------------------------------------+
|
||||
* | ^ |
|
||||
* | +---------+ | +--------+ |
|
||||
* | | | SRAM | | | |
|
||||
* | | Logic |--------+--->| Memory | |
|
||||
* | | Module | SRAMb | Module | |
|
||||
* | | |--------+--->| | |
|
||||
* | +---------+ | +--------+ |
|
||||
* | v |
|
||||
* +-----------------------------------------------+
|
||||
* formal_port_sramb
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
|
|
|
@ -55,4 +55,14 @@ void add_primitive_pb_type_module_nets(ModuleManager& module_manager,
|
|||
const size_t& child_instance_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
t_pb_type* cur_pb_type);
|
||||
|
||||
void add_module_nets_between_logic_and_memory_sram_bus(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const ModuleId& logic_module,
|
||||
const size_t& logic_instance_id,
|
||||
const ModuleId& memory_module,
|
||||
const size_t& memory_instance_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& logic_model);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -156,11 +156,26 @@ void print_verilog_primitive_block(std::fstream& fp,
|
|||
/* Add nets to connect the logic model ports to pb_type ports */
|
||||
add_primitive_pb_type_module_nets(module_manager, primitive_module, logic_module, logic_instance_id, circuit_lib, primitive_pb_graph_node->pb_type);
|
||||
|
||||
/* TODO: add the associated memory module as a child of primitive module */
|
||||
/* Add the associated memory module as a child of primitive module */
|
||||
std::string memory_module_name = generate_memory_module_name(circuit_lib, primitive_model, sram_model, std::string(verilog_mem_posfix));
|
||||
ModuleId memory_module = module_manager.find_module(memory_module_name);
|
||||
|
||||
/* TODO: Add nets to connect regular and mode-select SRAM ports to the SRAM port of memory module */
|
||||
/* If there is no memory module required, we can skip the assocated net addition */
|
||||
if (ModuleId::INVALID() != memory_module) {
|
||||
size_t memory_instance_id = module_manager.num_instance(primitive_module, memory_module);
|
||||
/* Add the memory module as a child of primitive module */
|
||||
module_manager.add_child_module(primitive_module, memory_module);
|
||||
|
||||
/* TODO: write the verilog module */
|
||||
/* Add nets to connect regular and mode-select SRAM ports to the SRAM port of memory module */
|
||||
add_module_nets_between_logic_and_memory_sram_bus(module_manager, primitive_module,
|
||||
logic_module, logic_instance_id,
|
||||
memory_module, memory_instance_id,
|
||||
circuit_lib, primitive_model);
|
||||
/* TODO: Add nets to connect configuration ports from memory module to primitive module */
|
||||
/* TODO: Add nets to connect formal verification ports from memory module to primitive module */
|
||||
}
|
||||
|
||||
/* Write the verilog module */
|
||||
write_verilog_module_to_file(fp, module_manager, primitive_module, use_explicit_mapping);
|
||||
|
||||
/* Add an empty line as a splitter */
|
||||
|
|
Loading…
Reference in New Issue