refactored local wire generation for Switch block
This commit is contained in:
parent
2b0e2615fa
commit
5bb40e7f74
|
@ -307,8 +307,6 @@ 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
|
* 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
|
* 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_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) {
|
||||||
|
@ -318,17 +316,14 @@ std::string generate_formal_verification_sram_port_name(const CircuitLibrary& ci
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* Generate the port name for a regular sram port
|
* Generate the port name for a regular sram port which appears in the
|
||||||
|
* port list of a module
|
||||||
* The port name is named after the cell name of SRAM in circuit library
|
* 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,
|
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,
|
||||||
const e_spice_model_port_type& port_type) {
|
const e_spice_model_port_type& port_type) {
|
||||||
/* Get memory_model */
|
|
||||||
|
|
||||||
std::string port_name = circuit_lib.model_name(sram_model) + std::string("_");
|
std::string port_name = circuit_lib.model_name(sram_model) + std::string("_");
|
||||||
|
|
||||||
switch (sram_orgz_type) {
|
switch (sram_orgz_type) {
|
||||||
|
@ -395,3 +390,69 @@ std::string generate_sram_port_name(const CircuitLibrary& circuit_lib,
|
||||||
|
|
||||||
return port_name;
|
return port_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Generate the port name for a regular sram port which is an internal
|
||||||
|
* wire of a module
|
||||||
|
* The port name is named after the cell name of SRAM in circuit library
|
||||||
|
*********************************************************************/
|
||||||
|
std::string generate_sram_local_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) {
|
||||||
|
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_local_bus");
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT( SPICE_MODEL_PORT_OUTPUT == port_type );
|
||||||
|
port_name += std::string("outb_local_bus");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN:
|
||||||
|
/* Three types of ports are available:
|
||||||
|
* (1) Input of Scan-chain Flip-Flops (SCFFs), enabled by port type of INPUT
|
||||||
|
* (2) Output of a chian of Scan-chain Flip-flops (SCFFs), enabled by port type of OUTPUT
|
||||||
|
* (2) Inverted output of a chian of Scan-chain Flip-flops (SCFFs), enabled by port type of INOUT
|
||||||
|
* +------+ +------+ +------+
|
||||||
|
* Head --->| SCFF |--->| SCFF |--->| SCFF |---> Tail
|
||||||
|
* +------+ +------+ +------+
|
||||||
|
*/
|
||||||
|
if (SPICE_MODEL_PORT_INPUT == port_type) {
|
||||||
|
port_name += std::string("scff_in_local_bus");
|
||||||
|
} else if ( SPICE_MODEL_PORT_OUTPUT == port_type ) {
|
||||||
|
port_name += std::string("scff_out_local_bus");
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT( SPICE_MODEL_PORT_INOUT == port_type );
|
||||||
|
port_name += std::string("scff_outb_local_bus");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_MEMORY_BANK: {
|
||||||
|
/* 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_local_bus");
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT( SPICE_MODEL_PORT_OUTPUT == port_type );
|
||||||
|
port_name += std::string("outb_local_bus");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid type of SRAM organization !\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return port_name;
|
||||||
|
}
|
||||||
|
|
|
@ -77,4 +77,9 @@ std::string generate_sram_port_name(const CircuitLibrary& circuit_lib,
|
||||||
const e_sram_orgz& sram_orgz_type,
|
const e_sram_orgz& sram_orgz_type,
|
||||||
const e_spice_model_port_type& port_type);
|
const e_spice_model_port_type& port_type);
|
||||||
|
|
||||||
|
std::string generate_sram_local_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
|
#endif
|
||||||
|
|
|
@ -482,7 +482,7 @@ void link_circuit_library_to_arch(t_arch* arch,
|
||||||
/* Check Circuit models first*/
|
/* Check Circuit models first*/
|
||||||
VTR_ASSERT_SAFE( (NULL != arch) && (NULL != arch->spice) );
|
VTR_ASSERT_SAFE( (NULL != arch) && (NULL != arch->spice) );
|
||||||
|
|
||||||
/* 1. Link the spice model defined in pb_types and routing switches */
|
/* 1. Link the circuit model defined in pb_types and routing switches */
|
||||||
/* Step A: Check routing switches, connection blocks*/
|
/* Step A: Check routing switches, connection blocks*/
|
||||||
if (0 >= arch->num_cb_switch) {
|
if (0 >= arch->num_cb_switch) {
|
||||||
vpr_printf(TIO_MESSAGE_ERROR,
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
@ -500,7 +500,7 @@ void link_circuit_library_to_arch(t_arch* arch,
|
||||||
__FILE__, __LINE__, arch->cb_switches[i].spice_model_name, arch->cb_switches[i].name);
|
__FILE__, __LINE__, arch->cb_switches[i].spice_model_name, arch->cb_switches[i].name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/* Check the spice model structure is matched with the structure in switch_inf */
|
/* Check the circuit model structure is matched with the structure in switch_inf */
|
||||||
if (0 < check_circuit_model_structure_match_switch_inf(arch->cb_switches[i], arch->spice->circuit_lib)) {
|
if (0 < check_circuit_model_structure_match_switch_inf(arch->cb_switches[i], arch->spice->circuit_lib)) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,7 @@ void link_circuit_library_to_arch(t_arch* arch,
|
||||||
/* Step C: Find SRAM Model*/
|
/* Step C: Find SRAM Model*/
|
||||||
link_sram_inf(&(arch->sram_inf), arch->spice->circuit_lib);
|
link_sram_inf(&(arch->sram_inf), arch->spice->circuit_lib);
|
||||||
|
|
||||||
/* Step D: Find the segment spice_model*/
|
/* Step D: Find the segment circuit_model*/
|
||||||
for (int i = 0; i < arch->num_segments; i++) {
|
for (int i = 0; i < arch->num_segments; i++) {
|
||||||
arch->Segments[i].circuit_model = link_circuit_model_by_name_and_type(arch->Segments[i].spice_model_name,
|
arch->Segments[i].circuit_model = link_circuit_model_by_name_and_type(arch->Segments[i].spice_model_name,
|
||||||
arch->spice->circuit_lib, SPICE_MODEL_CHAN_WIRE);
|
arch->spice->circuit_lib, SPICE_MODEL_CHAN_WIRE);
|
||||||
|
@ -562,7 +562,7 @@ void link_circuit_library_to_arch(t_arch* arch,
|
||||||
for (int i = 0; i < arch->num_directs; i++) {
|
for (int i = 0; i < arch->num_directs; i++) {
|
||||||
arch->Directs[i].circuit_model = link_circuit_model_by_name_and_type(arch->Directs[i].spice_model_name,
|
arch->Directs[i].circuit_model = link_circuit_model_by_name_and_type(arch->Directs[i].spice_model_name,
|
||||||
arch->spice->circuit_lib, SPICE_MODEL_WIRE);
|
arch->spice->circuit_lib, SPICE_MODEL_WIRE);
|
||||||
/* Check SPICE model type */
|
/* Check Circuit model type */
|
||||||
if (CircuitModelId::INVALID() == arch->Directs[i].circuit_model) {
|
if (CircuitModelId::INVALID() == arch->Directs[i].circuit_model) {
|
||||||
vpr_printf(TIO_MESSAGE_ERROR,
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
"(FILE:%s, LINE[%d])Invalid circuit model name(%s) of CLB to CLB Direct Connection (name=%s) is undefined in circuit models!\n",
|
"(FILE:%s, LINE[%d])Invalid circuit model name(%s) of CLB to CLB Direct Connection (name=%s) is undefined in circuit models!\n",
|
||||||
|
|
|
@ -140,6 +140,8 @@ void add_formal_verification_sram_ports_to_module_manager(ModuleManager& module_
|
||||||
* 2. Scan-chain Flip-flops:
|
* 2. Scan-chain Flip-flops:
|
||||||
* two ports will be added, which are the head of scan-chain
|
* two ports will be added, which are the head of scan-chain
|
||||||
* and the tail of scan-chain
|
* and the tail of scan-chain
|
||||||
|
* IMPORTANT: the port size will be forced to 1 in this case
|
||||||
|
* because the head and tail are both 1-bit ports!!!
|
||||||
* 3. Memory decoders:
|
* 3. Memory decoders:
|
||||||
* 2-4 ports will be added, depending on the ports available in the SRAM
|
* 2-4 ports will be added, depending on the ports available in the SRAM
|
||||||
* Among these, two ports are mandatory: BL and WL
|
* Among these, two ports are mandatory: BL and WL
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* This function will find the global ports required by a Switch Block
|
* This function will find the global ports required by a Switch Block
|
||||||
* module. It wil find all the circuit models in the circuit library
|
* module. It will find all the circuit models in the circuit library
|
||||||
* that may be included in the Switch Block
|
* that may be included in the Switch Block
|
||||||
* Collect the global ports from the circuit_models and merge with the same name
|
* Collect the global ports from the circuit_models and merge with the same name
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
@ -60,3 +60,31 @@ std::vector<CircuitPortId> find_switch_block_global_ports(const RRGSB& rr_gsb,
|
||||||
|
|
||||||
return global_ports;
|
return global_ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* This function will find the number of multiplexers required by
|
||||||
|
* a Switch Block module.
|
||||||
|
********************************************************************/
|
||||||
|
size_t find_switch_block_number_of_muxes(const RRGSB& rr_gsb) {
|
||||||
|
size_t num_muxes = 0;
|
||||||
|
/* Walk through the OUTPUT nodes at each side of a GSB,
|
||||||
|
* get the switch id of incoming edges
|
||||||
|
* and get the circuit model linked to the switch id
|
||||||
|
*/
|
||||||
|
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
|
||||||
|
Side side_manager(side);
|
||||||
|
for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) {
|
||||||
|
if (OUT_PORT != rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Check if this node is driven by a multiplexer */
|
||||||
|
if (true == rr_gsb.is_sb_node_passing_wire(side_manager.get_side(), itrack)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* This means we need a multiplexer, update the counter */
|
||||||
|
num_muxes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num_muxes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,4 +14,6 @@ std::vector<CircuitPortId> find_switch_block_global_ports(const RRGSB& rr_gsb,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
const std::vector<t_switch_inf>& switch_lib);
|
const std::vector<t_switch_inf>& switch_lib);
|
||||||
|
|
||||||
|
size_t find_switch_block_number_of_muxes(const RRGSB& rr_gsb);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,6 +48,27 @@
|
||||||
#include "verilog_writer_utils.h"
|
#include "verilog_writer_utils.h"
|
||||||
#include "verilog_routing.h"
|
#include "verilog_routing.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Print local wires that are used for SRAM configuration
|
||||||
|
* This function is supposed to be used by Verilog generation
|
||||||
|
* of switch blocks
|
||||||
|
* It will count the number of switch blocks, which is the
|
||||||
|
* port width for local wires when Configuration chain is used
|
||||||
|
********************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_switch_block_local_sram_wires(std::fstream& fp,
|
||||||
|
const RRGSB& rr_gsb,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& sram_model,
|
||||||
|
const e_sram_orgz sram_orgz_type,
|
||||||
|
const size_t& port_size) {
|
||||||
|
size_t local_port_size = port_size;
|
||||||
|
if (SPICE_SRAM_SCAN_CHAIN == sram_orgz_type) {
|
||||||
|
local_port_size = find_switch_block_number_of_muxes(rr_gsb);
|
||||||
|
}
|
||||||
|
print_verilog_local_sram_wires(fp, circuit_lib, sram_model, sram_orgz_type, local_port_size);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* Generate the Verilog module for a routing channel
|
* Generate the Verilog module for a routing channel
|
||||||
* Routing track wire, which is 1-input and dual output
|
* Routing track wire, which is 1-input and dual output
|
||||||
|
@ -2287,13 +2308,15 @@ void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manage
|
||||||
add_reserved_sram_ports_to_module_manager(module_manager, module_id,
|
add_reserved_sram_ports_to_module_manager(module_manager, module_id,
|
||||||
rr_gsb.get_sb_num_reserved_conf_bits());
|
rr_gsb.get_sb_num_reserved_conf_bits());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
/* Normal sram ports */
|
/* Normal sram ports */
|
||||||
if (0 < rr_gsb.get_sb_num_conf_bits()) {
|
if (0 < rr_gsb.get_sb_num_conf_bits()) {
|
||||||
/* 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,
|
add_sram_ports_to_module_manager(module_manager, module_id,
|
||||||
circuit_lib, sram_model, cur_sram_orgz_info->type,
|
circuit_lib, sram_model, cur_sram_orgz_info->type,
|
||||||
rr_gsb.get_sb_num_conf_bits());
|
rr_gsb.get_sb_num_conf_bits());
|
||||||
|
@ -2308,12 +2331,14 @@ void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manage
|
||||||
print_verilog_module_declaration(fp, module_manager, module_id);
|
print_verilog_module_declaration(fp, module_manager, module_id);
|
||||||
/* Finish printing ports */
|
/* Finish printing ports */
|
||||||
|
|
||||||
/* TODO: Local wires for memory configurations */
|
print_verilog_comment(fp, std::string("---- BEGIN local wires for SRAM data ports ----"));
|
||||||
/*
|
/* Local wires for memory configurations */
|
||||||
dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info,
|
print_verilog_switch_block_local_sram_wires(fp, rr_gsb, circuit_lib, sram_model, cur_sram_orgz_info->type,
|
||||||
rr_gsb.get_sb_conf_bits_lsb(),
|
rr_gsb.get_sb_num_conf_bits());
|
||||||
rr_gsb.get_sb_conf_bits_msb());
|
print_verilog_comment(fp, std::string("---- END local wires for SRAM data ports ----"));
|
||||||
*/
|
|
||||||
|
/* TODO: Print routing multiplexers */
|
||||||
|
|
||||||
/* 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));
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
/* FPGA-X2P context header files */
|
/* FPGA-X2P context header files */
|
||||||
#include "spice_types.h"
|
#include "spice_types.h"
|
||||||
|
#include "fpga_x2p_naming.h"
|
||||||
#include "fpga_x2p_utils.h"
|
#include "fpga_x2p_utils.h"
|
||||||
|
|
||||||
/* FPGA-Verilog context header files */
|
/* FPGA-Verilog context header files */
|
||||||
|
@ -646,3 +647,125 @@ void print_verilog_buffer_instance(std::fstream& fp,
|
||||||
module_manager.add_child_module(parent_module_id, buffer_module_id);
|
module_manager.add_child_module(parent_module_id, buffer_module_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Print local wires that are used for SRAM configuration
|
||||||
|
* The local wires are strongly dependent on the organization of SRAMs.
|
||||||
|
* 1. Standalone SRAMs:
|
||||||
|
* No need for local wires, their outputs are port of the module
|
||||||
|
*
|
||||||
|
* Module
|
||||||
|
* +------------------------------+
|
||||||
|
* | Sub-module |
|
||||||
|
* | +---------------------+ |
|
||||||
|
* | | sram_out|---->|---->sram_out
|
||||||
|
* | | | |
|
||||||
|
* | | sram_out|---->|---->sram_out
|
||||||
|
* | | | |
|
||||||
|
* | +---------------------+ |
|
||||||
|
* +------------------------------+
|
||||||
|
*
|
||||||
|
* 2. Configuration-chain Flip-flops:
|
||||||
|
* two ports will be added, which are the head of scan-chain
|
||||||
|
* and the tail of scan-chain
|
||||||
|
*
|
||||||
|
* Module
|
||||||
|
* +-----------------------------------------+
|
||||||
|
* | |
|
||||||
|
* | +------+ +------+ +------+ |
|
||||||
|
* | +->| CCFF |--->| CCFF | ... | CCFF |-+ |
|
||||||
|
* | | +------+ | +------+ | +------+ | |
|
||||||
|
* head--->|-+-----------+------------+-----------+->|--->tail
|
||||||
|
* | local wire |
|
||||||
|
* +-----------------------------------------+
|
||||||
|
* 3. Memory decoders:
|
||||||
|
* two ports will be added, which are regular output and inverted output
|
||||||
|
* Note that the outputs are the data outputs of SRAMs
|
||||||
|
* BL/WLs of memory decoders are ports of module but not local wires
|
||||||
|
*
|
||||||
|
* Module
|
||||||
|
* +-----------------------------------------+
|
||||||
|
* | |
|
||||||
|
* | +------+ +------+ +------+ |
|
||||||
|
* | | SRAM | | SRAM | ... | SRAM | |
|
||||||
|
* | +------+ +------+ +------+ |
|
||||||
|
* | ^ ^ ^ |
|
||||||
|
* | | | | |
|
||||||
|
* BL/WL--->|---------------------------------------->|
|
||||||
|
* | local wire |
|
||||||
|
* +-----------------------------------------+
|
||||||
|
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
void print_verilog_local_sram_wires(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& sram_model,
|
||||||
|
const e_sram_orgz sram_orgz_type,
|
||||||
|
const size_t& port_size) {
|
||||||
|
/* Make sure we have a valid file handler*/
|
||||||
|
check_file_handler(fp);
|
||||||
|
|
||||||
|
/* Port size must be at least one! */
|
||||||
|
if (0 == port_size) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Depend on the configuraion style */
|
||||||
|
switch(sram_orgz_type) {
|
||||||
|
case SPICE_SRAM_STANDALONE:
|
||||||
|
/* Nothing to do here */
|
||||||
|
break;
|
||||||
|
case SPICE_SRAM_SCAN_CHAIN: {
|
||||||
|
/* Generate the name of local wire for the CCFF inputs, CCFF output and inverted output */
|
||||||
|
std::vector<BasicPort> ccff_ports;
|
||||||
|
/* [0] => CCFF input */
|
||||||
|
ccff_ports.push_back(BasicPort(generate_sram_local_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_INPUT), port_size));
|
||||||
|
/* [1] => CCFF output */
|
||||||
|
ccff_ports.push_back(BasicPort(generate_sram_local_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_OUTPUT), port_size));
|
||||||
|
/* [2] => CCFF inverted output */
|
||||||
|
ccff_ports.push_back(BasicPort(generate_sram_local_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_INOUT), port_size));
|
||||||
|
/* Print local wire definition */
|
||||||
|
for (const auto& ccff_port : ccff_ports) {
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, ccff_port) << ";" << std::endl;
|
||||||
|
}
|
||||||
|
/* Connect first CCFF to the head */
|
||||||
|
/* Head is always a 1-bit port */
|
||||||
|
BasicPort ccff_head_port(generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_INPUT), 1);
|
||||||
|
BasicPort ccff_head_local_port(ccff_ports[0].get_name(), 1);
|
||||||
|
print_verilog_wire_connection(fp, ccff_head_local_port, ccff_head_port, false);
|
||||||
|
/* Connect last CCFF to the tail */
|
||||||
|
/* Tail is always a 1-bit port */
|
||||||
|
BasicPort ccff_tail_port(generate_sram_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_OUTPUT), 1);
|
||||||
|
BasicPort ccff_tail_local_port(ccff_ports[1].get_name(), ccff_ports[1].get_msb(), ccff_ports[1].get_msb());
|
||||||
|
print_verilog_wire_connection(fp, ccff_tail_local_port, ccff_tail_port, false);
|
||||||
|
/* Connect CCFFs into chains */
|
||||||
|
/* If port size is 0 or 1, there is no need for the chain connection */
|
||||||
|
if (2 > port_size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Cascade the CCFF between head and tail */
|
||||||
|
BasicPort ccff_chain_input_port(ccff_ports[0].get_name(), port_size - 1);
|
||||||
|
BasicPort ccff_chain_output_port(ccff_ports[1].get_name(), 1, port_size - 1);
|
||||||
|
print_verilog_wire_connection(fp, ccff_chain_output_port, ccff_chain_input_port, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPICE_SRAM_MEMORY_BANK: {
|
||||||
|
/* Generate the name of local wire for the SRAM output and inverted output */
|
||||||
|
std::vector<BasicPort> sram_ports;
|
||||||
|
/* [0] => SRAM output */
|
||||||
|
sram_ports.push_back(BasicPort(generate_sram_local_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_INPUT), port_size));
|
||||||
|
/* [1] => SRAM inverted output */
|
||||||
|
sram_ports.push_back(BasicPort(generate_sram_local_port_name(circuit_lib, sram_model, sram_orgz_type, SPICE_MODEL_PORT_OUTPUT), port_size));
|
||||||
|
/* Print local wire definition */
|
||||||
|
for (const auto& sram_port : sram_ports) {
|
||||||
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, sram_port) << ";" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
vpr_printf(TIO_MESSAGE_ERROR,
|
||||||
|
"(File:%s,[LINE%d])Invalid SRAM organization!\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -84,4 +84,10 @@ void print_verilog_buffer_instance(std::fstream& fp,
|
||||||
const BasicPort& instance_input_port,
|
const BasicPort& instance_input_port,
|
||||||
const BasicPort& instance_output_port);
|
const BasicPort& instance_output_port);
|
||||||
|
|
||||||
|
void print_verilog_local_sram_wires(std::fstream& fp,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& sram_model,
|
||||||
|
const e_sram_orgz sram_orgz_type,
|
||||||
|
const size_t& port_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue