complete parsers for ports
This commit is contained in:
parent
2c7d6e3de4
commit
c004699a14
|
@ -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<CircuitPortId> 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<std::string> input_port_names = input_port_parser.port_names();
|
||||
|
||||
/* Find port ids with given names */
|
||||
std::vector<CircuitPortId> 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<CircuitPortId> 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<std::string> output_port_names = output_port_parser.port_names();
|
||||
|
||||
/* Find port ids with given names */
|
||||
std::vector<CircuitPortId> 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<BasicPort> input_ports = input_port_parser.ports();
|
||||
std::vector<CircuitPortId> input_port_ids;
|
||||
std::vector<size_t> 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<BasicPort> output_ports = output_port_parser.ports();
|
||||
std::vector<CircuitPortId> output_port_ids;
|
||||
std::vector<size_t> 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));
|
||||
|
|
|
@ -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<CircuitPortId> get_delay_info_input_port_ids(const CircuitModelId& circuit_model_id,
|
||||
const enum spice_model_delay_type& delay_type) const;
|
||||
std::vector<CircuitPortId> 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 */
|
||||
|
|
|
@ -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) {
|
|
@ -5,6 +5,8 @@
|
|||
#ifndef DEVICE_PORT_H
|
||||
#define DEVICE_PORT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
/* 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 */
|
||||
};
|
|
@ -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<BasicPort> 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 <port_name> and <pin_string> */
|
||||
std::vector<std::string> 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
|
||||
***********************************************************************/
|
||||
|
|
|
@ -50,12 +50,19 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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. <port_name>[<LSB>:<MSB>]
|
||||
* 2. <port_name>[<MSB>:<LSB>]
|
||||
|
@ -64,13 +71,12 @@
|
|||
* 5. <port_name>
|
||||
* 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<std::string> 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<char> bracket_;
|
||||
char delim_;
|
||||
std::string port_name_;
|
||||
vtr::Point<size_t> 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<BasicPort> 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<BasicPort> ports_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue