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
|
||||
|
||||
.. option:: $c([string], ...);
|
||||
.. option:: $c([string], ...);, $cpure([string], ...);
|
||||
|
||||
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
|
||||
|
|
@ -196,6 +196,11 @@ or "`ifdef`"'s may break other tools.
|
|||
compatibility with other simulators, which require a differently named
|
||||
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
|
||||
|
||||
Format arguments may use C fprintf sizes after the % escape. Per the
|
||||
|
|
|
|||
|
|
@ -603,23 +603,30 @@ public:
|
|||
void add(AstNode* nodep) { addNodesp(nodep); }
|
||||
};
|
||||
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.
|
||||
//
|
||||
// @astgen op1 := nodesp : List[AstNode<AstNodeExpr|AstText>]
|
||||
const bool m_pure; // Whether the function is pure
|
||||
public:
|
||||
class Pure {};
|
||||
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;
|
||||
// METHODS
|
||||
bool cleanOut() const override { return false; }
|
||||
std::string emitC() 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 isPredictOptimizable() const override { return false; }
|
||||
bool isPure() override { return false; }
|
||||
bool isPredictOptimizable() const override { return m_pure; }
|
||||
bool isPure() override { return m_pure; }
|
||||
bool sameNode(const AstNode* /*samep*/) const override { return true; }
|
||||
// Add some text, or a node to this expression
|
||||
void add(const std::string& text) { addNodesp(new AstText{fileline(), text}); }
|
||||
|
|
|
|||
|
|
@ -1376,7 +1376,9 @@ public:
|
|||
putnbs(nodep, "");
|
||||
ofp()->putsNoTracking("\n");
|
||||
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, "");
|
||||
puts("\n");
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
|||
{ws} { FL_FWD; FL_BRK; } /* otherwise ignore white-space */
|
||||
{crnl} { FL_FWD; FL_BRK; } /* Count line numbers */
|
||||
/* 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 */
|
||||
"$acos" { FL; return yD_ACOS; }
|
||||
"$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_BITSTOSHORTREAL "$bitstoshortreal"
|
||||
%token<fl> yD_C "$c"
|
||||
%token<fl> yD_CPURE "$cpure"
|
||||
%token<fl> yD_CAST "$cast"
|
||||
%token<fl> yD_CEIL "$ceil"
|
||||
%token<fl> yD_CHANGED "$changed"
|
||||
|
|
@ -4101,7 +4102,7 @@ system_t_call<nodeStmtp>: // IEEE: system_tf_call (as task)
|
|||
}
|
||||
$$ = cstmtp;
|
||||
}
|
||||
| yD_SDF_ANNOTATE '(' exprEListE ')' { $$ = nullptr; $1->v3warn(SPECIFYIGN, "Ignoring unsupported: $sdf_annotate"); DEL($3); }
|
||||
| yD_SDF_ANNOTATE '(' exprEListE ')' { $$ = nullptr; $1->v3warn(SPECIFYIGN, "Ignoring unsupported: $sdf_annotate"); DEL($3); }
|
||||
| yD_STACKTRACE parenE { $$ = new AstStackTraceT{$1}; }
|
||||
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT{$1, $3}; }
|
||||
//
|
||||
|
|
@ -4268,6 +4269,14 @@ system_f_call<nodeExprp>: // IEEE: system_tf_call (as func)
|
|||
}
|
||||
$$ = 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_STACKTRACE parenE { $$ = new AstStackTraceF{$1}; }
|
||||
| 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