[core] now fpga verilog supports tile modules

This commit is contained in:
tangxifan 2023-07-18 22:35:22 -07:00
parent 5ae146bd86
commit 6607bb7e48
18 changed files with 222 additions and 33 deletions

View File

@ -68,6 +68,7 @@ constexpr const char* INV_PORT_POSTFIX = "_inv";
/* Bitstream file strings */
constexpr const char* BITSTREAM_XML_FILE_NAME_POSTFIX = "_bitstream.xml";
constexpr const char* DEFAULT_TILE_DIR_NAME = "tile/";
constexpr const char* DEFAULT_LB_DIR_NAME = "lb/";
constexpr const char* DEFAULT_RR_DIR_NAME = "routing/";
constexpr const char* DEFAULT_SUBMODULE_DIR_NAME = "sub_module/";

View File

@ -9,8 +9,6 @@
/* namespace openfpga begins */
namespace openfpga {
FabricTile::FabricTile(const vtr::Point<size_t>& max_coord) { init(max_coord); }
vtr::Point<size_t> FabricTile::tile_coordinate(
const FabricTileId& tile_id) const {
VTR_ASSERT(valid_tile_id(tile_id));
@ -155,6 +153,8 @@ std::vector<FabricTileId> FabricTile::unique_tiles() const {
return unique_tile_ids_;
}
bool FabricTile::empty() const { return ids_.empty(); }
FabricTileId FabricTile::create_tile(const vtr::Point<size_t>& coord) {
FabricTileId tile_id = FabricTileId(ids_.size());
ids_.push_back(tile_id);

View File

@ -23,9 +23,6 @@ namespace openfpga {
* 2. a collection of unique tiles
*******************************************************************/
class FabricTile {
public: /* Contructors */
FabricTile(const vtr::Point<size_t>& max_coord);
public: /* Accessors */
vtr::Point<size_t> tile_coordinate(const FabricTileId& tile_id) const;
std::vector<vtr::Point<size_t>> pb_coordinates(
@ -64,6 +61,8 @@ class FabricTile {
/** @brief Check if a connection block (with a coordinate) exists in a tile */
bool cb_in_tile(const FabricTileId& tile_id, const t_rr_type& cb_type,
const vtr::Point<size_t>& coord) const;
/** @brief Identify if the fabric tile is empty: no tiles are defined */
bool empty() const;
public: /* Mutators */
FabricTileId create_tile(const vtr::Point<size_t>& coord);

View File

@ -39,6 +39,7 @@ class NetlistManager {
SUBMODULE_NETLIST,
LOGIC_BLOCK_NETLIST,
ROUTING_MODULE_NETLIST,
TILE_MODULE_NETLIST,
TOP_MODULE_NETLIST,
TESTBENCH_NETLIST,
NUM_NETLIST_TYPES

View File

@ -149,8 +149,8 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd,
curr_status = build_device_module_graph(
openfpga_ctx.mutable_module_graph(), openfpga_ctx.mutable_decoder_lib(),
openfpga_ctx.mutable_blwl_shift_register_banks(),
const_cast<const T&>(openfpga_ctx), g_vpr_ctx.device(),
cmd_context.option_enable(cmd, opt_frame_view),
openfpga_ctx.mutable_fabric_tile(), const_cast<const T&>(openfpga_ctx),
g_vpr_ctx.device(), cmd_context.option_enable(cmd, opt_frame_view),
cmd_context.option_enable(cmd, opt_compress_routing),
cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
predefined_fabric_key, tile_config,

View File

@ -10,6 +10,7 @@
#include "device_rr_gsb.h"
#include "fabric_bitstream.h"
#include "fabric_global_port_info.h"
#include "fabric_tile.h"
#include "io_location_map.h"
#include "io_name_map.h"
#include "memory_bank_shift_register_banks.h"
@ -106,6 +107,7 @@ class OpenfpgaContext : public Context {
return io_location_map_;
}
const openfpga::IoNameMap& io_name_map() const { return io_name_map_; }
const openfpga::FabricTile& fabric_tile() const { return fabric_tile_; }
const openfpga::FabricGlobalPortInfo& fabric_global_port_info() const {
return fabric_global_port_info_;
}
@ -165,6 +167,7 @@ class OpenfpgaContext : public Context {
return io_location_map_;
}
openfpga::IoNameMap& mutable_io_name_map() { return io_name_map_; }
openfpga::FabricTile& mutable_fabric_tile() { return fabric_tile_; }
openfpga::FabricGlobalPortInfo& mutable_fabric_global_port_info() {
return fabric_global_port_info_;
}
@ -220,6 +223,7 @@ class OpenfpgaContext : public Context {
openfpga::ModuleManager module_graph_;
openfpga::IoLocationMap io_location_map_;
openfpga::IoNameMap io_name_map_;
openfpga::FabricTile fabric_tile_;
openfpga::FabricGlobalPortInfo fabric_global_port_info_;
/* Bitstream database */

View File

@ -500,8 +500,17 @@ std::string generate_switch_block_module_name(
/*********************************************************************
* Generate the module name for a switch block with a given index
*********************************************************************/
std::string generate_tile_module_name(const size_t& index) {
return std::string("tile_" + std::to_string(index));
std::string generate_tile_module_name(const vtr::Point<size_t>& tile_coord) {
return std::string("tile_" + std::to_string(tile_coord.x()) + "__" +
std::to_string(tile_coord.y()) + "_");
}
/*********************************************************************
* Generate the netlist name of a grid block
**********************************************************************/
std::string generate_tile_module_netlist_name(const std::string& block_name,
const std::string& postfix) {
return block_name + postfix;
}
/*********************************************************************

View File

@ -110,7 +110,10 @@ std::string generate_switch_block_module_name(
std::string generate_connection_block_module_name(
const t_rr_type& cb_type, const vtr::Point<size_t>& coordinate);
std::string generate_tile_module_name(const size_t& index);
std::string generate_tile_module_name(const vtr::Point<size_t>& tile_coord);
std::string generate_tile_module_netlist_name(const std::string& block_name,
const std::string& postfix);
std::string generate_sb_mux_instance_name(const std::string& prefix,
const e_side& sb_side,

View File

@ -57,16 +57,13 @@ int write_fabric_verilog_template(T& openfpga_ctx, const Command& cmd,
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
options.set_compress_routing(openfpga_ctx.flow_manager().compress_routing());
fpga_fabric_verilog(openfpga_ctx.mutable_module_graph(),
openfpga_ctx.mutable_verilog_netlists(),
openfpga_ctx.blwl_shift_register_banks(),
openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(),
openfpga_ctx.decoder_lib(), g_vpr_ctx.device(),
openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.device_rr_gsb(), options);
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
return fpga_fabric_verilog(
openfpga_ctx.mutable_module_graph(),
openfpga_ctx.mutable_verilog_netlists(),
openfpga_ctx.blwl_shift_register_banks(), openfpga_ctx.arch().circuit_lib,
openfpga_ctx.mux_lib(), openfpga_ctx.decoder_lib(), g_vpr_ctx.device(),
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.device_rr_gsb(),
openfpga_ctx.fabric_tile(), options);
}
/********************************************************************

View File

@ -33,7 +33,7 @@ namespace openfpga {
*******************************************************************/
int build_device_module_graph(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
MemoryBankShiftRegisterBanks& blwl_sr_banks,
MemoryBankShiftRegisterBanks& blwl_sr_banks, FabricTile& fabric_tile,
const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx,
const bool& frame_view, const bool& compress_routing,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
@ -103,8 +103,6 @@ int build_device_module_graph(
}
/* Build tile modules if defined */
FabricTile fabric_tile(vtr::Point<size_t>(vpr_device_ctx.grid.width(),
vpr_device_ctx.grid.height()));
if (!tile_config.is_valid()) {
/* Build detailed tile-level information */
status = build_fabric_tile(fabric_tile, tile_config, vpr_device_ctx.grid,
@ -114,9 +112,10 @@ int build_device_module_graph(
}
/* Build the modules */
build_tile_modules(
module_manager, decoder_lib, fabric_tile, vpr_device_ctx.grid,
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.device_rr_gsb(),
vpr_device_ctx.rr_graph, openfpga_ctx.arch().circuit_lib, sram_model,
module_manager, decoder_lib, openfpga_ctx.fabric_tile(),
vpr_device_ctx.grid, openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.device_rr_gsb(), vpr_device_ctx.rr_graph,
openfpga_ctx.arch().circuit_lib, sram_model,
openfpga_ctx.arch().config_protocol.type(), frame_view, verbose);
}

View File

@ -5,6 +5,7 @@
* Include header files that are required by function declaration
*******************************************************************/
#include "fabric_key.h"
#include "fabric_tile.h"
#include "io_name_map.h"
#include "openfpga_context.h"
#include "tile_config.h"
@ -19,7 +20,7 @@ namespace openfpga {
int build_device_module_graph(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
MemoryBankShiftRegisterBanks& blwl_sr_banks,
MemoryBankShiftRegisterBanks& blwl_sr_banks, FabricTile& fabric_tile,
const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx,
const bool& frame_view, const bool& compress_routing,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,

View File

@ -120,6 +120,8 @@ int build_fabric_tile(FabricTile& fabric_tile, const TileConfig& tile_config,
int status_code = CMD_EXEC_SUCCESS;
fabric_tile.init(vtr::Point<size_t>(grids.width(), grids.height()));
/* Depending on the selected style, follow different approaches */
if (tile_config.style() == TileConfig::e_style::TOP_LEFT) {
status_code =

View File

@ -991,10 +991,10 @@ static int build_tile_module(
int status_code = CMD_EXEC_SUCCESS;
/* Create the module */
std::string module_name = generate_tile_module_name(size_t(fabric_tile_id));
vtr::Point<size_t> tile_coord = fabric_tile.tile_coordinate(fabric_tile_id);
std::string module_name = generate_tile_module_name(tile_coord);
VTR_LOGV(verbose, "Building tile module '%s'...\n");
ModuleId tile_module = module_manager.add_module(module_name);
vtr::Point<size_t> tile_coord = fabric_tile.tile_coordinate(fabric_tile_id);
/* Add instance of programmable block */
std::vector<size_t>

View File

@ -23,6 +23,7 @@
#include "verilog_routing.h"
#include "verilog_simulation_info_writer.h"
#include "verilog_submodule.h"
#include "verilog_tile.h"
#include "verilog_top_module.h"
#include "verilog_top_testbench.h"
@ -53,15 +54,18 @@ namespace openfpga {
* We should think clearly about how to handle them for both Verilog and SPICE
*generators!
********************************************************************/
void fpga_fabric_verilog(
int fpga_fabric_verilog(
ModuleManager &module_manager, NetlistManager &netlist_manager,
const MemoryBankShiftRegisterBanks &blwl_sr_banks,
const CircuitLibrary &circuit_lib, const MuxLibrary &mux_lib,
const DecoderLibrary &decoder_lib, const DeviceContext &device_ctx,
const VprDeviceAnnotation &device_annotation,
const DeviceRRGSB &device_rr_gsb, const FabricVerilogOption &options) {
const DeviceRRGSB &device_rr_gsb, const FabricTile &fabric_tile,
const FabricVerilogOption &options) {
vtr::ScopedStartFinishTimer timer("Write Verilog netlists for FPGA fabric\n");
int status_code = CMD_EXEC_SUCCESS;
std::string src_dir_path = format_dir_path(options.output_directory());
/* Create directories */
@ -83,6 +87,13 @@ void fpga_fabric_verilog(
std::string rr_dir_path = src_dir_path + std::string(DEFAULT_RR_DIR_NAME);
create_directory(rr_dir_path);
/* Sub directory under SRC directory to contain all the tile netlists
*/
std::string tile_dir_path = src_dir_path + std::string(DEFAULT_TILE_DIR_NAME);
if (!fabric_tile.empty()) {
create_directory(tile_dir_path);
}
/* Print Verilog files containing preprocessing flags */
print_verilog_preprocessing_flags_netlist(std::string(src_dir_path), options);
@ -115,6 +126,16 @@ void fpga_fabric_verilog(
device_ctx, device_annotation, lb_dir_path,
std::string(DEFAULT_LB_DIR_NAME), options, options.verbose_output());
/* Generate tiles */
if (!fabric_tile.empty()) {
status_code = print_verilog_tiles(
netlist_manager, const_cast<const ModuleManager &>(module_manager),
tile_dir_path, fabric_tile, options);
if (status_code != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
}
/* Generate FPGA fabric */
print_verilog_core_module(netlist_manager,
const_cast<const ModuleManager &>(module_manager),
@ -132,6 +153,8 @@ void fpga_fabric_verilog(
*/
VTR_LOGV(options.verbose_output(), "Written %lu Verilog modules in total\n",
module_manager.num_modules());
return CMD_EXEC_SUCCESS;
}
/********************************************************************

View File

@ -16,6 +16,7 @@
#include "device_rr_gsb.h"
#include "fabric_bitstream.h"
#include "fabric_global_port_info.h"
#include "fabric_tile.h"
#include "fabric_verilog_options.h"
#include "io_location_map.h"
#include "io_name_map.h"
@ -37,13 +38,14 @@
/* begin namespace openfpga */
namespace openfpga {
void fpga_fabric_verilog(
int fpga_fabric_verilog(
ModuleManager& module_manager, NetlistManager& netlist_manager,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const DecoderLibrary& decoder_lib, const DeviceContext& device_ctx,
const VprDeviceAnnotation& device_annotation,
const DeviceRRGSB& device_rr_gsb, const FabricVerilogOption& options);
const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile,
const FabricVerilogOption& options);
int fpga_verilog_full_testbench(
const ModuleManager& module_manager,

View File

@ -138,6 +138,15 @@ void print_verilog_fabric_include_netlist(const NetlistManager& netlist_manager,
}
fp << std::endl;
/* Include all the tile modules */
print_verilog_comment(
fp, std::string("------ Include tile module netlists -----"));
for (const NetlistId& nlist_id :
netlist_manager.netlists_by_type(NetlistManager::TILE_MODULE_NETLIST)) {
print_verilog_include_netlist(fp, netlist_manager.netlist_name(nlist_id));
}
fp << std::endl;
/* Include FPGA top module */
print_verilog_comment(
fp, std::string("------ Include fabric top-level netlists -----"));

View File

@ -0,0 +1,110 @@
/********************************************************************
* This file includes functions that are used to print the top-level
* module for the FPGA fabric in Verilog format
*******************************************************************/
#include "verilog_tile.h"
#include <algorithm>
#include <fstream>
#include <map>
#include "command_exit_codes.h"
#include "openfpga_digest.h"
#include "openfpga_naming.h"
#include "verilog_constants.h"
#include "verilog_module_writer.h"
#include "verilog_writer_utils.h"
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Print the tile module for the FPGA fabric in Verilog format
*******************************************************************/
static int print_verilog_tile_module_netlist(
NetlistManager& netlist_manager, const ModuleManager& module_manager,
const std::string& verilog_dir, const FabricTile& fabric_tile,
const FabricTileId& fabric_tile_id, const FabricVerilogOption& options) {
/* Create a module as the top-level fabric, and add it to the module manager
*/
vtr::Point<size_t> tile_coord = fabric_tile.tile_coordinate(fabric_tile_id);
std::string tile_module_name = generate_tile_module_name(tile_coord);
ModuleId tile_module = module_manager.find_module(tile_module_name);
if (!module_manager.valid_module_id(tile_module)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Start printing out Verilog netlists */
/* Create the file name for Verilog netlist */
std::string verilog_fname(generate_tile_module_netlist_name(
tile_module_name, std::string(VERILOG_NETLIST_FILE_POSTFIX)));
std::string verilog_fpath(verilog_dir + verilog_fname);
VTR_LOG("Writing Verilog netlist '%s' for tile module '%s'...",
verilog_fpath.c_str(), tile_module_name.c_str());
/* Create the file stream */
std::fstream fp;
fp.open(verilog_fpath, std::fstream::out | std::fstream::trunc);
check_file_stream(verilog_fpath.c_str(), fp);
print_verilog_file_header(fp, std::string("Tile Verilog module for FPGA"),
options.time_stamp());
/* Write the module content in Verilog format */
write_verilog_module_to_file(fp, module_manager, tile_module,
options.explicit_port_mapping(),
options.default_net_type());
/* Add an empty line as a splitter */
fp << std::endl;
/* Close file handler */
fp.close();
/* Add fname to the netlist name list */
NetlistId nlist_id = NetlistId::INVALID();
if (options.use_relative_path()) {
nlist_id = netlist_manager.add_netlist(verilog_fname);
} else {
nlist_id = netlist_manager.add_netlist(verilog_fpath);
}
VTR_ASSERT(nlist_id);
netlist_manager.set_netlist_type(nlist_id,
NetlistManager::TILE_MODULE_NETLIST);
VTR_LOG("Done\n");
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Print all the tile modules for the FPGA fabric in Verilog format
*******************************************************************/
int print_verilog_tiles(NetlistManager& netlist_manager,
const ModuleManager& module_manager,
const std::string& verilog_dir,
const FabricTile& fabric_tile,
const FabricVerilogOption& options) {
vtr::ScopedStartFinishTimer timer("Build tile modules for the FPGA fabric");
int status_code = CMD_EXEC_SUCCESS;
/* Build a module for each unique tile */
for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) {
status_code = print_verilog_tile_module_netlist(
netlist_manager, module_manager, verilog_dir, fabric_tile, fabric_tile_id,
options);
if (status_code != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
}
return status_code;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,29 @@
#ifndef VERILOG_TILE_H
#define VERILOG_TILE_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#include "fabric_tile.h"
#include "fabric_verilog_options.h"
#include "module_manager.h"
#include "netlist_manager.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
int print_verilog_tiles(NetlistManager& netlist_manager,
const ModuleManager& module_manager,
const std::string& verilog_dir,
const FabricTile& fabric_tile,
const FabricVerilogOption& options);
} /* end namespace openfpga */
#endif