From 13ecb8e1778007f69f01cc6d78433aeb498817f0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 16 May 2019 19:35:10 -0400 Subject: [PATCH] Fix fault on with %t, bug1443. --- Changes | 4 +++- include/verilated.cpp | 24 +++++++++++++++++++----- src/V3EmitC.cpp | 5 +++-- src/V3Number.cpp | 5 +++-- src/V3Width.cpp | 7 +++++++ test_regress/t/t_display_realtime.pl | 21 +++++++++++++++++++++ test_regress/t/t_display_realtime.v | 22 ++++++++++++++++++++++ 7 files changed, 78 insertions(+), 10 deletions(-) create mode 100755 test_regress/t/t_display_realtime.pl create mode 100644 test_regress/t/t_display_realtime.v diff --git a/Changes b/Changes index 492257d01..bca84057a 100644 --- a/Changes +++ b/Changes @@ -8,9 +8,11 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Support VerilatedFstC set_time_unit, bug1433. [Pieter Kapsenberg] +**** Mark infrequently called functions with GCC cold attribute. + **** Fix sign-compare warning in verilated.cpp, bug1437. [Sergey Kvachonok] -**** Mark infrequently called functions with GCC cold attribute. +**** Fix fault on $realtime with %t, bug1443. [Julien Margetts] * Verilator 4.014 2019-05-08 diff --git a/include/verilated.cpp b/include/verilated.cpp index c8c3b8d87..fd6eea57c 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -642,14 +642,28 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA } case 'e': case 'f': - case 'g': { + case 'g': + case '^': { // Realtime const int lbits = va_arg(ap, int); double d = va_arg(ap, double); if (lbits) {} // UNUSED - always 64 - strncpy(tmpf, pctp, pos-pctp+1); - tmpf[pos-pctp+1] = '\0'; - sprintf(tmp, tmpf, d); - output += tmp; + switch (fmt) { + case '^': { // Realtime + int digits = sprintf(tmp, "%g", d/VL_TIME_MULTIPLIER); + int needmore = width-digits; + if (needmore>0) output.append(needmore, ' '); // Pre-pad spaces + output += tmp; + break; + } + default: { + strncpy(tmpf, pctp, pos-pctp+1); + tmpf[pos-pctp+1] = '\0'; + sprintf(tmp, tmpf, d); + output += tmp; + break; + } + break; + } // switch break; } default: { diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 2a61327bd..ee4776a80 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -1638,8 +1638,9 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, case 's': displayArg(nodep,&elistp,isScan, vfmt,'s'); break; case 'e': displayArg(nodep,&elistp,isScan, vfmt,'e'); break; case 'f': displayArg(nodep,&elistp,isScan, vfmt,'f'); break; - case 'g': displayArg(nodep,&elistp,isScan, vfmt,'g'); break; - case 'v': displayArg(nodep,&elistp,isScan, vfmt,'v'); break; + case 'g': displayArg(nodep,&elistp,isScan, vfmt,'g'); break; + case '^': displayArg(nodep,&elistp,isScan, vfmt,'^'); break; // Realtime + case 'v': displayArg(nodep,&elistp,isScan, vfmt,'v'); break; case 'm': { if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName"); string suffix = scopenamep->scopePrettySymName(); diff --git a/src/V3Number.cpp b/src/V3Number.cpp index cc8a1e1e9..0e7b3f04f 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -582,8 +582,9 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const { } case 'e': case 'f': - case 'g': { - char tmp[MAX_SPRINTF_DOUBLE_SIZE]; + case 'g': + case '^': { // Realtime + char tmp[MAX_SPRINTF_DOUBLE_SIZE]; sprintf(tmp, vformat.c_str(), toDouble()); return tmp; } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 2fafc6af8..1024e383a 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2172,6 +2172,13 @@ private: if (argp) argp=argp->nextp(); break; } + case 't': { // Convert decimal time to realtime + if (argp && argp->isDouble()) { // Convert it + ch = '^'; + } + if (argp) argp = argp->nextp(); + break; + } default: { // Most operators, just move to next argument if (argp) argp=argp->nextp(); break; diff --git a/test_regress/t/t_display_realtime.pl b/test_regress/t/t_display_realtime.pl new file mode 100755 index 000000000..113f68def --- /dev/null +++ b/test_regress/t/t_display_realtime.pl @@ -0,0 +1,21 @@ +#!/usr/bin/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. + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); + +1; diff --git a/test_regress/t/t_display_realtime.v b/test_regress/t/t_display_realtime.v new file mode 100644 index 000000000..2ab57a4fb --- /dev/null +++ b/test_regress/t/t_display_realtime.v @@ -0,0 +1,22 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + integer cyc=0; + + always @ (posedge clk) begin + cyc <= cyc + 1; + $display("TestCase at %1t (%s)", $realtime, cyc[0] ? "Option1" : "Option2"); + if (cyc==9) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule