complete parsers for ports

This commit is contained in:
tangxifan 2019-08-09 21:00:41 -06:00
parent 2c7d6e3de4
commit c004699a14
6 changed files with 176 additions and 68 deletions

View File

@ -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));

View File

@ -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 */

View File

@ -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) {

View File

@ -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 */
};

View File

@ -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
***********************************************************************/

View File

@ -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