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;
|
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
|
* 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);
|
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
|
/* 3. Check io has been defined and has input and output ports
|
||||||
* [a] We must have an IOPAD!
|
* [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
|
* [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 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
|
* 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_set(const CircuitPortId& circuit_port_id) const;
|
||||||
bool port_is_config_enable(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;
|
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 */
|
public: /* Public Accessors: Timing graph */
|
||||||
/* Get source/sink nodes and delay of edges */
|
/* Get source/sink nodes and delay of edges */
|
||||||
std::vector<CircuitEdgeId> timing_edges_by_model(const CircuitModelId& model_id) const;
|
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
|
* This files includes data structures for module management.
|
||||||
* module management.
|
* It keeps a list of modules that have been generated, the port map of the modules,
|
||||||
* It keeps a list of modules that have been
|
* parents and children of each modules. This will ease instanciation of modules
|
||||||
* generated, the port map of the modules,
|
* with explicit port map and outputting a hierarchy of modules
|
||||||
* parents and children of each modules
|
*
|
||||||
* This will ease instanciation of modules
|
* Module includes the basic information:
|
||||||
* with explicit port map and outputting a
|
* 1. unique identifier
|
||||||
* hierarchy of modules
|
* 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
|
#ifndef MODULE_MANAGER_H
|
||||||
#define MODULE_MANAGER_H
|
#define MODULE_MANAGER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
#include "module_manager_fwd.h"
|
#include "module_manager_fwd.h"
|
||||||
#include "device_port.h"
|
#include "device_port.h"
|
||||||
|
|
||||||
class ModuleManager {
|
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 */
|
private: /* Internal data */
|
||||||
vtr::vector<ModuleId, ModuleId> ids_;
|
vtr::vector<ModuleId, ModuleId> ids_; /* Unique identifier for each Module */
|
||||||
vtr::vector<ModuleId, BasicPort> ports_;
|
vtr::vector<ModuleId, std::string> names_; /* Unique identifier for each Module */
|
||||||
vtr::vector<ModuleId, std::vector<ModuleId>> parents_;
|
vtr::vector<ModuleId, std::vector<ModuleId>> parents_; /* Parent modules that include the module */
|
||||||
vtr::vector<ModuleId, std::vector<ModuleId>> children_;
|
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
|
#endif
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
|
|
||||||
#include "vtr_strong_id.h"
|
#include "vtr_strong_id.h"
|
||||||
|
|
||||||
/* Strong Ids for MUXes */
|
/* Strong Ids for ModuleManager */
|
||||||
struct module_id_tag;
|
struct module_id_tag;
|
||||||
|
struct module_port_id_tag;
|
||||||
|
|
||||||
typedef vtr::StrongId<module_id_tag> ModuleId;
|
typedef vtr::StrongId<module_id_tag> ModuleId;
|
||||||
|
typedef vtr::StrongId<module_port_id_tag> ModulePortId;
|
||||||
|
|
||||||
class ModuleManager;
|
class ModuleManager;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue