diff options
-rw-r--r-- | frontends/verilog/verilog_lexer.l | 2 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 26 | ||||
-rw-r--r-- | kernel/rtlil.cc | 4 | ||||
-rw-r--r-- | techlibs/common/simlib.v | 4 |
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; |