Support Verilog real to SystemC double (#6136) (#6158)

This commit is contained in:
George Polack 2025-07-25 14:05:36 -04:00 committed by GitHub
parent fa62cd3486
commit f1826a7c20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 129 additions and 3 deletions

View File

@ -66,6 +66,7 @@ Fuad Ismail
Furqan Nadir
G-A. Kamendje
Garrett Smith
George Polack
Geza Lore
Gianfranco Costamagna
Gijs Burghoorn

View File

@ -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);

View File

@ -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)

View File

@ -818,6 +818,8 @@ string AstVar::scType() const {
} else {
return "uint32_t";
}
} else if (isDouble()) {
return "double";
} else {
return "uint64_t";
}

View File

@ -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) {

View File

@ -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 <cmath>
#include <limits>
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<double>::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<double> 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;
}

View File

@ -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()

View File

@ -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