specify: system timing checks to accept min:typ:max triple
authorEddie Hung <eddie@fpgeh.com>
Thu, 13 Feb 2020 16:59:08 +0000 (08:59 -0800)
committerEddie Hung <eddie@fpgeh.com>
Thu, 13 Feb 2020 20:42:15 +0000 (12:42 -0800)
backends/verilog/verilog_backend.cc
frontends/verilog/verilog_parser.y
kernel/rtlil.cc
tests/various/specify.v

index 682c47a1f1510304a650da808db42bc3f57055ce..19541f1c46e95cf696029799579d4d12b66d55e3 100644 (file)
@@ -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";
index 8840cf4e8f3851e6dc5335f5931f8e015d5eb183..9b1b07f86ca65338332ddeb80b153be39c957337 100644 (file)
@@ -161,9 +161,9 @@ struct specify_rise_fall {
 %type <al> attr case_attr
 
 %type <specify_target_ptr> specify_target
-%type <specify_triple_ptr> specify_triple
+%type <specify_triple_ptr> specify_triple specify_opt_triple
 %type <specify_rise_fall_ptr> specify_rise_fall
-%type <ast> specify_if specify_condition specify_opt_arg
+%type <ast> specify_if specify_condition
 %type <ch> 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; };
index f286d139f92585fbf1a325d8e03ff73dd0310109..5d7e619019f9f5f40ac5df31d87a511b326855e9 100644 (file)
@@ -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)));
index e4dd132f1c6cd18587ce87fb4d1654bedcd525aa..5006e4c381d556db86b329d2fe7a1a93661cdf75 100644 (file)
@@ -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