Fix deadlock in `timeprecision` when using systemC (#3707)

This commit is contained in:
Kamil Rakoczy
2022-10-26 04:50:28 -07:00
committed by GitHub
parent 3487701b04
commit ed93a111c2
3 changed files with 52 additions and 16 deletions
+20 -16
View File
@@ -2426,23 +2426,25 @@ void VerilatedContext::timeunit(int value) VL_MT_SAFE {
} }
void VerilatedContext::timeprecision(int value) VL_MT_SAFE { void VerilatedContext::timeprecision(int value) VL_MT_SAFE {
if (value < 0) value = -value; // Stored as 0..15 if (value < 0) value = -value; // Stored as 0..15
const VerilatedLockGuard lock{m_mutex};
m_s.m_timeprecision = value;
#ifdef SYSTEMC_VERSION
const sc_time sc_res = sc_get_time_resolution();
int sc_prec = 99; int sc_prec = 99;
if (sc_res == sc_time(1, SC_SEC)) { {
sc_prec = 0; const VerilatedLockGuard lock{m_mutex};
} else if (sc_res == sc_time(1, SC_MS)) { m_s.m_timeprecision = value;
sc_prec = 3; #ifdef SYSTEMC_VERSION
} else if (sc_res == sc_time(1, SC_US)) { const sc_time sc_res = sc_get_time_resolution();
sc_prec = 6; if (sc_res == sc_time(1, SC_SEC)) {
} else if (sc_res == sc_time(1, SC_NS)) { sc_prec = 0;
sc_prec = 9; } else if (sc_res == sc_time(1, SC_MS)) {
} else if (sc_res == sc_time(1, SC_PS)) { sc_prec = 3;
sc_prec = 12; } else if (sc_res == sc_time(1, SC_US)) {
} else if (sc_res == sc_time(1, SC_FS)) { sc_prec = 6;
sc_prec = 15; } else if (sc_res == sc_time(1, SC_NS)) {
sc_prec = 9;
} else if (sc_res == sc_time(1, SC_PS)) {
sc_prec = 12;
} else if (sc_res == sc_time(1, SC_FS)) {
sc_prec = 15;
}
} }
if (value != sc_prec) { if (value != sc_prec) {
std::ostringstream msg; std::ostringstream msg;
@@ -2454,6 +2456,8 @@ void VerilatedContext::timeprecision(int value) VL_MT_SAFE {
const std::string msgs = msg.str(); const std::string msgs = msg.str();
VL_FATAL_MT("", 0, "", msgs.c_str()); VL_FATAL_MT("", 0, "", msgs.c_str());
} }
#else
}
#endif #endif
} }
const char* VerilatedContext::timeunitString() const VL_MT_SAFE { return vl_time_str(timeunit()); } const char* VerilatedContext::timeunitString() const VL_MT_SAFE { return vl_time_str(timeunit()); }
+2
View File
@@ -0,0 +1,2 @@
%Error: SystemC's sc_set_time_resolution is 10^-9, which does not match Verilog timeprecision 10^-12. Suggest use 'sc_set_time_resolution(1s)', or Verilator '--timescale-override 1s/1s'
Aborting...
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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(vltmt => 1);
top_filename("t/t_time_sc.v");
$Self->{sc_time_resolution} = 'SC_NS';
compile(
verilator_flags2 => ['-sc', '-timescale 1ps/1ps', # Mismatch w/sc_time_resolution
'+define+TEST_EXPECT=2us'],
threads => 2,
);
execute(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;