diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp index dd7862c3c..46df9d44a 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp @@ -38,6 +38,7 @@ #include "vtr_assert.h" +#include "port_parser.h" #include "circuit_library.h" /************************************************************************ @@ -1409,69 +1410,58 @@ void CircuitLibrary::set_edge_tfall(const CircuitModelId& circuit_model_id, cons return; } -/* Decode input names of delay_info to CircuitPorts */ -std::vector CircuitLibrary::get_delay_info_input_port_ids(const CircuitModelId& circuit_model_id, - const enum spice_model_delay_type& delay_type) const { - /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); - /* Parse the string */ -// MultiPortParser input_port_parser(delay_in_port_names[circuit_model_id][size_t(delay_type)]); -// input_port_parser.add_delima(" "); -// std::vector input_port_names = input_port_parser.port_names(); - - /* Find port ids with given names */ - std::vector input_port_ids; -// for (const auto& name : input_port_names) { - /* We must have a valid port ! */ -// VTR_ASSERT_SAFE(CIRCUIT_PORT_OPEN_ID != port(circuit_model_id, name)); - /* Convert to CircuitPortId */ -// input_port_ids.push_back(port(circuit_model_id, name)); - /* This must be an input port! */ -// VTR_ASSERT_SAFE(true == is_input_port(circuit_model_id, input_port_ids.back())); -// } - return input_port_ids; -} - -/* Decode input names of delay_info to CircuitPorts */ -std::vector CircuitLibrary::get_delay_info_output_port_ids(const CircuitModelId& circuit_model_id, - const enum spice_model_delay_type& delay_type) const { - /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); - /* Parse the string */ -// MultiPortParser output_port_parser(delay_out_port_names[circuit_model_id][size_t(delay_type)]); -// output_port_parser.add_delima(" "); -// std::vector output_port_names = output_port_parser.port_names(); - - /* Find port ids with given names */ - std::vector output_port_ids; -// for (const auto& name : output_port_names) { - /* We must have a valid port ! */ -// VTR_ASSERT_SAFE(CIRCUIT_PORT_OPEN_ID != port(circuit_model_id, name)); - /* Convert to CircuitPortId */ -// output_port_ids.push_back(port(circuit_model_id, name)); - /* This must be an output port! */ -// VTR_ASSERT_SAFE(true == is_output_port(circuit_model_id, output_port_ids.back())); -// } - return output_port_ids; -} - - /* Annotate delay values on a timing graph */ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& circuit_model_id) { /* validate the circuit_model_id */ VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); /* Go one delay_info by another */ - for (size_t i_delay_type = 0; i_delay_type < delay_types_[circuit_model_id].size(); ++i_delay_type) { + for (const auto& delay_type : delay_types_[circuit_model_id]) { /* Parse the input port names and output names. * We will store the parsing results in vectors: * 1. vector for port ids for each port name * 2. vector for pin ids for each port name */ + + /* Parse the string for inputs */ + MultiPortParser input_port_parser(delay_in_port_names_[circuit_model_id][size_t(delay_type)]); + std::vector input_ports = input_port_parser.ports(); std::vector input_port_ids; std::vector input_pin_ids; + /* Check each element */ + for (const auto& port_info : input_ports) { + /* Try to find a port by the given name */ + CircuitPortId port_id = port(circuit_model_id, port_info.get_name()); + /* We must have a valid port and Port width must be 1! */ + VTR_ASSERT_SAFE( (CIRCUIT_PORT_OPEN_ID != port_id) && (1 == port_info.get_width()) ); + /* The pin id should be valid! */ + VTR_ASSERT_SAFE(true == valid_circuit_pin_id(circuit_model_id, port_id, port_info.get_lsb())); + /* This must be an input port! */ + VTR_ASSERT_SAFE(true == is_input_port(circuit_model_id, port_id)); + /* Push to */ + input_port_ids.push_back(port_id); + input_pin_ids.push_back(port_info.get_lsb()); + } + /* Parse the string for outputs */ + MultiPortParser output_port_parser(delay_out_port_names_[circuit_model_id][size_t(delay_type)]); + std::vector output_ports = output_port_parser.ports(); std::vector output_port_ids; std::vector output_pin_ids; + /* Check each element */ + for (const auto& port_info : output_ports) { + /* Try to find a port by the given name */ + CircuitPortId port_id = port(circuit_model_id, port_info.get_name()); + /* We must have a valid port and Port width must be 1! */ + VTR_ASSERT_SAFE( (CIRCUIT_PORT_OPEN_ID != port_id) && (1 == port_info.get_width()) ); + /* The pin id should be valid! */ + VTR_ASSERT_SAFE(true == valid_circuit_pin_id(circuit_model_id, port_id, port_info.get_lsb())); + /* This must be an output port! */ + VTR_ASSERT_SAFE(true == is_output_port(circuit_model_id, port_id)); + /* Push to */ + output_port_ids.push_back(port_id); + output_pin_ids.push_back(port_info.get_lsb()); + } + } return; } @@ -1539,6 +1529,12 @@ bool CircuitLibrary::valid_circuit_port_id(const CircuitModelId& circuit_model_i return ( size_t(circuit_port_id) < port_ids_[circuit_model_id].size() ) && ( circuit_port_id == port_ids_[circuit_model_id][circuit_port_id] ); } +bool CircuitLibrary::valid_circuit_pin_id(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const size_t& pin_id) const { + /* validate the circuit_model_id */ + VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + return ( size_t(pin_id) < port_size(circuit_model_id, circuit_port_id) ); +} + bool CircuitLibrary::valid_delay_type(const CircuitModelId& circuit_model_id, const enum spice_model_delay_type& delay_type) const { /* validate the circuit_model_id */ VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h index 72300d4e1..8002c77c0 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h @@ -431,10 +431,6 @@ class CircuitLibrary { const CircuitPortId& to_port, const size_t& to_pin); void set_edge_trise(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id, const float& trise); void set_edge_tfall(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id, const float& tfall); - std::vector get_delay_info_input_port_ids(const CircuitModelId& circuit_model_id, - const enum spice_model_delay_type& delay_type) const; - std::vector get_delay_info_output_port_ids(const CircuitModelId& circuit_model_id, - const enum spice_model_delay_type& delay_type) const; void set_timing_graph_delays(const CircuitModelId& circuit_model_id); public: /* Internal mutators: build fast look-ups */ void build_circuit_model_lookup(); @@ -443,6 +439,7 @@ class CircuitLibrary { /* Validators */ bool valid_circuit_model_id(const CircuitModelId& circuit_model_id) const; bool valid_circuit_port_id(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; + bool valid_circuit_pin_id(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const size_t& pin_id) const; bool valid_delay_type(const CircuitModelId& circuit_model_id, const enum spice_model_delay_type& delay_type) const; bool valid_circuit_edge_id(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id) const; /* Invalidators */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/device_port.cpp b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.cpp similarity index 96% rename from vpr7_x2p/vpr/SRC/fpga_x2p/base/device_port.cpp rename to vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.cpp index 6ab88ac94..2e181fce5 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/device_port.cpp +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.cpp @@ -37,14 +37,26 @@ size_t BasicPort::get_lsb() const { return lsb_; } +/* get the name */ +std::string BasicPort::get_name() const { + return name_; +} + /* Mutators */ /* copy */ void BasicPort::set(const BasicPort& basic_port) { + name_ = basic_port.get_name(); lsb_ = basic_port.get_lsb(); msb_ = basic_port.get_msb(); return; } + +/* set the port LSB and MSB */ +void BasicPort::set_name(const std::string& name) { + name_ = name; + return; +} /* set the port LSB and MSB */ void BasicPort::set_width(size_t width) { diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/device_port.h b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.h similarity index 93% rename from vpr7_x2p/vpr/SRC/fpga_x2p/base/device_port.h rename to vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.h index 905a4d0bf..fbf887421 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/device_port.h +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.h @@ -5,6 +5,8 @@ #ifndef DEVICE_PORT_H #define DEVICE_PORT_H +#include + /* A basic port */ class BasicPort { public: /* Constructors */ @@ -14,8 +16,11 @@ class BasicPort { size_t get_width() const; /* get the port width */ size_t get_msb() const; /* get the LSB */ size_t get_lsb() const; /* get the LSB */ + std::string get_name() const; /* get the name */ + bool is_valid() const; /* check if port size is valid > 0 */ public: /* Mutators */ void set(const BasicPort& basic_port); /* copy */ + void set_name(const std::string& name); /* set the port LSB and MSB */ void set_width(size_t width); /* set the port LSB and MSB */ void set_width(size_t lsb, size_t msb); /* set the port LSB and MSB */ void set_lsb(size_t lsb); @@ -28,8 +33,8 @@ class BasicPort { void combine(const BasicPort& port); /* Combine two ports */ private: /* internal functions */ void make_invalid(); /* Make a port invalid */ - bool is_valid() const; /* check if port size is valid > 0 */ private: /* Internal Data */ + std::string name_; /* Name of this port */ size_t msb_; /* Most Significant Bit of this port */ size_t lsb_; /* Least Significant Bit of this port */ }; diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.cpp b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.cpp index 945cac4d1..c9e5eff16 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.cpp +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.cpp @@ -34,7 +34,7 @@ ***********************************************************************/ /************************************************************************ - * Member functions for PortParser class + * Member functions for Port parsers ***********************************************************************/ #include "string.h" @@ -46,6 +46,10 @@ #include "port_parser.h" +/************************************************************************ + * Member functions for PortParser class + ***********************************************************************/ + /************************************************************************ * Constructors ***********************************************************************/ @@ -64,6 +68,9 @@ std::string PortParser::data() const { return data_; } +BasicPort PortParser::port() const { + return port_; +} /************************************************************************ * Public Mutators @@ -87,12 +94,11 @@ void PortParser::parse() { /* Make sure we have a port name! */ VTR_ASSERT_SAFE ((1 == port_tokens.size()) || (2 == port_tokens.size())); /* Store the port name! */ - port_name_ = port_tokens[0]; + port_.set_name(port_tokens[0]); /* If we only have one token */ if (1 == port_tokens.size()) { - pin_range_.set_x(-1); - pin_range_.set_y(-1); + port_.set_width(0); return; /* We can finish here */ } @@ -109,17 +115,15 @@ void PortParser::parse() { /* Check if we have LSB and MSB or just one */ if ( 1 == pin_tokens.size() ) { /* Single pin */ - pin_range_.set_x(stoi(pin_tokens[0])); - pin_range_.set_y(stoi(pin_tokens[0])); + port_.set_width(stoi(pin_tokens[0]), stoi(pin_tokens[0])); } else if ( 2 == pin_tokens.size() ) { /* A number of pin */ - pin_range_.set_x(stoi(pin_tokens[0])); - pin_range_.set_y(stoi(pin_tokens[1])); + port_.set_width(stoi(pin_tokens[0]), stoi(pin_tokens[1])); } - /* Reorder to ensure LSB <= MSB */ - if (pin_range_.x() > pin_range_.y()) { - pin_range_.swap(); + /* Re-order to ensure LSB <= MSB */ + if (false == port_.is_valid()) { + port_.revert(); } return; @@ -136,6 +140,74 @@ void PortParser::set_default_delim() { return; } +/************************************************************************ + * Member functions for MultiPortParser class + ***********************************************************************/ + +/************************************************************************ + * Constructors + ***********************************************************************/ +MultiPortParser::MultiPortParser (const std::string& data) { + set_data(data); + set_default_delim(); + parse(); +} + +/************************************************************************ + * Public Accessors + ***********************************************************************/ +/* Get the data string */ +std::string MultiPortParser::data() const { + return data_; +} + +std::vector MultiPortParser::ports() const { + return ports_; +} + +/************************************************************************ + * Public Mutators + ***********************************************************************/ +void MultiPortParser::set_data(const std::string& data) { + data_ = data; + parse(); + return; +} + +/************************************************************************ + * Internal Mutators + ***********************************************************************/ +/* Split the data line into fragments and parse one by one */ +void MultiPortParser::parse() { + /* Clear content */ + clear(); + + /* Create a tokenizer */ + StringToken tokenizer(data_); + + /* Split the data into and */ + std::vector port_tokens = tokenizer.split(delim_); + + /* Use PortParser for each token */ + for (const auto& port : port_tokens) { + PortParser port_parser(port); + /* Get the port name, LSB and MSB */ + ports_.push_back(port_parser.port()); + } + + return; +} + +void MultiPortParser::set_default_delim() { + delim_ = ' '; + return; +} + +void MultiPortParser::clear() { + ports_.clear(); + return; +} + /************************************************************************ * End of file : port_parser.cpp ***********************************************************************/ diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.h b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.h index 3845b2c84..ddd527559 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.h +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.h @@ -50,12 +50,19 @@ #include #include +#include "vtr_geometry.h" + +#include "device_port.h" #include "string_token.h" /************************************************************************ * This file includes parsers for port definition in the architecture XML * language. Note that it is also compatiable to Verilog syntax. * It means we may reuse this for constructing a structural Verilog parser + ***********************************************************************/ + +/************************************************************************ + * Class PortParser: single port parser * Supported port definition: * 1. [:] * 2. [:] @@ -64,13 +71,12 @@ * 5. * In case 4 and 5, we will assign (-1,-1) for LSB and MSB ***********************************************************************/ - class PortParser{ public : /* Constructors*/ PortParser (const std::string& data); public : /* Public Accessors */ std::string data() const; - std::vector split(); + BasicPort port() const; public : /* Public Mutators */ void set_data(const std::string& data); private : /* Private Mutators */ @@ -81,8 +87,28 @@ class PortParser{ std::string data_; /* Lines to be splited */ vtr::Point bracket_; char delim_; - std::string port_name_; - vtr::Point pin_range_; + BasicPort port_; +}; + +/************************************************************************ + * MultiPortParser: a parser for multiple ports in one line + ***********************************************************************/ +class MultiPortParser { + public : /* Constructors*/ + MultiPortParser (const std::string& data); + public : /* Public Accessors */ + std::string data() const; + std::vector ports() const; + public : /* Public Mutators */ + void set_data(const std::string& data); + private : /* Private Mutators */ + void parse(); + void set_default_delim(); + void clear(); + private: /* Internal data */ + std::string data_; /* Lines to be splited */ + char delim_; + std::vector ports_; }; #endif