add recursive global port searching for circuit library
This commit is contained in:
parent
3fb3082447
commit
37a092e885
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
Loading…
Reference in New Issue