Connect CCFFs in a chain in a Verilog module
This commit is contained in:
parent
f0949fea2f
commit
4da5035627
|
@ -316,6 +316,22 @@ std::string generate_formal_verification_sram_port_name(const CircuitLibrary& ci
|
||||||
return port_name;
|
return port_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Generate the head port name of a configuration chain
|
||||||
|
* TODO: This could be replaced as a constexpr string
|
||||||
|
*********************************************************************/
|
||||||
|
std::string generate_configuration_chain_head_name() {
|
||||||
|
return std::string("ccff_head");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Generate the tail port name of a configuration chain
|
||||||
|
* TODO: This could be replaced as a constexpr string
|
||||||
|
*********************************************************************/
|
||||||
|
std::string generate_configuration_chain_tail_name() {
|
||||||
|
return std::string("ccff_tail");
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* Generate the port name for a regular sram port which appears in the
|
* Generate the port name for a regular sram port which appears in the
|
||||||
* port list of a module
|
* port list of a module
|
||||||
|
|
|
@ -72,6 +72,10 @@ std::string generate_reserved_sram_port_name(const e_spice_model_port_type& port
|
||||||
std::string generate_formal_verification_sram_port_name(const CircuitLibrary& circuit_lib,
|
std::string generate_formal_verification_sram_port_name(const CircuitLibrary& circuit_lib,
|
||||||
const CircuitModelId& sram_model);
|
const CircuitModelId& sram_model);
|
||||||
|
|
||||||
|
std::string generate_configuration_chain_head_name();
|
||||||
|
|
||||||
|
std::string generate_configuration_chain_tail_name();
|
||||||
|
|
||||||
std::string generate_sram_port_name(const CircuitLibrary& circuit_lib,
|
std::string generate_sram_port_name(const CircuitLibrary& circuit_lib,
|
||||||
const CircuitModelId& sram_model,
|
const CircuitModelId& sram_model,
|
||||||
const e_sram_orgz& sram_orgz_type,
|
const e_sram_orgz& sram_orgz_type,
|
||||||
|
|
|
@ -28,10 +28,7 @@
|
||||||
#include "verilog_memory.h"
|
#include "verilog_memory.h"
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* Generate Verilog modules for the memories that are used
|
* Flat memory modules
|
||||||
* by CMOS (SRAM-based) multiplexers
|
|
||||||
* We support:
|
|
||||||
* 1. Flat memory modules
|
|
||||||
*
|
*
|
||||||
* in[0] in[1] in[N]
|
* in[0] in[1] in[N]
|
||||||
* | | |
|
* | | |
|
||||||
|
@ -44,68 +41,15 @@
|
||||||
* v v v
|
* v v v
|
||||||
* +------------------------------------+
|
* +------------------------------------+
|
||||||
* | Multiplexer Configuration port |
|
* | Multiplexer Configuration port |
|
||||||
*
|
|
||||||
* 2. TODO: Local decoders
|
|
||||||
*
|
|
||||||
* in[0] in[1] in[N]
|
|
||||||
* | | |
|
|
||||||
* v v v
|
|
||||||
* +-------+ +-------+ +-------+
|
|
||||||
* | SRAM | | SRAM | ... | SRAM |
|
|
||||||
* | [0] | | [1] | | [N-1] |
|
|
||||||
* +-------+ +-------+ +-------+
|
|
||||||
* | | ... |
|
|
||||||
* v v v
|
|
||||||
* +------------------------------------+
|
|
||||||
* | Local decoders |
|
|
||||||
* +------------------------------------+
|
|
||||||
* | | ... |
|
|
||||||
* v v v
|
|
||||||
* +------------------------------------+
|
|
||||||
* | Multiplexer Configuration port |
|
|
||||||
*
|
|
||||||
* 3. TODO: Scan-chain organization
|
|
||||||
*
|
|
||||||
* in[0] in[1] in[N]
|
|
||||||
* | | |
|
|
||||||
* v v v
|
|
||||||
* +-------+ +-------+ +-------+
|
|
||||||
* scan-chain--->| SRAM |--->| SRAM |--->... --->| SRAM |---->scan-chain
|
|
||||||
* input&clock | [0] | | [1] | | [N-1] | output
|
|
||||||
* +-------+ +-------+ +-------+
|
|
||||||
* | | ... |
|
|
||||||
* v v v
|
|
||||||
* +-----------------------------------------+
|
|
||||||
* | Multiplexer Configuration port |
|
|
||||||
*
|
|
||||||
* 4. TODO: Memory bank organization
|
|
||||||
*
|
|
||||||
* Bit lines Word lines
|
|
||||||
* | |
|
|
||||||
* v v
|
|
||||||
* +------------------------------------+
|
|
||||||
* | Memory Module Configuration port |
|
|
||||||
* +------------------------------------+
|
|
||||||
* | | |
|
|
||||||
* v v v
|
|
||||||
* +-------+ +-------+ +-------+
|
|
||||||
* | SRAM | | SRAM | ... | SRAM |
|
|
||||||
* | [0] | | [1] | | [N-1] |
|
|
||||||
* +-------+ +-------+ +-------+
|
|
||||||
* | | ... |
|
|
||||||
* v v v
|
|
||||||
* +------------------------------------+
|
|
||||||
* | Multiplexer Configuration port |
|
|
||||||
|
|
||||||
*
|
*
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
static
|
static
|
||||||
void print_verilog_memory_module(ModuleManager& module_manager,
|
void print_verilog_memory_standalone_module(ModuleManager& module_manager,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
std::fstream& fp,
|
std::fstream& fp,
|
||||||
const std::string& module_name,
|
const std::string& module_name,
|
||||||
const CircuitModelId& sram_model,
|
const CircuitModelId& sram_model,
|
||||||
const size_t& num_mems) {
|
const size_t& num_mems) {
|
||||||
/* Make sure we have a valid file handler*/
|
/* Make sure we have a valid file handler*/
|
||||||
check_file_handler(fp);
|
check_file_handler(fp);
|
||||||
|
|
||||||
|
@ -121,6 +65,220 @@ void print_verilog_memory_module(ModuleManager& module_manager,
|
||||||
std::vector<CircuitPortId> sram_input_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_INPUT, true);
|
std::vector<CircuitPortId> sram_input_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_INPUT, true);
|
||||||
/* Get the output ports from the SRAM */
|
/* 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);
|
std::vector<CircuitPortId> sram_output_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_OUTPUT, true);
|
||||||
|
|
||||||
|
/* Add module ports: the ports come from the SRAM modules */
|
||||||
|
/* Add each global port */
|
||||||
|
for (const auto& port : sram_global_ports) {
|
||||||
|
/* Configure each global port: global ports are shared among the SRAMs, so it is independent from the memory size */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
/* Add each input port */
|
||||||
|
for (const auto& port : sram_input_ports) {
|
||||||
|
BasicPort input_port(circuit_lib.port_lib_name(port), num_mems);
|
||||||
|
module_manager.add_port(module_id, input_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);
|
||||||
|
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dump module definition + ports */
|
||||||
|
print_verilog_module_declaration(fp, module_manager, module_id);
|
||||||
|
/* Finish dumping ports */
|
||||||
|
|
||||||
|
/* Find the sram module in the module manager */
|
||||||
|
ModuleId sram_module_id = module_manager.find_module(circuit_lib.model_name(sram_model));
|
||||||
|
|
||||||
|
/* Instanciate each submodule */
|
||||||
|
for (size_t i = 0; i < num_mems; ++i) {
|
||||||
|
/* Create a port-to-port map */
|
||||||
|
std::map<std::string, BasicPort> port2port_name_map;
|
||||||
|
/* Map instance inputs [i] to SRAM module input */
|
||||||
|
for (const auto& port : sram_input_ports) {
|
||||||
|
BasicPort instance_input_port(circuit_lib.port_lib_name(port), i, i);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output an instance of the module */
|
||||||
|
print_verilog_module_instance(fp, module_manager, module_id, sram_module_id, port2port_name_map, circuit_lib.dump_explicit_port_map(sram_model));
|
||||||
|
/* IMPORTANT: this update MUST be called after the instance outputting!!!!
|
||||||
|
* update the module manager with the relationship between the parent and child modules
|
||||||
|
*/
|
||||||
|
module_manager.add_child_module(module_id, sram_module_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put an end to the Verilog module */
|
||||||
|
print_verilog_module_end(fp, module_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Scan-chain organization
|
||||||
|
*
|
||||||
|
* +-------+ +-------+ +-------+
|
||||||
|
* scan-chain--->| CCFF |--->| CCFF |--->... --->| CCFF |---->scan-chain
|
||||||
|
* input&clock | [0] | | [1] | | [N-1] | output
|
||||||
|
* +-------+ +-------+ +-------+
|
||||||
|
* | | ... |
|
||||||
|
* v v v
|
||||||
|
* +-----------------------------------------+
|
||||||
|
* | Multiplexer Configuration port |
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_memory_chain_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);
|
||||||
|
|
||||||
|
/* 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<enum e_spice_model_port_type> global_port_types;
|
||||||
|
global_port_types.push_back(SPICE_MODEL_PORT_CLOCK);
|
||||||
|
global_port_types.push_back(SPICE_MODEL_PORT_INPUT);
|
||||||
|
std::vector<CircuitPortId> 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<CircuitPortId> sram_input_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_INPUT, true);
|
||||||
|
/* Should have only 1 input port */
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Add module ports: the ports come from the SRAM modules */
|
||||||
|
/* Add each global port */
|
||||||
|
for (const auto& port : sram_global_ports) {
|
||||||
|
/* Configure each global port: global ports are shared among the SRAMs, so it is independent from the memory size */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
/* Add an input port, which is the head of configuration chain in the module */
|
||||||
|
/* TODO: restriction!!!
|
||||||
|
* consider only the first input of the CCFF model as the D port,
|
||||||
|
* which will be connected to the head of the chain
|
||||||
|
*/
|
||||||
|
BasicPort chain_head_port(generate_configuration_chain_head_name(),
|
||||||
|
circuit_lib.port_size(sram_input_ports[0]));
|
||||||
|
module_manager.add_port(module_id, chain_head_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
/* Add an output port, which is the tail of configuration chain in the module */
|
||||||
|
/* TODO: restriction!!!
|
||||||
|
* consider only the first output of the CCFF model as the Q port,
|
||||||
|
* which will be connected to the tail of the chain
|
||||||
|
*/
|
||||||
|
BasicPort chain_tail_port(generate_configuration_chain_tail_name(),
|
||||||
|
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);
|
||||||
|
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dump module definition + ports */
|
||||||
|
print_verilog_module_declaration(fp, module_manager, module_id);
|
||||||
|
/* Finish dumping ports */
|
||||||
|
|
||||||
|
/* Find the sram module in the module manager */
|
||||||
|
ModuleId sram_module_id = module_manager.find_module(circuit_lib.model_name(sram_model));
|
||||||
|
|
||||||
|
/* Instanciate each submodule */
|
||||||
|
for (size_t i = 0; i < num_mems; ++i) {
|
||||||
|
/* Create a port-to-port map */
|
||||||
|
std::map<std::string, BasicPort> port2port_name_map;
|
||||||
|
/* Map instance inputs [i] to SRAM module input */
|
||||||
|
for (const auto& port : sram_input_ports) {
|
||||||
|
BasicPort instance_input_port(circuit_lib.port_lib_name(port), i, i);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output an instance of the module */
|
||||||
|
print_verilog_module_instance(fp, module_manager, module_id, sram_module_id, port2port_name_map, circuit_lib.dump_explicit_port_map(sram_model));
|
||||||
|
/* IMPORTANT: this update MUST be called after the instance outputting!!!!
|
||||||
|
* update the module manager with the relationship between the parent and child modules
|
||||||
|
*/
|
||||||
|
module_manager.add_child_module(module_id, sram_module_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wire the memory cells into a chain
|
||||||
|
* The head of the chain will be wired to the input port of the first CCFF
|
||||||
|
* The tail of the chain will be wired to the output port of the last CCFF
|
||||||
|
* The output of each CCFF will be wired to the input of the next CCFFF in the chain
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
print_verilog_wire_connection(fp, chain_input_port, chain_output_port, false);
|
||||||
|
|
||||||
|
/* Put an end to the Verilog module */
|
||||||
|
print_verilog_module_end(fp, module_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Memory bank organization
|
||||||
|
*
|
||||||
|
* Bit lines(BL/BLB) Word lines (WL/WLB)
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* +------------------------------------+
|
||||||
|
* | Memory Module Configuration port |
|
||||||
|
* +------------------------------------+
|
||||||
|
* | | |
|
||||||
|
* v v v
|
||||||
|
* +-------+ +-------+ +-------+
|
||||||
|
* | SRAM | | SRAM | ... | SRAM |
|
||||||
|
* | [0] | | [1] | | [N-1] |
|
||||||
|
* +-------+ +-------+ +-------+
|
||||||
|
* | | ... |
|
||||||
|
* v v v
|
||||||
|
* +------------------------------------+
|
||||||
|
* | Multiplexer Configuration port |
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_memory_bank_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);
|
||||||
|
|
||||||
|
/* 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<enum e_spice_model_port_type> global_port_types;
|
||||||
|
global_port_types.push_back(SPICE_MODEL_PORT_CLOCK);
|
||||||
|
global_port_types.push_back(SPICE_MODEL_PORT_INPUT);
|
||||||
|
std::vector<CircuitPortId> 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<CircuitPortId> sram_input_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_INPUT, true);
|
||||||
|
/* A SRAM cell with BL/WL should not have any input */
|
||||||
|
VTR_ASSERT( 0 == 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);
|
||||||
/* Get the BL/WL ports from the SRAM */
|
/* Get the BL/WL ports from the SRAM */
|
||||||
std::vector<CircuitPortId> sram_bl_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_BL, true);
|
std::vector<CircuitPortId> sram_bl_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_BL, true);
|
||||||
std::vector<CircuitPortId> sram_blb_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_BLB, true);
|
std::vector<CircuitPortId> sram_blb_ports = circuit_lib.model_ports_by_type(sram_model, SPICE_MODEL_PORT_BLB, true);
|
||||||
|
@ -134,14 +292,7 @@ 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);
|
||||||
}
|
}
|
||||||
/* TODO: when Configuration-chain style is selected, the port map should be different!
|
/* Add each input port */
|
||||||
* 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);
|
||||||
|
@ -214,16 +365,54 @@ 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!!! */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Add local decoders here if required */
|
/* TODO: if a local memory decoder is required, instanciate it here */
|
||||||
|
|
||||||
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Generate Verilog modules for the memories that are used
|
||||||
|
* by a circuit model
|
||||||
|
* The organization of memory circuit will depend on the style of
|
||||||
|
* configuration protocols
|
||||||
|
* Currently, we support
|
||||||
|
* 1. Flat SRAM organization
|
||||||
|
* 2. Configuration chain
|
||||||
|
* 3. Memory bank (memory decoders)
|
||||||
|
********************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_memory_module(ModuleManager& module_manager,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const e_sram_orgz& sram_orgz_type,
|
||||||
|
std::fstream& fp,
|
||||||
|
const std::string& module_name,
|
||||||
|
const CircuitModelId& sram_model,
|
||||||
|
const size_t& num_mems) {
|
||||||
|
switch (sram_orgz_type) {
|
||||||
|
case SPICE_SRAM_STANDALONE:
|
||||||
|
print_verilog_memory_standalone_module(module_manager, circuit_lib, fp,
|
||||||
|
module_name, sram_model, num_mems);
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN:
|
||||||
|
print_verilog_memory_chain_module(module_manager, circuit_lib, fp,
|
||||||
|
module_name, sram_model, num_mems);
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_MEMORY_BANK:
|
||||||
|
print_verilog_memory_bank_module(module_manager, circuit_lib, fp,
|
||||||
|
module_name, sram_model, num_mems);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s, LINE%d) Invalid SRAM organization!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* Generate Verilog modules for the memories that are used
|
* Generate Verilog modules for the memories that are used
|
||||||
* by multiplexers
|
* by multiplexers
|
||||||
|
@ -240,6 +429,7 @@ void print_verilog_memory_module(ModuleManager& module_manager,
|
||||||
static
|
static
|
||||||
void print_verilog_mux_memory_module(ModuleManager& module_manager,
|
void print_verilog_mux_memory_module(ModuleManager& module_manager,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const e_sram_orgz& sram_orgz_type,
|
||||||
std::fstream& fp,
|
std::fstream& fp,
|
||||||
const CircuitModelId& mux_model,
|
const CircuitModelId& mux_model,
|
||||||
const MuxGraph& mux_graph) {
|
const MuxGraph& mux_graph) {
|
||||||
|
@ -258,7 +448,7 @@ void print_verilog_mux_memory_module(ModuleManager& module_manager,
|
||||||
/* Find the number of SRAMs in the module, this is also the port width */
|
/* Find the number of SRAMs in the module, this is also the port width */
|
||||||
size_t num_mems = mux_graph.num_memory_bits();
|
size_t num_mems = mux_graph.num_memory_bits();
|
||||||
|
|
||||||
print_verilog_memory_module(module_manager, circuit_lib, 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_mems);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPICE_MODEL_DESIGN_RRAM:
|
case SPICE_MODEL_DESIGN_RRAM:
|
||||||
|
@ -295,6 +485,7 @@ void print_verilog_mux_memory_module(ModuleManager& module_manager,
|
||||||
void print_verilog_submodule_memories(ModuleManager& module_manager,
|
void print_verilog_submodule_memories(ModuleManager& module_manager,
|
||||||
const MuxLibrary& mux_lib,
|
const MuxLibrary& mux_lib,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const e_sram_orgz& sram_orgz_type,
|
||||||
const std::string& verilog_dir,
|
const std::string& verilog_dir,
|
||||||
const std::string& submodule_dir) {
|
const std::string& submodule_dir) {
|
||||||
/* Plug in with the mux subckt */
|
/* Plug in with the mux subckt */
|
||||||
|
@ -328,7 +519,7 @@ void print_verilog_submodule_memories(ModuleManager& module_manager,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Create a Verilog module for the memories used by the multiplexer */
|
/* Create a Verilog module for the memories used by the multiplexer */
|
||||||
print_verilog_mux_memory_module(module_manager, circuit_lib, fp, mux_model, mux_graph);
|
print_verilog_mux_memory_module(module_manager, circuit_lib, sram_orgz_type, fp, mux_model, mux_graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the memory circuits for non-MUX circuit models.
|
/* Create the memory circuits for non-MUX circuit models.
|
||||||
|
@ -370,7 +561,7 @@ void print_verilog_submodule_memories(ModuleManager& module_manager,
|
||||||
std::string module_name = generate_memory_module_name(circuit_lib, model, sram_models[0], std::string(verilog_mem_posfix));
|
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 */
|
/* 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);
|
print_verilog_memory_module(module_manager, circuit_lib, sram_orgz_type, fp, module_name, sram_models[0], num_mems);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close the file stream */
|
/* Close the file stream */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
void print_verilog_submodule_memories(ModuleManager& module_manager,
|
void print_verilog_submodule_memories(ModuleManager& module_manager,
|
||||||
const MuxLibrary& mux_lib,
|
const MuxLibrary& mux_lib,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const e_sram_orgz& sram_orgz_type,
|
||||||
const std::string& verilog_dir,
|
const std::string& verilog_dir,
|
||||||
const std::string& submodule_dir);
|
const std::string& submodule_dir);
|
||||||
|
|
||||||
|
|
|
@ -1381,6 +1381,10 @@ void generate_verilog_cmos_mux_module(ModuleManager& module_manager,
|
||||||
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
|
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: the size of of memory ports depend on
|
||||||
|
* if a local encoder is used for the mux or not
|
||||||
|
*/
|
||||||
size_t sram_port_cnt = 0;
|
size_t sram_port_cnt = 0;
|
||||||
for (const auto& port : mux_sram_ports) {
|
for (const auto& port : mux_sram_ports) {
|
||||||
/* Multiplexing structure does not mode_sram_ports, they are handled in LUT modules
|
/* Multiplexing structure does not mode_sram_ports, they are handled in LUT modules
|
||||||
|
@ -1426,6 +1430,8 @@ void generate_verilog_cmos_mux_module(ModuleManager& module_manager,
|
||||||
generate_verilog_cmos_mux_module_input_buffers(module_manager, circuit_lib, fp, module_id, circuit_model, mux_graph);
|
generate_verilog_cmos_mux_module_input_buffers(module_manager, circuit_lib, fp, module_id, circuit_model, mux_graph);
|
||||||
generate_verilog_cmos_mux_module_output_buffers(module_manager, circuit_lib, fp, module_id, circuit_model, mux_graph);
|
generate_verilog_cmos_mux_module_output_buffers(module_manager, circuit_lib, fp, module_id, circuit_model, mux_graph);
|
||||||
|
|
||||||
|
/* TODO: add local decoder instance here */
|
||||||
|
|
||||||
/* 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3201,9 +3201,13 @@ void dump_verilog_submodules(ModuleManager& module_manager,
|
||||||
dump_verilog_submodule_muxes(cur_sram_orgz_info, verilog_dir, submodule_dir, routing_arch->num_switch,
|
dump_verilog_submodule_muxes(cur_sram_orgz_info, verilog_dir, submodule_dir, routing_arch->num_switch,
|
||||||
switch_inf, Arch.spice, routing_arch, fpga_verilog_opts.dump_explicit_verilog);
|
switch_inf, Arch.spice, routing_arch, fpga_verilog_opts.dump_explicit_verilog);
|
||||||
|
|
||||||
|
/* NOTE: local decoders generation must go before the MUX generation!!!
|
||||||
|
* because local decoders modules will be instanciated in the MUX modules
|
||||||
|
*/
|
||||||
|
print_verilog_submodule_mux_local_decoders(module_manager, mux_lib, Arch.spice->circuit_lib,
|
||||||
|
std::string(verilog_dir), std::string(submodule_dir));
|
||||||
print_verilog_submodule_muxes(module_manager, mux_lib, Arch.spice->circuit_lib, cur_sram_orgz_info, std::string(verilog_dir), std::string(submodule_dir));
|
print_verilog_submodule_muxes(module_manager, mux_lib, Arch.spice->circuit_lib, cur_sram_orgz_info, std::string(verilog_dir), std::string(submodule_dir));
|
||||||
|
|
||||||
print_verilog_submodule_mux_local_decoders(module_manager, mux_lib, Arch.spice->circuit_lib, std::string(verilog_dir), std::string(submodule_dir));
|
|
||||||
|
|
||||||
/* 2. LUTes */
|
/* 2. LUTes */
|
||||||
vpr_printf(TIO_MESSAGE_INFO, "Generating modules of LUTs...\n");
|
vpr_printf(TIO_MESSAGE_INFO, "Generating modules of LUTs...\n");
|
||||||
|
@ -3221,7 +3225,9 @@ void dump_verilog_submodules(ModuleManager& module_manager,
|
||||||
vpr_printf(TIO_MESSAGE_INFO, "Generating modules of memories...\n");
|
vpr_printf(TIO_MESSAGE_INFO, "Generating modules of memories...\n");
|
||||||
dump_verilog_submodule_memories(cur_sram_orgz_info, verilog_dir, submodule_dir, routing_arch->num_switch,
|
dump_verilog_submodule_memories(cur_sram_orgz_info, verilog_dir, submodule_dir, routing_arch->num_switch,
|
||||||
switch_inf, Arch.spice, routing_arch, fpga_verilog_opts.dump_explicit_verilog);
|
switch_inf, Arch.spice, routing_arch, fpga_verilog_opts.dump_explicit_verilog);
|
||||||
print_verilog_submodule_memories(module_manager, mux_lib, Arch.spice->circuit_lib, std::string(verilog_dir), std::string(submodule_dir));
|
print_verilog_submodule_memories(module_manager, mux_lib, Arch.spice->circuit_lib,
|
||||||
|
cur_sram_orgz_info->type,
|
||||||
|
std::string(verilog_dir), std::string(submodule_dir));
|
||||||
|
|
||||||
/* 5. Dump template for all the modules */
|
/* 5. Dump template for all the modules */
|
||||||
if (TRUE == fpga_verilog_opts.print_user_defined_template) {
|
if (TRUE == fpga_verilog_opts.print_user_defined_template) {
|
||||||
|
|
Loading…
Reference in New Issue