developing module manager
This commit is contained in:
parent
89589ddc1c
commit
732e24767f
|
@ -345,6 +345,39 @@ size_t check_sram_circuit_model_ports(const CircuitLibrary& circuit_lib,
|
|||
return num_err;
|
||||
}
|
||||
|
||||
/* Check all the ports make sure, they satisfy the restriction */
|
||||
static
|
||||
size_t check_circuit_library_ports(const CircuitLibrary& circuit_lib) {
|
||||
size_t num_err = 0;
|
||||
|
||||
/* Check global ports: make sure all the global ports are input ports */
|
||||
for (const auto& port : circuit_lib.ports()) {
|
||||
if ( (circuit_lib.port_is_global(port))
|
||||
&& (!circuit_lib.is_input_port(port)) ) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"Circuit port (type=%s) of model (name=%s) is defined as global but not an input port!\n",
|
||||
CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(circuit_lib.port_type(port))],
|
||||
circuit_lib.model_name(port).c_str());
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check set/reset/config_enable ports: make sure they are all global ports */
|
||||
for (const auto& port : circuit_lib.ports()) {
|
||||
if ( ( (circuit_lib.port_is_set(port))
|
||||
|| (circuit_lib.port_is_reset(port))
|
||||
|| (circuit_lib.port_is_config_enable(port)) )
|
||||
&& (!circuit_lib.port_is_global(port)) ) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"Circuit port (type=%s) of model (name=%s) is defined as a set/reset/config_enable port but it is not global!\n",
|
||||
CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(circuit_lib.port_type(port))],
|
||||
circuit_lib.model_name(port).c_str());
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
|
||||
return num_err;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Check points to make sure we have a valid circuit library
|
||||
|
@ -375,6 +408,9 @@ void check_circuit_library(const CircuitLibrary& circuit_lib) {
|
|||
*/
|
||||
num_err += check_circuit_library_unique_prefix(circuit_lib);
|
||||
|
||||
/* Check global ports */
|
||||
num_err += check_circuit_library_ports(circuit_lib);
|
||||
|
||||
/* 3. Check io has been defined and has input and output ports
|
||||
* [a] We must have an IOPAD!
|
||||
* [b] For each IOPAD, we must have at least an input, an output, an INOUT and an SRAM port
|
||||
|
|
|
@ -598,6 +598,20 @@ bool CircuitLibrary::port_is_prog(const CircuitPortId& circuit_port_id) const {
|
|||
return port_is_prog_[circuit_port_id];
|
||||
}
|
||||
|
||||
/* Return the id of parent circuit model for a circuit port */
|
||||
CircuitModelId CircuitLibrary::port_parent_model(const CircuitPortId& circuit_port_id) const {
|
||||
/* validate the circuit_port_id */
|
||||
VTR_ASSERT(valid_circuit_port_id(circuit_port_id));
|
||||
return port_model_ids_[circuit_port_id];
|
||||
}
|
||||
|
||||
/* Return the name of parent circuit model for a circuit port */
|
||||
std::string CircuitLibrary::model_name(const CircuitPortId& port_id) const {
|
||||
/* validate the circuit_port_id */
|
||||
VTR_ASSERT(valid_circuit_port_id(port_id));
|
||||
return model_names_[port_parent_model(port_id)];
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Accessors : Methods to visit timing graphs
|
||||
***********************************************************************/
|
||||
|
|
|
@ -266,6 +266,8 @@ class CircuitLibrary {
|
|||
bool port_is_set(const CircuitPortId& circuit_port_id) const;
|
||||
bool port_is_config_enable(const CircuitPortId& circuit_port_id) const;
|
||||
bool port_is_prog(const CircuitPortId& circuit_port_id) const;
|
||||
CircuitModelId port_parent_model(const CircuitPortId& circuit_port_id) const;
|
||||
std::string model_name(const CircuitPortId& port_id) const;
|
||||
public: /* Public Accessors: Timing graph */
|
||||
/* Get source/sink nodes and delay of edges */
|
||||
std::vector<CircuitEdgeId> timing_edges_by_model(const CircuitModelId& model_id) const;
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
/******************************************************************************
|
||||
* Memember functions for data structure ModuleManager
|
||||
******************************************************************************/
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include "vtr_assert.h"
|
||||
|
||||
#include "circuit_library.h"
|
||||
#include "module_manager.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Public Constructors
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* Public Mutators
|
||||
******************************************************************************/
|
||||
/* Add a module based on its circuit-level description */
|
||||
ModuleId ModuleManager::add_module_with_ports(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model) {
|
||||
ModuleId module = add_module(circuit_lib.model_name(circuit_model));
|
||||
|
||||
/* Add ports */
|
||||
/* Find global ports and add one by one */
|
||||
for (const auto& port : circuit_lib.model_global_ports(circuit_model)) {
|
||||
BasicPort port_info(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
|
||||
add_port(module, port_info, MODULE_GLOBAL_PORT);
|
||||
}
|
||||
|
||||
/* Find other ports and add one by one */
|
||||
/* Create a type-to-type map for ports */
|
||||
std::map<enum e_spice_model_port_type, enum e_module_port_type> port_type2type_map;
|
||||
port_type2type_map[SPICE_MODEL_PORT_INOUT] = MODULE_INOUT_PORT;
|
||||
port_type2type_map[SPICE_MODEL_PORT_INPUT] = MODULE_INPUT_PORT;
|
||||
port_type2type_map[SPICE_MODEL_PORT_CLOCK] = MODULE_INPUT_PORT;
|
||||
port_type2type_map[SPICE_MODEL_PORT_SRAM] = MODULE_INPUT_PORT;
|
||||
port_type2type_map[SPICE_MODEL_PORT_BL] = MODULE_INPUT_PORT;
|
||||
port_type2type_map[SPICE_MODEL_PORT_BLB] = MODULE_INPUT_PORT;
|
||||
port_type2type_map[SPICE_MODEL_PORT_WL] = MODULE_INPUT_PORT;
|
||||
port_type2type_map[SPICE_MODEL_PORT_WLB] = MODULE_INPUT_PORT;
|
||||
port_type2type_map[SPICE_MODEL_PORT_OUTPUT] = MODULE_OUTPUT_PORT;
|
||||
|
||||
/* Input ports (ignore all the global ports when searching the circuit_lib */
|
||||
for (const auto& kv : port_type2type_map) {
|
||||
for (const auto& port : circuit_lib.model_ports_by_type(circuit_model, kv.first, true)) {
|
||||
BasicPort port_info(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
|
||||
add_port(module, port_info, kv.second);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the new id */
|
||||
return module;
|
||||
}
|
||||
|
||||
/* Add a module */
|
||||
ModuleId ModuleManager::add_module(const std::string& name) {
|
||||
/* Find if the name has been used. If used, return an invalid Id and report error! */
|
||||
std::map<std::string, ModuleId>::iterator it = name_id_map_.find(name);
|
||||
if (it != name_id_map_.end()) {
|
||||
return ModuleId::INVALID();
|
||||
}
|
||||
|
||||
/* Create an new id */
|
||||
ModuleId module = ModuleId(ids_.size());
|
||||
ids_.push_back(module);
|
||||
|
||||
/* Allocate other attributes */
|
||||
names_.push_back(name);
|
||||
parents_.emplace_back();
|
||||
children_.emplace_back();
|
||||
|
||||
port_ids_.emplace_back();
|
||||
ports_.emplace_back();
|
||||
port_types_.emplace_back();
|
||||
|
||||
/* Register in the name-to-id map */
|
||||
name_id_map_[name] = module;
|
||||
|
||||
/* Build port lookup */
|
||||
port_lookup_.emplace_back();
|
||||
port_lookup_[module].resize(NUM_MODULE_PORT_TYPES);
|
||||
|
||||
/* Return the new id */
|
||||
return module;
|
||||
}
|
||||
|
||||
/* Add a port to a module */
|
||||
ModulePortId ModuleManager::add_port(const ModuleId& module,
|
||||
const BasicPort& port_info, const enum e_module_port_type& port_type) {
|
||||
/* Validate the id of module */
|
||||
VTR_ASSERT( valid_module_id(module) );
|
||||
|
||||
/* Add port and fill port attributes */
|
||||
ModulePortId port = ModulePortId(port_ids_[module].size());
|
||||
port_ids_[module].push_back(port);
|
||||
ports_[module].push_back(port_info);
|
||||
port_types_[module].push_back(port_type);
|
||||
|
||||
/* Update fast look-up for port */
|
||||
port_lookup_[module][port_type].push_back(port);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
/* Add a child module to a parent module */
|
||||
void ModuleManager::add_child_module(const ModuleId& parent_module, const ModuleId& child_module) {
|
||||
/* Validate the id of both parent and child modules */
|
||||
VTR_ASSERT ( valid_module_id(parent_module) );
|
||||
VTR_ASSERT ( valid_module_id(child_module) );
|
||||
|
||||
/* Try to find if the parent module is already in the list */
|
||||
std::vector<ModuleId>::iterator parent_it = std::find(parents_[child_module].begin(), parents_[child_module].end(), parent_module);
|
||||
if (parent_it == parents_[child_module].end()) {
|
||||
/* Update the parent module of child module */
|
||||
parents_[child_module].push_back(parent_module);
|
||||
}
|
||||
|
||||
std::vector<ModuleId>::iterator child_it = std::find(children_[child_module].begin(), children_[child_module].end(), child_module);
|
||||
if (child_it == children_[parent_module].end()) {
|
||||
/* Update the child module of parent module */
|
||||
children_[parent_module].push_back(child_module);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private validators/invalidators
|
||||
******************************************************************************/
|
||||
bool ModuleManager::valid_module_id(const ModuleId& module) const {
|
||||
return ( size_t(module) < ids_.size() ) && ( module == ids_[module] );
|
||||
}
|
||||
|
||||
bool ModuleManager::valid_module_port_id(const ModuleId& module, const ModulePortId& port) const {
|
||||
if (false == valid_module_id(module)) {
|
||||
return false;
|
||||
}
|
||||
return ( size_t(port) < port_ids_[module].size() ) && ( port == port_ids_[module][port] );
|
||||
}
|
||||
|
||||
void ModuleManager::invalidate_name2id_map() {
|
||||
name_id_map_.clear();
|
||||
}
|
||||
|
||||
void ModuleManager::invalidate_port_lookup() {
|
||||
port_lookup_.clear();
|
||||
}
|
|
@ -1,27 +1,66 @@
|
|||
/************************************************
|
||||
* This files includes data structures for
|
||||
* module management.
|
||||
* It keeps a list of modules that have been
|
||||
* generated, the port map of the modules,
|
||||
* parents and children of each modules
|
||||
* This will ease instanciation of modules
|
||||
* with explicit port map and outputting a
|
||||
* hierarchy of modules
|
||||
***********************************************/
|
||||
/******************************************************************************
|
||||
* This files includes data structures for module management.
|
||||
* It keeps a list of modules that have been generated, the port map of the modules,
|
||||
* parents and children of each modules. This will ease instanciation of modules
|
||||
* with explicit port map and outputting a hierarchy of modules
|
||||
*
|
||||
* Module includes the basic information:
|
||||
* 1. unique identifier
|
||||
* 2. module name: which should be unique
|
||||
* 3. port list: basic information of all the ports belonging to the module
|
||||
* 4. port types: types of each port, which will matter how we output the ports
|
||||
* 5. parent modules: ids of parent modules
|
||||
* 6. children modules: ids of child modules
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef MODULE_MANAGER_H
|
||||
#define MODULE_MANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "module_manager_fwd.h"
|
||||
#include "device_port.h"
|
||||
|
||||
class ModuleManager {
|
||||
private: /* Private data structures */
|
||||
enum e_module_port_type {
|
||||
MODULE_GLOBAL_PORT,
|
||||
MODULE_INOUT_PORT,
|
||||
MODULE_INPUT_PORT,
|
||||
MODULE_OUTPUT_PORT,
|
||||
MODULE_CLOCK_PORT,
|
||||
NUM_MODULE_PORT_TYPES
|
||||
};
|
||||
public: /* Public Constructors */
|
||||
public: /* Public mutators */
|
||||
/* Add a module */
|
||||
ModuleId add_module_with_ports(const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model);
|
||||
ModuleId add_module(const std::string& name);
|
||||
/* Add a port to a module */
|
||||
ModulePortId add_port(const ModuleId& module,
|
||||
const BasicPort& port_info, const enum e_module_port_type& port_type);
|
||||
/* Add a child module to a parent module */
|
||||
void add_child_module(const ModuleId& parent_module, const ModuleId& child_module);
|
||||
private: /* Private validators/invalidators */
|
||||
bool valid_module_id(const ModuleId& module) const;
|
||||
bool valid_module_port_id(const ModuleId& module, const ModulePortId& port) const;
|
||||
void invalidate_name2id_map();
|
||||
void invalidate_port_lookup();
|
||||
private: /* Internal data */
|
||||
vtr::vector<ModuleId, ModuleId> ids_;
|
||||
vtr::vector<ModuleId, BasicPort> ports_;
|
||||
vtr::vector<ModuleId, std::vector<ModuleId>> parents_;
|
||||
vtr::vector<ModuleId, std::vector<ModuleId>> children_;
|
||||
vtr::vector<ModuleId, ModuleId> ids_; /* Unique identifier for each Module */
|
||||
vtr::vector<ModuleId, std::string> names_; /* Unique identifier for each Module */
|
||||
vtr::vector<ModuleId, std::vector<ModuleId>> parents_; /* Parent modules that include the module */
|
||||
vtr::vector<ModuleId, std::vector<ModuleId>> children_; /* Child modules that this module contain */
|
||||
|
||||
vtr::vector<ModuleId, vtr::vector<ModulePortId, ModulePortId>> port_ids_; /* List of ports for each Module */
|
||||
vtr::vector<ModuleId, vtr::vector<ModulePortId, BasicPort>> ports_; /* List of ports for each Module */
|
||||
vtr::vector<ModuleId, vtr::vector<ModulePortId, enum e_module_port_type>> port_types_; /* Type of ports */
|
||||
|
||||
/* fast look-up for module */
|
||||
std::map<std::string, ModuleId> name_id_map_;
|
||||
/* fast look-up for ports */
|
||||
typedef vtr::vector<ModuleId, std::vector<std::vector<ModulePortId>>> PortLookup;
|
||||
mutable PortLookup port_lookup_; /* [module_ids][port_types][port_ids] */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
|
||||
#include "vtr_strong_id.h"
|
||||
|
||||
/* Strong Ids for MUXes */
|
||||
/* Strong Ids for ModuleManager */
|
||||
struct module_id_tag;
|
||||
struct module_port_id_tag;
|
||||
|
||||
typedef vtr::StrongId<module_id_tag> ModuleId;
|
||||
typedef vtr::StrongId<module_port_id_tag> ModulePortId;
|
||||
|
||||
class ModuleManager;
|
||||
|
||||
|
|
Loading…
Reference in New Issue