Fix bad ending address on $readmem (#3205).

This commit is contained in:
Wilson Snyder 2021-12-21 19:55:04 -05:00
parent 560b59f97f
commit 7526151670
10 changed files with 60 additions and 11 deletions

View File

@ -23,6 +23,7 @@ Verilator 4.217 devel
* Support up to 64 bit enums for .next/.prev/.name (#3244). [Alexander Grobman]
* Reduce .rodata footprint of trace initialization (#3250). [Geza Lore, Shunyao CAD]
* Use C++11 standard types for MacOS portability (#3254). [Adrien Le Masle]
* Fix bad ending address on $readmem (#3205). [Julie Schwartz]
* Fix MSWIN compile error (#2681). [Unai Martinez-Corral]
* Fix break under foreach loop (#3230).
* Fix VL_STREAML_FAST_QQI with 64 bit left-hand-side (#3232) (#3235)

View File

@ -168,6 +168,19 @@ void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool may
}
#endif
#ifndef VL_USER_WARN ///< Define this to override the vl_warn function
void vl_warn(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_UNSAFE {
if (false && hier) {}
if (filename && filename[0]) {
// Not VL_PRINTF_MT, already on main thread
VL_PRINTF("%%Warning: %s:%d: %s\n", filename, linenum, msg);
} else {
VL_PRINTF("%%Warning: %s\n", msg);
}
Verilated::runFlushCallbacks();
}
#endif
//===========================================================================
// Wrapper to call certain functions via messages when multithreaded
@ -201,6 +214,16 @@ void VL_FATAL_MT(const char* filename, int linenum, const char* hier, const char
#endif
}
void VL_WARN_MT(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE {
#ifdef VL_THREADED
VerilatedThreadMsgQueue::post(VerilatedMsg{[=]() { //
vl_warn(filename, linenum, hier, msg);
}});
#else
vl_warn(filename, linenum, hier, msg);
#endif
}
//===========================================================================
// Debug prints
@ -1876,6 +1899,7 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
ignore_to_eol = true;
} else if (c == '@') {
reading_addr = true;
m_anyAddr = true;
m_addr = 0;
}
// Check for hex or binary digits as file format requests
@ -1902,9 +1926,9 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
lastc = c;
}
if (VL_UNLIKELY(m_end != ~0ULL && m_addr <= m_end)) {
VL_FATAL_MT(m_filename.c_str(), m_linenum, "",
"$readmem file ended before specified final address (IEEE 2017 21.4)");
if (VL_UNLIKELY(m_end != ~0ULL && m_addr <= m_end && !m_anyAddr)) {
VL_WARN_MT(m_filename.c_str(), m_linenum, "",
"$readmem file ended before specified final address (IEEE 2017 21.4)");
}
return false; // EOF

View File

@ -231,7 +231,7 @@ private:
// Little selftest
#define SELF_CHECK(got, exp) \
do { \
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest\n"); \
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest"); \
} while (0)
SELF_CHECK(combineHier("a.b.c", "a.b.c"), "a.b.c");
SELF_CHECK(combineHier("a.b.c", "a.b"), "a.b*");
@ -358,7 +358,7 @@ public:
Verilated::quiesce();
const VerilatedLockGuard lock{m_mutex};
#ifndef VM_COVERAGE
VL_FATAL_MT("", 0, "", "%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
VL_FATAL_MT("", 0, "", "%Error: Called VerilatedCov::write when VM_COVERAGE disabled");
#endif
selftest();

View File

@ -43,12 +43,17 @@ extern void vl_finish(const char* filename, int linenum, const char* hier);
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
extern void vl_stop(const char* filename, int linenum, const char* hier);
/// Routine to call for a couple of fatal messages
/// Routine to call for fatal messages
/// User code may wish to replace this function, to do so, define VL_USER_FATAL.
/// This code does not have to be thread safe.
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
extern void vl_fatal(const char* filename, int linenum, const char* hier, const char* msg);
/// Routine to call for warning messages
/// User code may wish to replace this function, to do so, define VL_USER_WARN.
/// This code does not have to be thread safe.
extern void vl_warn(const char* filename, int linenum, const char* hier, const char* msg);
//=========================================================================
// Extern functions -- Slow path
@ -57,9 +62,12 @@ extern void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL
/// Multithread safe wrapper for calls to $stop
extern void VL_STOP_MT(const char* filename, int linenum, const char* hier,
bool maybe = true) VL_MT_SAFE;
/// Multithread safe wrapper to call for a couple of fatal messages
/// Multithread safe wrapper to call for fatal messages
extern void VL_FATAL_MT(const char* filename, int linenum, const char* hier,
const char* msg) VL_MT_SAFE;
/// Multithread safe wrapper to call for warning messages
extern void VL_WARN_MT(const char* filename, int linenum, const char* hier,
const char* msg) VL_MT_SAFE;
// clang-format off
/// Print a string, multithread safe. Eventually VL_PRINTF will get called.

View File

@ -660,7 +660,7 @@ static inline void cvtQDataToStr(char* dstp, QData value) {
void verilated_trace_imp_selftest() {
#define SELF_CHECK(got, exp) \
do { \
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest\n"); \
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest"); \
} while (0)
#define SELF_CHECK_TS(scale) \

View File

@ -86,6 +86,7 @@ class VlReadMem final {
FILE* m_fp; // File handle for filename
QData m_addr; // Next address to read
int m_linenum; // Line number last read from file
bool m_anyAddr = false; // Had address directive in the file
public:
VlReadMem(bool hex, int bits, const std::string& filename, QData start, QData end);
~VlReadMem();

View File

@ -1,2 +1,2 @@
%Error: t/t_sys_readmem_bad_end.mem:12: $readmem file ended before specified final address (IEEE 2017 21.4)
Aborting...
%Warning: t/t_sys_readmem_bad_end.mem:12: $readmem file ended before specified final address (IEEE 2017 21.4)
*-* All Finished *-*

View File

@ -14,7 +14,6 @@ compile(
);
execute(
fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename},
);

View File

@ -11,6 +11,9 @@ module t;
integer i;
initial begin
// No warning as has addresses
$readmemh("t/t_sys_readmem_bad_end2.mem", hex, 0, 15);
// Warning as wrong end address
$readmemh("t/t_sys_readmem_bad_end.mem", hex, 0, 15);
$write("*-* All Finished *-*\n");
$finish;

View File

@ -0,0 +1,13 @@
// DESCRIPTION: Verilator: Verilog Test data file
//
// Copyright 2006 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
10
11
@2
01
// Missing additional data