diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c index d29648472..96bb08c38 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c @@ -10,8 +10,10 @@ #include #include #include +#include /* Include vpr structs*/ +#include "vtr_geometry.h" #include "util.h" #include "physical_types.h" #include "vpr_types.h" @@ -315,7 +317,19 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup, dump_verilog_config_peripherals(sram_verilog_orgz_info, src_dir_path, submodule_dir_path); /* Print top-level Verilog module */ - print_verilog_top_module(module_manager, Arch.spice->circuit_lib, sram_verilog_orgz_info, + vtr::Point device_size(nx + 2, ny + 2); + std::vector> grids; + /* Fill the grid vectors */ + grids.resize(device_size.x()); + for (size_t ix = 0; ix < device_size.x(); ++ix) { + grids[ix].resize(device_size.y()); + for (size_t iy = 0; iy < device_size.y(); ++iy) { + grids[ix][iy] = grid[ix][iy]; + } + } + print_verilog_top_module(module_manager, Arch.spice->circuit_lib, + device_size, grids, + sram_verilog_orgz_info, std::string(vpr_setup.FileNameOpts.ArchFile), std::string(src_dir_path), TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_explicit_verilog); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_module.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_module.cpp index e6a2459dc..52bf921e8 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_module.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_module.cpp @@ -3,9 +3,13 @@ * module for the FPGA fabric in Verilog format *******************************************************************/ #include +#include #include "vtr_assert.h" +#include "vpr_types.h" +#include "globals.h" + #include "fpga_x2p_naming.h" #include "fpga_x2p_utils.h" #include "module_manager_utils.h" @@ -15,6 +19,128 @@ #include "verilog_module_writer.h" #include "verilog_top_module.h" + +/******************************************************************** + * Add a instance of a grid module to the top module + *******************************************************************/ +static +void add_top_module_grid_instance(ModuleManager& module_manager, + const ModuleId& top_module, + t_type_ptr grid_type, + const e_side& border_side) { + /* Find the module name for this type of grid */ + std::string grid_module_name_prefix(grid_verilog_file_name_prefix); + /* Add side string to the name if it is valid */ + if (NUM_SIDES != border_side) { + Side side_manager(border_side); + grid_module_name_prefix += std::string(side_manager.to_string()); + grid_module_name_prefix += std::string("_"); + } + std::string grid_module_name = generate_physical_block_module_name(grid_module_name_prefix, grid_type->pb_graph_head->pb_type); + ModuleId grid_module = module_manager.find_module(grid_module_name); + VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); + /* Add the module to top_module */ + module_manager.add_child_module(top_module, grid_module); +} + +/******************************************************************** + * Add all the grids as sub-modules across the fabric + * The grid modules are created for each unique type of grid (based + * on the type in data structure data_structure + * Here, we will iterate over the full fabric (coordinates) + * and instanciate the grid modules + * + * This function assumes an island-style floorplanning for FPGA fabric + * + * +-----------------------------------+ + * | I/O grids | + * | TOP side | + * +-----------------------------------+ + * + * +-----------+ +-----------------------------------+ +------------+ + * | | | | | | + * | I/O grids | | Core grids | | I/O grids | + * | LEFT side | | (CLB, Heterogeneous blocks, etc.) | | RIGHT side | + * | | | | | | + * +-----------+ +-----------------------------------+ +------------+ + * + * +-----------------------------------+ + * | I/O grids | + * | BOTTOM side | + * +-----------------------------------+ + * + *******************************************************************/ +static +void add_top_module_grid_instances(ModuleManager& module_manager, + const ModuleId& top_module, + const vtr::Point& device_size, + const std::vector>& grids) { + /* Instanciate core grids */ + for (size_t ix = 1; ix < device_size.x() - 1; ++ix) { + for (size_t iy = 1; iy < device_size.y() - 1; ++iy) { + /* Bypass EMPTY grid */ + if (EMPTY_TYPE == grids[ix][iy].type) { + continue; + } + /* Skip height > 1 tiles (mostly heterogeneous blocks) */ + if (0 < grids[ix][iy].offset) { + continue; + } + /* We should not meet any I/O grid */ + VTR_ASSERT(IO_TYPE != grids[ix][iy].type); + /* Add a grid module to top_module*/ + add_top_module_grid_instance(module_manager, top_module, + grids[ix][iy].type, + NUM_SIDES); + } + } + + /* Instanciate I/O grids */ + /* Create the coordinate range for each side of FPGA fabric */ + std::vector io_sides{TOP, RIGHT, BOTTOM, LEFT}; + std::map>> io_coordinates; + + /* TOP side*/ + for (size_t ix = 1; ix < device_size.x() - 1; ++ix) { + io_coordinates[TOP].push_back(vtr::Point(ix, device_size.y() - 1)); + } + + /* RIGHT side */ + for (size_t iy = 1; iy < device_size.y() - 1; ++iy) { + io_coordinates[RIGHT].push_back(vtr::Point(device_size.x() - 1, iy)); + } + + /* BOTTOM side*/ + for (size_t ix = 1; ix < device_size.x() - 1; ++ix) { + io_coordinates[BOTTOM].push_back(vtr::Point(ix, 0)); + } + + /* LEFT side */ + for (size_t iy = 1; iy < device_size.y() - 1; ++iy) { + io_coordinates[LEFT].push_back(vtr::Point(0, iy)); + } + + /* Add instances of I/O grids to top_module */ + for (const e_side& io_side : io_sides) { + for (const vtr::Point& io_coordinate : io_coordinates[io_side]) { + /* Bypass EMPTY grid */ + if (EMPTY_TYPE == grids[io_coordinate.x()][io_coordinate.y()].type) { + continue; + } + /* Skip height > 1 tiles (mostly heterogeneous blocks) */ + if (0 < grids[io_coordinate.x()][io_coordinate.y()].offset) { + continue; + } + /* We should not meet any I/O grid */ + VTR_ASSERT(IO_TYPE == grids[io_coordinate.x()][io_coordinate.y()].type); + /* Add a grid module to top_module*/ + add_top_module_grid_instance(module_manager, top_module, + grids[io_coordinate.x()][io_coordinate.y()].type, + io_side); + } + } +} + /******************************************************************** * Print the top-level module for the FPGA fabric in Verilog format * This function will @@ -28,6 +154,8 @@ *******************************************************************/ void print_verilog_top_module(ModuleManager& module_manager, const CircuitLibrary& circuit_lib, + const vtr::Point& device_size, + const std::vector>& grids, t_sram_orgz_info* cur_sram_orgz_info, const std::string& arch_name, const std::string& verilog_dir, @@ -37,8 +165,13 @@ void print_verilog_top_module(ModuleManager& module_manager, ModuleId top_module = module_manager.add_module(top_module_name); /* TODO: Add sub modules, which are grid, SB and CBX/CBY modules as instances */ + /* Add all the grids across the fabric */ + add_top_module_grid_instances(module_manager, top_module, device_size, grids); + /* Add all the SBs across the fabric */ + /* Add all the CBX and CBYs across the fabric */ /* TODO: Add module nets to connect the sub modules */ + /* TODO: Add inter-CLB direct connections */ /* TODO: Add global ports to the top-level module */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_module.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_module.h index acf5c2f14..b5d4f3586 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_module.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_module.h @@ -5,12 +5,16 @@ #define VERILOG_TOP_MODULE_H #include +#include "vtr_geometry.h" +#include "vpr_types.h" #include "spice_types.h" #include "circuit_library.h" #include "module_manager.h" void print_verilog_top_module(ModuleManager& module_manager, const CircuitLibrary& circuit_lib, + const vtr::Point& device_size, + const std::vector>& grids, t_sram_orgz_info* cur_sram_orgz_info, const std::string& arch_name, const std::string& verilog_dir,