developing module manager

This commit is contained in:
tangxifan 2019-08-22 23:48:46 -06:00
parent 89589ddc1c
commit 732e24767f
6 changed files with 253 additions and 15 deletions

View File

@ -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

View File

@ -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
***********************************************************************/

View File

@ -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;

View File

@ -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();
}

View File

@ -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

View File

@ -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;