diff --git a/Changes b/Changes index e644a6031..08a34a3f0 100644 --- a/Changes +++ b/Changes @@ -46,9 +46,10 @@ Verilator 5.023 devel * Fix `--prof-exec` predicted time values (#4988). [Geza Lore] * Fix class type as an associative array parameter (#4997). * Fix inout ports of unpacked struct type (#5000). [Ryszard Rozak, Antmicro Ltd.] -* Fix `unique {}` constraints missing semicolon (#5001) -* Fix preprocessor to respect strings in joins (#5007) -* Fix internal error on missing pattern key (#5023) +* Fix `unique {}` constraints missing semicolon (#5001). +* Fix preprocessor to respect strings in joins (#5007). +* Fix $readmem with missing newline (#5019). [Josse Van Delm] +* Fix internal error on missing pattern key (#5023). Verilator 5.022 2024-02-24 diff --git a/include/verilated.cpp b/include/verilated.cpp index c58a9fcc7..3f6598cb7 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -2113,7 +2113,8 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) { "$readmem file ended before specified final address (IEEE 1800-2023 21.4)"); } - return false; // EOF + addrr = m_addr; + return indata; // EOF } void VlReadMem::setData(void* valuep, const std::string& rhs) { const QData shift = m_hex ? 4ULL : 1ULL; @@ -2262,6 +2263,7 @@ void VL_READMEM_N(bool hex, // Hex format, else binary QData addr = 0; std::string value; if (rmem.get(addr /*ref*/, value /*ref*/)) { + // printf("readmem.get [%" PRIu64 "]=%s\n", addr, value.c_str()); if (VL_UNLIKELY(addr < static_cast(array_lsb) || addr >= static_cast(array_lsb + depth))) { VL_FATAL_MT(filename.c_str(), rmem.linenum(), "", diff --git a/test_regress/t/t_sys_readmem_eof.pl b/test_regress/t/t_sys_readmem_eof.pl new file mode 100755 index 000000000..83e6e124b --- /dev/null +++ b/test_regress/t/t_sys_readmem_eof.pl @@ -0,0 +1,34 @@ +#!/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); + +sub gen { + # Generate using file to avoid missing newline in repository + my $filename = shift; + my $fh = IO::File->new(">$filename"); + $fh->print("// Generated by t_vthread.pl\n"); + $fh->print("1\n"); + $fh->print("10\n"); + $fh->print("20\n"); + $fh->print("30"); # No newline +} + +gen($Self->{obj_dir} . "/dat.mem"); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_sys_readmem_eof.v b/test_regress/t/t_sys_readmem_eof.v new file mode 100644 index 000000000..a3c604016 --- /dev/null +++ b/test_regress/t/t_sys_readmem_eof.v @@ -0,0 +1,22 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 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); +`define STRINGIFY(x) `"x`" + +module t(); + reg [7:0] rom [4]; + initial begin + $readmemh({`STRINGIFY(`TEST_OBJ_DIR), "/dat.mem"}, rom); + `checkh(rom[0], 8'h1); + `checkh(rom[1], 8'h10); + `checkh(rom[2], 8'h20); + `checkh(rom[3], 8'h30); + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule