0% found this document useful (1 vote)
1K views

Create A Sine Wave Generator Using SystemVerilog

The document describes how to create a sine wave generator module in SystemVerilog using the DPI feature and real data types. It discusses importing math functions from C using DPI, defining a module that outputs a real sine wave by calling the sin function and passing time as an argument, and allows real values to be passed through ports. The module samples the sine function at a given rate to produce the output wave.

Uploaded by

dawadhali
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (1 vote)
1K views

Create A Sine Wave Generator Using SystemVerilog

The document describes how to create a sine wave generator module in SystemVerilog using the DPI feature and real data types. It discusses importing math functions from C using DPI, defining a module that outputs a real sine wave by calling the sin function and passing time as an argument, and allows real values to be passed through ports. The module samples the sine function at a given rate to produce the output wave.

Uploaded by

dawadhali
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

Create a Sine Wave Generator Using SystemVerilog

By Timothy Pylant on June 30, 2009Comments(5)Filed under: Functional Verification, SystemVerilog, IES, AMS, Incisive
Enterprise Simulator (IES), IES-XL, Incisive

Two capabilities in SystemVerilog allow for the creation of a module that can produce a sine wave as an output: the
ability to pass real values through port connections and DPI.
Obviously, to produce a sine wave, you need access to the sin function. This is where DPI is handy to add the math
functions to your simulation. Here is an example of a package I created to contain the math functions:

packagemath_pkg;
//importdpitaskCName=SVfunctionname
import"DPI"purefunctionrealcos(inputrealrTheta);
import"DPI"purefunctionrealsin(inputrealrTheta);
import"DPI"purefunctionreallog(inputrealrVal);
import"DPI"purefunctionreallog10(inputrealrVal);
endpackage:math_pkg
The import"DPI" construct defines a new function that you can use in your code that refers to a C function. In the
case of the math functions listed above, they already exist in the libmath.so library built into Linux and so there is no
additional code required. Now that I have my math functions, I can create my module.

modulesine_wave(outputrealsine_out);
importmath_pkg::*;

parametersampling_time=5;
constrealpi=3.1416;
realtime_us,time_s;
bitsampling_clock;
realfreq=20;
realoffset=2.5;
realampl=2.5;

alwayssampling_clock=#(sampling_time)~sampling_clock;

always@(sampling_clock)begin
time_us=$time/1000;
time_s=time_us/1000000;
end
assignsine_out=offset+(ampl*sin(2*pi*freq*time_s));
endmodule
Here I have used import in a different context. In this case import is used to make the code in
my packageavailable to the scope in which I import it. Now when I call the sinn function, it will use the DPI code
frommath_pkg to execute the function.
The sine_wave module also shows the use of passing a real value through a port. The output sine_out is of
type real and is computed using the sin function.
SystemVerilog allows a real variable to be used as a port. The limitation is that a real variable can only be driven by a
single driver. If that is a problem, you can make the module a Verilog AMS module and define the real variable as
a wreal (real wire). By using wreal, you can have multiple drivers and use a variety of resolution types to solve any
conflicts.
Tim Pylant

Comments(5)
B
y S. Mutchnik on July 16, 2009
Hi Tim, I had this same problem before and used something else I found:

A function that has a sin approximation, input is real, and you invoke the function at the desired clock rate and supplying the
desired input, here is the code:
`define PI 3.14159265
function real sin;
input x;
real x;
real x1,y,y2,y3,y5,y7,sum,sign;
begin
sign = 1.0;
x1 = x;
if (x1<0)
begin
x1 = -x1;
sign = -1.0;
end
while (x1 > `PI/2.0)
begin
x1 = x1 - `PI;
sign = -1.0*sign;
end
y = x1*2/`PI;
y2 = y*y;
y3 = y*y2;
y5 = y3*y2;
y7 = y5*y2;
sum = 1.570794*y - 0.645962*y3 +
0.079692*y5 - 0.004681712*y7;
sin = sign*sum;
end
endfunction // sin

By tpylant on July 16, 2009


That works great! I just put your code in my package in place of the "import...sin" and it worked like a champ.
Thanks for sharing,

Tim
By S. Mutchnik on July 17, 2009
If we are at it already, here is the COS function, Root of 2, Natural base LOG, LOG 2 and LOG 10 (best to have all these
and the SIN function together in the same file since they may call on each other):
// COS function
function real cos;
input x;
real x;
begin
cos = sin(x + `PI / 2.0);
end
endfunction
// ROOT of 2
function real rootof2;
input n;
integer n;
real power;
integer i;
begin
power = 0.82629586;
power = power / 10000000.0;
power = power + 1.0;
i = -23;
if (n >= 1)
begin
power = 2.0;
i = 0;
end
for (i=i; i< n; i=i+1)
begin
power = power * power;
end
rootof2 = power;

end
endfunction // rootof2
// does LOG_N of a number
function real log_n;
input x;
real x;
real re,log_2;
integer i;
begin
if (x <= 0.0)
begin
$display("log N illegal argument:",x);
$stop;
log_n = 0.0;
end
else
begin
if (x<1.0)
re = 1.0/x;
else
re = x;
log_2 = 0.0;
for (i=7; i>=-23; i=i-1)
begin
if (re > rootof2(i))
begin
re = re/rootof2(i);
log_2 = 2.0*log_2 + 1.0;
end
else
log_2 = log_2*2.0;
end
if (x < 1.0)

log_n = -log_2/12102203.16;
else
log_n = log_2/12102203.16;
end
end
endfunction // log_n
// does LOG2 of a number - using LOG_N
function real log2;
input x;
real x;
begin
log2 = log_n(x)/log_n(2.0);
end
endfunction // log2
// does LOG10 of a number - using LOG_N
function real log10;
input x;
real x;
begin
log10 = log_n(x)/log_n(10.0);
end
endfunction // log10

By tpylant on July 17, 2009


Awesome!
Thanks,
Tim
By Alok Sharma on March 10, 2011
I have a signal generating sine wave. Need some code that can make sense out of it in terms of frequency, amplitude etc.
and dump it in a file.
Any quick thoughts please,
Thanks,
Alok

You might also like