diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp index f5b2ba6af..a423e5409 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp @@ -372,12 +372,14 @@ std::vector CircuitLibrary::model_ports(const CircuitModelId& mod } /* Recursively find all the global ports in the circuit model / sub circuit_model */ -std::vector CircuitLibrary::model_global_ports(const CircuitModelId& model_id) const { +std::vector 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 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 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 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 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 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 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); @@ -1569,7 +1625,70 @@ void CircuitLibrary::link_pass_gate_logic_model(const CircuitModelId& model_id) } pass_gate_logic_model_ids_[model_id] = model(pass_gate_logic_model_names_[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::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 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) { @@ -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; } diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.h b/vpr7_x2p/libarchfpga/SRC/circuit_library.h index cab53bec6..a638ea8d1 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.h @@ -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 model_ports(const CircuitModelId& model_id) const; - std::vector model_global_ports(const CircuitModelId& model_id) const; + std::vector model_global_ports(const CircuitModelId& model_id, const bool& recursive) const; std::vector 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 model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type) const; std::vector 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 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 model_spice_netlists_; vtr::vector model_is_default_; + /* Submodules that a circuit model contains */ + vtr::vector> 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 wire_types_; vtr::vector> wire_rc_; /* x => wire_res_val, y=> wire_cap_val */ vtr::vector wire_num_levels_; - }; #endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp index f375c446c..85502cc48 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp @@ -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; - } diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_essential_gates.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_essential_gates.cpp index a5378fcd9..41d2fb560 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_essential_gates.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_essential_gates.cpp @@ -145,7 +145,7 @@ void print_verilog_invbuf_module(std::fstream& fp, /* Find the input port, output port and global inputs*/ std::vector input_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true); std::vector output_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_OUTPUT, true); - std::vector global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT); + std::vector 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 input_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true); std::vector output_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_OUTPUT, true); - std::vector global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT); + std::vector 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 input_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true); std::vector output_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_OUTPUT, true); - std::vector global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT); + std::vector global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true); /* Make sure: * There is only 1 output port, diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_mux.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_mux.cpp index 9255097c9..dce86830a 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_mux.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_mux.cpp @@ -47,7 +47,7 @@ void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp, /* Get model ports of tgate */ std::vector tgate_input_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT, true); std::vector tgate_output_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_OUTPUT, true); - std::vector tgate_global_ports = circuit_lib.model_global_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT); + std::vector 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());