aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--frontends/verilog/verilog_lexer.l2
-rw-r--r--frontends/verilog/verilog_parser.y26
-rw-r--r--kernel/rtlil.cc4
-rw-r--r--techlibs/common/simlib.v4
4 files changed, 23 insertions, 13 deletions
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index cd96236a1..1a818a2ce 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -301,7 +301,7 @@ supply1 { return TOK_SUPPLY1; }
return TOK_ID;
}
-"$"(setup|hold|skew) {
+"$"(setup|hold|setuphold|removal|recovery|recrem|skew|timeskew|fullskew|nochange) {
if (!specify_mode) REJECT;
frontend_verilog_yylval.string = new std::string(yytext);
return TOK_ID;
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 13ff1d38b..351f38101 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -153,7 +153,7 @@ struct specify_rise_fall {
%type <specify_target_ptr> specify_target
%type <specify_triple_ptr> specify_triple
%type <specify_rise_fall_ptr> specify_rise_fall
-%type <ast> specify_if specify_condition
+%type <ast> specify_if specify_condition specify_opt_arg
%type <ch> specify_edge
// operator precedence from low to high
@@ -816,8 +816,9 @@ specify_item:
delete target;
delete timing;
} |
- TOK_ID '(' specify_edge expr specify_condition ',' specify_edge expr specify_condition ',' expr ')' ';' {
- if (*$1 != "$setup" && *$1 != "$hold" && *$1 != "$skew")
+ TOK_ID '(' specify_edge expr specify_condition ',' specify_edge expr specify_condition ',' expr specify_opt_arg ')' ';' {
+ if (*$1 != "$setup" && *$1 != "$hold" && *$1 != "$setuphold" && *$1 != "$removal" && *$1 != "$recovery" &&
+ *$1 != "$recrem" && *$1 != "$skew" && *$1 != "$timeskew" && *$1 != "$fullskew" && *$1 != "$nochange")
frontend_verilog_yyerror("Unsupported specify rule type: %s\n", $1->c_str());
AstNode *src_pen = AstNode::mkconst_int($3 != 0, false, 1);
@@ -829,6 +830,7 @@ specify_item:
AstNode *dst_expr = $8, *dst_en = $9 ? $9 : AstNode::mkconst_int(1, false, 1);
AstNode *limit = $11;
+ AstNode *limit2 = $12;
AstNode *cell = new AstNode(AST_CELL);
ast_stack.back()->children.push_back(cell);
@@ -836,15 +838,15 @@ specify_item:
cell->children.push_back(new AstNode(AST_CELLTYPE));
cell->children.back()->str = "$specrule";
- cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(*$1 == "$skew", false, 1)));
- cell->children.back()->str = "\\SKEW";
-
- cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(*$1 == "$hold", false, 1)));
- cell->children.back()->str = "\\HOLD";
+ cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_str(*$1)));
+ cell->children.back()->str = "\\TYPE";
cell->children.push_back(new AstNode(AST_PARASET, limit));
cell->children.back()->str = "\\T_LIMIT";
+ cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2 : AstNode::mkconst_int(0, true)));
+ cell->children.back()->str = "\\T_LIMIT2";
+
cell->children.push_back(new AstNode(AST_PARASET, src_pen));
cell->children.back()->str = "\\SRC_PEN";
@@ -872,6 +874,14 @@ specify_item:
delete $1;
};
+specify_opt_arg:
+ ',' expr {
+ $$ = $2;
+ } |
+ /* empty */ {
+ $$ = nullptr;
+ };
+
specify_if:
TOK_IF '(' expr ')' {
$$ = $3;
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 3dd18c296..040644c47 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1219,13 +1219,13 @@ namespace {
}
if (cell->type == "$specrule") {
+ param("\\TYPE");
param_bool("\\SRC_PEN");
param_bool("\\SRC_POL");
param_bool("\\DST_PEN");
param_bool("\\DST_POL");
- param_bool("\\SKEW");
- param_bool("\\HOLD");
param("\\T_LIMIT");
+ param("\\T_LIMIT2");
port("\\SRC_EN", 1);
port("\\DST_EN", 1);
port("\\SRC", param("\\SRC_WIDTH"));
diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v
index 965242cdc..a424d3089 100644
--- a/techlibs/common/simlib.v
+++ b/techlibs/common/simlib.v
@@ -1419,9 +1419,9 @@ endmodule
module \$specrule (EN_SRC, EN_DST, SRC, DST);
-parameter SKEW = 0;
-parameter HOLD = 0;
+parameter TYPE = "";
parameter T_LIMIT = 0;
+parameter T_LIMIT2 = 0;
parameter SRC_WIDTH = 1;
parameter DST_WIDTH = 1;