From b523ecf2f45f80488412781ba9a3455a71d64d62 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 13 Feb 2020 08:59:08 -0800 Subject: [PATCH] specify: system timing checks to accept min:typ:max triple --- backends/verilog/verilog_backend.cc | 12 +++++++-- frontends/verilog/verilog_parser.y | 41 ++++++++++++++++++++--------- kernel/rtlil.cc | 8 ++++-- tests/various/specify.v | 7 +++++ 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 682c47a1f..19541f1c4 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1417,11 +1417,19 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) decimal = 1; f << ", "; - dump_const(f, cell->getParam("\\T_LIMIT")); + dump_const(f, cell->getParam("\\T_LIMIT_MIN")); + f << ": "; + dump_const(f, cell->getParam("\\T_LIMIT_TYP")); + f << ": "; + dump_const(f, cell->getParam("\\T_LIMIT_MAX")); if (spec_type == "$setuphold" || spec_type == "$recrem" || spec_type == "$fullskew") { f << ", "; - dump_const(f, cell->getParam("\\T_LIMIT2")); + dump_const(f, cell->getParam("\\T_LIMIT2_MIN")); + f << ": "; + dump_const(f, cell->getParam("\\T_LIMIT2_TYP")); + f << ": "; + dump_const(f, cell->getParam("\\T_LIMIT2_MAX")); } f << ");\n"; diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 8840cf4e8..9b1b07f86 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -161,9 +161,9 @@ struct specify_rise_fall { %type attr case_attr %type specify_target -%type specify_triple +%type specify_triple specify_opt_triple %type specify_rise_fall -%type specify_if specify_condition specify_opt_arg +%type specify_if specify_condition %type specify_edge // operator precedence from low to high @@ -855,7 +855,7 @@ specify_item: delete target; delete timing; } | - TOK_ID '(' specify_edge expr specify_condition ',' specify_edge expr specify_condition ',' expr specify_opt_arg ')' ';' { + TOK_ID '(' specify_edge expr specify_condition ',' specify_edge expr specify_condition ',' specify_triple specify_opt_triple ')' ';' { 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()); @@ -868,8 +868,8 @@ specify_item: AstNode *dst_pol = AstNode::mkconst_int($7 == 'p', false, 1); AstNode *dst_expr = $8, *dst_en = $9 ? $9 : AstNode::mkconst_int(1, false, 1); - AstNode *limit = $11; - AstNode *limit2 = $12; + specify_triple *limit = $11; + specify_triple *limit2 = $12; AstNode *cell = new AstNode(AST_CELL); ast_stack.back()->children.push_back(cell); @@ -880,11 +880,23 @@ specify_item: 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, limit->t_min)); + cell->children.back()->str = "\\T_LIMIT_MIN"; - 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, limit->t_avg)); + cell->children.back()->str = "\\T_LIMIT_TYP"; + + cell->children.push_back(new AstNode(AST_PARASET, limit->t_max)); + cell->children.back()->str = "\\T_LIMIT_MAX"; + + cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_min : AstNode::mkconst_int(0, true))); + cell->children.back()->str = "\\T_LIMIT2_MIN"; + + cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_avg : AstNode::mkconst_int(0, true))); + cell->children.back()->str = "\\T_LIMIT2_TYP"; + + cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_max : AstNode::mkconst_int(0, true))); + cell->children.back()->str = "\\T_LIMIT2_MAX"; cell->children.push_back(new AstNode(AST_PARASET, src_pen)); cell->children.back()->str = "\\SRC_PEN"; @@ -913,8 +925,8 @@ specify_item: delete $1; }; -specify_opt_arg: - ',' expr { +specify_opt_triple: + ',' specify_triple { $$ = $2; } | /* empty */ { @@ -1123,7 +1135,12 @@ ignspec_constant_expression: expr { delete $1; }; ignspec_expr: - expr { delete $1; }; + expr { delete $1; } | + expr ':' expr ':' expr { + delete $1; + delete $3; + delete $5; + }; ignspec_id: TOK_ID { delete $1; }; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f286d139f..5d7e61901 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1258,8 +1258,12 @@ namespace { param_bool(ID(SRC_POL)); param_bool(ID(DST_PEN)); param_bool(ID(DST_POL)); - param(ID(T_LIMIT)); - param(ID(T_LIMIT2)); + param(ID(T_LIMIT_MIN)); + param(ID(T_LIMIT_TYP)); + param(ID(T_LIMIT_MAX)); + param(ID(T_LIMIT2_MIN)); + param(ID(T_LIMIT2_TYP)); + param(ID(T_LIMIT2_MAX)); port(ID(SRC_EN), 1); port(ID(DST_EN), 1); port(ID(SRC), param(ID(SRC_WIDTH))); diff --git a/tests/various/specify.v b/tests/various/specify.v index e4dd132f1..5006e4c38 100644 --- a/tests/various/specify.v +++ b/tests/various/specify.v @@ -44,3 +44,10 @@ specify (posedge clk *> (q +: d)) = (3,1); endspecify endmodule + +module test4(input clk, d, output q); +specify + $setup(d, posedge clk, 1:2:3); + $setuphold(d, posedge clk, 1:2:3, 4:5:6); +endspecify +endmodule -- 2.30.2