From 2b0e2615faae5e6a2a54963ad2e2ab12753c538a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 25 Sep 2019 16:09:58 -0600 Subject: [PATCH] refactored sram port addition to module manager --- .../vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp | 90 +++++++++++++++++-- .../vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h | 8 +- .../fpga_x2p/base/module_manager_utils.cpp | 85 +++++++++++++++++- .../SRC/fpga_x2p/base/module_manager_utils.h | 11 ++- .../SRC/fpga_x2p/verilog/verilog_routing.c | 21 +++-- 5 files changed, 194 insertions(+), 21 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp index 8884c3750..db19f59f2 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp @@ -308,16 +308,90 @@ std::string generate_reserved_sram_port_name(const e_spice_model_port_type& port * Generate the port name for a sram port, used for formal verification * The port name is named after the cell name of SRAM in circuit library * TODO: - * Use the new refactored data structure to replace the sram_orgz_info + * Use the new refactored data structure to replace the t_sram_orgz_info *********************************************************************/ -std::string generate_formal_verification_sram_port_name(t_sram_orgz_info* cur_sram_orgz_info) { - /* Get memory_model */ - t_spice_model* mem_model = NULL; - get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); - VTR_ASSERT(NULL != mem_model); /* We must have a valid memory model */ - - std::string port_name = std::string(mem_model->name) + std::string("_out_fm"); +std::string generate_formal_verification_sram_port_name(const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model) { + std::string port_name = circuit_lib.model_name(sram_model) + std::string("_out_fm"); return port_name; } +/********************************************************************* + * Generate the port name for a regular sram port + * The port name is named after the cell name of SRAM in circuit library + * TODO: + * Use the new refactored data structure to replace the t_sram_orgz_info + *********************************************************************/ +std::string generate_sram_port_name(const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model, + const e_sram_orgz& sram_orgz_type, + const e_spice_model_port_type& port_type) { + /* Get memory_model */ + + std::string port_name = circuit_lib.model_name(sram_model) + std::string("_"); + + switch (sram_orgz_type) { + case SPICE_SRAM_STANDALONE: { + /* Two types of ports are available: + * (1) Regular output of a SRAM, enabled by port type of INPUT + * (2) Inverted output of a SRAM, enabled by port type of OUTPUT + */ + if (SPICE_MODEL_PORT_INPUT == port_type) { + port_name += std::string("out"); + } else { + VTR_ASSERT( SPICE_MODEL_PORT_OUTPUT == port_type ); + port_name += std::string("outb"); + } + break; + } + case SPICE_SRAM_SCAN_CHAIN: + /* Two types of ports are available: + * (1) Head of a chain of Scan-chain Flip-Flops (SCFFs), enabled by port type of INPUT + * (2) Tail of a chian of Scan-chain Flip-flops (SCFFs), enabled by port type of OUTPUT + * +------+ +------+ +------+ + * Head --->| SCFF |--->| SCFF |--->| SCFF |---> Tail + * +------+ +------+ +------+ + */ + if (SPICE_MODEL_PORT_INPUT == port_type) { + port_name += std::string("scff_head"); + } else { + VTR_ASSERT( SPICE_MODEL_PORT_OUTPUT == port_type ); + port_name += std::string("scff_tail"); + } + break; + case SPICE_SRAM_MEMORY_BANK: + /* Four types of ports are available: + * (1) Bit Lines (BLs) of a SRAM cell, enabled by port type of BL + * (2) Word Lines (WLs) of a SRAM cell, enabled by port type of WL + * (3) Inverted Bit Lines (BLBs) of a SRAM cell, enabled by port type of BLB + * (4) Inverted Word Lines (WLBs) of a SRAM cell, enabled by port type of WLB + * + * BL BLB WL WLB BL BLB WL WLB BL BLB WL WLB + * [0] [0] [0] [0] [1] [1] [1] [1] [i] [i] [i] [i] + * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | | | | | | + * +----------+ +----------+ +----------+ + * | SRAM | | SRAM | ... | SRAM | + * +----------+ +----------+ +----------+ + */ + if (SPICE_MODEL_PORT_BL == port_type) { + port_name += std::string("bl"); + } else if (SPICE_MODEL_PORT_WL == port_type) { + port_name += std::string("wl"); + } else if (SPICE_MODEL_PORT_BLB == port_type) { + port_name += std::string("blb"); + } else { + VTR_ASSERT( SPICE_MODEL_PORT_WLB == port_type ); + port_name += std::string("wlb"); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Invalid type of SRAM organization !\n", + __FILE__, __LINE__); + exit(1); + } + + return port_name; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h index ed49595d0..732f47e5f 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h @@ -69,6 +69,12 @@ std::string generate_grid_port_name(const vtr::Point& coordinate, std::string generate_reserved_sram_port_name(const e_spice_model_port_type& port_type); -std::string generate_formal_verification_sram_port_name(t_sram_orgz_info* cur_sram_orgz_info); +std::string generate_formal_verification_sram_port_name(const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model); + +std::string generate_sram_port_name(const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model, + const e_sram_orgz& sram_orgz_type, + const e_spice_model_port_type& port_type); #endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp index da37f3a4b..bc844ca7c 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp @@ -116,14 +116,95 @@ void add_reserved_sram_ports_to_module_manager(ModuleManager& module_manager, ********************************************************************/ void add_formal_verification_sram_ports_to_module_manager(ModuleManager& module_manager, const ModuleId& module_id, - t_sram_orgz_info* cur_sram_orgz_info, + const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model, + const e_sram_orgz sram_orgz_type, const std::string& preproc_flag, const size_t& port_size) { /* Create a port */ - std::string port_name = generate_formal_verification_sram_port_name(cur_sram_orgz_info); + std::string port_name = generate_formal_verification_sram_port_name(circuit_lib, sram_model); BasicPort module_port(port_name, port_size); /* Add generated ports to the ModuleManager */ ModulePortId port_id = module_manager.add_port(module_id, module_port, ModuleManager::MODULE_INPUT_PORT); /* Add pre-processing flag if defined */ module_manager.set_port_preproc_flag(module_id, port_id, preproc_flag); } + +/******************************************************************** + * Add a list of ports that are used for SRAM configuration to a module + * in the module manager + * The type and names of added ports strongly depend on the + * organization of SRAMs. + * 1. Standalone SRAMs: + * two ports will be added, which are regular output and inverted output + * 2. Scan-chain Flip-flops: + * two ports will be added, which are the head of scan-chain + * and the tail of scan-chain + * 3. Memory decoders: + * 2-4 ports will be added, depending on the ports available in the SRAM + * Among these, two ports are mandatory: BL and WL + * The other two ports are optional: BLB and WLB + * Note that the constraints are correletated to the checking rules + * in check_circuit_library() + ********************************************************************/ +void add_sram_ports_to_module_manager(ModuleManager& module_manager, + const ModuleId& module_id, + const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model, + const e_sram_orgz sram_orgz_type, + const size_t& port_size) { + /* Prepare a list of port types to be added, the port type will be used to create port names */ + std::vector model_port_types; + /* Prepare a list of module port types to be added, the port type will be used to specify the port type in Verilog/SPICE module */ + std::vector module_port_types; + /* Actual port size may be different from user specification. Think about SCFF */ + size_t sram_port_size = port_size; + + switch (sram_orgz_type) { + case SPICE_SRAM_STANDALONE: + model_port_types.push_back(SPICE_MODEL_PORT_INPUT); + module_port_types.push_back(ModuleManager::MODULE_INPUT_PORT); + model_port_types.push_back(SPICE_MODEL_PORT_OUTPUT); + module_port_types.push_back(ModuleManager::MODULE_INPUT_PORT); + break; + case SPICE_SRAM_SCAN_CHAIN: + model_port_types.push_back(SPICE_MODEL_PORT_INPUT); + module_port_types.push_back(ModuleManager::MODULE_INPUT_PORT); + model_port_types.push_back(SPICE_MODEL_PORT_OUTPUT); + module_port_types.push_back(ModuleManager::MODULE_OUTPUT_PORT); + /* SCFF head/tail are single-bit ports */ + sram_port_size = 1; + break; + case SPICE_SRAM_MEMORY_BANK: { + std::vector ports_to_search; + ports_to_search.push_back(SPICE_MODEL_PORT_BL); + ports_to_search.push_back(SPICE_MODEL_PORT_WL); + ports_to_search.push_back(SPICE_MODEL_PORT_BLB); + ports_to_search.push_back(SPICE_MODEL_PORT_WLB); + /* Try to find a BL/WL/BLB/WLB port and update the port types/module port types to be added */ + for (const auto& port_to_search : ports_to_search) { + std::vector found_port = circuit_lib.model_ports_by_type(sram_model, port_to_search); + if (0 == found_port.size()) { + continue; + } + model_port_types.push_back(port_to_search); + module_port_types.push_back(ModuleManager::MODULE_INPUT_PORT); + } + break; + } + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Invalid type of SRAM organization !\n", + __FILE__, __LINE__); + exit(1); + } + + /* Add ports to the module manager */ + for (size_t iport = 0; iport < model_port_types.size(); ++iport) { + /* Create a port */ + std::string port_name = generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, model_port_types[iport]); + BasicPort module_port(port_name, sram_port_size); + /* Add generated ports to the ModuleManager */ + module_manager.add_port(module_id, module_port, module_port_types[iport]); + } +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.h index 2fa5e98bf..7ab8892c1 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.h @@ -26,9 +26,18 @@ void add_reserved_sram_ports_to_module_manager(ModuleManager& module_manager, void add_formal_verification_sram_ports_to_module_manager(ModuleManager& module_manager, const ModuleId& module_id, - t_sram_orgz_info* cur_sram_orgz_info, + const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model, + const e_sram_orgz sram_orgz_type, const std::string& preproc_flag, const size_t& port_size); +void add_sram_ports_to_module_manager(ModuleManager& module_manager, + const ModuleId& module_id, + const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model, + const e_sram_orgz sram_orgz_type, + const size_t& port_size); + #endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c index a411f08f1..d9f135892 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c @@ -2287,16 +2287,19 @@ void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manage add_reserved_sram_ports_to_module_manager(module_manager, module_id, rr_gsb.get_sb_num_reserved_conf_bits()); } - /* TODO: Normal sram ports */ - /* - dump_verilog_sram_ports(fp, cur_sram_orgz_info, - rr_gsb.get_sb_conf_bits_lsb(), - rr_gsb.get_sb_conf_bits_msb(), - VERILOG_PORT_INPUT); - */ - /* Add ports only visible during formal verification to the module */ + /* Normal sram ports */ if (0 < rr_gsb.get_sb_num_conf_bits()) { - add_formal_verification_sram_ports_to_module_manager(module_manager, module_id, cur_sram_orgz_info, + /* TODO: this should be added to the cur_sram_orgz_info !!! */ + t_spice_model* mem_model = NULL; + get_sram_orgz_info_mem_model(cur_sram_orgz_info, & mem_model); + CircuitModelId sram_model = circuit_lib.model(mem_model->name); + VTR_ASSERT(CircuitModelId::INVALID() != sram_model); + add_sram_ports_to_module_manager(module_manager, module_id, + circuit_lib, sram_model, cur_sram_orgz_info->type, + rr_gsb.get_sb_num_conf_bits()); + /* Add ports only visible during formal verification to the module */ + add_formal_verification_sram_ports_to_module_manager(module_manager, module_id, circuit_lib, sram_model, + cur_sram_orgz_info->type, std::string(verilog_formal_verification_preproc_flag), rr_gsb.get_sb_num_conf_bits()); }