Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17049 Discussions

Simulating a FIFO using QuestaSim

DrewMissler
Beginner
722 Views

This is not a question but a step-by-step document of how to simulate the Intel IP FIFO as there are not many resources on how to do this. If the post is formatted wrong, I've attached a document that should be formatted correctly. I hope some starting out in FPGA development can find this helpful.

 

Simulating FIFO Using Questa Sim

Tools: Quartus 23.1 Standard, QuestaSim

Verilog

  • Create a new Quartus Project (.qpf)
    1. File -> New -> New Quartus Prime Project
    2. [Introduction] Next
    3. [Directory, Name, Top-Level Entity] Pick file location, name project/top-level entity something descriptive

DrewMissler_0-1722006447827.png

 

  1. [Project Type] Empty
  2. [Add Files] Next
  3. [Family, Device, & Board Settings] Choose accordingly, I left as default (as there is no physical FPGA I am using for this simulation)
  4. [EDA Tool Settings] Choose Questa Intel FPGA for Simulation tab and either Verilog or VHDL accordingly for the format

DrewMissler_1-1722006447832.png

 

  1. [Summary] Finish
  • Generate IP (PLL and FIFO)
    1. Under [IP Catalog] on the right side, select Library -> Basic Functions -> Clocks, PLLs and Resets -> PLL | Then double click PLL Intel FPGA IP | Give the PLL a name, in my case I named it, “my_pll” | click OK

 

  1. The next step sets up the given IP (this case is PLL) | For [General] Number Of Clocks: 2, outclock0 Desired Frequency: 100 MHz, outclock1 Desired Frequency: 25 MHz | (don’t worry about changing anything else in this case) | Finish
  2. A Generation window will pop up -> Exit -> Yes (to adding files to project)
  3. Under [IP Catalog] on the right side, select Library -> Basic Functions -> On Chip Memory | Then double click FIFO | Give the FIFO a name, in my case I named it, “my_fifo” | click OK

DrewMissler_2-1722006447835.png

 

  1. Under the common clock setting, select No -> Next

DrewMissler_3-1722006447838.png

 

  1. Under DCFIFO 1, select Best metastability protection -> 3 sync stages -> Next

DrewMissler_4-1722006447840.png

 

  1. Under DCFIFO 2, select Asynchronous clear -> Next

DrewMissler_5-1722006447842.png

 

  1. For the next few prompts, leave as default until [Summary], where you select Instantiation Template File -> Finish
  2. As with the PLL, you will be prompted to add the files to the project where you will select Yes
  • Creating a Top File
    1. Click File -> New -> SystemVerilog HDL File -> OK

DrewMissler_6-1722006447844.png

 

  1. Input the following code and save as “top.sv”:

-         // top module with inputs/outputs

-         module top (input clk, rst,

-                                                                                         output rdempty, wrfull,

-                                                                                         output [7:0] data_out);

-          

-         //wires each signal                     

-          

-         logic clk_25, clk_100;                  // 25MHz and 100 MHz clocks

-         logic flag_locked;

-         logic fifo_aclr;

-          

-         assign fifo_aclr = !flag_locked; // aclr = not flag_locked

-          

-         logic wrreq; // write request

-         logic [7:0] data_in; // 8 bits of input data

-          

-         always_ff @(posedge clk_100,posedge fifo_aclr) begin // every 100 MHz clock

-           if (fifo_aclr) begin // if clear, data = 0

-             data_in<='0;

-           end else begin

-             if (flag_locked) begin // if not clear, data in += 00000001?

-                                                 data_in <= data_in+8'b1;

-                              end

-           end

-         end

-          

-         always_ff @(posedge clk_100,posedge fifo_aclr) begin // write clock = 100 MHz

-           if (fifo_aclr) begin // if clear, write request = 0

-             wrreq<='0;

-           end else begin

-             wrreq<=~wrreq; // otherwise, write request inverted

-           end

-         end

-          

-         logic rdreq;

-         always_ff @(posedge clk_25,posedge fifo_aclr) begin // read clock = 25 MHz

-           if (fifo_aclr) begin // if clear, read request = 0

-             rdreq<='0;

-           end else begin

-             rdreq<=~rdreq; // otherwise, read request inverted

-           end

-         end

-          

-         my_fifo    my_fifo_inst ( // fifo instance

-                             .aclr ( fifo_aclr ),

-                             .data ( data_in ),

-                             .rdclk ( clk_25 ), // read clock is 25 MHz

-                             .rdreq ( rdreq ),

-                             .wrclk ( clk_100 ), // write clock is 100 MHz

-                             .wrreq ( wrreq ),

-                             .q ( data_out ), // output is data_out

-                             .rdempty ( rdempty ),

-                             .wrfull ( wrfull )

-                             );

-          

-         my_pll uut( // PLL instantiation, sets up 25MHz and 100MHz clocks

-                                                 .refclk(clk),  

-                                                 .rst(rst),     

-                                                 .outclk_0(clk_100),

-                                                 .outclk_1(clk_25),

-                                                 .locked(flag_locked)   

-                             );

-          

-        endmodule

There are included comments for understanding

  1. Add the file to the project and set it as the top entity by right clicking on top.sv under Project Navigator (you may have to switch to the files tab) and selecting “Set as Top-Level Entity”

DrewMissler_7-1722006447855.png

 

  • Creating a Constraints File
    1. Select File -> New -> Synopsys Design Constraints File

DrewMissler_8-1722006447857.png

 

  1. Insert the following code and save as top.sdc:

-        #File:top.sdc

-        create_clock -period 20.000 -waveform {0.000 10.000} -name clk50 [get_ports {clk}]

-        derive_pll_clocks

  • Compile the Project
    1. Compile the project by selecting Processing -> Start Compilation

DrewMissler_9-1722006447869.png

 

  • Creating the Testbench
    1. Click File -> New -> SystemVerilog HDL File -> OK
    2. Insert the following code and name it “top_tb.sv”:

-         `timescale 1ns/1ps

-          

-         module top_tb;

-          

-         logic clk, rst, rdempty, wrfull;

-         logic [7:0] data_out;

-          

-         top my_top(.*);

-          

-         initial begin // sets up clock

-           clk=0;

-           forever #10 clk=~clk;

-         end

-          

-         initial begin

-           $monitor(" empty:",rdempty," full:",wrfull," dout:",data_out);

-           rst = 1;

-           repeat (10) begin

-              @ (negedge clk);

-           end

-           rst = 0;

-           repeat (1000)begin

-             @ (negedge clk);

-           end

-           $stop; //$finish tends to close the simulator

-         end

-                                                                                        

-        endmodule

  • Simulating the Project
    1. Start the simulator by going to Tools -> Run Simulation Tool -> RTL Simulation
    2. Once QuestaSim opens, select Compile -> Compile… | Select top_tb.sv, top.sv, my_fifo.v, my_pll.v and my_pll_0002.v from the “my_pll/” directory (you can use CTRL + left-click to select multiple files) | Select Compile then Done
    3. To start the simulation, type the following command into the QuestaSim command line:

vsim -voptargs=+acc work.top_tb -L altera_mf_ver -L altera_lnsim_ver

(The -voptargs=+acc will simulate the project unoptimized, which when not done, caused issues that will be explained later in this document)

  1. Add signals into the waveform by running the following command:

add wave -position insertpoint sim:/top_tb/*

(The /* after your directory will add all signals from that file to the waveform)

  1. Finally type the following command to run the simulation:

run -all

  1. The simulation is now complete and will be shown in the waveform window

DrewMissler_10-1722006447876.png

 

Problems Encountered

The largest problem encountered was the simulation attempting to run while optimizing the file. This caused QuestaSim to not recognize the signals in the top_tb file and therefore I was unable to add them to the simulation waveform. To fix this, I used the -voptargs=+acc command to run the simulation unoptimized.

 

Notes

To add more signals to the waveform, you can right click on the signal from the given file and select Add to Wave.

This project adds the simulation data in the top.v file, this can also be done (which will separate the simulation data) in the testbench file. There will be a separate document on doing so.

The simulation can also be scripted as to save time on setting it up in the QuestaSim GUI. This will also be done in a separate document.

This document describes the process of creating the project in Verilog. There will also be a document on doing so in VHDL.

 

References

https://eclipse.umbc.edu/robucci/cmpeRSD/discussions/discussion09/

Very helpful tutorial that I followed to achieve this simulation

Labels (1)
0 Kudos
1 Reply
TingJiangT_Intel
Employee
583 Views

Thanks a lot, the steps are very detailed and accurate. That really helps.

Appreciate for your kindly sharing again.


0 Kudos
Reply