reserve configuration blocks and bits in bitstream manager builder to be memory efficient
This commit is contained in:
parent
b85af57971
commit
405824081b
|
@ -154,6 +154,13 @@ void BitstreamManager::reserve_blocks(const size_t& num_blocks) {
|
|||
child_block_ids_.reserve(num_blocks);
|
||||
}
|
||||
|
||||
void BitstreamManager::reserve_bits(const size_t& num_bits) {
|
||||
bit_ids_.reserve(num_bits);
|
||||
bit_values_.reserve(num_bits);
|
||||
shared_config_bit_values_.reserve(num_bits);
|
||||
bit_parent_block_ids_.reserve(num_bits);
|
||||
}
|
||||
|
||||
ConfigBlockId BitstreamManager::create_block() {
|
||||
ConfigBlockId block = ConfigBlockId(block_ids_.size());
|
||||
/* Add a new bit, and allocate associated data structures */
|
||||
|
|
|
@ -98,6 +98,9 @@ class BitstreamManager {
|
|||
/* Reserve memory for a number of clocks */
|
||||
void reserve_blocks(const size_t& num_blocks);
|
||||
|
||||
/* Reserve memory for a number of bits */
|
||||
void reserve_bits(const size_t& num_bits);
|
||||
|
||||
/* Create a new block of configuration bits */
|
||||
ConfigBlockId create_block();
|
||||
|
||||
|
|
|
@ -20,6 +20,82 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Estimate the number of blocks to be added to the whole device bitstream
|
||||
* This function will recursively walk through the module graph
|
||||
* from the specified top module and count the number of configurable children
|
||||
* which are the blocks that will be added to the bitstream manager
|
||||
*******************************************************************/
|
||||
static
|
||||
size_t rec_estimate_device_bitstream_num_blocks(const ModuleManager& module_manager,
|
||||
const ModuleId& top_module) {
|
||||
size_t num_blocks = 0;
|
||||
|
||||
/* Those child modules which have no children are
|
||||
* actually configurable memory elements
|
||||
* We skip them in couting
|
||||
*/
|
||||
if (0 == module_manager.configurable_children(top_module).size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t num_configurable_children = module_manager.configurable_children(top_module).size();
|
||||
for (size_t ichild = 0; ichild < num_configurable_children; ++ichild) {
|
||||
ModuleId child_module = module_manager.configurable_children(top_module)[ichild];
|
||||
num_blocks += rec_estimate_device_bitstream_num_blocks(module_manager, child_module);
|
||||
}
|
||||
|
||||
/* Add the number of blocks at current level */
|
||||
num_blocks++;
|
||||
|
||||
return num_blocks;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Estimate the number of configuration bits to be added to the whole device bitstream
|
||||
* This function will recursively walk through the module graph
|
||||
* from the specified top module and count the number of leaf configurable children
|
||||
* which are the bits that will be added to the bitstream manager
|
||||
*******************************************************************/
|
||||
static
|
||||
size_t rec_estimate_device_bitstream_num_bits(const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const e_config_protocol_type& config_protocol_type) {
|
||||
size_t num_bits = 0;
|
||||
|
||||
/* If a child module has no configurable children, this is a leaf node
|
||||
* We can count it in. Otherwise, we should go recursively.
|
||||
*/
|
||||
if (0 == module_manager.configurable_children(top_module).size()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t num_configurable_children = module_manager.configurable_children(top_module).size();
|
||||
/* Frame-based configuration protocol will have 1 decoder
|
||||
* if there are more than 1 configurable children
|
||||
*/
|
||||
if ( (CONFIG_MEM_FRAME_BASED == config_protocol_type)
|
||||
&& (2 <= num_configurable_children)) {
|
||||
num_configurable_children--;
|
||||
}
|
||||
|
||||
/* Memory configuration protocol will have 2 decoders
|
||||
* at the top-level
|
||||
*/
|
||||
if (CONFIG_MEM_MEMORY_BANK == config_protocol_type) {
|
||||
std::string top_block_name = generate_fpga_top_module_name();
|
||||
if (top_module == module_manager.find_module(top_block_name)) {
|
||||
num_configurable_children -= 2;
|
||||
}
|
||||
}
|
||||
for (size_t ichild = 0; ichild < num_configurable_children; ++ichild) {
|
||||
ModuleId child_module = module_manager.configurable_children(top_module)[ichild];
|
||||
num_bits += rec_estimate_device_bitstream_num_bits(module_manager, child_module, config_protocol_type);
|
||||
}
|
||||
|
||||
return num_bits;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A top-level function to build a bistream from the FPGA device
|
||||
* 1. It will organize the bitstream w.r.t. the hierarchy of module graphs
|
||||
|
@ -52,6 +128,21 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
|
|||
*/
|
||||
std::string top_block_name = generate_fpga_top_module_name();
|
||||
ConfigBlockId top_block = bitstream_manager.add_block(top_block_name);
|
||||
const ModuleId& top_module = openfpga_ctx.module_graph().find_module(top_block_name);
|
||||
VTR_ASSERT(true == openfpga_ctx.module_graph().valid_module_id(top_module));
|
||||
|
||||
/* Estimate the number of blocks to be added to the database */
|
||||
size_t num_blocks_to_reserve = rec_estimate_device_bitstream_num_blocks(openfpga_ctx.module_graph(),
|
||||
top_module);
|
||||
bitstream_manager.reserve_blocks(num_blocks_to_reserve);
|
||||
VTR_LOGV(verbose, "Reserved %lu configurable blocks\n", num_blocks_to_reserve);
|
||||
|
||||
/* Estimate the number of bits to be added to the database */
|
||||
size_t num_bits_to_reserve = rec_estimate_device_bitstream_num_bits(openfpga_ctx.module_graph(),
|
||||
top_module,
|
||||
openfpga_ctx.arch().config_protocol.type());
|
||||
bitstream_manager.reserve_bits(num_bits_to_reserve);
|
||||
VTR_LOGV(verbose, "Reserved %lu configuration bits\n", num_bits_to_reserve);
|
||||
|
||||
/* Create bitstream from grids */
|
||||
VTR_LOGV(verbose, "Building grid bitstream...\n");
|
||||
|
@ -80,7 +171,13 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
|
|||
openfpga_ctx.device_rr_gsb());
|
||||
VTR_LOGV(verbose, "Done\n");
|
||||
|
||||
VTR_LOGV(verbose, "Decoded %lu configuration bits\n", bitstream_manager.bits().size());
|
||||
VTR_LOGV(verbose,
|
||||
"Decoded %lu configuration bits into %lu blocks\n",
|
||||
bitstream_manager.bits().size(),
|
||||
bitstream_manager.blocks().size());
|
||||
|
||||
//VTR_ASSERT(num_blocks_to_reserve == bitstream_manager.blocks().size());
|
||||
//VTR_ASSERT(num_bits_to_reserve == bitstream_manager.bits().size());
|
||||
|
||||
return bitstream_manager;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue