After installing all needed tools it is time to run the example. Icoprog comes with an example to blink all the LED’s. Connect to your RPi, change to the icoprog directory and build the bitstream for the example (if it is not built already):
This make target is responsible for the following tasks:
Synthesis via yosys: Takes example.vVerilog hardware description file as input and synthesizes it to example.blif
Pick and Route via arachne-pnr: Takes example.blif and example.pcf and generates a Bitstream in textual representation to example.txt, at this point you can still cat it and read it.
Generate Bitstream with icepack: Takes the readable textual representation of the Bitstream (example.txt) and writes the Bitstream to example.bin
Flashing the Example
Now that the Bitstream is available, it is time to flash it to the FPGA:
This will invoke icoprog and flash example.bin to the icoBoard. You should now see the three LED’s on the board blinking.
Dissecting the Source
Let’s take a deeper look into the two source files used to build the Bitstream.
example.pcf
The physical constraints file contains the pin mappings to variables:
The led variables are mapped to the pins they are connected to. Same goes with clk, which is the FPGA’s clock signal. You can verify and look up the pin identifiers and what they are connected to in the schematic.
example.v
This may be the point where you should go through some Verilog tutorials first. But let’s look at it anyway and see if we can find out what is happening. The following description is comming from someone who never has seen Verilog before, so bear with me.
The firs line seems to define a new module and set the used IO pins defined in example.pcf as in or output, so clk is an input. led1, led2 and led3 are set as output.
The next line seems to initialize a variable called COUNTER_BITS with an integer value of 26, and the one after that seems to initialize a register with the name counter to an array of length COUNTER_BITS and initializes them with 0. So we have an array capable of holding 26 bits which are all zeroed out at the beginning:
The next line seems to define a function that is executed every time when a positive edge from the clock is detected and executes everything until end.
Alright, so the part that lets the LED’s blink seems to be in the always block. The first line is pretty forward, increase the counter by one:
So on every positive edge, our 26 Bit counter is increased by one, lets check out what counter contains:
So the counter will overflow every 67108865th time back to the initial state.
Good, so the functionality to flash the LED’s has to happen in the second line of the always block:
This seems to assign the LED’s a value from our counter array, let’s take a look in detail:
For this part we need to know what ^, » and [COUNTER_BITS-1 -: 3] do.
It is reasonable to assume that » is the right shift operator, shifting the counter array to the right by one Bit, but in this case it only shifts the first three bits because of [COUNTER_BITS-1 -: 3]. Further we can assume, that ^ is the bit wise xor operator.
This means:
Now it also should be clear what [COUNTER_BITS-1 -: 3] does, it “selects” the first three bits and writes them to the LED’s. But is this true? Well that is easy to confirm, just flash the example and watch the LED’s.
There are basically eight different states the example loops through, which makes sense - there are 3 LED’s and all different permutations are 2^3 = 8. Each state 8388608 positive edges long.
But why do we need 26 bits? Because three bits are displayed on the LED’s, leaving 23 for the count of the duration of a single state, and we all love the number 23.
This is in fact something you can now easily try for yourself. If you increase the number of bits, each state will hold on for a longer time. To be exact, each state is held for (n-3)^2 positive edges.
Same thing goes with decreasing until a point where the state changes so fast, that you can not follow it with your eye and all LED’s seem to be on all the time.
Interpreting the graphical representation
With yosys you have the possibility to show a graphical representation of the design. You can use the interactive yosys console to test this.
Create two files:
example.v with the following content:
example.ys with the following content:
Then run the yosys script:
This should generate a dot file that looks like this: