From e2b492f18413ad89ec30cbe31cc1798a8545cb5e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Jul 2020 20:35:10 -0600 Subject: [PATCH] add circuit model tech binding --- .../libarchopenfpga/src/circuit_library.cpp | 17 +++++++++++ .../libarchopenfpga/src/circuit_library.h | 8 +++++ .../libarchopenfpga/src/openfpga_arch.h | 3 ++ .../src/openfpga_arch_linker.cpp | 28 +++++++++++++++++- .../src/openfpga_arch_linker.h | 2 ++ .../src/read_xml_circuit_library.cpp | 29 +++++++++++++++++++ .../src/read_xml_openfpga_arch.cpp | 3 ++ .../src/technology_library.cpp | 2 +- 8 files changed, 90 insertions(+), 2 deletions(-) diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.cpp b/libopenfpga/libarchopenfpga/src/circuit_library.cpp index a235e53af..cccc62e71 100644 --- a/libopenfpga/libarchopenfpga/src/circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/circuit_library.cpp @@ -120,6 +120,13 @@ bool CircuitLibrary::is_power_gated(const CircuitModelId& model_id) const { return is_power_gated_[model_id]; } +/* Access the device model name that is binded to a circuit model */ +std::string CircuitLibrary::device_model_name(const CircuitModelId& model_id) const { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + return device_model_names_[model_id]; +} + /* Return a flag showing if inputs are buffered for a circuit model */ bool CircuitLibrary::is_input_buffered(const CircuitModelId& model_id) const { /* validate the model_id */ @@ -1135,6 +1142,9 @@ CircuitModelId CircuitLibrary::add_model(const enum e_circuit_model_type& type) /* Design technology information */ design_tech_types_.push_back(NUM_CIRCUIT_MODEL_DESIGN_TECH_TYPES); is_power_gated_.push_back(false); + + /* Device technology information */ + device_model_names_.emplace_back(); /* Buffer existence */ buffer_existence_.emplace_back(); @@ -1263,6 +1273,13 @@ void CircuitLibrary::set_model_is_power_gated(const CircuitModelId& model_id, co return; } +/* Set the device model name that is binded to a Circuit Model */ +void CircuitLibrary::set_device_model_name(const CircuitModelId& model_id, const std::string& name) { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + device_model_names_[model_id] = name; +} + /* Set input buffer information for the circuit model */ void CircuitLibrary::set_model_input_buffer(const CircuitModelId& model_id, const bool& existence, const std::string& model_name) { diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.h b/libopenfpga/libarchopenfpga/src/circuit_library.h index c6a62dc27..abb03d1f8 100644 --- a/libopenfpga/libarchopenfpga/src/circuit_library.h +++ b/libopenfpga/libarchopenfpga/src/circuit_library.h @@ -194,8 +194,11 @@ class CircuitLibrary { bool model_is_default(const CircuitModelId& model_id) const; bool dump_structural_verilog(const CircuitModelId& model_id) const; bool dump_explicit_port_map(const CircuitModelId& model_id) const; + /* Design technology information */ enum e_circuit_model_design_tech design_tech_type(const CircuitModelId& model_id) const; bool is_power_gated(const CircuitModelId& model_id) const; + /* Device technology information */ + std::string device_model_name(const CircuitModelId& model_id) const; /* General buffer information */ bool is_input_buffered(const CircuitModelId& model_id) const; bool is_output_buffered(const CircuitModelId& model_id) const; @@ -319,6 +322,8 @@ class CircuitLibrary { /* Design technology information */ void set_model_design_tech_type(const CircuitModelId& model_id, const enum e_circuit_model_design_tech& design_tech_type); void set_model_is_power_gated(const CircuitModelId& model_id, const bool& is_power_gated); + /* Design technology information */ + void set_device_model_name(const CircuitModelId& model_id, const std::string& name); /* Buffer existence */ void set_model_input_buffer(const CircuitModelId& model_id, const bool& existence, const std::string& model_name); @@ -513,6 +518,9 @@ class CircuitLibrary { vtr::vector design_tech_types_; vtr::vector is_power_gated_; + /* Device technology information */ + vtr::vector device_model_names_; + /* Buffer existence */ vtr::vector> buffer_existence_; vtr::vector> buffer_model_names_; diff --git a/libopenfpga/libarchopenfpga/src/openfpga_arch.h b/libopenfpga/libarchopenfpga/src/openfpga_arch.h index 33d8f1b6c..68d0b6f68 100644 --- a/libopenfpga/libarchopenfpga/src/openfpga_arch.h +++ b/libopenfpga/libarchopenfpga/src/openfpga_arch.h @@ -29,6 +29,9 @@ struct Arch { /* Technology devices */ TechnologyLibrary tech_lib; + /* Binding between circuit models and technology models */ + std::map circuit_tech_binding; + /* Configuration protocol settings */ ConfigProtocol config_protocol; diff --git a/libopenfpga/libarchopenfpga/src/openfpga_arch_linker.cpp b/libopenfpga/libarchopenfpga/src/openfpga_arch_linker.cpp index 90ae1aad3..eab105ec3 100644 --- a/libopenfpga/libarchopenfpga/src/openfpga_arch_linker.cpp +++ b/libopenfpga/libarchopenfpga/src/openfpga_arch_linker.cpp @@ -16,7 +16,7 @@ void link_config_protocol_to_circuit_library(openfpga::Arch& openfpga_arch) { /* Error out if the circuit model id is invalid */ if (CircuitModelId::INVALID() == config_memory_model) { - VTR_LOG("Invalid memory model name (=%s) defined in !", + VTR_LOG("Invalid memory model name '%s' defined in !", openfpga_arch.config_protocol.memory_model_name().c_str()); exit(1); } @@ -24,6 +24,32 @@ void link_config_protocol_to_circuit_library(openfpga::Arch& openfpga_arch) { openfpga_arch.config_protocol.set_memory_model(config_memory_model); } +/******************************************************************** + * Link the circuit model of circuit library + * to these device model defined in technology library + *******************************************************************/ +void bind_circuit_model_to_technology_model(openfpga::Arch& openfpga_arch) { + /* Ensure a clean start */ + openfpga_arch.circuit_tech_binding.clear(); + + for (const CircuitModelId& circuit_model : openfpga_arch.circuit_lib.models()) { + const std::string device_model_name = openfpga_arch.circuit_lib.device_model_name(circuit_model); + if (true == device_model_name.empty()) { + continue; + } + /* Try to find the device model name in technology library */ + TechnologyModelId tech_model = openfpga_arch.tech_lib.model(device_model_name); + if (false == openfpga_arch.tech_lib.valid_model_id(tech_model)) { + VTR_LOG("Invalid device model name '%s' defined in circuit model '%s'!", + device_model_name.c_str(), + openfpga_arch.circuit_lib.model_name(circuit_model).c_str()); + exit(1); + } + /* Create binding */ + openfpga_arch.circuit_tech_binding[circuit_model] = tech_model; + } +} + /******************************************************************** * Link the circuit model of SRAM ports of each circuit model * to a default SRAM circuit model. diff --git a/libopenfpga/libarchopenfpga/src/openfpga_arch_linker.h b/libopenfpga/libarchopenfpga/src/openfpga_arch_linker.h index 52e49cb66..a6c966058 100644 --- a/libopenfpga/libarchopenfpga/src/openfpga_arch_linker.h +++ b/libopenfpga/libarchopenfpga/src/openfpga_arch_linker.h @@ -5,6 +5,8 @@ void link_config_protocol_to_circuit_library(openfpga::Arch& openfpga_arch); +void bind_circuit_model_to_technology_model(openfpga::Arch& openfpga_arch); + void config_circuit_models_sram_port_to_default_sram_model(CircuitLibrary& circuit_lib, const CircuitModelId& default_sram_model); diff --git a/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp index 7a894ab34..bb7905d48 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp @@ -397,6 +397,23 @@ void read_xml_model_design_technology(pugi::xml_node& xml_model, } } +/******************************************************************** + * Parse XML codes of device technology of a circuit model to circuit library + *******************************************************************/ +static +void read_xml_model_device_technology(pugi::xml_node& xml_model, + const pugiutil::loc_data& loc_data, + CircuitLibrary& circuit_lib, const CircuitModelId& model) { + + auto xml_device_tech = get_single_child(xml_model, "device_technology", loc_data); + + /* Parse device model name */ + const char* device_model_name_attr = get_attribute(xml_device_tech, "device_model_name", loc_data).value(); + if (nullptr != device_model_name_attr) { + circuit_lib.set_device_model_name(model, std::string(device_model_name_attr)); + } +} + /******************************************************************** * This is a generic function to parse XML codes that describe * a buffer of a circuit model to circuit library @@ -698,6 +715,18 @@ void read_xml_circuit_model(pugi::xml_node& xml_model, } } + /* Parse device technology attributes + * This is applicable to only atom circuit models: + * - inverter/buffer + * - pass gate + * - logic gates + */ + if ((CIRCUIT_MODEL_INVBUF == circuit_lib.model_type(model)) + || (CIRCUIT_MODEL_PASSGATE == circuit_lib.model_type(model)) + || (CIRCUIT_MODEL_GATE == circuit_lib.model_type(model))) { + read_xml_model_device_technology(xml_model, loc_data, circuit_lib, model); + } + /* Input buffer attributes, NOT required for circuit models which are inverters or buffers */ if (CIRCUIT_MODEL_INVBUF != circuit_lib.model_type(model)) { auto xml_input_buffer = get_single_child(xml_model, "input_buffer", loc_data); diff --git a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp index 1d5f23e9e..6bc31ef46 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp @@ -64,6 +64,9 @@ openfpga::Arch read_xml_openfpga_arch(const char* arch_file_name) { /* Build the internal link for technology library */ openfpga_arch.tech_lib.link_models_to_variations(); + /* Binding circuit models to device models */ + bind_circuit_model_to_technology_model(openfpga_arch); + /* Parse configuration protocol to data structure */ openfpga_arch.config_protocol = read_xml_config_protocol(xml_openfpga_arch, loc_data); diff --git a/libopenfpga/libarchopenfpga/src/technology_library.cpp b/libopenfpga/libarchopenfpga/src/technology_library.cpp index 4ee9bf1c6..3f8e8e7f9 100644 --- a/libopenfpga/libarchopenfpga/src/technology_library.cpp +++ b/libopenfpga/libarchopenfpga/src/technology_library.cpp @@ -54,7 +54,7 @@ std::string TechnologyLibrary::model_name(const TechnologyModelId& model_id) con */ TechnologyModelId TechnologyLibrary::model(const std::string& name) const { std::map::const_iterator it = model_name2ids_.find(name); - if (it != model_name2ids_.end()) { + if (it == model_name2ids_.end()) { return TechnologyModelId::INVALID(); }