add fabric key library
This commit is contained in:
parent
278acee216
commit
f081cef495
|
@ -3,3 +3,4 @@ add_subdirectory(libini)
|
||||||
add_subdirectory(libopenfpgashell)
|
add_subdirectory(libopenfpgashell)
|
||||||
add_subdirectory(libarchopenfpga)
|
add_subdirectory(libarchopenfpga)
|
||||||
add_subdirectory(libopenfpgautil)
|
add_subdirectory(libopenfpgautil)
|
||||||
|
add_subdirectory(libfabrickey)
|
||||||
|
|
|
@ -61,6 +61,21 @@ void write_xml_attribute(std::fstream& fp,
|
||||||
fp << "\"";
|
fp << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A most utilized function to write an XML attribute to file
|
||||||
|
* This accepts the value as a size_t
|
||||||
|
*******************************************************************/
|
||||||
|
void write_xml_attribute(std::fstream& fp,
|
||||||
|
const char* attr,
|
||||||
|
const size_t& value) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
openfpga::valid_file_stream(fp);
|
||||||
|
|
||||||
|
fp << " " << attr << "=\"";
|
||||||
|
fp << value;
|
||||||
|
fp << "\"";
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* A most utilized function to write an XML attribute to file
|
* A most utilized function to write an XML attribute to file
|
||||||
* This accepts the value as a float
|
* This accepts the value as a float
|
||||||
|
|
|
@ -26,4 +26,8 @@ void write_xml_attribute(std::fstream& fp,
|
||||||
const char* attr,
|
const char* attr,
|
||||||
const float& value);
|
const float& value);
|
||||||
|
|
||||||
|
void write_xml_attribute(std::fstream& fp,
|
||||||
|
const char* attr,
|
||||||
|
const size_t& value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
cmake_minimum_required(VERSION 3.9)
|
||||||
|
|
||||||
|
project("libfabrickey")
|
||||||
|
|
||||||
|
file(GLOB_RECURSE EXEC_SOURCES test/*.cpp)
|
||||||
|
file(GLOB_RECURSE LIB_SOURCES src/*.cpp)
|
||||||
|
file(GLOB_RECURSE LIB_HEADERS src/*.h)
|
||||||
|
files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
#Remove test executable from library
|
||||||
|
list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES})
|
||||||
|
|
||||||
|
#Create the library
|
||||||
|
add_library(libfabrickey STATIC
|
||||||
|
${LIB_HEADERS}
|
||||||
|
${LIB_SOURCES})
|
||||||
|
target_include_directories(libfabrickey PUBLIC ${LIB_INCLUDE_DIRS})
|
||||||
|
set_target_properties(libfabrickey PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
|
||||||
|
|
||||||
|
#Specify link-time dependancies
|
||||||
|
target_link_libraries(libfabrickey
|
||||||
|
libopenfpgautil
|
||||||
|
libarchopenfpga
|
||||||
|
libvtrutil
|
||||||
|
libpugixml
|
||||||
|
libpugiutil)
|
||||||
|
|
||||||
|
#Create the test executable
|
||||||
|
foreach(testsourcefile ${EXEC_SOURCES})
|
||||||
|
# Use a simple string replace, to cut off .cpp.
|
||||||
|
get_filename_component(testname ${testsourcefile} NAME_WE)
|
||||||
|
add_executable(${testname} ${testsourcefile})
|
||||||
|
# Make sure the library is linked to each test executable
|
||||||
|
target_link_libraries(${testname} libfabrickey)
|
||||||
|
endforeach(testsourcefile ${EXEC_SOURCES})
|
|
@ -0,0 +1,7 @@
|
||||||
|
<fabric_key>
|
||||||
|
<key id="0" name="sb" value="0"/>
|
||||||
|
<key id="2" name="cb" value="10"/>
|
||||||
|
<key id="1" name="sb" value="7"/>
|
||||||
|
<key id="3" name="clb" value="53"/>
|
||||||
|
<key id="4" name="bram" value="32"/>
|
||||||
|
</fabric_key>
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
|
||||||
|
#include "fabric_key.h"
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Member functions for class FabricKey
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Constructors
|
||||||
|
***********************************************************************/
|
||||||
|
FabricKey::FabricKey() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Public Accessors : aggregates
|
||||||
|
***********************************************************************/
|
||||||
|
FabricKey::fabric_key_range FabricKey::keys() const {
|
||||||
|
return vtr::make_range(key_ids_.begin(), key_ids_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Public Accessors : Basic data query
|
||||||
|
***********************************************************************/
|
||||||
|
/* Access the name of a key */
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Public Mutators
|
||||||
|
***********************************************************************/
|
||||||
|
void FabricKey::reserve_keys(const size_t& num_keys) {
|
||||||
|
key_ids_.reserve(num_keys);
|
||||||
|
key_names_.reserve(num_keys);
|
||||||
|
key_values_.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();
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FabricKey::set_key_name(const FabricKeyId& key_id,
|
||||||
|
const std::string& name) {
|
||||||
|
/* validate the key_id */
|
||||||
|
VTR_ASSERT(valid_key_id(key_id));
|
||||||
|
|
||||||
|
key_names_[key_id] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FabricKey::set_key_value(const FabricKeyId& key_id,
|
||||||
|
const size_t& value) {
|
||||||
|
/* validate the key_id */
|
||||||
|
VTR_ASSERT(valid_key_id(key_id));
|
||||||
|
|
||||||
|
key_values_[key_id] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Internal invalidators/validators
|
||||||
|
***********************************************************************/
|
||||||
|
/* Validators */
|
||||||
|
bool FabricKey::valid_key_id(const FabricKeyId& key_id) const {
|
||||||
|
return ( size_t(key_id) < key_ids_.size() ) && ( key_id == key_ids_[key_id] );
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef FABRIC_KEY_H
|
||||||
|
#define FABRIC_KEY_H
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* This file include the declaration of fabric key
|
||||||
|
*******************************************************************/
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
/* Headers from vtrutil library */
|
||||||
|
#include "vtr_vector.h"
|
||||||
|
|
||||||
|
#include "fabric_key_fwd.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A data structure to describe a secure key for fabric organization
|
||||||
|
*
|
||||||
|
* Typical usage:
|
||||||
|
* --------------
|
||||||
|
* // Create an empty fabric key
|
||||||
|
* FabricKey fabric_key;
|
||||||
|
* // Add a key with name and value
|
||||||
|
* FabricKeyId key = fabic_key.create_key(key_name, key_value);
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
class FabricKey {
|
||||||
|
public: /* Types */
|
||||||
|
typedef vtr::vector<FabricKeyId, FabricKeyId>::const_iterator fabric_key_iterator;
|
||||||
|
/* Create range */
|
||||||
|
typedef vtr::Range<fabric_key_iterator> fabric_key_range;
|
||||||
|
public: /* Constructors */
|
||||||
|
FabricKey();
|
||||||
|
public: /* Accessors: aggregates */
|
||||||
|
fabric_key_range keys() const;
|
||||||
|
public: /* Public Accessors: Basic data query */
|
||||||
|
std::string key_name(const FabricKeyId& key_id) const;
|
||||||
|
size_t key_value(const FabricKeyId& key_id) const;
|
||||||
|
public: /* Public Mutators: model-related */
|
||||||
|
void reserve_keys(const size_t& num_keys);
|
||||||
|
FabricKeyId create_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);
|
||||||
|
public: /* Public invalidators/validators */
|
||||||
|
bool valid_key_id(const FabricKeyId& key_id) const;
|
||||||
|
private: /* Internal data */
|
||||||
|
/* Unique ids for each key */
|
||||||
|
vtr::vector<FabricKeyId, FabricKeyId> key_ids_;
|
||||||
|
|
||||||
|
/* Names for each key */
|
||||||
|
vtr::vector<FabricKeyId, std::string> key_names_;
|
||||||
|
|
||||||
|
/* Values for each key */
|
||||||
|
vtr::vector<FabricKeyId, size_t> key_values_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,22 @@
|
||||||
|
/************************************************************************
|
||||||
|
* A header file for FabricKey class, including critical data declaration
|
||||||
|
* Please include this file only for using any TechnologyLibrary data structure
|
||||||
|
* Refer to fabric_key.h for more details
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Create strong id for FabricKey to avoid illegal type casting
|
||||||
|
***********************************************************************/
|
||||||
|
#ifndef FABRIC_KEY_FWD_H
|
||||||
|
#define FABRIC_KEY_FWD_H
|
||||||
|
|
||||||
|
#include "vtr_strong_id.h"
|
||||||
|
|
||||||
|
struct fabric_key_id_tag;
|
||||||
|
|
||||||
|
typedef vtr::StrongId<fabric_key_id_tag> FabricKeyId;
|
||||||
|
|
||||||
|
/* Short declaration of class */
|
||||||
|
class FabricKey;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,88 @@
|
||||||
|
/********************************************************************
|
||||||
|
* This file includes the top-level function of this library
|
||||||
|
* which reads an XML of a fabric key to the associated
|
||||||
|
* data structures
|
||||||
|
*******************************************************************/
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/* Headers from pugi XML library */
|
||||||
|
#include "pugixml.hpp"
|
||||||
|
#include "pugixml_util.hpp"
|
||||||
|
|
||||||
|
/* Headers from vtr util library */
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
#include "vtr_time.h"
|
||||||
|
|
||||||
|
/* Headers from libarchfpga */
|
||||||
|
#include "arch_error.h"
|
||||||
|
#include "read_xml_util.h"
|
||||||
|
|
||||||
|
#include "read_xml_fabric_key.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Parse XML codes of a <key> to an object of FabricKey
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void read_xml_component_key(pugi::xml_node& xml_component_key,
|
||||||
|
const pugiutil::loc_data& loc_data,
|
||||||
|
FabricKey& fabric_key) {
|
||||||
|
|
||||||
|
/* Find the id of component key */
|
||||||
|
const size_t& id = get_attribute(xml_component_key, "id", loc_data).as_int();
|
||||||
|
const std::string& name = get_attribute(xml_component_key, "name", loc_data).as_string();
|
||||||
|
const size_t& value = get_attribute(xml_component_key, "value", loc_data).as_int();
|
||||||
|
|
||||||
|
if (false == fabric_key.valid_key_id(FabricKeyId(id))) {
|
||||||
|
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_component_key),
|
||||||
|
"Invalid 'id' attribute '%d'\n",
|
||||||
|
id);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTR_ASSERT_SAFE(true == fabric_key.valid_key_id(FabricKeyId(id)));
|
||||||
|
|
||||||
|
fabric_key.set_key_name(FabricKeyId(id), name);
|
||||||
|
fabric_key.set_key_value(FabricKeyId(id), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Parse XML codes about <fabric> to an object of FabricKey
|
||||||
|
*******************************************************************/
|
||||||
|
FabricKey read_xml_fabric_key(const char* key_fname) {
|
||||||
|
|
||||||
|
vtr::ScopedStartFinishTimer timer("Read Fabric Key");
|
||||||
|
|
||||||
|
FabricKey fabric_key;
|
||||||
|
|
||||||
|
/* Parse the file */
|
||||||
|
pugi::xml_document doc;
|
||||||
|
pugiutil::loc_data loc_data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
loc_data = pugiutil::load_xml(doc, key_fname);
|
||||||
|
|
||||||
|
pugi::xml_node xml_root = get_single_child(doc, "fabric_key", loc_data);
|
||||||
|
|
||||||
|
size_t num_keys = std::distance(xml_root.children().begin(), xml_root.children().end());
|
||||||
|
fabric_key.reserve_keys(num_keys);
|
||||||
|
for (size_t ikey = 0; ikey < num_keys; ++ikey) {
|
||||||
|
fabric_key.create_key();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate over the children under this node,
|
||||||
|
* each child should be named after circuit_model
|
||||||
|
*/
|
||||||
|
for (pugi::xml_node xml_key : xml_root.children()) {
|
||||||
|
/* Error out if the XML child has an invalid name! */
|
||||||
|
if (xml_key.name() != std::string("key")) {
|
||||||
|
bad_tag(xml_key, loc_data, xml_root, {"key"});
|
||||||
|
}
|
||||||
|
read_xml_component_key(xml_key, loc_data, fabric_key);
|
||||||
|
}
|
||||||
|
} catch (pugiutil::XmlError& e) {
|
||||||
|
archfpga_throw(key_fname, e.line(),
|
||||||
|
"%s", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
return fabric_key;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef READ_XML_FABRIC_KEY_H
|
||||||
|
#define READ_XML_FABRIC_KEY_H
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Include header files that are required by function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
#include "pugixml_util.hpp"
|
||||||
|
#include "pugixml.hpp"
|
||||||
|
#include "fabric_key.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
FabricKey read_xml_fabric_key(const char* key_fname);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,69 @@
|
||||||
|
/********************************************************************
|
||||||
|
* This file includes functions that outputs a configuration protocol to XML format
|
||||||
|
*******************************************************************/
|
||||||
|
/* Headers from system goes first */
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/* Headers from vtr util library */
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
#include "vtr_log.h"
|
||||||
|
#include "vtr_time.h"
|
||||||
|
#include "openfpga_digest.h"
|
||||||
|
|
||||||
|
/* Headers from arch openfpga library */
|
||||||
|
#include "write_xml_utils.h"
|
||||||
|
|
||||||
|
/* Headers from fabrickey library */
|
||||||
|
#include "write_xml_fabric_key.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A writer to output a component key to XML format
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void write_xml_fabric_component_key(std::fstream& fp,
|
||||||
|
const char* fname,
|
||||||
|
const FabricKey& fabric_key,
|
||||||
|
const FabricKeyId& component_key) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
openfpga::check_file_stream(fname, fp);
|
||||||
|
|
||||||
|
fp << "\t" << "<key";
|
||||||
|
|
||||||
|
write_xml_attribute(fp, "id", size_t(component_key));
|
||||||
|
write_xml_attribute(fp, "name", fabric_key.key_name(component_key).c_str());
|
||||||
|
write_xml_attribute(fp, "value", fabric_key.key_value(component_key));
|
||||||
|
|
||||||
|
fp << "/>" << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A writer to output a fabric key to XML format
|
||||||
|
*******************************************************************/
|
||||||
|
void write_xml_fabric_key(const char* fname,
|
||||||
|
const FabricKey& fabric_key) {
|
||||||
|
|
||||||
|
vtr::ScopedStartFinishTimer timer("Write Fabric Key");
|
||||||
|
|
||||||
|
/* Create a file handler */
|
||||||
|
std::fstream fp;
|
||||||
|
/* Open the file stream */
|
||||||
|
fp.open(std::string(fname), std::fstream::out | std::fstream::trunc);
|
||||||
|
|
||||||
|
/* Validate the file stream */
|
||||||
|
openfpga::check_file_stream(fname, fp);
|
||||||
|
|
||||||
|
/* Write the root node */
|
||||||
|
fp << "<fabric_key>" << "\n";
|
||||||
|
|
||||||
|
/* Write component by component */
|
||||||
|
for (const FabricKeyId& key : fabric_key.keys()) {
|
||||||
|
write_xml_fabric_component_key(fp, fname, fabric_key, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish writing the root node */
|
||||||
|
fp << "</fabric_key>" << "\n";
|
||||||
|
|
||||||
|
/* Close the file stream */
|
||||||
|
fp.close();
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef WRITE_XML_FABRIC_KEY_H
|
||||||
|
#define WRITE_XML_FABRIC_KEY_H
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Include header files that are required by function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
#include <fstream>
|
||||||
|
#include "fabric_key.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
void write_xml_fabric_key(const char* fname,
|
||||||
|
const FabricKey& fabric_key);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,34 @@
|
||||||
|
/********************************************************************
|
||||||
|
* Unit test functions to validate the correctness of
|
||||||
|
* 1. parser of data structures
|
||||||
|
* 2. writer of data structures
|
||||||
|
*******************************************************************/
|
||||||
|
/* Headers from vtrutils */
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
#include "vtr_log.h"
|
||||||
|
|
||||||
|
/* Headers from fabric key */
|
||||||
|
#include "read_xml_fabric_key.h"
|
||||||
|
#include "write_xml_fabric_key.h"
|
||||||
|
|
||||||
|
int main(int argc, const char** argv) {
|
||||||
|
/* Ensure we have only one or two argument */
|
||||||
|
VTR_ASSERT((2 == argc) || (3 == argc));
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse the fabric key from an XML file */
|
||||||
|
FabricKey test_key = read_xml_fabric_key(argv[1]);
|
||||||
|
VTR_LOG("Read the fabric key from an XML file: %s.\n",
|
||||||
|
argv[1]);
|
||||||
|
|
||||||
|
/* Output the circuit library to an XML file
|
||||||
|
* This is optional only used when there is a second argument
|
||||||
|
*/
|
||||||
|
if (3 <= argc) {
|
||||||
|
write_xml_fabric_key(argv[2], test_key);
|
||||||
|
VTR_LOG("Echo the fabric key to an XML file: %s.\n",
|
||||||
|
argv[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue