parent
a1cd7d1f3a
commit
8da8ca4203
|
|
@ -6961,6 +6961,40 @@ class WidthVisitor final : public VNVisitor {
|
|||
}
|
||||
userIterateChildren(nodep, nullptr);
|
||||
}
|
||||
void visit(AstResizeLValue* nodep) override {
|
||||
// RESIZELVALUE adjusts width of lvalues for assignments/function calls
|
||||
// The parent context determines the required width
|
||||
UINFO(9, "visit AstResizeLValue " << nodep << endl);
|
||||
if (nodep->didWidthAndSet()) return;
|
||||
|
||||
UASSERT_OBJ(nodep->lhsp(), nodep, "ResizeLValue missing lhs expression");
|
||||
|
||||
// First, process child to know its natural width
|
||||
if (m_vup->prelim()) {
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP{CONTEXT_DET, PRELIM}.p());
|
||||
}
|
||||
|
||||
// Get the required width from parent context
|
||||
if (AstNodeDType* const vdtypep = m_vup->dtypeNullp()) {
|
||||
// Parent specified required width - use it
|
||||
nodep->dtypeFrom(vdtypep);
|
||||
} else if (!nodep->dtypep()) {
|
||||
// No parent context, use child's type
|
||||
nodep->dtypeFrom(nodep->lhsp());
|
||||
}
|
||||
|
||||
// Verify we ended up with a valid datatype
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep, "ResizeLValue still missing dtype after visiting");
|
||||
UASSERT_OBJ(nodep->width() > 0, nodep, "ResizeLValue has invalid width");
|
||||
|
||||
// Log the transformation for debugging
|
||||
UINFO(9, " ResizeLValue: " << nodep->lhsp()->width() << " bits -> " << nodep->width()
|
||||
<< " bits" << endl);
|
||||
|
||||
// Final processing
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP{SELF, FINAL}.p());
|
||||
nodep->didWidth(true);
|
||||
}
|
||||
void visitClass(AstClass* nodep) {
|
||||
if (nodep->didWidthAndSet()) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -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(verilator_flags2=["--binary -Wno-WIDTHEXPAND"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Alex Solomatnikov.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
package x_pkg;
|
||||
typedef bit unsigned [64-1:0] x_reg_data_t ;
|
||||
virtual class x_reg;
|
||||
extern virtual task read(output int status, output x_reg_data_t value, input int path);
|
||||
endclass: x_reg
|
||||
task x_reg::read(output int status, output x_reg_data_t value, input int path);
|
||||
endtask: read
|
||||
endpackage // x_pkg
|
||||
|
||||
package s_c_env_pkg;
|
||||
import x_pkg::*;
|
||||
|
||||
class r_reg_p_s_reg_n_doorbell extends x_reg;
|
||||
x_reg_data_t val;
|
||||
function new(int _val);
|
||||
val = _val;
|
||||
endfunction
|
||||
extern virtual task read(output int status, output x_reg_data_t value, input int path);
|
||||
endclass : r_reg_p_s_reg_n_doorbell
|
||||
task r_reg_p_s_reg_n_doorbell::read(output int status, output x_reg_data_t value, input int path);
|
||||
status = 1;
|
||||
value = val;
|
||||
endtask: read
|
||||
|
||||
class r_block_p_s_reg;
|
||||
rand r_reg_p_s_reg_n_doorbell n_doorbell;
|
||||
|
||||
function new(int _val);
|
||||
n_doorbell = new(_val);
|
||||
endfunction
|
||||
endclass : r_block_p_s_reg
|
||||
|
||||
class r_top_s_reg;
|
||||
rand r_block_p_s_reg p_s[16];
|
||||
endclass
|
||||
|
||||
class s_c_env;
|
||||
r_top_s_reg r_reg_model;
|
||||
endclass: s_c_env
|
||||
endpackage // s_c_env_pkg
|
||||
|
||||
package s_c_sequences_pkg;
|
||||
import x_pkg::*;
|
||||
import s_c_env_pkg::*;
|
||||
class s_c_v_regs_seq;
|
||||
s_c_env m_env;
|
||||
virtual task body();
|
||||
int unsigned p, rdata;
|
||||
int status;
|
||||
if (m_env == null)
|
||||
m_env = new;
|
||||
if (m_env.r_reg_model == null)
|
||||
m_env.r_reg_model = new;
|
||||
foreach (m_env.r_reg_model.p_s[p]) begin
|
||||
if (m_env.r_reg_model.p_s[p] == null) begin
|
||||
m_env.r_reg_model.p_s[p] = new(p);
|
||||
end
|
||||
m_env.r_reg_model.p_s[p].n_doorbell.read(status, rdata, 0);
|
||||
if (status != 1) $stop;
|
||||
if (rdata != p) $stop;
|
||||
end
|
||||
endtask
|
||||
endclass
|
||||
endpackage // s_c_sequences_pkg
|
||||
|
||||
module t;
|
||||
|
||||
s_c_sequences_pkg::s_c_v_regs_seq seq;
|
||||
|
||||
initial begin
|
||||
seq = new;
|
||||
seq.body();
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule // t
|
||||
Loading…
Reference in New Issue