Skip to content

HDL Simulation with Vivado

Peter Saunderson edited this page Feb 28, 2016 · 2 revisions

Home / Tutorial Index / HDL Simulation with Vivado

Introduction

Simulation of designs is an important part of the development cycle. I have not found a guide anywhere so here is a first attempt to guide the reader into Vivado simulation.

First I have only proven this with Xilinx Vivado 2014.4.1 and before starting built the fpga project in parallella/parallella-fpga. See Building the FPGA for a brief guide.

Second this description is written with respect to the 7020_hdmi project, however there is also a 7010_hdmi project and that also has a Elink2.tcl script so make sure that you use the correct script and that the file paths in the script are correct for your environment.

Third this description is now old and references files in the older design https://github.com/peteasa/parallella-fpga/tree/a2725f0bd93006a2a28382732d565247286edb36. You might consider trying the latest fpga design and using the Verilator simulator HDL Simulation with Verilator.

Preparation

I use Linux Xilinx tools, so you may have to modify things a bit for the Windows tools if you use windows.

The AdaptevaLib/ip_repo/axi_traffic_controller_1.0 is used in the 7020_hdmi/7020_hdmi.srcs/sources_1/bd/elink_testbench block design to read and write hex address and data from / to files (look in 7020_hdmi/7020_hdmi.sim) and present them to the elink2 and elink_gold subblocks. elink_gold is a simulation of the elink connection so that RX and TX data can be presented to the elink2 subblock in the simulation. In this design the data is written to registers or memory from a file and read from the same registers or memory and written to an output file that you will only see after the simulation has completed (rdata0_out, rdata1_out and rdata1_ecfg_out).

The axi_traffic_controller_1.0 verilog code has been updated to ignore the inbuilt comparision (setting read_mismatch <= 0)

else if ((M_AXI_RVALID && axi_rready) && (M_AXI_RDATA != expected_rdata))
  read_mismatch <= 1'b0;

If this modification is not made then the simulation run will appear to fail when actually it has succeeded. Instead of using the read_mismatch register, compare the *_out file contents and check that the data written out of the simulation is correct to ensure that the simulation has succeeded. Look in 7020_hdmi/7020_hdmi.srcs/sources_1/ipshared/adapteva/axi_traffic_controller_v1_0/030c79bb/hdl/axi_traffic_controller_v1_0_M_AXI.v to check that the above modification has been made.

As part of the "Generation of Output Products" step (this should have occurred during the make process Building the FPGA) the library hdl code is copied to the sources_1 folder. Later as part of the simulation step it is these files that are compiled and simulated. So ensure that the file is present. If the "Generation of Output Products" step has used different paths and the folder 030c79bb does not exist then modify the file paths in 7020_hdmi/Elink2.tcl to match the paths that are present. Also in that script file modify the sources_1 and imports paths to match your configuration. If the clone of the parallella project is in the home directory and you launch vivado from the desktop icon then there should be no problems!

In Vivado normally I run synthesis prior to simulation to check that the design is ok first (Run Synthesis step).

Have a go at stepping throught the simplest test run

To start the simulator navigate to {Flow Navigator; Simulation; Run Simulation} and select the Behavioural Simulation option. With a text editor, edit the simulation tcl script 7020_hdmi/Elink2.tcl and at the end of that script file comment out all the steps apart from the eCfgRegWrite function then save the file:

# Uncomment this for eCfgRegWrite
[eCfgRegWrite $sources_1 $imports]

# Uncomment this for WriteeCfg
# [WriteeCfg $sources_1 $imports]

# Uncomment this for WriteElinkGold (and write to elink2)
# [WriteElinkGold $sources_1 $imports]

# Uncomment this for tracing ELINK2 -> Gold
# [StartTx $sources_1 $imports]

Now in vivado navigate to {Tools; Run tcl Script} and select that Elink2.tcl script file. The eCfgRegWrite tcl function should run and the first breakpoint should be reached in $sources_1/ipshared/adapteva.com/eCfg_v1_0/909fbb94/hdl/ecfg.v 313. At this point the file 7020_hdmi.sim/wdata_ecfg has been read, mi_din will contain the first data item from that file "00000001" and the address of the E_REG_SYSRESET register in ecfg.v will have been selected so that ecfg_reset_reg is set to "1". You can view the wave traces in the Elink2.wcfg Waveform window that has opened. Right hand mouse click on the small dot next to elink2 and then on the small dot next to eCfg at the bottom of the list to display the significant eCfg input signals.

Now press F8 and notice that mi_addr[11:0] shows 0x40 and mi_din[31:0] shows 0x1. F8 moves on one step in the simulator, typically all the steps happen in parallel in the hardware but the software simulator cant show that so you have to press F8 a lot to get the Waveform window to update.

Now press <SHIFT F2> and the second breakpoint is reached in $sources_1/ipshared/adapteva.com/eCfg_v1_0/909fbb94/hdl/ecfg.v 242. At this point the second value has been read from wdata_ecfg and the second address has been read from waddr_ecfg. Notice that mi_addr[11:0] shows 0x44.

The yellow cursor on the Waveform window marks the point at which the trace will be zoomed if you move <CTRL mouse wheel> or press the zoom in button on the window border then the trace will expand to show more details.

Viewing the results

If you run the simulation till all the stages are complete (done <= 3'b111) then look in the folder 7020_hdmi/7020_hdmi.sim you will see that additional data files have been created with the address and data information read from the elink during the simulation run.

  • waddr - contains the 5 addresses that are presented on the AXI bus to elink
  • wdata - contains the associated 5 data values written to the elink.
  • raddr - contains the 5 addresses that are presented on the AXI bus for read, notice they are in a different order
  • rdata0_out - contains associated 5 data values read from elink
  • rdata1_out - contains associated 5 data values read from elink

waddr_ecfg, wdata_ecfg, raddr_ecfg, rdata1_ecfg_out are the configuration values written to configure elink and the read back of these.

Notice that if the elink reads from the wrong place the rdata* file will have deadbeef as the data or perhaps even the wrong data value. If you are interested I have a patched version of esaxi_v1_0_S00_AXI.v that fixes this simulation data access problem. I have decided that the issue is only with the simulation run and is not a real design issue, however sometimes its good to be able to see the whole thing working "correctly".

Other test runs

Look in 7020_hdmi/Elink2.tcl for the other functions:

proc eCfgRegWrite - provides breakpoints for significant places in the read and write of eCfg registers that configure the elink2 for the test run.

proc WriteeCfg - provides breakpoints for significant places in the axi_traffic_controller verilog to show read and write to the files as the eCfg registers are updated, finishing at INIT Complete.

proc WriteElinkGold - is a more complicated script because two overlapping activities are in progress. First the axi_traffic_controller is writing to the elink_gold module that then generates the elink RX traffic, Second a different instance of the axi_traffic_controller is writing to the elink2 subblock that then generates the elink TX traffic. The script starts at INIT Complete and finishes at the end of the simulation run when done <= 0x3.

proc WriteElinkGold - traces the flow of data from axi_traffic_controller -> the fifo_103x16_write -> eproto_tx and the elink TX.

Uncomment one of these at a time and try out the other simulation runs that I have prepared, for example to run StartTx:

# Uncomment this for eCfgRegWrite
# [eCfgRegWrite $sources_1 $imports]

# Uncomment this for WriteeCfg
# [WriteeCfg $sources_1 $imports]

# Uncomment this for WriteElinkGold (and write to elink2)
# [WriteElinkGold $sources_1 $imports]

# Uncomment this for tracing ELINK2 -> Gold
[StartTx $sources_1 $imports]

Conclusion

The Vivado simulator is very primitive and sometimes even gives the wrong output, however with the use of the tcl scripts it is possible to investigate the design and even automate design verification tests. I hope that this quick guide has helped getting started with the Vivado simulator.

Feedback is always welcome

Home / Tutorial Index / HDL Simulation with Vivado