From 29104b6fa5595f876cf994cf8764777a30c61d50 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 20 Aug 2019 15:14:28 -0600 Subject: [PATCH] rework on the circuit model ports and start prototyping mux Verilog generation --- .../libarchfpga/SRC/check_circuit_library.cpp | 8 +- vpr7_x2p/libarchfpga/SRC/circuit_library.cpp | 878 +++++++++--------- vpr7_x2p/libarchfpga/SRC/circuit_library.h | 240 +++-- .../libarchfpga/SRC/circuit_library_fwd.h | 5 + vpr7_x2p/libarchfpga/SRC/circuit_types.h | 1 + vpr7_x2p/libarchfpga/SRC/read_xml_spice.c | 42 +- vpr7_x2p/vpr/SRC/device/mux_graph.cpp | 36 +- vpr7_x2p/vpr/SRC/device/mux_graph.h | 8 +- .../fpga_x2p/base/link_arch_circuit_lib.cpp | 15 +- .../SRC/fpga_x2p/base/link_arch_circuit_lib.h | 1 - .../vpr/SRC/fpga_x2p/base/module_manager.h | 27 + .../SRC/fpga_x2p/base/module_manager_fwd.h | 18 + .../verilog/verilog_compact_netlist.c | 4 +- .../vpr/SRC/fpga_x2p/verilog/verilog_global.h | 8 +- .../verilog/verilog_submodule_mux.cpp | 166 +++- .../fpga_x2p/verilog/verilog_submodule_mux.h | 1 + .../SRC/fpga_x2p/verilog/verilog_submodules.c | 3 +- .../vpr/SRC/fpga_x2p/verilog/verilog_utils.c | 3 +- .../vpr/SRC/fpga_x2p/verilog/verilog_utils.h | 3 +- .../fpga_x2p/verilog/verilog_writer_utils.cpp | 39 + .../fpga_x2p/verilog/verilog_writer_utils.h | 15 + 21 files changed, 879 insertions(+), 642 deletions(-) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_fwd.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.h diff --git a/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp index 2f51fa9bb..8fc98cc50 100644 --- a/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp @@ -150,7 +150,7 @@ size_t check_one_circuit_model_port_required(const CircuitLibrary& circuit_lib, size_t num_err = 0; for (const auto& port_type: port_types_to_check) { - if (0 == circuit_lib.ports_by_type(circuit_model, port_type).size()) { + if (0 == circuit_lib.model_ports_by_type(circuit_model, port_type).size()) { vpr_printf(TIO_MESSAGE_ERROR, "%s circuit model(name=%s) does not have %s port\n", CIRCUIT_MODEL_TYPE_STRING[size_t(circuit_lib.model_type(circuit_model))], @@ -175,11 +175,11 @@ size_t check_one_circuit_model_port_size_required(const CircuitLibrary& circuit_ size_t num_err = 0; - if (port_size_to_check != circuit_lib.port_size(circuit_model, circuit_port)) { + if (port_size_to_check != circuit_lib.port_size(circuit_port)) { vpr_printf(TIO_MESSAGE_ERROR, "Port of circuit model(name=%s) does not have a port(type=%s) of size=%d.\n", circuit_lib.model_name(circuit_model).c_str(), - CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(circuit_lib.port_type(circuit_model, circuit_port))], + CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(circuit_lib.port_type(circuit_port))], port_size_to_check); /* Incremental the counter for errors */ num_err++; @@ -202,7 +202,7 @@ size_t check_one_circuit_model_port_type_and_size_required(const CircuitLibrary& size_t num_err = 0; - std::vector ports = circuit_lib.ports_by_type(circuit_model, port_type_to_check, include_global_ports); + std::vector ports = circuit_lib.model_ports_by_type(circuit_model, port_type_to_check, include_global_ports); if (num_ports_to_check != ports.size()) { vpr_printf(TIO_MESSAGE_ERROR, "Expect %d %s ports for a %s circuit model, but only have %d %s ports!\n", diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp index e39d81793..1e45f5b7f 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp @@ -55,12 +55,12 @@ CircuitLibrary::CircuitLibrary() { /************************************************************************ * Public Accessors : aggregates ***********************************************************************/ -CircuitLibrary::model_range CircuitLibrary::models() const { +CircuitLibrary::circuit_model_range CircuitLibrary::models() const { return vtr::make_range(model_ids_.begin(), model_ids_.end()); } -CircuitLibrary::circuit_port_range CircuitLibrary::ports(const CircuitModelId& model_id) const { - return vtr::make_range(port_ids_[model_id].begin(), port_ids_[model_id].end()); +CircuitLibrary::circuit_port_range CircuitLibrary::ports() const { + return vtr::make_range(port_ids_.begin(), port_ids_.end()); } /* Find circuit models in the same type (defined by users) and return a list of ids */ @@ -77,84 +77,6 @@ std::vector CircuitLibrary::models_by_type(const enum e_spice_mo return type_ids; } -/* Find the ports of a circuit model by a given type, return a list of qualified ports */ -std::vector CircuitLibrary::ports_by_type(const CircuitModelId& model_id, - const enum e_spice_model_port_type& type) const { - std::vector port_ids; - for (const auto& port_id : ports(model_id)) { - /* We skip unmatched ports */ - if ( type != port_type(model_id, port_id) ) { - continue; - } - port_ids.push_back(port_id); - } - return port_ids; -} - -/* Find the ports of a circuit model by a given type, return a list of qualified ports - * with an option to include/exclude global ports - */ -std::vector CircuitLibrary::ports_by_type(const CircuitModelId& model_id, - const enum e_spice_model_port_type& type, - const bool& include_global_port) const { - std::vector port_ids; - for (const auto& port_id : ports(model_id)) { - /* We skip unmatched ports */ - if ( type != port_type(model_id, port_id) ) { - continue; - } - /* We skip global ports if specified */ - if ( (false == include_global_port) - && (true == port_is_global(model_id, port_id)) ) { - continue; - } - port_ids.push_back(port_id); - } - return port_ids; -} - - -/* Create a vector for all the ports whose directionality is input - * This includes all the ports other than whose types are OUPUT or INOUT - */ -std::vector CircuitLibrary::input_ports(const CircuitModelId& model_id) const { - std::vector input_ports; - for (const auto& port_id : ports(model_id)) { - /* We skip output ports */ - if ( false == is_input_port(model_id, port_id) ) { - continue; - } - input_ports.push_back(port_id); - } - return input_ports; -} - -/* Create a vector for all the ports whose directionality is output - * This includes all the ports whose types are OUPUT or INOUT - */ -std::vector CircuitLibrary::output_ports(const CircuitModelId& model_id) const { - std::vector output_ports; - for (const auto& port_id : ports(model_id)) { - /* We skip input ports */ - if ( false == is_output_port(model_id, port_id) ) { - continue; - } - output_ports.push_back(port_id); - } - return output_ports; -} - -/* Create a vector for the pin indices, which is bounded by the size of a port - * Start from 0 and end to port_size - 1 - */ -std::vector CircuitLibrary::pins(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const { - std::vector pin_range(port_size(model_id, circuit_port_id)); - /* Create a vector, with sequentially increasing numbers */ - std::iota(pin_range.begin(), pin_range.end(), 0); - return pin_range; -} - - /************************************************************************ * Public Accessors : Basic data query on Circuit Models ***********************************************************************/ @@ -256,24 +178,24 @@ bool CircuitLibrary::is_lut_intermediate_buffered(const CircuitModelId& model_id return buffer_existence_[model_id][LUT_INTER_BUFFER]; } -/* Find the type of pass-gate logic for a circuit model (recursive function) +/* Find the id of pass-gate circuit model * Two cases to be considered: * 1. this is a pass-gate circuit model, just find the data and return * 2. this circuit model includes a pass-gate, find the link to pass-gate circuit model and go recursively */ -enum e_spice_model_pass_gate_logic_type CircuitLibrary::pass_gate_logic_type(const CircuitModelId& model_id) const { +CircuitModelId CircuitLibrary::pass_gate_logic_model(const CircuitModelId& model_id) const { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); /* Return the data if this is a pass-gate circuit model */ if (SPICE_MODEL_PASSGATE == model_type(model_id)) { - return pass_gate_logic_types_[model_id]; + return model_ids_[model_id]; } /* Otherwise, we need to make sure this circuit model contains a pass-gate */ CircuitModelId pgl_model_id = pass_gate_logic_model_ids_[model_id]; VTR_ASSERT( CircuitModelId::INVALID() != pgl_model_id ); - return pass_gate_logic_type(pgl_model_id); + return pgl_model_id; } /* Return the multiplex structure of a circuit model */ @@ -325,41 +247,36 @@ size_t CircuitLibrary::mux_const_input_value(const CircuitModelId& model_id) con return mux_const_input_values_[model_id]; } +/* Return the type of gate for a circuit model + * Only applicable for GATE circuit model + */ +enum e_spice_model_gate_type CircuitLibrary::gate_type(const CircuitModelId& model_id) const { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + /* validate the circuit model type is MUX */ + VTR_ASSERT(SPICE_MODEL_GATE == model_type(model_id)); + return gate_types_[model_id]; +} + /************************************************************************ - * Public Accessors : Basic data query on Circuit Porst + * Public Accessors : Basic data query on Circuit models' Circuit Port ***********************************************************************/ -/* identify if this port is an input port */ -bool CircuitLibrary::is_input_port(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const { - /* validate the model_id and circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - /* Only SPICE_MODEL_OUTPUT AND INOUT are considered as outputs */ - return ( (SPICE_MODEL_PORT_OUTPUT != port_type(model_id, circuit_port_id)) - && (SPICE_MODEL_PORT_INOUT != port_type(model_id, circuit_port_id)) ); -} - -/* identify if this port is an output port */ -bool CircuitLibrary::is_output_port(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const { - /* validate the model_id and circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - /* Only SPICE_MODEL_OUTPUT AND INOUT are considered as outputs */ - return ( (SPICE_MODEL_PORT_OUTPUT == port_type(model_id, circuit_port_id)) - || (SPICE_MODEL_PORT_INOUT == port_type(model_id, circuit_port_id)) ); -} - /* Given a name and return the port id */ -CircuitPortId CircuitLibrary::port(const CircuitModelId& model_id, const std::string& name) const { +CircuitPortId CircuitLibrary::model_port(const CircuitModelId& model_id, const std::string& name) const { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); /* Walk through the ports and try to find a matched name */ CircuitPortId ret = CircuitPortId::INVALID(); size_t num_found = 0; - for (auto port_id : ports(model_id)) { - if (0 != name.compare(port_prefix(model_id, port_id))) { - continue; /* Not the one, go to the next*/ + for (auto model_ports_by_type : model_port_lookup_[model_id]) { + for (auto port_id : model_ports_by_type) { + if (0 != name.compare(port_prefix(port_id))) { + continue; /* Not the one, go to the next*/ + } + ret = port_id; /* Find one */ + num_found++; } - ret = port_id; /* Find one */ - num_found++; } /* Make sure we will not find two ports with the same name */ VTR_ASSERT( (0 == num_found) || (1 == num_found) ); @@ -367,122 +284,259 @@ CircuitPortId CircuitLibrary::port(const CircuitModelId& model_id, const std::st } /* Access the type of a port of a circuit model */ -size_t CircuitLibrary::num_ports(const CircuitModelId& model_id) const { +size_t CircuitLibrary::num_model_ports(const CircuitModelId& model_id) const { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); - return port_ids_[model_id].size(); + /* Search the port look up and return a list */ + size_t num_of_ports = 0; + for (auto model_ports_by_type : model_port_lookup_[model_id]) { + num_of_ports += model_ports_by_type.size(); + } + return num_of_ports; } /* Access the type of a port of a circuit model * with an option to include/exclude global ports * when counting */ -size_t CircuitLibrary::num_ports_by_type(const CircuitModelId& model_id, - const enum e_spice_model_port_type& port_type, - const bool& include_global_port) const { +size_t CircuitLibrary::num_model_ports_by_type(const CircuitModelId& model_id, + const enum e_spice_model_port_type& port_type, + const bool& include_global_port) const { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); - return ports_by_type(model_id, port_type, include_global_port).size(); + /* Search the port look up */ + VTR_ASSERT(port_type < model_port_lookup_[model_id].size()); + size_t num_ports = 0; + for (auto port : model_port_lookup_[model_id][port_type]) { + /* By pass non-global ports if required by user */ + if ( (false == include_global_port) + && (true == port_is_global(port)) ) { + continue; + } + num_ports++; + } + + return num_ports; +} + +/* Find all the ports belong to a circuit model */ +std::vector CircuitLibrary::model_ports(const CircuitModelId& model_id) const { + /* validate the circuit_model_id */ + VTR_ASSERT(valid_model_id(model_id)); + /* Search the port look up and return a list */ + std::vector port_ids; + for (auto model_ports_by_type : model_port_lookup_[model_id]) { + for (auto port_id : model_ports_by_type) { + port_ids.push_back(port_id); + } + } + return port_ids; +} + +/* Recursively find all the global ports in the circuit model / sub circuit_model */ +std::vector CircuitLibrary::model_global_ports(const CircuitModelId& model_id) const { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + + /* Search all the ports */ + std::vector global_ports; + for (auto port : model_ports(model_id)) { + /* By pass non-global ports*/ + if (false == port_is_global(port)) { + continue; + } + /* This is a global port, update global_ports */ + global_ports.push_back(port); + } + + return global_ports; +} + +/* Find the ports of a circuit model by a given type, return a list of qualified ports */ +std::vector CircuitLibrary::model_ports_by_type(const CircuitModelId& model_id, + const enum e_spice_model_port_type& type) const { + std::vector port_ids; + for (const auto& port_id : model_ports(model_id)) { + /* We skip unmatched ports */ + if ( type != port_type(port_id) ) { + continue; + } + port_ids.push_back(port_id); + } + return port_ids; +} + +/* Find the ports of a circuit model by a given type, return a list of qualified ports + * with an option to include/exclude global ports + */ +std::vector CircuitLibrary::model_ports_by_type(const CircuitModelId& model_id, + const enum e_spice_model_port_type& type, + const bool& include_global_port) const { + std::vector port_ids; + for (const auto& port_id : model_port_lookup_[model_id][type]) { + /* We skip unmatched ports */ + if ( type != port_type(port_id) ) { + continue; + } + /* We skip global ports if specified */ + if ( (false == include_global_port) + && (true == port_is_global(port_id)) ) { + continue; + } + port_ids.push_back(port_id); + } + return port_ids; +} + + +/* Create a vector for all the ports whose directionality is input + * This includes all the ports other than whose types are OUPUT or INOUT + */ +std::vector CircuitLibrary::model_input_ports(const CircuitModelId& model_id) const { + std::vector input_ports; + for (const auto& port_id : model_ports(model_id)) { + /* We skip output ports */ + if ( false == is_input_port(port_id) ) { + continue; + } + input_ports.push_back(port_id); + } + return input_ports; +} + +/* Create a vector for all the ports whose directionality is output + * This includes all the ports whose types are OUPUT or INOUT + */ +std::vector CircuitLibrary::model_output_ports(const CircuitModelId& model_id) const { + std::vector output_ports; + for (const auto& port_id : model_ports(model_id)) { + /* We skip input ports */ + if ( false == is_output_port(port_id) ) { + continue; + } + output_ports.push_back(port_id); + } + return output_ports; +} + +/* Create a vector for the pin indices, which is bounded by the size of a port + * Start from 0 and end to port_size - 1 + */ +std::vector CircuitLibrary::pins(const CircuitPortId& circuit_port_id) const { + std::vector pin_range(port_size(circuit_port_id)); + /* Create a vector, with sequentially increasing numbers */ + std::iota(pin_range.begin(), pin_range.end(), 0); + return pin_range; +} + + +/************************************************************************ + * Public Accessors : Basic data query on Circuit Port + ***********************************************************************/ + +/* identify if this port is an input port */ +bool CircuitLibrary::is_input_port(const CircuitPortId& circuit_port_id) const { + /* validate the circuit_port_id */ + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + /* Only SPICE_MODEL_OUTPUT AND INOUT are considered as outputs */ + return ( (SPICE_MODEL_PORT_OUTPUT != port_type(circuit_port_id)) + && (SPICE_MODEL_PORT_INOUT != port_type(circuit_port_id)) ); +} + +/* identify if this port is an output port */ +bool CircuitLibrary::is_output_port(const CircuitPortId& circuit_port_id) const { + /* validate the circuit_port_id */ + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + /* Only SPICE_MODEL_OUTPUT AND INOUT are considered as outputs */ + return ( (SPICE_MODEL_PORT_OUTPUT == port_type(circuit_port_id)) + || (SPICE_MODEL_PORT_INOUT == port_type(circuit_port_id)) ); } /* Access the type of a port of a circuit model */ -enum e_spice_model_port_type CircuitLibrary::port_type(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +enum e_spice_model_port_type CircuitLibrary::port_type(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_types_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_types_[circuit_port_id]; } /* Access the type of a port of a circuit model */ -size_t CircuitLibrary::port_size(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +size_t CircuitLibrary::port_size(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_sizes_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_sizes_[circuit_port_id]; } /* Access the prefix of a port of a circuit model */ -std::string CircuitLibrary::port_prefix(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +std::string CircuitLibrary::port_prefix(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_prefix_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_prefix_[circuit_port_id]; } /* Access the lib_name of a port of a circuit model */ -std::string CircuitLibrary::port_lib_name(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +std::string CircuitLibrary::port_lib_name(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_lib_names_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_lib_names_[circuit_port_id]; } /* Access the inv_prefix of a port of a circuit model */ -std::string CircuitLibrary::port_inv_prefix(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +std::string CircuitLibrary::port_inv_prefix(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_inv_prefix_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_inv_prefix_[circuit_port_id]; } /* Return the default value of a port of a circuit model */ -size_t CircuitLibrary::port_default_value(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +size_t CircuitLibrary::port_default_value(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_default_values_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_default_values_[circuit_port_id]; } /* Return a flag if the port is used in mode-selection purpuse of a circuit model */ -bool CircuitLibrary::port_is_mode_select(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +bool CircuitLibrary::port_is_mode_select(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_is_mode_select_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_is_mode_select_[circuit_port_id]; } /* Return a flag if the port is a global one of a circuit model */ -bool CircuitLibrary::port_is_global(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +bool CircuitLibrary::port_is_global(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_is_global_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_is_global_[circuit_port_id]; } /* Return a flag if the port does a reset functionality in a circuit model */ -bool CircuitLibrary::port_is_reset(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +bool CircuitLibrary::port_is_reset(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_is_reset_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_is_reset_[circuit_port_id]; } /* Return a flag if the port does a set functionality in a circuit model */ -bool CircuitLibrary::port_is_set(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +bool CircuitLibrary::port_is_set(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_is_set_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_is_set_[circuit_port_id]; } /* Return a flag if the port enables a configuration in a circuit model */ -bool CircuitLibrary::port_is_config_enable(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +bool CircuitLibrary::port_is_config_enable(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_is_config_enable_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_is_config_enable_[circuit_port_id]; } /* Return a flag if the port is used during programming a FPGA in a circuit model */ -bool CircuitLibrary::port_is_prog(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id) const { +bool CircuitLibrary::port_is_prog(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return port_is_prog_[model_id][circuit_port_id]; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_is_prog_[circuit_port_id]; } - /************************************************************************ * Public Accessors : Methods to find circuit model ***********************************************************************/ @@ -496,7 +550,7 @@ CircuitModelId CircuitLibrary::model(const char* name) const { CircuitModelId CircuitLibrary::model(const std::string& name) const { CircuitModelId ret = CircuitModelId::INVALID(); size_t num_found = 0; - for (model_string_iterator it = model_names_.begin(); + for (circuit_model_string_iterator it = model_names_.begin(); it != model_names_.end(); it++) { /* Bypass unmatched names */ @@ -525,18 +579,17 @@ CircuitModelId CircuitLibrary::default_model(const enum e_spice_model_type& type * Public Accessors: Timing graph ***********************************************************************/ /* Given the source and sink port information, find the edge connecting the two ports */ -CircuitEdgeId CircuitLibrary::edge(const CircuitModelId& model_id, - const CircuitPortId& from_port, const size_t from_pin, +CircuitEdgeId CircuitLibrary::edge(const CircuitPortId& from_port, const size_t from_pin, const CircuitPortId& to_port, const size_t to_pin) { /* validate the circuit_pin_id */ - VTR_ASSERT(valid_circuit_pin_id(model_id, from_port, from_pin)); - VTR_ASSERT(valid_circuit_pin_id(model_id, to_port, to_pin)); + VTR_ASSERT(valid_circuit_pin_id(from_port, from_pin)); + VTR_ASSERT(valid_circuit_pin_id(to_port, to_pin)); /* Walk through the edge list until we find the one */ - for (auto edge : edge_ids_[model_id]) { - if ( (from_port == edge_src_port_ids_[model_id][edge]) - && (from_pin == edge_src_pin_ids_[model_id][edge]) - && (to_port == edge_sink_port_ids_[model_id][edge]) - && (to_pin == edge_sink_pin_ids_[model_id][edge]) ) { + for (auto edge : edge_ids_) { + if ( (from_port == edge_src_port_ids_[edge]) + && (from_pin == edge_src_pin_ids_[edge]) + && (to_port == edge_sink_port_ids_[edge]) + && (to_pin == edge_sink_pin_ids_[edge]) ) { return edge; } } @@ -548,7 +601,7 @@ CircuitEdgeId CircuitLibrary::edge(const CircuitModelId& model_id, * Public Mutators ***********************************************************************/ /* Add a circuit model to the library, and return it Id */ -CircuitModelId CircuitLibrary::add_model() { +CircuitModelId CircuitLibrary::add_model(const enum e_spice_model_type& type) { /* Create a new id*/ CircuitModelId model_id = CircuitModelId(model_ids_.size()); /* Update the id list */ @@ -556,7 +609,7 @@ CircuitModelId CircuitLibrary::add_model() { /* Initialize other attributes */ /* Fundamental information */ - model_types_.push_back(NUM_CIRCUIT_MODEL_TYPES); + model_types_.push_back(type); model_names_.emplace_back(); model_prefix_.emplace_back(); model_verilog_netlists_.emplace_back(); @@ -581,39 +634,6 @@ CircuitModelId CircuitLibrary::add_model() { pass_gate_logic_model_names_.emplace_back(); pass_gate_logic_model_ids_.emplace_back(); - /* Port information */ - port_ids_.emplace_back(); - port_types_.emplace_back(); - port_sizes_.emplace_back(); - port_prefix_.emplace_back(); - port_lib_names_.emplace_back(); - port_inv_prefix_.emplace_back(); - port_default_values_.emplace_back(); - port_is_mode_select_.emplace_back(); - port_is_global_.emplace_back(); - port_is_reset_.emplace_back(); - port_is_set_.emplace_back(); - port_is_config_enable_.emplace_back(); - port_is_prog_.emplace_back(); - port_model_names_.emplace_back(); - port_model_ids_.emplace_back(); - port_inv_model_names_.emplace_back(); - port_inv_model_ids_.emplace_back(); - port_tri_state_maps_.emplace_back(); - port_lut_frac_level_.emplace_back(); - port_lut_output_masks_.emplace_back(); - port_sram_orgz_.emplace_back(); - - /* Timing graphs */ - edge_ids_.emplace_back(); - port_in_edge_ids_.emplace_back(); - port_out_edge_ids_.emplace_back(); - edge_src_port_ids_.emplace_back(); - edge_src_pin_ids_.emplace_back(); - edge_sink_port_ids_.emplace_back(); - edge_sink_pin_ids_.emplace_back(); - edge_timing_info_.emplace_back(); - /* Delay information */ delay_types_.emplace_back(); delay_in_port_names_.emplace_back(); @@ -653,24 +673,10 @@ CircuitModelId CircuitLibrary::add_model() { wire_rc_.emplace_back(); wire_num_levels_.push_back(-1); - /* Update circuit port fast look-up */ - model_port_lookup_.emplace_back(); - - /* Invalidate fast look-up*/ - invalidate_model_lookup(); - - return model_id; -} - -/* Set the type of a Circuit Model */ -void CircuitLibrary::set_model_type(const CircuitModelId& model_id, - const enum e_spice_model_type& type) { - /* validate the model_id */ - VTR_ASSERT(valid_model_id(model_id)); - model_types_[model_id] = type; /* Build the fast look-up for circuit models */ build_model_lookup(); - return; + + return model_id; } /* Set the name of a Circuit Model */ @@ -747,7 +753,7 @@ void CircuitLibrary::set_model_is_power_gated(const CircuitModelId& model_id, co /* Set input buffer information for the circuit model */ void CircuitLibrary::set_model_input_buffer(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name) { + const bool& existence, const std::string& model_name) { /* Just call the base function and give the proper type */ set_model_buffer(model_id, INPUT, existence, model_name); return; @@ -755,7 +761,7 @@ void CircuitLibrary::set_model_input_buffer(const CircuitModelId& model_id, /* Set output buffer information for the circuit model */ void CircuitLibrary::set_model_output_buffer(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name) { + const bool& existence, const std::string& model_name) { /* Just call the base function and give the proper type */ set_model_buffer(model_id, OUTPUT, existence, model_name); return; @@ -763,7 +769,7 @@ void CircuitLibrary::set_model_output_buffer(const CircuitModelId& model_id, /* Set input buffer information for the circuit model, only applicable to LUTs! */ void CircuitLibrary::set_model_lut_input_buffer(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name) { + const bool& existence, const std::string& model_name) { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); /* Make sure the circuit model is a LUT! */ @@ -775,7 +781,7 @@ void CircuitLibrary::set_model_lut_input_buffer(const CircuitModelId& model_id, /* Set input inverter information for the circuit model, only applicable to LUTs! */ void CircuitLibrary::set_model_lut_input_inverter(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name) { + const bool& existence, const std::string& model_name) { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); /* Make sure the circuit model is a LUT! */ @@ -787,7 +793,7 @@ void CircuitLibrary::set_model_lut_input_inverter(const CircuitModelId& model_id /* Set intermediate buffer information for the circuit model, only applicable to LUTs! */ void CircuitLibrary::set_model_lut_intermediate_buffer(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name) { + const bool& existence, const std::string& model_name) { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); /* Make sure the circuit model is a LUT! */ @@ -798,7 +804,7 @@ void CircuitLibrary::set_model_lut_intermediate_buffer(const CircuitModelId& mod } void CircuitLibrary::set_model_lut_intermediate_buffer_location_map(const CircuitModelId& model_id, - const std::string& location_map) { + const std::string& location_map) { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); buffer_location_maps_[model_id][LUT_INTER_BUFFER] = location_map; @@ -815,248 +821,222 @@ void CircuitLibrary::set_model_pass_gate_logic(const CircuitModelId& model_id, c } /* Add a port to a circuit model */ -CircuitPortId CircuitLibrary::add_model_port(const CircuitModelId& model_id) { +CircuitPortId CircuitLibrary::add_model_port(const CircuitModelId& model_id, + const enum e_spice_model_port_type& port_type) { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); /* Create a port id */ - CircuitPortId circuit_port_id = CircuitPortId(port_ids_[model_id].size()); + CircuitPortId circuit_port_id = CircuitPortId(port_ids_.size()); /* Update the id list */ - port_ids_[model_id].push_back(circuit_port_id); + port_ids_.push_back(circuit_port_id); /* Initialize other attributes */ - port_types_[model_id].push_back(NUM_CIRCUIT_MODEL_PORT_TYPES); - port_sizes_[model_id].push_back(-1); - port_prefix_[model_id].emplace_back(); - port_lib_names_[model_id].emplace_back(); - port_inv_prefix_[model_id].emplace_back(); - port_default_values_[model_id].push_back(-1); - port_is_mode_select_[model_id].push_back(false); - port_is_global_[model_id].push_back(false); - port_is_reset_[model_id].push_back(false); - port_is_set_[model_id].push_back(false); - port_is_config_enable_[model_id].push_back(false); - port_is_prog_[model_id].push_back(false); - port_model_names_[model_id].emplace_back(); - port_model_ids_[model_id].push_back(CircuitModelId::INVALID()); - port_inv_model_names_[model_id].emplace_back(); - port_inv_model_ids_[model_id].push_back(CircuitModelId::INVALID()); - port_tri_state_maps_[model_id].emplace_back(); - port_lut_frac_level_[model_id].push_back(-1); - port_lut_output_masks_[model_id].emplace_back(); - port_sram_orgz_[model_id].push_back(NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES); + port_model_ids_.push_back(model_id); + port_types_.push_back(port_type); + port_sizes_.push_back(-1); + port_prefix_.emplace_back(); + port_lib_names_.emplace_back(); + port_inv_prefix_.emplace_back(); + port_default_values_.push_back(-1); + port_is_mode_select_.push_back(false); + port_is_global_.push_back(false); + port_is_reset_.push_back(false); + port_is_set_.push_back(false); + port_is_config_enable_.push_back(false); + port_is_prog_.push_back(false); + port_tri_state_model_names_.emplace_back(); + port_tri_state_model_ids_.push_back(CircuitModelId::INVALID()); + port_inv_model_names_.emplace_back(); + port_inv_model_ids_.push_back(CircuitModelId::INVALID()); + port_tri_state_maps_.emplace_back(); + port_lut_frac_level_.push_back(-1); + port_lut_output_masks_.emplace_back(); + port_sram_orgz_.push_back(NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES); /* For timing graphs */ - port_in_edge_ids_[model_id].emplace_back(); - port_out_edge_ids_[model_id].emplace_back(); + port_in_edge_ids_.emplace_back(); + port_out_edge_ids_.emplace_back(); + + /* Build the fast look-up for circuit model ports */ + build_model_port_lookup(); return circuit_port_id; } -/* Set the type for a port of a circuit model */ -void CircuitLibrary::set_port_type(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const enum e_spice_model_port_type& port_type) { - /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_types_[model_id][circuit_port_id] = port_type; - /* Build the fast look-up for circuit model ports */ - build_model_port_lookup(model_id); - return; -} - /* Set the size for a port of a circuit model */ -void CircuitLibrary::set_port_size(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_size(const CircuitPortId& circuit_port_id, const size_t& port_size) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_sizes_[model_id][circuit_port_id] = port_size; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_sizes_[circuit_port_id] = port_size; return; } /* Set the prefix for a port of a circuit model */ -void CircuitLibrary::set_port_prefix(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_prefix(const CircuitPortId& circuit_port_id, const std::string& port_prefix) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_prefix_[model_id][circuit_port_id] = port_prefix; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_prefix_[circuit_port_id] = port_prefix; return; } /* Set the lib_name for a port of a circuit model */ -void CircuitLibrary::set_port_lib_name(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_lib_name(const CircuitPortId& circuit_port_id, const std::string& lib_name) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_lib_names_[model_id][circuit_port_id] = lib_name; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_lib_names_[circuit_port_id] = lib_name; return; } /* Set the inv_prefix for a port of a circuit model */ -void CircuitLibrary::set_port_inv_prefix(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_inv_prefix(const CircuitPortId& circuit_port_id, const std::string& inv_prefix) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_inv_prefix_[model_id][circuit_port_id] = inv_prefix; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_inv_prefix_[circuit_port_id] = inv_prefix; return; } /* Set the default value for a port of a circuit model */ -void CircuitLibrary::set_port_default_value(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_default_value(const CircuitPortId& circuit_port_id, const size_t& default_value) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_default_values_[model_id][circuit_port_id] = default_value; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_default_values_[circuit_port_id] = default_value; return; } /* Set the is_mode_select for a port of a circuit model */ -void CircuitLibrary::set_port_is_mode_select(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_is_mode_select(const CircuitPortId& circuit_port_id, const bool& is_mode_select) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_is_mode_select_[model_id][circuit_port_id] = is_mode_select; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_is_mode_select_[circuit_port_id] = is_mode_select; return; } /* Set the is_global for a port of a circuit model */ -void CircuitLibrary::set_port_is_global(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_is_global(const CircuitPortId& circuit_port_id, const bool& is_global) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_is_global_[model_id][circuit_port_id] = is_global; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_is_global_[circuit_port_id] = is_global; return; } /* Set the is_reset for a port of a circuit model */ -void CircuitLibrary::set_port_is_reset(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_is_reset(const CircuitPortId& circuit_port_id, const bool& is_reset) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_is_reset_[model_id][circuit_port_id] = is_reset; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_is_reset_[circuit_port_id] = is_reset; return; } /* Set the is_set for a port of a circuit model */ -void CircuitLibrary::set_port_is_set(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_is_set(const CircuitPortId& circuit_port_id, const bool& is_set) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_is_set_[model_id][circuit_port_id] = is_set; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_is_set_[circuit_port_id] = is_set; return; } /* Set the is_config_enable for a port of a circuit model */ -void CircuitLibrary::set_port_is_config_enable(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_is_config_enable(const CircuitPortId& circuit_port_id, const bool& is_config_enable) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_is_config_enable_[model_id][circuit_port_id] = is_config_enable; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_is_config_enable_[circuit_port_id] = is_config_enable; return; } /* Set the is_prog for a port of a circuit model */ -void CircuitLibrary::set_port_is_prog(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_is_prog(const CircuitPortId& circuit_port_id, const bool& is_prog) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_is_prog_[model_id][circuit_port_id] = is_prog; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_is_prog_[circuit_port_id] = is_prog; return; } /* Set the model_name for a port of a circuit model */ -void CircuitLibrary::set_port_model_name(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const std::string& model_name) { +void CircuitLibrary::set_port_tri_state_model_name(const CircuitPortId& circuit_port_id, + const std::string& model_name) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_model_names_[model_id][circuit_port_id] = model_name; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_tri_state_model_names_[circuit_port_id] = model_name; return; } /* Set the model_id for a port of a circuit model */ -void CircuitLibrary::set_port_model_id(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const CircuitModelId& port_model_id) { +void CircuitLibrary::set_port_tri_state_model_id(const CircuitPortId& circuit_port_id, + const CircuitModelId& port_model_id) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_model_ids_[model_id][circuit_port_id] = port_model_id; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_tri_state_model_ids_[circuit_port_id] = port_model_id; return; } /* Set the inv_model_name for a port of a circuit model */ -void CircuitLibrary::set_port_inv_model_name(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const std::string& inv_model_name) { +void CircuitLibrary::set_port_inv_model_name(const CircuitPortId& circuit_port_id, + const std::string& inv_model_name) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_inv_model_names_[model_id][circuit_port_id] = inv_model_name; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_inv_model_names_[circuit_port_id] = inv_model_name; return; } /* Set the inv_model_id for a port of a circuit model */ -void CircuitLibrary::set_port_inv_model_id(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const CircuitModelId& inv_model_id) { +void CircuitLibrary::set_port_inv_model_id(const CircuitPortId& circuit_port_id, + const CircuitModelId& inv_model_id) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_inv_model_ids_[model_id][circuit_port_id] = inv_model_id; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_inv_model_ids_[circuit_port_id] = inv_model_id; return; } /* Set the tri-state map for a port of a circuit model */ -void CircuitLibrary::set_port_tri_state_map(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_tri_state_map(const CircuitPortId& circuit_port_id, const std::string& tri_state_map) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - port_tri_state_maps_[model_id][circuit_port_id] = tri_state_map; + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + port_tri_state_maps_[circuit_port_id] = tri_state_map; return; } /* Set the LUT fracturable level for a port of a circuit model, only applicable to LUTs */ -void CircuitLibrary::set_port_lut_frac_level(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_lut_frac_level(const CircuitPortId& circuit_port_id, const size_t& lut_frac_level) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); /* Make sure this is a LUT */ - VTR_ASSERT(SPICE_MODEL_LUT == model_type(model_id)); - port_lut_frac_level_[model_id][circuit_port_id] = lut_frac_level; + VTR_ASSERT(SPICE_MODEL_LUT == model_type(port_model_ids_[circuit_port_id])); + port_lut_frac_level_[circuit_port_id] = lut_frac_level; return; } /* Set the LUT fracturable level for a port of a circuit model, only applicable to LUTs */ -void CircuitLibrary::set_port_lut_output_mask(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_lut_output_mask(const CircuitPortId& circuit_port_id, const std::vector& lut_output_masks) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); /* Make sure this is a LUT */ - VTR_ASSERT(SPICE_MODEL_LUT == model_type(model_id)); - port_lut_output_masks_[model_id][circuit_port_id] = lut_output_masks; + VTR_ASSERT(SPICE_MODEL_LUT == model_type(port_model_ids_[circuit_port_id])); + port_lut_output_masks_[circuit_port_id] = lut_output_masks; return; } /* Set the SRAM organization for a port of a circuit model, only applicable to SRAM ports */ -void CircuitLibrary::set_port_sram_orgz(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, +void CircuitLibrary::set_port_sram_orgz(const CircuitPortId& circuit_port_id, const enum e_sram_orgz& sram_orgz) { /* validate the circuit_port_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); /* Make sure this is a SRAM port */ - VTR_ASSERT(SPICE_MODEL_PORT_SRAM == port_type(model_id, circuit_port_id)); - port_sram_orgz_[model_id][circuit_port_id] = sram_orgz; + VTR_ASSERT(SPICE_MODEL_PORT_SRAM == port_type(circuit_port_id)); + port_sram_orgz_[circuit_port_id] = sram_orgz; return; } @@ -1383,7 +1363,7 @@ void CircuitLibrary::set_wire_num_levels(const CircuitModelId& model_id, * If no, resize the vector and then assign values */ void CircuitLibrary::set_model_buffer(const CircuitModelId& model_id, const enum e_buffer_type buffer_type, - const bool& existence, const std::string& model_name) { + const bool& existence, const std::string& model_name) { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); /* Check the range of vector */ @@ -1405,16 +1385,14 @@ void CircuitLibrary::set_model_buffer(const CircuitModelId& model_id, const enum * We search the inv_model_name in the CircuitLibrary and * configure the port inv_model_id */ -void CircuitLibrary::link_port_model(const CircuitModelId& model_id) { - /* validate the model_id */ - VTR_ASSERT(valid_model_id(model_id)); +void CircuitLibrary::link_port_tri_state_model() { /* Walk through each ports, get the port id and find the circuit model id by name */ - for (auto& port_id : ports(model_id)) { + for (auto& port_id : ports()) { /* Bypass empty name */ - if (true == port_model_names_[model_id][port_id].empty()) { + if (true == port_tri_state_model_names_[port_id].empty()) { continue; } - port_model_ids_[model_id][port_id] = model(port_model_names_[model_id][port_id]); + port_tri_state_model_ids_[port_id] = model(port_tri_state_model_names_[port_id]); } return; } @@ -1423,27 +1401,18 @@ void CircuitLibrary::link_port_model(const CircuitModelId& model_id) { * We search the inv_model_name in the CircuitLibrary and * configure the port inv_model_id */ -void CircuitLibrary::link_port_inv_model(const CircuitModelId& model_id) { - /* validate the model_id */ - VTR_ASSERT(valid_model_id(model_id)); +void CircuitLibrary::link_port_inv_model() { /* Walk through each ports, get the port id and find the circuit model id by name */ - for (auto& port_id : ports(model_id)) { + for (auto& port_id : ports()) { /* Bypass empty name */ - if (true == port_inv_model_names_[model_id][port_id].empty()) { + if (true == port_inv_model_names_[port_id].empty()) { continue; } - port_inv_model_ids_[model_id][port_id] = model(port_inv_model_names_[model_id][port_id]); + port_inv_model_ids_[port_id] = model(port_inv_model_names_[port_id]); } return; } -/* Link all the circuit model ids for each port of a circuit model */ -void CircuitLibrary::link_port_models(const CircuitModelId& model_id) { - link_port_model(model_id); - link_port_inv_model(model_id); - return; -} - /* Link the buffer_model * We search the buffer_model_name in the CircuitLibrary and * configure the buffer_model_id @@ -1476,36 +1445,26 @@ void CircuitLibrary::link_pass_gate_logic_model(const CircuitModelId& model_id) return; } -/* Build the links for attributes of each model by searching the model_names */ -void CircuitLibrary::build_model_links() { - /* Walk through each circuit model, build links one by one */ - for (auto& model_id : models()) { - /* Build links for buffers, pass-gates model */ - link_buffer_model(model_id); - link_pass_gate_logic_model(model_id); - /* Build links for ports */ - link_port_models(model_id); - } - return; -} - /* Build the timing graph for a circuit models*/ void CircuitLibrary::build_model_timing_graph(const CircuitModelId& model_id) { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + /* Now we start allocating a timing graph * Add outgoing edges for each input pin of the circuit model */ - for (auto& from_port_id : input_ports(model_id)) { + for (const auto& from_port_id : model_input_ports(model_id)) { /* Add edges for each input pin */ - for (auto& from_pin_id : pins(model_id, from_port_id)) { + for (const auto& from_pin_id : pins(from_port_id)) { /* We should walk through output pins here */ - for (auto& to_port_id : output_ports(model_id)) { - for (auto& to_pin_id : pins(model_id, to_port_id)) { + for (const auto& to_port_id : model_output_ports(model_id)) { + for (const auto& to_pin_id : pins(to_port_id)) { /* Skip self-loops */ if (from_port_id == to_port_id) { continue; } /* Add an edge to bridge the from_pin_id and to_pin_id */ - add_edge(model_id, from_port_id, from_pin_id, to_port_id, to_pin_id); + add_edge(from_port_id, from_pin_id, to_port_id, to_pin_id); } } } @@ -1513,12 +1472,29 @@ void CircuitLibrary::build_model_timing_graph(const CircuitModelId& model_id) { return; } +/************************************************************************ + * Public Mutators: builders and linkers + ***********************************************************************/ +/* Build the links for attributes of each model by searching the model_names */ +void CircuitLibrary::build_model_links() { + /* Walk through each circuit model, build links one by one */ + for (auto& model_id : models()) { + /* Build links for buffers, pass-gates model */ + link_buffer_model(model_id); + link_pass_gate_logic_model(model_id); + } + /* Build links for ports */ + link_port_tri_state_model(); + link_port_inv_model(); + return; +} + /* Build the timing graph for a circuit models*/ void CircuitLibrary::build_timing_graphs() { + /* Free the timing graph if it already exists, we will rebuild one */ + invalidate_model_timing_graph(); /* Walk through each circuit model, build timing graph one by one */ for (auto& model_id : models()) { - /* Free the timing graph if it already exists, we will rebuild one */ - invalidate_model_timing_graph(model_id); build_model_timing_graph(model_id); /* Annotate timing information */ set_timing_graph_delays(model_id); @@ -1530,44 +1506,40 @@ void CircuitLibrary::build_timing_graphs() { * Internal mutators: build timing graphs ***********************************************************************/ /* Add an edge between two pins of two ports, and assign an default timing value */ -void CircuitLibrary::add_edge(const CircuitModelId& model_id, - const CircuitPortId& from_port, const size_t& from_pin, +void CircuitLibrary::add_edge(const CircuitPortId& from_port, const size_t& from_pin, const CircuitPortId& to_port, const size_t& to_pin) { - /* validate the model_id */ - VTR_ASSERT(valid_model_id(model_id)); - /* Create an edge in the edge id list */ - CircuitEdgeId edge_id = CircuitEdgeId(edge_ids_[model_id].size()); + CircuitEdgeId edge_id = CircuitEdgeId(edge_ids_.size()); /* Expand the edge list */ - edge_ids_[model_id].push_back(edge_id); + edge_ids_.push_back(edge_id); /* Initialize other attributes */ /* Update the list of incoming edges for to_port */ /* Resize upon need */ - if (to_pin >= port_in_edge_ids_[model_id][to_port].size()) { - port_in_edge_ids_[model_id][to_port].resize(to_pin + 1); + if (to_pin >= port_in_edge_ids_[to_port].size()) { + port_in_edge_ids_[to_port].resize(to_pin + 1); } - port_in_edge_ids_[model_id][to_port][to_pin] = edge_id; + port_in_edge_ids_[to_port][to_pin] = edge_id; /* Update the list of outgoing edges for from_port */ /* Resize upon need */ - if (from_pin >= port_out_edge_ids_[model_id][from_port].size()) { - port_out_edge_ids_[model_id][from_port].resize(from_pin + 1); + if (from_pin >= port_out_edge_ids_[from_port].size()) { + port_out_edge_ids_[from_port].resize(from_pin + 1); } - port_out_edge_ids_[model_id][from_port][from_pin] = edge_id; + port_out_edge_ids_[from_port][from_pin] = edge_id; /* Update source ports and pins of the edge */ - edge_src_port_ids_[model_id].push_back(from_port); - edge_src_pin_ids_[model_id].push_back(from_pin); + edge_src_port_ids_.push_back(from_port); + edge_src_pin_ids_.push_back(from_pin); /* Update sink ports and pins of the edge */ - edge_sink_port_ids_[model_id].push_back(to_port); - edge_sink_pin_ids_[model_id].push_back(to_pin); + edge_sink_port_ids_.push_back(to_port); + edge_sink_pin_ids_.push_back(to_pin); /* Give a default value for timing values */ std::vector timing_info(NUM_CIRCUIT_MODEL_DELAY_TYPES, 0); - edge_timing_info_[model_id].push_back(timing_info); + edge_timing_info_.push_back(timing_info); return; } @@ -1577,10 +1549,10 @@ void CircuitLibrary::set_edge_delay(const CircuitModelId& model_id, const enum spice_model_delay_type& delay_type, const float& delay_value) { /* validate the circuit_edge_id */ - VTR_ASSERT(valid_circuit_edge_id(model_id, circuit_edge_id)); + VTR_ASSERT(valid_circuit_edge_id(circuit_edge_id)); VTR_ASSERT(valid_delay_type(model_id, delay_type)); - edge_timing_info_[model_id][circuit_edge_id][size_t(delay_type)] = delay_value; + edge_timing_info_[circuit_edge_id][size_t(delay_type)] = delay_value; return; } @@ -1604,22 +1576,22 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& model_id) { /* Check each element */ for (auto& port_info : input_ports) { /* Try to find a port by the given name */ - CircuitPortId port_id = port(model_id, port_info.get_name()); + CircuitPortId port_id = model_port(model_id, port_info.get_name()); /* We must have a valid port and Port width must be 1! */ VTR_ASSERT(CircuitPortId::INVALID() != port_id); if (0 == port_info.get_width()) { /* we need to configure the port width if it is zero. * This means that parser find some compact port defintion such as */ - size_t port_width = port_size(model_id, port_id); + size_t port_width = port_size(port_id); port_info.set_width(port_width); } else { VTR_ASSERT(1 == port_info.get_width()); } /* The pin id should be valid! */ - VTR_ASSERT(true == valid_circuit_pin_id(model_id, port_id, port_info.get_lsb())); + VTR_ASSERT(true == valid_circuit_pin_id(port_id, port_info.get_lsb())); /* This must be an input port! */ - VTR_ASSERT(true == is_input_port(model_id, port_id)); + VTR_ASSERT(true == is_input_port(port_id)); /* Push to */ input_port_ids.push_back(port_id); input_pin_ids.push_back(port_info.get_lsb()); @@ -1633,22 +1605,22 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& model_id) { /* Check each element */ for (auto& port_info : output_ports) { /* Try to find a port by the given name */ - CircuitPortId port_id = port(model_id, port_info.get_name()); + CircuitPortId port_id = model_port(model_id, port_info.get_name()); /* We must have a valid port and Port width must be 1! */ VTR_ASSERT(CircuitPortId::INVALID() != port_id); if (0 == port_info.get_width()) { /* we need to configure the port width if it is zero. * This means that parser find some compact port defintion such as */ - size_t port_width = port_size(model_id, port_id); + size_t port_width = port_size(port_id); port_info.set_width(port_width); } else { VTR_ASSERT(1 == port_info.get_width()); } /* The pin id should be valid! */ - VTR_ASSERT(true == valid_circuit_pin_id(model_id, port_id, port_info.get_lsb())); + VTR_ASSERT(true == valid_circuit_pin_id(port_id, port_info.get_lsb())); /* This must be an output port! */ - VTR_ASSERT(true == is_output_port(model_id, port_id)); + VTR_ASSERT(true == is_output_port(port_id)); /* Push to */ output_port_ids.push_back(port_id); output_pin_ids.push_back(port_info.get_lsb()); @@ -1667,11 +1639,10 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& model_id) { for (size_t i = 0; i < port_delay_parser.height(); ++i) { for (size_t j = 0; j < port_delay_parser.width(); ++j) { float delay_value = port_delay_parser.delay(i, j); - CircuitEdgeId edge_id = edge(model_id, - input_port_ids[j], input_pin_ids[j], + CircuitEdgeId edge_id = edge(input_port_ids[j], input_pin_ids[j], output_port_ids[i], output_pin_ids[i]); /* make sure we have an valid edge_id */ - VTR_ASSERT(true == valid_circuit_edge_id(model_id, edge_id)); + VTR_ASSERT(true == valid_circuit_edge_id(edge_id)); set_edge_delay(model_id, edge_id, delay_type, delay_value); } @@ -1717,14 +1688,19 @@ void CircuitLibrary::build_model_lookup() { } /* Build fast look-up for circuit model ports */ -void CircuitLibrary::build_model_port_lookup(const CircuitModelId& model_id) { +void CircuitLibrary::build_model_port_lookup() { + /* For all the ports in the list, categorize by model_id and port_type */ /* invalidate fast look-up */ - invalidate_model_port_lookup(model_id); + invalidate_model_port_lookup(); /* Classify circuit models by type */ - model_port_lookup_[size_t(model_id)].resize(NUM_CIRCUIT_MODEL_PORT_TYPES); + model_port_lookup_.resize(model_ids_.size()); + for (const auto& model_id : model_ids_) { + model_port_lookup_[model_id].resize(NUM_CIRCUIT_MODEL_PORT_TYPES); + } /* Walk through models and categorize */ - for (auto& port_id : port_ids_[model_id]) { - model_port_lookup_[size_t(model_id)][port_type(model_id, port_id)].push_back(port_id); + for (const auto& port : port_ids_) { + CircuitModelId model_id = port_model_ids_[port]; + model_port_lookup_[model_id][port_type(port)].push_back(port); } return; } @@ -1737,16 +1713,14 @@ bool CircuitLibrary::valid_model_id(const CircuitModelId& model_id) const { return ( size_t(model_id) < model_ids_.size() ) && ( model_id == model_ids_[model_id] ); } -bool CircuitLibrary::valid_circuit_port_id(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const { - /* validate the model_id */ - VTR_ASSERT(valid_model_id(model_id)); - return ( size_t(circuit_port_id) < port_ids_[model_id].size() ) && ( circuit_port_id == port_ids_[model_id][circuit_port_id] ); +bool CircuitLibrary::valid_circuit_port_id(const CircuitPortId& circuit_port_id) const { + return ( size_t(circuit_port_id) < port_ids_.size() ) && ( circuit_port_id == port_ids_[circuit_port_id] ); } -bool CircuitLibrary::valid_circuit_pin_id(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id, const size_t& pin_id) const { +bool CircuitLibrary::valid_circuit_pin_id(const CircuitPortId& circuit_port_id, const size_t& pin_id) const { /* validate the model_id */ - VTR_ASSERT(valid_circuit_port_id(model_id, circuit_port_id)); - return ( size_t(pin_id) < port_size(model_id, circuit_port_id) ); + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return ( size_t(pin_id) < port_size(circuit_port_id) ); } bool CircuitLibrary::valid_delay_type(const CircuitModelId& model_id, const enum spice_model_delay_type& delay_type) const { @@ -1755,10 +1729,8 @@ bool CircuitLibrary::valid_delay_type(const CircuitModelId& model_id, const enum return ( size_t(delay_type) < delay_types_[model_id].size() ) && ( delay_type == delay_types_[model_id][size_t(delay_type)] ); } -bool CircuitLibrary::valid_circuit_edge_id(const CircuitModelId& model_id, const CircuitEdgeId& circuit_edge_id) const { - /* validate the model_id */ - VTR_ASSERT(valid_model_id(model_id)); - return ( size_t(circuit_edge_id) < edge_ids_[model_id].size() ) && ( circuit_edge_id == edge_ids_[model_id][circuit_edge_id] ); +bool CircuitLibrary::valid_circuit_edge_id(const CircuitEdgeId& circuit_edge_id) const { + return ( size_t(circuit_edge_id) < edge_ids_.size() ) && ( circuit_edge_id == edge_ids_[circuit_edge_id] ); } /* Validate the value of constant input @@ -1781,31 +1753,27 @@ void CircuitLibrary::invalidate_model_lookup() const { } /* Empty fast lookup for circuit ports for a model */ -void CircuitLibrary::invalidate_model_port_lookup(const CircuitModelId& model_id) const { - /* validate the model_id */ - VTR_ASSERT(valid_model_id(model_id)); - model_port_lookup_[size_t(model_id)].clear(); +void CircuitLibrary::invalidate_model_port_lookup() const { + model_port_lookup_.clear(); return; } /* Clear all the data structure related to the timing graph */ -void CircuitLibrary::invalidate_model_timing_graph(const CircuitModelId& model_id) { - /* validate the model_id */ - VTR_ASSERT(valid_model_id(model_id)); - edge_ids_[model_id].clear(); +void CircuitLibrary::invalidate_model_timing_graph() { + edge_ids_.clear(); - for (const auto& port_id : ports(model_id)) { - port_in_edge_ids_[model_id][port_id].clear(); - port_out_edge_ids_[model_id][port_id].clear(); + for (const auto& port_id : ports()) { + port_in_edge_ids_[port_id].clear(); + port_out_edge_ids_[port_id].clear(); } - edge_src_port_ids_[model_id].clear(); - edge_src_pin_ids_[model_id].clear(); + edge_src_port_ids_.clear(); + edge_src_pin_ids_.clear(); - edge_sink_port_ids_[model_id].clear(); - edge_sink_pin_ids_[model_id].clear(); + edge_sink_port_ids_.clear(); + edge_sink_pin_ids_.clear(); - edge_timing_info_[model_id].clear(); + edge_timing_info_.clear(); return; } diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.h b/vpr7_x2p/libarchfpga/SRC/circuit_library.h index a74429347..72172bf30 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.h @@ -102,6 +102,7 @@ * * ------ Port information ------ * 1. port_ids_: unique id of ports belonging to a circuit model + * 1. port_model_ids_: unique id of the parent circuit model for the port * 2. port_types_: types of ports belonging to a circuit model * 3. port_sizes_: width of ports belonging to a circuit model * 4. port_prefix_: prefix of a port when instance of a circuit model @@ -113,8 +114,8 @@ * 10. port_is_set: specify if this port is a set signal which needs special pulse widths in testbenches * 11. port_is_config_enable: specify if this port is a config_enable signal which needs special pulse widths in testbenches * 12. port_is_prog: specify if this port is for FPGA programming use which needs special pulse widths in testbenches - * 13. port_model_name: the name of circuit model linked to the port - * 14. port_model_ids_: the Id of circuit model linked to the port + * 13. port_tri_state_model_name: the name of circuit model linked to tri-state the port + * 14. port_tri_state_model_ids_: the Id of circuit model linked to tri-state the port * 15. port_inv_model_names_: the name of inverter circuit model linked to the port * 16. port_inv_model_ids_: the Id of inverter circuit model linked to the port * 17. port_tri_state_map_: only applicable to inputs of LUTs, the tri-state map applied to each pin of this port @@ -187,12 +188,12 @@ ***********************************************************************/ class CircuitLibrary { public: /* Types */ - typedef vtr::vector::const_iterator model_iterator; - typedef vtr::vector::const_iterator model_string_iterator; + typedef vtr::vector::const_iterator circuit_model_iterator; + typedef vtr::vector::const_iterator circuit_model_string_iterator; typedef vtr::vector::const_iterator circuit_port_iterator; typedef vtr::vector::const_iterator circuit_edge_iterator; /* Create range */ - typedef vtr::Range model_range; + typedef vtr::Range circuit_model_range; typedef vtr::Range circuit_port_range; typedef vtr::Range circuit_edge_range; /* local enumeration for buffer existence */ @@ -202,14 +203,9 @@ class CircuitLibrary { public: /* Constructors */ CircuitLibrary(); public: /* Accessors: aggregates */ - model_range models() const; - circuit_port_range ports(const CircuitModelId& model_id) const; + circuit_model_range models() const; + circuit_port_range ports() const; std::vector models_by_type(const enum e_spice_model_type& type) const; - std::vector ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type) const; - std::vector ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const; - std::vector input_ports(const CircuitModelId& model_id) const; - std::vector output_ports(const CircuitModelId& model_id) const; - std::vector pins(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; public: /* Public Accessors: Basic data query on Circuit Models*/ size_t num_models() const; enum e_spice_model_type model_type(const CircuitModelId& model_id) const; @@ -225,41 +221,48 @@ class CircuitLibrary { bool is_input_buffered(const CircuitModelId& model_id) const; bool is_output_buffered(const CircuitModelId& model_id) const; bool is_lut_intermediate_buffered(const CircuitModelId& model_id) const; - enum e_spice_model_pass_gate_logic_type pass_gate_logic_type(const CircuitModelId& model_id) const; + CircuitModelId pass_gate_logic_model(const CircuitModelId& model_id) const; enum e_spice_model_structure mux_structure(const CircuitModelId& model_id) const; size_t mux_num_levels(const CircuitModelId& model_id) const; bool mux_add_const_input(const CircuitModelId& model_id) const; size_t mux_const_input_value(const CircuitModelId& model_id) const; + enum e_spice_model_gate_type gate_type(const CircuitModelId& model_id) const; + public: /* Public Accessors: Basic data query on cirucit models' Circuit Ports*/ + CircuitPortId model_port(const CircuitModelId& model_id, const std::string& name) const; + 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_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; + std::vector model_output_ports(const CircuitModelId& model_id) const; + std::vector pins(const CircuitPortId& circuit_port_id) const; public: /* Public Accessors: Basic data query on Circuit Ports*/ - bool is_input_port(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - bool is_output_port(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - CircuitPortId port(const CircuitModelId& model_id, const std::string& name) const; - size_t num_ports(const CircuitModelId& model_id) const; - size_t num_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const; - enum e_spice_model_port_type port_type(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - size_t port_size(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - std::string port_prefix(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - std::string port_lib_name(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - std::string port_inv_prefix(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - size_t port_default_value(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - bool port_is_mode_select(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - bool port_is_global(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - bool port_is_reset(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - bool port_is_set(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - bool port_is_config_enable(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - bool port_is_prog(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; + bool is_input_port(const CircuitPortId& circuit_port_id) const; + bool is_output_port(const CircuitPortId& circuit_port_id) const; + enum e_spice_model_port_type port_type(const CircuitPortId& circuit_port_id) const; + size_t port_size(const CircuitPortId& circuit_port_id) const; + std::string port_prefix(const CircuitPortId& circuit_port_id) const; + std::string port_lib_name(const CircuitPortId& circuit_port_id) const; + std::string port_inv_prefix(const CircuitPortId& circuit_port_id) const; + size_t port_default_value(const CircuitPortId& circuit_port_id) const; + bool port_is_mode_select(const CircuitPortId& circuit_port_id) const; + bool port_is_global(const CircuitPortId& circuit_port_id) const; + bool port_is_reset(const CircuitPortId& circuit_port_id) const; + 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; public: /* Public Accessors: Methods to find circuit model */ CircuitModelId model(const char* name) const; CircuitModelId model(const std::string& name) const; CircuitModelId default_model(const enum e_spice_model_type& type) const; public: /* Public Accessors: Timing graph */ - CircuitEdgeId edge(const CircuitModelId& model_id, - const CircuitPortId& from_port, const size_t from_pin, + CircuitEdgeId edge(const CircuitPortId& from_port, const size_t from_pin, const CircuitPortId& to_port, const size_t to_pin); public: /* Public Mutators */ - CircuitModelId add_model(); + CircuitModelId add_model(const enum e_spice_model_type& type); /* Fundamental information */ - void set_model_type(const CircuitModelId& model_id, const enum e_spice_model_type& type); void set_model_name(const CircuitModelId& model_id, const std::string& name); void set_model_prefix(const CircuitModelId& model_id, const std::string& prefix); void set_model_verilog_netlist(const CircuitModelId& model_id, const std::string& verilog_netlist); @@ -273,80 +276,59 @@ class CircuitLibrary { void set_model_is_power_gated(const CircuitModelId& model_id, const bool& is_power_gated); /* Buffer existence */ void set_model_input_buffer(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name); + const bool& existence, const std::string& model_name); void set_model_output_buffer(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name); + const bool& existence, const std::string& model_name); void set_model_lut_input_buffer(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name); + const bool& existence, const std::string& model_name); void set_model_lut_input_inverter(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name); + const bool& existence, const std::string& model_name); void set_model_lut_intermediate_buffer(const CircuitModelId& model_id, - const bool& existence, const std::string& model_name); + const bool& existence, const std::string& model_name); void set_model_lut_intermediate_buffer_location_map(const CircuitModelId& model_id, - const std::string& location_map); + const std::string& location_map); /* Pass-gate-related parameters */ void set_model_pass_gate_logic(const CircuitModelId& model_id, const std::string& model_name); /* Port information */ - CircuitPortId add_model_port(const CircuitModelId& model_id); - void set_port_type(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const enum e_spice_model_port_type& port_type); - void set_port_size(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + CircuitPortId add_model_port(const CircuitModelId& model_id, + const enum e_spice_model_port_type& port_type); + void set_port_size(const CircuitPortId& circuit_port_id, const size_t& port_size); - void set_port_prefix(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_prefix(const CircuitPortId& circuit_port_id, const std::string& port_prefix); - void set_port_lib_name(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_lib_name(const CircuitPortId& circuit_port_id, const std::string& lib_name); - void set_port_inv_prefix(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_inv_prefix(const CircuitPortId& circuit_port_id, const std::string& inv_prefix); - void set_port_default_value(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_default_value(const CircuitPortId& circuit_port_id, const size_t& default_val); - void set_port_is_mode_select(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_is_mode_select(const CircuitPortId& circuit_port_id, const bool& is_mode_select); - void set_port_is_global(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_is_global(const CircuitPortId& circuit_port_id, const bool& is_global); - void set_port_is_reset(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_is_reset(const CircuitPortId& circuit_port_id, const bool& is_reset); - void set_port_is_set(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_is_set(const CircuitPortId& circuit_port_id, const bool& is_set); - void set_port_is_config_enable(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_is_config_enable(const CircuitPortId& circuit_port_id, const bool& is_config_enable); - void set_port_is_prog(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_is_prog(const CircuitPortId& circuit_port_id, const bool& is_prog); - void set_port_model_name(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const std::string& model_name); - void set_port_model_id(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const CircuitModelId& port_model_id); - void set_port_inv_model_name(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const std::string& inv_model_name); - void set_port_inv_model_id(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, - const CircuitModelId& inv_model_id); - void set_port_tri_state_map(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_tri_state_model_name(const CircuitPortId& circuit_port_id, + const std::string& model_name); + void set_port_tri_state_model_id(const CircuitPortId& circuit_port_id, + const CircuitModelId& port_model_id); + void set_port_inv_model_name(const CircuitPortId& circuit_port_id, + const std::string& inv_model_name); + void set_port_inv_model_id(const CircuitPortId& circuit_port_id, + const CircuitModelId& inv_model_id); + void set_port_tri_state_map(const CircuitPortId& circuit_port_id, const std::string& tri_state_map); - void set_port_lut_frac_level(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_lut_frac_level(const CircuitPortId& circuit_port_id, const size_t& lut_frac_level); - void set_port_lut_output_mask(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_lut_output_mask(const CircuitPortId& circuit_port_id, const std::vector& lut_output_masks); - void set_port_sram_orgz(const CircuitModelId& model_id, - const CircuitPortId& circuit_port_id, + void set_port_sram_orgz(const CircuitPortId& circuit_port_id, const enum e_sram_orgz& sram_orgz); /* Delay information */ void add_delay_info(const CircuitModelId& model_id, @@ -415,19 +397,18 @@ class CircuitLibrary { const float& c_val); void set_wire_num_levels(const CircuitModelId& model_id, const size_t& num_level); - public: /* Public Mutators: builders */ + private: /* Private Mutators: builders */ void set_model_buffer(const CircuitModelId& model_id, const enum e_buffer_type buffer_type, const bool& existence, const std::string& model_name); - void link_port_model(const CircuitModelId& model_id); - void link_port_inv_model(const CircuitModelId& model_id); - void link_port_models(const CircuitModelId& model_id); + void link_port_tri_state_model(); + void link_port_inv_model(); void link_buffer_model(const CircuitModelId& model_id); void link_pass_gate_logic_model(const CircuitModelId& model_id); - void build_model_links(); void build_model_timing_graph(const CircuitModelId& model_id); + public: /* Public Mutators: builders */ + void build_model_links(); void build_timing_graphs(); public: /* Internal mutators: build timing graphs */ - void add_edge(const CircuitModelId& model_id, - const CircuitPortId& from_port, const size_t& from_pin, + void add_edge(const CircuitPortId& from_port, const size_t& from_pin, const CircuitPortId& to_port, const size_t& to_pin); void set_edge_delay(const CircuitModelId& model_id, const CircuitEdgeId& circuit_edge_id, @@ -437,19 +418,19 @@ class CircuitLibrary { void set_timing_graph_delays(const CircuitModelId& model_id); public: /* Internal mutators: build fast look-ups */ void build_model_lookup(); - void build_model_port_lookup(const CircuitModelId& model_id); + void build_model_port_lookup(); private: /* Internal invalidators/validators */ /* Validators */ bool valid_model_id(const CircuitModelId& model_id) const; - bool valid_circuit_port_id(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; - bool valid_circuit_pin_id(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id, const size_t& pin_id) const; + bool valid_circuit_port_id(const CircuitPortId& circuit_port_id) const; + bool valid_circuit_pin_id(const CircuitPortId& circuit_port_id, const size_t& pin_id) const; bool valid_delay_type(const CircuitModelId& model_id, const enum spice_model_delay_type& delay_type) const; - bool valid_circuit_edge_id(const CircuitModelId& model_id, const CircuitEdgeId& circuit_edge_id) const; + bool valid_circuit_edge_id(const CircuitEdgeId& circuit_edge_id) const; bool valid_mux_const_input_value(const size_t& const_input_value) const; /* Invalidators */ void invalidate_model_lookup() const; - void invalidate_model_port_lookup(const CircuitModelId& model_id) const; - void invalidate_model_timing_graph(const CircuitModelId& model_id); + void invalidate_model_port_lookup() const; + void invalidate_model_timing_graph(); private: /* Internal data */ /* Fundamental information */ vtr::vector model_ids_; @@ -466,7 +447,7 @@ class CircuitLibrary { */ typedef std::vector> CircuitModelLookup; mutable CircuitModelLookup model_lookup_; /* [model_type][model_ids] */ - typedef std::vector>> CircuitModelPortLookup; + typedef vtr::vector>> CircuitModelPortLookup; mutable CircuitModelPortLookup model_port_lookup_; /* [model_id][port_type][port_ids] */ /* Verilog generator options */ @@ -488,37 +469,38 @@ class CircuitLibrary { vtr::vector pass_gate_logic_model_ids_; /* Port information */ - vtr::vector> port_ids_; - vtr::vector> port_types_; - vtr::vector> port_sizes_; - vtr::vector> port_prefix_; - vtr::vector> port_lib_names_; - vtr::vector> port_inv_prefix_; - vtr::vector> port_default_values_; - vtr::vector> port_is_mode_select_; - vtr::vector> port_is_global_; - vtr::vector> port_is_reset_; - vtr::vector> port_is_set_; - vtr::vector> port_is_config_enable_; - vtr::vector> port_is_prog_; - vtr::vector> port_model_names_; - vtr::vector> port_model_ids_; - vtr::vector> port_inv_model_names_; - vtr::vector> port_inv_model_ids_; - vtr::vector> port_tri_state_maps_; - vtr::vector> port_lut_frac_level_; - vtr::vector>> port_lut_output_masks_; - vtr::vector> port_sram_orgz_; + vtr::vector port_ids_; + vtr::vector port_model_ids_; + vtr::vector port_types_; + vtr::vector port_sizes_; + vtr::vector port_prefix_; + vtr::vector port_lib_names_; + vtr::vector port_inv_prefix_; + vtr::vector port_default_values_; + vtr::vector port_is_mode_select_; + vtr::vector port_is_global_; + vtr::vector port_is_reset_; + vtr::vector port_is_set_; + vtr::vector port_is_config_enable_; + vtr::vector port_is_prog_; + vtr::vector port_tri_state_model_names_; + vtr::vector port_tri_state_model_ids_; + vtr::vector port_inv_model_names_; + vtr::vector port_inv_model_ids_; + vtr::vector port_tri_state_maps_; + vtr::vector port_lut_frac_level_; + vtr::vector> port_lut_output_masks_; + vtr::vector port_sram_orgz_; /* Timing graphs */ - vtr::vector> edge_ids_; - vtr::vector>> port_in_edge_ids_; - vtr::vector>> port_out_edge_ids_; - vtr::vector> edge_src_port_ids_; - vtr::vector> edge_src_pin_ids_; - vtr::vector> edge_sink_port_ids_; - vtr::vector> edge_sink_pin_ids_; - vtr::vector>> edge_timing_info_; /* x0 => trise, x1 => tfall */ + vtr::vector edge_ids_; + vtr::vector> port_in_edge_ids_; + vtr::vector> port_out_edge_ids_; + vtr::vector edge_src_port_ids_; + vtr::vector edge_src_pin_ids_; + vtr::vector edge_sink_port_ids_; + vtr::vector edge_sink_pin_ids_; + vtr::vector> edge_timing_info_; /* x0 => trise, x1 => tfall */ /* Delay information */ vtr::vector> delay_types_; diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library_fwd.h b/vpr7_x2p/libarchfpga/SRC/circuit_library_fwd.h index 522fbbfcc..cef4fc4a0 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library_fwd.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library_fwd.h @@ -7,6 +7,9 @@ /************************************************************************ * Create strong id for Circuit Models/Ports to avoid illegal type casting ***********************************************************************/ +#ifndef CIRCUIT_LIBRARY_FWD_H +#define CIRCUIT_LIBRARY_FWD_H + #include "vtr_strong_id.h" struct circuit_model_id_tag; @@ -19,3 +22,5 @@ typedef vtr::StrongId CircuitEdgeId; /* Short declaration of class */ class CircuitLibrary; + +#endif diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_types.h b/vpr7_x2p/libarchfpga/SRC/circuit_types.h index eff20f141..92e8b1c61 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_types.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_types.h @@ -102,6 +102,7 @@ enum e_spice_model_pass_gate_logic_type { SPICE_MODEL_PASS_GATE_TRANSMISSION, SPICE_MODEL_PASS_GATE_TRANSISTOR, SPICE_MODEL_PASS_GATE_RRAM, /* RRAM can be treated as a special type of pass-gate logic */ + SPICE_MODEL_PASS_GATE_STDCELL, /* Standard cell as a special type of pass-gate logic */ NUM_CIRCUIT_MODEL_PASS_GATE_TYPES }; diff --git a/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c b/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c index e6f400fb2..e59ebcaab 100644 --- a/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c +++ b/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c @@ -1573,11 +1573,9 @@ CircuitLibrary build_circuit_library(int num_spice_model, t_spice_model* spice_m /* Go spice_model by spice_model */ for (int imodel = 0; imodel < num_spice_model; ++imodel) { /* Add a spice model to the circuit_lib */ - CircuitModelId model_id = circuit_lib.add_model(); + CircuitModelId model_id = circuit_lib.add_model(spice_models[imodel].type); /* Fill fundamental attributes */ /* Basic information*/ - circuit_lib.set_model_type(model_id, spice_models[imodel].type); - std::string name(spice_models[imodel].name); circuit_lib.set_model_name(model_id, name); @@ -1728,59 +1726,57 @@ CircuitLibrary build_circuit_library(int num_spice_model, t_spice_model* spice_m /* Ports */ for (int iport = 0; iport < spice_models[imodel].num_port; ++iport) { - CircuitPortId port_id = circuit_lib.add_model_port(model_id); + CircuitPortId port_id = circuit_lib.add_model_port(model_id, spice_models[imodel].ports[iport].type); /* Fill fundamental attributes */ - circuit_lib.set_port_type(model_id, port_id, spice_models[imodel].ports[iport].type); - - circuit_lib.set_port_size(model_id, port_id, spice_models[imodel].ports[iport].size); + circuit_lib.set_port_size(port_id, spice_models[imodel].ports[iport].size); std::string port_prefix(spice_models[imodel].ports[iport].prefix); - circuit_lib.set_port_prefix(model_id, port_id, port_prefix); + circuit_lib.set_port_prefix(port_id, port_prefix); std::string port_lib_name(spice_models[imodel].ports[iport].lib_name); - circuit_lib.set_port_lib_name(model_id, port_id, port_lib_name); + circuit_lib.set_port_lib_name(port_id, port_lib_name); if (NULL != spice_models[imodel].ports[iport].inv_prefix) { std::string port_inv_prefix(spice_models[imodel].ports[iport].inv_prefix); - circuit_lib.set_port_inv_prefix(model_id, port_id, port_inv_prefix); + circuit_lib.set_port_inv_prefix(port_id, port_inv_prefix); } - circuit_lib.set_port_default_value(model_id, port_id, spice_models[imodel].ports[iport].default_val); + circuit_lib.set_port_default_value(port_id, spice_models[imodel].ports[iport].default_val); - circuit_lib.set_port_is_mode_select(model_id, port_id, TRUE == spice_models[imodel].ports[iport].mode_select); - circuit_lib.set_port_is_global(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_global); - circuit_lib.set_port_is_reset(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_reset); - circuit_lib.set_port_is_set(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_set); - circuit_lib.set_port_is_config_enable(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_config_enable); - circuit_lib.set_port_is_prog(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_prog); + circuit_lib.set_port_is_mode_select(port_id, TRUE == spice_models[imodel].ports[iport].mode_select); + circuit_lib.set_port_is_global(port_id, TRUE == spice_models[imodel].ports[iport].is_global); + circuit_lib.set_port_is_reset(port_id, TRUE == spice_models[imodel].ports[iport].is_reset); + circuit_lib.set_port_is_set(port_id, TRUE == spice_models[imodel].ports[iport].is_set); + circuit_lib.set_port_is_config_enable(port_id, TRUE == spice_models[imodel].ports[iport].is_config_enable); + circuit_lib.set_port_is_prog(port_id, TRUE == spice_models[imodel].ports[iport].is_prog); if (NULL != spice_models[imodel].ports[iport].spice_model_name) { std::string port_model_name(spice_models[imodel].ports[iport].spice_model_name); - circuit_lib.set_port_model_name(model_id, port_id, port_model_name); + circuit_lib.set_port_tri_state_model_name(port_id, port_model_name); } if (NULL != spice_models[imodel].ports[iport].inv_spice_model_name) { std::string port_inv_model_name(spice_models[imodel].ports[iport].inv_spice_model_name); - circuit_lib.set_port_inv_model_name(model_id, port_id, port_inv_model_name); + circuit_lib.set_port_inv_model_name(port_id, port_inv_model_name); } if (NULL != spice_models[imodel].ports[iport].tri_state_map) { std::string port_tri_state_map(spice_models[imodel].ports[iport].tri_state_map); - circuit_lib.set_port_tri_state_map(model_id, port_id, port_tri_state_map); + circuit_lib.set_port_tri_state_map(port_id, port_tri_state_map); } if (SPICE_MODEL_LUT == spice_models[imodel].type) { - circuit_lib.set_port_lut_frac_level(model_id, port_id, spice_models[imodel].ports[iport].lut_frac_level); + circuit_lib.set_port_lut_frac_level(port_id, spice_models[imodel].ports[iport].lut_frac_level); std::vector port_lut_output_mask; for (int ipin = 0; ipin < spice_models[imodel].ports[iport].size; ++ipin) { port_lut_output_mask.push_back(spice_models[imodel].ports[iport].lut_output_mask[ipin]); } - circuit_lib.set_port_lut_output_mask(model_id, port_id, port_lut_output_mask); + circuit_lib.set_port_lut_output_mask(port_id, port_lut_output_mask); } if (SPICE_MODEL_PORT_SRAM == spice_models[imodel].ports[iport].type) { - circuit_lib.set_port_sram_orgz(model_id, port_id, spice_models[imodel].ports[iport].organization); + circuit_lib.set_port_sram_orgz(port_id, spice_models[imodel].ports[iport].organization); } } } diff --git a/vpr7_x2p/vpr/SRC/device/mux_graph.cpp b/vpr7_x2p/vpr/SRC/device/mux_graph.cpp index 1312384c1..70446bbe4 100644 --- a/vpr7_x2p/vpr/SRC/device/mux_graph.cpp +++ b/vpr7_x2p/vpr/SRC/device/mux_graph.cpp @@ -67,6 +67,19 @@ size_t MuxGraph::num_inputs() const { return num_inputs; } +/* Find the number of outputs in the MUX graph */ +size_t MuxGraph::num_outputs() const { + /* need to check if the graph is valid or not */ + VTR_ASSERT_SAFE(valid_mux_graph()); + /* Sum up the number of INPUT nodes in each level */ + size_t num_outputs = 0; + for (auto node_per_level : node_lookup_) { + num_outputs += node_per_level[MUX_OUTPUT_NODE].size(); + } + return num_outputs; +} + + /* Find the number of levels in the MUX graph */ size_t MuxGraph::num_levels() const { /* need to check if the graph is valid or not */ @@ -133,7 +146,7 @@ MuxGraph MuxGraph::subgraph(const MuxNodeId& root_node) const { /* Add output nodes to subgraph */ MuxNodeId to_node_subgraph = mux_graph.add_node(MUX_OUTPUT_NODE); - mux_graph.node_levels_[to_node_subgraph] = 0; + mux_graph.node_levels_[to_node_subgraph] = 1; /* Update the node-to-node map */ node2node_map[root_node] = to_node_subgraph; @@ -155,7 +168,7 @@ MuxGraph MuxGraph::subgraph(const MuxNodeId& root_node) const { MuxEdgeId edge_subgraph = mux_graph.add_edge(node2node_map[from_node_origin], node2node_map[root_node]); edge2edge_map[edge_origin] = edge_subgraph; /* Configure edges */ - mux_graph.edge_types_[edge_subgraph] = this->edge_types_[edge_origin]; + mux_graph.edge_models_[edge_subgraph] = this->edge_models_[edge_origin]; mux_graph.edge_inv_mem_[edge_subgraph] = this->edge_inv_mem_[edge_origin]; } @@ -179,6 +192,9 @@ MuxGraph MuxGraph::subgraph(const MuxNodeId& root_node) const { mem2mem_map[mem_origin] = mem_subgraph; } + /* Since the graph is finalized, it is time to build the fast look-up */ + mux_graph.build_node_lookup(); + return mux_graph; } @@ -300,7 +316,7 @@ MuxEdgeId MuxGraph::add_edge(const MuxNodeId& from_node, const MuxNodeId& to_nod /* Push to the node list */ edge_ids_.push_back(edge); /* Resize the other node-related vectors */ - edge_types_.push_back(NUM_CIRCUIT_MODEL_PASS_GATE_TYPES); + edge_models_.push_back(CircuitModelId::INVALID()); edge_mem_ids_.push_back(MuxMemId::INVALID()); edge_inv_mem_.push_back(false); @@ -386,7 +402,7 @@ void MuxGraph::set_edge_mem_id(const MuxEdgeId& edge, const MuxMemId& mem) { */ void MuxGraph::build_multilevel_mux_graph(const size_t& mux_size, const size_t& num_levels, const size_t& num_inputs_per_branch, - const enum e_spice_model_pass_gate_logic_type& pgl_type) { + const CircuitModelId& pgl_model) { /* Make sure mux_size for each branch is valid */ VTR_ASSERT(valid_mux_implementation_num_inputs(num_inputs_per_branch)); @@ -439,7 +455,7 @@ void MuxGraph::build_multilevel_mux_graph(const size_t& mux_size, /* Create an edge and connect the two nodes */ MuxEdgeId edge = add_edge(expand_node, seed_node); /* Configure the edge */ - edge_types_[edge] = pgl_type; + edge_models_[edge] = pgl_model; /* Memory id depends on the level and offset in the current branch * if number of inputs per branch is 2, it indicates a tree-like multiplexer, @@ -517,7 +533,7 @@ void MuxGraph::build_multilevel_mux_graph(const size_t& mux_size, * input_node --->+ */ void MuxGraph::build_onelevel_mux_graph(const size_t& mux_size, - const enum e_spice_model_pass_gate_logic_type& pgl_type) { + const CircuitModelId& pgl_model) { /* Make sure mux_size is valid */ VTR_ASSERT(valid_mux_implementation_num_inputs(mux_size)); @@ -538,7 +554,7 @@ void MuxGraph::build_onelevel_mux_graph(const size_t& mux_size, */ MuxEdgeId edge = add_edge(input_node, output_node); /* Configure the edge */ - edge_types_[edge] = pgl_type; + edge_models_[edge] = pgl_model; /* Create a memory bit*/ MuxMemId mem = add_mem(); @@ -574,11 +590,11 @@ void MuxGraph::build_mux_graph(const CircuitLibrary& circuit_lib, size_t num_inputs_per_branch = 2; /* Build a multilevel mux graph */ - build_multilevel_mux_graph(impl_mux_size, num_levels, num_inputs_per_branch, circuit_lib.pass_gate_logic_type(circuit_model)); + build_multilevel_mux_graph(impl_mux_size, num_levels, num_inputs_per_branch, circuit_lib.pass_gate_logic_model(circuit_model)); break; } case SPICE_MODEL_STRUCTURE_ONELEVEL: { - build_onelevel_mux_graph(impl_mux_size, circuit_lib.pass_gate_logic_type(circuit_model)); + build_onelevel_mux_graph(impl_mux_size, circuit_lib.pass_gate_logic_model(circuit_model)); break; } case SPICE_MODEL_STRUCTURE_MULTILEVEL: { @@ -588,7 +604,7 @@ void MuxGraph::build_mux_graph(const CircuitLibrary& circuit_lib, /* Build a multilevel mux graph */ build_multilevel_mux_graph(impl_mux_size, circuit_lib.mux_num_levels(circuit_model), num_inputs_per_branch, - circuit_lib.pass_gate_logic_type(circuit_model)); + circuit_lib.pass_gate_logic_model(circuit_model)); break; } default: diff --git a/vpr7_x2p/vpr/SRC/device/mux_graph.h b/vpr7_x2p/vpr/SRC/device/mux_graph.h index fc5dd1f98..0b76da5da 100644 --- a/vpr7_x2p/vpr/SRC/device/mux_graph.h +++ b/vpr7_x2p/vpr/SRC/device/mux_graph.h @@ -63,6 +63,8 @@ class MuxGraph { public: /* Public accessors: Data query */ /* Find the number of inputs in the MUX graph */ size_t num_inputs() const; + /* Find the number of outputs in the MUX graph */ + size_t num_outputs() const; /* Find the number of levels in the MUX graph */ size_t num_levels() const; /* Find the number of SRAMs in the MUX graph */ @@ -88,10 +90,10 @@ class MuxGraph { private: /* Private mutators : graph builders */ void build_multilevel_mux_graph(const size_t& mux_size, const size_t& num_levels, const size_t& num_inputs_per_branch, - const enum e_spice_model_pass_gate_logic_type& pgl_type); + const CircuitModelId& pgl_model) ; /* Build the graph for a given one-level multiplexer implementation */ void build_onelevel_mux_graph(const size_t& mux_size, - const enum e_spice_model_pass_gate_logic_type& pgl_type); + const CircuitModelId& pgl_model) ; /* Build the graph for a given multiplexer model */ void build_mux_graph(const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, @@ -120,7 +122,7 @@ class MuxGraph { vtr::vector edge_ids_; /* Unique ids for each edge */ vtr::vector> edge_src_nodes_; /* source nodes drive this edge */ vtr::vector> edge_sink_nodes_; /* sink nodes this edge drives */ - vtr::vector edge_types_; /* type of each edge: tgate/pass-gate */ + vtr::vector edge_models_; /* type of each edge: tgate/pass-gate */ vtr::vector edge_mem_ids_; /* ids of memory bit that control the edge */ vtr::vector edge_inv_mem_; /* if the edge is controlled by an inverted output of a memory bit */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.cpp index c8dd0b8c3..8a78d734e 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.cpp @@ -196,7 +196,6 @@ void link_sram_inf(t_sram_inf* cur_sram_inf, **************************************************************************/ t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type, const CircuitLibrary& circuit_lib, - const CircuitModelId& circuit_model, const CircuitPortId& circuit_port) { t_port* ret = NULL; size_t num_found = 0; @@ -204,10 +203,10 @@ t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type, /* Search ports */ for (int iport = 0; iport < pb_type->num_ports; iport++) { /* Match the name and port size*/ - if ( (0 == circuit_lib.port_prefix(circuit_model, circuit_port).compare(pb_type->ports[iport].name)) - && (size_t(pb_type->ports[iport].num_pins) == circuit_lib.port_size(circuit_model, circuit_port))) { + if ( (0 == circuit_lib.port_prefix(circuit_port).compare(pb_type->ports[iport].name)) + && (size_t(pb_type->ports[iport].num_pins) == circuit_lib.port_size(circuit_port))) { /* Match the type*/ - switch (circuit_lib.port_type(circuit_model, circuit_port)) { + switch (circuit_lib.port_type(circuit_port)) { case SPICE_MODEL_PORT_INPUT: if ((IN_PORT == pb_type->ports[iport].type) &&(0 == pb_type->ports[iport].is_clock)) { @@ -236,7 +235,7 @@ t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type, break; default: vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for circuit model port(%s)!\n", - __FILE__, __LINE__, circuit_lib.port_prefix(circuit_model, circuit_port)); + __FILE__, __LINE__, circuit_lib.port_prefix(circuit_port)); exit(1); } } @@ -246,7 +245,7 @@ t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type, if (1 < num_found) { vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", - __FILE__, __LINE__, pb_type->name, circuit_lib.port_prefix(circuit_model, circuit_port).c_str()); + __FILE__, __LINE__, pb_type->name, circuit_lib.port_prefix(circuit_port).c_str()); exit(1); } @@ -276,8 +275,8 @@ int link_pb_type_port_to_circuit_model_ports(const t_pb_type* cur_pb_type, } /* For each port, find a SPICE model port, which has the same name and port size */ - for (auto& port : circuit_lib.ports(circuit_model)) { - t_port* cur_pb_type_port = find_pb_type_port_match_circuit_model_port(cur_pb_type, circuit_lib, circuit_model, port); + for (auto& port : circuit_lib.model_ports(circuit_model)) { + t_port* cur_pb_type_port = find_pb_type_port_match_circuit_model_port(cur_pb_type, circuit_lib, port); /* Not every spice_model_port can find a mapped pb_type_port. * Since a pb_type only includes necessary ports in technology mapping. * ports for physical designs may be ignored ! diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.h index 1b134a78d..f69314377 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.h @@ -54,7 +54,6 @@ CircuitModelId link_circuit_model_by_name_and_type(const char* circuit_model_nam t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type, const CircuitLibrary& circuit_lib, - const CircuitModelId& circuit_model, const CircuitPortId& circuit_port); void link_circuit_library_to_arch(t_arch* arch, diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.h new file mode 100644 index 000000000..76dc603e8 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.h @@ -0,0 +1,27 @@ +/************************************************ + * 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 + ***********************************************/ + +#ifndef MODULE_MANAGER_H +#define MODULE_MANAGER_H + +#include +#include "module_manager_fwd.h" +#include "device_port.h" + +class ModuleManager { + private: /* Internal data */ + vtr::vector ids_; + vtr::vector ports_; + vtr::vector> parents_; + vtr::vector> children_; +}; + +#endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_fwd.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_fwd.h new file mode 100644 index 000000000..abaa0854b --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_fwd.h @@ -0,0 +1,18 @@ +/************************************************** + * This file includes only declarations for + * the data structures for module managers + * Please refer to module_manager.h for more details + *************************************************/ +#ifndef MODULE_MANAGER_FWD_H +#define MODULE_MANAGER_FWD_H + +#include "vtr_strong_id.h" + +/* Strong Ids for MUXes */ +struct module_id_tag; + +typedef vtr::StrongId ModuleId; + +class ModuleManager; + +#endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c index 4c0ec145f..8fc306335 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c @@ -803,9 +803,9 @@ void dump_compact_verilog_defined_one_switch_box(t_sram_orgz_info* cur_sram_orgz chan_coordinator.get_x(), chan_coordinator.get_y(), itrack, rr_sb.get_chan_node_direction(side_manager.get_side(), itrack))); if (true == is_explicit_mapping) { - fprintf(fp, ")",itrack); + fprintf(fp, ")"); } - fprintf(fp, ",\n",itrack); + fprintf(fp, ",\n"); } fprintf(fp, "//----- %s side inputs: CLB output pins -----\n", convert_side_index_to_string(side)); /* Dump OPINs of adjacent CLBs */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.h index 4701b18de..73d75b766 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.h @@ -1,3 +1,5 @@ +#ifndef VERILOG_GLOBAL_H +#define VERILOG_GLOBAL_H /* global parameters for dumping synthesizable verilog */ extern char* verilog_netlist_file_postfix; @@ -140,8 +142,10 @@ VERILOG_PORT_OUTPUT, VERILOG_PORT_INOUT, VERILOG_PORT_WIRE, VERILOG_PORT_REG, -VERILOG_PORT_CONKT +VERILOG_PORT_CONKT, +NUM_VERILOG_PORT_TYPES }; +constexpr std::array VERILOG_PORT_TYPE_STRING = {{"input", "output", "inout", "wire", "reg", ""}}; /* string version of enum e_verilog_port_type */ enum e_verilog_tb_type { VERILOG_TB_TOP, @@ -149,3 +153,5 @@ VERILOG_TB_BLIF_TOP, VERILOG_TB_AUTOCHECK_TOP, VERILOG_TB_FORMAL_VERIFICATION }; + +#endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodule_mux.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodule_mux.cpp index f60cef851..23f62a77f 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodule_mux.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodule_mux.cpp @@ -5,12 +5,25 @@ * such as a branch in a multiplexer * and the full multiplexer **********************************************/ +#include #include "util.h" #include "vtr_assert.h" -#include "verilog_submodule_mux.h" +/* Device-level header files */ +#include "mux_graph.h" +#include "physical_types.h" +#include "vpr_types.h" +/* FPGA-X2P context header files */ +#include "spice_types.h" +#include "fpga_x2p_naming.h" + +/* FPGA-Verilog context header files */ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_writer_utils.h" +#include "verilog_submodule_mux.h" /*********************************************** * Generate Verilog codes modeling an branch circuit @@ -20,7 +33,153 @@ static void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp, const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, + const std::string& module_name, const MuxGraph& mux_graph) { + /* Get the tgate model */ + CircuitModelId tgate_model = circuit_lib.pass_gate_logic_model(circuit_model); + + /* Skip output if the tgate model is a MUX2, it is handled by essential-gate generator */ + if (SPICE_MODEL_GATE == circuit_lib.model_type(tgate_model)) { + VTR_ASSERT(SPICE_MODEL_GATE_MUX2 == circuit_lib.gate_type(tgate_model)); + return; + } + + /* Get model ports of tgate */ + std::vector tgate_input_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT); + std::vector tgate_output_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_OUTPUT); + VTR_ASSERT(3 == tgate_input_ports.size()); + VTR_ASSERT(1 == tgate_output_ports.size()); + + /* Make sure we have a valid file handler*/ + check_file_handler(fp); + + /* Generate the Verilog netlist according to the mux_graph */ + /* Find out the number of inputs */ + size_t num_inputs = mux_graph.num_inputs(); + /* Find out the number of outputs */ + size_t num_outputs = mux_graph.num_outputs(); + /* Find out the number of memory bits */ + size_t num_mems = mux_graph.num_memory_bits(); + + /* Check codes to ensure the port of Verilog netlists will match */ + /* MUX graph must have only 1 output */ + VTR_ASSERT(1 == num_outputs); + /* MUX graph must have only 1 level*/ + VTR_ASSERT(1 == mux_graph.num_levels()); + + /* Comment lines */ + fp << "//---- Structural Verilog for CMOS MUX basis module:" << module_name << "-----" << std::endl; + + /* Print the port list and definition */ + fp << "module " << module_name << "(" << std::endl; + + /* Create port information */ + BasicPort input_port; + /* Configure each input port */ + input_port.set_name(std::string("in")); + input_port.set_width(num_inputs); + + BasicPort output_port; + /* Configure each input port */ + output_port.set_name(std::string("out")); + output_port.set_width(num_outputs); + + BasicPort mem_port; + /* Configure each input port */ + mem_port.set_name(std::string("mem")); + mem_port.set_width(num_mems); + + BasicPort mem_inv_port; + /* Configure each input port */ + mem_inv_port.set_name(std::string("mem_inv")); + mem_inv_port.set_width(num_mems); + + /* TODO: Generate global ports */ + + + /* TODO: add a module to the Module Manager */ + + /* Port list */ + fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, input_port) << "," << std::endl; + fp << "\t" << generate_verilog_port(VERILOG_PORT_OUTPUT, output_port) << "," << std::endl; + fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, mem_port) << "," << std::endl; + fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, mem_inv_port) << std::endl; + fp << ");" << std::endl; + + /* Verilog Behavior description for a MUX */ + fp << "//---- Structure-level description -----" << std::endl; + /* Special case: only one memory, switch case is simpler + * When mem = 1, propagate input 0; + * when mem = 0, propagate input 1; + */ + if (1 == num_mems) { + /* Transmission gates are connected to each input and also the output*/ + fp << "\t" << circuit_lib.model_name(tgate_model) << " " << circuit_lib.model_prefix(tgate_model) << "_0 "; + /* Dump explicit port map if required */ + if (true == circuit_lib.dump_explicit_port_map(tgate_model)) { + fp << " ("; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[0]) << "(" << "in[0]" << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[1]) << "(" << generate_verilog_port(VERILOG_PORT_CONKT, mem_port) << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[2]) << "(" << generate_verilog_port(VERILOG_PORT_CONKT, mem_inv_port) << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_output_ports[0]) << "(" << generate_verilog_port(VERILOG_PORT_CONKT, output_port) << ")"; + fp << ");" << std::endl; + } else { + fp << " ("; + fp << generate_verilog_port(VERILOG_PORT_CONKT, input_port); + fp << ", " << generate_verilog_port(VERILOG_PORT_CONKT, mem_port); + fp << ", " << generate_verilog_port(VERILOG_PORT_CONKT, mem_inv_port); + fp << ", " << generate_verilog_port(VERILOG_PORT_CONKT, output_port); + fp << ");" << std::endl; + } + /* Transmission gates are connected to each input and also the output*/ + fp << "\t" << circuit_lib.model_name(tgate_model) << " " << circuit_lib.model_prefix(tgate_model) << "_1 "; + /* Dump explicit port map if required */ + if (true == circuit_lib.dump_explicit_port_map(tgate_model)) { + fp << " ("; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[0]) << "(" << "in[1]" << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[1]) << "(" << generate_verilog_port(VERILOG_PORT_CONKT, mem_inv_port) << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[2]) << "(" << generate_verilog_port(VERILOG_PORT_CONKT, mem_port) << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_output_ports[0]) << "(" << generate_verilog_port(VERILOG_PORT_CONKT, output_port) << ")"; + fp << ");" << std::endl; + } else { + fp << " ("; + fp << generate_verilog_port(VERILOG_PORT_CONKT, input_port); + fp << ", " << generate_verilog_port(VERILOG_PORT_CONKT, mem_inv_port); + fp << ", " << generate_verilog_port(VERILOG_PORT_CONKT, mem_port); + fp << ", " << generate_verilog_port(VERILOG_PORT_CONKT, output_port); + fp << ");" << std::endl; + } + } else { + /* Other cases, we need to follow the rules: + * When mem[k] is enabled, switch on input[k] + * Only one memory bit is enabled! + */ + for (size_t i = 0; i < num_mems; i++) { + fp << "\t" << circuit_lib.model_name(tgate_model) << " " << circuit_lib.model_prefix(tgate_model) << "_" << i << " "; + if (true == circuit_lib.dump_explicit_port_map(tgate_model)) { + fp << " ("; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[0]) << "(" << "in[" << i << "]" << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[1]) << "(" << "mem[" << i << "]" << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[2]) << "(" << "mem_inv[" << i << "]" << "),"; + fp << " ." << circuit_lib.port_lib_name(tgate_output_ports[0]) << "(" << generate_verilog_port(VERILOG_PORT_CONKT, output_port) << ")"; + fp << ");" << std::endl; + } else { + fp << " ("; + fp << "in[" << i << "]"; + fp << ", " << "mem[" << i << "]"; + fp << ", " << "mem_inv[" << i << "]"; + fp << ", " << generate_verilog_port(VERILOG_PORT_CONKT, output_port); + fp << ");" << std::endl; + } + } + } + + /* Put an end to this module */ + fp << "endmodule" << std::endl; + + /* Comment lines */ + fp << "//---- END Structural Verilog CMOS MUX basis module: " << module_name << "-----" << std::endl << std::endl; + return; } @@ -31,12 +190,15 @@ void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp, void generate_verilog_mux_branch_module(std::fstream& fp, const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, + const size_t& mux_size, const MuxGraph& mux_graph) { + std::string module_name = generate_verilog_mux_branch_subckt_name(circuit_lib, circuit_model, mux_size, verilog_mux_basis_posfix); + /* Multiplexers built with different technology is in different organization */ switch (circuit_lib.design_tech_type(circuit_model)) { case SPICE_MODEL_DESIGN_CMOS: if (true == circuit_lib.dump_structural_verilog(circuit_model)) { - generate_verilog_cmos_mux_branch_module_structural(fp, circuit_lib, circuit_model, mux_graph); + generate_verilog_cmos_mux_branch_module_structural(fp, circuit_lib, circuit_model, module_name, mux_graph); } else { /* dump_verilog_cmos_mux_one_basis_module(fp, mux_basis_subckt_name, diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodule_mux.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodule_mux.h index 6e7e84b30..8c03d86e1 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodule_mux.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodule_mux.h @@ -15,6 +15,7 @@ void generate_verilog_mux_branch_module(std::fstream& fp, const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, + const size_t& mux_size, const MuxGraph& mux_graph); #endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c index c1f2944f9..2d058b491 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c @@ -2854,7 +2854,8 @@ void dump_verilog_submodule_muxes(t_sram_orgz_info* cur_sram_orgz_info, std::vector branch_mux_graphs = mux_graph.build_mux_branch_graphs(); /* Create branch circuits, which are N:1 one-level or 2:1 tree-like MUXes */ for (auto branch_mux_graph : branch_mux_graphs) { - generate_verilog_mux_branch_module(sfp, spice->circuit_lib, mux_circuit_model, branch_mux_graph); + generate_verilog_mux_branch_module(sfp, spice->circuit_lib, mux_circuit_model, + mux_graph.num_inputs(), branch_mux_graph); } } diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.c index dc62b3797..7251fdc83 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.c @@ -144,7 +144,7 @@ void dump_include_user_defined_verilog_netlists(FILE* fp, return; } -void check_file_handler(const std::fstream& fp) { +void check_file_handler(std::fstream& fp) { /* Make sure we have a valid file handler*/ /* Print out debugging information for if the file is not opened/created properly */ if (!fp.is_open() || !fp.good()) { @@ -855,7 +855,6 @@ int rec_dump_verilog_spice_model_lib_global_ports(FILE* fp, return dumped_port_cnt; } - /* Dump all the global ports that are stored in the linked list * Return the number of ports that have been dumped */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.h index 06aaba142..53359f048 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.h @@ -10,7 +10,7 @@ void init_include_user_defined_verilog_netlists(t_spice spice); void dump_include_user_defined_verilog_netlists(FILE* fp, t_spice spice); -void check_file_handler(const std::fstream& fp); +void check_file_handler(std::fstream& fp); void dump_verilog_file_header(FILE* fp, char* usage); @@ -52,6 +52,7 @@ void dump_verilog_subckt_header_file(t_llist* subckt_llist_head, char determine_verilog_generic_port_split_sign(enum e_dump_verilog_port_type dump_port_type); + void dump_verilog_generic_port(FILE* fp, enum e_dump_verilog_port_type dump_port_type, char* port_name, int port_lsb, int port_msb); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp new file mode 100644 index 000000000..da8d2acc0 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp @@ -0,0 +1,39 @@ +/************************************************ + * Include functions for most frequently + * used Verilog writers + ***********************************************/ +#include "vtr_assert.h" + +/* Device-level header files */ + +/* FPGA-X2P context header files */ +#include "spice_types.h" + +/* FPGA-Verilog context header files */ +#include "verilog_global.h" +#include "verilog_writer_utils.h" + +/* Generate a string of a Verilog port */ +std::string generate_verilog_port(const enum e_dump_verilog_port_type& verilog_port_type, + const BasicPort& port_info) { + std::string verilog_line; + + /* Ensure the port type is valid */ + VTR_ASSERT(verilog_port_type < NUM_VERILOG_PORT_TYPES); + + std::string size_str = "[" + std::to_string(port_info.get_lsb()) + ":" + std::to_string(port_info.get_msb()) + "]"; + + /* Only connection require a format of [:] + * others require a format of [:] + */ + if (VERILOG_PORT_CONKT == verilog_port_type) { + verilog_line = port_info.get_name() + " " + size_str; + } else { + verilog_line = VERILOG_PORT_TYPE_STRING[verilog_port_type]; + verilog_line += "" + size_str + " " + port_info.get_name(); + } + + return verilog_line; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.h new file mode 100644 index 000000000..14f7a8e68 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.h @@ -0,0 +1,15 @@ +/************************************************ + * Header file for verilog_writer_utils.cpp + * Include function declaration for most frequently + * used Verilog writers + ***********************************************/ +#ifndef VERILOG_WRITER_UTILS_H +#define VERILOG_WRITER_UTILS_H + +#include +#include "device_port.h" + +std::string generate_verilog_port(const enum e_dump_verilog_port_type& dump_port_type, + const BasicPort& port_info); + +#endif