Add `$cpure` (#6580)
This commit is contained in:
parent
cb3c2706a8
commit
43373010dc
|
|
@ -156,7 +156,7 @@ or "`ifdef`"'s may break other tools.
|
||||||
|
|
||||||
.. t_dist_docs_style restart_sort
|
.. t_dist_docs_style restart_sort
|
||||||
|
|
||||||
.. option:: $c([string], ...);
|
.. option:: $c([string], ...);, $cpure([string], ...);
|
||||||
|
|
||||||
The string will be embedded directly in the output C++ code at the point
|
The string will be embedded directly in the output C++ code at the point
|
||||||
where the surrounding Verilog code is compiled. It may either be a
|
where the surrounding Verilog code is compiled. It may either be a
|
||||||
|
|
@ -196,6 +196,11 @@ or "`ifdef`"'s may break other tools.
|
||||||
compatibility with other simulators, which require a differently named
|
compatibility with other simulators, which require a differently named
|
||||||
PLI function name for each different output width.
|
PLI function name for each different output width.
|
||||||
|
|
||||||
|
`$cpure` is similar to `$c` except that it indicates the
|
||||||
|
expression is pure, versus `$c` which is assumed impure.
|
||||||
|
`$cpure` is for internal use only, and it might change
|
||||||
|
without notice in any future version or Verilator.
|
||||||
|
|
||||||
.. option:: $display, $write, $fdisplay, $fwrite, $sformat, $swrite
|
.. option:: $display, $write, $fdisplay, $fwrite, $sformat, $swrite
|
||||||
|
|
||||||
Format arguments may use C fprintf sizes after the % escape. Per the
|
Format arguments may use C fprintf sizes after the % escape. Per the
|
||||||
|
|
|
||||||
|
|
@ -603,23 +603,30 @@ public:
|
||||||
void add(AstNode* nodep) { addNodesp(nodep); }
|
void add(AstNode* nodep) { addNodesp(nodep); }
|
||||||
};
|
};
|
||||||
class AstCExprUser final : public AstNodeExpr {
|
class AstCExprUser final : public AstNodeExpr {
|
||||||
// User '$c' statement - Like AstCStmt, with text tracking and optimizations disabled.
|
// User '$c' or '$cpure' expression - Like AstCStmt, with text tracking and optimizations
|
||||||
|
// disabled.
|
||||||
//
|
//
|
||||||
// Use AstCExpr instead, unless the text is from user input.
|
// Use AstCExpr instead, unless the text is from user input.
|
||||||
//
|
//
|
||||||
// @astgen op1 := nodesp : List[AstNode<AstNodeExpr|AstText>]
|
// @astgen op1 := nodesp : List[AstNode<AstNodeExpr|AstText>]
|
||||||
|
const bool m_pure; // Whether the function is pure
|
||||||
public:
|
public:
|
||||||
|
class Pure {};
|
||||||
AstCExprUser(FileLine* fl)
|
AstCExprUser(FileLine* fl)
|
||||||
: ASTGEN_SUPER_CExprUser(fl) {}
|
: ASTGEN_SUPER_CExprUser(fl)
|
||||||
|
, m_pure{false} {}
|
||||||
|
AstCExprUser(FileLine* fl, Pure)
|
||||||
|
: ASTGEN_SUPER_CExprUser(fl)
|
||||||
|
, m_pure{true} {}
|
||||||
ASTGEN_MEMBERS_AstCExprUser;
|
ASTGEN_MEMBERS_AstCExprUser;
|
||||||
// METHODS
|
// METHODS
|
||||||
bool cleanOut() const override { return false; }
|
bool cleanOut() const override { return false; }
|
||||||
std::string emitC() override { V3ERROR_NA_RETURN(""); }
|
std::string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||||
std::string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
std::string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
||||||
bool isGateOptimizable() const override { return false; }
|
bool isGateOptimizable() const override { return m_pure; }
|
||||||
bool isOutputter() override { return true; }
|
bool isOutputter() override { return true; }
|
||||||
bool isPredictOptimizable() const override { return false; }
|
bool isPredictOptimizable() const override { return m_pure; }
|
||||||
bool isPure() override { return false; }
|
bool isPure() override { return m_pure; }
|
||||||
bool sameNode(const AstNode* /*samep*/) const override { return true; }
|
bool sameNode(const AstNode* /*samep*/) const override { return true; }
|
||||||
// Add some text, or a node to this expression
|
// Add some text, or a node to this expression
|
||||||
void add(const std::string& text) { addNodesp(new AstText{fileline(), text}); }
|
void add(const std::string& text) { addNodesp(new AstText{fileline(), text}); }
|
||||||
|
|
|
||||||
|
|
@ -1376,7 +1376,9 @@ public:
|
||||||
putnbs(nodep, "");
|
putnbs(nodep, "");
|
||||||
ofp()->putsNoTracking("\n");
|
ofp()->putsNoTracking("\n");
|
||||||
if (/* is always from $c */ v3Global.opt.decoration() && !v3Global.opt.protectIds()) {
|
if (/* is always from $c */ v3Global.opt.decoration() && !v3Global.opt.protectIds()) {
|
||||||
ofp()->putsNoTracking("// $c expression at " + nodep->fileline()->ascii() + "\n");
|
ofp()->putsNoTracking(
|
||||||
|
(nodep->isPure() ? "// $cpure expression at " : "// $c expression at ")
|
||||||
|
+ nodep->fileline()->ascii() + "\n");
|
||||||
}
|
}
|
||||||
emitNodesWithText(nodep->nodesp(), m_useSelfForThis, false, "");
|
emitNodesWithText(nodep->nodesp(), m_useSelfForThis, false, "");
|
||||||
puts("\n");
|
puts("\n");
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||||
{crnl} { FL_FWD; FL_BRK; } /* Count line numbers */
|
{crnl} { FL_FWD; FL_BRK; } /* Count line numbers */
|
||||||
/* Extensions to Verilog set, some specified by PSL */
|
/* Extensions to Verilog set, some specified by PSL */
|
||||||
"$c"[0-9]* { FL; return yD_C; } /*Verilator only*/
|
"$c"[0-9]* { FL; return yD_C; } /*Verilator only*/
|
||||||
|
"$cpure"[0-9]* { FL; return yD_CPURE; } /*Verilator only*/
|
||||||
/* System Tasks */
|
/* System Tasks */
|
||||||
"$acos" { FL; return yD_ACOS; }
|
"$acos" { FL; return yD_ACOS; }
|
||||||
"$acosh" { FL; return yD_ACOSH; }
|
"$acosh" { FL; return yD_ACOSH; }
|
||||||
|
|
|
||||||
|
|
@ -611,6 +611,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
|
||||||
%token<fl> yD_BITSTOREAL "$bitstoreal"
|
%token<fl> yD_BITSTOREAL "$bitstoreal"
|
||||||
%token<fl> yD_BITSTOSHORTREAL "$bitstoshortreal"
|
%token<fl> yD_BITSTOSHORTREAL "$bitstoshortreal"
|
||||||
%token<fl> yD_C "$c"
|
%token<fl> yD_C "$c"
|
||||||
|
%token<fl> yD_CPURE "$cpure"
|
||||||
%token<fl> yD_CAST "$cast"
|
%token<fl> yD_CAST "$cast"
|
||||||
%token<fl> yD_CEIL "$ceil"
|
%token<fl> yD_CEIL "$ceil"
|
||||||
%token<fl> yD_CHANGED "$changed"
|
%token<fl> yD_CHANGED "$changed"
|
||||||
|
|
@ -4268,6 +4269,14 @@ system_f_call<nodeExprp>: // IEEE: system_tf_call (as func)
|
||||||
}
|
}
|
||||||
$$ = cexprp;
|
$$ = cexprp;
|
||||||
}
|
}
|
||||||
|
| yD_CPURE '(' cStrList ')' {
|
||||||
|
AstCExprUser* cexprp = nullptr;
|
||||||
|
if (!v3Global.opt.ignc()) {
|
||||||
|
cexprp = new AstCExprUser{$1, AstCExprUser::Pure{}};
|
||||||
|
cexprp->add($3);
|
||||||
|
}
|
||||||
|
$$ = cexprp;
|
||||||
|
}
|
||||||
| yD_CAST '(' expr ',' expr ')' { $$ = new AstCastDynamic{$1, $5, $3}; }
|
| yD_CAST '(' expr ',' expr ')' { $$ = new AstCastDynamic{$1, $5, $3}; }
|
||||||
| yD_STACKTRACE parenE { $$ = new AstStackTraceF{$1}; }
|
| yD_STACKTRACE parenE { $$ = new AstStackTraceF{$1}; }
|
||||||
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF{$1, $3}; }
|
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF{$1, $3}; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. This program is free software; you
|
||||||
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module for SystemVerilog 'alias'
|
||||||
|
//
|
||||||
|
// Simple bi-directional transitive alias test.
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Antmicro.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
function int func();
|
||||||
|
static int someVar = 12;
|
||||||
|
return $cpure(someVar, "+ 6");
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
module t;
|
||||||
|
initial begin
|
||||||
|
if (func() != 18) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue