Support `specparam` (#5767).
This commit is contained in:
parent
189d094202
commit
f508dadc97
1
Changes
1
Changes
|
@ -19,6 +19,7 @@ Verilator 5.037 devel
|
|||
* Support SARIF JSON diagnostic output with `--diagnostics-sarif`. (#6017)
|
||||
* Support 1-bit params with -G and -pvalue (#6051) (#6082). [Paul Swirhun]
|
||||
* Support `$timeformat` with missing arguments (#6113). [Alex Solomatnikov]
|
||||
* Support `specparam` (#5767).
|
||||
* Support parameter forward types.
|
||||
* Add PROCINITASSIGN on initial assignments to process variables (#2481). [Niraj Menon]
|
||||
* Add BADVLTPRAGMA on unknown Verilator pragmas (#5945). [Shou-Li Hsu]
|
||||
|
|
13
src/V3Ast.h
13
src/V3Ast.h
|
@ -923,6 +923,7 @@ public:
|
|||
UNKNOWN,
|
||||
GPARAM,
|
||||
LPARAM,
|
||||
SPECPARAM,
|
||||
GENVAR,
|
||||
VAR, // Reg, integer, logic, etc
|
||||
SUPPLY0,
|
||||
|
@ -951,9 +952,10 @@ public:
|
|||
constexpr operator en() const { return m_e; }
|
||||
const char* ascii() const {
|
||||
static const char* const names[]
|
||||
= {"?", "GPARAM", "LPARAM", "GENVAR", "VAR", "SUPPLY0", "SUPPLY1",
|
||||
"WIRE", "WREAL", "TRIAND", "TRIOR", "TRIWIRE", "TRI0", "TRI1",
|
||||
"PORT", "BLOCKTEMP", "MODULETEMP", "STMTTEMP", "XTEMP", "IFACEREF", "MEMBER"};
|
||||
= {"?", "GPARAM", "LPARAM", "SPECPARAM", "GENVAR", "VAR",
|
||||
"SUPPLY0", "SUPPLY1", "WIRE", "WREAL", "TRIAND", "TRIOR",
|
||||
"TRIWIRE", "TRI0", "TRI1", "PORT", "BLOCKTEMP", "MODULETEMP",
|
||||
"STMTTEMP", "XTEMP", "IFACEREF", "MEMBER"};
|
||||
return names[m_e];
|
||||
}
|
||||
bool isParam() const { return m_e == GPARAM || m_e == LPARAM; }
|
||||
|
@ -983,8 +985,8 @@ public:
|
|||
return (m_e == BLOCKTEMP || m_e == MODULETEMP || m_e == STMTTEMP || m_e == XTEMP);
|
||||
}
|
||||
bool isVPIAccessible() const {
|
||||
return (m_e == VAR || m_e == GPARAM || m_e == LPARAM || m_e == PORT || m_e == WIRE
|
||||
|| m_e == TRI0 || m_e == TRI1);
|
||||
return (m_e == VAR || m_e == GPARAM || m_e == LPARAM || m_e == SPECPARAM || m_e == PORT
|
||||
|| m_e == WIRE || m_e == TRI0 || m_e == TRI1);
|
||||
}
|
||||
|
||||
const char* traceSigKind() const {
|
||||
|
@ -993,6 +995,7 @@ public:
|
|||
/* UNKNOWN: */ "", // Should not be traced
|
||||
/* GPARAM: */ "PARAMETER",
|
||||
/* LPARAM: */ "PARAMETER",
|
||||
/* SPECPARAM: */ "PARAMETER",
|
||||
/* GENVAR: */ "PARAMETER",
|
||||
/* VAR: */ "VAR",
|
||||
/* SUPPLY0: */ "SUPPLY0",
|
||||
|
|
|
@ -688,7 +688,13 @@ void V3ParseImp::tokenPipelineSym() {
|
|||
int token = yylval.token;
|
||||
if (token == yaID__LEX || token == yaID__CC || token == yaID__aTYPE) {
|
||||
importIfInStd(yylval.fl, *(yylval.strp));
|
||||
if (token == yaID__LEX) token = yaID__ETC;
|
||||
if (token == yaID__LEX) {
|
||||
if (VString::startsWith(*(yylval.strp), "PATHPULSE__024a")) {
|
||||
token = yaID__PATHPULSE;
|
||||
} else {
|
||||
token = yaID__ETC;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_afterColonColon = token == yP_COLONCOLON;
|
||||
yylval.token = token;
|
||||
|
|
|
@ -426,6 +426,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
|
|||
%token<strp> yaID__ETC "IDENTIFIER"
|
||||
%token<strp> yaID__CC "IDENTIFIER-::"
|
||||
%token<strp> yaID__LEX "IDENTIFIER-in-lex"
|
||||
%token<strp> yaID__PATHPULSE "IDENTIFIER-for-pathpulse"
|
||||
%token<strp> yaID__aINST "IDENTIFIER-for-instance"
|
||||
%token<strp> yaID__aTYPE "IDENTIFIER-for-type"
|
||||
// Can't predecode aFUNCTION, can declare after use
|
||||
|
@ -5787,12 +5788,42 @@ specify_itemList<nodep>: // IEEE: { specify_item }
|
|||
;
|
||||
|
||||
specify_item<nodep>: // ==IEEE: specify_item
|
||||
system_timing_check { $$ = $1; }
|
||||
specparam_declaration { $$ = $1; }
|
||||
| system_timing_check { $$ = $1; }
|
||||
| junkToSemiList ';' { $$ = nullptr; }
|
||||
;
|
||||
|
||||
specparam_declaration<nodep>: // ==IEEE: specparam_declaration
|
||||
ySPECPARAM junkToSemiList ';' { $$ = nullptr; }
|
||||
specparam_declarationFront list_of_specparam_assignments ';'
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
specparam_declarationFront: // IEEE: part of specparam_declaration
|
||||
// // Front must execute first so VARDTYPE is ready before list of vars
|
||||
ySPECPARAM
|
||||
{ VARRESET_NONLIST(SPECPARAM);
|
||||
AstNodeDType* dtp = new AstBasicDType{$1, VBasicDTypeKwd::DOUBLE};
|
||||
VARDTYPE(dtp); }
|
||||
| ySPECPARAM packed_dimension
|
||||
{ VARRESET_NONLIST(SPECPARAM);
|
||||
AstNodeDType* const dtp = GRAMMARP->addRange(
|
||||
new AstBasicDType{$2->fileline(), LOGIC_IMPLICIT}, $2, true);
|
||||
VARDTYPE(dtp); }
|
||||
;
|
||||
|
||||
list_of_specparam_assignments<varp>: // ==IEEE: list_of_specparam_assignments
|
||||
specparam_assignment { $$ = $1; }
|
||||
| list_of_specparam_assignments ',' specparam_assignment { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
specparam_assignment<varp>: // ==IEEE: specparam_assignment
|
||||
idNotPathpulse sigAttrListE '=' minTypMax
|
||||
{ $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
|
||||
if ($4) $$->valuep($4); }
|
||||
// // IEEE: pulse_control_specparam
|
||||
| idPathpulse sigAttrListE '=' '(' minTypMax ',' minTypMax ')'
|
||||
{ $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
|
||||
if ($5) $$->valuep($5); }
|
||||
;
|
||||
|
||||
system_timing_check<nodep>: // ==IEEE: system_timing_check
|
||||
|
@ -5851,7 +5882,7 @@ junkToSemiList:
|
|||
;
|
||||
|
||||
junkToSemi:
|
||||
BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE,yD_SETUPHOLD) { }
|
||||
BISONPRE_NOT(';',yD_SETUPHOLD,yENDMODULE,yENDSPECIFY,ySPECPARAM) { }
|
||||
| error {}
|
||||
;
|
||||
|
||||
|
@ -5860,16 +5891,27 @@ junkToSemi:
|
|||
|
||||
id<strp>:
|
||||
yaID__ETC { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
| yaID__PATHPULSE { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
| idRandomize { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
;
|
||||
|
||||
idAny<strp>: // Any kind of identifier
|
||||
yaID__ETC { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
| yaID__PATHPULSE { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
| yaID__aINST { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
| yaID__aTYPE { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
| idRandomize { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
;
|
||||
|
||||
idNotPathpulse<strp>: // Id excluding specparam PATHPULSE$, IEEE: part of specparam_assignment
|
||||
yaID__ETC { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
| idRandomize { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
;
|
||||
|
||||
idPathpulse<strp>: // Id for specparam PATHPULSE$, IEEE: part of pulse_control_specparam
|
||||
yaID__PATHPULSE { $$ = $1; $<fl>$ = $<fl>1; }
|
||||
;
|
||||
|
||||
idAnyAsParseRef<parseRefp>: // Any kind of identifier as a ParseRef
|
||||
idAny
|
||||
{ $$ = new AstParseRef{$<fl>1, VParseRefExp::PX_TEXT, *$1}; }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%Error: t/t_flag_wpedantic_bad.v:8:8: syntax error, unexpected global, expecting IDENTIFIER or do or final or randomize
|
||||
%Error: t/t_flag_wpedantic_bad.v:8:8: syntax error, unexpected global
|
||||
8 | reg global;
|
||||
| ^~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%Error: t/t_lint_pkg_colon_bad.v:8:8: syntax error, unexpected IDENTIFIER-::, expecting IDENTIFIER or do or final or randomize
|
||||
%Error: t/t_lint_pkg_colon_bad.v:8:8: syntax error, unexpected IDENTIFIER-::
|
||||
8 | reg mispkgb::bar_t b;
|
||||
| ^~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%Error: t/t_param_type_bad.v:9:27: syntax error, unexpected INTEGER NUMBER, expecting IDENTIFIER or IDENTIFIER-for-instance or IDENTIFIER-for-type or randomize
|
||||
%Error: t/t_param_type_bad.v:9:27: syntax error, unexpected INTEGER NUMBER
|
||||
9 | localparam type bad2 = 2;
|
||||
| ^
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%Error: t/t_pp_circ_subst_bad.v:8:80001: Too many preprocessor tokens on a line (>40000); perhaps recursive `define
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type, expecting IDENTIFIER or do or final or randomize
|
||||
%Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%Error: t/t_pp_circ_subst_bad.v:8:40002: Too many preprocessor tokens on a line (>20000); perhaps recursive `define
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type, expecting IDENTIFIER or do or final or randomize
|
||||
%Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -11,6 +11,8 @@ import vltest_bootstrap
|
|||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||
test.compile(verilator_flags2=['--binary'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
|
@ -0,0 +1,44 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
specify
|
||||
specparam tdevice_PU = 3e8;
|
||||
specparam Tdelay11 = 1.1;
|
||||
// verilator lint_off MINTYPMAXDLY
|
||||
specparam Tmintypmax = 1.0:1.1:1.2;
|
||||
specparam PATHPULSE$a$b = (3.0:3.1:3.2, 4.0:4.1:4.2);
|
||||
specparam randomize = 1; // Special parser corner-case
|
||||
endspecify
|
||||
|
||||
// Support in other simulators is limited for module specparams
|
||||
specparam Tmod34 = 3.4, Tmod35 = 3.5; // IEEE 6.20.5 allowed in body
|
||||
// Support in other simulators is limited for ranged specparams
|
||||
specparam [5:2] Tranged = 4'b1011;
|
||||
|
||||
localparam real PATHPULSE$normal$var = 6.78;
|
||||
|
||||
reg PoweredUp;
|
||||
wire DelayIn, DelayOut;
|
||||
|
||||
assign #tdevice_PU DelayOut = DelayIn;
|
||||
|
||||
initial begin
|
||||
PoweredUp = 1'b0;
|
||||
#tdevice_PU PoweredUp = 1'b1;
|
||||
if (Tdelay11 != 1.1) $stop;
|
||||
`ifdef VERILATOR
|
||||
if (Tmintypmax != 1.1) $stop;
|
||||
if (PATHPULSE$a$b != 3.1) $stop;
|
||||
`endif
|
||||
if (Tranged != 4'b1011) $stop;
|
||||
if (Tmod34 != 3.4) $stop;
|
||||
if (Tmod35 != 3.5) $stop;
|
||||
if (PATHPULSE$normal$var != 6.78) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
|
@ -1,5 +0,0 @@
|
|||
%Error: t/t_specparam_unsup.v:14:8: Can't find definition of variable: 'tdevice_PU'
|
||||
14 | #tdevice_PU PoweredUp = 1'b1;
|
||||
| ^~~~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
|
@ -1,16 +0,0 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t ();
|
||||
reg PoweredUp;
|
||||
specify
|
||||
specparam tdevice_PU = 3e8;
|
||||
endspecify
|
||||
initial begin
|
||||
PoweredUp = 1'b0;
|
||||
#tdevice_PU PoweredUp = 1'b1;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue