add fabric bitstream support for memory bank configuration protocol

This commit is contained in:
tangxifan 2020-05-30 19:12:46 -06:00
parent 0e16ee1030
commit 51e1559352
3 changed files with 141 additions and 7 deletions

View File

@ -15,6 +15,7 @@
#include "openfpga_reserved_words.h" #include "openfpga_reserved_words.h"
#include "openfpga_naming.h" #include "openfpga_naming.h"
#include "decoder_library_utils.h"
#include "bitstream_manager_utils.h" #include "bitstream_manager_utils.h"
#include "build_fabric_bitstream.h" #include "build_fabric_bitstream.h"
@ -73,6 +74,90 @@ void rec_build_module_fabric_dependent_chain_bitstream(const BitstreamManager& b
} }
} }
/********************************************************************
* This function aims to build a bitstream for memory-bank protocol
* It will walk through all the configurable children under a module
* in a recursive way, following a Depth-First Search (DFS) strategy
* For each configuration child, we use its instance name as a key to spot the
* configuration bits in bitstream manager.
* Note that it is guarentee that the instance name in module manager is
* consistent with the block names in bitstream manager
* We use this link to reorganize the bitstream in the sequence of memories as we stored
* in the configurable_children() and configurable_child_instances() of each module of module manager
*
* In such configuration organization, each memory cell has an unique index.
* Using this index, we can infer the address codes for both BL and WL decoders.
* Note that, we must get the number of BLs and WLs before using this function!
*******************************************************************/
static
void rec_build_module_fabric_dependent_memory_bank_bitstream(const BitstreamManager& bitstream_manager,
const ConfigBlockId& parent_block,
const ModuleManager& module_manager,
const ModuleId& parent_module,
const size_t& bl_addr_size,
const size_t& wl_addr_size,
const size_t& num_bls,
const size_t& num_wls,
size_t& cur_mem_index,
FabricBitstream& fabric_bitstream) {
/* Depth-first search: if we have any children in the parent_block,
* we dive to the next level first!
*/
if (0 < bitstream_manager.block_children(parent_block).size()) {
for (size_t child_id = 0; child_id < module_manager.configurable_children(parent_module).size(); ++child_id) {
ModuleId child_module = module_manager.configurable_children(parent_module)[child_id];
size_t child_instance = module_manager.configurable_child_instances(parent_module)[child_id];
/* Get the instance name and ensure it is not empty */
std::string instance_name = module_manager.instance_name(parent_module, child_module, child_instance);
/* Find the child block that matches the instance name! */
ConfigBlockId child_block = bitstream_manager.find_child_block(parent_block, instance_name);
/* We must have one valid block id! */
if (true != bitstream_manager.valid_block_id(child_block))
VTR_ASSERT(true == bitstream_manager.valid_block_id(child_block));
/* Go recursively */
rec_build_module_fabric_dependent_memory_bank_bitstream(bitstream_manager, child_block,
module_manager, child_module,
bl_addr_size, wl_addr_size,
num_bls, num_wls,
cur_mem_index,
fabric_bitstream);
}
/* Ensure that there should be no configuration bits in the parent block */
VTR_ASSERT(0 == bitstream_manager.block_bits(parent_block).size());
}
/* Note that, reach here, it means that this is a leaf node.
* We add the configuration bits to the fabric_bitstream,
* And then, we can return
*/
for (const ConfigBitId& config_bit : bitstream_manager.block_bits(parent_block)) {
FabricBitId fabric_bit = fabric_bitstream.add_bit(config_bit);
/* Find BL address */
size_t cur_bl_index = cur_mem_index / num_bls;
std::vector<size_t> bl_addr_bits_vec = itobin_vec(cur_bl_index, bl_addr_size);
/* Find WL address */
size_t cur_wl_index = cur_mem_index % num_wls;
std::vector<size_t> wl_addr_bits_vec = itobin_vec(cur_wl_index, wl_addr_size);
/* Set BL address */
fabric_bitstream.set_bit_bl_address(fabric_bit, bl_addr_bits_vec);
/* Set WL address */
fabric_bitstream.set_bit_wl_address(fabric_bit, wl_addr_bits_vec);
/* Set data input */
fabric_bitstream.set_bit_din(fabric_bit, bitstream_manager.bit_value(config_bit));
/* Increase the memory index */
cur_mem_index++;
}
}
/******************************************************************** /********************************************************************
* This function aims to build a bitstream for frame-based configuration protocol * This function aims to build a bitstream for frame-based configuration protocol
* It will walk through all the configurable children under a module * It will walk through all the configurable children under a module
@ -287,6 +372,23 @@ void build_module_fabric_dependent_bitstream(const ConfigProtocol& config_protoc
break; break;
} }
case CONFIG_MEM_MEMORY_BANK: { case CONFIG_MEM_MEMORY_BANK: {
size_t cur_mem_index = 0;
/* Find BL address port size */
ModulePortId bl_addr_port = module_manager.find_module_port(top_module, std::string(MEMORY_BL_PORT_NAME));
BasicPort bl_addr_port_info = module_manager.module_port(top_module, bl_addr_port);
size_t num_bls = find_memory_decoder_data_size(bl_addr_port_info.get_width());
/* Find WL address port size */
ModulePortId wl_addr_port = module_manager.find_module_port(top_module, std::string(MEMORY_WL_PORT_NAME));
BasicPort wl_addr_port_info = module_manager.module_port(top_module, wl_addr_port);
size_t num_wls = find_memory_decoder_data_size(wl_addr_port_info.get_width());
rec_build_module_fabric_dependent_memory_bank_bitstream(bitstream_manager, top_block,
module_manager, top_module,
bl_addr_port_info.get_width(),
wl_addr_port_info.get_width(),
num_bls, num_wls,
cur_mem_index, fabric_bitstream);
break; break;
} }
case CONFIG_MEM_FRAME_BASED: { case CONFIG_MEM_FRAME_BASED: {

View File

@ -31,7 +31,18 @@ std::vector<size_t> FabricBitstream::bit_address(const FabricBitId& bit_id) cons
/* Ensure a valid id */ /* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_id)); VTR_ASSERT(true == valid_bit_id(bit_id));
return bit_addresses_[bit_id]; return bit_addresses_[bit_id][0];
}
std::vector<size_t> FabricBitstream::bit_bl_address(const FabricBitId& bit_id) const {
return bit_address(bit_id);
}
std::vector<size_t> FabricBitstream::bit_wl_address(const FabricBitId& bit_id) const {
/* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_id));
return bit_addresses_[bit_id][1];
} }
bool FabricBitstream::bit_din(const FabricBitId& bit_id) const { bool FabricBitstream::bit_din(const FabricBitId& bit_id) const {
@ -58,7 +69,18 @@ FabricBitId FabricBitstream::add_bit(const ConfigBitId& config_bit_id) {
void FabricBitstream::set_bit_address(const FabricBitId& bit_id, void FabricBitstream::set_bit_address(const FabricBitId& bit_id,
const std::vector<size_t>& address) { const std::vector<size_t>& address) {
VTR_ASSERT(true == valid_bit_id(bit_id)); VTR_ASSERT(true == valid_bit_id(bit_id));
bit_addresses_[bit_id] = address; bit_addresses_[bit_id][0] = address;
}
void FabricBitstream::set_bit_bl_address(const FabricBitId& bit_id,
const std::vector<size_t>& address) {
set_bit_address(bit_id, address);
}
void FabricBitstream::set_bit_wl_address(const FabricBitId& bit_id,
const std::vector<size_t>& address) {
VTR_ASSERT(true == valid_bit_id(bit_id));
bit_addresses_[bit_id][1] = address;
} }
void FabricBitstream::set_bit_din(const FabricBitId& bit_id, void FabricBitstream::set_bit_din(const FabricBitId& bit_id,

View File

@ -13,11 +13,11 @@
* By using the link between ArchBitstreamManager and FabricBitstream, * By using the link between ArchBitstreamManager and FabricBitstream,
* we can build a sequence of configuration bits to fit different configuration protocols. * we can build a sequence of configuration bits to fit different configuration protocols.
* *
* +----------------------+ +--------------------------+ * +----------------------+ +-------------------+
* | | ConfigBitId | | * | | ConfigBitId | |
* | ArchBitstreamManager |---------------->| FabricBitstream | * | ArchBitstreamManager |---------------->| FabricBitstream |
* | | | | * | | | |
* +----------------------+ +--------------------------+ * +----------------------+ +-------------------+
* *
* Restrictions: * Restrictions:
* 1. Each block inside BitstreamManager should have only 1 parent block * 1. Each block inside BitstreamManager should have only 1 parent block
@ -53,6 +53,8 @@ class FabricBitstream {
/* Find the address of bitstream */ /* Find the address of bitstream */
std::vector<size_t> bit_address(const FabricBitId& bit_id) const; std::vector<size_t> bit_address(const FabricBitId& bit_id) const;
std::vector<size_t> bit_bl_address(const FabricBitId& bit_id) const;
std::vector<size_t> bit_wl_address(const FabricBitId& bit_id) const;
/* Find the data-in of bitstream */ /* Find the data-in of bitstream */
bool bit_din(const FabricBitId& bit_id) const; bool bit_din(const FabricBitId& bit_id) const;
@ -64,6 +66,12 @@ class FabricBitstream {
void set_bit_address(const FabricBitId& bit_id, void set_bit_address(const FabricBitId& bit_id,
const std::vector<size_t>& address); const std::vector<size_t>& address);
void set_bit_bl_address(const FabricBitId& bit_id,
const std::vector<size_t>& address);
void set_bit_wl_address(const FabricBitId& bit_id,
const std::vector<size_t>& address);
void set_bit_din(const FabricBitId& bit_id, void set_bit_din(const FabricBitId& bit_id,
const bool& din); const bool& din);
@ -83,8 +91,10 @@ class FabricBitstream {
/* Address bits: this is designed for memory decoders /* Address bits: this is designed for memory decoders
* Here we store the binary format of the address, which can be loaded * Here we store the binary format of the address, which can be loaded
* to the configuration protocol directly * to the configuration protocol directly
*
* We use a 2-element array, as we may have a BL address and a WL address
*/ */
vtr::vector<FabricBitId, std::vector<size_t>> bit_addresses_; vtr::vector<FabricBitId, std::array<std::vector<size_t>, 2>> bit_addresses_;
/* Data input (Din) bits: this is designed for memory decoders */ /* Data input (Din) bits: this is designed for memory decoders */
vtr::vector<FabricBitId, bool> bit_dins_; vtr::vector<FabricBitId, bool> bit_dins_;