From 5c166e76e52cdaf6ea97952c17d3d79185a59f96 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Jul 2016 14:23:22 +0200 Subject: [PATCH] Added $initstate cell type and vlog function --- frontends/ast/simplify.cc | 24 ++++++++++++++++++++++++ frontends/verilog/verilog_parser.y | 2 ++ kernel/celltypes.h | 1 + kernel/rtlil.cc | 6 ++++++ kernel/satgen.h | 6 +++--- manual/CHAPTER_CellLib.tex | 2 +- techlibs/common/simlib.v | 17 +++++++++++++++++ 7 files changed, 54 insertions(+), 4 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 18a752e06..4c64626f7 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -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) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 10de3a19f..86a127428 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -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); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index c3f05de57..1eea0530c 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -117,6 +117,7 @@ struct CellTypes setup_type("$assert", {A, EN}, pool(), true); setup_type("$assume", {A, EN}, pool(), true); setup_type("$predict", {A, EN}, pool(), true); + setup_type("$initstate", pool(), {Y}, true); setup_type("$equiv", {A, B}, {Y}, true); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index cf3c80604..2e5157e85 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -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); diff --git a/kernel/satgen.h b/kernel/satgen.h index 22b11fe26..eb1c6fe36 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -69,7 +69,7 @@ struct SatGen SigPool initial_state; std::map asserts_a, asserts_en; std::map assumes_a, assumes_en; - std::map expects_a, expects_en; + std::map predict_a, predict_en; std::map> 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; } diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index b1e000aa2..0f1136346 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -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} diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 38687489a..8ab124034 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -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; -- 2.30.2