rework on the circuit model ports and start prototyping mux Verilog generation

This commit is contained in:
tangxifan 2019-08-20 15:14:28 -06:00
parent a7ac1e4980
commit 29104b6fa5
21 changed files with 879 additions and 642 deletions

View File

@ -150,7 +150,7 @@ size_t check_one_circuit_model_port_required(const CircuitLibrary& circuit_lib,
size_t num_err = 0; size_t num_err = 0;
for (const auto& port_type: port_types_to_check) { 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, vpr_printf(TIO_MESSAGE_ERROR,
"%s circuit model(name=%s) does not have %s port\n", "%s circuit model(name=%s) does not have %s port\n",
CIRCUIT_MODEL_TYPE_STRING[size_t(circuit_lib.model_type(circuit_model))], 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; 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, vpr_printf(TIO_MESSAGE_ERROR,
"Port of circuit model(name=%s) does not have a port(type=%s) of size=%d.\n", "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_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); port_size_to_check);
/* Incremental the counter for errors */ /* Incremental the counter for errors */
num_err++; num_err++;
@ -202,7 +202,7 @@ size_t check_one_circuit_model_port_type_and_size_required(const CircuitLibrary&
size_t num_err = 0; size_t num_err = 0;
std::vector<CircuitPortId> ports = circuit_lib.ports_by_type(circuit_model, port_type_to_check, include_global_ports); std::vector<CircuitPortId> ports = circuit_lib.model_ports_by_type(circuit_model, port_type_to_check, include_global_ports);
if (num_ports_to_check != ports.size()) { if (num_ports_to_check != ports.size()) {
vpr_printf(TIO_MESSAGE_ERROR, vpr_printf(TIO_MESSAGE_ERROR,
"Expect %d %s ports for a %s circuit model, but only have %d %s ports!\n", "Expect %d %s ports for a %s circuit model, but only have %d %s ports!\n",

File diff suppressed because it is too large Load Diff

View File

@ -102,6 +102,7 @@
* *
* ------ Port information ------ * ------ Port information ------
* 1. port_ids_: unique id of ports belonging to a circuit model * 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 * 2. port_types_: types of ports belonging to a circuit model
* 3. port_sizes_: width 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 * 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 * 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 * 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 * 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 * 13. port_tri_state_model_name: the name of circuit model linked to tri-state the port
* 14. port_model_ids_: the Id of circuit model linked to 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 * 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 * 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 * 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 { class CircuitLibrary {
public: /* Types */ public: /* Types */
typedef vtr::vector<CircuitModelId, CircuitModelId>::const_iterator model_iterator; typedef vtr::vector<CircuitModelId, CircuitModelId>::const_iterator circuit_model_iterator;
typedef vtr::vector<CircuitModelId, std::string>::const_iterator model_string_iterator; typedef vtr::vector<CircuitModelId, std::string>::const_iterator circuit_model_string_iterator;
typedef vtr::vector<CircuitPortId, CircuitPortId>::const_iterator circuit_port_iterator; typedef vtr::vector<CircuitPortId, CircuitPortId>::const_iterator circuit_port_iterator;
typedef vtr::vector<CircuitEdgeId, CircuitEdgeId>::const_iterator circuit_edge_iterator; typedef vtr::vector<CircuitEdgeId, CircuitEdgeId>::const_iterator circuit_edge_iterator;
/* Create range */ /* Create range */
typedef vtr::Range<model_iterator> model_range; typedef vtr::Range<circuit_model_iterator> circuit_model_range;
typedef vtr::Range<circuit_port_iterator> circuit_port_range; typedef vtr::Range<circuit_port_iterator> circuit_port_range;
typedef vtr::Range<circuit_edge_iterator> circuit_edge_range; typedef vtr::Range<circuit_edge_iterator> circuit_edge_range;
/* local enumeration for buffer existence */ /* local enumeration for buffer existence */
@ -202,14 +203,9 @@ class CircuitLibrary {
public: /* Constructors */ public: /* Constructors */
CircuitLibrary(); CircuitLibrary();
public: /* Accessors: aggregates */ public: /* Accessors: aggregates */
model_range models() const; circuit_model_range models() const;
circuit_port_range ports(const CircuitModelId& model_id) const; circuit_port_range ports() const;
std::vector<CircuitModelId> models_by_type(const enum e_spice_model_type& type) const; std::vector<CircuitModelId> models_by_type(const enum e_spice_model_type& type) const;
std::vector<CircuitPortId> ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type) const;
std::vector<CircuitPortId> ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const;
std::vector<CircuitPortId> input_ports(const CircuitModelId& model_id) const;
std::vector<CircuitPortId> output_ports(const CircuitModelId& model_id) const;
std::vector<size_t> pins(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const;
public: /* Public Accessors: Basic data query on Circuit Models*/ public: /* Public Accessors: Basic data query on Circuit Models*/
size_t num_models() const; size_t num_models() const;
enum e_spice_model_type model_type(const CircuitModelId& model_id) 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_input_buffered(const CircuitModelId& model_id) const;
bool is_output_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; 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; enum e_spice_model_structure mux_structure(const CircuitModelId& model_id) const;
size_t mux_num_levels(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; bool mux_add_const_input(const CircuitModelId& model_id) const;
size_t mux_const_input_value(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<CircuitPortId> model_ports(const CircuitModelId& model_id) const;
std::vector<CircuitPortId> model_global_ports(const CircuitModelId& model_id) const;
std::vector<CircuitPortId> model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type) const;
std::vector<CircuitPortId> model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const;
std::vector<CircuitPortId> model_input_ports(const CircuitModelId& model_id) const;
std::vector<CircuitPortId> model_output_ports(const CircuitModelId& model_id) const;
std::vector<size_t> pins(const CircuitPortId& circuit_port_id) const;
public: /* Public Accessors: Basic data query on Circuit Ports*/ 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_input_port(const CircuitPortId& circuit_port_id) const;
bool is_output_port(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; bool is_output_port(const CircuitPortId& circuit_port_id) const;
CircuitPortId port(const CircuitModelId& model_id, const std::string& name) const; enum e_spice_model_port_type port_type(const CircuitPortId& circuit_port_id) const;
size_t num_ports(const CircuitModelId& model_id) const; size_t port_size(const CircuitPortId& circuit_port_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; std::string port_prefix(const CircuitPortId& circuit_port_id) const;
enum e_spice_model_port_type port_type(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; std::string port_lib_name(const CircuitPortId& circuit_port_id) const;
size_t port_size(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; std::string port_inv_prefix(const CircuitPortId& circuit_port_id) const;
std::string port_prefix(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; size_t port_default_value(const CircuitPortId& circuit_port_id) const;
std::string port_lib_name(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; bool port_is_mode_select(const CircuitPortId& circuit_port_id) const;
std::string port_inv_prefix(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; bool port_is_global(const CircuitPortId& circuit_port_id) const;
size_t port_default_value(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; bool port_is_reset(const CircuitPortId& circuit_port_id) const;
bool port_is_mode_select(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; bool port_is_set(const CircuitPortId& circuit_port_id) const;
bool port_is_global(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; bool port_is_config_enable(const CircuitPortId& circuit_port_id) const;
bool port_is_reset(const CircuitModelId& model_id, const CircuitPortId& circuit_port_id) const; bool port_is_prog(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;
public: /* Public Accessors: Methods to find circuit model */ public: /* Public Accessors: Methods to find circuit model */
CircuitModelId model(const char* name) const; CircuitModelId model(const char* name) const;
CircuitModelId model(const std::string& name) const; CircuitModelId model(const std::string& name) const;
CircuitModelId default_model(const enum e_spice_model_type& type) const; CircuitModelId default_model(const enum e_spice_model_type& type) const;
public: /* Public Accessors: Timing graph */ public: /* Public Accessors: Timing graph */
CircuitEdgeId edge(const CircuitModelId& model_id, CircuitEdgeId edge(const CircuitPortId& from_port, const size_t from_pin,
const CircuitPortId& from_port, const size_t from_pin,
const CircuitPortId& to_port, const size_t to_pin); const CircuitPortId& to_port, const size_t to_pin);
public: /* Public Mutators */ public: /* Public Mutators */
CircuitModelId add_model(); CircuitModelId add_model(const enum e_spice_model_type& type);
/* Fundamental information */ /* 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_name(const CircuitModelId& model_id, const std::string& name);
void set_model_prefix(const CircuitModelId& model_id, const std::string& prefix); 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); 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); void set_model_is_power_gated(const CircuitModelId& model_id, const bool& is_power_gated);
/* Buffer existence */ /* Buffer existence */
void set_model_input_buffer(const CircuitModelId& model_id, 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, 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, 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, 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, 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, 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 */ /* Pass-gate-related parameters */
void set_model_pass_gate_logic(const CircuitModelId& model_id, const std::string& model_name); void set_model_pass_gate_logic(const CircuitModelId& model_id, const std::string& model_name);
/* Port information */ /* Port information */
CircuitPortId add_model_port(const CircuitModelId& model_id); CircuitPortId add_model_port(const CircuitModelId& model_id,
void set_port_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type);
const CircuitPortId& circuit_port_id, void set_port_size(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,
const size_t& port_size); const size_t& port_size);
void set_port_prefix(const CircuitModelId& model_id, void set_port_prefix(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const std::string& port_prefix); const std::string& port_prefix);
void set_port_lib_name(const CircuitModelId& model_id, void set_port_lib_name(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const std::string& lib_name); const std::string& lib_name);
void set_port_inv_prefix(const CircuitModelId& model_id, void set_port_inv_prefix(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const std::string& inv_prefix); const std::string& inv_prefix);
void set_port_default_value(const CircuitModelId& model_id, void set_port_default_value(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const size_t& default_val); const size_t& default_val);
void set_port_is_mode_select(const CircuitModelId& model_id, void set_port_is_mode_select(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const bool& is_mode_select); const bool& is_mode_select);
void set_port_is_global(const CircuitModelId& model_id, void set_port_is_global(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const bool& is_global); const bool& is_global);
void set_port_is_reset(const CircuitModelId& model_id, void set_port_is_reset(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const bool& is_reset); const bool& is_reset);
void set_port_is_set(const CircuitModelId& model_id, void set_port_is_set(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const bool& is_set); const bool& is_set);
void set_port_is_config_enable(const CircuitModelId& model_id, void set_port_is_config_enable(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const bool& is_config_enable); const bool& is_config_enable);
void set_port_is_prog(const CircuitModelId& model_id, void set_port_is_prog(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const bool& is_prog); const bool& is_prog);
void set_port_model_name(const CircuitModelId& model_id, void set_port_tri_state_model_name(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id, const std::string& model_name);
const std::string& model_name); void set_port_tri_state_model_id(const CircuitPortId& circuit_port_id,
void set_port_model_id(const CircuitModelId& model_id, const CircuitModelId& port_model_id);
const CircuitPortId& circuit_port_id, void set_port_inv_model_name(const CircuitPortId& circuit_port_id,
const CircuitModelId& port_model_id); const std::string& inv_model_name);
void set_port_inv_model_name(const CircuitModelId& model_id, void set_port_inv_model_id(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id, const CircuitModelId& inv_model_id);
const std::string& inv_model_name); void set_port_tri_state_map(const CircuitPortId& circuit_port_id,
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,
const std::string& tri_state_map); const std::string& tri_state_map);
void set_port_lut_frac_level(const CircuitModelId& model_id, void set_port_lut_frac_level(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const size_t& lut_frac_level); const size_t& lut_frac_level);
void set_port_lut_output_mask(const CircuitModelId& model_id, void set_port_lut_output_mask(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const std::vector<size_t>& lut_output_masks); const std::vector<size_t>& lut_output_masks);
void set_port_sram_orgz(const CircuitModelId& model_id, void set_port_sram_orgz(const CircuitPortId& circuit_port_id,
const CircuitPortId& circuit_port_id,
const enum e_sram_orgz& sram_orgz); const enum e_sram_orgz& sram_orgz);
/* Delay information */ /* Delay information */
void add_delay_info(const CircuitModelId& model_id, void add_delay_info(const CircuitModelId& model_id,
@ -415,19 +397,18 @@ class CircuitLibrary {
const float& c_val); const float& c_val);
void set_wire_num_levels(const CircuitModelId& model_id, void set_wire_num_levels(const CircuitModelId& model_id,
const size_t& num_level); 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 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_tri_state_model();
void link_port_inv_model(const CircuitModelId& model_id); void link_port_inv_model();
void link_port_models(const CircuitModelId& model_id);
void link_buffer_model(const CircuitModelId& model_id); void link_buffer_model(const CircuitModelId& model_id);
void link_pass_gate_logic_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); void build_model_timing_graph(const CircuitModelId& model_id);
public: /* Public Mutators: builders */
void build_model_links();
void build_timing_graphs(); void build_timing_graphs();
public: /* Internal mutators: build timing graphs */ public: /* Internal mutators: build timing graphs */
void add_edge(const CircuitModelId& model_id, void add_edge(const CircuitPortId& from_port, const size_t& from_pin,
const CircuitPortId& from_port, const size_t& from_pin,
const CircuitPortId& to_port, const size_t& to_pin); const CircuitPortId& to_port, const size_t& to_pin);
void set_edge_delay(const CircuitModelId& model_id, void set_edge_delay(const CircuitModelId& model_id,
const CircuitEdgeId& circuit_edge_id, const CircuitEdgeId& circuit_edge_id,
@ -437,19 +418,19 @@ class CircuitLibrary {
void set_timing_graph_delays(const CircuitModelId& model_id); void set_timing_graph_delays(const CircuitModelId& model_id);
public: /* Internal mutators: build fast look-ups */ public: /* Internal mutators: build fast look-ups */
void build_model_lookup(); void build_model_lookup();
void build_model_port_lookup(const CircuitModelId& model_id); void build_model_port_lookup();
private: /* Internal invalidators/validators */ private: /* Internal invalidators/validators */
/* Validators */ /* Validators */
bool valid_model_id(const CircuitModelId& model_id) const; 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_port_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_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_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; bool valid_mux_const_input_value(const size_t& const_input_value) const;
/* Invalidators */ /* Invalidators */
void invalidate_model_lookup() const; void invalidate_model_lookup() const;
void invalidate_model_port_lookup(const CircuitModelId& model_id) const; void invalidate_model_port_lookup() const;
void invalidate_model_timing_graph(const CircuitModelId& model_id); void invalidate_model_timing_graph();
private: /* Internal data */ private: /* Internal data */
/* Fundamental information */ /* Fundamental information */
vtr::vector<CircuitModelId, CircuitModelId> model_ids_; vtr::vector<CircuitModelId, CircuitModelId> model_ids_;
@ -466,7 +447,7 @@ class CircuitLibrary {
*/ */
typedef std::vector<std::vector<CircuitModelId>> CircuitModelLookup; typedef std::vector<std::vector<CircuitModelId>> CircuitModelLookup;
mutable CircuitModelLookup model_lookup_; /* [model_type][model_ids] */ mutable CircuitModelLookup model_lookup_; /* [model_type][model_ids] */
typedef std::vector<std::vector<std::vector<CircuitPortId>>> CircuitModelPortLookup; typedef vtr::vector<CircuitModelId, std::vector<std::vector<CircuitPortId>>> CircuitModelPortLookup;
mutable CircuitModelPortLookup model_port_lookup_; /* [model_id][port_type][port_ids] */ mutable CircuitModelPortLookup model_port_lookup_; /* [model_id][port_type][port_ids] */
/* Verilog generator options */ /* Verilog generator options */
@ -488,37 +469,38 @@ class CircuitLibrary {
vtr::vector<CircuitModelId, CircuitModelId> pass_gate_logic_model_ids_; vtr::vector<CircuitModelId, CircuitModelId> pass_gate_logic_model_ids_;
/* Port information */ /* Port information */
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, CircuitPortId>> port_ids_; vtr::vector<CircuitPortId, CircuitPortId> port_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, enum e_spice_model_port_type>> port_types_; vtr::vector<CircuitPortId, CircuitModelId> port_model_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, size_t>> port_sizes_; vtr::vector<CircuitPortId, enum e_spice_model_port_type> port_types_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_prefix_; vtr::vector<CircuitPortId, size_t> port_sizes_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_lib_names_; vtr::vector<CircuitPortId, std::string> port_prefix_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_inv_prefix_; vtr::vector<CircuitPortId, std::string> port_lib_names_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, size_t>> port_default_values_; vtr::vector<CircuitPortId, std::string> port_inv_prefix_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_mode_select_; vtr::vector<CircuitPortId, size_t> port_default_values_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_global_; vtr::vector<CircuitPortId, bool> port_is_mode_select_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_reset_; vtr::vector<CircuitPortId, bool> port_is_global_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_set_; vtr::vector<CircuitPortId, bool> port_is_reset_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_config_enable_; vtr::vector<CircuitPortId, bool> port_is_set_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_prog_; vtr::vector<CircuitPortId, bool> port_is_config_enable_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_model_names_; vtr::vector<CircuitPortId, bool> port_is_prog_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, CircuitModelId>> port_model_ids_; vtr::vector<CircuitPortId, std::string> port_tri_state_model_names_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_inv_model_names_; vtr::vector<CircuitPortId, CircuitModelId> port_tri_state_model_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, CircuitModelId>> port_inv_model_ids_; vtr::vector<CircuitPortId, std::string> port_inv_model_names_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_tri_state_maps_; vtr::vector<CircuitPortId, CircuitModelId> port_inv_model_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, size_t>> port_lut_frac_level_; vtr::vector<CircuitPortId, std::string> port_tri_state_maps_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::vector<size_t>>> port_lut_output_masks_; vtr::vector<CircuitPortId, size_t> port_lut_frac_level_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, enum e_sram_orgz>> port_sram_orgz_; vtr::vector<CircuitPortId, std::vector<size_t>> port_lut_output_masks_;
vtr::vector<CircuitPortId, enum e_sram_orgz> port_sram_orgz_;
/* Timing graphs */ /* Timing graphs */
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, CircuitEdgeId>> edge_ids_; vtr::vector<CircuitEdgeId, CircuitEdgeId> edge_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, vtr::vector<size_t, CircuitEdgeId>>> port_in_edge_ids_; vtr::vector<CircuitPortId, vtr::vector<size_t, CircuitEdgeId>> port_in_edge_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, vtr::vector<size_t, CircuitEdgeId>>> port_out_edge_ids_; vtr::vector<CircuitPortId, vtr::vector<size_t, CircuitEdgeId>> port_out_edge_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, CircuitPortId>> edge_src_port_ids_; vtr::vector<CircuitEdgeId, CircuitPortId> edge_src_port_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, size_t>> edge_src_pin_ids_; vtr::vector<CircuitEdgeId, size_t> edge_src_pin_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, CircuitPortId>> edge_sink_port_ids_; vtr::vector<CircuitEdgeId, CircuitPortId> edge_sink_port_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, size_t>> edge_sink_pin_ids_; vtr::vector<CircuitEdgeId, size_t> edge_sink_pin_ids_;
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, std::vector<float>>> edge_timing_info_; /* x0 => trise, x1 => tfall */ vtr::vector<CircuitEdgeId, std::vector<float>> edge_timing_info_; /* x0 => trise, x1 => tfall */
/* Delay information */ /* Delay information */
vtr::vector<CircuitModelId, std::vector<enum spice_model_delay_type>> delay_types_; vtr::vector<CircuitModelId, std::vector<enum spice_model_delay_type>> delay_types_;

View File

@ -7,6 +7,9 @@
/************************************************************************ /************************************************************************
* Create strong id for Circuit Models/Ports to avoid illegal type casting * 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" #include "vtr_strong_id.h"
struct circuit_model_id_tag; struct circuit_model_id_tag;
@ -19,3 +22,5 @@ typedef vtr::StrongId<circuit_edge_id_tag> CircuitEdgeId;
/* Short declaration of class */ /* Short declaration of class */
class CircuitLibrary; class CircuitLibrary;
#endif

View File

@ -102,6 +102,7 @@ enum e_spice_model_pass_gate_logic_type {
SPICE_MODEL_PASS_GATE_TRANSMISSION, SPICE_MODEL_PASS_GATE_TRANSMISSION,
SPICE_MODEL_PASS_GATE_TRANSISTOR, 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_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 NUM_CIRCUIT_MODEL_PASS_GATE_TYPES
}; };

View File

@ -1573,11 +1573,9 @@ CircuitLibrary build_circuit_library(int num_spice_model, t_spice_model* spice_m
/* Go spice_model by spice_model */ /* Go spice_model by spice_model */
for (int imodel = 0; imodel < num_spice_model; ++imodel) { for (int imodel = 0; imodel < num_spice_model; ++imodel) {
/* Add a spice model to the circuit_lib */ /* 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 */ /* Fill fundamental attributes */
/* Basic information*/ /* Basic information*/
circuit_lib.set_model_type(model_id, spice_models[imodel].type);
std::string name(spice_models[imodel].name); std::string name(spice_models[imodel].name);
circuit_lib.set_model_name(model_id, 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 */ /* Ports */
for (int iport = 0; iport < spice_models[imodel].num_port; ++iport) { 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 */ /* Fill fundamental attributes */
circuit_lib.set_port_type(model_id, port_id, spice_models[imodel].ports[iport].type); circuit_lib.set_port_size(port_id, spice_models[imodel].ports[iport].size);
circuit_lib.set_port_size(model_id, port_id, spice_models[imodel].ports[iport].size);
std::string port_prefix(spice_models[imodel].ports[iport].prefix); 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); 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) { if (NULL != spice_models[imodel].ports[iport].inv_prefix) {
std::string port_inv_prefix(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_mode_select(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_global(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_reset(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_set(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_config_enable(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_prog(port_id, TRUE == spice_models[imodel].ports[iport].is_prog);
if (NULL != spice_models[imodel].ports[iport].spice_model_name) { if (NULL != spice_models[imodel].ports[iport].spice_model_name) {
std::string port_model_name(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) { 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); 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) { if (NULL != spice_models[imodel].ports[iport].tri_state_map) {
std::string port_tri_state_map(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) { 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<size_t> port_lut_output_mask; std::vector<size_t> port_lut_output_mask;
for (int ipin = 0; ipin < spice_models[imodel].ports[iport].size; ++ipin) { 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]); 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) { 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);
} }
} }
} }

View File

@ -67,6 +67,19 @@ size_t MuxGraph::num_inputs() const {
return num_inputs; 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 */ /* Find the number of levels in the MUX graph */
size_t MuxGraph::num_levels() const { size_t MuxGraph::num_levels() const {
/* need to check if the graph is valid or not */ /* 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 */ /* Add output nodes to subgraph */
MuxNodeId to_node_subgraph = mux_graph.add_node(MUX_OUTPUT_NODE); 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 */ /* Update the node-to-node map */
node2node_map[root_node] = to_node_subgraph; 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]); MuxEdgeId edge_subgraph = mux_graph.add_edge(node2node_map[from_node_origin], node2node_map[root_node]);
edge2edge_map[edge_origin] = edge_subgraph; edge2edge_map[edge_origin] = edge_subgraph;
/* Configure edges */ /* 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]; 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; 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; return mux_graph;
} }
@ -300,7 +316,7 @@ MuxEdgeId MuxGraph::add_edge(const MuxNodeId& from_node, const MuxNodeId& to_nod
/* Push to the node list */ /* Push to the node list */
edge_ids_.push_back(edge); edge_ids_.push_back(edge);
/* Resize the other node-related vectors */ /* 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_mem_ids_.push_back(MuxMemId::INVALID());
edge_inv_mem_.push_back(false); 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, void MuxGraph::build_multilevel_mux_graph(const size_t& mux_size,
const size_t& num_levels, const size_t& num_inputs_per_branch, 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 */ /* Make sure mux_size for each branch is valid */
VTR_ASSERT(valid_mux_implementation_num_inputs(num_inputs_per_branch)); 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 */ /* Create an edge and connect the two nodes */
MuxEdgeId edge = add_edge(expand_node, seed_node); MuxEdgeId edge = add_edge(expand_node, seed_node);
/* Configure the edge */ /* 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 /* 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, * 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 --->+ * input_node --->+
*/ */
void MuxGraph::build_onelevel_mux_graph(const size_t& mux_size, 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 */ /* Make sure mux_size is valid */
VTR_ASSERT(valid_mux_implementation_num_inputs(mux_size)); 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); MuxEdgeId edge = add_edge(input_node, output_node);
/* Configure the edge */ /* Configure the edge */
edge_types_[edge] = pgl_type; edge_models_[edge] = pgl_model;
/* Create a memory bit*/ /* Create a memory bit*/
MuxMemId mem = add_mem(); MuxMemId mem = add_mem();
@ -574,11 +590,11 @@ void MuxGraph::build_mux_graph(const CircuitLibrary& circuit_lib,
size_t num_inputs_per_branch = 2; size_t num_inputs_per_branch = 2;
/* Build a multilevel mux graph */ /* 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; break;
} }
case SPICE_MODEL_STRUCTURE_ONELEVEL: { 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; break;
} }
case SPICE_MODEL_STRUCTURE_MULTILEVEL: { case SPICE_MODEL_STRUCTURE_MULTILEVEL: {
@ -588,7 +604,7 @@ void MuxGraph::build_mux_graph(const CircuitLibrary& circuit_lib,
/* Build a multilevel mux graph */ /* Build a multilevel mux graph */
build_multilevel_mux_graph(impl_mux_size, circuit_lib.mux_num_levels(circuit_model), build_multilevel_mux_graph(impl_mux_size, circuit_lib.mux_num_levels(circuit_model),
num_inputs_per_branch, num_inputs_per_branch,
circuit_lib.pass_gate_logic_type(circuit_model)); circuit_lib.pass_gate_logic_model(circuit_model));
break; break;
} }
default: default:

View File

@ -63,6 +63,8 @@ class MuxGraph {
public: /* Public accessors: Data query */ public: /* Public accessors: Data query */
/* Find the number of inputs in the MUX graph */ /* Find the number of inputs in the MUX graph */
size_t num_inputs() const; 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 */ /* Find the number of levels in the MUX graph */
size_t num_levels() const; size_t num_levels() const;
/* Find the number of SRAMs in the MUX graph */ /* Find the number of SRAMs in the MUX graph */
@ -88,10 +90,10 @@ class MuxGraph {
private: /* Private mutators : graph builders */ private: /* Private mutators : graph builders */
void build_multilevel_mux_graph(const size_t& mux_size, void build_multilevel_mux_graph(const size_t& mux_size,
const size_t& num_levels, const size_t& num_inputs_per_branch, 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 */ /* Build the graph for a given one-level multiplexer implementation */
void build_onelevel_mux_graph(const size_t& mux_size, 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 */ /* Build the graph for a given multiplexer model */
void build_mux_graph(const CircuitLibrary& circuit_lib, void build_mux_graph(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
@ -120,7 +122,7 @@ class MuxGraph {
vtr::vector<MuxEdgeId, MuxEdgeId> edge_ids_; /* Unique ids for each edge */ vtr::vector<MuxEdgeId, MuxEdgeId> edge_ids_; /* Unique ids for each edge */
vtr::vector<MuxEdgeId, std::vector<MuxNodeId>> edge_src_nodes_; /* source nodes drive this edge */ vtr::vector<MuxEdgeId, std::vector<MuxNodeId>> edge_src_nodes_; /* source nodes drive this edge */
vtr::vector<MuxEdgeId, std::vector<MuxNodeId>> edge_sink_nodes_; /* sink nodes this edge drives */ vtr::vector<MuxEdgeId, std::vector<MuxNodeId>> edge_sink_nodes_; /* sink nodes this edge drives */
vtr::vector<MuxEdgeId, enum e_spice_model_pass_gate_logic_type> edge_types_; /* type of each edge: tgate/pass-gate */ vtr::vector<MuxEdgeId, CircuitModelId> edge_models_; /* type of each edge: tgate/pass-gate */
vtr::vector<MuxEdgeId, MuxMemId> edge_mem_ids_; /* ids of memory bit that control the edge */ vtr::vector<MuxEdgeId, MuxMemId> edge_mem_ids_; /* ids of memory bit that control the edge */
vtr::vector<MuxEdgeId, bool> edge_inv_mem_; /* if the edge is controlled by an inverted output of a memory bit */ vtr::vector<MuxEdgeId, bool> edge_inv_mem_; /* if the edge is controlled by an inverted output of a memory bit */

View File

@ -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, t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const CircuitPortId& circuit_port) { const CircuitPortId& circuit_port) {
t_port* ret = NULL; t_port* ret = NULL;
size_t num_found = 0; 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 */ /* Search ports */
for (int iport = 0; iport < pb_type->num_ports; iport++) { for (int iport = 0; iport < pb_type->num_ports; iport++) {
/* Match the name and port size*/ /* Match the name and port size*/
if ( (0 == circuit_lib.port_prefix(circuit_model, circuit_port).compare(pb_type->ports[iport].name)) 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_model, circuit_port))) { && (size_t(pb_type->ports[iport].num_pins) == circuit_lib.port_size(circuit_port))) {
/* Match the type*/ /* Match the type*/
switch (circuit_lib.port_type(circuit_model, circuit_port)) { switch (circuit_lib.port_type(circuit_port)) {
case SPICE_MODEL_PORT_INPUT: case SPICE_MODEL_PORT_INPUT:
if ((IN_PORT == pb_type->ports[iport].type) if ((IN_PORT == pb_type->ports[iport].type)
&&(0 == pb_type->ports[iport].is_clock)) { &&(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; break;
default: default:
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for circuit model port(%s)!\n", 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); 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) { if (1 < num_found) {
vpr_printf(TIO_MESSAGE_ERROR, vpr_printf(TIO_MESSAGE_ERROR,
"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", "(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); 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 each port, find a SPICE model port, which has the same name and port size */
for (auto& port : circuit_lib.ports(circuit_model)) { 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, circuit_model, port); 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. /* Not every spice_model_port can find a mapped pb_type_port.
* Since a pb_type only includes necessary ports in technology mapping. * Since a pb_type only includes necessary ports in technology mapping.
* ports for physical designs may be ignored ! * ports for physical designs may be ignored !

View File

@ -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, t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const CircuitPortId& circuit_port); const CircuitPortId& circuit_port);
void link_circuit_library_to_arch(t_arch* arch, void link_circuit_library_to_arch(t_arch* arch,

View File

@ -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 <string>
#include "module_manager_fwd.h"
#include "device_port.h"
class ModuleManager {
private: /* Internal data */
vtr::vector<ModuleId, ModuleId> ids_;
vtr::vector<ModuleId, BasicPort> ports_;
vtr::vector<ModuleId, std::vector<ModuleId>> parents_;
vtr::vector<ModuleId, std::vector<ModuleId>> children_;
};
#endif

View File

@ -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<module_id_tag> ModuleId;
class ModuleManager;
#endif

View File

@ -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, chan_coordinator.get_x(), chan_coordinator.get_y(), itrack,
rr_sb.get_chan_node_direction(side_manager.get_side(), itrack))); rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)));
if (true == is_explicit_mapping) { 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)); fprintf(fp, "//----- %s side inputs: CLB output pins -----\n", convert_side_index_to_string(side));
/* Dump OPINs of adjacent CLBs */ /* Dump OPINs of adjacent CLBs */

View File

@ -1,3 +1,5 @@
#ifndef VERILOG_GLOBAL_H
#define VERILOG_GLOBAL_H
/* global parameters for dumping synthesizable verilog */ /* global parameters for dumping synthesizable verilog */
extern char* verilog_netlist_file_postfix; extern char* verilog_netlist_file_postfix;
@ -140,8 +142,10 @@ VERILOG_PORT_OUTPUT,
VERILOG_PORT_INOUT, VERILOG_PORT_INOUT,
VERILOG_PORT_WIRE, VERILOG_PORT_WIRE,
VERILOG_PORT_REG, VERILOG_PORT_REG,
VERILOG_PORT_CONKT VERILOG_PORT_CONKT,
NUM_VERILOG_PORT_TYPES
}; };
constexpr std::array<const char*, NUM_VERILOG_PORT_TYPES> VERILOG_PORT_TYPE_STRING = {{"input", "output", "inout", "wire", "reg", ""}}; /* string version of enum e_verilog_port_type */
enum e_verilog_tb_type { enum e_verilog_tb_type {
VERILOG_TB_TOP, VERILOG_TB_TOP,
@ -149,3 +153,5 @@ VERILOG_TB_BLIF_TOP,
VERILOG_TB_AUTOCHECK_TOP, VERILOG_TB_AUTOCHECK_TOP,
VERILOG_TB_FORMAL_VERIFICATION VERILOG_TB_FORMAL_VERIFICATION
}; };
#endif

View File

@ -5,12 +5,25 @@
* such as a branch in a multiplexer * such as a branch in a multiplexer
* and the full multiplexer * and the full multiplexer
**********************************************/ **********************************************/
#include <string>
#include "util.h" #include "util.h"
#include "vtr_assert.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 * Generate Verilog codes modeling an branch circuit
@ -20,7 +33,153 @@ static
void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp, void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const std::string& module_name,
const MuxGraph& mux_graph) { 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<CircuitPortId> tgate_input_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT);
std::vector<CircuitPortId> 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; 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, void generate_verilog_mux_branch_module(std::fstream& fp,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const size_t& mux_size,
const MuxGraph& mux_graph) { 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 */ /* Multiplexers built with different technology is in different organization */
switch (circuit_lib.design_tech_type(circuit_model)) { switch (circuit_lib.design_tech_type(circuit_model)) {
case SPICE_MODEL_DESIGN_CMOS: case SPICE_MODEL_DESIGN_CMOS:
if (true == circuit_lib.dump_structural_verilog(circuit_model)) { 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 { } else {
/* /*
dump_verilog_cmos_mux_one_basis_module(fp, mux_basis_subckt_name, dump_verilog_cmos_mux_one_basis_module(fp, mux_basis_subckt_name,

View File

@ -15,6 +15,7 @@
void generate_verilog_mux_branch_module(std::fstream& fp, void generate_verilog_mux_branch_module(std::fstream& fp,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model, const CircuitModelId& circuit_model,
const size_t& mux_size,
const MuxGraph& mux_graph); const MuxGraph& mux_graph);
#endif #endif

View File

@ -2854,7 +2854,8 @@ void dump_verilog_submodule_muxes(t_sram_orgz_info* cur_sram_orgz_info,
std::vector<MuxGraph> branch_mux_graphs = mux_graph.build_mux_branch_graphs(); std::vector<MuxGraph> branch_mux_graphs = mux_graph.build_mux_branch_graphs();
/* Create branch circuits, which are N:1 one-level or 2:1 tree-like MUXes */ /* Create branch circuits, which are N:1 one-level or 2:1 tree-like MUXes */
for (auto branch_mux_graph : branch_mux_graphs) { 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);
} }
} }

View File

@ -144,7 +144,7 @@ void dump_include_user_defined_verilog_netlists(FILE* fp,
return; return;
} }
void check_file_handler(const std::fstream& fp) { void check_file_handler(std::fstream& fp) {
/* Make sure we have a valid file handler*/ /* Make sure we have a valid file handler*/
/* Print out debugging information for if the file is not opened/created properly */ /* Print out debugging information for if the file is not opened/created properly */
if (!fp.is_open() || !fp.good()) { 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; return dumped_port_cnt;
} }
/* Dump all the global ports that are stored in the linked list /* Dump all the global ports that are stored in the linked list
* Return the number of ports that have been dumped * Return the number of ports that have been dumped
*/ */

View File

@ -10,7 +10,7 @@ void init_include_user_defined_verilog_netlists(t_spice spice);
void dump_include_user_defined_verilog_netlists(FILE* fp, void dump_include_user_defined_verilog_netlists(FILE* fp,
t_spice spice); 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, void dump_verilog_file_header(FILE* fp,
char* usage); 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); char determine_verilog_generic_port_split_sign(enum e_dump_verilog_port_type dump_port_type);
void dump_verilog_generic_port(FILE* fp, void dump_verilog_generic_port(FILE* fp,
enum e_dump_verilog_port_type dump_port_type, enum e_dump_verilog_port_type dump_port_type,
char* port_name, int port_lsb, int port_msb); char* port_name, int port_lsb, int port_msb);

View File

@ -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 <port_name>[<lsb>:<msb>]
* others require a format of <port_type> [<lsb>:<msb>] <port_name>
*/
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;
}

View File

@ -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 <string>
#include "device_port.h"
std::string generate_verilog_port(const enum e_dump_verilog_port_type& dump_port_type,
const BasicPort& port_info);
#endif