add recursive global port searching for circuit library

This commit is contained in:
tangxifan 2019-08-23 16:36:30 -06:00
parent 3fb3082447
commit 37a092e885
5 changed files with 142 additions and 13 deletions

View File

@ -372,12 +372,14 @@ std::vector<CircuitPortId> CircuitLibrary::model_ports(const CircuitModelId& mod
}
/* Recursively find all the global ports in the circuit model / sub circuit_model */
std::vector<CircuitPortId> CircuitLibrary::model_global_ports(const CircuitModelId& model_id) const {
std::vector<CircuitPortId> CircuitLibrary::model_global_ports(const CircuitModelId& model_id,
const bool& recursive) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
/* Search all the ports */
std::vector<CircuitPortId> global_ports;
/* Search all the ports */
for (auto port : model_ports(model_id)) {
/* By pass non-global ports*/
if (false == port_is_global(port)) {
@ -387,12 +389,39 @@ std::vector<CircuitPortId> CircuitLibrary::model_global_ports(const CircuitModel
global_ports.push_back(port);
}
/* Finish, if we do not need to go recursively */
if (false == recursive) {
return global_ports;
}
/* If go recursively, we search all the buffer/pass-gate circuit model ids */
/* Go search every sub circuit model included the current circuit model */
for (const auto& sub_model : sub_models_[model_id]) {
std::vector<CircuitPortId> sub_global_ports = model_global_ports(sub_model, recursive);
for (const auto& sub_global_port : sub_global_ports) {
/* Add to global_ports, if it is not already found in the list */
bool add_to_list = true;
for (const auto& global_port : global_ports) {
if (0 == port_prefix(sub_global_port).compare(port_prefix(global_port))) {
/* Same name, skip list update */
add_to_list = false;
break;
}
}
if (true == add_to_list) {
/* Add the sub_global_port to the list */
global_ports.push_back(sub_global_port);
}
}
}
return global_ports;
}
/* Recursively find all the global ports in the circuit model / sub circuit_model */
std::vector<CircuitPortId> CircuitLibrary::model_global_ports_by_type(const CircuitModelId& model_id,
const enum e_spice_model_port_type& type) const {
const enum e_spice_model_port_type& type,
const bool& recursive) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
@ -411,6 +440,32 @@ std::vector<CircuitPortId> CircuitLibrary::model_global_ports_by_type(const Circ
global_ports.push_back(port);
}
/* Finish, if we do not need to go recursively */
if (false == recursive) {
return global_ports;
}
/* If go recursively, we search all the buffer/pass-gate circuit model ids */
/* Go search every sub circuit model included the current circuit model */
for (const auto& sub_model : sub_models_[model_id]) {
std::vector<CircuitPortId> sub_global_ports = model_global_ports_by_type(sub_model, type, recursive);
for (const auto& sub_global_port : sub_global_ports) {
/* Add to global_ports, if it is not already found in the list */
bool add_to_list = true;
for (const auto& global_port : global_ports) {
if (0 == port_prefix(sub_global_port).compare(port_prefix(global_port))) {
/* Same name, skip list update */
add_to_list = false;
break;
}
}
if (true == add_to_list) {
/* Add the sub_global_port to the list */
global_ports.push_back(sub_global_port);
}
}
}
return global_ports;
}
@ -741,6 +796,7 @@ CircuitModelId CircuitLibrary::add_model(const enum e_spice_model_type& type) {
model_verilog_netlists_.emplace_back();
model_spice_netlists_.emplace_back();
model_is_default_.push_back(false);
sub_models_.emplace_back();
/* Verilog generator options */
dump_structural_verilog_.push_back(false);
@ -1571,6 +1627,69 @@ void CircuitLibrary::link_pass_gate_logic_model(const CircuitModelId& model_id)
return;
}
/* Find if a model is already in the submodel list */
bool CircuitLibrary::is_unique_submodel(const CircuitModelId& model_id, const CircuitModelId& submodel_id) {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
VTR_ASSERT(valid_model_id(submodel_id));
std::vector<CircuitModelId>::iterator it = std::find(sub_models_[model_id].begin(), sub_models_[model_id].end(), submodel_id);
if (it == sub_models_[model_id].end()) {
return true;
}
return false;
}
/* Build the sub module list for each circuit model,
* Find the linked circuit model id in
* pass-gate, buffers, ports */
void CircuitLibrary::build_submodels() {
for (const auto& model: models()) {
/* Make sure a clean start */
sub_models_[model].clear();
/* build a list of candidates */
std::vector<CircuitModelId> candidates;
/* Find buffer models */
for (const auto& buffer_model : buffer_model_ids_[model]) {
/* Skip any invalid ids */
if (CircuitModelId::INVALID() == buffer_model) {
continue;
}
candidates.push_back(buffer_model);
}
/* Find pass-gate models */
/* Skip any invalid ids */
if (CircuitModelId::INVALID() != pass_gate_logic_model_ids_[model]) {
candidates.push_back(pass_gate_logic_model_ids_[model]);
}
/* Find each port circuit models */
for (const auto& port: model_ports(model)) {
/* Find tri-state circuit models */
/* Skip any invalid ids */
if (CircuitModelId::INVALID() != port_tri_state_model_ids_[port]) {
candidates.push_back(port_tri_state_model_ids_[port]);
}
/* Find inv circuit models */
/* Skip any invalid ids */
if (CircuitModelId::INVALID() != port_inv_model_ids_[port]) {
candidates.push_back(port_inv_model_ids_[port]);
}
}
/* Build a unique list */
for (const auto& cand : candidates) {
/* Make sure the model id is unique in the list */
if (true == is_unique_submodel(model,cand)) {
sub_models_[model].push_back(cand);
}
}
}
}
/* Build the timing graph for a circuit models*/
void CircuitLibrary::build_model_timing_graph(const CircuitModelId& model_id) {
/* validate the model_id */
@ -1612,6 +1731,10 @@ void CircuitLibrary::build_model_links() {
/* Build links for ports */
link_port_tri_state_model();
link_port_inv_model();
/* Build submodels */
build_submodels();
return;
}

View File

@ -74,6 +74,8 @@
* 5. verilog_netlist_: specified path and file name of Verilog netlist if a circuit model is not auto-generated
* 6. spice_netlist_: specified path and file name of SPICE netlist if a circuit model is not auto-generated
* 7. is_default_: indicate if the circuit model is the default one among all those in the same type
* 8. sub_models_: the sub circuit models included by a circuit model. It is a collection of unique circuit model ids
* found in the CircuitModelId of pass-gate/buffers/port-related circuit models.
*
* ------ Fast look-ups-----
* 1. model_lookup_: A multi-dimension vector to provide fast look-up on circuit models for users
@ -243,9 +245,10 @@ class CircuitLibrary {
size_t num_model_ports(const CircuitModelId& model_id) const;
size_t num_model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const;
std::vector<CircuitPortId> model_ports(const CircuitModelId& model_id) const;
std::vector<CircuitPortId> model_global_ports(const CircuitModelId& model_id) const;
std::vector<CircuitPortId> model_global_ports(const CircuitModelId& model_id, const bool& recursive) const;
std::vector<CircuitPortId> model_global_ports_by_type(const CircuitModelId& model_id,
const enum e_spice_model_port_type& type) const;
const enum e_spice_model_port_type& type,
const bool& recursive) const;
std::vector<CircuitPortId> model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type) const;
std::vector<CircuitPortId> model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const;
std::vector<CircuitPortId> model_input_ports(const CircuitModelId& model_id) const;
@ -426,6 +429,8 @@ class CircuitLibrary {
void link_port_inv_model();
void link_buffer_model(const CircuitModelId& model_id);
void link_pass_gate_logic_model(const CircuitModelId& model_id);
bool is_unique_submodel(const CircuitModelId& model_id, const CircuitModelId& submodel_id);
void build_submodels();
void build_model_timing_graph(const CircuitModelId& model_id);
public: /* Public Mutators: builders */
void build_model_links();
@ -466,6 +471,9 @@ class CircuitLibrary {
vtr::vector<CircuitModelId, std::string> model_spice_netlists_;
vtr::vector<CircuitModelId, bool> model_is_default_;
/* Submodules that a circuit model contains */
vtr::vector<CircuitModelId, std::vector<CircuitModelId>> sub_models_;
/* fast look-up for circuit models to categorize by types
* [type][num_ids]
* Important: we force the default circuit model in the first element for each type
@ -566,7 +574,6 @@ class CircuitLibrary {
vtr::vector<CircuitModelId, enum e_wire_model_type> wire_types_;
vtr::vector<CircuitModelId, vtr::Point<float>> wire_rc_; /* x => wire_res_val, y=> wire_cap_val */
vtr::vector<CircuitModelId, size_t> wire_num_levels_;
};
#endif

View File

@ -20,7 +20,7 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager,
/* Add ports */
/* Find global ports and add one by one */
for (const auto& port : circuit_lib.model_global_ports(circuit_model)) {
for (const auto& port : circuit_lib.model_global_ports(circuit_model, true)) {
BasicPort port_info(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
module_manager.add_port(module, port_info, ModuleManager::MODULE_GLOBAL_PORT);
}
@ -48,5 +48,4 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager,
/* Return the new id */
return module;
}

View File

@ -145,7 +145,7 @@ void print_verilog_invbuf_module(std::fstream& fp,
/* Find the input port, output port and global inputs*/
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true);
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_OUTPUT, true);
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT);
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true);
/* Make sure:
* There is only 1 input port and 1 output port,
@ -248,7 +248,7 @@ void print_verilog_passgate_module(std::fstream& fp,
/* Find the input port, output port*/
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true);
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_OUTPUT, true);
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT);
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true);
switch (circuit_lib.pass_gate_logic_type(circuit_model)) {
case SPICE_MODEL_PASS_GATE_TRANSMISSION:
@ -483,7 +483,7 @@ void print_verilog_gate_module(std::fstream& fp,
/* Find the input port, output port*/
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true);
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_OUTPUT, true);
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT);
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true);
/* Make sure:
* There is only 1 output port,

View File

@ -47,7 +47,7 @@ void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp,
/* Get model ports of tgate */
std::vector<CircuitPortId> tgate_input_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT, true);
std::vector<CircuitPortId> tgate_output_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_OUTPUT, true);
std::vector<CircuitPortId> tgate_global_ports = circuit_lib.model_global_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT);
std::vector<CircuitPortId> tgate_global_ports = circuit_lib.model_global_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT, true);
VTR_ASSERT(3 == tgate_input_ports.size());
VTR_ASSERT(1 == tgate_output_ports.size());