Chapter 1: ¡Hello world! Setbit - miguemoya/open-fpga-verilog-tutorial GitHub Wiki

Examples of this chapter in github

Before starting

Do not forget to clone the tutorials on your computer, to be able to access to all the sample programs:

https://github.com/Obijuan/open-fpga-verilog-tutorial.git

Enter the working directory of tutorial 1:

cd open-fpga-verilog-tutorial/tutorial/ICESTICK/T01-setbit/

You are ready to do the tutorial!

Introduction

The simplest digital circuit is just a wire connected to a known logic level, "1", for example. This way, if you connect a LED to it, it will light up (1) or turn off (0).

Imagen 1

The output of this circuit has been called "A".

setbit.v: Hardware description.

In order to synthesize this circuit into an FPGA, we have to describe it first, using a hardware description language (HDL). In this tutorial we use Verilog, given that we have all the free tools for its simulation/synthesis.

Verilog is a language used for describing hardware... but beware! IT IS NOT A PROGRAMMING LANGUAGE! It's a description language! It allows us to describe the connections and the elements of a digital system.

The Verilog code for this "hello world" circuit implementation can be found in the setbit.v file. It looks like this:

//-- Fichero setbit.v
module setbit(output A);
wire A;
    
assign A = 1;
    
endmodule

Synthesis into the FPGA

In addition to the Verilog file, we'll need to specify which pin of the FPGA we want the component's "A" output to be connected to. This association is made with the setbit.pcf file, (pcf = Physical Constraint File). We will output the "A" signal through pin 99, which is connected to the D1 LED; but it could be any other pin:

set_io A 99

In this example, the file only has one line, linking the "A" label to pin 99 of the FPGA.

Figure 2 graphically displays this idea. We are describing hardware, so making sketches and drawings is a good idea in order to understand our design better:

Imagen 2

To make the complete synthesis of the circuit, we go to the tutorial/T01-setbit folder, and we execute the make sint from the console:

$ make sint

yosys -p "synth_ice40 -blif setbit.blif" setbit.v

/----------------------------------------------------------------------------\
|                                                                            |
|  yosys -- Yosys Open SYnthesis Suite                                       |
|                                                                            |
|  Copyright (C) 2012 - 2015  Clifford Wolf <[email protected]>           |
|                                                                            |
|  Permission to use, copy, modify, and/or distribute this software for any  |
|  purpose with or without fee is hereby granted, provided that the above    |
...

A lot more messages will pop up. My laptop takes less than a second to synthesize. Final messages a look like this:

...
After placement:
PIOs       1 / 96
PLBs       1 / 160
BRAMs      0 / 16

place time 0.00s
route...
pass 1, 0 shared.
route time 0.00s
write_txt setbit.txt...
#-- Generar binario final, listo para descargar en fgpa
icepack setbit.txt setbit.bin
$

When it finishes, it generates a "setbit.bin" file. This file will be uploaded to the FPGA in order to configure it. We put the iCEStick into the USB and execute this command:

$ sudo iceprog setbit.bin

NOTE: If the ICEStick is configured as indicated in chapter 0, the download can be done without sudo.

The process last about 3 seconds The messages that pop up are:

[sudo] password for obijuan: 
init..
cdone: high
reset..
cdone: low
flash ID: 0x20 0xBA 0x16 0x10 0x00 0x00 0x23 0x12 0x67 0x21 0x23 0x00 0x21 0x00 0x43 0x04 0x11 0x11 0x5F 0x7D
file size: 32216
erase 64kB sector at 0x000000..
programming..
reading..
VERIFY OK
cdone: high
Bye.
$

LED D1 on the iCEStick will turn on:

Note: The other LEDs may be dimmly lit. That is normal. It is because they have no signal assigned in the FPGA, and there is a weak pullup by default.

Simulation

Simulate first, synthesize later

In the previous example we directly uploaded to the FPGA because the design was PREVIOUSLY TESTED. When we work with FPGAs we are actually making hardware and we always have to be very careful. We could write a design that contains a short circuit. And it could also happen that the tools don't warn us, (especially in these first versions, still in an alpha stage). If we upload that circuit into the FPGA we could break it.

Because of that, we ALWAYS SIMULATE THE CODE that we write. Once we are sure enough that it works, (and it doesn't have a critical mistake) we upload it into the FPGA.

Testing components: the testbench

If we buy a chip and we want to test it, what do we do? Usually we solder it directly onto a PCB or we put it in a socket. But we can also plug it into a breadboard and place all the wires by ourselves.

In Verilog (and the rest of HDL languages) it's the same idea. You can't simulate a verilog component right away, you need to write a testbench that indicates which cables connect to which pins, which input signals to send the circuit, and check that the circuit outputs the right values. This testbench file is also written in Verilog.

How do we test the setbit component? It's a chip that has only one output pin, always high. In real life we would plug it onto a breadboard, we power it up, we would connect a cable to the output pin, and we would check it's high in voltage with a multimeter. We will do exactly the same, but with Verilog. We would get something like this:

Imagen 3

The file is called setbit_tb.v. We always use the "_tb" suffix to indicate that it the file is a testbench and not a real piece of hardware. This testbench is NOT SYNTHESIZABLE, is a code FOR SIMULATION PURPOSES ONLY. That's why this time we can think of Verilog as a programming language, we are programming something that will "happen" to our circuit.

The testbench has 3 elements: the "setbit" component, a cable called "A" and a check block (The equivalent of a multimeter). This is the code:

    //-- Test bench module
    module setbit_tb;
    
    //-- Cable for connecting the output pin to setbit
    //-- We could give it ANY name, but we call it A (like the setbit pin)
    wire A;
    
    //-- Place the component (it's actually called "instance") and
    //-- connect the A cable to the A pin.
    setbit SB1 (
     .A (A)
    );
    
    //-- Begin the test (Checking block)
    initial begin
    
        //-- Define a file to dump all the data.
        $dumpfile("setbit_tb.vcd");
    
        //-- Dump all the data into that file when simulation finishes
        $dumpvars(0, setbit_tb);
    
        //-- After 10 time units, check if the cable is high.
        //-- In case of not being high, report the problem but
        //-- don't stop the simulation.
        # 10 if (A != 1)
               $display("---->¡ERROR! Output is not 1");
             else
               $display("Component ok!");

      //-- End simulation 10 time units after checking
      # 10 $finish;
    end
    endmodule

Simulating!

We use icarus verilog and GTKwave tools for simulation. We execute the command:

$ make sim

and a window will pop up with the results of the simulation:

At a glance we can see it behaves as intended: the signal in A is always a "1". We can ignore the time units for now, they are seconds by default. After 20 units, simulation ends.

The console will show the following messages:

#-- Compilar
iverilog setbit.v setbit_tb.v -o setbit_tb.out
#-- Simular
./setbit_tb.out
VCD info: dumpfile setbit_tb.vcd opened for output.
Component ok!
#-- Ver visualmente la simulacion con gtkwave
gtkwave setbit_tb.vcd setbit_tb.gtkw &

The one that says "Component ok!" is the one we placed in the testbench when the output was "1".

Proposed exercises

  • Change the component so it outputs a 0. Upload it into the FPGA. Check that the LED is off now.

  • Change the original example so setbit is output through the D2 LED (associated with pin 98 instead of 99)

Conclusions

We have created our first circuit in verilog , a "hello world" consisting of 1 wire. We have synthesized and loaded it into the FPGA. We have also written one test bench in verilog to simulate it. We already have all the tools installed, configured and we have verified that they work. We are ready to tackle more complex designs and learn more verilog

Introduced concepts:

  • pin connections are assigned
  • Creating components with module
  • Definition of output ports with output
  • Definition of a wire with wire
  • testbench