Fix __Vlip undefined error in --freloop (#4824).

This commit is contained in:
Wilson Snyder 2024-03-03 11:10:46 -05:00
parent 9f8f61ef2f
commit 0fbd4313b2
4 changed files with 120 additions and 15 deletions

View File

@ -20,6 +20,7 @@ Verilator 5.023 devel
**Minor:** **Minor:**
* Fix invalid cast on string structure creation (#4921). [esynr3z] * Fix invalid cast on string structure creation (#4921). [esynr3z]
* Fix __Vlip undefined error in --freloop (#4824). [Justin Yao Du]
Verilator 5.022 2024-02-24 Verilator 5.022 2024-02-24

View File

@ -41,7 +41,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
class ReloopVisitor final : public VNVisitor { class ReloopVisitor final : public VNVisitor {
// NODE STATE // NODE STATE
// AstCFunc::user1p -> Var* for temp var, 0=not set yet // AstCFunc::user1p -> Var number temp var, 0=not set yet
const VNUser1InUse m_inuser1; const VNUser1InUse m_inuser1;
// STATE // STATE
@ -63,18 +63,11 @@ class ReloopVisitor final : public VNVisitor {
// METHODS // METHODS
static AstVar* findCreateVarTemp(FileLine* fl, AstCFunc* cfuncp) { static AstVar* createVarTemp(FileLine* fl, AstCFunc* cfuncp) {
AstVar* varp = VN_AS(cfuncp->user1p(), Var);
if (!varp) {
const string newvarname{"__Vilp"};
varp = new AstVar{fl, VVarType::STMTTEMP, newvarname, VFlagLogicPacked{}, 32};
UASSERT_OBJ(cfuncp, fl, "Assignment not under a function"); UASSERT_OBJ(cfuncp, fl, "Assignment not under a function");
if (cfuncp->initsp()) const string newvarname{"__Vilp" + std::to_string(cfuncp->user1Inc() + 1)};
cfuncp->initsp()->addNextHere(varp); AstVar* const varp
else = new AstVar{fl, VVarType::STMTTEMP, newvarname, VFlagLogicPacked{}, 32};
cfuncp->addInitsp(varp);
cfuncp->user1p(varp);
}
return varp; return varp;
} }
void mergeEnd() { void mergeEnd() {
@ -93,7 +86,7 @@ class ReloopVisitor final : public VNVisitor {
AstNodeAssign* const bodyp = m_mgAssignps.front(); AstNodeAssign* const bodyp = m_mgAssignps.front();
UASSERT_OBJ(bodyp->lhsp() == m_mgSelLp, bodyp, "Corrupt queue/state"); UASSERT_OBJ(bodyp->lhsp() == m_mgSelLp, bodyp, "Corrupt queue/state");
FileLine* const fl = bodyp->fileline(); FileLine* const fl = bodyp->fileline();
AstVar* const itp = findCreateVarTemp(fl, m_mgCfuncp); AstVar* const itp = createVarTemp(fl, m_mgCfuncp);
if (m_mgOffset > 0) { if (m_mgOffset > 0) {
UASSERT_OBJ(m_mgIndexLo >= m_mgOffset, bodyp, UASSERT_OBJ(m_mgIndexLo >= m_mgOffset, bodyp,
@ -111,7 +104,8 @@ class ReloopVisitor final : public VNVisitor {
new AstAdd{fl, new AstConst{fl, 1}, new AstVarRef{fl, itp, VAccess::READ}}}; new AstAdd{fl, new AstConst{fl, 1}, new AstVarRef{fl, itp, VAccess::READ}}};
AstWhile* const whilep = new AstWhile{fl, condp, nullptr, incp}; AstWhile* const whilep = new AstWhile{fl, condp, nullptr, incp};
initp->addNext(whilep); initp->addNext(whilep);
bodyp->replaceWith(initp); itp->AstNode::addNext(initp);
bodyp->replaceWith(itp);
whilep->addStmtsp(bodyp); whilep->addStmtsp(bodyp);
// Replace constant index with new loop index // Replace constant index with new loop index

View File

@ -0,0 +1,22 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# 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
scenarios(simulator => 1);
compile(
verilator_flags2 => ['--assert'],
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,88 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Justin Yao Du.
// SPDX-License-Identifier: CC0-1.0
typedef logic [7:0] Word;
typedef logic [255:0] BigItem;
module shuffler
(
input logic clk,
input logic reset_l,
output logic odd,
output logic [255:0][7:0] shuffle
);
Word ctr;
assign odd = ctr[0];
always_ff @(posedge clk) begin
if (!reset_l) begin
ctr <= 0;
end
else begin
ctr <= ctr + 1;
end
end
for (genvar i = 0; i < 256; i++) always_comb begin
shuffle[i] = Word'(i) - ctr;
end
for (genvar i = 0; i < 256; i++) begin
assert property (@(posedge clk) shuffle[ctr + Word'(i)] == i);
end
endmodule
interface big_port();
BigItem big;
function automatic BigItem get_big();
return big;
endfunction
modport reader(import get_big);
endinterface
module foo (
input clk,
input reset_l,
big_port.reader big);
logic odd;
Word[255 : 0] shuffle;
shuffler fifo (
.clk,
.reset_l,
.odd,
.shuffle
);
BigItem bigs[256];
for (genvar i = 0; i < 256; i++) always_comb begin
bigs[i] = odd ? big.get_big() : 0;
end
endmodule
module t (/*AUTOARG*/
// Inputs
clk, reset_l
);
input clk;
input reset_l;
big_port big();
foo foo (
.clk,
.reset_l,
.big);
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule