2020-05-27 16:09:18 -05:00
|
|
|
/******************************************************************************
|
|
|
|
* This file includes member functions for data structure FabricBitstream
|
|
|
|
******************************************************************************/
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include "vtr_assert.h"
|
2020-07-03 16:12:29 -05:00
|
|
|
#include "openfpga_decode.h"
|
2020-05-27 16:09:18 -05:00
|
|
|
#include "fabric_bitstream.h"
|
|
|
|
|
|
|
|
/* begin namespace openfpga */
|
|
|
|
namespace openfpga {
|
|
|
|
|
2020-07-02 17:08:50 -05:00
|
|
|
/**************************************************
|
|
|
|
* Public Constructor
|
|
|
|
*************************************************/
|
|
|
|
FabricBitstream::FabricBitstream() {
|
|
|
|
num_bits_ = 0;
|
2020-07-02 20:17:34 -05:00
|
|
|
invalid_bit_ids_.clear();
|
2020-07-03 16:12:29 -05:00
|
|
|
address_length_ = 0;
|
|
|
|
wl_address_length_ = 0;
|
2020-09-28 22:04:08 -05:00
|
|
|
|
|
|
|
num_regions_ = 0;
|
|
|
|
invalid_region_ids_.clear();
|
2021-01-09 19:47:12 -06:00
|
|
|
|
|
|
|
use_address_ = false;
|
|
|
|
use_wl_address_ = false;
|
2020-07-02 17:08:50 -05:00
|
|
|
}
|
|
|
|
|
2020-05-27 16:09:18 -05:00
|
|
|
/**************************************************
|
|
|
|
* Public Accessors : Aggregates
|
|
|
|
*************************************************/
|
2020-07-03 11:55:25 -05:00
|
|
|
size_t FabricBitstream::num_bits() const {
|
|
|
|
return num_bits_;
|
|
|
|
}
|
|
|
|
|
2020-05-27 16:09:18 -05:00
|
|
|
/* Find all the configuration bits */
|
|
|
|
FabricBitstream::fabric_bit_range FabricBitstream::bits() const {
|
2020-07-02 17:08:50 -05:00
|
|
|
return vtr::make_range(fabric_bit_iterator(FabricBitId(0), invalid_bit_ids_),
|
|
|
|
fabric_bit_iterator(FabricBitId(num_bits_), invalid_bit_ids_));
|
2020-05-27 16:09:18 -05:00
|
|
|
}
|
|
|
|
|
2020-09-28 22:04:08 -05:00
|
|
|
size_t FabricBitstream::num_regions() const {
|
|
|
|
return num_regions_;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find all the configuration bits */
|
|
|
|
FabricBitstream::fabric_bit_region_range FabricBitstream::regions() const {
|
|
|
|
return vtr::make_range(fabric_bit_region_iterator(FabricBitRegionId(0), invalid_region_ids_),
|
|
|
|
fabric_bit_region_iterator(FabricBitRegionId(num_regions_), invalid_region_ids_));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<FabricBitId> FabricBitstream::region_bits(const FabricBitRegionId& region_id) const {
|
|
|
|
/* Ensure a valid id */
|
|
|
|
VTR_ASSERT(true == valid_region_id(region_id));
|
|
|
|
|
2020-09-29 13:22:10 -05:00
|
|
|
return region_bit_ids_[region_id];
|
2020-09-28 22:04:08 -05:00
|
|
|
}
|
|
|
|
|
2020-05-27 16:09:18 -05:00
|
|
|
/******************************************************************************
|
|
|
|
* Public Accessors
|
|
|
|
******************************************************************************/
|
|
|
|
ConfigBitId FabricBitstream::config_bit(const FabricBitId& bit_id) const {
|
|
|
|
/* Ensure a valid id */
|
|
|
|
VTR_ASSERT(true == valid_bit_id(bit_id));
|
|
|
|
|
|
|
|
return config_bit_ids_[bit_id];
|
|
|
|
}
|
|
|
|
|
2020-07-02 16:56:50 -05:00
|
|
|
std::vector<char> FabricBitstream::bit_address(const FabricBitId& bit_id) const {
|
2020-05-27 16:09:18 -05:00
|
|
|
/* Ensure a valid id */
|
|
|
|
VTR_ASSERT(true == valid_bit_id(bit_id));
|
2020-07-03 11:17:03 -05:00
|
|
|
VTR_ASSERT(true == use_address_);
|
2020-05-27 16:09:18 -05:00
|
|
|
|
2020-10-30 22:19:20 -05:00
|
|
|
return bit_addresses_[bit_id];
|
2020-05-30 20:12:46 -05:00
|
|
|
}
|
|
|
|
|
2020-07-02 16:56:50 -05:00
|
|
|
std::vector<char> FabricBitstream::bit_bl_address(const FabricBitId& bit_id) const {
|
2020-05-30 20:12:46 -05:00
|
|
|
return bit_address(bit_id);
|
|
|
|
}
|
|
|
|
|
2020-07-02 16:56:50 -05:00
|
|
|
std::vector<char> FabricBitstream::bit_wl_address(const FabricBitId& bit_id) const {
|
2020-05-30 20:12:46 -05:00
|
|
|
/* Ensure a valid id */
|
|
|
|
VTR_ASSERT(true == valid_bit_id(bit_id));
|
2020-07-03 11:17:03 -05:00
|
|
|
VTR_ASSERT(true == use_address_);
|
|
|
|
VTR_ASSERT(true == use_wl_address_);
|
2020-05-30 20:12:46 -05:00
|
|
|
|
2020-10-30 22:19:20 -05:00
|
|
|
return bit_wl_addresses_[bit_id];
|
2020-05-27 16:09:18 -05:00
|
|
|
}
|
|
|
|
|
2020-07-02 16:56:50 -05:00
|
|
|
char FabricBitstream::bit_din(const FabricBitId& bit_id) const {
|
2020-05-27 16:09:18 -05:00
|
|
|
/* Ensure a valid id */
|
|
|
|
VTR_ASSERT(true == valid_bit_id(bit_id));
|
2020-07-03 11:17:03 -05:00
|
|
|
VTR_ASSERT(true == use_address_);
|
2020-05-27 16:09:18 -05:00
|
|
|
|
|
|
|
return bit_dins_[bit_id];
|
|
|
|
}
|
|
|
|
|
2020-07-03 11:17:03 -05:00
|
|
|
bool FabricBitstream::use_address() const {
|
|
|
|
return use_address_;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FabricBitstream::use_wl_address() const {
|
|
|
|
return use_wl_address_;
|
|
|
|
}
|
|
|
|
|
2020-05-27 16:09:18 -05:00
|
|
|
/******************************************************************************
|
|
|
|
* Public Mutators
|
|
|
|
******************************************************************************/
|
2020-07-03 11:17:03 -05:00
|
|
|
void FabricBitstream::reserve_bits(const size_t& num_bits) {
|
2020-07-02 13:39:18 -05:00
|
|
|
config_bit_ids_.reserve(num_bits);
|
2020-07-03 11:17:03 -05:00
|
|
|
|
|
|
|
if (true == use_address_) {
|
|
|
|
bit_addresses_.reserve(num_bits);
|
|
|
|
bit_dins_.reserve(num_bits);
|
|
|
|
|
|
|
|
if (true == use_wl_address_) {
|
|
|
|
bit_wl_addresses_.reserve(num_bits);
|
|
|
|
}
|
|
|
|
}
|
2020-07-02 13:39:18 -05:00
|
|
|
}
|
|
|
|
|
2020-05-27 16:09:18 -05:00
|
|
|
FabricBitId FabricBitstream::add_bit(const ConfigBitId& config_bit_id) {
|
2020-07-02 17:08:50 -05:00
|
|
|
FabricBitId bit = FabricBitId(num_bits_);
|
2020-05-27 16:09:18 -05:00
|
|
|
/* Add a new bit, and allocate associated data structures */
|
2020-07-02 17:08:50 -05:00
|
|
|
num_bits_++;
|
2020-05-27 16:09:18 -05:00
|
|
|
config_bit_ids_.push_back(config_bit_id);
|
|
|
|
|
2020-10-30 22:19:20 -05:00
|
|
|
if (true == use_address_) {
|
|
|
|
bit_addresses_.emplace_back();
|
|
|
|
bit_dins_.emplace_back();
|
|
|
|
|
|
|
|
if (true == use_wl_address_) {
|
|
|
|
bit_wl_addresses_.emplace_back();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-27 16:09:18 -05:00
|
|
|
return bit;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FabricBitstream::set_bit_address(const FabricBitId& bit_id,
|
2020-07-02 16:56:50 -05:00
|
|
|
const std::vector<char>& address) {
|
2020-05-27 16:09:18 -05:00
|
|
|
VTR_ASSERT(true == valid_bit_id(bit_id));
|
2020-07-03 11:17:03 -05:00
|
|
|
VTR_ASSERT(true == use_address_);
|
2020-07-03 16:12:29 -05:00
|
|
|
VTR_ASSERT(address_length_ == address.size());
|
2020-10-30 22:19:20 -05:00
|
|
|
bit_addresses_[bit_id] = address;
|
2020-05-30 20:12:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void FabricBitstream::set_bit_bl_address(const FabricBitId& bit_id,
|
2020-07-02 16:56:50 -05:00
|
|
|
const std::vector<char>& address) {
|
2020-05-30 20:12:46 -05:00
|
|
|
set_bit_address(bit_id, address);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FabricBitstream::set_bit_wl_address(const FabricBitId& bit_id,
|
2020-07-02 16:56:50 -05:00
|
|
|
const std::vector<char>& address) {
|
2020-05-30 20:12:46 -05:00
|
|
|
VTR_ASSERT(true == valid_bit_id(bit_id));
|
2020-07-03 11:17:03 -05:00
|
|
|
VTR_ASSERT(true == use_address_);
|
|
|
|
VTR_ASSERT(true == use_wl_address_);
|
2020-07-03 16:12:29 -05:00
|
|
|
VTR_ASSERT(wl_address_length_ == address.size());
|
2020-10-30 22:19:20 -05:00
|
|
|
bit_wl_addresses_[bit_id] = address;
|
2020-05-27 16:09:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void FabricBitstream::set_bit_din(const FabricBitId& bit_id,
|
2020-07-02 16:56:50 -05:00
|
|
|
const char& din) {
|
2020-05-27 16:09:18 -05:00
|
|
|
VTR_ASSERT(true == valid_bit_id(bit_id));
|
2020-07-03 11:17:03 -05:00
|
|
|
VTR_ASSERT(true == use_address_);
|
2020-05-27 16:09:18 -05:00
|
|
|
bit_dins_[bit_id] = din;
|
|
|
|
}
|
|
|
|
|
2020-07-03 11:17:03 -05:00
|
|
|
void FabricBitstream::set_use_address(const bool& enable) {
|
|
|
|
/* Add a lock, only can be modified when num bits are zero*/
|
|
|
|
if (0 == num_bits_) {
|
|
|
|
use_address_ = enable;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-03 16:12:29 -05:00
|
|
|
void FabricBitstream::set_address_length(const size_t& length) {
|
|
|
|
if (true == use_address_) {
|
|
|
|
address_length_ = length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FabricBitstream::set_bl_address_length(const size_t& length) {
|
|
|
|
set_address_length(length);
|
|
|
|
}
|
|
|
|
|
2020-07-03 11:17:03 -05:00
|
|
|
void FabricBitstream::set_use_wl_address(const bool& enable) {
|
|
|
|
/* Add a lock, only can be modified when num bits are zero*/
|
|
|
|
if (0 == num_bits_) {
|
|
|
|
use_wl_address_ = enable;
|
|
|
|
}
|
2020-05-27 16:53:40 -05:00
|
|
|
}
|
|
|
|
|
2020-07-03 16:12:29 -05:00
|
|
|
void FabricBitstream::set_wl_address_length(const size_t& length) {
|
|
|
|
if (true == use_address_) {
|
|
|
|
wl_address_length_ = length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-28 22:04:08 -05:00
|
|
|
void FabricBitstream::reserve_regions(const size_t& num_regions) {
|
2020-09-29 13:22:10 -05:00
|
|
|
region_bit_ids_.reserve(num_regions);
|
|
|
|
}
|
|
|
|
|
|
|
|
FabricBitRegionId FabricBitstream::add_region() {
|
|
|
|
FabricBitRegionId region = FabricBitRegionId(num_regions_);
|
|
|
|
/* Add a new bit, and allocate associated data structures */
|
|
|
|
num_regions_++;
|
|
|
|
region_bit_ids_.emplace_back();
|
|
|
|
|
|
|
|
return region;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FabricBitstream::add_bit_to_region(const FabricBitRegionId& region_id,
|
|
|
|
const FabricBitId& bit_id) {
|
|
|
|
VTR_ASSERT(true == valid_region_id(region_id));
|
|
|
|
VTR_ASSERT(true == valid_bit_id(bit_id));
|
|
|
|
|
|
|
|
region_bit_ids_[region_id].push_back(bit_id);
|
2020-09-28 22:04:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void FabricBitstream::reverse() {
|
|
|
|
std::reverse(config_bit_ids_.begin(), config_bit_ids_.end());
|
|
|
|
|
|
|
|
if (true == use_address_) {
|
|
|
|
std::reverse(bit_addresses_.begin(), bit_addresses_.end());
|
|
|
|
std::reverse(bit_dins_.begin(), bit_dins_.end());
|
|
|
|
|
|
|
|
if (true == use_wl_address_) {
|
|
|
|
std::reverse(bit_wl_addresses_.begin(), bit_wl_addresses_.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FabricBitstream::reverse_region_bits(const FabricBitRegionId& region_id) {
|
|
|
|
VTR_ASSERT(true == valid_region_id(region_id));
|
|
|
|
|
2020-09-29 13:22:10 -05:00
|
|
|
std::reverse(region_bit_ids_[region_id].begin(), region_bit_ids_[region_id].end());
|
2020-09-28 22:04:08 -05:00
|
|
|
}
|
|
|
|
|
2020-05-27 16:09:18 -05:00
|
|
|
/******************************************************************************
|
|
|
|
* Public Validators
|
|
|
|
******************************************************************************/
|
2020-09-28 22:04:08 -05:00
|
|
|
bool FabricBitstream::valid_bit_id(const FabricBitId& bit_id) const {
|
2020-07-02 17:08:50 -05:00
|
|
|
return (size_t(bit_id) < num_bits_);
|
2020-05-27 16:09:18 -05:00
|
|
|
}
|
|
|
|
|
2020-09-28 22:04:08 -05:00
|
|
|
bool FabricBitstream::valid_region_id(const FabricBitRegionId& region_id) const {
|
|
|
|
return (size_t(region_id) < num_regions_);
|
|
|
|
}
|
|
|
|
|
2020-05-27 16:09:18 -05:00
|
|
|
} /* end namespace openfpga */
|