refactored memory module Verilog generation for scan-chains
This commit is contained in:
parent
b082e60c10
commit
b905c0c68c
|
@ -0,0 +1,272 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* This file includes functions that are used for
|
||||||
|
* generating ports for memory modules
|
||||||
|
*********************************************************************/
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "fpga_x2p_naming.h"
|
||||||
|
#include "fpga_x2p_mem_utils.h"
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Create a port-to-port map for a CMOS memory module
|
||||||
|
*
|
||||||
|
* Configuration Chain
|
||||||
|
* -------------------
|
||||||
|
*
|
||||||
|
* config_bus (head) config_bus (tail)
|
||||||
|
* | ^
|
||||||
|
* v |
|
||||||
|
* +-------------------------------------+
|
||||||
|
* | CMOS-based Memory Module |
|
||||||
|
* +-------------------------------------+
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* sram_out sram_outb
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Memory bank
|
||||||
|
* -----------
|
||||||
|
*
|
||||||
|
* config_bus (BL) config_bus (WL)
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* +-------------------------------------+
|
||||||
|
* | CMOS-based Memory Module |
|
||||||
|
* +-------------------------------------+
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* sram_out sram_outb
|
||||||
|
*
|
||||||
|
**********************************************************************/
|
||||||
|
static
|
||||||
|
std::map<std::string, BasicPort> generate_cmos_mem_module_port2port_map(const ModuleManager& module_manager,
|
||||||
|
const ModuleId& mem_module,
|
||||||
|
const BasicPort& config_bus,
|
||||||
|
const std::vector<BasicPort>& mem_output_bus_ports,
|
||||||
|
const e_sram_orgz& sram_orgz_type) {
|
||||||
|
std::map<std::string, BasicPort> port2port_name_map;
|
||||||
|
|
||||||
|
switch (sram_orgz_type) {
|
||||||
|
case SPICE_SRAM_STANDALONE:
|
||||||
|
/* Nothing to do */
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN: {
|
||||||
|
/* Link the head port of the memory module:
|
||||||
|
* the LSB of config bus port is the head port index
|
||||||
|
*/
|
||||||
|
std::vector<BasicPort> config_bus_ports;
|
||||||
|
config_bus_ports.push_back(BasicPort(generate_local_config_bus_port_name(), config_bus.get_msb(), config_bus.get_msb() + 1));
|
||||||
|
BasicPort head_port(config_bus_ports[0].get_name(), config_bus_ports[0].get_lsb(), config_bus_ports[0].get_lsb());
|
||||||
|
port2port_name_map[generate_configuration_chain_head_name()] = head_port;
|
||||||
|
|
||||||
|
/* Link the tail port of the memory module:
|
||||||
|
* the MSB of config bus port is the tail port index
|
||||||
|
*/
|
||||||
|
BasicPort tail_port(config_bus_ports[0].get_name(), config_bus_ports[0].get_msb(), config_bus_ports[0].get_msb());
|
||||||
|
port2port_name_map[generate_configuration_chain_tail_name()] = tail_port;
|
||||||
|
|
||||||
|
/* Link the SRAM output ports of the memory module */
|
||||||
|
VTR_ASSERT( 2 == mem_output_bus_ports.size() );
|
||||||
|
port2port_name_map[generate_configuration_chain_data_out_name()] = mem_output_bus_ports[0];
|
||||||
|
port2port_name_map[generate_configuration_chain_inverted_data_out_name()] = mem_output_bus_ports[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPICE_SRAM_MEMORY_BANK:
|
||||||
|
/* TODO: */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid type of SRAM organization!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return port2port_name_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Create a port-to-port map for a ReRAM-based memory module
|
||||||
|
* Memory bank
|
||||||
|
* -----------
|
||||||
|
*
|
||||||
|
* config_bus (BL) config_bus (WL)
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* +-------------------------------------+
|
||||||
|
* | ReRAM-based Memory Module |
|
||||||
|
* +-------------------------------------+
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* Mem_out Mem_outb
|
||||||
|
**********************************************************************/
|
||||||
|
static
|
||||||
|
std::map<std::string, BasicPort> generate_rram_mem_module_port2port_map(const ModuleManager& module_manager,
|
||||||
|
const ModuleId& mem_module,
|
||||||
|
const BasicPort& config_bus,
|
||||||
|
const std::vector<BasicPort>& mem_output_bus_ports,
|
||||||
|
const e_sram_orgz& sram_orgz_type) {
|
||||||
|
std::map<std::string, BasicPort> port2port_name_map;
|
||||||
|
|
||||||
|
switch (sram_orgz_type) {
|
||||||
|
case SPICE_SRAM_STANDALONE:
|
||||||
|
/* Not supported */
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN: {
|
||||||
|
/* Link the head port of the memory module:
|
||||||
|
* the LSB of config bus port is the head port index
|
||||||
|
*/
|
||||||
|
std::vector<BasicPort> config_bus_ports;
|
||||||
|
config_bus_ports.push_back(BasicPort(generate_local_config_bus_port_name(), config_bus.get_msb(), config_bus.get_msb() + 1));
|
||||||
|
BasicPort head_port(config_bus_ports[0].get_name(), config_bus_ports[0].get_lsb(), config_bus_ports[0].get_lsb());
|
||||||
|
port2port_name_map[generate_configuration_chain_head_name()] = head_port;
|
||||||
|
|
||||||
|
/* Link the tail port of the memory module:
|
||||||
|
* the MSB of config bus port is the tail port index
|
||||||
|
*/
|
||||||
|
BasicPort tail_port(config_bus_ports[0].get_name(), config_bus_ports[0].get_msb(), config_bus_ports[0].get_msb());
|
||||||
|
port2port_name_map[generate_configuration_chain_tail_name()] = tail_port;
|
||||||
|
|
||||||
|
/* Link the SRAM output ports of the memory module */
|
||||||
|
VTR_ASSERT( 2 == mem_output_bus_ports.size() );
|
||||||
|
port2port_name_map[generate_configuration_chain_data_out_name()] = mem_output_bus_ports[0];
|
||||||
|
port2port_name_map[generate_configuration_chain_inverted_data_out_name()] = mem_output_bus_ports[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPICE_SRAM_MEMORY_BANK:
|
||||||
|
/* TODO: link BL/WL/Reserved Ports to the inputs of a memory module */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid type of SRAM organization!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return port2port_name_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Create a port-to-port map for a memory module
|
||||||
|
* The content of the port-to-port map will depend not only
|
||||||
|
* the design technology of the memory cells but also the
|
||||||
|
* configuration styles of FPGA fabric.
|
||||||
|
* Here we will branch on the design technology
|
||||||
|
**********************************************************************/
|
||||||
|
std::map<std::string, BasicPort> generate_mem_module_port2port_map(const ModuleManager& module_manager,
|
||||||
|
const ModuleId& mem_module,
|
||||||
|
const BasicPort& config_bus,
|
||||||
|
const std::vector<BasicPort>& mem_output_bus_ports,
|
||||||
|
const e_spice_model_design_tech& mem_design_tech,
|
||||||
|
const e_sram_orgz& sram_orgz_type) {
|
||||||
|
std::map<std::string, BasicPort> port2port_name_map;
|
||||||
|
|
||||||
|
switch (mem_design_tech) {
|
||||||
|
case SPICE_MODEL_DESIGN_CMOS:
|
||||||
|
port2port_name_map = generate_cmos_mem_module_port2port_map(module_manager, mem_module, config_bus, mem_output_bus_ports, sram_orgz_type);
|
||||||
|
break;
|
||||||
|
case SPICE_MODEL_DESIGN_RRAM:
|
||||||
|
port2port_name_map = generate_rram_mem_module_port2port_map(module_manager, mem_module, config_bus, mem_output_bus_ports, sram_orgz_type);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid type of memory design technology !\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return port2port_name_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Update the LSB and MSB of a configuration bus based on the number of
|
||||||
|
* memory bits of a CMOS memory module.
|
||||||
|
**********************************************************************/
|
||||||
|
static
|
||||||
|
void update_cmos_mem_module_config_bus(const e_sram_orgz& sram_orgz_type,
|
||||||
|
const size_t& num_config_bits,
|
||||||
|
BasicPort& config_bus) {
|
||||||
|
switch (sram_orgz_type) {
|
||||||
|
case SPICE_SRAM_STANDALONE:
|
||||||
|
/* Not supported */
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN:
|
||||||
|
/* Scan-chain of a memory module only has a head and a tail.
|
||||||
|
* LSB and MSB of configuration bus will be shifted to the next head.
|
||||||
|
*/
|
||||||
|
VTR_ASSERT(true == config_bus.rotate(1));
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_MEMORY_BANK:
|
||||||
|
/* In this case, a memory module has a number of BL/WL and BLB/WLB (possibly).
|
||||||
|
* LSB and MSB of configuration bus will be shifted by the number of BL/WL/BLB/WLB.
|
||||||
|
*/
|
||||||
|
VTR_ASSERT(true == config_bus.rotate(num_config_bits));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid type of SRAM organization!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Update the LSB and MSB of a configuration bus based on the number of
|
||||||
|
* memory bits of a ReRAM memory module.
|
||||||
|
**********************************************************************/
|
||||||
|
static
|
||||||
|
void update_rram_mem_module_config_bus(const e_sram_orgz& sram_orgz_type,
|
||||||
|
const size_t& num_config_bits,
|
||||||
|
BasicPort& config_bus) {
|
||||||
|
switch (sram_orgz_type) {
|
||||||
|
case SPICE_SRAM_STANDALONE:
|
||||||
|
/* Not supported */
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN:
|
||||||
|
/* Scan-chain of a memory module only has a head and a tail.
|
||||||
|
* LSB and MSB of configuration bus will be shifted to the next head.
|
||||||
|
* TODO: this may be changed later!!!
|
||||||
|
*/
|
||||||
|
VTR_ASSERT(true == config_bus.rotate(1));
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_MEMORY_BANK:
|
||||||
|
/* In this case, a memory module contains unique BL/WL or BLB/WLB,
|
||||||
|
* which are not shared with other modules
|
||||||
|
* TODO: this may be changed later!!!
|
||||||
|
*/
|
||||||
|
VTR_ASSERT(true == config_bus.rotate(1));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid type of SRAM organization!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Update the LSB and MSB of a configuration bus based on the number of
|
||||||
|
* memory bits of a module.
|
||||||
|
* Note that this function is designed to do such simple job, in purpose of
|
||||||
|
* being independent from adding ports or printing ports.
|
||||||
|
* As such, this function can be re-used in bitstream generation
|
||||||
|
* when Verilog generation is not needed.
|
||||||
|
* DO NOT update the configuration bus in the function of adding/printing ports
|
||||||
|
**********************************************************************/
|
||||||
|
void update_mem_module_config_bus(const e_sram_orgz& sram_orgz_type,
|
||||||
|
const e_spice_model_design_tech& mem_design_tech,
|
||||||
|
const size_t& num_config_bits,
|
||||||
|
BasicPort& config_bus) {
|
||||||
|
switch (mem_design_tech) {
|
||||||
|
case SPICE_MODEL_DESIGN_CMOS:
|
||||||
|
update_cmos_mem_module_config_bus(sram_orgz_type, num_config_bits, config_bus);
|
||||||
|
break;
|
||||||
|
case SPICE_MODEL_DESIGN_RRAM:
|
||||||
|
update_rram_mem_module_config_bus(sram_orgz_type, num_config_bits, config_bus);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid type of memory design technology !\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/********************************************************************
|
||||||
|
* Header file for fpga_x2p_mem_utils.cpp
|
||||||
|
**********************************************************************/
|
||||||
|
#ifndef FPGA_X2P_MEM_UTILS_H
|
||||||
|
#define FPGA_X2P_MEM_UTILS_H
|
||||||
|
|
||||||
|
/* Header files are included for the data types appear in the function declaration below */
|
||||||
|
#include <vector>
|
||||||
|
#include "device_port.h"
|
||||||
|
#include "spice_types.h"
|
||||||
|
#include "module_manager.h"
|
||||||
|
|
||||||
|
std::map<std::string, BasicPort> generate_mem_module_port2port_map(const ModuleManager& module_manager,
|
||||||
|
const ModuleId& mem_module,
|
||||||
|
const BasicPort& config_bus,
|
||||||
|
const std::vector<BasicPort>& mem_output_bus_ports,
|
||||||
|
const e_spice_model_design_tech& mem_design_tech,
|
||||||
|
const e_sram_orgz& sram_orgz_type);
|
||||||
|
|
||||||
|
void update_mem_module_config_bus(const e_sram_orgz& sram_orgz_type,
|
||||||
|
const e_spice_model_design_tech& mem_design_tech,
|
||||||
|
const size_t& num_config_bits,
|
||||||
|
BasicPort& config_bus);
|
||||||
|
|
||||||
|
#endif
|
|
@ -210,150 +210,3 @@ void add_sram_ports_to_module_manager(ModuleManager& module_manager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* Create a port-to-port map for a CMOS memory module
|
|
||||||
*
|
|
||||||
* Configuration Chain
|
|
||||||
* -------------------
|
|
||||||
*
|
|
||||||
* config_bus (head) config_bus (tail)
|
|
||||||
* | ^
|
|
||||||
* v |
|
|
||||||
* +-------------------------------------+
|
|
||||||
* | CMOS-based Memory Module |
|
|
||||||
* +-------------------------------------+
|
|
||||||
* | |
|
|
||||||
* v v
|
|
||||||
* sram_out sram_outb
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Memory bank
|
|
||||||
* -----------
|
|
||||||
*
|
|
||||||
* config_bus (BL) config_bus (WL)
|
|
||||||
* | |
|
|
||||||
* v v
|
|
||||||
* +-------------------------------------+
|
|
||||||
* | CMOS-based Memory Module |
|
|
||||||
* +-------------------------------------+
|
|
||||||
* | |
|
|
||||||
* v v
|
|
||||||
* sram_out sram_outb
|
|
||||||
*
|
|
||||||
**********************************************************************/
|
|
||||||
static
|
|
||||||
std::map<std::string, BasicPort> generate_cmos_mem_module_port2port_map(const ModuleManager& module_manager,
|
|
||||||
const ModuleId& mem_module,
|
|
||||||
const std::vector<BasicPort>& config_bus_ports,
|
|
||||||
const std::vector<BasicPort>& mem_output_bus_ports,
|
|
||||||
const e_sram_orgz& sram_orgz_type) {
|
|
||||||
std::map<std::string, BasicPort> port2port_name_map;
|
|
||||||
|
|
||||||
switch (sram_orgz_type) {
|
|
||||||
case SPICE_SRAM_STANDALONE:
|
|
||||||
/* Nothing to do */
|
|
||||||
break;
|
|
||||||
case SPICE_SRAM_SCAN_CHAIN: {
|
|
||||||
/* Link the head port of the memory module:
|
|
||||||
* the LSB of config bus port is the head port index
|
|
||||||
*/
|
|
||||||
VTR_ASSERT( 1 == config_bus_ports.size() );
|
|
||||||
BasicPort head_port(config_bus_ports[0].get_name(), config_bus_ports[0].get_lsb(), config_bus_ports[0].get_lsb());
|
|
||||||
port2port_name_map[generate_configuration_chain_head_name()] = head_port;
|
|
||||||
|
|
||||||
/* Link the tail port of the memory module:
|
|
||||||
* the MSB of config bus port is the tail port index
|
|
||||||
*/
|
|
||||||
BasicPort tail_port(config_bus_ports[0].get_name(), config_bus_ports[0].get_msb(), config_bus_ports[0].get_msb());
|
|
||||||
port2port_name_map[generate_configuration_chain_tail_name()] = tail_port;
|
|
||||||
|
|
||||||
/* Link the SRAM output ports of the memory module */
|
|
||||||
VTR_ASSERT( 2 == mem_output_bus_ports.size() );
|
|
||||||
port2port_name_map[generate_configuration_chain_data_out_name()] = mem_output_bus_ports[0];
|
|
||||||
port2port_name_map[generate_configuration_chain_inverted_data_out_name()] = mem_output_bus_ports[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SPICE_SRAM_MEMORY_BANK:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vpr_printf(TIO_MESSAGE_ERROR,
|
|
||||||
"(File:%s,[LINE%d])Invalid type of SRAM organization!\n",
|
|
||||||
__FILE__, __LINE__);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return port2port_name_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* Create a port-to-port map for a ReRAM-based memory module
|
|
||||||
* Memory bank
|
|
||||||
* -----------
|
|
||||||
*
|
|
||||||
* config_bus (BL) config_bus (WL)
|
|
||||||
* | |
|
|
||||||
* v v
|
|
||||||
* +-------------------------------------+
|
|
||||||
* | ReRAM-based Memory Module |
|
|
||||||
* +-------------------------------------+
|
|
||||||
* | |
|
|
||||||
* v v
|
|
||||||
* Mem_out Mem_outb
|
|
||||||
**********************************************************************/
|
|
||||||
static
|
|
||||||
std::map<std::string, BasicPort> generate_rram_mem_module_port2port_map(const ModuleManager& module_manager,
|
|
||||||
const ModuleId& mem_module,
|
|
||||||
const e_sram_orgz& sram_orgz_type) {
|
|
||||||
std::map<std::string, BasicPort> port2port_name_map;
|
|
||||||
|
|
||||||
switch (sram_orgz_type) {
|
|
||||||
case SPICE_SRAM_STANDALONE:
|
|
||||||
/* Not supported */
|
|
||||||
break;
|
|
||||||
case SPICE_SRAM_SCAN_CHAIN:
|
|
||||||
/* TODO: to be supported */
|
|
||||||
break;
|
|
||||||
case SPICE_SRAM_MEMORY_BANK:
|
|
||||||
/* TODO: link BL/WL/Reserved Ports to the inputs of a memory module */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vpr_printf(TIO_MESSAGE_ERROR,
|
|
||||||
"(File:%s,[LINE%d])Invalid type of SRAM organization!\n",
|
|
||||||
__FILE__, __LINE__);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return port2port_name_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* Create a port-to-port map for a memory module
|
|
||||||
* The content of the port-to-port map will depend not only
|
|
||||||
* the design technology of the memory cells but also the
|
|
||||||
* configuration styles of FPGA fabric.
|
|
||||||
* Here we will branch on the design technology
|
|
||||||
**********************************************************************/
|
|
||||||
std::map<std::string, BasicPort> generate_mem_module_port2port_map(const ModuleManager& module_manager,
|
|
||||||
const ModuleId& mem_module,
|
|
||||||
const std::vector<BasicPort>& config_bus_ports,
|
|
||||||
const std::vector<BasicPort>& mem_output_bus_ports,
|
|
||||||
const e_spice_model_design_tech& mem_design_tech,
|
|
||||||
const e_sram_orgz& sram_orgz_type) {
|
|
||||||
std::map<std::string, BasicPort> port2port_name_map;
|
|
||||||
|
|
||||||
switch (mem_design_tech) {
|
|
||||||
case SPICE_MODEL_DESIGN_CMOS:
|
|
||||||
port2port_name_map = generate_cmos_mem_module_port2port_map(module_manager, mem_module, config_bus_ports, mem_output_bus_ports, sram_orgz_type);
|
|
||||||
break;
|
|
||||||
case SPICE_MODEL_DESIGN_RRAM:
|
|
||||||
port2port_name_map = generate_rram_mem_module_port2port_map(module_manager, mem_module, sram_orgz_type);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vpr_printf(TIO_MESSAGE_ERROR,
|
|
||||||
"(File:%s,[LINE%d])Invalid type of memory design technology !\n",
|
|
||||||
__FILE__, __LINE__);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return port2port_name_map;
|
|
||||||
}
|
|
||||||
|
|
|
@ -38,12 +38,5 @@ void add_sram_ports_to_module_manager(ModuleManager& module_manager,
|
||||||
const e_sram_orgz sram_orgz_type,
|
const e_sram_orgz sram_orgz_type,
|
||||||
const size_t& port_size);
|
const size_t& port_size);
|
||||||
|
|
||||||
std::map<std::string, BasicPort> generate_mem_module_port2port_map(const ModuleManager& module_manager,
|
|
||||||
const ModuleId& mem_module,
|
|
||||||
const std::vector<BasicPort>& config_bus_ports,
|
|
||||||
const std::vector<BasicPort>& mem_output_bus_ports,
|
|
||||||
const e_spice_model_design_tech& mem_design_tech,
|
|
||||||
const e_sram_orgz& sram_orgz_type);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "mux_utils.h"
|
#include "mux_utils.h"
|
||||||
#include "module_manager.h"
|
#include "module_manager.h"
|
||||||
#include "module_manager_utils.h"
|
#include "module_manager_utils.h"
|
||||||
|
#include "fpga_x2p_mem_utils.h"
|
||||||
|
|
||||||
/* Include Verilog support headers*/
|
/* Include Verilog support headers*/
|
||||||
#include "verilog_global.h"
|
#include "verilog_global.h"
|
||||||
|
@ -2321,6 +2322,7 @@ static
|
||||||
void print_verilog_unique_switch_box_mux(ModuleManager& module_manager,
|
void print_verilog_unique_switch_box_mux(ModuleManager& module_manager,
|
||||||
std::fstream& fp,
|
std::fstream& fp,
|
||||||
t_sram_orgz_info* cur_sram_orgz_info,
|
t_sram_orgz_info* cur_sram_orgz_info,
|
||||||
|
BasicPort& config_bus,
|
||||||
const ModuleId& sb_module,
|
const ModuleId& sb_module,
|
||||||
const RRGSB& rr_sb,
|
const RRGSB& rr_sb,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
|
@ -2451,18 +2453,22 @@ void print_verilog_unique_switch_box_mux(ModuleManager& module_manager,
|
||||||
std::map<std::string, BasicPort> mem_port2port_name_map;
|
std::map<std::string, BasicPort> mem_port2port_name_map;
|
||||||
|
|
||||||
/* TODO: Make the port2port map generation more generic!!! */
|
/* TODO: Make the port2port map generation more generic!!! */
|
||||||
std::vector<BasicPort> config_ports;
|
/* Link the SRAM ports of the routing multiplexer to the memory module */
|
||||||
config_ports.push_back(BasicPort(generate_local_config_bus_port_name(), mux_instance_id - 1, mux_instance_id));
|
|
||||||
std::vector<BasicPort> mem_output_ports;
|
std::vector<BasicPort> mem_output_ports;
|
||||||
mem_output_ports.push_back(mux_config_port);
|
mem_output_ports.push_back(mux_config_port);
|
||||||
mem_output_ports.push_back(mux_config_inv_port);
|
mem_output_ports.push_back(mux_config_inv_port);
|
||||||
mem_port2port_name_map = generate_mem_module_port2port_map(module_manager, mem_module,
|
mem_port2port_name_map = generate_mem_module_port2port_map(module_manager, mem_module,
|
||||||
config_ports,
|
config_bus,
|
||||||
mem_output_ports,
|
mem_output_ports,
|
||||||
circuit_lib.design_tech_type(mux_model),
|
circuit_lib.design_tech_type(mux_model),
|
||||||
cur_sram_orgz_info->type);
|
cur_sram_orgz_info->type);
|
||||||
|
/* Update the config bus for the module */
|
||||||
|
update_mem_module_config_bus(cur_sram_orgz_info->type,
|
||||||
|
circuit_lib.design_tech_type(mux_model),
|
||||||
|
mux_num_config_bits,
|
||||||
|
config_bus);
|
||||||
|
|
||||||
/* Print an instance of the MUX Module */
|
/* Print an instance of the memory module associated with the routing multiplexer */
|
||||||
print_verilog_comment(fp, std::string("----- BEGIN Instanciation of memory cells for a routing multiplexer -----"));
|
print_verilog_comment(fp, std::string("----- BEGIN Instanciation of memory cells for a routing multiplexer -----"));
|
||||||
print_verilog_module_instance(fp, module_manager, sb_module, mem_module, mem_port2port_name_map, use_explicit_mapping);
|
print_verilog_module_instance(fp, module_manager, sb_module, mem_module, mem_port2port_name_map, use_explicit_mapping);
|
||||||
print_verilog_comment(fp, std::string("----- END Instanciation of memory cells for a routing multiplexer -----"));
|
print_verilog_comment(fp, std::string("----- END Instanciation of memory cells for a routing multiplexer -----"));
|
||||||
|
@ -2491,6 +2497,7 @@ static
|
||||||
void print_verilog_unique_switch_box_interc(ModuleManager& module_manager,
|
void print_verilog_unique_switch_box_interc(ModuleManager& module_manager,
|
||||||
std::fstream& fp,
|
std::fstream& fp,
|
||||||
t_sram_orgz_info* cur_sram_orgz_info,
|
t_sram_orgz_info* cur_sram_orgz_info,
|
||||||
|
BasicPort& config_bus,
|
||||||
const ModuleId& sb_module,
|
const ModuleId& sb_module,
|
||||||
const RRGSB& rr_sb,
|
const RRGSB& rr_sb,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
|
@ -2525,7 +2532,7 @@ void print_verilog_unique_switch_box_interc(ModuleManager& module_manager,
|
||||||
drive_rr_nodes[DEFAULT_SWITCH_ID]);
|
drive_rr_nodes[DEFAULT_SWITCH_ID]);
|
||||||
} else if (1 < drive_rr_nodes.size()) {
|
} else if (1 < drive_rr_nodes.size()) {
|
||||||
/* Print the multiplexer, fan_in >= 2 */
|
/* Print the multiplexer, fan_in >= 2 */
|
||||||
print_verilog_unique_switch_box_mux(module_manager, fp, cur_sram_orgz_info,
|
print_verilog_unique_switch_box_mux(module_manager, fp, cur_sram_orgz_info, config_bus,
|
||||||
sb_module, rr_sb, circuit_lib, mux_lib,
|
sb_module, rr_sb, circuit_lib, mux_lib,
|
||||||
rr_switches, chan_side, cur_rr_node,
|
rr_switches, chan_side, cur_rr_node,
|
||||||
drive_rr_nodes,
|
drive_rr_nodes,
|
||||||
|
@ -2725,6 +2732,11 @@ void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manage
|
||||||
rr_gsb.get_sb_num_conf_bits());
|
rr_gsb.get_sb_num_conf_bits());
|
||||||
print_verilog_comment(fp, std::string("---- END local wires for SRAM data ports ----"));
|
print_verilog_comment(fp, std::string("---- END local wires for SRAM data ports ----"));
|
||||||
|
|
||||||
|
/* Create a counter for the configuration bus */
|
||||||
|
BasicPort config_bus;
|
||||||
|
/* Counter start from 0 */
|
||||||
|
config_bus.set_width(0, 0);
|
||||||
|
|
||||||
/* TODO: Print routing multiplexers */
|
/* TODO: Print routing multiplexers */
|
||||||
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
|
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
|
||||||
Side side_manager(side);
|
Side side_manager(side);
|
||||||
|
@ -2732,7 +2744,8 @@ void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manage
|
||||||
for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) {
|
for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) {
|
||||||
/* We care INC_DIRECTION tracks at this side*/
|
/* We care INC_DIRECTION tracks at this side*/
|
||||||
if (OUT_PORT == rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
if (OUT_PORT == rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||||
print_verilog_unique_switch_box_interc(module_manager, fp, cur_sram_orgz_info, module_id, rr_sb,
|
print_verilog_unique_switch_box_interc(module_manager, fp, cur_sram_orgz_info, config_bus,
|
||||||
|
module_id, rr_sb,
|
||||||
circuit_lib, mux_lib, rr_switches,
|
circuit_lib, mux_lib, rr_switches,
|
||||||
side_manager.get_side(),
|
side_manager.get_side(),
|
||||||
itrack, is_explicit_mapping);
|
itrack, is_explicit_mapping);
|
||||||
|
@ -2740,6 +2753,8 @@ void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Add check code for config_bus. The MSB should match the number of configuration bits!!! */
|
||||||
|
|
||||||
/* Put an end to the Verilog module */
|
/* Put an end to the Verilog module */
|
||||||
print_verilog_module_end(fp, module_manager.module_name(module_id));
|
print_verilog_module_end(fp, module_manager.module_name(module_id));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue