This shows you the differences between two versions of the page.
gtkwave_simulation_for_ice [2019/09/11 07:06] 210.18.207.206 created |
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 | ||
- | |||