Merge remote-tracking branch 'upstream/master'

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
This commit is contained in:
Matt Liberty 2024-03-28 11:40:49 -07:00
commit 95276f8731
27 changed files with 534 additions and 188 deletions

3
.gitignore vendored
View File

@ -6,9 +6,12 @@ TAGS
.#*
.~lock.*\.*#
.DS_Store
.vscode
.idea
Makefile
gmon.out
cmake-build-debug
build
pvt

View File

@ -30,6 +30,8 @@ project(STA VERSION 2.5.0
option(USE_CUDD "Use CUDD BDD package")
option(CUDD_DIR "CUDD BDD package directory")
option(USE_TCL_READLINE "Use TCL readliine package")
option(USE_SANITIZE "Compile with santize address enabled")
# Turn on to debug compiler args.
set(CMAKE_VERBOSE_MAKEFILE OFF)
@ -333,8 +335,6 @@ add_custom_command(OUTPUT ${STA_TCL_INIT}
# Do not use REQUIRED because it also requires TK, which is not used by OpenSTA.
find_package(TCL)
option(USE_TCL_READLINE "Use TCL readliine package")
set(TCL_READLINE 0)
# check for tclReadline
if (USE_TCL_READLINE)
@ -539,6 +539,12 @@ target_include_directories(OpenSTA
# common to gcc/clang
set(CXX_FLAGS -Wall -Wextra -pedantic -Wcast-qual -Wredundant-decls -Wformat-security)
if(USE_SANITIZE)
message(STATUS "Sanitize: ${USE_SANITIZE}")
set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=address;-fno-omit-frame-pointer;-fno-common")
set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=address")
endif()
target_compile_options(OpenSTA
PRIVATE
$<$<CXX_COMPILER_ID:GNU>:${CXX_FLAGS}>

View File

@ -152,7 +152,7 @@ Use the following commands to checkout the git repository and build the
OpenSTA library and excutable.
```
git clone https://github.com/The-OpenROAD-Project/OpenSTA.git
git clone https://github.com/parallaxsw/OpenSTA.git
cd OpenSTA
mkdir build
cd build

View File

@ -1158,11 +1158,10 @@ GraphDelayCalc::loadCap(const Pin *drvr_pin,
const DcalcAnalysisPt *dcalc_ap) const
{
const MinMax *min_max = dcalc_ap->constraintMinMax();
float load_cap = 0.0;
float load_cap = min_max->initValue();
for (auto drvr_rf : RiseFall::range()) {
float cap = loadCap(drvr_pin, drvr_rf, dcalc_ap);
if (min_max->compare(cap, load_cap))
load_cap = cap;
load_cap = min_max->minMax(cap, load_cap);
}
arc_delay_calc_->finishDrvrPin();
return load_cap;

View File

@ -38,6 +38,7 @@ class LibertyCell;
class LibertyPort;
typedef Map<const char*, ConcreteCell*, CharPtrLess> ConcreteCellMap;
typedef Map<string, string> AttributeMap;
typedef Vector<ConcretePort*> ConcretePortSeq;
typedef Map<const char*, ConcretePort*, CharPtrLess> ConcretePortMap;
typedef ConcreteCellMap::ConstIterator ConcreteLibraryCellIterator;
@ -105,6 +106,9 @@ public:
ConcreteCellPortBitIterator *portBitIterator() const;
bool isLeaf() const { return is_leaf_; }
void setIsLeaf(bool is_leaf);
void setAttribute(const string &key,
const string &value);
string getAttribute(const string &key) const;
// Cell acts as port factory.
ConcretePort *makePort(const char *name);
@ -158,6 +162,7 @@ protected:
// Port bit count (expanded buses).
int port_bit_count_;
bool is_leaf_;
AttributeMap attribute_map_;
private:
friend class ConcreteLibrary;

View File

@ -38,6 +38,7 @@ class ConcreteBindingTbl;
class ConcreteLibertyLibraryIterator;
typedef Vector<ConcreteLibrary*> ConcreteLibrarySeq;
typedef Map<string, string> AttributeMap;
typedef Map<const char*, ConcreteLibrary*, CharPtrLess> ConcreteLibraryMap;
typedef ConcreteLibrarySeq::ConstIterator ConcreteLibraryIterator;
typedef Map<const char *, ConcreteInstance*,
@ -74,6 +75,8 @@ public:
const PatternMatch *pattern) const override;
const char *name(const Cell *cell) const override;
string getAttribute(const Cell *cell,
const string &key) const override;
ObjectId id(const Cell *cell) const override;
Library *library(const Cell *cell) const override;
LibertyCell *libertyCell(Cell *cell) const override;
@ -108,6 +111,8 @@ public:
PortMemberIterator *memberIterator(const Port *port) const override;
const char *name(const Instance *instance) const override;
string getAttribute(const Instance *inst,
const string &key) const override;
ObjectId id(const Instance *instance) const override;
Cell *cell(const Instance *instance) const override;
Instance *parent(const Instance *instance) const override;
@ -175,6 +180,9 @@ public:
const char *name) override;
void setIsLeaf(Cell *cell,
bool is_leaf) override;
void setAttribute(Cell *cell,
const string &key,
const string &value) override;
Port *makePort(Cell *cell,
const char *name) override;
Port *makeBusPort(Cell *cell,
@ -206,6 +214,9 @@ public:
Pin *connect(Instance *inst,
LibertyPort *port,
Net *net) override;
void setAttribute(Instance *inst,
const string &key,
const string &value) override;
void disconnectPin(Pin *pin) override;
void deletePin(Pin *pin) override;
Net *makeNet(const char *name,
@ -285,6 +296,9 @@ public:
InstanceNetIterator *netIterator() const;
Instance *findChild(const char *name) const;
InstanceChildIterator *childIterator() const;
void setAttribute(const string &key,
const string &value);
string getAttribute(const string &key) const;
void addChild(ConcreteInstance *child);
void deleteChild(ConcreteInstance *child);
void addPin(ConcretePin *pin);
@ -310,6 +324,7 @@ protected:
ConcretePinSeq pins_;
ConcreteInstanceChildMap *children_;
ConcreteInstanceNetMap *nets_;
AttributeMap attribute_map_;
private:
friend class ConcreteNetwork;

View File

@ -49,6 +49,7 @@ public:
const char *asString() const { return name_; }
int index() const { return index_; }
float initValue() const { return init_value_; }
int initValueInt() const { return init_value_int_; }
// Max value1 > value2, Min value1 < value2.
bool compare(float value1,
float value2) const;
@ -74,12 +75,14 @@ private:
MinMax(const char *name,
int index,
float init_value,
int init_value_int,
bool (*compare)(float value1,
float value2));
const char *name_;
int index_;
float init_value_;
int init_value_int_;
bool (*compare_)(float value1,
float value2);

View File

@ -144,6 +144,9 @@ public:
virtual Cell *cell(LibertyCell *cell) const = 0;
// Filename may return null.
virtual const char *filename(const Cell *cell) = 0;
// Attributes can be null
virtual string getAttribute(const Cell *cell,
const string &key) const = 0;
// Name can be a simple, bundle, bus, or bus bit name.
virtual Port *findPort(const Cell *cell,
const char *name) const = 0;
@ -206,6 +209,8 @@ public:
const PatternMatch *pattern) const;
virtual InstanceSeq findInstancesHierMatching(const Instance *instance,
const PatternMatch *pattern) const;
virtual string getAttribute(const Instance *inst,
const string &key) const = 0;
// Hierarchical path name.
virtual const char *pathName(const Instance *instance) const;
bool pathNameLess(const Instance *inst1,
@ -544,6 +549,12 @@ public:
const char *name) = 0;
virtual void setIsLeaf(Cell *cell,
bool is_leaf) = 0;
virtual void setAttribute(Cell *cell,
const string &key,
const string &value) = 0;
virtual void setAttribute(Instance *instance,
const string &key,
const string &value) = 0;
virtual Port *makePort(Cell *cell,
const char *name) = 0;
virtual Port *makeBusPort(Cell *cell,

View File

@ -45,6 +45,8 @@ public:
const PatternMatch *pattern) const override;
const char *name(const Cell *cell) const override;
string getAttribute(const Cell *cell,
const string &key) const override;
ObjectId id(const Cell *cell) const override;
Library *library(const Cell *cell) const override;
LibertyCell *libertyCell(Cell *cell) const override;
@ -80,6 +82,8 @@ public:
bool hasMembers(const Port *port) const override;
ObjectId id(const Instance *instance) const override;
string getAttribute(const Instance *inst,
const string &key) const override;
Instance *topInstance() const override;
Cell *cell(const Instance *instance) const override;
Instance *parent(const Instance *instance) const override;

View File

@ -268,6 +268,22 @@ ConcreteCell::setIsLeaf(bool is_leaf)
is_leaf_ = is_leaf;
}
void
ConcreteCell::setAttribute(const string &key,
const string &value)
{
attribute_map_.insert(key, value);
}
string
ConcreteCell::getAttribute(const string &key) const
{
if (attribute_map_.hasKey(key)) {
return attribute_map_.findKey(key);
}
return "";
}
ConcretePort *
ConcreteCell::findPort(const char *name) const
{

View File

@ -557,6 +557,15 @@ ConcreteNetwork::setIsLeaf(Cell *cell,
ccell->setIsLeaf(is_leaf);
}
void
ConcreteNetwork::setAttribute(Cell *cell,
const string &key,
const string &value)
{
ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
ccell->setAttribute(key, value);
}
Library *
ConcreteNetwork::library(const Cell *cell) const
{
@ -597,6 +606,14 @@ ConcreteNetwork::filename(const Cell *cell)
return ccell->filename();
}
string
ConcreteNetwork::getAttribute(const Cell *cell,
const string &key) const
{
const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
return ccell->getAttribute(key);
}
Port *
ConcreteNetwork::findPort(const Cell *cell,
const char *name) const
@ -921,6 +938,14 @@ ConcreteNetwork::id(const Instance *instance) const
return inst->id();
}
string
ConcreteNetwork::getAttribute(const Instance *inst,
const string &key) const
{
const ConcreteInstance *cinst = reinterpret_cast<const ConcreteInstance*>(inst);
return cinst->getAttribute(key);
}
Cell *
ConcreteNetwork::cell(const Instance *instance) const
{
@ -1325,6 +1350,15 @@ ConcreteNetwork::connect(Instance *inst,
return connect(inst, reinterpret_cast<Port*>(port), net);
}
void
ConcreteNetwork::setAttribute(Instance *inst,
const string &key,
const string &value)
{
ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
cinst->setAttribute(key, value);
}
Pin *
ConcreteNetwork::connect(Instance *inst,
Port *port,
@ -1648,6 +1682,22 @@ ConcreteInstance::childIterator() const
return new ConcreteInstanceChildIterator(children_);
}
void
ConcreteInstance::setAttribute(const string &key,
const string &value)
{
attribute_map_.insert(key, value);
}
string
ConcreteInstance::getAttribute(const string &key) const
{
if (attribute_map_.hasKey(key)) {
return attribute_map_.findKey(key);
}
return "";
}
void
ConcreteInstance::addChild(ConcreteInstance *child)
{

View File

@ -122,6 +122,13 @@ NetworkNameAdapter::id(const Cell *cell) const
return network_->id(cell);
}
string
NetworkNameAdapter::getAttribute(const Cell *cell,
const string &key) const
{
return network_->getAttribute(cell, key);
}
Library *
NetworkNameAdapter::library(const Cell *cell) const
{
@ -327,6 +334,13 @@ NetworkNameAdapter::cell(const Instance *instance) const
return network_->cell(instance);
}
string
NetworkNameAdapter::getAttribute(const Instance *inst,
const string &key) const
{
return network_->getAttribute(inst, key);
}
Instance *
NetworkNameAdapter::parent(const Instance *instance) const
{

View File

@ -231,8 +231,7 @@ ReadVcdActivities::findVarActivity(const VcdValues &var_values,
if (prev_value == '1')
high_time += time_max - prev_time;
duty = static_cast<double>(high_time) / time_max;
activity = transition_count
/ (time_max * vcd_.timeUnitScale() / clk_period_);
activity = transition_count / (time_max * vcd_.timeScale() / clk_period_);
}
void
@ -240,7 +239,7 @@ ReadVcdActivities::checkClkPeriod(const Pin *pin,
double transition_count)
{
VcdTime time_max = vcd_.timeMax();
double sim_period = time_max * vcd_.timeUnitScale() / (transition_count / 2.0);
double sim_period = time_max * vcd_.timeScale() / (transition_count / 2.0);
ClockSet *clks = sdc_->findLeafPinClocks(pin);
if (clks) {

View File

@ -135,12 +135,14 @@ VcdReader::parseTimescale()
vector<string> tokens = readStmtTokens();
if (tokens.size() == 1) {
size_t last;
vcd_->setTimeScale(std::stod(tokens[0], &last));
double time_scale = std::stod(tokens[0], &last);
setTimeUnit(tokens[0].substr(last));
vcd_->setTimeScale(time_scale * vcd_->timeUnitScale());
}
else if (tokens.size() == 2) {
vcd_->setTimeScale(std::stod(tokens[0]));
setTimeUnit(tokens[1]);
double time_scale = std::stod(tokens[0]);
vcd_->setTimeScale(time_scale * vcd_->timeUnitScale());
}
else
report_->fileError(801, filename_, stmt_line_, "timescale syntax error.");

View File

@ -3705,7 +3705,7 @@ Sta::portExtCaps(const Port *port,
bool fanout_exists = false;
pin_cap = min_max->initValue();
wire_cap = min_max->initValue();
fanout = min_max->initValue();
fanout = min_max->initValueInt();
for (RiseFall *rf : RiseFall::range()) {
float pin_cap1, wire_cap1;
int fanout1;

View File

@ -140,26 +140,26 @@ proc set_cmd_units { args } {
set_unit_values "distance" -distance "m" keys
}
proc set_unit_values { unit key unit_name key_var } {
proc set_unit_values { unit key suffix key_var } {
upvar 1 $key_var keys
if { [info exists keys($key)] } {
set value $keys($key)
if { [string equal -nocase $value $unit_name] } {
set_cmd_unit_scale $unit 1.0
} else {
set prefix [string index $value 0]
set suffix [string range $value 1 end]
# unit includes "1" prefix
if { [string is digit $prefix] } {
set prefix [string index $value 1]
set suffix [string range $value 2 end]
}
if { [string equal -nocase $suffix $unit_name] } {
set scale [unit_prefix_scale $unit $prefix]
set_cmd_unit_scale $unit $scale
set suffix_length [string length $suffix]
set arg_suffix [string range $value end-[expr $suffix_length - 1] end]
if { [string match -nocase $arg_suffix $suffix] } {
set arg_prefix [string range $value 0 end-$suffix_length]
if { [regexp "^(10*)?(\[Mkmunpf\])?$" $arg_prefix ignore mult prefix] } {
#puts "$arg_prefix '$mult' '$prefix'"
if { $mult == "" } {
set mult 1
}
set scale [unit_prefix_scale $unit $prefix ]
set_cmd_unit_scale $unit $scale
} else {
sta_error 163 "unknown $unit unit '$suffix'."
sta_error 343 "unknown unit $unit prefix '${arg_prefix}'."
}
} else {
sta_error 501 "incorrect unit suffix '$arg_suffix'."
}
if [info exists keys(-digits)] {
set_cmd_unit_digits $unit $keys(-digits)

View File

@ -235,51 +235,44 @@ proc set_units { args } {
check_unit "current" -current "A" keys
check_unit "power" -power "W" keys
check_unit "distance" -distance "m" keys
check_unit "power" -power "w" keys
}
proc check_unit { unit key unit_name key_var } {
proc check_unit { unit key suffix key_var } {
upvar 1 $key_var keys
if { [info exists keys($key)] } {
set value $keys($key)
if { [string equal -nocase $value $unit_name] } {
check_unit_scale $unit 1.0
} else {
set prefix [string index $value 0]
set suffix [string range $value 1 end]
# unit includes "1" prefix
if { [string is digit $prefix] } {
set prefix [string index $value 1]
set suffix [string range $value 2 end]
}
if { [string equal -nocase $suffix $unit_name] } {
set scale [unit_prefix_scale $unit $prefix]
check_unit_scale $unit $scale
set suffix_length [string length $suffix]
set arg_suffix [string range $value end-[expr $suffix_length - 1] end]
if { [string match -nocase $arg_suffix $suffix] } {
set arg_prefix [string range $value 0 end-$suffix_length]
if { [regexp "^(10*)?(\[Mkmunpf\])?$" $arg_prefix ignore mult prefix] } {
#puts "$arg_prefix '$mult' '$prefix'"
if { $mult == "" } {
set mult 1
}
set scale [unit_prefix_scale $unit $prefix ]
check_unit_scale $unit [expr $scale * $mult]
} else {
sta_error 343 "unknown unit $unit '$suffix'."
sta_error 343 "unknown unit $unit prefix '${arg_prefix}'."
}
} else {
sta_error 501 "incorrect unit suffix '$arg_suffix'."
}
}
}
proc unit_prefix_scale { unit prefix } {
if { [string equal $prefix "M"] } {
return 1E+6
} elseif { [string equal $prefix "k"] } {
return 1E+3
} elseif { [string equal $prefix "m"] } {
return 1E-3
} elseif { [string equal $prefix "u"] } {
return 1E-6
} elseif { [string equal $prefix "n"] } {
return 1E-9
} elseif { [string equal $prefix "p"] } {
return 1E-12
} elseif { [string equal $prefix "f"] } {
return 1E-15
} else {
sta_error 344 "unknown $unit prefix '$prefix'."
switch -exact -- $prefix {
"M" { return 1E+6 }
"k" { return 1E+3 }
"" { return 1E+0 }
"m" { return 1E-3 }
"u" { return 1E-6 }
"n" { return 1E-9 }
"p" { return 1E-12 }
"f" { return 1E-15 }
}
sta_error 344 "unknown $unit prefix '$prefix'."
}
proc check_unit_scale { unit scale } {

View File

@ -4180,11 +4180,13 @@ void finish() { delete self; }
} // LibertyLibraryIterator methods
%extend Cell {
const char *name() { return cmdNetwork()->name(self); }
Library *library() { return cmdNetwork()->library(self); }
LibertyCell *liberty_cell() { return cmdNetwork()->libertyCell(self); }
bool is_leaf() { return cmdNetwork()->isLeaf(self); }
CellPortIterator *
port_iterator() { return cmdNetwork()->portIterator(self); }
string get_attribute(const char *key) { return cmdNetwork()->getAttribute(self, key); }
Port *
find_port(const char *name)
@ -4409,6 +4411,7 @@ find_pin(const char *name)
{
return cmdLinkedNetwork()->findPin(self, name);
}
string get_attribute(const char *key) { return cmdNetwork()->getAttribute(self, key); }
} // Instance methods
%extend InstanceChildIterator {

View File

@ -122,6 +122,7 @@ record_example_tests {
}
record_sta_tests {
verilog_attribute
}
define_test_group fast [group_tests all]

View File

@ -0,0 +1,4 @@
top_instance:"counter" attribute "src" = synthesis/tests/counter.v:16.1-32.10
instance: _1415_ attribute "src" = synthesis/tests/counter.v:22.3-28.6
instance: _1415_ attribute "attr1" = test_attr1
instance: _1415_ attribute "attr2" = test_attr2

View File

@ -0,0 +1,18 @@
read_liberty ../examples/sky130hd_tt.lib
read_verilog verilog_attribute.v
link_design counter
create_clock -name clk [get_ports clk] -period 50
set instance [sta::top_instance]
set cell [$instance cell]
set cell_name [$cell name]
set src_location [$cell get_attribute "src"]
puts "top_instance:\"$cell_name\" attribute \"src\" = $src_location"
set instance_name "_1415_"
set instance_src_location [[sta::find_instance $instance_name] get_attribute "src"]
set instance_attr1 [[sta::find_instance $instance_name] get_attribute "attr1"]
set instance_attr2 [[sta::find_instance $instance_name] get_attribute "attr2"]
puts "instance: $instance_name attribute \"src\" = $instance_src_location"
puts "instance: $instance_name attribute \"attr1\" = $instance_attr1"
puts "instance: $instance_name attribute \"attr2\" = $instance_attr2"

21
test/verilog_attribute.v Normal file
View File

@ -0,0 +1,21 @@
/* Generated by Yosys 0.8+ */
(* hdlname = "\\counter" *)
(* top = 1 *)
(* src = "synthesis/tests/counter.v:16.1-32.10" *)
module counter(clk, reset, in, out);
(* src = "synthesis/tests/counter.v:17.14-17.17" *)
input clk;
(* src = "synthesis/tests/counter.v:19.18-19.21" *)
output out;
(* src = "synthesis/tests/counter.v:18.14-18.19" *)
input reset;
input in;
(* src = "synthesis/tests/counter.v:22.3-28.6", attr1 = "test_attr1", attr2 = "test_attr2" *)
sky130_fd_sc_hd__dfrtp_1 _1415_ (
.CLK(clk),
.D(in),
.Q(out),
.RESET_B(reset)
);
endmodule

View File

@ -17,6 +17,7 @@
#include "MinMax.hh"
#include <algorithm>
#include <limits>
#include "StringUtil.hh"
@ -40,18 +41,20 @@ compareMax(float value1,
////////////////////////////////////////////////////////////////
MinMax MinMax::min_("min", 0, INF, compareMin);
MinMax MinMax::max_("max", 1, -INF, compareMax);
MinMax MinMax::min_("min", 0, INF, std::numeric_limits<int>::max(), compareMin);
MinMax MinMax::max_("max", 1, -INF, std::numeric_limits<int>::min(), compareMax);
const std::array<MinMax*, 2> MinMax::range_{&min_, &max_};
const std::array<int, 2> MinMax::range_index_{min_.index(), max_.index()};
MinMax::MinMax(const char *name,
int index,
float init_value,
int init_value_int,
bool (*compare)(float value1, float value2)) :
name_(name),
index_(index),
init_value_(init_value),
init_value_int_(init_value_int),
compare_(compare)
{
}

View File

@ -41,7 +41,6 @@ verilogFlushBuffer()
%option never-interactive
%x COMMENT
%x ATTRIBUTE
%x QSTRING
SIGN "+"|"-"
@ -77,21 +76,6 @@ ID_TOKEN {ID_ESCAPED_TOKEN}|{ID_ALPHA_TOKEN}
}
}
"(*" { BEGIN ATTRIBUTE; }
<ATTRIBUTE>{
.
{EOL} { sta::verilog_reader->incrLine(); }
"*)" { BEGIN INITIAL; }
<<EOF>> {
VerilogParse_error("unterminated attribute");
BEGIN(INITIAL);
yyterminate();
}
}
{SIGN}?{UNSIGNED_NUMBER}?"'"[bB][01_xz]+ {
VerilogParse_lval.constant = sta::stringCopy(VerilogLex_text);
return CONSTANT;
@ -121,6 +105,8 @@ ID_TOKEN {ID_ESCAPED_TOKEN}|{ID_ALPHA_TOKEN}
return ((int) VerilogLex_text[0]);
}
"(*" { return ATTRIBUTE_OPEN; }
"*)" { return ATTRIBUTE_CLOSED; }
assign { return ASSIGN; }
endmodule { return ENDMODULE; }
inout { return INOUT; }

View File

@ -17,6 +17,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdlib>
#include <string>
#include <iostream>
#include "PortDirection.hh"
#include "verilog/VerilogReaderPvt.hh"
@ -33,6 +35,7 @@ int VerilogLex_lex();
int ival;
const char *string;
const char *constant;
const char *attribute_spec_value;
sta::VerilogModule *module;
sta::VerilogStmt *stmt;
sta::VerilogStmtSeq *stmt_seq;
@ -44,10 +47,15 @@ int VerilogLex_lex();
sta::VerilogNet *net;
sta::VerilogNetBitSelect *net_bit;
sta::VerilogNetSeq *nets;
sta::VerilogAttributeEntry *attribute_entry;
sta::VerilogAttributeEntrySeq *attribute_seq;
sta::VerilogAttributeStmt *attribute_stmt;
sta::VerilogAttributeStmtSeq *attribute_stmt_seq;
}
%token INT CONSTANT ID STRING MODULE ENDMODULE ASSIGN PARAMETER DEFPARAM
%token WIRE WAND WOR TRI INPUT OUTPUT INOUT SUPPLY1 SUPPLY0 REG
%token ATTRIBUTE_OPEN ATTRIBUTE_CLOSED
%left '-' '+'
%left '*' '/'
@ -55,8 +63,10 @@ int VerilogLex_lex();
%type <string> ID STRING
%type <ival> WIRE WAND WOR TRI INPUT OUTPUT INOUT SUPPLY1 SUPPLY0
%type <ival> ATTRIBUTE_OPEN ATTRIBUTE_CLOSED
%type <ival> INT parameter_exprs parameter_expr module_begin
%type <constant> CONSTANT
%type <attribute_spec_value> attr_spec_value
%type <port_type> dcl_type port_dcl_type
%type <stmt> stmt declaration instance parameter parameter_dcls parameter_dcl
%type <stmt> defparam param_values param_value port_dcl
@ -69,6 +79,10 @@ int VerilogLex_lex();
%type <net> inst_named_pin net_named net_expr_concat
%type <nets> port_list port_refs inst_ordered_pins
%type <nets> inst_named_pins net_exprs inst_pins
%type <attribute_entry> attr_spec
%type <attribute_seq> attr_specs
%type <attribute_stmt> attribute_instance
%type <attribute_stmt_seq> attribute_instance_seq
%start file
@ -92,14 +106,14 @@ module_begin:
;
module:
module_begin ID ';' stmts ENDMODULE
{ sta::verilog_reader->makeModule($2, new sta::VerilogNetSeq,$4,$1);}
| module_begin ID '(' ')' ';' stmts ENDMODULE
{ sta::verilog_reader->makeModule($2, new sta::VerilogNetSeq,$6,$1);}
| module_begin ID '(' port_list ')' ';' stmts ENDMODULE
{ sta::verilog_reader->makeModule($2, $4, $7, $1); }
| module_begin ID '(' port_dcls ')' ';' stmts ENDMODULE
{ sta::verilog_reader->makeModule($2, $4, $7, $1); }
attribute_instance_seq module_begin ID ';' stmts ENDMODULE
{ sta::verilog_reader->makeModule($3, new sta::VerilogNetSeq, $5, $1, $2);}
| attribute_instance_seq module_begin ID '(' ')' ';' stmts ENDMODULE
{ sta::verilog_reader->makeModule($3, new sta::VerilogNetSeq, $7, $1, $2);}
| attribute_instance_seq module_begin ID '(' port_list ')' ';' stmts ENDMODULE
{ sta::verilog_reader->makeModule($3, $5, $8, $1, $2); }
| attribute_instance_seq module_begin ID '(' port_dcls ')' ';' stmts ENDMODULE
{ sta::verilog_reader->makeModule($3, $5, $8, $1, $2); }
;
port_list:
@ -157,11 +171,12 @@ port_dcls:
;
port_dcl:
port_dcl_type { $<ival>$ = sta::verilog_reader->line(); } dcl_arg
{ $$ = sta::verilog_reader->makeDcl($1, $3, $<ival>2); }
| port_dcl_type { $<ival>$ = sta::verilog_reader->line(); }
'[' INT ':' INT ']' dcl_arg
{ $$ = sta::verilog_reader->makeDclBus($1, $4, $6, $8, $<ival>2); }
attribute_instance_seq port_dcl_type
{ $<ival>$ = sta::verilog_reader->line(); } dcl_arg
{ $$ = sta::verilog_reader->makeDcl($2, $4, $1, $<ival>3); }
| attribute_instance_seq port_dcl_type
{ $<ival>$ = sta::verilog_reader->line(); } '[' INT ':' INT ']' dcl_arg
{ $$ = sta::verilog_reader->makeDclBus($2, $5, $7, $9, $1, $<ival>3); }
;
port_dcl_type:
@ -282,11 +297,11 @@ param_value:
;
declaration:
dcl_type { $<ival>$ = sta::verilog_reader->line(); } dcl_args ';'
{ $$ = sta::verilog_reader->makeDcl($1, $3, $<ival>2); }
| dcl_type { $<ival>$ = sta::verilog_reader->line(); }
attribute_instance_seq dcl_type { $<ival>$ = sta::verilog_reader->line(); } dcl_args ';'
{ $$ = sta::verilog_reader->makeDcl($2, $4, $1, $<ival>3); }
| attribute_instance_seq dcl_type { $<ival>$ = sta::verilog_reader->line(); }
'[' INT ':' INT ']' dcl_args ';'
{ $$ = sta::verilog_reader->makeDclBus($1, $4, $6, $8, $<ival>2); }
{ $$ = sta::verilog_reader->makeDclBus($2, $5, $7, $9, $1,$<ival>3); }
;
dcl_type:
@ -344,11 +359,11 @@ net_assign_lhs:
;
instance:
ID { $<ival>$ = sta::verilog_reader->line(); } ID '(' inst_pins ')' ';'
{ $$ = sta::verilog_reader->makeModuleInst($1, $3, $5, $<ival>2); }
| ID { $<ival>$ = sta::verilog_reader->line(); } parameter_values
attribute_instance_seq ID { $<ival>$ = sta::verilog_reader->line(); } ID '(' inst_pins ')' ';'
{ $$ = sta::verilog_reader->makeModuleInst($2, $4, $6, $1, $<ival>3); }
| attribute_instance_seq ID { $<ival>$ = sta::verilog_reader->line(); } parameter_values
ID '(' inst_pins ')' ';'
{ $$ = sta::verilog_reader->makeModuleInst($1, $4, $6, $<ival>2); }
{ $$ = sta::verilog_reader->makeModuleInst($2, $5, $7, $1, $<ival>3); }
;
parameter_values:
@ -467,4 +482,41 @@ net_expr:
| net_expr_concat
;
attribute_instance_seq:
// empty
{ $$ = new sta::VerilogAttributeStmtSeq; }
| attribute_instance_seq attribute_instance
{ if ($2) $1->push_back($2); }
;
attribute_instance:
ATTRIBUTE_OPEN attr_specs ATTRIBUTE_CLOSED
{ $$ = new sta::VerilogAttributeStmt($2); }
;
attr_specs:
attr_spec
{ $$ = new sta::VerilogAttributeEntrySeq;
$$->push_back($1);
}
| attr_specs ',' attr_spec
{ $$->push_back($3); }
;
attr_spec:
ID
{ $$ = new sta::VerilogAttributeEntry($1, "1"); }
| ID '=' attr_spec_value
{ $$ = new sta::VerilogAttributeEntry($1, $3); }
;
attr_spec_value:
CONSTANT
{ $$ = $1; }
| STRING
{ $$ = $1; }
| INT
{ $$ = sta::stringCopy(std::to_string($1).c_str()); }
;
%%

View File

@ -26,6 +26,7 @@
#include "PortDirection.hh"
#include "Network.hh"
#include "VerilogNamespace.hh"
#include "StringUtil.hh"
#include "verilog/VerilogReaderPvt.hh"
extern int
@ -253,6 +254,7 @@ void
VerilogReader::makeModule(const char *module_vname,
VerilogNetSeq *ports,
VerilogStmtSeq *stmts,
VerilogAttributeStmtSeq *attribute_stmts,
int line)
{
string module_name = moduleVerilogToSta(module_vname);
@ -263,10 +265,17 @@ VerilogReader::makeModule(const char *module_vname,
module_map_.erase(cell);
network_->deleteCell(cell);
}
VerilogModule *module = new VerilogModule(module_name.c_str(),
ports, stmts,
filename_, line, this);
VerilogModule *module = new VerilogModule(module_name.c_str(), ports, stmts,
attribute_stmts, filename_, line, this);
cell = network_->makeCell(library_, module_name.c_str(), false, filename_);
for (VerilogAttributeStmt *stmt : *attribute_stmts) {
for (VerilogAttributeEntry *entry : *stmt->attribute_sequence()) {
network_->setAttribute(cell, entry->key(), entry->value());
}
}
module_map_[cell] = module;
makeCellPorts(cell, module, ports);
module_count_++;
@ -277,6 +286,7 @@ void
VerilogReader::makeModule(const char *module_name,
VerilogStmtSeq *port_dcls,
VerilogStmtSeq *stmts,
VerilogAttributeStmtSeq *attribute_stmts,
int line)
{
VerilogNetSeq *ports = new VerilogNetSeq;
@ -293,7 +303,7 @@ VerilogReader::makeModule(const char *module_name,
}
}
delete port_dcls;
makeModule(module_name, ports, stmts, line);
makeModule(module_name, ports, stmts, attribute_stmts, line);
}
void
@ -392,6 +402,7 @@ VerilogReader::checkModuleDcls(VerilogModule *module,
VerilogDcl *
VerilogReader::makeDcl(PortDirection *dir,
VerilogDclArgSeq *args,
VerilogAttributeStmtSeq* attribute_stmts,
int line)
{
if (dir->isInternal()) {
@ -411,24 +422,25 @@ VerilogReader::makeDcl(PortDirection *dir,
delete args;
if (assign_args) {
dcl_count_++;
return new VerilogDcl(dir, assign_args, line);
return new VerilogDcl(dir, assign_args, attribute_stmts, line);
}
else
return nullptr;
}
else {
dcl_count_++;
return new VerilogDcl(dir, args, line);
return new VerilogDcl(dir, args, attribute_stmts, line);
}
}
VerilogDcl *
VerilogReader::makeDcl(PortDirection *dir,
VerilogDclArg *arg,
VerilogAttributeStmtSeq* attribute_stmts,
int line)
{
dcl_count_++;
return new VerilogDcl(dir, arg, line);
return new VerilogDcl(dir, arg, attribute_stmts, line);
}
VerilogDclBus *
@ -436,10 +448,12 @@ VerilogReader::makeDclBus(PortDirection *dir,
int from_index,
int to_index,
VerilogDclArg *arg,
VerilogAttributeStmtSeq* attribute_stmts,
int line)
{
dcl_bus_count_++;
return new VerilogDclBus(dir, from_index, to_index, arg, line);
return new VerilogDclBus(dir, from_index, to_index, arg, attribute_stmts,
line);
}
VerilogDclBus *
@ -447,10 +461,12 @@ VerilogReader::makeDclBus(PortDirection *dir,
int from_index,
int to_index,
VerilogDclArgSeq *args,
VerilogAttributeStmtSeq* attribute_stmts,
int line)
{
dcl_bus_count_++;
return new VerilogDclBus(dir, from_index, to_index, args, line);
return new VerilogDclBus(dir, from_index, to_index, args, attribute_stmts,
line);
}
VerilogDclArg *
@ -529,9 +545,10 @@ VerilogReader::makeAssign(VerilogNet *lhs,
VerilogInst *
VerilogReader::makeModuleInst(const char *module_vname,
const char *inst_vname,
VerilogNetSeq *pins,
const int line)
const char *inst_vname,
VerilogNetSeq *pins,
VerilogAttributeStmtSeq* attribute_stmts,
const int line)
{
string module_name = moduleVerilogToSta(module_vname);
string inst_name = instanceVerilogToSta(inst_vname);
@ -571,7 +588,7 @@ VerilogReader::makeModuleInst(const char *module_vname,
net_port_ref_scalar_net_count_--;
}
VerilogInst *inst = new VerilogLibertyInst(liberty_cell, inst_name.c_str(),
net_names, line);
net_names, attribute_stmts, line);
delete pins;
if (report_stmt_stats_) {
inst_names_ += inst_name.size() + 1;
@ -585,7 +602,9 @@ VerilogReader::makeModuleInst(const char *module_vname,
else {
VerilogInst *inst = new VerilogModuleInst(module_name.c_str(),
inst_name.c_str(),
pins, line);
pins,
attribute_stmts,
line);
if (report_stmt_stats_) {
inst_module_names_ += module_name.size() + 1;
inst_names_ += inst_name.size() + 1;
@ -817,16 +836,18 @@ VerilogReader::netVerilogName(const char *net_name)
////////////////////////////////////////////////////////////////
VerilogModule::VerilogModule(const char *name,
VerilogNetSeq *ports,
VerilogStmtSeq *stmts,
const char *filename,
int line,
VerilogReader *reader) :
VerilogNetSeq *ports,
VerilogStmtSeq *stmts,
VerilogAttributeStmtSeq *attribute_stmts,
const char *filename,
int line,
VerilogReader *reader) :
VerilogStmt(line),
name_(stringCopy(name)),
filename_(filename),
ports_(ports),
stmts_(stmts)
stmts_(stmts),
attribute_stmts_(attribute_stmts)
{
parseStmts(reader);
}
@ -837,6 +858,8 @@ VerilogModule::~VerilogModule()
delete ports_;
stmts_->deleteContents();
delete stmts_;
attribute_stmts_->deleteContents();
delete attribute_stmts_;
stringDelete(name_);
}
@ -936,15 +959,19 @@ VerilogStmt::VerilogStmt(int line) :
}
VerilogInst::VerilogInst(const char *inst_name,
VerilogAttributeStmtSeq* attribute_stmts,
const int line) :
VerilogStmt(line),
inst_name_(stringCopy(inst_name))
inst_name_(stringCopy(inst_name)),
attribute_stmts_(attribute_stmts)
{
}
VerilogInst::~VerilogInst()
{
stringDelete(inst_name_);
attribute_stmts_->deleteContents();
delete attribute_stmts_;
}
void
@ -955,10 +982,11 @@ VerilogInst::setInstanceName(const char *inst_name)
}
VerilogModuleInst::VerilogModuleInst(const char *module_name,
const char *inst_name,
VerilogNetSeq *pins,
int line) :
VerilogInst(inst_name, line),
const char *inst_name,
VerilogNetSeq *pins,
VerilogAttributeStmtSeq* attribute_stmts,
int line) :
VerilogInst(inst_name, attribute_stmts, line),
module_name_(stringCopy(module_name)),
pins_(pins)
{
@ -990,10 +1018,11 @@ VerilogModuleInst::namedPins()
}
VerilogLibertyInst::VerilogLibertyInst(LibertyCell *cell,
const char *inst_name,
const char **net_names,
const int line) :
VerilogInst(inst_name, line),
const char *inst_name,
const char **net_names,
VerilogAttributeStmtSeq* attribute_stmts,
const int line) :
VerilogInst(inst_name, attribute_stmts, line),
cell_(cell),
net_names_(net_names)
{
@ -1012,28 +1041,34 @@ VerilogLibertyInst::~VerilogLibertyInst()
}
VerilogDcl::VerilogDcl(PortDirection *dir,
VerilogDclArgSeq *args,
int line) :
VerilogDclArgSeq *args,
VerilogAttributeStmtSeq* attribute_stmts,
int line) :
VerilogStmt(line),
dir_(dir),
args_(args)
args_(args),
attribute_stmts_(attribute_stmts)
{
}
VerilogDcl::VerilogDcl(PortDirection *dir,
VerilogDclArg *arg,
int line) :
VerilogDclArg *arg,
VerilogAttributeStmtSeq* attribute_stmts,
int line) :
VerilogStmt(line),
dir_(dir)
{
args_ = new VerilogDclArgSeq;
args_->push_back(arg);
attribute_stmts_ = attribute_stmts;
}
VerilogDcl::~VerilogDcl()
{
args_->deleteContents();
delete args_;
attribute_stmts_->deleteContents();
delete attribute_stmts_;
}
void
@ -1049,22 +1084,24 @@ VerilogDcl::portName()
}
VerilogDclBus::VerilogDclBus(PortDirection *dir,
int from_index,
int to_index,
VerilogDclArgSeq *args,
int line) :
VerilogDcl(dir, args, line),
int from_index,
int to_index,
VerilogDclArgSeq *args,
VerilogAttributeStmtSeq* attribute_stmts,
int line) :
VerilogDcl(dir, args, attribute_stmts, line),
from_index_(from_index),
to_index_(to_index)
{
}
VerilogDclBus::VerilogDclBus(PortDirection *dir,
int from_index,
int to_index,
VerilogDclArg *arg,
int line) :
VerilogDcl(dir, arg, line),
int from_index,
int to_index,
VerilogDclArg *arg,
VerilogAttributeStmtSeq* attribute_stmts,
int line) :
VerilogDcl(dir, arg, attribute_stmts, line),
from_index_(from_index),
to_index_(to_index)
{
@ -1702,6 +1739,45 @@ VerilogNetPortRefPart::name() const
return name_;
}
VerilogAttributeEntry::VerilogAttributeEntry(std::string key,
std::string value) :
key_(key),
value_(value)
{
}
std::string
VerilogAttributeEntry::key()
{
return key_;
}
std::string
VerilogAttributeEntry::value()
{
return value_;
}
VerilogAttributeStmt::VerilogAttributeStmt(
VerilogAttributeEntrySeq* attribute_sequence):
attribute_sequence_(attribute_sequence)
{
}
VerilogAttributeStmt::~VerilogAttributeStmt()
{
attribute_sequence_->deleteContents();
delete attribute_sequence_;
}
VerilogAttributeEntrySeq*
VerilogAttributeStmt::attribute_sequence()
{
return attribute_sequence_;
}
////////////////////////////////////////////////////////////////
//
// Link verilog network
@ -1859,6 +1935,13 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst,
cell = network_->cell(lib_cell);
Instance *inst = network_->makeInstance(cell, mod_inst->instanceName(),
parent);
VerilogAttributeStmtSeq *attribute_stmts = mod_inst->attribute_stmts();
for (VerilogAttributeStmt *stmt : *attribute_stmts) {
for (VerilogAttributeEntry *entry : *stmt->attribute_sequence()) {
network_->setAttribute(inst, entry->key(), entry->value());
}
}
if (lib_cell) {
// Make all pins so timing arcs are built.
LibertyCellPortBitIterator port_iter(lib_cell);
@ -2044,6 +2127,12 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst,
Cell *cell = reinterpret_cast<Cell*>(lib_cell);
Instance *inst = network_->makeInstance(cell, lib_inst->instanceName(),
parent);
VerilogAttributeStmtSeq *attribute_stmts = lib_inst->attribute_stmts();
for (VerilogAttributeStmt *stmt : *attribute_stmts) {
for (VerilogAttributeEntry *entry : *stmt->attribute_sequence()) {
network_->setAttribute(inst, entry->key(), entry->value());
}
}
const char **net_names = lib_inst->netNames();
LibertyCellPortBitIterator port_iter(lib_cell);
while (port_iter.hasNext()) {
@ -2205,7 +2294,7 @@ VerilogBindingTbl::find(const char *name, NetworkReader *network)
}
void
VerilogBindingTbl::bind(const char *name,
VerilogBindingTbl::bind(const char *name,
Net *net)
{
map_[name] = net;

View File

@ -37,6 +37,8 @@ using std::set;
class Debug;
class Report;
class VerilogAttributeEntry;
class VerilogAttributeStmt;
class VerilogReader;
class VerilogStmt;
class VerilogNet;
@ -60,6 +62,8 @@ class VerilogNetPortRef;
class VerilogError;
class LibertyCell;
typedef Vector<VerilogAttributeStmt*> VerilogAttributeStmtSeq;
typedef Vector<VerilogAttributeEntry*> VerilogAttributeEntrySeq;
typedef Vector<VerilogNet*> VerilogNetSeq;
typedef Vector<VerilogStmt*> VerilogStmtSeq;
typedef Map<const char*, VerilogDcl*, CharPtrLess> VerilogDclMap;
@ -87,35 +91,42 @@ public:
int &result,
size_t max_size);
void makeModule(const char *module_name,
VerilogNetSeq *ports,
VerilogStmtSeq *stmts,
int line);
VerilogNetSeq *ports,
VerilogStmtSeq *stmts,
VerilogAttributeStmtSeq *attribute_stmts,
int line);
void makeModule(const char *module_name,
VerilogStmtSeq *port_dcls,
VerilogStmtSeq *stmts,
int line);
VerilogStmtSeq *port_dcls,
VerilogStmtSeq *stmts,
VerilogAttributeStmtSeq *attribute_stmts,
int line);
VerilogDcl *makeDcl(PortDirection *dir,
VerilogDclArgSeq *args,
int line);
VerilogDclArgSeq *args,
VerilogAttributeStmtSeq* attribute_stmts,
int line);
VerilogDcl *makeDcl(PortDirection *dir,
VerilogDclArg *arg,
int line);
VerilogDclArg *arg,
VerilogAttributeStmtSeq* attribute_stmts,
int line);
VerilogDclArg *makeDclArg(const char *net_name);
VerilogDclArg*makeDclArg(VerilogAssign *assign);
VerilogDclBus *makeDclBus(PortDirection *dir,
int from_index,
int to_index,
VerilogDclArg *arg,
int line);
int from_index,
int to_index,
VerilogDclArg *arg,
VerilogAttributeStmtSeq* attribute_stmts,
int line);
VerilogDclBus *makeDclBus(PortDirection *dir,
int from_index,
int to_index,
VerilogDclArgSeq *args,
int line);
int from_index,
int to_index,
VerilogDclArgSeq *args,
VerilogAttributeStmtSeq* attribute_stmts,
int line);
VerilogInst *makeModuleInst(const char *module_name,
const char *inst_name,
VerilogNetSeq *pins,
const int line);
const char *inst_name,
VerilogNetSeq *pins,
VerilogAttributeStmtSeq* attribute_stmts,
const int line);
VerilogAssign *makeAssign(VerilogNet *lhs,
VerilogNet *rhs,
int line);
@ -326,14 +337,16 @@ class VerilogModule : public VerilogStmt
{
public:
VerilogModule(const char *name,
VerilogNetSeq *ports,
VerilogStmtSeq *stmts,
const char *filename,
int line,
VerilogReader *reader);
VerilogNetSeq *ports,
VerilogStmtSeq *stmts,
VerilogAttributeStmtSeq *attribute_stmts,
const char *filename,
int line,
VerilogReader *reader);
virtual ~VerilogModule();
const char *name() { return name_; }
const char *filename() { return filename_; }
VerilogAttributeStmtSeq *attribute_stmts() { return attribute_stmts_; }
VerilogNetSeq *ports() { return ports_; }
VerilogDcl *declaration(const char *net_name);
VerilogStmtSeq *stmts() { return stmts_; }
@ -352,17 +365,20 @@ private:
VerilogNetSeq *ports_;
VerilogStmtSeq *stmts_;
VerilogDclMap dcl_map_;
VerilogAttributeStmtSeq *attribute_stmts_;
};
class VerilogDcl : public VerilogStmt
{
public:
VerilogDcl(PortDirection *dir,
VerilogDclArgSeq *args,
int line);
VerilogDclArgSeq *args,
VerilogAttributeStmtSeq *attribute_stmts,
int line);
VerilogDcl(PortDirection *dir,
VerilogDclArg *arg,
int line);
VerilogDclArg *arg,
VerilogAttributeStmtSeq *attribute_stmts,
int line);
virtual ~VerilogDcl();
const char *portName();
virtual bool isBus() const { return false; }
@ -376,21 +392,24 @@ public:
private:
PortDirection *dir_;
VerilogDclArgSeq *args_;
VerilogAttributeStmtSeq *attribute_stmts_;
};
class VerilogDclBus : public VerilogDcl
{
public:
VerilogDclBus(PortDirection *dir,
int from_index,
int to_index,
VerilogDclArgSeq *args,
int line);
int from_index,
int to_index,
VerilogDclArgSeq *args,
VerilogAttributeStmtSeq* attribute_stmts,
int line);
VerilogDclBus(PortDirection *dir,
int from_index,
int to_index,
VerilogDclArg *arg,
int line);
int from_index,
int to_index,
VerilogDclArg *arg,
VerilogAttributeStmtSeq* attribute_stmts,
int line);
virtual bool isBus() const { return true; }
int fromIndex() const { return from_index_; }
int toIndex() const { return to_index_; }
@ -437,23 +456,27 @@ class VerilogInst : public VerilogStmt
{
public:
VerilogInst(const char *inst_name,
const int line);
VerilogAttributeStmtSeq* attribute_stmts,
const int line);
virtual ~VerilogInst();
virtual bool isInstance() const { return true; }
const char *instanceName() const { return inst_name_; }
VerilogAttributeStmtSeq *attribute_stmts() const { return attribute_stmts_; }
void setInstanceName(const char *inst_name);
private:
const char *inst_name_;
VerilogAttributeStmtSeq* attribute_stmts_;
};
class VerilogModuleInst : public VerilogInst
{
public:
VerilogModuleInst(const char *module_name,
const char *inst_name,
VerilogNetSeq *pins,
const int line);
const char *inst_name,
VerilogNetSeq *pins,
VerilogAttributeStmtSeq* attribute_stmts,
const int line);
virtual ~VerilogModuleInst();
virtual bool isModuleInst() const { return true; }
const char *moduleName() const { return module_name_; }
@ -473,9 +496,10 @@ class VerilogLibertyInst : public VerilogInst
{
public:
VerilogLibertyInst(LibertyCell *cell,
const char *inst_name,
const char **net_names,
const int line);
const char *inst_name,
const char **net_names,
VerilogAttributeStmtSeq* attribute_stmts,
const int line);
virtual ~VerilogLibertyInst();
virtual bool isLibertyInst() const { return true; }
LibertyCell *cell() const { return cell_; }
@ -691,4 +715,29 @@ class VerilogNetNameIterator : public Iterator<const char*>
{
};
class VerilogAttributeStmt
{
public:
VerilogAttributeStmt(VerilogAttributeEntrySeq *attribute_sequence);
VerilogAttributeEntrySeq *attribute_sequence();
virtual ~VerilogAttributeStmt();
private:
VerilogAttributeEntrySeq *attribute_sequence_;
};
class VerilogAttributeEntry
{
public:
VerilogAttributeEntry(std::string key,
std::string value);
virtual std::string key();
virtual std::string value();
virtual ~VerilogAttributeEntry() = default;
private:
std::string key_;
std::string value_;
};
} // namespace