diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 553cfa711..f20d2519b 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -66,6 +66,7 @@ Fuad Ismail Furqan Nadir G-A. Kamendje Garrett Smith +George Polack Geza Lore Gianfranco Costamagna Gijs Burghoorn diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index 03b3ed685..2bcb7f5fc 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -458,9 +458,11 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE { //=================================================================== // SYSTEMC OPERATORS -// Copying verilog format to systemc integers and bit vectors. +// Copying verilog format to systemc integers, doubles, and bit vectors. // Get a SystemC variable +#define VL_ASSIGN_DSD(obits, vvar, svar) \ + { (vvar) = (svar).read(); } #define VL_ASSIGN_ISI(obits, vvar, svar) \ { (vvar) = VL_CLEAN_II((obits), (obits), (svar).read()); } #define VL_ASSIGN_QSQ(obits, vvar, svar) \ @@ -504,9 +506,11 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE { (owp)[words - 1] &= VL_MASK_E(obits); \ } -// Copying verilog format from systemc integers and bit vectors. +// Copying verilog format from systemc integers, doubles, and bit vectors. // Set a SystemC variable +#define VL_ASSIGN_SDD(obits, svar, vvar) \ + { (svar).write(vvar); } #define VL_ASSIGN_SII(obits, svar, vvar) \ { (svar).write(vvar); } #define VL_ASSIGN_SQQ(obits, svar, vvar) \ @@ -2804,6 +2808,12 @@ extern void VL_TIMEFORMAT_IINI(bool hasUnits, int units, bool hasPrecision, int bool hasSuffix, const std::string& suffix, bool hasWidth, int width, VerilatedContext* contextp) VL_MT_SAFE; extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE; +inline IData VL_VALUEPLUSARGS_IND(int rbits, const std::string& ld, double& rdr) VL_MT_SAFE { + VlWide<2> rwp; + const IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp); + if (got) rdr = VL_CVT_D_Q(VL_SET_QW(rwp)); + return got; +} inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, CData& rdr) VL_MT_SAFE { VlWide<2> rwp; const IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp); diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 22e272e95..74cc9d005 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -162,7 +162,7 @@ public: uint32_t arrayUnpackedElements() const; // 1, or total multiplication of all dimensions static int uniqueNumInc() { return ++s_uniqueNum; } const char* charIQWN() const { - return (isString() ? "N" : isWide() ? "W" : isQuad() ? "Q" : "I"); + return (isString() ? "N" : isWide() ? "W" : isDouble() ? "D" : isQuad() ? "Q" : "I"); } string cType(const string& name, bool forFunc, bool isRef, bool packed = false) const; // Represents a C++ LiteralType? (can be constexpr) diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index d62af4471..4d21a7392 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -818,6 +818,8 @@ string AstVar::scType() const { } else { return "uint32_t"; } + } else if (isDouble()) { + return "double"; } else { return "uint64_t"; } diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 348e2f558..c5e5c1efb 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -207,6 +207,7 @@ public: puts(nodep->isScBigUint() ? "SB" : (nodep->isScUint() || nodep->isScUintBool()) ? "SU" : nodep->isScBv() ? "SW" + : nodep->isDouble() ? "SD" : (nodep->isScQuad() ? "SQ" : "SI")); } void emitDatap(AstNode* nodep) { diff --git a/test_regress/t/t_var_sc_double.cpp b/test_regress/t/t_var_sc_double.cpp new file mode 100644 index 000000000..d8642ac12 --- /dev/null +++ b/test_regress/t/t_var_sc_double.cpp @@ -0,0 +1,75 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2025 by George Polack. +// SPDX-License-Identifier: CC0-1.0 + +#include VM_PREFIX_INCLUDE +#include +#include + +using namespace sc_core; +using namespace sc_dt; + +VM_PREFIX* tb = nullptr; +bool pass = true; + +double sc_time_stamp() { return 0; } + +void compareDoubles(double const lwp, double const rwp, double epsilon = std::numeric_limits::epsilon()) { + auto diff = std::fabs(lwp - rwp); + if (diff >= epsilon) { + pass &= false; + VL_PRINTF("%%Error: There is a difference of %f, in double variables\n", diff); + } +} + +#ifdef SYSTEMC_VERSION +int sc_main(int, char**) +#else +int main() +#endif +{ + Verilated::debug(0); + tb = new VM_PREFIX{"tb"}; + + double input_var = 1.5; + double out_var; + +#ifdef SYSTEMC_VERSION + // clang-format off + sc_signal SC_NAMED(i_a), SC_NAMED(o_z); + + tb->i_a(i_a); tb->o_z(o_z); + // clang-format on +#endif + +#ifdef SYSTEMC_VERSION + sc_start(1, SC_NS); +#else + tb->eval(); +#endif + + // This testcase is testing conversion to/from Verilog real to/from SystemC double. + VL_ASSIGN_SDD(0, i_a, input_var); + +#ifdef SYSTEMC_VERSION + sc_start(1, SC_NS); +#else + tb->eval(); +#endif + + VL_ASSIGN_DSD(0, out_var, o_z); + + compareDoubles(input_var, out_var); + + tb->final(); + VL_DO_DANGLING(delete tb, tb); + + if (pass) { + VL_PRINTF("*-* All Finished *-*\n"); + } else { + vl_fatal(__FILE__, __LINE__, "top", "Unexpected results from test\n"); + } + return 0; +} diff --git a/test_regress/t/t_var_sc_double.py b/test_regress/t/t_var_sc_double.py new file mode 100755 index 000000000..fb4049cf1 --- /dev/null +++ b/test_regress/t/t_var_sc_double.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(make_top_shell=False, + make_main=False, + verilator_flags2=["--exe", test.pli_filename, "--sc -fno-inline"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_var_sc_double.v b/test_regress/t/t_var_sc_double.v new file mode 100644 index 000000000..c140ce083 --- /dev/null +++ b/test_regress/t/t_var_sc_double.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2025 by George Polack. +// SPDX-License-Identifier: CC0-1.0 + +module t ( + // Outputs + o_z, + // Inputs + i_a + ); + input real i_a; + output real o_z; + + assign o_z = i_a; +endmodule