Added $initstate cell type and vlog function
authorClifford Wolf <clifford@clifford.at>
Thu, 21 Jul 2016 12:23:22 +0000 (14:23 +0200)
committerClifford Wolf <clifford@clifford.at>
Thu, 21 Jul 2016 12:23:22 +0000 (14:23 +0200)
frontends/ast/simplify.cc
frontends/verilog/verilog_parser.y
kernel/celltypes.h
kernel/rtlil.cc
kernel/satgen.h
manual/CHAPTER_CellLib.tex
techlibs/common/simlib.v

index 18a752e06f8955776ec610aace4c91bfbaaee93c..4c64626f7924653faa274d26310a2b43ca71f576 100644 (file)
@@ -1626,6 +1626,30 @@ skip_dynamic_range_lvalue_expansion:;
        {
                if (type == AST_FCALL)
                {
+                       if (str == "\\$initstate")
+                       {
+                               int myidx = autoidx++;
+
+                               AstNode *wire = new AstNode(AST_WIRE);
+                               wire->str = stringf("$initstate$%d_wire", myidx);
+                               current_ast_mod->children.push_back(wire);
+                               while (wire->simplify(true, false, false, 1, -1, false, false)) { }
+
+                               AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE), new AstNode(AST_ARGUMENT, new AstNode(AST_IDENTIFIER)));
+                               cell->str = stringf("$initstate$%d", myidx);
+                               cell->children[0]->str = "$initstate";
+                               cell->children[1]->str = "\\Y";
+                               cell->children[1]->children[0]->str = wire->str;
+                               cell->children[1]->children[0]->id2ast = wire;
+                               current_ast_mod->children.push_back(cell);
+                               while (cell->simplify(true, false, false, 1, -1, false, false)) { }
+
+                               newNode = new AstNode(AST_IDENTIFIER);
+                               newNode->str = wire->str;
+                               newNode->id2ast = wire;
+                               goto apply_newNode;
+                       }
+
                        if (str == "\\$clog2")
                        {
                                if (children.size() != 1)
index 10de3a19fc3f53704a2f334b35712726258454a8..86a12742802f1a886b09d47d641d6acd5fc9ae91 100644 (file)
@@ -1189,6 +1189,8 @@ rvalue:
                $$ = new AstNode(AST_IDENTIFIER, $2);
                $$->str = *$1;
                delete $1;
+               if ($2 == nullptr && $$->str == "\\$initstate")
+                       $$->type = AST_FCALL;
        } |
        hierarchical_id non_opt_multirange {
                $$ = new AstNode(AST_IDENTIFIER, $2);
index c3f05de579901002555f59b35a805779fc45191b..1eea0530c57c63b43703cee58ccef52e96ed52da 100644 (file)
@@ -117,6 +117,7 @@ struct CellTypes
                setup_type("$assert", {A, EN}, pool<RTLIL::IdString>(), true);
                setup_type("$assume", {A, EN}, pool<RTLIL::IdString>(), true);
                setup_type("$predict", {A, EN}, pool<RTLIL::IdString>(), true);
+               setup_type("$initstate", pool<RTLIL::IdString>(), {Y}, true);
                setup_type("$equiv", {A, B}, {Y}, true);
        }
 
index cf3c80604fff6475288b1365b59b0c6f8282b59f..2e5157e857fd32777db8849bcf38c81d0e13223e 100644 (file)
@@ -1024,6 +1024,12 @@ namespace {
                                return;
                        }
 
+                       if (cell->type == "$initstate") {
+                               port("\\Y", 1);
+                               check_expected();
+                               return;
+                       }
+
                        if (cell->type == "$equiv") {
                                port("\\A", 1);
                                port("\\B", 1);
index 22b11fe26c80c7f198a662495eebcbf84adfdb18..eb1c6fe36f4331b19386d2747beb03960942370f 100644 (file)
@@ -69,7 +69,7 @@ struct SatGen
        SigPool initial_state;
        std::map<std::string, RTLIL::SigSpec> asserts_a, asserts_en;
        std::map<std::string, RTLIL::SigSpec> assumes_a, assumes_en;
-       std::map<std::string, RTLIL::SigSpec> expects_a, expects_en;
+       std::map<std::string, RTLIL::SigSpec> predict_a, predict_en;
        std::map<std::string, std::map<RTLIL::SigBit, int>> imported_signals;
        bool ignore_div_by_zero;
        bool model_undef;
@@ -1350,8 +1350,8 @@ struct SatGen
                if (cell->type == "$predict")
                {
                        std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
-                       expects_a[pf].append((*sigmap)(cell->getPort("\\A")));
-                       expects_en[pf].append((*sigmap)(cell->getPort("\\EN")));
+                       predict_a[pf].append((*sigmap)(cell->getPort("\\A")));
+                       predict_en[pf].append((*sigmap)(cell->getPort("\\EN")));
                        return true;
                }
 
index b1e000aa24a8d25f163cf1a01f4d725a80cf4cb7..0f1136346cf39389fb0a867a66e64ea5e01799e5 100644 (file)
@@ -421,7 +421,7 @@ pass. The combinatorial logic cells can be mapped to physical cells from a Liber
 using the {\tt abc} pass.
 
 \begin{fixme}
-Add information about {\tt \$assert}, {\tt \$assume}, {\tt \$predict}, and {\tt \$equiv} cells.
+Add information about {\tt \$assert}, {\tt \$assume}, {\tt \$predict}, {\tt \$equiv}, and {\tt \$initstate} cells.
 \end{fixme}
 
 \begin{fixme}
index 38687489ae819fb1217bdc075543b68ff3c4d016..8ab1240344868c93afdfe7c499154b5f83ba5de8 100644 (file)
@@ -1313,6 +1313,23 @@ endmodule
 
 // --------------------------------------------------------
 
+module \$initstate (Y);
+
+output reg Y = 1;
+reg [3:0] cnt = 1;
+reg trig = 0;
+
+initial trig <= 1;
+
+always @(cnt, trig) begin
+       Y <= |cnt;
+       cnt <= cnt + |cnt;
+end
+
+endmodule
+
+// --------------------------------------------------------
+
 module \$equiv (A, B, Y);
 
 input A, B;