refactoring Verilog generation for routing channels

This commit is contained in:
tangxifan 2019-09-16 17:35:51 -06:00
parent ec3854a648
commit d83cad7c2e
5 changed files with 559 additions and 28 deletions

View File

@ -138,3 +138,64 @@ std::string generate_memory_module_name(const CircuitLibrary& circuit_lib,
const std::string& postfix) { const std::string& postfix) {
return std::string( circuit_lib.model_name(circuit_model) + "_" + circuit_lib.model_name(sram_model) + postfix ); return std::string( circuit_lib.model_name(circuit_model) + "_" + circuit_lib.model_name(sram_model) + postfix );
} }
/*********************************************************************
* Generate the netlist name for a unique routing block
* It could be
* 1. Routing channel
* 2. Connection block
* 3. Switch block
* A unique block id should be given
*********************************************************************/
std::string generate_routing_block_netlist_name(const std::string& prefix,
const size_t& block_id,
const std::string& postfix) {
return std::string( prefix + std::to_string(block_id) + postfix );
}
/*********************************************************************
* Generate the netlist name for a routing block with a given coordinate
* It could be
* 1. Routing channel
* 2. Connection block
* 3. Switch block
*********************************************************************/
std::string generate_routing_block_netlist_name(const std::string& prefix,
const vtr::Point<size_t>& coordinate,
const std::string& postfix) {
return std::string( prefix + std::to_string(coordinate.x()) + std::string("_") + std::to_string(coordinate.y()) + postfix );
}
/*********************************************************************
* Generate the module name for a unique routing channel
*********************************************************************/
std::string generate_routing_channel_module_name(const t_rr_type& chan_type,
const size_t& block_id) {
/* Channel must be either CHANX or CHANY */
VTR_ASSERT( (CHANX == chan_type) || (CHANY == chan_type) );
/* Create a map between chan_type and module_prefix */
std::map<t_rr_type, std::string> module_prefix_map;
/* TODO: use a constexpr string to replace the fixed name? */
module_prefix_map[CHANX] = std::string("chanx");
module_prefix_map[CHANY] = std::string("chany");
return std::string( module_prefix_map[chan_type] + std::string("_") + std::to_string(block_id) + std::string("_") );
}
/*********************************************************************
* Generate the module name for a routing channel with a given coordinate
*********************************************************************/
std::string generate_routing_channel_module_name(const t_rr_type& chan_type,
const vtr::Point<size_t>& coordinate) {
/* Channel must be either CHANX or CHANY */
VTR_ASSERT( (CHANX == chan_type) || (CHANY == chan_type) );
/* Create a map between chan_type and module_prefix */
std::map<t_rr_type, std::string> module_prefix_map;
/* TODO: use a constexpr string to replace the fixed name? */
module_prefix_map[CHANX] = std::string("chanx");
module_prefix_map[CHANY] = std::string("chany");
return std::string( module_prefix_map[chan_type] + std::to_string(coordinate.x()) + std::string("_") + std::to_string(coordinate.y()) + std::string("_") );
}

View File

@ -9,7 +9,9 @@
#include <string> #include <string>
#include "vtr_geometry.h"
#include "circuit_library.h" #include "circuit_library.h"
#include "vpr_types.h"
std::string generate_verilog_mux_node_name(const size_t& node_level, std::string generate_verilog_mux_node_name(const size_t& node_level,
const bool& add_buffer_postfix); const bool& add_buffer_postfix);
@ -38,4 +40,18 @@ std::string generate_memory_module_name(const CircuitLibrary& circuit_lib,
const CircuitModelId& sram_model, const CircuitModelId& sram_model,
const std::string& postfix); const std::string& postfix);
std::string generate_routing_block_netlist_name(const std::string& prefix,
const size_t& block_id,
const std::string& postfix);
std::string generate_routing_block_netlist_name(const std::string& prefix,
const vtr::Point<size_t>& block_id,
const std::string& postfix);
std::string generate_routing_channel_module_name(const t_rr_type& chan_type,
const size_t& block_id);
std::string generate_routing_channel_module_name(const t_rr_type& chan_type,
const vtr::Point<size_t>& block_id);
#endif #endif

