1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //*************************************************************************
3 //
4 // Copyright 2009-2009 by Wilson Snyder. This program is free software; you can
5 // redistribute it and/or modify it under the terms of either the GNU
6 // Lesser General Public License Version 3 or the Perl Artistic License
7 // Version 2.0.
8 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
9 //
10 //*************************************************************************
11 
12 #include <cstdio>
13 #include <cstring>
14 #include "svdpi.h"
15 
16 //======================================================================
17 
18 // clang-format off
19 #if defined(VERILATOR)
20 # include "Vt_dpi_import__Dpi.h"
21 #elif defined(VCS)
22 # include "../vc_hdrs.h"
23 #elif defined(CADENCE)
24 # define NEED_EXTERNS
25 #else
26 # error "Unknown simulator for DPI test"
27 #endif
28 // clang-format on
29 
30 typedef struct {
31     int a;
32     int b;
33 } substruct_t;
34 
35 #ifdef NEED_EXTERNS
36 extern "C" {
37 // If get ncsim: *F,NOFDPI: Function {foo} not found in default libdpi.
38 // Then probably forgot to list a function here.
39 
40 extern unsigned char dpii_f_bit(unsigned char i);
41 extern svBitVecVal dpii_f_bit8(const svBitVecVal* i);
42 extern svBitVecVal dpii_f_bit9(const svBitVecVal* i);
43 extern svBitVecVal dpii_f_bit16(const svBitVecVal* i);
44 extern svBitVecVal dpii_f_bit17(const svBitVecVal* i);
45 extern svBitVecVal dpii_f_bit32(const svBitVecVal* i);
46 extern long long dpii_f_bit33(const svBitVecVal* i);
47 extern long long dpii_f_bit64(const svBitVecVal* i);
48 extern long long dpii_f_bit95(const svBitVecVal* i, svBitVecVal* o);
49 extern int dpii_f_int(int i);
50 extern char dpii_f_byte(char i);
51 extern short int dpii_f_shortint(short int i);
52 extern long long dpii_f_longint(long long i);
53 extern void* dpii_f_chandle(void* i);
54 extern const char* dpii_f_string(const char* i);
55 extern double dpii_f_real(double i);
56 extern float dpii_f_shortreal(float i);
57 
58 extern void dpii_v_bit(unsigned char i, unsigned char* o);
59 extern void dpii_v_int(int i, int* o);
60 extern void dpii_v_uint(unsigned int i, unsigned int* o);
61 extern void dpii_v_byte(char i, char* o);
62 extern void dpii_v_shortint(short int i, short int* o);
63 extern void dpii_v_ushort(unsigned short i, unsigned short* o);
64 extern void dpii_v_longint(long long i, long long* o);
65 extern void dpii_v_ulong(unsigned long long i, unsigned long long* o);
66 extern void dpii_v_struct(const svBitVecVal* i, svBitVecVal* o);
67 extern void dpii_v_substruct(const svBitVecVal* i, int* o);
68 extern void dpii_v_chandle(void* i, void** o);
69 extern void dpii_v_string(const char* i, const char** o);
70 extern void dpii_v_real(double i, double* o);
71 extern void dpii_v_shortreal(float i, float* o);
72 
73 extern void dpii_v_struct(const svBitVecVal* i, svBitVecVal* o);
74 extern void dpii_v_substruct(const svBitVecVal* i, int* o);
75 extern void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o);
76 extern void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o);
77 extern void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o);
78 
79 extern void dpii_v_reg(unsigned char i, unsigned char* o);
80 extern void dpii_v_reg15(const svLogicVecVal* i, svLogicVecVal* o);
81 extern void dpii_v_reg95(const svLogicVecVal* i, svLogicVecVal* o);
82 extern void dpii_v_integer(const svLogicVecVal* i, svLogicVecVal* o);
83 extern void dpii_v_time(const svLogicVecVal* i, svLogicVecVal* o);
84 
85 extern int dpii_f_strlen(const char* i);
86 
87 extern void dpii_f_void();
88 extern int dpii_t_void();
89 extern int dpii_t_void_context();
90 extern int dpii_t_int(int i, int* o);
91 
92 extern int dpii_fa_bit(int i);
93 }
94 #endif
95 
96 //======================================================================
97 
dpii_f_bit(unsigned char i)98 unsigned char dpii_f_bit(unsigned char i) { return 0x1 & ~i; }
dpii_f_bit8(const svBitVecVal * i)99 svBitVecVal dpii_f_bit8(const svBitVecVal* i) { return 0xffUL & ~*i; }
dpii_f_bit9(const svBitVecVal * i)100 svBitVecVal dpii_f_bit9(const svBitVecVal* i) { return 0x1ffUL & ~*i; }
dpii_f_bit16(const svBitVecVal * i)101 svBitVecVal dpii_f_bit16(const svBitVecVal* i) { return 0xffffUL & ~*i; }
dpii_f_bit17(const svBitVecVal * i)102 svBitVecVal dpii_f_bit17(const svBitVecVal* i) { return 0x1ffffUL & ~*i; }
dpii_f_bit32(const svBitVecVal * i)103 svBitVecVal dpii_f_bit32(const svBitVecVal* i) { return ~*i; }
dpii_f_bit33(const svBitVecVal * i)104 long long dpii_f_bit33(const svBitVecVal* i) {
105     return ((1ULL << 33) - 1) & ~((long long)(i[1]) << 32ULL | i[0]);
106 }
dpii_f_bit64(const svBitVecVal * i)107 long long dpii_f_bit64(const svBitVecVal* i) { return ~((long long)(i[1]) << 32ULL | i[0]); }
108 
dpii_f_int(int i)109 int dpii_f_int(int i) { return ~i; }
dpii_f_byte(char i)110 char dpii_f_byte(char i) { return ~i; }
dpii_f_shortint(short int i)111 short int dpii_f_shortint(short int i) { return ~i; }
dpii_f_longint(long long i)112 long long dpii_f_longint(long long i) { return ~i; }
dpii_f_chandle(void * i)113 void* dpii_f_chandle(void* i) { return i; }
dpii_f_string(const char * i)114 const char* dpii_f_string(const char* i) { return i; }
dpii_f_real(double i)115 double dpii_f_real(double i) { return i + 1.5; }
dpii_f_shortreal(float i)116 float dpii_f_shortreal(float i) { return i + 1.5f; }
117 
dpii_v_bit(unsigned char i,unsigned char * o)118 void dpii_v_bit(unsigned char i, unsigned char* o) { *o = 1 & ~i; }
dpii_v_int(int i,int * o)119 void dpii_v_int(int i, int* o) { *o = ~i; }
dpii_v_uint(unsigned int i,unsigned int * o)120 void dpii_v_uint(unsigned int i, unsigned int* o) { *o = ~i; }
dpii_v_byte(char i,char * o)121 void dpii_v_byte(char i, char* o) { *o = ~i; }
dpii_v_shortint(short int i,short int * o)122 void dpii_v_shortint(short int i, short int* o) { *o = ~i; }
dpii_v_ushort(unsigned short i,unsigned short * o)123 void dpii_v_ushort(unsigned short i, unsigned short* o) { *o = ~i; }
dpii_v_longint(long long i,long long * o)124 void dpii_v_longint(long long i, long long* o) { *o = ~i; }
dpii_v_ulong(unsigned long long i,unsigned long long * o)125 void dpii_v_ulong(unsigned long long i, unsigned long long* o) { *o = ~i; }
dpii_v_chandle(void * i,void ** o)126 void dpii_v_chandle(void* i, void** o) { *o = i; }
dpii_v_string(const char * i,const char ** o)127 void dpii_v_string(const char* i, const char** o) { *o = i; }
dpii_v_real(double i,double * o)128 void dpii_v_real(double i, double* o) { *o = i + 1.5; }
dpii_v_shortreal(float i,float * o)129 void dpii_v_shortreal(float i, float* o) { *o = i + 1.5f; }
130 
dpii_v_reg(unsigned char i,unsigned char * o)131 void dpii_v_reg(unsigned char i, unsigned char* o) { *o = (~i) & 1; }
dpii_v_reg15(const svLogicVecVal * i,svLogicVecVal * o)132 void dpii_v_reg15(const svLogicVecVal* i, svLogicVecVal* o) {
133     o[0].aval = (~i[0].aval) & 0x7fffUL;
134     o[0].bval = 0;
135 }
dpii_v_reg95(const svLogicVecVal * i,svLogicVecVal * o)136 void dpii_v_reg95(const svLogicVecVal* i, svLogicVecVal* o) {
137     o[0].aval = (~i[0].aval);
138     o[1].aval = (~i[1].aval);
139     o[2].aval = (~i[2].aval) & 0x7fffffffUL;
140     o[0].bval = 0;
141     o[1].bval = 0;
142     o[2].bval = 0;
143 }
dpii_v_integer(const svLogicVecVal * i,svLogicVecVal * o)144 void dpii_v_integer(const svLogicVecVal* i, svLogicVecVal* o) {
145     o[0].aval = (~i[0].aval);
146     o[0].bval = 0;
147 }
dpii_v_time(const svLogicVecVal * i,svLogicVecVal * o)148 void dpii_v_time(const svLogicVecVal* i, svLogicVecVal* o) {
149     o[0].aval = (~i[0].aval);
150     o[1].aval = (~i[1].aval);
151     o[0].bval = 0;
152     o[1].bval = 0;
153 }
154 
dpii_v_struct(const svBitVecVal * i,svBitVecVal * o)155 void dpii_v_struct(const svBitVecVal* i, svBitVecVal* o) {
156     o[0] = ~i[0];
157     o[1] = ~i[1];
158     o[2] = ~i[2];
159 }
dpii_v_substruct(const svBitVecVal * i,int * o)160 void dpii_v_substruct(const svBitVecVal* i, int* o) {
161     // To be most like other tools, this should automagically take the substruct_t
162     // as an argument, and not require this cast...
163     substruct_t* issp = (substruct_t*)i;
164     o[0] = issp->b - issp->a;
165 }
dpii_v_bit64(const svBitVecVal * i,svBitVecVal * o)166 void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o) {
167     o[0] = ~i[0];
168     o[1] = ~i[1];
169 }
dpii_v_bit95(const svBitVecVal * i,svBitVecVal * o)170 void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o) {
171     o[0] = (~i[0]);
172     o[1] = (~i[1]);
173     o[2] = (~i[2]) & 0x7fffffffUL;
174 }
dpii_v_bit96(const svBitVecVal * i,svBitVecVal * o)175 void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o) {
176     o[0] = ~i[0];
177     o[1] = ~i[1];
178     o[2] = ~i[2];
179 }
180 
dpii_f_strlen(const char * i)181 int dpii_f_strlen(const char* i) { return strlen(i); }
182 
183 //======================================================================
184 
dpii_f_void()185 void dpii_f_void() {}
186 
187 #ifdef VCS
dpii_t_void()188 void dpii_t_void() {}
dpii_t_void_context()189 void dpii_t_void_context() {}
dpii_t_int(int i,int * o)190 void dpii_t_int(int i, int* o) { *o = i; }
191 #else
dpii_t_void()192 int dpii_t_void() { return svIsDisabledState(); }
dpii_t_void_context()193 int dpii_t_void_context() { return svIsDisabledState(); }
dpii_t_int(int i,int * o)194 int dpii_t_int(int i, int* o) {
195     *o = i;
196     bool disabled = svIsDisabledState();  // Tasks generally need this
197     svAckDisabledState();
198     return disabled;
199 }
200 #endif
201 
dpii_fa_bit(int i)202 int dpii_fa_bit(int i) { return ~i; }
203