start implementing module graph-based connection

This commit is contained in:
tangxifan 2019-10-09 20:30:16 -06:00
parent 9cb6e64ab3
commit 557d8b60f3
3 changed files with 170 additions and 0 deletions

View File

@ -148,6 +148,18 @@ ModuleId ModuleManager::add_module(const std::string& name) {
port_is_register_.emplace_back();
port_preproc_flags_.emplace_back();
net_ids_.emplace_back();
net_names_.emplace_back();
net_src_module_ids_.emplace_back();
net_src_instance_ids_.emplace_back();
net_src_port_ids_.emplace_back();
net_src_pin_ids_.emplace_back();
net_sink_module_ids_.emplace_back();
net_sink_instance_ids_.emplace_back();
net_sink_port_ids_.emplace_back();
net_sink_pin_ids_.emplace_back();
/* Register in the name-to-id map */
name_id_map_[name] = module;
@ -155,6 +167,11 @@ ModuleId ModuleManager::add_module(const std::string& name) {
port_lookup_.emplace_back();
port_lookup_[module].resize(NUM_MODULE_PORT_TYPES);
/* Build fast look-up for nets */
net_lookup_.emplace_back();
/* Reserve the instance 0 for the module */
net_lookup_[module][module].emplace_back();
/* Return the new id */
return module;
}
@ -177,6 +194,10 @@ ModulePortId ModuleManager::add_port(const ModuleId& module,
/* Update fast look-up for port */
port_lookup_[module][port_type].push_back(port);
/* Update fast look-up for nets */
VTR_ASSERT_SAFE(1 == net_lookup_[module][module].size());
net_lookup_[module][module][0][port].resize(port_info.get_width());
return port;
}
@ -234,6 +255,106 @@ void ModuleManager::add_child_module(const ModuleId& parent_module, const Module
/* Increase the counter of instances */
num_child_instances_[parent_module][child_it - children_[parent_module].begin()]++;
}
/* Update fast look-up for nets */
size_t instance_id = net_lookup_[parent_module][child_module].size();
/* Find the ports for the child module and update the fast look-up */
for (ModulePortId child_port : port_ids_[child_module]) {
net_lookup_[parent_module][child_module].emplace_back();
net_lookup_[parent_module][child_module][instance_id][child_port].resize(ports_[child_module][child_port].get_width());
}
}
/* Add a net to the connection graph of the module */
ModuleNetId ModuleManager::create_module_net(const ModuleId& module) {
/* Validate the module id */
VTR_ASSERT ( valid_module_id(module) );
/* Create an new id */
ModuleNetId net = ModuleNetId(net_ids_[module].size());
net_ids_[module].push_back(net);
/* Allocate net-related data structures */
net_names_[module].emplace_back();
net_src_module_ids_[module].emplace_back();
net_src_instance_ids_[module].emplace_back();
net_src_port_ids_[module].emplace_back();
net_src_pin_ids_[module].emplace_back();
net_sink_module_ids_[module].emplace_back();
net_sink_instance_ids_[module].emplace_back();
net_sink_port_ids_[module].emplace_back();
net_sink_pin_ids_[module].emplace_back();
return net;
}
/* Add a source to a net in the connection graph */
void ModuleManager::add_module_net_source(const ModuleId& module, const ModuleNetId& net,
const ModuleId& src_module, const size_t& instance_id,
const ModulePortId& src_port, const size_t& src_pin) {
/* Validate the module and net id */
VTR_ASSERT(valid_module_net_id(module, net));
/* Validate the source module */
VTR_ASSERT(valid_module_id(src_module));
net_src_module_ids_[module][net].push_back(src_module);
/* if it has the same id as module, our instance id will be by default 0 */
size_t src_instance_id = instance_id;
if (src_module == module) {
src_instance_id = 0;
net_src_instance_ids_[module][net].push_back(src_instance_id);
} else {
/* Check the instance id of the src module */
VTR_ASSERT (src_instance_id < num_instance(module, src_module));
net_src_instance_ids_[module][net].push_back(src_instance_id);
}
/* Validate the port exists in the src module */
VTR_ASSERT(valid_module_port_id(src_module, src_port));
net_src_port_ids_[module][net].push_back(src_port);
/* Validate the pin id is in the range of the port width */
VTR_ASSERT(src_pin < module_port(src_module, src_port).get_width());
net_src_pin_ids_[module][net].push_back(src_pin);
/* Update fast look-up for nets */
net_lookup_[module][src_module][src_instance_id][src_port][src_pin] = net;
}
/* Add a sink to a net in the connection graph */
void ModuleManager::add_module_net_sink(const ModuleId& module, const ModuleNetId& net,
const ModuleId& sink_module, const size_t& instance_id,
const ModulePortId& sink_port, const size_t& sink_pin) {
/* Validate the module and net id */
VTR_ASSERT(valid_module_net_id(module, net));
/* Validate the source module */
VTR_ASSERT(valid_module_id(sink_module));
net_sink_module_ids_[module][net].push_back(sink_module);
/* if it has the same id as module, our instance id will be by default 0 */
size_t sink_instance_id = instance_id;
if (sink_module == module) {
sink_instance_id = 0;
net_sink_instance_ids_[module][net].push_back(sink_instance_id);
} else {
/* Check the instance id of the src module */
VTR_ASSERT (sink_instance_id < num_instance(module, sink_module));
net_sink_instance_ids_[module][net].push_back(sink_instance_id);
}
/* Validate the port exists in the sink module */
VTR_ASSERT(valid_module_port_id(sink_module, sink_port));
net_sink_port_ids_[module][net].push_back(sink_port);
/* Validate the pin id is in the range of the port width */
VTR_ASSERT(sink_pin < module_port(sink_module, sink_port).get_width());
net_sink_pin_ids_[module][net].push_back(sink_pin);
/* Update fast look-up for nets */
net_lookup_[module][sink_module][sink_instance_id][sink_port][sink_pin] = net;
}
/******************************************************************************
@ -250,6 +371,13 @@ bool ModuleManager::valid_module_port_id(const ModuleId& module, const ModulePor
return ( size_t(port) < port_ids_[module].size() ) && ( port == port_ids_[module][port] );
}
bool ModuleManager::valid_module_net_id(const ModuleId& module, const ModuleNetId& net) const {
if (false == valid_module_id(module)) {
return false;
}
return ( size_t(net) < net_ids_[module].size() ) && ( net == net_ids_[module][net] );
}
void ModuleManager::invalidate_name2id_map() {
name_id_map_.clear();
}
@ -257,3 +385,7 @@ void ModuleManager::invalidate_name2id_map() {
void ModuleManager::invalidate_port_lookup() {
port_lookup_.clear();
}
void ModuleManager::invalidate_net_lookup() {
net_lookup_.clear();
}

View File

@ -68,19 +68,33 @@ class ModuleManager {
void set_port_preproc_flag(const ModuleId& module, const ModulePortId& port, const std::string& preproc_flag);
/* Add a child module to a parent module */
void add_child_module(const ModuleId& parent_module, const ModuleId& child_module);
/* Add a net to the connection graph of the module */
ModuleNetId create_module_net(const ModuleId& module);
/* Add a source to a net in the connection graph */
void add_module_net_source(const ModuleId& module, const ModuleNetId& net,
const ModuleId& src_module, const size_t& instance_id,
const ModulePortId& src_port, const size_t& src_pin);
/* Add a sink to a net in the connection graph */
void add_module_net_sink(const ModuleId& module, const ModuleNetId& net,
const ModuleId& sink_module, const size_t& instance_id,
const ModulePortId& sink_port, const size_t& sink_pin);
public: /* Public validators/invalidators */
bool valid_module_id(const ModuleId& module) const;
bool valid_module_port_id(const ModuleId& module, const ModulePortId& port) const;
bool valid_module_net_id(const ModuleId& module, const ModuleNetId& net) const;
private: /* Private validators/invalidators */
void invalidate_name2id_map();
void invalidate_port_lookup();
void invalidate_net_lookup();
private: /* Internal data */
/* Module-level data */
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, std::vector<size_t>> num_child_instances_; /* Number of children instance in each child module */
/* Port-level data */
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 */
@ -88,11 +102,31 @@ class ModuleManager {
vtr::vector<ModuleId, vtr::vector<ModulePortId, bool>> port_is_register_; /* If the port is a register, use for Verilog port definition. If enabled: <port_type> reg <port_name> */
vtr::vector<ModuleId, vtr::vector<ModulePortId, std::string>> port_preproc_flags_; /* If a port is available only when a pre-processing flag is enabled. This is to record the pre-processing flags */
/* Graph-level data:
* We use nets to model the connection between pins of modules and instances.
* To avoid large memory footprint, we do NOT create pins,
* To enable fast look-up on pins, we create a fast look-up
*/
vtr::vector<ModuleId, vtr::vector<ModuleNetId, ModuleNetId>> net_ids_; /* List of nets for each Module */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::string>> net_names_; /* Name of net */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::vector<ModuleId>>> net_src_module_ids_; /* Pin ids that drive the net */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::vector<size_t>>> net_src_instance_ids_; /* Pin ids that drive the net */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::vector<ModulePortId>>> net_src_port_ids_; /* Pin ids that drive the net */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::vector<size_t>>> net_src_pin_ids_; /* Pin ids that drive the net */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::vector<ModuleId>>> net_sink_module_ids_; /* Pin ids that the net drives */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::vector<size_t>>> net_sink_instance_ids_; /* Pin ids that drive the net */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::vector<ModulePortId>>> net_sink_port_ids_; /* Pin ids that drive the net */
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::vector<size_t>>> net_sink_pin_ids_; /* Pin ids that drive the net */
/* 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] */
/* fast look-up for nets */
typedef vtr::vector<ModuleId, std::map<ModuleId, std::vector<std::map<ModulePortId, std::vector<ModuleNetId>>>>> NetLookup;
mutable NetLookup net_lookup_; /* [module_ids][module_ids][instance_ids][port_ids][pin_ids] */
};
#endif

View File

@ -11,9 +11,13 @@
/* Strong Ids for ModuleManager */
struct module_id_tag;
struct module_port_id_tag;
struct module_pin_id_tag;
struct module_net_id_tag;
typedef vtr::StrongId<module_id_tag> ModuleId;
typedef vtr::StrongId<module_port_id_tag> ModulePortId;
typedef vtr::StrongId<module_pin_id_tag> ModulePinId;
typedef vtr::StrongId<module_net_id_tag> ModuleNetId;
class ModuleManager;