Fix BLKANDNBLK on $readmem/$writemem (#3379).

This commit is contained in:
Wilson Snyder 2022-06-04 12:43:18 -04:00
parent 32100a3c91
commit e7dc2de14b
3 changed files with 38 additions and 13 deletions

View File

@ -26,6 +26,7 @@ Verilator 4.223 devel
* Define VM_TRACE_VCD when tracing in VCD format. [Geza Lore, Shunyao CAD]
* Add assert when VerilatedContext is mis-deleted (#3121). [Rupert Swarbrick]
* Fix hang with large case statement optimization (#3405). [Mike Urbach]
* Fix BLKANDNBLK on $readmem/$writemem (#3379). [Alex Solomatnikov]
* Fix 'with' operator with type casting (#3387). [xiak95]
* Fix incorrect conditional merging (#3409). [Raynard Qiao]
* Fix passing VL_TRACE_FST_WRITER_THREAD in CMake build. [Geza Lore, Shunyao CAD]

View File

@ -94,6 +94,7 @@ private:
bool m_inDly = false; // True in delayed assignments
bool m_inLoop = false; // True in for loops
bool m_inInitial = false; // True in initial blocks
bool m_ignoreBlkAndNBlk = false; // Suppress delayed assignment BLKANDNBLK
using VarMap = std::map<const std::pair<AstNodeModule*, std::string>, AstVar*>;
VarMap m_modVarMap; // Table of new var names created under module
VDouble0 m_statSharedSet; // Statistic tracking
@ -105,6 +106,7 @@ private:
void markVarUsage(AstNodeVarRef* nodep, bool blocking) {
// Ignore if warning is disabled on this reference (used by V3Force).
if (nodep->fileline()->warnIsOff(V3ErrorCode::BLKANDNBLK)) return;
if (m_ignoreBlkAndNBlk) return;
if (blocking) nodep->user5(true);
AstVarScope* const vscp = nodep->varScopep();
// UINFO(4, " MVU " << blocking << " " << nodep << endl);
@ -485,6 +487,13 @@ private:
}
}
virtual void visit(AstNodeReadWriteMem* nodep) override {
VL_RESTORER(m_ignoreBlkAndNBlk);
m_ignoreBlkAndNBlk = true; // $readmem/$writemem often used in mem models
// so we will suppress BLKANDNBLK warnings
iterateChildren(nodep);
}
virtual void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE
nodep->v3fatalSrc(
"For statements should have been converted to while statements in V3Begin");

View File

@ -6,22 +6,37 @@
`define STRINGIFY(x) `"x`"
module t;
module t(/*AUTOARG*/
// Inputs
clk
);
input clk;
int cyc;
reg [5:0] assoc_c[int];
reg [95:0] assoc_w[int];
initial begin
assoc_c[300] = 10; // See if clearing must happen first
$readmemb("t/t_sys_readmem_b.mem", assoc_c);
$display("assoc_c=%p", assoc_c);
$writememh({`STRINGIFY(`TEST_OBJ_DIR),"/t_sys_writemem_c_b.mem"}, assoc_c);
$readmemb("t/t_sys_readmem_b.mem", assoc_w);
// Not conditional with TEST_VERBOSE as found bug with wide display
$display("assoc_w=%p", assoc_w);
$writememh({`STRINGIFY(`TEST_OBJ_DIR),"/t_sys_writemem_w_h.mem"}, assoc_w);
$write("*-* All Finished *-*\n");
$finish;
always_ff @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc == 1) begin
assoc_c[300] <= 10; // See if clearing must happen first
// Also checks no BLKANDNBLK due to readmem/writemem
end
else if (cyc == 2) begin
$readmemb("t/t_sys_readmem_b.mem", assoc_c);
$display("assoc_c=%p", assoc_c);
$writememh({`STRINGIFY(`TEST_OBJ_DIR),"/t_sys_writemem_c_b.mem"}, assoc_c);
end
else if (cyc == 3) begin
$readmemb("t/t_sys_readmem_b.mem", assoc_w);
// Not conditional with TEST_VERBOSE as found bug with wide display
$display("assoc_w=%p", assoc_w);
$writememh({`STRINGIFY(`TEST_OBJ_DIR),"/t_sys_writemem_w_h.mem"}, assoc_w);
end
else if (cyc == 4) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule