diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp index 597329292..3c41111e3 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.cpp @@ -671,3 +671,38 @@ std::string generate_mux_sram_port_name(const CircuitLibrary& circuit_lib, std::string prefix = generate_mux_subckt_name(circuit_lib, mux_model, mux_size, std::string()); return generate_local_sram_port_name(prefix, mux_instance_id, port_type); } + +/********************************************************************* + * Generate the netlist name of a physical block + **********************************************************************/ +std::string generate_physical_block_netlist_name(const std::string& block_name, + const bool& is_block_io, + const e_side& io_side, + const std::string& postfix) { + /* Add the name of physical block */ + std::string module_name(block_name); + + if (true == is_block_io) { + Side side_manager(io_side); + module_name += std::string("_"); + module_name += std::string(side_manager.to_string()); + } + + module_name += postfix; + + return module_name; +} + +/********************************************************************* + * Generate the module name of a physical block + **********************************************************************/ +std::string generate_physical_block_module_name(const std::string& prefix, + const std::string& block_name, + const bool& is_block_io, + const e_side& io_side) { + std::string module_name(prefix); + + module_name += generate_physical_block_netlist_name(block_name, is_block_io, io_side, std::string()); + + return module_name; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h index bd7ced7b8..8673de395 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_naming.h @@ -130,4 +130,14 @@ std::string generate_mux_sram_port_name(const CircuitLibrary& circuit_lib, const size_t& mux_instance_id, const e_spice_model_port_type& port_type); +std::string generate_physical_block_netlist_name(const std::string& block_name, + const bool& is_block_io, + const e_side& io_side, + const std::string& postfix); + +std::string generate_physical_block_module_name(const std::string& prefix, + const std::string& block_name, + const bool& is_block_io, + const e_side& io_side); + #endif 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 f35a024aa..025199f20 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c @@ -280,7 +280,8 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup, vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); /* Dump routing resources: switch blocks, connection blocks and channel tracks */ - print_verilog_routing_resources(module_manager, mux_lib, sram_verilog_orgz_info, src_dir_path, rr_dir_path, Arch, vpr_setup.RoutingArch, + print_verilog_routing_resources(module_manager, mux_lib, 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, vpr_setup.FPGA_SPICE_Opts); @@ -289,9 +290,10 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup, * 1. a compact output * 2. a full-size output */ - dump_compact_verilog_logic_blocks(sram_verilog_orgz_info, src_dir_path, - lb_dir_path, &Arch, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_explicit_verilog); + print_compact_verilog_logic_blocks(module_manager, mux_lib, + sram_verilog_orgz_info, src_dir_path, + lb_dir_path, Arch, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_explicit_verilog); /* Generate the Verilog module of the configuration peripheral protocol * which loads bitstream to FPGA fabric diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c index c38742ddc..191941080 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c @@ -12,6 +12,7 @@ #include /* Include vpr structs*/ +#include "vtr_assert.h" #include "util.h" #include "physical_types.h" #include "vpr_types.h" @@ -29,6 +30,7 @@ #include "fpga_x2p_bitstream_utils.h" #include "spice_mux.h" #include "fpga_x2p_globals.h" +#include "fpga_x2p_naming.h" /* Include Synthesizable Verilog headers */ #include "verilog_global.h" @@ -36,6 +38,7 @@ #include "verilog_primitives.h" #include "verilog_pbtypes.h" #include "verilog_routing.h" +#include "verilog_writer_utils.h" #include "verilog_top_netlist_utils.h" #include "verilog_compact_netlist.h" @@ -274,6 +277,113 @@ void compact_verilog_update_grid_spice_model_and_sram_orgz_info(t_sram_orgz_info return; } +/***************************************************************************** + * This function will create a Verilog file and print out a Verilog netlist + * for a type of physical block + * + * For IO blocks: + * The param 'border_side' is required, which is specify which side of fabric + * the I/O block locates at. + *****************************************************************************/ +void print_verilog_physical_block(ModuleManager& module_manager, + const MuxLibrary& mux_lib, + const CircuitLibrary& circuit_lib, + t_sram_orgz_info* cur_sram_orgz_info, + const std::string& verilog_dir, + const std::string& subckt_dir, + t_type_ptr phy_block_type, + const e_side& border_side, + const bool& use_explicit_mapping) { + /* Check code: if this is an IO block, the border side MUST be valid */ + if (IO_TYPE == phy_block_type) { + VTR_ASSERT(NUM_SIDES != border_side); + } + + /* Give a name to the Verilog netlist */ + /* Create the file name for Verilog */ + std::string verilog_fname(subckt_dir + + generate_physical_block_netlist_name(std::string(phy_block_type->name), + IO_TYPE == phy_block_type, + border_side, + std::string(verilog_netlist_file_postfix)) + ); + /* TODO: remove the bak file when the file is ready */ + verilog_fname += ".bak"; + + /* Create the file stream */ + + /* Echo status */ + if (IO_TYPE == phy_block_type) { + Side side_manager(border_side); + vpr_printf(TIO_MESSAGE_INFO, + "Writing FPGA Verilog Netlist (%s) for logic block %s at %s side ...\n", + verilog_fname.c_str(), phy_block_type->name, + side_manager.c_str()); + } else { + vpr_printf(TIO_MESSAGE_INFO, + "Writing FPGA Verilog Netlist (%s) for logic block %s...\n", + verilog_fname.c_str(), phy_block_type->name); + } + + /* 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 physical block: " + std::string(phy_block_type->name) + "]")); + + /* Print preprocessing flags */ + print_verilog_include_defines_preproc_file(fp, verilog_dir); + + /* TODO: Print Verilog modules for all the pb_types/pb_graph_nodes */ + for (int iz = 0; iz < phy_block_type->capacity; ++iz) { + /* ONLY output one Verilog module (which is unique), others are the same */ + if (0 < iz) { + continue; + } + /* TODO: use a Depth-First Search Algorithm to print the sub-modules + * Note: DFS is the right way. Do NOT use BFS. + * DFS can guarantee that all the sub-modules can be registered properly + * to its parent in module manager + */ + print_verilog_comment(fp, std::string("---- BEGIN Sub-module of physical block:" + std::string(phy_block_type->name) + " ----")); + print_verilog_comment(fp, std::string("---- END Sub-module of physical block:" + std::string(phy_block_type->name) + " ----")); + } + + /* TODO: Create a Verilog Module for the top-level physical block, and add to module manager */ + std::string module_name = generate_physical_block_module_name(std::string(grid_verilog_file_name_prefix), phy_block_type->name, IO_TYPE == phy_block_type, border_side); + ModuleId module_id = module_manager.add_module(module_name); + + /* TODO: Add ports to the module */ + + + /* TODO: Print the module definition for the top-level Verilog module of physical block */ + print_verilog_module_declaration(fp, module_manager, module_id); + /* Finish printing ports */ + + /* Print an empty line a splitter */ + fp << std::endl; + + /* TODO: instanciate all the sub modules */ + for (int iz = 0; iz < phy_block_type->capacity; ++iz) { + } + + /* Put an end to the top-level Verilog module of physical block */ + 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 */ + /* + grid_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(grid_verilog_subckt_file_path_head, verilog_fname.c_str()); + */ +} + /* Create a Verilog file and dump a module consisting of a I/O block, * The pins appear in the port list will depend on the selected border side */ @@ -511,63 +621,81 @@ void dump_compact_verilog_one_physical_block(t_sram_orgz_info* cur_sram_orgz_inf * 2. Only one module for each CLB (FILL_TYPE) * 3. Only one module for each heterogeneous block */ -void dump_compact_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info, - char* verilog_dir, - char* subckt_dir, - t_arch* arch, - bool is_explicit_mapping) { - int itype, iside, num_sides; - int* stamped_spice_model_cnt = NULL; - t_sram_orgz_info* stamped_sram_orgz_info = NULL; - +void print_compact_verilog_logic_blocks(ModuleManager& module_manager, + const MuxLibrary& mux_lib, + t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* subckt_dir, + t_arch& arch, + const bool& is_explicit_mapping) { /* Create a snapshot on spice_model counter */ - stamped_spice_model_cnt = snapshot_spice_model_counter(arch->spice->num_spice_model, - arch->spice->spice_models); + int* stamped_spice_model_cnt = snapshot_spice_model_counter(arch.spice->num_spice_model, + arch.spice->spice_models); /* Create a snapshot on sram_orgz_info */ - stamped_sram_orgz_info = snapshot_sram_orgz_info(cur_sram_orgz_info); + t_sram_orgz_info* stamped_sram_orgz_info = snapshot_sram_orgz_info(cur_sram_orgz_info); /* Enumerate the types, dump one Verilog module for each */ - for (itype = 0; itype < num_types; itype++) { + for (int itype = 0; itype < num_types; itype++) { if (EMPTY_TYPE == &type_descriptors[itype]) { /* Bypass empty type or NULL */ continue; } else if (IO_TYPE == &type_descriptors[itype]) { - num_sides = 4; - /* Special for I/O block, generate one module for each border side */ - for (iside = 0; iside < num_sides; iside++) { + /* Special for I/O block, generate one module for each border side */ + for (int iside = 0; iside < NUM_SIDES; iside++) { + Side side_manager(iside); dump_compact_verilog_one_physical_block(cur_sram_orgz_info, verilog_dir, subckt_dir, &type_descriptors[itype], iside, is_explicit_mapping); + + print_verilog_physical_block(module_manager, mux_lib, arch.spice->circuit_lib, + cur_sram_orgz_info, + std::string(verilog_dir), std::string(subckt_dir), + &type_descriptors[itype], + side_manager.get_side(), + is_explicit_mapping); } continue; } else if (FILL_TYPE == &type_descriptors[itype]) { - /* For CLB */ - dump_compact_verilog_one_physical_block(cur_sram_orgz_info, - verilog_dir, subckt_dir, - &type_descriptors[itype], -1, - is_explicit_mapping); - continue; - } else { - /* For heterogenenous blocks */ + /* For CLB */ dump_compact_verilog_one_physical_block(cur_sram_orgz_info, verilog_dir, subckt_dir, &type_descriptors[itype], -1, is_explicit_mapping); + print_verilog_physical_block(module_manager, mux_lib, arch.spice->circuit_lib, + cur_sram_orgz_info, + std::string(verilog_dir), std::string(subckt_dir), + &type_descriptors[itype], + NUM_SIDES, + is_explicit_mapping); + continue; + } else { + /* For heterogenenous blocks */ + dump_compact_verilog_one_physical_block(cur_sram_orgz_info, + verilog_dir, subckt_dir, + &type_descriptors[itype], -1, + is_explicit_mapping); + + print_verilog_physical_block(module_manager, mux_lib, arch.spice->circuit_lib, + cur_sram_orgz_info, + std::string(verilog_dir), std::string(subckt_dir), + &type_descriptors[itype], + NUM_SIDES, + is_explicit_mapping); } } /* Output a header file for all the logic blocks */ - vpr_printf(TIO_MESSAGE_INFO,"Generating header file for grid submodules...\n"); + vpr_printf(TIO_MESSAGE_INFO, "Generating header file for grid submodules...\n"); dump_verilog_subckt_header_file(grid_verilog_subckt_file_path_head, subckt_dir, logic_block_verilog_file_name); /* Recover spice_model counter */ - set_spice_model_counter(arch->spice->num_spice_model, - arch->spice->spice_models, + set_spice_model_counter(arch.spice->num_spice_model, + arch.spice->spice_models, stamped_spice_model_cnt); /* Restore sram_orgz_info to the base */ @@ -577,8 +705,8 @@ void dump_compact_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info, * THIS FUNCTION MUST GO AFTER OUTPUTING PHYSICAL LOGIC BLOCKS!!! */ compact_verilog_update_grid_spice_model_and_sram_orgz_info(cur_sram_orgz_info, - arch->spice->num_spice_model, - arch->spice->spice_models); + arch.spice->num_spice_model, + arch.spice->spice_models); /* Free */ free_sram_orgz_info(stamped_sram_orgz_info, stamped_sram_orgz_info->type); my_free (stamped_spice_model_cnt); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.h index 5086722d2..2cf7931e7 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.h @@ -1,6 +1,16 @@ #ifndef VERILOG_COMPACT_NETLIST_H #define VERILOG_COMPACT_NETLIST_H +void print_verilog_physical_block(ModuleManager& module_manager, + const MuxLibrary& mux_lib, + const CircuitLibrary& circuit_lib, + t_sram_orgz_info* cur_sram_orgz_info, + const std::string& verilog_dir_path, + const std::string& subckt_dir_path, + t_type_ptr phy_block_type, + const e_side& border_side, + const bool& use_explicit_mapping); + void dump_compact_verilog_one_physical_block(t_sram_orgz_info* cur_sram_orgz_info, char* verilog_dir_path, char* subckt_dir_path, @@ -8,11 +18,13 @@ void dump_compact_verilog_one_physical_block(t_sram_orgz_info* cur_sram_orgz_inf int border_side, bool is_explicit_mapping); -void dump_compact_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info, - char* verilog_dir, - char* subckt_dir, - t_arch* arch, - bool is_explicit_mapping); +void print_compact_verilog_logic_blocks(ModuleManager& module_manager, + const MuxLibrary& mux_lib, + t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* subckt_dir, + t_arch& arch, + const bool& is_explicit_mapping); void dump_compact_verilog_top_netlist(t_sram_orgz_info* cur_sram_orgz_info, char* circuit_name,