diff --git a/libopenfpga/libfabrickey/key_examples/key_example.xml b/libopenfpga/libfabrickey/key_examples/key_example.xml
index 49140b6e0..b9b0aa814 100644
--- a/libopenfpga/libfabrickey/key_examples/key_example.xml
+++ b/libopenfpga/libfabrickey/key_examples/key_example.xml
@@ -1,7 +1,9 @@
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/libopenfpga/libfabrickey/src/fabric_key.cpp b/libopenfpga/libfabrickey/src/fabric_key.cpp
index b4bf5efac..dfe445c75 100644
--- a/libopenfpga/libfabrickey/src/fabric_key.cpp
+++ b/libopenfpga/libfabrickey/src/fabric_key.cpp
@@ -1,4 +1,7 @@
+#include
+
#include "vtr_assert.h"
+#include "vtr_log.h"
#include "fabric_key.h"
@@ -20,24 +23,31 @@ FabricKey::fabric_key_range FabricKey::keys() const {
return vtr::make_range(key_ids_.begin(), key_ids_.end());
}
+FabricKey::fabric_region_range FabricKey::regions() const {
+ return vtr::make_range(region_ids_.begin(), region_ids_.end());
+}
+
/************************************************************************
* Public Accessors : Basic data query
***********************************************************************/
-/* Access the name of a key */
+std::vector FabricKey::region_keys(const FabricRegionId& region_id) const {
+ /* validate the region_id */
+ VTR_ASSERT(valid_region_id(region_id));
+ return region_key_ids_[region_id];
+}
+
std::string FabricKey::key_name(const FabricKeyId& key_id) const {
/* validate the key_id */
VTR_ASSERT(valid_key_id(key_id));
return key_names_[key_id];
}
-/* Access the value of a key */
size_t FabricKey::key_value(const FabricKeyId& key_id) const {
/* validate the key_id */
VTR_ASSERT(valid_key_id(key_id));
return key_values_[key_id];
}
-/* Access the alias of a key */
std::string FabricKey::key_alias(const FabricKeyId& key_id) const {
/* validate the key_id */
VTR_ASSERT(valid_key_id(key_id));
@@ -51,20 +61,78 @@ bool FabricKey::empty() const {
/************************************************************************
* Public Mutators
***********************************************************************/
+
+void FabricKey::reserve_regions(const size_t& num_regions) {
+ region_ids_.reserve(num_regions);
+ region_key_ids_.reserve(num_regions);
+}
+
+FabricRegionId FabricKey::create_region() {
+ /* Create a new id */
+ FabricRegionId region = FabricRegionId(region_ids_.size());
+ region_ids_.push_back(region);
+ region_key_ids_.emplace_back();
+
+ return region;
+}
+
+void FabricKey::reserve_region_keys(const FabricRegionId& region_id,
+ const size_t& num_keys) {
+ /* validate the region_id */
+ VTR_ASSERT(valid_region_id(region_id));
+
+ region_key_ids_[region_id].reserve(num_keys);
+}
+
+void FabricKey::add_key_to_region(const FabricRegionId& region_id,
+ const FabricKeyId& key_id) {
+ /* validate the key_id */
+ VTR_ASSERT(valid_key_id(key_id));
+ /* validate the region_id */
+ VTR_ASSERT(valid_region_id(region_id));
+
+ /* Check if the key is already in the region */
+ if (region_key_ids_[region_id].end() != std::find(region_key_ids_[region_id].begin(),
+ region_key_ids_[region_id].end(),
+ key_id)) {
+ VTR_LOG_WARN("Try to add a key '%s' which is already in the region '%lu'!\n",
+ key_name(key_id).c_str(),
+ size_t(region_id));
+ VTR_ASSERT(region_id == key_regions_[key_id]);
+ return; /* Nothing to do but leave a warning! */
+ }
+
+ /* Register the key in the region */
+ region_key_ids_[region_id].push_back(key_id);
+
+ /* If the key is already in another region, we will error out */
+ if ( (true == valid_region_id(key_regions_[key_id]))
+ && (region_id != key_regions_[key_id])) {
+ VTR_LOG_ERROR("Try to add a key '%s' to region '%lu' but it is already in another region '%lu'!\n",
+ key_name(key_id).c_str(),
+ size_t(key_regions_[key_id]),
+ size_t(region_id));
+ exit(1);
+ }
+
+ key_regions_[key_id] = region_id;
+}
+
void FabricKey::reserve_keys(const size_t& num_keys) {
key_ids_.reserve(num_keys);
key_names_.reserve(num_keys);
key_values_.reserve(num_keys);
+ key_regions_.reserve(num_keys);
key_alias_.reserve(num_keys);
}
-/* Create a new key and add it to the library, return an id */
FabricKeyId FabricKey::create_key() {
/* Create a new id */
FabricKeyId key = FabricKeyId(key_ids_.size());
key_ids_.push_back(key);
key_names_.emplace_back();
key_values_.emplace_back();
+ key_regions_.emplace_back(FabricRegionId::INVALID());
key_alias_.emplace_back();
return key;
@@ -98,6 +166,10 @@ void FabricKey::set_key_alias(const FabricKeyId& key_id,
* Internal invalidators/validators
***********************************************************************/
/* Validators */
+bool FabricKey::valid_region_id(const FabricRegionId& region_id) const {
+ return ( size_t(region_id) < region_ids_.size() ) && ( region_id == region_ids_[region_id] );
+}
+
bool FabricKey::valid_key_id(const FabricKeyId& key_id) const {
return ( size_t(key_id) < key_ids_.size() ) && ( key_id == key_ids_[key_id] );
}
diff --git a/libopenfpga/libfabrickey/src/fabric_key.h b/libopenfpga/libfabrickey/src/fabric_key.h
index 4ca678722..0ca1d252d 100644
--- a/libopenfpga/libfabrickey/src/fabric_key.h
+++ b/libopenfpga/libfabrickey/src/fabric_key.h
@@ -15,41 +15,94 @@
/********************************************************************
* A data structure to describe a secure key for fabric organization
+ * A fabric may consist of multiple regions
+ * Each region contains a number of keys
+ *
+ * Note that:
+ * - each key can only be defined in one unique region
*
* Typical usage:
* --------------
* // Create an empty fabric key
* FabricKey fabric_key;
+ * // Create a region
+ * FabricRegionId region = fabric_key.create_region();
* // Add a key with name and value
- * FabricKeyId key = fabic_key.create_key(key_name, key_value);
+ * FabricKeyId key = fabric_key.create_key(key_name, key_value);
+ * // Affilate a key to a region
+ * fabric_key.add_key_to_region(region, key);
*
*******************************************************************/
class FabricKey {
public: /* Types */
typedef vtr::vector::const_iterator fabric_key_iterator;
+ typedef vtr::vector::const_iterator fabric_region_iterator;
/* Create range */
+ typedef vtr::Range fabric_region_range;
typedef vtr::Range fabric_key_range;
public: /* Constructors */
FabricKey();
public: /* Accessors: aggregates */
fabric_key_range keys() const;
+ fabric_region_range regions() const;
public: /* Public Accessors: Basic data query */
+ /* Access all the keys of a region */
+ std::vector region_keys(const FabricRegionId& region_id) const;
+
+ /* Access the name of a key */
std::string key_name(const FabricKeyId& key_id) const;
+
+ /* Access the value of a key */
size_t key_value(const FabricKeyId& key_id) const;
+
+ /* Access the alias of a key */
std::string key_alias(const FabricKeyId& key_id) const;
+
+ /* Check if there are any keys */
bool empty() const;
+
public: /* Public Mutators: model-related */
+
+ /* Reserve a number of regions to be memory efficent */
+ void reserve_regions(const size_t& num_regions);
+
+ /* Create a new region and add it to the library, return an id */
+ FabricRegionId create_region();
+
+ /* Reserve the memory space for keys under a region, to be memory efficient */
+ void reserve_region_keys(const FabricRegionId& region_id,
+ const size_t& num_keys);
+
+ /* Add a key to a region */
+ void add_key_to_region(const FabricRegionId& region_id,
+ const FabricKeyId& key_id);
+
+ /* Reserve a number of keys to be memory efficent */
void reserve_keys(const size_t& num_keys);
+
+ /* Create a new key and add it to the library, return an id */
FabricKeyId create_key();
+
+ /* Configure attributes of a key */
void set_key_name(const FabricKeyId& key_id,
const std::string& name);
+
void set_key_value(const FabricKeyId& key_id,
const size_t& value);
+
void set_key_alias(const FabricKeyId& key_id,
const std::string& alias);
+
public: /* Public invalidators/validators */
+ bool valid_region_id(const FabricRegionId& region_id) const;
bool valid_key_id(const FabricKeyId& key_id) const;
private: /* Internal data */
+ /* Unique ids for each region */
+ vtr::vector region_ids_;
+
+ /* Key ids for each region */
+ vtr::vector> region_key_ids_;
+
/* Unique ids for each key */
vtr::vector key_ids_;
@@ -59,6 +112,9 @@ class FabricKey {
/* Values for each key */
vtr::vector key_values_;
+ /* Region for each key */
+ vtr::vector key_regions_;
+
/* Optional alias for each key, with which a key can also be represented */
vtr::vector key_alias_;
};
diff --git a/libopenfpga/libfabrickey/src/fabric_key_fwd.h b/libopenfpga/libfabrickey/src/fabric_key_fwd.h
index 523eaeab8..249093fd2 100644
--- a/libopenfpga/libfabrickey/src/fabric_key_fwd.h
+++ b/libopenfpga/libfabrickey/src/fabric_key_fwd.h
@@ -12,8 +12,10 @@
#include "vtr_strong_id.h"
+struct fabric_region_id_tag;
struct fabric_key_id_tag;
+typedef vtr::StrongId FabricRegionId;
typedef vtr::StrongId FabricKeyId;
/* Short declaration of class */