First of all I would like to thank the Element14 Roadtest team for giving me the opportunity to review the Spartan S7 development board.
I got introduced to the Xilinx 7-series FPGAs back in 2013 and I’ve been wondering for a while why there is no Spartan 7. At certain point I thought that the 7-series marks the end of the Spartan family. Recently I was happy to find out that Spartan is far from over and now thanks to the Roadtest team I get to experience the S7 from first person.
What is the Arty S7
Arty S7 Box
The device I get to review is the Arty S7 development board, which features the XC7S50-1CSGA324C Spartan 7 FPGA. The kit includes… well for that price of 89$ the kit includes only the FPGA board. In other words there is no USB cables, power supply etc., however, Digilent has put rubber pads on the bottom side of the board which, I believe, will make the life of many people a bit easier when working with the board.
Inside the Arty S7 box
The bottom side of the S7
Otherwise you can find:
- The Spartan chip, which has:
- 32600 LUTs
- 65200 FFs
- 2700 Kbs of BRAM (75 blocks)
- 5 PLL/MMCM (quite good for a chip of this size)
- Dual channel 12-bit XADC at 1MSPS
- On-board clocks:
- On-board memory:
- 256M DDR3L RAM at 650MHz
- 16MB Quad-SPI Flash
- User Interfaces:
- 4 general purpose switches
- 4 general purpose buttons
- 1 FPGA Reset button, serves as reset input for the FPGA design (active low)
- 1 PROG button, erases the bitstream from the FPGA
- 4 yellow general purpose LEDs
- 2 RGB LRDs
- 1 red DONE LED, indicates that the FPGA is programmed
- 1 yellow power-on LED
- 2 UART LEDs
- 32 PMOD I/O pins, but 16 are shared with the Arduino connector
- 45 pin-Arduino connector with 16 pins shared with the PMODs.
- The Arduino connector also has 6 single-ended 0-3.3V analog inputs and 3 Differential analog inputs
- Power jack(7-15V, 1 Amp min or optimally -12 Volts DC, 3 amps)
- Pin 7(GND) and 8(Vcc) of J8. Note that this option is not compatible with the power jack – power through the jack or the pins. In other words: the jumper is just a different interface to the same DC-to-DC converter inputs.
On the other side you can use both USB and Power jack/J8. In this case the power will be drawn from the jack/J8, no matter if you plug the USB before of after the power jack/J8 - the board will switch automatically between the two.
- via the micro USB, which is connected the on-board JTAG
- by booting from the Quad-SPI flash, JP1 must be shorted.
- or in case you are not able to use the USB, you can connect one of these Digilent JTAG programmers
Digilent have mentioned that JP1 must be open when programming from the JTAG in order to avoid interference from the flash, however, I managed to program the device even with the jumper shorted, and therefore it is not a problem to leave it there, whenever you try a new bitstream.
At first when I noticed the J9, I was wondering why are the holes not in straight line, as you would expect from a normal PCB hole array.
JTAG pin hole array
Later on I realized that the idea of this layout is that you can connect an external JTAG, without having to solder pin connector and still have a reliable connection between the board and the JTAG.
JTAG connector plugged into the pin holes
The JTAG header is simply an alternative to the micro USB port.
To see out of the box demo check out Dixon's post.
Testing the S7
To test this board I will try to build a complete Microblaze design including all peripherals (buttons, switches, LEDS, PMODs, SPI, UART and the DDR.) and using only the supplied “materials” – the IPs from the board panel and the provided constrain file.
Arty S7 Board panel
- Building the basic Microblaze system
Let’s start with the clock and the reset as they are present in almost every design. I had the board files included into my Vivado, hence I added the clock and the reset from the Board panel.
The reset is active low, and when added from the pane it creates an input pin “reset” and a processing system reset block.
Reset elements added to the block design
I did the same for the system clock.
System clock elements
However, there is a little problem. If you simply add the clock and the reset and then run the automatic connection option you end up with the following configuration.
System clock elements automatically connected to the Reset elements
The issue is that the reset is active low, but the clock wizard reset is configured as active high. This is a problem because clock wizard will be constantly in reset, therefore one needs to go to the setting of the IP and change the polarity of the reset. Then the block looks like this.
Block diagram with correct clock wizard reset polarity
Reset polarity option in the bottom of the output clocks options page
Great! Now let’s get the Microblaze. I added it from the catalogue and give the processor a local memory of 128KB. The rest is done automatically.
The result looks like this:
Basic Microbalze system
Cool! But it would be nice if the processor has something to interact with… like a UART. Therefore I went to the Board panel and double-clicked on the USB UART.
Board panel peripherals with the SB UART at the bottom of the page
Added it and ran connection automation. The result is:
Block diagram of the Microblaze, UART, clock and reset elements
One last thing before starting the synthesis – the default baud rate of the UART is 9600, It was changed to 115200 in order to fit the UART settings from the SDK.
The system is ready form testing. The pin constrains from Digilent are added to the design and Generate Bitstream is ran.
Arty S7 constrains included in the project files
The current configuration will be enough for a system that can interact through UART. This test will confirm that the design is working. Afterwards one will be able to increase the complexity of the system.
Once the Bitstream was complete I got the following critical warning:
Basic design critical warnings
This, however, seems to be fine because I compared the constrain file and the pin names from the IO Planner and that the pin locations match somehow.
Figure 18 IO Planner pins
Now that the bitstream is complete, export the hardware to and create a Hello World application in SDK. In order to use xil_printf, I had to enlarge the heap and the stack of the processor . This happened in the Generate liker script options.
Generating linker script
Linker script options with Heap and Stack sizes set to 8KB
Then I connected the board, put the hardware design, connected the UART of the SDK and ran the software (make sure you are connected to the right COM port).
Code used in the Hello World test
Figure 22 Hello World
- *** – Human User Interface
Since the system is working, the design got a bit more complicated. This happened by adding the buttons, switches and LEDs from the Board panel. The resulting system looks like this:
Microblaze design with UART, buttons, switches and LEDS
The wrapper is updated, the bitstream regenerated and the hardware exported to SKD.
To test the RGBs I added the PWM.c and PWM.h from the example design and tried to run the LEDs. There is a little problem. It seems that the RGB IP from the on-board demo does not match with the one from the Board panel:
RGB PWM IP from the on-board project
RGB PWM IP from the Board panel
The difference is not visible, but the IP on figure 24 seems to be designed to drive the RGBs, whereas the block from image 25 is a generic AXI GPIO. To solve this problem you can create your own RGB interface or include the IP from the demo project. The PWM IP of the demo project is supposed to be in …\source\Arty-S7-50-base\src\bd\system\ip\system_PWM_0_0. Unfortunately I did not manage to add the IP or the source files of the IP, therefore I decided to make my own IP, which you can find in my Github repository. This also means that the PWM.c and PWM.h are not used and therefore removed from the project. This forced me to redesign the system, which now looks like this:
Microblaze design with custom RGB controller
Where in the right top corner you can see my custom RGB controller IP. Proceeding further with the project another issue came up – the LEDs did not work. Probably a problem with the constrains. After a lot of digging I found out that it was the problem was in the AXI GPIO. By default the IP looks like this:
LED AXI GPIO added from the Board panel
Even though ports were somehow correct, the LEDs did not lid up. After some investigation with ILA on both the AXI side and the GPIO, I found out that the IP is receiving the commands and is sending out the correct data. This meant that the problem is in the port, therefore I removed the port and connected a new one only to the output of the IP. Now it works!
Working LED AXI GPIO IP configuration
Code used to test the RGBs and the LEDs
Result of the LED test
The LEDs are ready, time for the buttons and the switches.
Code used to read the buttons and the switches
Reading the buttons and the switches
The buttons and the switches are working. The next step is adding the DDR RAM memory. Just like for the rest of the IPs, add the DDR from the Board panel and run the automatic connections. Because there are no DDR pin configurations in the XDC file, I simply updated the wrapper and generated the bitstream. In the software code I simply wrote a value to address 0 of the DDR and then read it back (this test may be too simple to verify the DDR operation but it is enough at this point).
Code used to test the DRAM
Adding the DDR to the design
This also seems to work. Here I decided to stop the review, because the review is taking too much time. Later on I would like to add the XADC the flash, try some PMODs and use the Arduino shield as well as see what can you actually do with *** frequency higher than 50MHz . This however, will happen later on. The test project built in this test as well as the RGB IP can be found in my Github.
The board is working fine, but my biggest concern was the use of the constrains. It is nice that the IPs from the Board panel are connected to their respective pins automatically, however, this seems to cause critical warnings and I don’t like having critical warning in my design, therefore I prefer to use the constrain file. Moreover as shown before, there were some issues with the LED IP. This means that the ports of the IPs have to be edited manually in order to fit the XDC file definitions. Further investigation needs to be done on this topic. I believe this is a problem because dealing with IO planning especially in Vivado can be a tricky task.
Pin names mismatch
Board Peripherals pin name
XDC file name
Another thing was the RGB IP. At first I thought that I am not using it correctly, but after some digging I reconstructed the on-board project from the TCL file ..\source\Arty-S7-50-base\proj\create_project.tcl in order to try the hardware design. I managed to run the RGBs with the demo hardware and my own software, but when I tried to reconstruct the project completely in order to use my software and the recreated hardware, the attempt failed. Then I found out that the RGB IP used in the demo is not the same as the one from the Board panel.
Board panel of the reconstructed on-board demo project
Since I couldn’t find the source files, I decided to build my own. The problem here is that the board is targeted for beginners and if my theory, that the IP provided from the Board panel is a generic AXI GPIO IP, is true, then I believe that a lot of people will have difficulties when working with the RGBs and will get frustrated.
These two issues can be a serious annoyance, especially for people who are just starting with FPGAs. I didn’t have enough time to the Arduino Shield, the SPI and the PMODs, but that will happen later on.
Since I was talking about the demo project - there is no description of the project. I know that it’s aim is to show that the board is working, but some people may want to reverse engineer the project in order to learn how to use the IPs. And the lack of documentation is making this task difficult, which is also not that beginner friendly.
So far you may think that my impression and experience with the board was not that good, however, that is not entirely true. Using the buttons, the switches and the DDR was quite easy and I encountered no problems when working with these peripherals.
 According to my university teacher not all users are human, hence the *** abbreviation.
 I am not completely sure that the IP from the Board panel is not working properly, because I did not manage to spend enough time for investigation, however I took the demo project and replaced the PWM IP with the one from the Board panel and the RGBs were not working. Moreover notice in the demo project that in the GPIO folder the RGB LEDs peripheral is unconnected.