View File

@ -280,7 +280,7 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup,
vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts);
/* Dump routing resources: switch blocks, connection blocks and channel tracks */ /* Dump routing resources: switch blocks, connection blocks and channel tracks */
dump_verilog_routing_resources(sram_verilog_orgz_info, src_dir_path, rr_dir_path, Arch, &vpr_setup.RoutingArch, print_verilog_routing_resources(module_manager, sram_verilog_orgz_info, src_dir_path, rr_dir_path, Arch, vpr_setup.RoutingArch,
num_rr_nodes, rr_node, rr_node_indices, rr_indexed_data, num_rr_nodes, rr_node, rr_node_indices, rr_indexed_data,
vpr_setup.FPGA_SPICE_Opts); vpr_setup.FPGA_SPICE_Opts);
@ -295,6 +295,7 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup,
/* Generate the Verilog module of the configuration peripheral protocol /* Generate the Verilog module of the configuration peripheral protocol
* which loads bitstream to FPGA fabric * which loads bitstream to FPGA fabric
* TODO: generate the BL/WL decoders!!!!
* *
* IMPORTANT: this function should be called after Verilog generation of * IMPORTANT: this function should be called after Verilog generation of
* core logic (i.e., logic blocks and routing resources) !!! * core logic (i.e., logic blocks and routing resources) !!!

View File

@ -1,7 +1,7 @@
/***********************************/ /*********************************************************************
/* SPICE Modeling for VPR */ * This file includes functions that are used for
/* Xifan TANG, EPFL/LSI */ * Verilog generation of FPGA routing architecture (global routing)
/***********************************/ *********************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
@ -11,6 +11,7 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <vector> #include <vector>
#include <fstream>
#include <algorithm> #include <algorithm>
/* Include vpr structs*/ /* Include vpr structs*/
@ -24,6 +25,8 @@
#include "route_common.h" #include "route_common.h"
#include "vpr_utils.h" #include "vpr_utils.h"
#include "vtr_assert.h"
/* Include SPICE support headers*/ /* Include SPICE support headers*/
#include "linkedlist.h" #include "linkedlist.h"
#include "rr_blocks.h" #include "rr_blocks.h"
@ -34,12 +37,421 @@
#include "fpga_x2p_pbtypes_utils.h" #include "fpga_x2p_pbtypes_utils.h"
#include "fpga_x2p_bitstream_utils.h" #include "fpga_x2p_bitstream_utils.h"
#include "fpga_x2p_globals.h" #include "fpga_x2p_globals.h"
#include "fpga_x2p_naming.h"
/* Include Verilog support headers*/ /* Include Verilog support headers*/
#include "verilog_global.h" #include "verilog_global.h"
#include "verilog_utils.h" #include "verilog_utils.h"
#include "verilog_writer_utils.h"
#include "verilog_routing.h" #include "verilog_routing.h"
/*********************************************************************
* Generate the Verilog module for a routing channel
* Routing track wire, which is 1-input and dual output
* This type of wires are used in the global routing architecture.
* One of the output is wired to another Switch block multiplexer,
* while the mid-output is wired to a Connection block multiplexer.
*
* | CLB |
* +------------+
* ^
* |
* +------------------------------+
* | Connection block multiplexer |
* +------------------------------+
* ^
* | mid-output +--------------
* +--------------------+ |
* input --->| Routing track wire |--------->| Switch Block
* +--------------------+ output |
* +--------------
*
* IMPORTANT: This function is designed for outputting unique Verilog modules
* of routing channels
*
* TODO: This function should be adapted to the RRGraph object
*********************************************************************/
static
void print_verilog_routing_unique_chan_subckt(ModuleManager& module_manager,
const std::string& verilog_dir,
const std::string& subckt_dir,
const size_t& rr_chan_subckt_id,
const RRChan& rr_chan) {
std::string fname_prefix;
/* TODO: use a constexpr String arrary to replace this switch cases? */
/* Find the prefix for the Verilog file name */
switch (rr_chan.get_type()) {
case CHANX:
fname_prefix = std::string(chanx_verilog_file_name_prefix);
break;
case CHANY:
fname_prefix = std::string(chany_verilog_file_name_prefix);
break;
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File:%s, [LINE%d])Invalid Channel type! Should be CHANX or CHANY.\n",
__FILE__, __LINE__);
exit(1);
}
std::string verilog_fname(subckt_dir + generate_routing_block_netlist_name(fname_prefix, rr_chan_subckt_id, std::string(verilog_netlist_file_postfix)));
/* TODO: remove the bak file when the file is ready */
verilog_fname += ".bak";
/* Create the file stream */
std::fstream fp;
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
check_file_handler(fp);
print_verilog_file_header(fp, "Verilog modules for routing channel in X- and Y-direction");
/* Print preprocessing flags */
print_verilog_include_defines_preproc_file(fp, verilog_dir);
/* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = module_manager.add_module(generate_routing_channel_module_name(rr_chan.get_type(), rr_chan_subckt_id));
/* Add ports to the module */
/* For the LEFT side of a X-direction routing channel
* or the BOTTOM bottom side of a Y-direction routing channel
* Routing Resource Nodes in INC_DIRECTION are inputs of the module
*
* For the RIGHT side of a X-direction routing channel
* or the TOP bottom side of a Y-direction routing channel
* Routing Resource Nodes in INC_DIRECTION are outputs of the module
*
* An example of X-direction routing channel consisting of W routing nodes:
* +--------------------------+
* nodeA(INC_DIRECTION)--->| in[0] out[0] |---> nodeA(INC_DIRECTION)
* nodeB(DEC_DIRECTION)<---| out[1] in[1] |<--- nodeB(DEC_DIRECTION)
* ... ... ... ...
* nodeX(INC_DIRECTION)--->| in[W-1] out[W-1] |---> nodeX(INC_DIRECTION)
* +--------------------------+
*
* An example of Y-direction routing channel consisting of W routing nodes:
*
* nodeA nodeB nodeX
* (INC_DIRECTION) (DEC_DIRECTION) (DEC_DIRECTION)
* ^ | ... |
* | v v
* +------------------------------ ... -------+
* | out[0] in[1] in[X] |
* | |
* | |
* | in[0] out[1] ... out[X] |
* +------------------------------ ... -------+
* ^ | |
* | v v
* nodeA nodeB nodeX
* (INC_DIRECTION) (DEC_DIRECTION) (DEC_DIRECTION)
*/
/* Add ports at LEFT/BOTTOM side of the module */
for (size_t itrack = 0; itrack < rr_chan.get_chan_width(); ++itrack) {
switch (rr_chan.get_node(itrack)->direction) {
case INC_DIRECTION: {
/* TODO: naming should be more flexible !!! */
BasicPort input_port(std::string("in" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
break;
}
case DEC_DIRECTION: {
/* TODO: naming should be more flexible !!! */
BasicPort output_port(std::string("out" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
break;
}
case BI_DIRECTION:
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File: %s [LINE%d]) Invalid direction of rr_node %s[%lu]_in/out[%lu]!\n",
__FILE__, __LINE__,
convert_chan_type_to_string(rr_chan.get_type()),
rr_chan_subckt_id, itrack);
exit(1);
}
}
/* Add ports at RIGHT/TOP side of the module */
for (size_t itrack = 0; itrack < rr_chan.get_chan_width(); ++itrack) {
switch (rr_chan.get_node(itrack)->direction) {
case INC_DIRECTION: {
/* TODO: naming should be more flexible !!! */
BasicPort output_port(std::string("out" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
break;
}
case DEC_DIRECTION: {
/* TODO: naming should be more flexible !!! */
BasicPort input_port(std::string("in" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
break;
}
case BI_DIRECTION:
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File: %s [LINE%d]) Invalid direction of rr_node %s[%lu]_in/out[%lu]!\n",
__FILE__, __LINE__,
convert_chan_type_to_string(rr_chan.get_type()),
rr_chan_subckt_id, itrack);
exit(1);
}
}
/* Add middle-point output for connection box inputs */
for (size_t itrack = 0; itrack < rr_chan.get_chan_width(); ++itrack) {
/* TODO: naming should be more flexible !!! */
BasicPort mid_output_port(std::string("mid_out" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, mid_output_port, ModuleManager::MODULE_OUTPUT_PORT);
}
/* dump module definition + ports */
print_verilog_module_declaration(fp, module_manager, module_id);
/* Finish dumping ports */
/* Print short-wire connection:
*
* in[i] ----------> out[i]
* |
* +-----> mid_out[i]
*/
for (size_t itrack = 0; itrack < rr_chan.get_chan_width(); ++itrack) {
/* short connecting inputs and outputs:
* length of metal wire and parasitics are handled by semi-custom flow
*/
BasicPort input_port(std::string("in" + std::to_string(itrack)), 1);
BasicPort output_port(std::string("out" + std::to_string(itrack)), 1);
BasicPort mid_output_port(std::string("mid_out" + std::to_string(itrack)), 1);
print_verilog_wire_connection(fp, output_port, input_port, false);
print_verilog_wire_connection(fp, mid_output_port, input_port, false);
}
/* Put an end to the Verilog module */
print_verilog_module_end(fp, module_manager.module_name(module_id));
/* Add an empty line as a splitter */
fp << std::endl;
/* Close file handler */
fp.close();
/* Add fname to the linked list */
/* Uncomment this when it is ready
routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, verilog_fname.c_str());
*/
return;
}
/*********************************************************************
* Generate the Verilog module for a routing channel
* Routing track wire, which is 1-input and dual output
* This type of wires are used in the global routing architecture.
* One of the output is wired to another Switch block multiplexer,
* while the mid-output is wired to a Connection block multiplexer.
*
* | CLB |
* +------------+
* ^
* |
* +------------------------------+
* | Connection block multiplexer |
* +------------------------------+
* ^
* | mid-output +--------------
* +--------------------+ |
* input --->| Routing track wire |--------->| Switch Block
* +--------------------+ output |
* +--------------
*
* IMPORTANT: This function is designed for outputting non-unique Verilog modules
* of routing channels
*
* TODO: This function should be adapted to the RRGraph object
*********************************************************************/
static
void print_verilog_routing_chan_subckt(ModuleManager& module_manager,
const std::string& verilog_dir,
const std::string& subckt_dir,
const vtr::Point<size_t>& chan_coordinate,
const t_rr_type& chan_type,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices) {
int chan_width = 0;
t_rr_node** chan_rr_nodes = NULL;
std::string fname_prefix;
/* TODO: use a constexpr String arrary to replace this switch cases? */
/* Find the prefix for the Verilog file name */
switch (chan_type) {
case CHANX:
fname_prefix = std::string(chanx_verilog_file_name_prefix);
break;
case CHANY:
fname_prefix = std::string(chany_verilog_file_name_prefix);
break;
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File:%s, [LINE%d])Invalid Channel type! Should be CHANX or CHANY.\n",
__FILE__, __LINE__);
exit(1);
}
std::string verilog_fname(subckt_dir + generate_routing_block_netlist_name(fname_prefix, chan_coordinate, std::string(verilog_netlist_file_postfix)));
/* TODO: remove the bak file when the file is ready */
verilog_fname += ".bak";
/* Create the file stream */
std::fstream fp;
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
check_file_handler(fp);
print_verilog_file_header(fp, "Verilog modules for routing channel in X- and Y-direction");
/* Print preprocessing flags */
print_verilog_include_defines_preproc_file(fp, verilog_dir);
/* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = module_manager.add_module(generate_routing_channel_module_name(chan_type, chan_coordinate));
/* Collect rr_nodes for Tracks for chanx[ix][iy] */
chan_rr_nodes = get_chan_rr_nodes(&chan_width, chan_type, chan_coordinate.x(), chan_coordinate.y(),
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
/* Add ports to the module */
/* For the LEFT side of a X-direction routing channel
* or the BOTTOM bottom side of a Y-direction routing channel
* Routing Resource Nodes in INC_DIRECTION are inputs of the module
*
* For the RIGHT side of a X-direction routing channel
* or the TOP bottom side of a Y-direction routing channel
* Routing Resource Nodes in INC_DIRECTION are outputs of the module
*
* An example of X-direction routing channel consisting of W routing nodes:
* +--------------------------+
* nodeA(INC_DIRECTION)--->| in[0] out[0] |---> nodeA(INC_DIRECTION)
* nodeB(DEC_DIRECTION)<---| out[1] in[1] |<--- nodeB(DEC_DIRECTION)
* ... ... ... ...
* nodeX(INC_DIRECTION)--->| in[W-1] out[W-1] |---> nodeX(INC_DIRECTION)
* +--------------------------+
*
* An example of Y-direction routing channel consisting of W routing nodes:
*
* nodeA nodeB nodeX
* (INC_DIRECTION) (DEC_DIRECTION) (DEC_DIRECTION)
* ^ | ... |
* | v v
* +------------------------------ ... -------+
* | out[0] in[1] in[X] |
* | |
* | |
* | in[0] out[1] ... out[X] |
* +------------------------------ ... -------+
* ^ | |
* | v v
* nodeA nodeB nodeX
* (INC_DIRECTION) (DEC_DIRECTION) (DEC_DIRECTION)
*/
/* Add ports at LEFT/BOTTOM side of the module */
for (size_t itrack = 0; itrack < size_t(chan_width); ++itrack) {
switch (chan_rr_nodes[itrack]->direction) {
case INC_DIRECTION: {
/* TODO: naming should be more flexible !!! */
BasicPort input_port(std::string("in" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
break;
}
case DEC_DIRECTION: {
/* TODO: naming should be more flexible !!! */
BasicPort output_port(std::string("out" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
break;
}
case BI_DIRECTION:
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File: %s [LINE%d]) Invalid direction of rr_node %s[%lu][%lu]_in/out[%lu]!\n",
__FILE__, __LINE__,
convert_chan_type_to_string(chan_type),
chan_coordinate.x(), chan_coordinate.y(), itrack);
exit(1);
}
}
/* Add ports at RIGHT/TOP side of the module */
for (size_t itrack = 0; itrack < size_t(chan_width); ++itrack) {
switch (chan_rr_nodes[itrack]->direction) {
case INC_DIRECTION: {
/* TODO: naming should be more flexible !!! */
BasicPort output_port(std::string("out" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
break;
}
case DEC_DIRECTION: {
/* TODO: naming should be more flexible !!! */
BasicPort input_port(std::string("in" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
break;
}
case BI_DIRECTION:
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File: %s [LINE%d]) Invalid direction of rr_node %s[%lu][%lu]_in/out[%lu]!\n",
__FILE__, __LINE__,
convert_chan_type_to_string(chan_type),
chan_coordinate.x(), chan_coordinate.y(), itrack);
exit(1);
}
}
/* Add middle-point output for connection box inputs */
for (size_t itrack = 0; itrack < size_t(chan_width); ++itrack) {
/* TODO: naming should be more flexible !!! */
BasicPort mid_output_port(std::string("mid_out" + std::to_string(itrack)), 1);
module_manager.add_port(module_id, mid_output_port, ModuleManager::MODULE_OUTPUT_PORT);
}
/* dump module definition + ports */
print_verilog_module_declaration(fp, module_manager, module_id);
/* Finish dumping ports */
/* Print short-wire connection:
*
* in[i] ----------> out[i]
* |
* +-----> mid_out[i]
*/
for (size_t itrack = 0; itrack < size_t(chan_width); ++itrack) {
/* short connecting inputs and outputs:
* length of metal wire and parasitics are handled by semi-custom flow
*/
BasicPort input_port(std::string("in" + std::to_string(itrack)), 1);
BasicPort output_port(std::string("out" + std::to_string(itrack)), 1);
BasicPort mid_output_port(std::string("mid_out" + std::to_string(itrack)), 1);
print_verilog_wire_connection(fp, output_port, input_port, false);
print_verilog_wire_connection(fp, mid_output_port, input_port, false);
}
/* Put an end to the Verilog module */
print_verilog_module_end(fp, module_manager.module_name(module_id));
/* Add an empty line as a splitter */
fp << std::endl;
/* Close file handler */
fp.close();
/* Add fname to the linked list */
/* Uncomment this when it is ready
routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, verilog_fname.c_str());
*/
/* Free */
my_free(chan_rr_nodes);
return;
}
static static
void dump_verilog_routing_chan_subckt(char* verilog_dir, void dump_verilog_routing_chan_subckt(char* verilog_dir,
char* subckt_dir, char* subckt_dir,
@ -3894,18 +4306,33 @@ void dump_verilog_routing_connection_box_subckt(t_sram_orgz_info* cur_sram_orgz_
return; return;
} }
/* Top Function*/ /*********************************************************************
/* Build the routing resource SPICE sub-circuits*/ * Top-level function:
void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info, * Build the Verilog modules for global routing architecture
* 1. Routing channels
* 2. Switch blocks
* 3. Connection blocks
*
* This function supports two styles in Verilog generation:
* 1. Explicit port mapping
* 2. Inexplicit port mapping
*
* This function also supports high hierarchical Verilog generation
* (when the compact_routing_hierarchy is set true)
* In this mode, Verilog generation will be done for only those
* unique modules in terms of internal logics
*********************************************************************/
void print_verilog_routing_resources(ModuleManager& module_manager,
t_sram_orgz_info* cur_sram_orgz_info,
char* verilog_dir, char* verilog_dir,
char* subckt_dir, char* subckt_dir,
t_arch arch, const t_arch& arch,
t_det_routing_arch* routing_arch, const t_det_routing_arch& routing_arch,
int LL_num_rr_nodes, t_rr_node* LL_rr_node, int LL_num_rr_nodes, t_rr_node* LL_rr_node, /* To be replaced by RRGraph object */
t_ivec*** LL_rr_node_indices, t_ivec*** LL_rr_node_indices,
t_rr_indexed_data* LL_rr_indexed_data, t_rr_indexed_data* LL_rr_indexed_data,
t_fpga_spice_opts FPGA_SPICE_Opts) { const t_fpga_spice_opts& FPGA_SPICE_Opts) {
assert(UNI_DIRECTIONAL == routing_arch->directionality); VTR_ASSERT (UNI_DIRECTIONAL == routing_arch.directionality);
boolean compact_routing_hierarchy = FPGA_SPICE_Opts.compact_routing_hierarchy; boolean compact_routing_hierarchy = FPGA_SPICE_Opts.compact_routing_hierarchy;
boolean explicit_port_mapping = FPGA_SPICE_Opts.SynVerilogOpts.dump_explicit_verilog; boolean explicit_port_mapping = FPGA_SPICE_Opts.SynVerilogOpts.dump_explicit_verilog;
@ -3934,12 +4361,18 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,
for (size_t ichan = 0; ichan < device_rr_chan.get_num_modules(CHANX); ++ichan) { for (size_t ichan = 0; ichan < device_rr_chan.get_num_modules(CHANX); ++ichan) {
dump_verilog_routing_chan_subckt(verilog_dir, subckt_dir, dump_verilog_routing_chan_subckt(verilog_dir, subckt_dir,
ichan, device_rr_chan.get_module(CHANX, ichan), explicit_port_mapping); ichan, device_rr_chan.get_module(CHANX, ichan), explicit_port_mapping);
print_verilog_routing_unique_chan_subckt(module_manager, std::string(verilog_dir), std::string(subckt_dir),
ichan, device_rr_chan.get_module(CHANX, ichan));
} }
/* Y - channels [1...ny][0..nx]*/ /* Y - channels [1...ny][0..nx]*/
vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Channels...\n"); vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Channels...\n");
for (size_t ichan = 0; ichan < device_rr_chan.get_num_modules(CHANY); ++ichan) { for (size_t ichan = 0; ichan < device_rr_chan.get_num_modules(CHANY); ++ichan) {
dump_verilog_routing_chan_subckt(verilog_dir, subckt_dir, dump_verilog_routing_chan_subckt(verilog_dir, subckt_dir,
ichan, device_rr_chan.get_module(CHANY, ichan), explicit_port_mapping); ichan, device_rr_chan.get_module(CHANY, ichan), explicit_port_mapping);
print_verilog_routing_unique_chan_subckt(module_manager, std::string(verilog_dir), std::string(subckt_dir),
ichan, device_rr_chan.get_module(CHANY, ichan));
} }
} else { } else {
/* Output the full array of routing channels */ /* Output the full array of routing channels */
@ -3949,6 +4382,12 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,
dump_verilog_routing_chan_subckt(verilog_dir, subckt_dir, ix, iy, CHANX, dump_verilog_routing_chan_subckt(verilog_dir, subckt_dir, ix, iy, CHANX,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, LL_rr_indexed_data, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, LL_rr_indexed_data,
arch.num_segments, explicit_port_mapping); arch.num_segments, explicit_port_mapping);
vtr::Point<size_t> chan_coordinate;
chan_coordinate.set_x(size_t(ix));
chan_coordinate.set_y(size_t(iy));
print_verilog_routing_chan_subckt(module_manager, std::string(verilog_dir), std::string(subckt_dir), chan_coordinate, CHANX,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
} }
} }
/* Y - channels [1...ny][0..nx]*/ /* Y - channels [1...ny][0..nx]*/
@ -3958,6 +4397,12 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,
dump_verilog_routing_chan_subckt(verilog_dir, subckt_dir, ix, iy, CHANY, dump_verilog_routing_chan_subckt(verilog_dir, subckt_dir, ix, iy, CHANY,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, LL_rr_indexed_data, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, LL_rr_indexed_data,
arch.num_segments, explicit_port_mapping); arch.num_segments, explicit_port_mapping);
vtr::Point<size_t> chan_coordinate;
chan_coordinate.set_x(size_t(ix));
chan_coordinate.set_y(size_t(iy));
print_verilog_routing_chan_subckt(module_manager, std::string(verilog_dir), std::string(subckt_dir), chan_coordinate, CHANY,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
} }
} }
} }

