-
Notifications
You must be signed in to change notification settings - Fork 0
Chapter 1: ¡Hello world! Setbit
Examples of this chapter in github
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!
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).
The output of this circuit has been called "A".
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
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:
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.
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.
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:
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
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".
-
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)
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
- pin connections are assigned
- Creating components with module
- Definition of output ports with output
- Definition of a wire with wire
- testbench
0 You are leaving the privative sector (EN)
1 ¡Hola mundo! (EN) (RU)
2 De un bit a datos (EN)
3 Puerta NOT (EN)
4 Contador de 26 bits (EN)
5 Prescaler de N bits (EN)
6 Múltiples prescalers (EN)
7 Contador de 4 bits con prescaler (EN)
8 Registro de 4 bits (EN)
9 Inicializador (EN)
10 Registro de desplazamiento (EN)
11 Multiplexor de 2 a 1 (EN)
12 Multiplexor de M a 1 (EN)
13 Inicializando registros (EN)
14 Registro de N bits con reset síncrono
15 Divisor de frecuencias
16 Contador de segundos
17 Generando tonos audibles
18 Tocando notas
19 Secuenciando notas
20 Comunicaciones serie asíncronas
21 Baudios y transmisión
22 Reglas de diseño síncrono
23 Controladores y autómatas finitos
24 Unidad de transmisión serie asíncrona
25 Unidad de recepción serie asíncrona
26 Memoria ROM
27 Memoria ROM genérica
28 Memoria RAM
29 Puertas triestado
30 Hacia el microprocesador y más allá