From 48b2bff0d909e2c6d0740d2a5386123eb238349f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 27 Sep 2020 20:08:11 -0600 Subject: [PATCH] [OpenFPGA Tool] Update fabric key data structure to support regions --- .../libfabrickey/key_examples/key_example.xml | 12 +-- libopenfpga/libfabrickey/src/fabric_key.cpp | 80 ++++++++++++++++++- libopenfpga/libfabrickey/src/fabric_key.h | 58 +++++++++++++- libopenfpga/libfabrickey/src/fabric_key_fwd.h | 2 + 4 files changed, 142 insertions(+), 10 deletions(-) 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 */