View File

@ -1,5 +1,12 @@
/***********************************************
* Header file for verilog_routing.cpp
**********************************************/
#ifndef VERILOG_ROUTING_H #ifndef VERILOG_ROUTING_H
#define VERILOG_ROUTING_H #define VERILOG_ROUTING_H
/* Include other header files which are dependency on the function declared below */
#include "module_manager.h"
void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info, void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
char* verilog_dir, char* verilog_dir,
char* subckt_dir, char* subckt_dir,
@ -133,14 +140,15 @@ void dump_verilog_routing_connection_box_subckt(t_sram_orgz_info* cur_sram_orgz_
bool is_explicit_mapping); bool is_explicit_mapping);
void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info, void print_verilog_routing_resources(ModuleManager& module_manager,
t_sram_orgz_info* cur_sram_orgz_info,
char* verilog_dir, char* verilog_dir,
char* subckt_dir, char* subckt_dir,
t_arch arch, const t_arch& arch,
t_det_routing_arch* routing_arch, const t_det_routing_arch& routing_arch,
int LL_num_rr_nodes, t_rr_node* LL_rr_node, int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices, t_ivec*** LL_rr_node_indices,
t_rr_indexed_data* LL_rr_indexed_data, t_rr_indexed_data* LL_rr_indexed_data,
t_fpga_spice_opts FPGA_SPICE_Opts); const t_fpga_spice_opts& FPGA_SPICE_Opts);
#endif #endif