From 009c0d63b507cc408502f8bf977d5cf5044f1c3e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 13 Sep 2019 15:05:31 -0600 Subject: [PATCH] refactored the memory bank. Ready to plug-in the test --- vpr7_x2p/libarchfpga/SRC/circuit_library.cpp | 19 +++++ vpr7_x2p/libarchfpga/SRC/circuit_library.h | 4 + .../vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp | 13 +++- .../vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h | 5 ++ .../SRC/fpga_x2p/verilog/verilog_memory.cpp | 76 +++++++++++++------ 5 files changed, 93 insertions(+), 24 deletions(-) diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp index 6eeb5fa7c..6a7d23a64 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp @@ -592,6 +592,25 @@ std::vector CircuitLibrary::model_global_ports_by_type(const Circ return global_ports; } + +/* Recursively find all the global ports in the circuit model / sub circuit_model + * whose port type matches users' specification + */ +std::vector CircuitLibrary::model_global_ports_by_type(const CircuitModelId& model_id, + const std::vector& types, + const bool& recursive, + const bool& ignore_config_memories) const { + std::vector global_ports; + std::vector ignore_list; + + for (const auto& port_type : types) { + std::vector global_port_by_type = model_global_ports_by_type(model_id, port_type, recursive, ignore_config_memories); + /* Insert the vector to the final global_ports */ + global_ports.insert(global_ports.begin(), global_port_by_type.begin(), global_port_by_type.end()); + } + return global_ports; +} + /* Recursively find all the global ports in the circuit model / sub circuit_model * but ignore all the SRAM and SCFF, which are configuration memories */ diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.h b/vpr7_x2p/libarchfpga/SRC/circuit_library.h index 220be6a97..56de466a7 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.h @@ -258,6 +258,10 @@ class CircuitLibrary { const enum e_spice_model_port_type& type, const bool& recursive, const std::vector& ignore_model_types) const; + std::vector model_global_ports_by_type(const CircuitModelId& model_id, + const std::vector& type, + const bool& recursive, + const bool& ignore_config_memories) const; std::vector model_global_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& type, const bool& recursive, 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 32ae2f723..66a28eff3 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 @@ -122,9 +122,20 @@ std::string generate_segment_wire_subckt_name(const std::string& wire_model_name * input --->| Routing track wire |--------->| Switch Block * +--------------------+ output | * +-------------- - + * ********************************************************************/ std::string generate_segment_wire_mid_output_name(const std::string& regular_output_name) { /* TODO: maybe have a postfix? */ return std::string("mid_" + regular_output_name); } + +/********************************************************************* + * Generate the module name for a memory sub-circuit + ********************************************************************/ +std::string generate_memory_module_name(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const CircuitModelId& sram_model, + const std::string& postfix) { + return std::string( circuit_lib.model_name(circuit_model) + "_" + circuit_lib.model_name(sram_model) + postfix ); +} + 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 edd125ea7..dbf6abff5 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 @@ -33,4 +33,9 @@ std::string generate_segment_wire_subckt_name(const std::string& wire_model_name std::string generate_segment_wire_mid_output_name(const std::string& regular_output_name); +std::string generate_memory_module_name(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const CircuitModelId& sram_model, + const std::string& postfix); + #endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_memory.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_memory.cpp index 2dea66cc5..32026efdb 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_memory.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_memory.cpp @@ -99,31 +99,23 @@ * ********************************************************************/ static -void print_verilog_cmos_mux_memory_module(ModuleManager& module_manager, - const CircuitLibrary& circuit_lib, - std::fstream& fp, - const CircuitModelId& mux_model, - const MuxGraph& mux_graph) { +void print_verilog_memory_module(ModuleManager& module_manager, + const CircuitLibrary& circuit_lib, + std::fstream& fp, + const std::string& module_name, + const CircuitModelId& sram_model, + const size_t& num_mems) { /* Make sure we have a valid file handler*/ check_file_handler(fp); - /* Generate module name */ - std::string module_name = generate_verilog_mux_subckt_name(circuit_lib, mux_model, - find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()), - std::string(verilog_mem_posfix)); - - /* Get the sram ports from the mux */ - std::vector mux_sram_ports = circuit_lib.model_ports_by_type(mux_model, SPICE_MODEL_PORT_SRAM, true); - VTR_ASSERT( 1 == mux_sram_ports.size() ); - /* Get the circuit model for the memory circuit used by the multiplexer */ - CircuitModelId sram_model = circuit_lib.port_tri_state_model(mux_sram_ports[0]); - VTR_ASSERT(CircuitModelId::INVALID() != sram_model); - /* Create a module and add to the module manager */ ModuleId module_id = module_manager.add_module(module_name); VTR_ASSERT(ModuleId::INVALID() != module_id); /* Get the global ports required by the SRAM */ - std::vector sram_global_ports = circuit_lib.model_global_ports_by_type(sram_model, SPICE_MODEL_PORT_INPUT, true, true); + std::vector global_port_types; + global_port_types.push_back(SPICE_MODEL_PORT_CLOCK); + global_port_types.push_back(SPICE_MODEL_PORT_INPUT); + std::vector sram_global_ports = circuit_lib.model_global_ports_by_type(sram_model, global_port_types, true, false); /* Get the input ports from the SRAM */ std::vector sram_input_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_INPUT, true); /* Get the output ports from the SRAM */ @@ -134,9 +126,6 @@ void print_verilog_cmos_mux_memory_module(ModuleManager& module_manager, std::vector sram_wl_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_WL, true); std::vector sram_wlb_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_WLB, true); - /* Find the number of SRAMs in the module, this is also the port width */ - size_t num_mems = mux_graph.num_memory_bits(); - /* Add module ports: the ports come from the SRAM modules */ /* Add each global port */ for (const auto& port : sram_global_ports) { @@ -244,9 +233,25 @@ void print_verilog_mux_memory_module(ModuleManager& module_manager, const MuxGraph& mux_graph) { /* Multiplexers built with different technology is in different organization */ switch (circuit_lib.design_tech_type(mux_model)) { - case SPICE_MODEL_DESIGN_CMOS: - print_verilog_cmos_mux_memory_module(module_manager, circuit_lib, fp, mux_model, mux_graph); + case SPICE_MODEL_DESIGN_CMOS: { + /* Generate module name */ + std::string module_name = generate_verilog_mux_subckt_name(circuit_lib, mux_model, + find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()), + std::string(verilog_mem_posfix)); + + /* Get the sram ports from the mux */ + std::vector mux_sram_ports = circuit_lib.model_ports_by_type(mux_model, SPICE_MODEL_PORT_SRAM, true); + VTR_ASSERT( 1 == mux_sram_ports.size() ); + /* Get the circuit model for the memory circuit used by the multiplexer */ + CircuitModelId sram_model = circuit_lib.port_tri_state_model(mux_sram_ports[0]); + VTR_ASSERT(CircuitModelId::INVALID() != sram_model); + + /* 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, fp, module_name, sram_model, num_mems); break; + } case SPICE_MODEL_DESIGN_RRAM: /* We do not need a memory submodule for RRAM MUX, * RRAM are embedded in the datapath @@ -332,7 +337,32 @@ void print_verilog_submodule_memories(ModuleManager& module_manager, if (0 == sram_ports.size()) { continue; } + /* Find the name of memory module */ + /* Get the total number of SRAMs */ + size_t num_mems = 0; + for (const auto& port : sram_ports) { + num_mems += circuit_lib.port_size(port); + } + /* Get the circuit model for the memory circuit used by the multiplexer */ + std::vector sram_models; + for (const auto& port : sram_ports) { + CircuitModelId sram_model = circuit_lib.port_tri_state_model(port); + VTR_ASSERT(CircuitModelId::INVALID() != sram_model); + /* Found in the vector of sram_models, do not update and go to the next */ + if (sram_models.end() != std::find(sram_models.begin(), sram_models.end(), sram_model)) { + continue; + } + /* sram_model not found in the vector, update the sram_models */ + sram_models.push_back(sram_model); + } + /* Should have only 1 SRAM model */ + VTR_ASSERT( 1 == sram_models.size() ); + + /* Create the module name for the memory block */ + std::string module_name = generate_memory_module_name(circuit_lib, model, sram_models[0], std::string(verilog_mem_posfix)); + /* Create a Verilog module for the memories used by the circuit model */ + print_verilog_memory_module(module_manager, circuit_lib, fp, module_name, sram_models[0], num_mems); } /* Close the file stream */