affliate configuration bitstream to sb blocks

This commit is contained in:
tangxifan 2019-10-25 10:42:12 -06:00
parent cc63adf6e0
commit 0b687669c8
9 changed files with 89 additions and 23 deletions

View File

@ -734,6 +734,22 @@ std::string generate_grid_block_module_name(const std::string& prefix,
return module_name;
}
/*********************************************************************
* Generate the instance name for a configurable memory module in a Switch Block
********************************************************************/
std::string generate_sb_memory_instance_name(const std::string& prefix,
const e_side& sb_side,
const size_t& track_id,
const std::string& postfix) {
std::string instance_name(prefix);
instance_name += std::string("_") + Side(sb_side).to_string();
instance_name += std::string("_track_") + std::to_string(track_id);
instance_name += postfix;
return instance_name;
}
/*********************************************************************
* Generate the instance name of a grid block
**********************************************************************/
@ -753,7 +769,6 @@ std::string generate_grid_block_instance_name(const std::string& prefix,
return module_name;
}
/*********************************************************************
* Generate the module name of a physical block
* To ensure a unique name for each physical block inside the graph of complex blocks

View File

@ -76,6 +76,11 @@ std::string generate_switch_block_module_name(const vtr::Point<size_t>& coordina
std::string generate_connection_block_module_name(const t_rr_type& cb_type,
const vtr::Point<size_t>& coordinate);
std::string generate_sb_memory_instance_name(const std::string& prefix,
const e_side& sb_side,
const size_t& track_id,
const std::string& postfix);
std::string generate_grid_port_name(const vtr::Point<size_t>& coordinate,
const size_t& height,
const e_side& side,

View File

@ -0,0 +1,13 @@
/********************************************************************
* This file includes all the reserved words that are used in
* naming module, blocks, instances and cells in FPGA X2P support,
* including:
* Verilog generation, SPICE generation and bitstream generation
*******************************************************************/
#ifndef FPGA_X2P_RESERVED_WORDS_H
#define FPGA_X2P_RESERVED_WORDS_H
constexpr char* SWITCH_BLOCK_MEM_INSTANCE_PREFIX = "mem_";
constexpr char* MEMORY_MODULE_POSTFIX = "_mem";
#endif

View File

@ -77,7 +77,7 @@ BitstreamManager build_device_bitstream(const t_vpr_setup& vpr_setup,
ConfigBlockId top_block = bitstream_manager.add_block(top_block_name);
/* Create bitstream from routing architectures */
build_routing_bitstream(bitstream_manager, module_manager, circuit_lib, mux_lib, rr_switches, L_rr_node, L_device_rr_gsb);
build_routing_bitstream(bitstream_manager, top_block, module_manager, circuit_lib, mux_lib, rr_switches, L_rr_node, L_device_rr_gsb);
/* End time count */
clock_t t_end = clock();

View File

@ -10,6 +10,7 @@
#include "vtr_assert.h"
#include "util.h"
#include "mux_utils.h"
#include "fpga_x2p_reserved_words.h"
#include "fpga_x2p_types.h"
#include "fpga_x2p_naming.h"
#include "fpga_x2p_utils.h"
@ -25,12 +26,12 @@
*******************************************************************/
static
void build_switch_block_mux_bitstream(BitstreamManager& bitstream_manager,
const ConfigBlockId& mux_mem_block,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const std::vector<t_switch_inf>& rr_switches,
t_rr_node* L_rr_node,
const RRGSB& rr_gsb,
t_rr_node* cur_rr_node,
const std::vector<t_rr_node*>& drive_rr_nodes,
const int& switch_index) {
@ -60,9 +61,18 @@ void build_switch_block_mux_bitstream(BitstreamManager& bitstream_manager,
/* Generate bitstream depend on both technology and structure of this MUX */
std::vector<bool> mux_bitstream = build_mux_bitstream(circuit_lib, mux_model, mux_lib, datapath_mux_size, path_id);
/* Find the module in module manager and ensure the bitstream size matches! */
std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(MEMORY_MODULE_POSTFIX));
ModuleId mux_mem_module = module_manager.find_module(mem_module_name);
VTR_ASSERT (true == module_manager.valid_module_id(mux_mem_module));
ModulePortId mux_mem_out_port_id = module_manager.find_module_port(mux_mem_module, generate_configuration_chain_data_out_name());
VTR_ASSERT(mux_bitstream.size() == module_manager.module_port(mux_mem_module, mux_mem_out_port_id).get_width());
/* Add the bistream to the bitstream manager */
for (const bool& bit : mux_bitstream) {
bitstream_manager.add_bit(bit);
ConfigBitId config_bit = bitstream_manager.add_bit(bit);
/* Link the memory bits to the mux mem block */
bitstream_manager.add_bit_to_block(mux_mem_block, config_bit);
}
}
@ -75,6 +85,7 @@ void build_switch_block_mux_bitstream(BitstreamManager& bitstream_manager,
*******************************************************************/
static
void build_switch_block_interc_bitstream(BitstreamManager& bitstream_manager,
const ConfigBlockId& sb_configurable_block,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
@ -105,10 +116,14 @@ void build_switch_block_interc_bitstream(BitstreamManager& bitstream_manager,
/* No bitstream generation required by a special direct connection*/
return;
} else if (1 < drive_rr_nodes.size()) {
/* Create the block denoting the memory instances that drives this node in Switch Block */
std::string mem_block_name = generate_sb_memory_instance_name(SWITCH_BLOCK_MEM_INSTANCE_PREFIX, chan_side, chan_node_id, std::string(""));
ConfigBlockId mux_mem_block = bitstream_manager.add_block(mem_block_name);
bitstream_manager.add_child_block(sb_configurable_block, mux_mem_block);
/* This is a routing multiplexer! Generate bitstream */
build_switch_block_mux_bitstream(bitstream_manager, module_manager,
build_switch_block_mux_bitstream(bitstream_manager, mux_mem_block, module_manager,
circuit_lib, mux_lib, rr_switches, L_rr_node,
rr_gsb, cur_rr_node, drive_rr_nodes,
cur_rr_node, drive_rr_nodes,
cur_rr_node->drive_switches[DEFAULT_SWITCH_ID]);
} /*Nothing should be done else*/
}
@ -126,27 +141,28 @@ void build_switch_block_interc_bitstream(BitstreamManager& bitstream_manager,
*******************************************************************/
static
void build_switch_block_bitstream(BitstreamManager& bitstream_manager,
const ConfigBlockId& sb_configurable_block,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const std::vector<t_switch_inf>& rr_switches,
t_rr_node* L_rr_node,
const RRGSB& rr_sb) {
/* TODO: Create a block for the bitstream which corresponds to the Switch block */
const RRGSB& rr_gsb) {
/* Iterate over all the multiplexers */
for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) {
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
Side side_manager(side);
for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) {
VTR_ASSERT( (CHANX == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type)
|| (CHANY == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type));
for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) {
VTR_ASSERT( (CHANX == rr_gsb.get_chan_node(side_manager.get_side(), itrack)->type)
|| (CHANY == rr_gsb.get_chan_node(side_manager.get_side(), itrack)->type));
/* Only output port indicates a routing multiplexer */
if (OUT_PORT != rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)) {
if (OUT_PORT != rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
continue;
}
build_switch_block_interc_bitstream(bitstream_manager, module_manager,
build_switch_block_interc_bitstream(bitstream_manager, sb_configurable_block,
module_manager,
circuit_lib, mux_lib, rr_switches, L_rr_node,
rr_sb, side_manager.get_side(), itrack);
rr_gsb, side_manager.get_side(), itrack);
}
}
}
@ -158,6 +174,7 @@ void build_switch_block_bitstream(BitstreamManager& bitstream_manager,
* 2. Generate bitstreams for both X-direction and Y-direction Connection Blocks
*******************************************************************/
void build_routing_bitstream(BitstreamManager& bitstream_manager,
const ConfigBlockId& top_configurable_block,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
@ -175,7 +192,13 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager,
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);
build_switch_block_bitstream(bitstream_manager, module_manager,
/* Create a block for the bitstream which corresponds to the Switch block */
vtr::Point<size_t> sb_coord(rr_gsb.get_sb_x(), rr_gsb.get_sb_y());
ConfigBlockId sb_configurable_block = bitstream_manager.add_block(generate_switch_block_module_name(sb_coord));
/* Set switch block as a child of top block */
bitstream_manager.add_child_block(top_configurable_block, sb_configurable_block);
build_switch_block_bitstream(bitstream_manager, sb_configurable_block, module_manager,
circuit_lib, mux_lib, rr_switches, L_rr_node,
rr_gsb);
}

View File

@ -13,6 +13,7 @@
#include "rr_blocks.h"
void build_routing_bitstream(BitstreamManager& bitstream_manager,
const ConfigBlockId& top_configurable_block,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,

View File

@ -16,6 +16,7 @@
#include "globals.h"
/* Header files for FPGA X2P tool suite */
#include "fpga_x2p_reserved_words.h"
#include "fpga_x2p_naming.h"
#include "fpga_x2p_types.h"
#include "fpga_x2p_utils.h"
@ -338,7 +339,7 @@ void build_primitive_block_module(ModuleManager& module_manager,
add_primitive_pb_type_module_nets(module_manager, primitive_module, logic_module, logic_instance_id, circuit_lib, primitive_pb_graph_node->pb_type);
/* Add the associated memory module as a child of primitive module */
std::string memory_module_name = generate_memory_module_name(circuit_lib, primitive_model, sram_model, std::string(verilog_mem_posfix));
std::string memory_module_name = generate_memory_module_name(circuit_lib, primitive_model, sram_model, std::string(MEMORY_MODULE_POSTFIX));
ModuleId memory_module = module_manager.find_module(memory_module_name);
/* Vectors to record all the memory modules have been added
@ -551,7 +552,7 @@ void add_module_pb_graph_pin_interc(ModuleManager& module_manager,
std::string mux_mem_module_name = generate_mux_subckt_name(circuit_lib,
cur_interc->circuit_model,
fan_in,
std::string(verilog_mem_posfix));
std::string(MEMORY_MODULE_POSTFIX));
ModuleId mux_mem_module = module_manager.find_module(mux_mem_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mux_mem_module));
size_t mux_mem_instance = module_manager.num_instance(pb_module, mux_mem_module);

View File

@ -20,6 +20,7 @@
/* FPGA-X2P context header files */
#include "spice_types.h"
#include "fpga_x2p_reserved_words.h"
#include "fpga_x2p_naming.h"
#include "fpga_x2p_utils.h"
@ -586,7 +587,7 @@ void build_mux_memory_module(ModuleManager& module_manager,
/* Generate module name */
std::string module_name = generate_mux_subckt_name(circuit_lib, mux_model,
find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()),
std::string(verilog_mem_posfix));
std::string(MEMORY_MODULE_POSTFIX));
/* Get the sram ports from the mux */
std::vector<CircuitModelId> sram_models = find_circuit_sram_models(circuit_lib, mux_model);
@ -671,7 +672,7 @@ void build_memory_modules(ModuleManager& module_manager,
VTR_ASSERT( 1 == sram_models.size() );
/* Create the module name for the memory block */
std::string module_name = generate_memory_module_name(circuit_lib, model, sram_models[0], std::string(verilog_mem_posfix));
std::string module_name = generate_memory_module_name(circuit_lib, model, sram_models[0], std::string(MEMORY_MODULE_POSTFIX));
/* Create a Verilog module for the memories used by the circuit model */
build_memory_module(module_manager, circuit_lib, sram_orgz_type, module_name, sram_models[0], num_mems);

View File

@ -13,6 +13,7 @@
#include "util.h"
#include "device_coordinator.h"
#include "fpga_x2p_reserved_words.h"
#include "fpga_x2p_types.h"
#include "fpga_x2p_naming.h"
@ -226,6 +227,7 @@ void build_switch_block_mux_module(ModuleManager& module_manager,
const std::vector<std::vector<t_grid_tile>>& grids,
const std::vector<t_switch_inf>& rr_switches,
const e_side& chan_side,
const size_t& chan_node_id,
t_rr_node* cur_rr_node,
const std::vector<t_rr_node*>& drive_rr_nodes,
const size_t& switch_index,
@ -291,12 +293,17 @@ void build_switch_block_mux_module(ModuleManager& module_manager,
/* Instanciate memory modules */
/* Find the name and module id of the memory module */
std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(verilog_mem_posfix));
std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(MEMORY_MODULE_POSTFIX));
ModuleId mem_module = module_manager.find_module(mem_module_name);
VTR_ASSERT (true == module_manager.valid_module_id(mem_module));
size_t mem_instance_id = module_manager.num_instance(sb_module, mem_module);
module_manager.add_child_module(sb_module, mem_module);
/* Give an instance name: this name should be consistent with the block name given in bitstream manager,
* If you want to bind the bitstream generation to modules
*/
std::string mem_instance_name = generate_sb_memory_instance_name(SWITCH_BLOCK_MEM_INSTANCE_PREFIX, chan_side, chan_node_id, std::string(""));
module_manager.set_child_instance_name(sb_module, mem_module, mem_instance_id, mem_instance_name);
/* Add nets to connect regular and mode-select SRAM ports to the SRAM port of memory module */
add_module_nets_between_logic_and_memory_sram_bus(module_manager, sb_module,
@ -355,7 +362,7 @@ void build_switch_block_interc_modules(ModuleManager& module_manager,
/* Print the multiplexer, fan_in >= 2 */
build_switch_block_mux_module(module_manager,
sb_module, rr_gsb, circuit_lib,
grids, rr_switches, chan_side, cur_rr_node,
grids, rr_switches, chan_side, chan_node_id, cur_rr_node,
drive_rr_nodes,
cur_rr_node->drive_switches[DEFAULT_SWITCH_ID],
input_port_to_module_nets);
@ -756,7 +763,7 @@ void build_connection_block_mux_module(ModuleManager& module_manager,
/* Instanciate memory modules */
/* Find the name and module id of the memory module */
std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(verilog_mem_posfix));
std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(MEMORY_MODULE_POSTFIX));
ModuleId mem_module = module_manager.find_module(mem_module_name);
VTR_ASSERT (true == module_manager.valid_module_id(mem_module));