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(libarchopenfpga)
|
||||
add_subdirectory(libopenfpgautil)
|
||||
add_subdirectory(libfabrickey)
|
||||
|
|
|
@ -61,6 +61,21 @@ void write_xml_attribute(std::fstream& 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
|
||||
* This accepts the value as a float
|
||||
|
|
|
@ -26,4 +26,8 @@ void write_xml_attribute(std::fstream& fp,
|
|||
const char* attr,
|
||||
const float& value);
|
||||
|
||||
void write_xml_attribute(std::fstream& fp,
|
||||
const char* attr,
|
||||
const size_t& value);
|
||||
|
||||
#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