• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Blogs
  2. Verification
  3. Create a Sine Wave Generator Using SystemVerilog
tpylant
tpylant

Community Member

Blog Activity
Options
  • Subscribe by email
  • More
  • Cancel
SystemVerilog
AMS
Functional Verification
Incisive
Incisive Enterprise Simulator (IES)
IES
IES-XL

Create a Sine Wave Generator Using SystemVerilog

30 Jun 2009 • 2 minute read

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:

package math_pkg;

  //import dpi task      C Name = SV function name

  import "DPI" pure function real cos (input real rTheta);

  import "DPI" pure function real sin (input real rTheta);

  import "DPI" pure function real log (input real rVal);

  import "DPI" pure function real log10 (input real rVal);

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.

module sine_wave(output real sine_out);

  import math_pkg::*;

 

  parameter  sampling_time = 5;

  const real pi = 3.1416;

  real       time_us, time_s ;

  bit        sampling_clock;

  real       freq = 20;

  real       offset = 2.5;

  real       ampl = 2.5;

 

  always sampling_clock = #(sampling_time) ~sampling_clock;

 

  always @(sampling_clock) begin

    time_us = $time/1000;

    time_s = time_us/1000000;

  end

  assign sine_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 package available to the scope in which I import it. Now when I call the sinn function, it will use the DPI code from math_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

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information