diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c index 12afb3a2e..139459706 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c @@ -3843,338 +3843,3 @@ void print_verilog_routing_resources(ModuleManager& module_manager, return; } - - -/******************************************************************** - * Print the sub-circuit of a connection Box (Type: [CHANX|CHANY]) - * Actually it is very similiar to switch box but - * the difference is connection boxes connect Grid INPUT Pins to channels - * NOTE: direct connection between CLBs should NOT be included inside this - * module! They should be added in the top-level module as their connection - * is not limited to adjacent CLBs!!! - * - * Location of a X- and Y-direction Connection Block in FPGA fabric - * +------------+ +-------------+ - * | |------>| | - * | CLB |<------| Y-direction | - * | | ... | Connection | - * | |------>| Block | - * +------------+ +-------------+ - * | ^ ... | | ^ ... | - * v | v v | v - * +-------------------+ +-------------+ - * --->| |--->| | - * <---| X-direction |<---| Switch | - * ...| Connection block |... | Block | - * --->| |--->| | - * +-------------------+ +-------------+ - * - * Internal structure: - * This is an example of a X-direction connection block - * Note that middle output ports are shorted wire from inputs of routing tracks, - * which are also the inputs of routing multiplexer of the connection block - * - * CLB Input Pins - * (IPINs) - * ^ ^ ^ - * | | ... | - * +--------------------------+ - * | ^ ^ ^ | - * | | | ... | | - * | +--------------------+ | - * | | routing | | - * | | multiplexers | | - * | +--------------------+ | - * | middle outputs | - * | of routing channel | - * | ^ ^ ^ ^ ^ ^ ^ ^ | - * | | | | | ... | | | | | - * in[0] -->|------------------------->|---> out[0] - * out[1] <--|<-------------------------|<--- in[1] - * | ... | - * in[W-2] -->|------------------------->|---> out[W-2] - * out[W-1] <--|<-------------------------|<--- in[W-1] - * +--------------------------+ - * - * W: routing channel width - * - ********************************************************************/ -static -void print_verilog_routing_connection_box_unique_module(ModuleManager& module_manager, - const std::string& verilog_dir, - const std::string& subckt_dir, - const RRGSB& rr_gsb, - const t_rr_type& cb_type, - const bool& use_explicit_port_map) { - /* Create the netlist */ - vtr::Point gsb_coordinate(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type)); - std::string verilog_fname(subckt_dir + generate_connection_block_netlist_name(cb_type, gsb_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, std::string("Verilog modules for Unique Connection Blocks[" + std::to_string(rr_gsb.get_cb_x(cb_type)) + "]["+ std::to_string(rr_gsb.get_cb_y(cb_type)) + "]")); - - /* 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 cb_module = module_manager.find_module(generate_connection_block_module_name(cb_type, gsb_coordinate)); - VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); - - /* Write the verilog module */ - write_verilog_module_to_file(fp, module_manager, cb_module, use_explicit_port_map); - - /* Add an empty line as a splitter */ - fp << std::endl; - - /* Close file handler */ - fp.close(); - - /* Add fname to the linked list */ - routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, verilog_fname.c_str()); -} - -/********************************************************************* - * Generate the Verilog module for a Switch Box. - * A Switch Box module consists of following ports: - * 1. Channel Y [x][y] inputs - * 2. Channel X [x+1][y] inputs - * 3. Channel Y [x][y-1] outputs - * 4. Channel X [x][y] outputs - * 5. Grid[x][y+1] Right side outputs pins - * 6. Grid[x+1][y+1] Left side output pins - * 7. Grid[x+1][y+1] Bottom side output pins - * 8. Grid[x+1][y] Top side output pins - * 9. Grid[x+1][y] Left side output pins - * 10. Grid[x][y] Right side output pins - * 11. Grid[x][y] Top side output pins - * 12. Grid[x][y+1] Bottom side output pins - * - * Location of a Switch Box in FPGA fabric: - * - * -------------- -------------- - * | | | | - * | Grid | ChanY | Grid | - * | [x][y+1] | [x][y+1] | [x+1][y+1] | - * | | | | - * -------------- -------------- - * ---------- - * ChanX | Switch | ChanX - * [x][y] | Box | [x+1][y] - * | [x][y] | - * ---------- - * -------------- -------------- - * | | | | - * | Grid | ChanY | Grid | - * | [x][y] | [x][y] | [x+1][y] | - * | | | | - * -------------- -------------- - * - * Switch Block pin location map - * - * Grid[x][y+1] ChanY[x][y+1] Grid[x+1][y+1] - * right_pins inputs/outputs left_pins - * | ^ | - * | | | - * v v v - * +-----------------------------------------------+ - * | | - * Grid[x][y+1] | | Grid[x+1][y+1] - * bottom_pins---->| |<---- bottom_pins - * | | - * ChanX[x][y] | Switch Box [x][y] | ChanX[x+1][y] - * inputs/outputs<--->| |<---> inputs/outputs - * | | - * Grid[x][y+1] | | Grid[x+1][y+1] - * top_pins---->| |<---- top_pins - * | | - * +-----------------------------------------------+ - * ^ ^ ^ - * | | | - * | v | - * Grid[x][y] ChanY[x][y] Grid[x+1][y] - * right_pins inputs/outputs left_pins - * - * - ********************************************************************/ -static -void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manager, - const std::string& verilog_dir, - const std::string& subckt_dir, - const RRGSB& rr_gsb, - const bool& use_explicit_port_map) { - /* Create the netlist */ - vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); - std::string verilog_fname(subckt_dir + generate_routing_block_netlist_name(sb_verilog_file_name_prefix, gsb_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, std::string("Verilog modules for Unique Switch Blocks[" + std::to_string(rr_gsb.get_sb_x()) + "]["+ std::to_string(rr_gsb.get_sb_y()) + "]")); - - /* 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 sb_module = module_manager.find_module(generate_switch_block_module_name(gsb_coordinate)); - VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); - - /* Write the verilog module */ - write_verilog_module_to_file(fp, module_manager, sb_module, use_explicit_port_map); - - /* Close file handler */ - fp.close(); - - /* Add fname to the linked list */ - routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, verilog_fname.c_str()); - - return; -} - - -/******************************************************************** - * Iterate over all the connection blocks in a device - * and build a module for each of them - *******************************************************************/ -static -void print_verilog_flatten_connection_block_modules(ModuleManager& module_manager, - const DeviceRRGSB& L_device_rr_gsb, - const std::string& verilog_dir, - const std::string& subckt_dir, - const t_rr_type& cb_type, - const bool& use_explicit_port_map) { - /* Build unique X-direction connection block modules */ - DeviceCoordinator cb_range = L_device_rr_gsb.get_gsb_range(); - - for (size_t ix = 0; ix < cb_range.get_x(); ++ix) { - for (size_t iy = 0; iy < cb_range.get_y(); ++iy) { - /* Check if the connection block exists in the device! - * Some of them do NOT exist due to heterogeneous blocks (height > 1) - * We will skip those modules - */ - const RRGSB& rr_gsb = L_device_rr_gsb.get_gsb(ix, iy); - if ( (TRUE != is_cb_exist(cb_type, rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type))) - || (true != rr_gsb.is_cb_exist(cb_type))) { - continue; - } - print_verilog_routing_connection_box_unique_module(module_manager, - verilog_dir, - subckt_dir, - rr_gsb, cb_type, - use_explicit_port_map); - } - } -} - -/******************************************************************** - * A top-level function of this file - * Print all the modules for global routing architecture of a FPGA fabric - * in Verilog format in a flatten way: - * Each connection block and switch block will be generated as a unique module - * Covering: - * 1. Connection blocks - * 2. Switch blocks - *******************************************************************/ -void print_verilog_flatten_routing_modules(ModuleManager& module_manager, - const DeviceRRGSB& L_device_rr_gsb, - const t_det_routing_arch& routing_arch, - const std::string& verilog_dir, - const std::string& subckt_dir, - const bool& use_explicit_port_map) { - /* We only support uni-directional routing architecture now */ - VTR_ASSERT (UNI_DIRECTIONAL == routing_arch.directionality); - - /* TODO: deprecate DeviceCoordinator, use vtr::Point only! */ - DeviceCoordinator sb_range = L_device_rr_gsb.get_gsb_range(); - - /* Build unique switch block modules */ - for (size_t ix = 0; ix < sb_range.get_x(); ++ix) { - for (size_t iy = 0; iy < sb_range.get_y(); ++iy) { - const RRGSB& rr_gsb = L_device_rr_gsb.get_gsb(ix, iy); - print_verilog_routing_switch_box_unique_module(module_manager, - verilog_dir, - subckt_dir, - rr_gsb, - use_explicit_port_map); - } - } - - print_verilog_flatten_connection_block_modules(module_manager, L_device_rr_gsb, verilog_dir, subckt_dir, CHANX, use_explicit_port_map); - - print_verilog_flatten_connection_block_modules(module_manager, L_device_rr_gsb, verilog_dir, subckt_dir, CHANY, use_explicit_port_map); - - vpr_printf(TIO_MESSAGE_INFO,"Generating header file for routing submodules...\n"); - dump_verilog_subckt_header_file(routing_verilog_subckt_file_path_head, - subckt_dir.c_str(), - routing_verilog_file_name); -} - - -/******************************************************************** - * A top-level function of this file - * Print all the unique modules for global routing architecture of a FPGA fabric - * in Verilog format, including: - * 1. Connection blocks - * 2. Switch blocks - * - * Note: this function SHOULD be called only when - * the option compact_routing_hierarchy is turned on!!! - *******************************************************************/ -void print_verilog_unique_routing_modules(ModuleManager& module_manager, - const DeviceRRGSB& L_device_rr_gsb, - const t_det_routing_arch& routing_arch, - const std::string& verilog_dir, - const std::string& subckt_dir, - const bool& use_explicit_port_map) { - /* We only support uni-directional routing architecture now */ - VTR_ASSERT (UNI_DIRECTIONAL == routing_arch.directionality); - - /* Build unique switch block modules */ - for (size_t isb = 0; isb < L_device_rr_gsb.get_num_sb_unique_module(); ++isb) { - const RRGSB& unique_mirror = L_device_rr_gsb.get_sb_unique_module(isb); - print_verilog_routing_switch_box_unique_module(module_manager, - verilog_dir, - subckt_dir, - unique_mirror, - use_explicit_port_map); - } - - /* Build unique X-direction connection block modules */ - for (size_t icb = 0; icb < L_device_rr_gsb.get_num_cb_unique_module(CHANX); ++icb) { - const RRGSB& unique_mirror = L_device_rr_gsb.get_cb_unique_module(CHANX, icb); - - print_verilog_routing_connection_box_unique_module(module_manager, - verilog_dir, - subckt_dir, - unique_mirror, CHANX, - use_explicit_port_map); - } - - /* Build unique X-direction connection block modules */ - for (size_t icb = 0; icb < L_device_rr_gsb.get_num_cb_unique_module(CHANY); ++icb) { - const RRGSB& unique_mirror = L_device_rr_gsb.get_cb_unique_module(CHANY, icb); - - print_verilog_routing_connection_box_unique_module(module_manager, - verilog_dir, - subckt_dir, - unique_mirror, CHANY, - use_explicit_port_map); - } - - vpr_printf(TIO_MESSAGE_INFO,"Generating header file for routing submodules...\n"); - dump_verilog_subckt_header_file(routing_verilog_subckt_file_path_head, - subckt_dir.c_str(), - routing_verilog_file_name); - -} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.cpp new file mode 100644 index 000000000..c392f699f --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.cpp @@ -0,0 +1,351 @@ +/********************************************************************* + * This file includes functions that are used for + * Verilog generation of FPGA routing architecture (global routing) + *********************************************************************/ +#include +#include "vtr_assert.h" + +/* Include FPGA-X2P header files*/ +#include "fpga_x2p_naming.h" +#include "fpga_x2p_utils.h" + +/* Include FPGA-Verilog header files*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_writer_utils.h" +#include "verilog_module_writer.h" +#include "verilog_routing.h" + +/******************************************************************** + * Print the sub-circuit of a connection Box (Type: [CHANX|CHANY]) + * Actually it is very similiar to switch box but + * the difference is connection boxes connect Grid INPUT Pins to channels + * NOTE: direct connection between CLBs should NOT be included inside this + * module! They should be added in the top-level module as their connection + * is not limited to adjacent CLBs!!! + * + * Location of a X- and Y-direction Connection Block in FPGA fabric + * +------------+ +-------------+ + * | |------>| | + * | CLB |<------| Y-direction | + * | | ... | Connection | + * | |------>| Block | + * +------------+ +-------------+ + * | ^ ... | | ^ ... | + * v | v v | v + * +-------------------+ +-------------+ + * --->| |--->| | + * <---| X-direction |<---| Switch | + * ...| Connection block |... | Block | + * --->| |--->| | + * +-------------------+ +-------------+ + * + * Internal structure: + * This is an example of a X-direction connection block + * Note that middle output ports are shorted wire from inputs of routing tracks, + * which are also the inputs of routing multiplexer of the connection block + * + * CLB Input Pins + * (IPINs) + * ^ ^ ^ + * | | ... | + * +--------------------------+ + * | ^ ^ ^ | + * | | | ... | | + * | +--------------------+ | + * | | routing | | + * | | multiplexers | | + * | +--------------------+ | + * | middle outputs | + * | of routing channel | + * | ^ ^ ^ ^ ^ ^ ^ ^ | + * | | | | | ... | | | | | + * in[0] -->|------------------------->|---> out[0] + * out[1] <--|<-------------------------|<--- in[1] + * | ... | + * in[W-2] -->|------------------------->|---> out[W-2] + * out[W-1] <--|<-------------------------|<--- in[W-1] + * +--------------------------+ + * + * W: routing channel width + * + ********************************************************************/ +static +void print_verilog_routing_connection_box_unique_module(ModuleManager& module_manager, + const std::string& verilog_dir, + const std::string& subckt_dir, + const RRGSB& rr_gsb, + const t_rr_type& cb_type, + const bool& use_explicit_port_map) { + /* Create the netlist */ + vtr::Point gsb_coordinate(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type)); + std::string verilog_fname(subckt_dir + generate_connection_block_netlist_name(cb_type, gsb_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, std::string("Verilog modules for Unique Connection Blocks[" + std::to_string(rr_gsb.get_cb_x(cb_type)) + "]["+ std::to_string(rr_gsb.get_cb_y(cb_type)) + "]")); + + /* 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 cb_module = module_manager.find_module(generate_connection_block_module_name(cb_type, gsb_coordinate)); + VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); + + /* Write the verilog module */ + write_verilog_module_to_file(fp, module_manager, cb_module, use_explicit_port_map); + + /* Add an empty line as a splitter */ + fp << std::endl; + + /* Close file handler */ + fp.close(); + + /* Add fname to the linked list */ + routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, verilog_fname.c_str()); +} + +/********************************************************************* + * Generate the Verilog module for a Switch Box. + * A Switch Box module consists of following ports: + * 1. Channel Y [x][y] inputs + * 2. Channel X [x+1][y] inputs + * 3. Channel Y [x][y-1] outputs + * 4. Channel X [x][y] outputs + * 5. Grid[x][y+1] Right side outputs pins + * 6. Grid[x+1][y+1] Left side output pins + * 7. Grid[x+1][y+1] Bottom side output pins + * 8. Grid[x+1][y] Top side output pins + * 9. Grid[x+1][y] Left side output pins + * 10. Grid[x][y] Right side output pins + * 11. Grid[x][y] Top side output pins + * 12. Grid[x][y+1] Bottom side output pins + * + * Location of a Switch Box in FPGA fabric: + * + * -------------- -------------- + * | | | | + * | Grid | ChanY | Grid | + * | [x][y+1] | [x][y+1] | [x+1][y+1] | + * | | | | + * -------------- -------------- + * ---------- + * ChanX | Switch | ChanX + * [x][y] | Box | [x+1][y] + * | [x][y] | + * ---------- + * -------------- -------------- + * | | | | + * | Grid | ChanY | Grid | + * | [x][y] | [x][y] | [x+1][y] | + * | | | | + * -------------- -------------- + * + * Switch Block pin location map + * + * Grid[x][y+1] ChanY[x][y+1] Grid[x+1][y+1] + * right_pins inputs/outputs left_pins + * | ^ | + * | | | + * v v v + * +-----------------------------------------------+ + * | | + * Grid[x][y+1] | | Grid[x+1][y+1] + * bottom_pins---->| |<---- bottom_pins + * | | + * ChanX[x][y] | Switch Box [x][y] | ChanX[x+1][y] + * inputs/outputs<--->| |<---> inputs/outputs + * | | + * Grid[x][y+1] | | Grid[x+1][y+1] + * top_pins---->| |<---- top_pins + * | | + * +-----------------------------------------------+ + * ^ ^ ^ + * | | | + * | v | + * Grid[x][y] ChanY[x][y] Grid[x+1][y] + * right_pins inputs/outputs left_pins + * + * + ********************************************************************/ +static +void print_verilog_routing_switch_box_unique_module(ModuleManager& module_manager, + const std::string& verilog_dir, + const std::string& subckt_dir, + const RRGSB& rr_gsb, + const bool& use_explicit_port_map) { + /* Create the netlist */ + vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); + std::string verilog_fname(subckt_dir + generate_routing_block_netlist_name(sb_verilog_file_name_prefix, gsb_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, std::string("Verilog modules for Unique Switch Blocks[" + std::to_string(rr_gsb.get_sb_x()) + "]["+ std::to_string(rr_gsb.get_sb_y()) + "]")); + + /* 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 sb_module = module_manager.find_module(generate_switch_block_module_name(gsb_coordinate)); + VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); + + /* Write the verilog module */ + write_verilog_module_to_file(fp, module_manager, sb_module, use_explicit_port_map); + + /* Close file handler */ + fp.close(); + + /* Add fname to the linked list */ + routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, verilog_fname.c_str()); + + return; +} + + +/******************************************************************** + * Iterate over all the connection blocks in a device + * and build a module for each of them + *******************************************************************/ +static +void print_verilog_flatten_connection_block_modules(ModuleManager& module_manager, + const DeviceRRGSB& L_device_rr_gsb, + const std::string& verilog_dir, + const std::string& subckt_dir, + const t_rr_type& cb_type, + const bool& use_explicit_port_map) { + /* Build unique X-direction connection block modules */ + DeviceCoordinator cb_range = L_device_rr_gsb.get_gsb_range(); + + for (size_t ix = 0; ix < cb_range.get_x(); ++ix) { + for (size_t iy = 0; iy < cb_range.get_y(); ++iy) { + /* Check if the connection block exists in the device! + * Some of them do NOT exist due to heterogeneous blocks (height > 1) + * We will skip those modules + */ + const RRGSB& rr_gsb = L_device_rr_gsb.get_gsb(ix, iy); + if ( (TRUE != is_cb_exist(cb_type, rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type))) + || (true != rr_gsb.is_cb_exist(cb_type))) { + continue; + } + print_verilog_routing_connection_box_unique_module(module_manager, + verilog_dir, + subckt_dir, + rr_gsb, cb_type, + use_explicit_port_map); + } + } +} + +/******************************************************************** + * A top-level function of this file + * Print all the modules for global routing architecture of a FPGA fabric + * in Verilog format in a flatten way: + * Each connection block and switch block will be generated as a unique module + * Covering: + * 1. Connection blocks + * 2. Switch blocks + *******************************************************************/ +void print_verilog_flatten_routing_modules(ModuleManager& module_manager, + const DeviceRRGSB& L_device_rr_gsb, + const t_det_routing_arch& routing_arch, + const std::string& verilog_dir, + const std::string& subckt_dir, + const bool& use_explicit_port_map) { + /* We only support uni-directional routing architecture now */ + VTR_ASSERT (UNI_DIRECTIONAL == routing_arch.directionality); + + /* TODO: deprecate DeviceCoordinator, use vtr::Point only! */ + DeviceCoordinator sb_range = L_device_rr_gsb.get_gsb_range(); + + /* Build unique switch block modules */ + for (size_t ix = 0; ix < sb_range.get_x(); ++ix) { + for (size_t iy = 0; iy < sb_range.get_y(); ++iy) { + const RRGSB& rr_gsb = L_device_rr_gsb.get_gsb(ix, iy); + print_verilog_routing_switch_box_unique_module(module_manager, + verilog_dir, + subckt_dir, + rr_gsb, + use_explicit_port_map); + } + } + + print_verilog_flatten_connection_block_modules(module_manager, L_device_rr_gsb, verilog_dir, subckt_dir, CHANX, use_explicit_port_map); + + print_verilog_flatten_connection_block_modules(module_manager, L_device_rr_gsb, verilog_dir, subckt_dir, CHANY, use_explicit_port_map); + + vpr_printf(TIO_MESSAGE_INFO,"Generating header file for routing submodules...\n"); + dump_verilog_subckt_header_file(routing_verilog_subckt_file_path_head, + subckt_dir.c_str(), + routing_verilog_file_name); +} + + +/******************************************************************** + * A top-level function of this file + * Print all the unique modules for global routing architecture of a FPGA fabric + * in Verilog format, including: + * 1. Connection blocks + * 2. Switch blocks + * + * Note: this function SHOULD be called only when + * the option compact_routing_hierarchy is turned on!!! + *******************************************************************/ +void print_verilog_unique_routing_modules(ModuleManager& module_manager, + const DeviceRRGSB& L_device_rr_gsb, + const t_det_routing_arch& routing_arch, + const std::string& verilog_dir, + const std::string& subckt_dir, + const bool& use_explicit_port_map) { + /* We only support uni-directional routing architecture now */ + VTR_ASSERT (UNI_DIRECTIONAL == routing_arch.directionality); + + /* Build unique switch block modules */ + for (size_t isb = 0; isb < L_device_rr_gsb.get_num_sb_unique_module(); ++isb) { + const RRGSB& unique_mirror = L_device_rr_gsb.get_sb_unique_module(isb); + print_verilog_routing_switch_box_unique_module(module_manager, + verilog_dir, + subckt_dir, + unique_mirror, + use_explicit_port_map); + } + + /* Build unique X-direction connection block modules */ + for (size_t icb = 0; icb < L_device_rr_gsb.get_num_cb_unique_module(CHANX); ++icb) { + const RRGSB& unique_mirror = L_device_rr_gsb.get_cb_unique_module(CHANX, icb); + + print_verilog_routing_connection_box_unique_module(module_manager, + verilog_dir, + subckt_dir, + unique_mirror, CHANX, + use_explicit_port_map); + } + + /* Build unique X-direction connection block modules */ + for (size_t icb = 0; icb < L_device_rr_gsb.get_num_cb_unique_module(CHANY); ++icb) { + const RRGSB& unique_mirror = L_device_rr_gsb.get_cb_unique_module(CHANY, icb); + + print_verilog_routing_connection_box_unique_module(module_manager, + verilog_dir, + subckt_dir, + unique_mirror, CHANY, + use_explicit_port_map); + } + + vpr_printf(TIO_MESSAGE_INFO,"Generating header file for routing submodules...\n"); + dump_verilog_subckt_header_file(routing_verilog_subckt_file_path_head, + subckt_dir.c_str(), + routing_verilog_file_name); + +}