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:**
* 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

View File

@ -41,7 +41,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
class ReloopVisitor final : public VNVisitor {
// 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;
// STATE
@ -63,18 +63,11 @@ class ReloopVisitor final : public VNVisitor {
// METHODS
static AstVar* findCreateVarTemp(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");
if (cfuncp->initsp())
cfuncp->initsp()->addNextHere(varp);
else
cfuncp->addInitsp(varp);
cfuncp->user1p(varp);
}
static AstVar* createVarTemp(FileLine* fl, AstCFunc* cfuncp) {
UASSERT_OBJ(cfuncp, fl, "Assignment not under a function");
const string newvarname{"__Vilp" + std::to_string(cfuncp->user1Inc() + 1)};
AstVar* const varp
= new AstVar{fl, VVarType::STMTTEMP, newvarname, VFlagLogicPacked{}, 32};
return varp;
}
void mergeEnd() {
@ -93,7 +86,7 @@ class ReloopVisitor final : public VNVisitor {
AstNodeAssign* const bodyp = m_mgAssignps.front();
UASSERT_OBJ(bodyp->lhsp() == m_mgSelLp, bodyp, "Corrupt queue/state");
FileLine* const fl = bodyp->fileline();
AstVar* const itp = findCreateVarTemp(fl, m_mgCfuncp);
AstVar* const itp = createVarTemp(fl, m_mgCfuncp);
if (m_mgOffset > 0) {
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}}};
AstWhile* const whilep = new AstWhile{fl, condp, nullptr, incp};
initp->addNext(whilep);
bodyp->replaceWith(initp);
itp->AstNode::addNext(initp);
bodyp->replaceWith(itp);
whilep->addStmtsp(bodyp);
// 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