Support parameter names in pattern initialization (#5593) (#5596)

This commit is contained in:
Greg Davill 2024-11-14 22:55:58 +10:30 committed by GitHub
parent 8e82440a55
commit 904be103df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 75 additions and 1 deletions

View File

@ -65,6 +65,7 @@ Gijs Burghoorn
Glen Gibb
Gökçe Aydos
Graham Rushton
Greg Davill
Guokai Chen
Gus Smith
Gustav Svensk

View File

@ -1728,11 +1728,12 @@ public:
class AstPatMember final : public AstNodeExpr {
// Verilog '{a} or '{a{b}}
// Parents: AstPattern
// Children: expression, AstPattern, replication count
// Children: expression, AstPattern, replication count, decoded nodep if TEXT
// Expression to assign or another AstPattern (list if replicated)
// @astgen op1 := lhssp : List[AstNodeExpr]
// @astgen op2 := keyp : Optional[AstNode]
// @astgen op3 := repp : Optional[AstNodeExpr] // replication count, or nullptr for count 1
// @astgen op4 := varrefp : Optional[AstNodeExpr] // Decoded variable if TEXT
bool m_default = false;
public:

View File

@ -2744,6 +2744,24 @@ class LinkDotResolveVisitor final : public VNVisitor {
m_inSens = true;
iterateChildren(nodep);
}
void visit(AstPatMember* nodep) override {
LINKDOT_VISIT_START();
if (nodep->varrefp()) return; // only do this mapping once
// If we have a TEXT token as our key, lookup if it's a LPARAM
if (AstText* const textp = VN_CAST(nodep->keyp(), Text)) {
UINFO(9, indent() << "visit " << nodep << endl);
UINFO(9, indent() << " " << textp << endl);
// Lookup
if (VSymEnt* const foundp = m_curSymp->findIdFallback(textp->text())) {
if (AstVar* const varp = VN_CAST(foundp->nodep(), Var)) {
// Attach found Text reference to PatMember
nodep->varrefp(new AstVarRef{nodep->fileline(), varp, VAccess::READ});
UINFO(9, indent() << " new " << nodep->varrefp() << endl);
}
}
}
iterateChildren(nodep);
}
void visit(AstParseRef* nodep) override {
if (nodep->user3SetOnce()) return;
LINKDOT_VISIT_START();

View File

@ -7824,8 +7824,11 @@ class WidthVisitor final : public VNVisitor {
for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp;
patp = VN_AS(patp->nextp(), PatMember)) {
if (patp->keyp()) {
if (patp->varrefp()) V3Const::constifyParamsEdit(patp->varrefp());
if (const AstConst* const constp = VN_CAST(patp->keyp(), Const)) {
element = constp->toSInt();
} else if (const AstConst* const constp = VN_CAST(patp->varrefp(), Const)) {
element = constp->toSInt();
} else {
patp->keyp()->v3error("Assignment pattern key not supported/understood: "
<< patp->keyp()->prettyTypeName());

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 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()

View File

@ -0,0 +1,33 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2010 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
module t (/*AUTOARG*/);
localparam int unsigned SPI_INDEX = 0;
localparam int unsigned I2C_INDEX = 1;
localparam int unsigned TMR_INDEX = 4;
localparam logic [31:0] AHB_ADDR[6] = '{
SPI_INDEX: 32'h80001000,
I2C_INDEX: 32'h80002000,
TMR_INDEX: 32'h80003000,
default: '0};
initial begin
`checkh(AHB_ADDR[0], 32'h80001000);
`checkh(AHB_ADDR[1], 32'h80002000);
`checkh(AHB_ADDR[2], 32'h0);
`checkh(AHB_ADDR[3], 32'h0);
`checkh(AHB_ADDR[4], 32'h80003000);
`checkh(AHB_ADDR[5], 32'h0);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule