This shows you the differences between two versions of the page.
gtkwave_simulation_for_ice [2019/09/11 09:08] 210.18.207.206 |
gtkwave_simulation_for_ice [2021/02/02 01:24] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== FPGA Verilog simulation using GTKWave on the iCE-feather ====== | ||
- | |||
- | One of the nice things about working with FPGAs and Verilog is the array of open source tools and development boards that are available. | ||
- | |||
- | For this article I'll be using the [[https://github.com/joshajohnson/iCE40-feather|iCE-feather]] development board by Josh Johnson which is based on the [[https://github.com/icebreaker-fpga/icebreaker-examples|ICEBreaker]] [[https://github.com/icebreaker-fpga/icebreaker|board]], but the simulation set up should be the same for many boards. | ||
- | |||
- | If you are using an iCE-feather, you can follow the [[https://github.com/joshajohnson/WTFpga/blob/master/install.md|set up instructions]] to get the icestorm toolchain installed, and get drivers working for this FTDI based board. | ||
- | |||
- | Our aim is to take a verilog file, a testbench and simulate it using Icarus Verilog / GTKWave. | ||
- | |||
- | ===== Setting up a project ===== | ||
- | |||
- | We'll start with a simple standard blinker in one file. | ||
- | |||
- | Create a folder called: | ||
- | |||
- | ''simple-blink'' | ||
- | |||
- | Create a verilog file inside the folder and call it ''blink.v'': | ||
- | |||
- | <code verilog> | ||
- | `default_nettype none | ||
- | |||
- | module top #(parameter integer DELAY = 2500000) ( | ||
- | input wire clk, | ||
- | output wire nLED_GRN | ||
- | ); | ||
- | |||
- | reg [31:0] r_MAX = DELAY; | ||
- | reg [31:0] r_COUNT = 0; | ||
- | |||
- | reg r_led = 0; | ||
- | |||
- | always @ (posedge clk) | ||
- | begin | ||
- | if (r_COUNT < r_MAX) | ||
- | begin | ||
- | r_COUNT <= r_COUNT + 1; | ||
- | end | ||
- | else | ||
- | begin | ||
- | r_COUNT <= 0; | ||
- | r_led <= !r_led; | ||
- | end | ||
- | end | ||
- | |||
- | assign nLED_GRN = r_led; | ||
- | |||
- | endmodule | ||
- | |||
- | </code> | ||
- | |||
- | Nice and simple, blink the red LED on the iCE-feather board after several thousand clock cycles. | ||
- | |||
- | Now a testbench file, create a ''blink_tb.v'' file in our project folder: | ||
- | |||
- | <code verilog> | ||
- | `timescale 1ns/1ns | ||
- | `include "blink.v" | ||
- | |||
- | module blink_tb; | ||
- | |||
- | reg tClk = 1'b0; | ||
- | wire tLed; | ||
- | |||
- | top #( | ||
- | .DELAY(10) | ||
- | ) UUT | ||
- | ( | ||
- | .clk(tClk), | ||
- | .nLED_GRN(tLed) | ||
- | ); | ||
- | |||
- | always #2 tClk <= !tClk; | ||
- | |||
- | // Dump wave | ||
- | initial begin | ||
- | $dumpfile("blink_tb.lxt"); | ||
- | $dumpvars(0,blink_tb); | ||
- | end | ||
- | |||
- | initial | ||
- | begin | ||
- | #100; | ||
- | $finish; | ||
- | end | ||
- | |||
- | endmodule | ||
- | </code> | ||
- | |||
- | I'll explain a couple of things from the testbench. Firstly, an ns timescale is being used. So each time unit is a nanosecond. This will keep the timescale nice and compressed to view in the simulation. In the real module, the timescale has too much data to comfortably view. | ||
- | |||
- | There is a dump file generated using the testbench. Icarus Verilog / GTKWave uses these files for its simulation. | ||
- | |||
- | Now to download and install Icarus Verilog / GTKWave from: http://bleyer.org/icarus | ||
- | |||
- | Open a commandline to the project folder. We'll execute all the steps manually. And later, we'll move them to a Makefile to make life much easier. | ||
- | |||
- | |||
- | ===== Manual Simulation Steps ===== | ||
- | |||
- | Create a ''sim'' folder with: | ||
- | |||
- | mkdir sim | ||
- | |||
- | Next... | ||
- | |||
- | iverilog -Wall -o sim/blink_tb blink_tb.v | ||
- | |||
- | This will compile the testbench into code suitable for simulation by the ''vvp'' runtime. | ||
- | |||
- | vvp sim/blink_tb -lxt2 | ||
- | |||
- | vvp takes the compiled blink_tb and executes a simulation with it. The -lxt2 flag means to output an lxt2 dump file that the GTKWave is able to nicely display for us. | ||
- | |||
- | mv blink_tb.lxt sim/blink_tb.lxt | ||
- | |||
- | Simply move the resulting blink_tb.lxt file into the ''sim'' folder. | ||
- | |||
- | gtkwave sim/blink_tb.lxt | ||
- | | ||
- | Here's the exciting bit. GTKWave will open up and load the simulation dump. But as yet, no signals have been chosen to visualise: | ||
- | |||
- | {{ :wiki:gtkwave-loaded.png?nolink |}} | ||
- | |||
- | Drag the ''clk[0]'' and ''nLED_GRN[0]'' signals into the ''Waves'' pane and your waveforms will display! | ||
- | |||
- | {{ :wiki:gtkwave-with-signals.png?nolink |}} | ||
- | |||
- | The wave setup is lost if you exit GTKWave. But you can save a config so that these signals are chosen next time you recompile the code. Select ''File'' > ''Write Save File As''. | ||
- | |||
- | {{ :wiki:gtkwave-save-config.png?nolink |}} | ||
- | |||
- | Save the file into the ''sim'' folder as: ''gtkwaveConfig.gtkw'' | ||
- | |||
- | Now close GTKWave. Next time you execute with: ''gtkwave sim/blink_tb.lxt'' the signals you set will be shown again. | ||
- | |||
- | |||
- | ===== Automatic Simulation Steps with a Makefile ===== | ||
- | |||
- | It would be cumbersome to type all those commands each time you made a change to your verilog code to display your simulation. Thankfully a makefile can make like so much easier. | ||
- | |||
- | You can [[https://github.com/joshajohnson/WTFpga/blob/master/blink/Makefile|pinch a really nice one]] from Josh Johnson's version of the WTFpga course. | ||
- | |||
- | The main piece of interest from the makefile is this: | ||
- | |||
- | <code makefile> | ||
- | simulate: | ||
- | iverilog -Wall -o sim/$(PROJ)_tb $(PROJ)_tb.v | ||
- | vvp sim/$(PROJ)_tb -lxt2 | ||
- | mv $(PROJ)_tb.lxt sim/$(PROJ)_tb.lxt | ||
- | gtkwave sim/$(PROJ)_tb.lxt sim/gtkwaveConfig.gtkw | ||
- | </code> | ||
- | |||
- | Copy the Makefile into the root of your project folder. | ||
- | |||
- | Now you can execute everything and see your simulation in one step with: | ||
- | |||
- | make simulate | ||
- | | ||
- | And that's it. Enjoy! | ||