diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context.cpp deleted file mode 100644 index 95b3ec978..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * This file includes member functions for data structure BitstreamContext - ******************************************************************************/ -#include "vtr_assert.h" -#include "bitstream_context.h" - -/************************************************** - * Public Accessors : Aggregates - *************************************************/ -/* Find all the configuration bits */ -BitstreamContext::config_bit_range BitstreamContext::bits() const { - return vtr::make_range(bit_ids_.begin(), bit_ids_.end()); -} - -/****************************************************************************** - * Public Accessors - ******************************************************************************/ -bool BitstreamContext::bit_value(const ConfigBitId& bit_id) const { - /* Ensure a valid id */ - VTR_ASSERT(true == valid_bit_id(bit_id)); - - return bit_values_[bit_id]; -} - - -/****************************************************************************** - * Public Mutators - ******************************************************************************/ -ConfigBitId BitstreamContext::add_bit(const bool& bit_value) { - ConfigBitId bit = ConfigBitId(bit_ids_.size()); - /* Add a new bit, and allocate associated data structures */ - bit_ids_.push_back(bit); - bit_values_.push_back(bit_value); - shared_config_bit_values_.emplace_back(); - bit_parent_modules_.emplace_back(); - bit_parent_instances_.emplace_back(); - - return bit; -} - -/****************************************************************************** - * Public Validators - ******************************************************************************/ -bool BitstreamContext::valid_bit_id(const ConfigBitId& bit_id) const { - return (size_t(bit_id) < bit_ids_.size()) && (bit_id == bit_ids_[bit_id]); -} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context.h deleted file mode 100644 index 651726784..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context.h +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * This file introduces a data structure to store bitstream-related information - ******************************************************************************/ -#ifndef BITSTREAM_CONTEXT_H -#define BITSTREAM_CONTEXT_H - -#include -#include "vtr_vector.h" -#include "module_manager.h" - -#include "bitstream_context_fwd.h" - -class BitstreamContext { - public: /* Types and ranges */ - typedef vtr::vector::const_iterator config_bit_iterator; - - typedef vtr::Range config_bit_range; - - public: /* Public aggregators */ - /* Find all the configuration bits */ - config_bit_range bits() const; - - public: /* Public Accessors */ - bool bit_value(const ConfigBitId& bit_id) const; - - public: /* Public Mutators */ - ConfigBitId add_bit(const bool& bit_value); - - public: /* Public Validators */ - bool valid_bit_id(const ConfigBitId& bit_id) const; - - private: /* Internal data */ - size_t num_shared_bits_; /* Number of reserved Bit/WL Lines, ONLY applicable to RRAM-based FPGA */ - - /* Unique id of a bit in the Bitstream */ - vtr::vector bit_ids_; - /* value of a bit in the Bitstream */ - vtr::vector bit_values_; - /* value of a shared configuration bits in the Bitstream */ - vtr::vector> shared_config_bit_values_; - - /* Back-annotation for the bits */ - /* Parent Module of a bit in the Bitstream - * For each bit, the list of ModuleId and instance ids reflect its position in the module tree - * The first ModuleId/Instance is the direct parent module/instance of the bit - * while the last ModuleId/instance is the top-level module/instance of the bit - * For example: a bit could be back traced by - * []/.../[] - */ - vtr::vector> bit_parent_modules_; - vtr::vector> bit_parent_instances_; - - /* Fast lookup for bitstream */ - std::map bit_lookup_; -}; - -#endif - diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager.cpp new file mode 100644 index 000000000..c26423b3e --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager.cpp @@ -0,0 +1,141 @@ +/****************************************************************************** + * This file includes member functions for data structure BitstreamManager + ******************************************************************************/ +#include + +#include "vtr_assert.h" +#include "bitstream_manager.h" + +/************************************************** + * Public Accessors : Aggregates + *************************************************/ +/* Find all the configuration bits */ +BitstreamManager::config_bit_range BitstreamManager::bits() const { + return vtr::make_range(bit_ids_.begin(), bit_ids_.end()); +} + +/* Find all the configuration blocks */ +BitstreamManager::config_block_range BitstreamManager::blocks() const { + return vtr::make_range(block_ids_.begin(), block_ids_.end()); +} + +/****************************************************************************** + * Public Accessors + ******************************************************************************/ +bool BitstreamManager::bit_value(const ConfigBitId& bit_id) const { + /* Ensure a valid id */ + VTR_ASSERT(true == valid_bit_id(bit_id)); + + return bit_values_[bit_id]; +} + +std::string BitstreamManager::block_name(const ConfigBlockId& block_id) const { + /* Ensure the input ids are valid */ + VTR_ASSERT(true == valid_block_id(block_id)); + + return block_names_[block_id]; +} + +ConfigBlockId BitstreamManager::block_parent(const ConfigBlockId& block_id) const { + /* Ensure the input ids are valid */ + VTR_ASSERT(true == valid_block_id(block_id)); + + return parent_block_ids_[block_id]; +} + +std::vector BitstreamManager::block_children(const ConfigBlockId& block_id) const { + /* Ensure the input ids are valid */ + VTR_ASSERT(true == valid_block_id(block_id)); + + return child_block_ids_[block_id]; +} + +std::vector BitstreamManager::block_bits(const ConfigBlockId& block_id) const { + /* Ensure the input ids are valid */ + VTR_ASSERT(true == valid_block_id(block_id)); + + return block_bit_ids_[block_id]; +} + +ConfigBlockId BitstreamManager::bit_parent_block(const ConfigBitId& bit_id) const { + /* Ensure the input ids are valid */ + VTR_ASSERT(true == valid_bit_id(bit_id)); + + return bit_parent_block_ids_[bit_id]; +} + +/****************************************************************************** + * Public Mutators + ******************************************************************************/ +ConfigBitId BitstreamManager::add_bit(const bool& bit_value) { + ConfigBitId bit = ConfigBitId(bit_ids_.size()); + /* Add a new bit, and allocate associated data structures */ + bit_ids_.push_back(bit); + bit_values_.push_back(bit_value); + shared_config_bit_values_.emplace_back(); + bit_parent_block_ids_.push_back(ConfigBlockId::INVALID()); + + return bit; +} + +ConfigBlockId BitstreamManager::add_block(const std::string& block_name) { + ConfigBlockId block = ConfigBlockId(block_ids_.size()); + /* Add a new bit, and allocate associated data structures */ + block_ids_.push_back(block); + block_names_.push_back(block_name); + block_bit_ids_.emplace_back(); + parent_block_ids_.push_back(ConfigBlockId::INVALID()); + child_block_ids_.emplace_back(); + + return block; +} + +void BitstreamManager::add_child_block(const ConfigBlockId& parent_block, const ConfigBlockId& child_block) { + /* Ensure the input ids are valid */ + VTR_ASSERT(true == valid_block_id(parent_block)); + VTR_ASSERT(true == valid_block_id(child_block)); + + /* We should have only a parent block for each block! */ + VTR_ASSERT(ConfigBlockId::INVALID() == parent_block_ids_[child_block]); + + /* Ensure the child block is not in the list of children of the parent block */ + std::vector::iterator it = std::find(child_block_ids_[parent_block].begin(), child_block_ids_[parent_block].end(), child_block); + VTR_ASSERT(it == child_block_ids_[parent_block].end()); + + /* Add the child_block to the parent_block */ + child_block_ids_[parent_block].push_back(child_block); + /* Register the block in the parent of the block */ + parent_block_ids_[child_block] = parent_block; +} + +void BitstreamManager::add_bit_to_block(const ConfigBlockId& block, const ConfigBitId& bit) { + /* Ensure the input ids are valid */ + VTR_ASSERT(true == valid_block_id(block)); + VTR_ASSERT(true == valid_bit_id(bit)); + + /* We should have only a parent block for each bit! */ + VTR_ASSERT(ConfigBlockId::INVALID() == bit_parent_block_ids_[bit]); + + /* Add the bit to the block */ + block_bit_ids_[block].push_back(bit); + /* Register the block in the parent of the bit */ + bit_parent_block_ids_[bit] = block; +} + +void BitstreamManager::add_shared_config_bit_values(const ConfigBitId& bit, const std::vector& shared_config_bits) { + /* Ensure the input ids are valid */ + VTR_ASSERT(true == valid_bit_id(bit)); + + shared_config_bit_values_[bit] = shared_config_bits; +} + +/****************************************************************************** + * Public Validators + ******************************************************************************/ +bool BitstreamManager::valid_bit_id(const ConfigBitId& bit_id) const { + return (size_t(bit_id) < bit_ids_.size()) && (bit_id == bit_ids_[bit_id]); +} + +bool BitstreamManager::valid_block_id(const ConfigBlockId& block_id) const { + return (size_t(block_id) < block_ids_.size()) && (block_id == block_ids_[block_id]); +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager.h new file mode 100644 index 000000000..ac35b7539 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager.h @@ -0,0 +1,122 @@ +/****************************************************************************** + * This file introduces a data structure to store bitstream-related information + * + * General concept + * --------------- + * The idea is to create a unified data structure that stores all the configuration bits + * with proper annotation to which modules in FPGA fabric it belongs to. + * 1. It can be easily organized in fabric-dependent representation + * (generate a sequence of bitstream which exactly fit the configuration protocol of FPGA fabric) + * 2. Or it can be easily organized in fabric-independent representation (think about XML file) + * + * Cross-reference + * --------------- + * May be used only when you want to bind the bitstream to a specific FPGA fabric! + * If you do so, please make sure the block name is exactly same as the instance name + * of a child module in ModuleManager!!! + * The configurable modules/instances in module manager are arranged + * in the sequence to fit different configuration protocol. + * By using the link between ModuleManager and BitstreamManager, + * we can build a sequence of configuration bits to fit different configuration protocols. + * + * +------------------+ +-----------------+ + * | | block_name == instance_name | | + * | BitstreamManager |-------------------------------->| ModuleManager | + * | | | | + * +------------------+ +-----------------+ + * + * Restrictions: + * 1. Each block inside BitstreamManager should have only 1 parent block + * and multiple child block + * 2. Each bit inside BitstreamManager should have only 1 parent block + * + ******************************************************************************/ +#ifndef BITSTREAM_MANAGER_H +#define BITSTREAM_MANAGER_H + +#include +#include "vtr_vector.h" + +#include "bitstream_manager_fwd.h" + +class BitstreamManager { + public: /* Types and ranges */ + typedef vtr::vector::const_iterator config_bit_iterator; + typedef vtr::vector::const_iterator config_block_iterator; + + typedef vtr::Range config_bit_range; + typedef vtr::Range config_block_range; + + public: /* Public aggregators */ + /* Find all the configuration bits */ + config_bit_range bits() const; + + config_block_range blocks() const; + + public: /* Public Accessors */ + /* Find the value of bitstream */ + bool bit_value(const ConfigBitId& bit_id) const; + + /* Find a name of a block */ + std::string block_name(const ConfigBlockId& block_id) const; + + /* Find the parent of a block */ + ConfigBlockId block_parent(const ConfigBlockId& block_id) const; + + /* Find the children of a block */ + std::vector block_children(const ConfigBlockId& block_id) const; + + /* Find all the bits that belong to a block */ + std::vector block_bits(const ConfigBlockId& block_id) const; + + /* Find the parent block of a bit */ + ConfigBlockId bit_parent_block(const ConfigBitId& bit_id) const; + + public: /* Public Mutators */ + /* Add a new configuration bit to the bitstream manager */ + ConfigBitId add_bit(const bool& bit_value); + + /* Add a new block of configuration bits to the bitstream manager */ + ConfigBlockId add_block(const std::string& block_name); + + /* Set a block as a child block of another */ + void add_child_block(const ConfigBlockId& parent_block, const ConfigBlockId& child_block); + + /* Add a configuration bit to a block */ + void add_bit_to_block(const ConfigBlockId& block, const ConfigBitId& bit); + + /* Add share configuration bits to a configuration bit */ + void add_shared_config_bit_values(const ConfigBitId& bit, const std::vector& shared_config_bits); + + public: /* Public Validators */ + bool valid_bit_id(const ConfigBitId& bit_id) const; + + bool valid_block_id(const ConfigBlockId& block_id) const; + + private: /* Internal data */ + /* Unique id of a block of bits in the Bitstream */ + vtr::vector block_ids_; + vtr::vector> block_bit_ids_; + + /* Back-annotation for the bits */ + /* Parent block of a bit in the Bitstream + * For each bit, the block name can be designed to be same as the instance name in a module + * to reflect its position in the module tree (ModuleManager) + * Note that the blocks here all unique, unlike ModuleManager where modules can be instanciated + * Therefore, this block graph can be considered as a flattened graph of ModuleGraph + */ + vtr::vector block_names_; + vtr::vector parent_block_ids_; + vtr::vector> child_block_ids_; + + /* Unique id of a bit in the Bitstream */ + vtr::vector bit_ids_; + vtr::vector bit_parent_block_ids_; + /* value of a bit in the Bitstream */ + vtr::vector bit_values_; + /* value of a shared configuration bits in the Bitstream */ + vtr::vector> shared_config_bit_values_; +}; + +#endif + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context_fwd.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager_fwd.h similarity index 60% rename from vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context_fwd.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager_fwd.h index 5309b82bc..a9cebe55a 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_context_fwd.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/bitstream_manager_fwd.h @@ -1,18 +1,20 @@ /************************************************** * This file includes only declarations for * the data structures for bitstream database - * Please refer to bitstream_context.h for more details + * Please refer to bitstream_manager.h for more details *************************************************/ -#ifndef BITSTREAM_CONTEXT_FWD_H -#define BITSTREAM_CONTEXT_MANAGER_FWD_H +#ifndef BITSTREAM_MANAGER_FWD_H +#define BITSTREAM_MANAGER_FWD_H #include "vtr_strong_id.h" /* Strong Ids for BitstreamContext */ +struct config_block_id_tag; struct config_bit_id_tag; +typedef vtr::StrongId ConfigBlockId; typedef vtr::StrongId ConfigBitId; -class BitstreamContext; +class BitstreamManager; #endif