In my last two blogs, I talked only about VHDL codes and the implementation of digital logic design in Vivado. In this blog, I will be working on the hardware aspects.
I received the Arty-S7 board from e14 for the Spartan_Migration challenge. I will use the board to perform simple experiments to show how to control hardware such as switches, LEDs, using FPGAs. Then for an advanced project, I will use the board to implement an IR-based object counter project by adding an IR sensor.
Arty S7 Board
Let's take a look at the board first -
It came in a nicely packed box with ARTY S7 written on top. It mentions that it is for makers and hobbyists and after experimenting with the board, I can agree. It is pretty simple to get started with the board, and Digilent provides ample resources online to get started with the Arty S7 board. You can find them here.
The FPGA board looks like this
It has plenty of switches that can be used for inputs (4 push buttons and 4 toggle switches) = 8 inputs!!
It also has 4 LEDs +2 RGB LEDs from LD0 to LD5 apart from that, there are 4 ports (PMOD connectors) with 8 I/O pins per port that can be used for interfacing with other components such as displays, Bluetooth modules, etc as some of the other challenges have shown it in their blogs.
Powering it up!
Let's try powering on the board.
Upon powering it on, the pre-loaded program starts running inside the Spartan-7 FPGA and the LEDs start "running" from left to right and right to left.
Playing with the toggle switches, the LEDs just glows, corresponding to the switch toggled. The push buttons change the status of the 2 RGB LEDs to Off, R, G, and B states, respectively.
Constraints file and Programming the FPGA
Now let's try to implement a simple hardware-controlled logic gate such as AND gate that I implemented in the last blog. Here, I will use the toggle switches as inputs to the AND gate and one of the LEDs as an output for the AND gate.
The entire process of writing the code remains the same as last blog, except that now we have to define that the inputs are actual inputs from the real world (hardware) and the output is an actual real-world device (LED). To do so, we have to write a constraints file in Vivado. A constraints file will "map" our input and output signals that we have defined in the VHDL code to the physical pins on the FPGA, where we will connect our switches and LEDs.
Since the PCB for the Arty S7 is already there, we cannot change the connections of these hardware components with the FPGA chip, so for defining the constraints file, I will first take a look at the datasheet to check the connections of these switches and LEDs with the pins of the FPGA so that we can define our constraints.
The connection diagram below shows the connections of the physical pins with the external components. We have to define these physical pins in the constraints file.
Here the toggle switches/slide switches are connected to the FPGA's H14, H18, G18, and M5 pins. I will use the H14 and H18 as inputs. Similarly, for the LEDs, I will require only 1 LED to show the output; I will use the LD2 connected to the E18 pin of the FPGA.
To define a constraint file, there are two methods -
- Most of the blogs that I read here used the master XDC file to define the constraints. A master XDC file is available for download from the digilent website. The master XDC file contains all the external components that are present on the Arty S7 board mapped to the respective pins. This method is relatively easy as all the peripherals are already listed in the master XDC file and the user just has to uncomment the required lines. Personally, I do not prefer this method as every time; I have to delete or comment the constraints that are not in use for my project.
- The second method is by defining our own constraints using the I/O floor planning window. This is my preferred method because this gives the user flexibility in case you are working on a standalone FPGA chip instead of an evaluation board. You need not worry about the syntax, as the I/O floor planning will automatically generate the XDC file for you. The user just needs to know the correct logic for the particular device. Here, for the switches and LEDs, it is LVCMOS33.
To define the constraints, first, open the implemented design in Vivado (after running synthesis and implementation)
Then from the drop-down menu at the top right corner, select I/O planning.
It will open a new tab below named I/O ports. This will automaticall detect the I/O ports from our VHDL code.
Just for reference, this was my entity for AND gate -
entity logic_gates is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : out STD_LOGIC);
end logic_gates;
The I/O floor planning automatically detected 3 ports, 2 inputs, and 1 output. Now from the drop-down menu for each pin, I can select the package pin as mentioned above. The switches are H14 and H18 and LED with E 18 pin with LVCMOS33 logic for all. Once everything is defined in floor planning just click on save and vivado will prompt you to save and name the XDC file.
I have shown how the automatically generated XDC file looks like
Now again, run the synthesis and implementation after generating the XDC file. Finally, for the last step, generate a bitstream; If the XDC is correct, this will generate a file that has to be loaded into the FPGA. The bit file will program the FPGA with our code, and it is expected that the FPGA will give the results as seen in the simulations.
To program the FPGA with our bit file, click on hardware manager -> open target -> program device. This will open a prompt to program the device (FPGA) with the bit file.
That's it. Now the FPGA has our program inside the core. Let's give it a try. The initial demo program is erased from the FPGA, and now I will try if my implemented AND gate works or not.
The above video shows all the logic combinations for a 2-bit input using the switches. It can be seen that only for both the switches ON (11) combination, the LED is ON, and for all other combinations, the LED remains OFF.
Hence, it is verified that our VHDL code actually works as expected inside the FPGA, and we also saw how to interface external real-world components with the FPGA and control them.