Red Pitaya FPGA Project 1 – LED Blinker
Red Pitaya is a Zynq7 FPGA-based low cost electronic board with many components such as two core ARM processor, fast ADCs, fast DACs, USB, LAN, etc. In many aspects Red Pitaya is similar to the Arduino or Rasbery Pi with a large community of enthusiasts and increasing collection of open-source material. What makes Red Pitaya even better are the two fast ADCs, two fast DACs and most of all the programmable logic or field-programmable-gate-array (FPGA). With an on-chip FPGA Red Pitaya could be used for high performance computing, state-of-the-art measurement system, signal processing and much more. Having both linux-based processing system and programmable logic Red Pitaya is an ideal board for introduction to the FPGA programming and ultimately for building powerful professional and non-professional projects such as radar, radio systems, vector-network-analyzer, etc.
Available documentation for Red Pitaya’s FPGA development is at the moment rather scarce and can be quite confusing for total beginners. In this series of Red Pitaya FPGA projects I would like to reduce this confusion and help people to quickly start developing their own ideas.
Our projects will be similar to the ones made by Pavel Demin where we will even use some of his Red-Pitaya specific IP cores. Here posts will similarly not start with a modification of the official Red Pitaya source code as it contains many components required by bazaar apps and is thus unnecessarily complex. Instead we will start with a minimal system and gradually add new components.
In the first post we will set up a development platform for programming FPGA using Xilinx’s Vivado software and create the simplest example – a hardware equivalent of the Hello World – the LED blink. For convenience all steps presented here will be shown for Windows operating system, although most of them will also work on Linux. For more information regarding Vivado installation under Linux see RedPitaya’s (for Vivado 2013.3) or Pavel Demin’s (for Vivado 2016.2) page.
At this stage it is assumed that Red Pitaya is successfully connected the local network with an established ssh (or Putty) connection. If not, follow Red Pitaya’s official quick-start instructions.
For the FPGA development platform we will use Xilinx’s Vivado Design Suite with SDK. At the time of writing the latest version was Vivado 2016.2, however, other versions would also work. The Vivado Suite can be installed for free with WebPACK licence, which can be downloaded after registration from their webpage.
To install Vivado follow these steps:
- Register, download and install latest Vivado Design Suite with SDK.
- Obtain free WebPACK licence
- Optionally download and install Lab tools
After the installation of Vivado is complete download project source files from https://github.com/apotocnik/redpitaya_guide or if git is installed execute in command prompt
git clone https://github.com/apotocnik/redpitaya_guide.git
Now, we are ready to build our first project 1_led_blink. Open Vivado and in Vivado Tcl Console navigate to the base folder: redpitaya_guide/ . There execute the following line
make_project.tcl automatically creates a full project in the tmp/1_led_blink/ folder. Take a moment to examine the Block Design. If it is not open click on Open Block Design on the left-hand side of the window. When you are ready click Generate Bitstream at the bottom-left part of the window to generate bitstream file. After you confirm that both Synthesis and Implementation will be executed beforehand the longer process starts.
When synthesis, implementation and bitstream generation are successfully finished the bit file can be found at redpitaya_guide/tmp/1_led_blink/1_led_blink.runs/impl_1/system_wrapper.bit
Copy newly generated bit file to the RedPitaya’s /root/tmp folder using WinSCP or type the following commands in Linux console
cd redpitaya_guide/tmp/1_led_blink/1_led_blink.runs/impl_1/ scp system_wrapper.bit root@your_rp_ip:led_blink.bit
Finally, we are ready to program the FPGA with our own bitstream file located in the /root/ folder on Red Pitaya. To program the FPGA simply execute the following line in the Linux console on your Red Pitaya (use Putty):
cat /root/led_blink.bit > /dev/xdevcfg
Now, you should see the 0th LED blink. Don’t worry, you did not destroy your Red Pitaya. If you want to roll back to the official Red Pitaya FPGA program run
cat /opt/redpitaya/fpga/fpga_X.XX.bit > /dev/xdevcfg
or simply restart Red Pitaya. In case you want to upload your bitstream during the boot-up follow Pavel’s instructions on how to create custom SD card for Red Pitaya.
Congratulations, you have just programmed your FPGA! But now, you are probably asking yourself what just happened? Let us quickly go though the most important steps to understand how we made one of the LEDs blink.
In this project we did not need to write any hardware description language (HDL) code. Instead we use IP cores which are a packaged code already available in Vivado and connect them in the IP Integrator. IP integrator (Block Design) is a useful addition to Vivado, which offers a visual representation of our program flow. It also helps us connect relevant blocks and navigate between our code. We will learn how to add our code as a block in the Block Design in the next project.
During the project creation the script specifies Red Pitaya’s FPGA part name xc7z010clg400-1. This information is important for synthesis, implementation and bitstream generation. Later, the script creates Red Pitaya specific external ports related to the chip pins as described in the constraint file shown in Sources tab under Constraints/constrs_1/port.xdc (or redpitaya_guide/cfg/port.xdc).
Next, the script adds the Zynq processing_system7 block with Red Pitaya specific settings set by redpitaya_guide/cfg/red_pitaya.xml. This IP core represents an interface between the processing system used for running Linux and the programmable logic (FPGA). There are many useful shared ports such as a clock (FCLK_CLK0), and communication interface ports (M_AXI_GPIO) which we will use in the future projects. Quick introduction to processing_system7 can be found on the Xilinx’s video page.
Some of the external ports are differential and therefore need to be properly handled. For this reason the script adds three buffers with differential ports (IBUFDS type) and connects them to those external ports (adc_clk_*, 2 x dasy_*). These buffers play no role in our LED blinking algorithm but should be there for proper implementation.
To achieve LED blinking with an interval of around 1 s we use FCLK_CLK0 clock from the processing_system7 block running at 125 MHz. To reduce the frequency from 125 MHz to 1 Hz we connect FCLK_CLK0 to 32-bit Binary Counter block and then to the Slice block which selects only 26th bit. The time interval of 26th bit is therefore
2 * 2^26/125 MHz = 1.07 s.
The 26-th bit is finally wired to the led(0) which makes LED(0) blink on the Red Pitaya board. You can change the size of the Binary Counter or the Slice position by double clicking on the block and changing its parameters. The connections (wires) are simply made by clicking on a free port and dragging it another port or wire. IP Integrator will check port types and sizes and allow a connection only if these are compatible. Sometimes IP Integrator offers a Run Block Automation option on top of the Block Design area which can automatically connects ports and even adds additional blocks when needed. Further information on how to use Vivado’s IP Integrator (Block Design) can be found in Xilinx documentation.
One can play and create more exciting blinking LEDs sequences. For fun try changing blocks responsible for blinking to the following diagram and see what happens. For this you can use a number of available Xilinx’s IP cores when right clicking on the empty space on the Block Design and choosing Add IP …. Don’t forget to change the LEFT attribute of the led port to 3.
Instead of connecting our periodic signal to the LED (led_o) we can also connect it to an extension port exp_tri_p_io linked with the DIO0_p pin on the extension connector E1. Since the exp_tri_p_io is bidirectional we cannot simply wire it in the block_design. There are two ways to solve this problem. (1) Delete the exp_tri_p_io port and create a new one with the same name and different direction. You can create the port by right-clicking on the block design area and select Create Port… or modify a tcl command found on line 38 in cfg/port.tcl file and execute it in the tcl console. (2) The second solution is much simpler. Use the following tcl command to connect your signal to the desired bidirectional port (exp_tri_p_io)
connect_bd_net [get_bd_pins xlconcat_0/In0] [get_bd_pins exp_p_tri_io]
We can check if the DIO0_p pin has a periodic signal by connecting it to the neighbouring pin DIO0_n on the E1 connector with an external wire. We can use the same technique to connect the corresponding exp_tri_n_io port to the second LED in the block design. Check the Extension connector’s manual to locate appropriate pins. If all goes well, as soon as you connect DIO0_p and DIO0_n pins two LEDs should blink at the same time. Be careful when connecting any external signals to the E1 connector. Always check the voltage requirements first. The following schematics shows how to assemble the block design.
This concludes our first project. We have learned how to install Zynq FPGA Vivado development suite and created a simple project where we run the synthesis, the implementation and generated a bitstream file. We uploaded the bit-file to Red Pitaya’s Linux and used it to configure the programmable logic. Since here all Red-Pitaya specific components are present, LED blinker is an ideal starting point for more advanced projects.
|Red Pitaya Project 2 – The Knight Rider Lights >>|
Fantastic first tutorial to FPGA on the red pitaya – finally I understand how to start progamming this thing.
Wonderful! The docs of red pitaya are currently a mess. This tutorial saved me a lot of time. Fantastic work! Brilliant! Thank you!
This is truly a masterpiece. Thanks a lot for your work!
I like your tutorial, however i found a problem, where the clean clone of the git repository produces an error in vivado.
The problem is in the make_project.tcl, where a wrong project name is selected.
To fix this problem uncomment 1_led_blinker and comment 4_frequency_counter in the make_project.tcl as shown below:
#set project_name “1_led_blink”
#set project_name “2_knight_rider”
#set project_name “3_stopwatch”
set project_name “4_frequency_counter”
#set project_name “5_averager”
set project_name “1_led_blink”
#set project_name “2_knight_rider”
#set project_name “3_stopwatch”
#set project_name “4_frequency_counter”
#set project_name “5_averager
Thank you for the comment. I the code should new build the first project by default.
However if you run into an error during project generation in vivado
change the following 2 lines in the make_project.tcl
#set project_name “1_led_blink” -> set project_name “1_led_blink”
set project_name “4_frequency_counter” -> #set project_name “4_frequency_counter”
THANK YOU SO MUCH! THIS HELPED A LOT!
Thanks for the tutorial, it was very helpful. I had a error using this command:
cat /root/tmp/led_blink.bit > /dev/xdevcfg
The solution is easy just replacing for the respective symbols:
cat /root/tmp/led_blink.bit &> /dev/xdevcfg
Thanks. Its corrected.
On my browser missing the _ and the :
but i think of an error for the scp command
scp system_wrapper.bit firstname.lastname@example.org:tmp/led_blink.bit
Thank you for the comment. I have corrected the scp command.
Hi, I can’t launch tcl file… problem should be in the path. I don’t understand directory where create base folder ” redpitaya_guide/ ” …
Thanks a lot for the information.
If you downloaded redpitaya_guide/ folder for example to
simply change directory in Vivado console by typing
and then run in the same console:
I already make led blink like your design block.
unfortunately i got some problem that i dont know how to setting differential output buffer in util_ds_bof_2.
[DRC 23-20] Rule violation (IOSTDTYPE-1) IOStandard Type – I/O port daisy_n_o is Single-Ended but has an IOStandard of DIFF_HSTL_I_18 which can only support Differential
[DRC 23-20] Rule violation (IOSTDTYPE-1) IOStandard Type – I/O port daisy_p_o is Single-Ended but has an IOStandard of DIFF_HSTL_I_18 which can only support Differential
[Vivado 12-1345] Error(s) found during DRC. Bitgen not run.
From your design schematic, daisy_n_o and daisy_p_o are not have inverter OBUF_inst. it seems you already modify the single ended output to differential.
I already search in many reference to modify single ended to diferential in buffer obuf_ds but it is still not solve my problem yet.
From this comment:
“Some of the external ports are differential and therefore need to be properly handled. For this reason the script adds three buffers with differential ports (IBUFDS type) and connects them to those external ports (adc_clk_*, 2 x dasy_*). These buffers play no role in our LED blinking algorithm but should be there for proper implementation.”
i already modified with delete util_ds_buf_1 and util_ds_buf_2.
Also i already delete some comment in ports.xdc and system.v that it contain daisy_p_o, daisy_n_o, daisy_p_i and daisy_n_i
The result is my bitstream generate is no problem.
The .bit file from this modification (without util_ds_buf_1 and util_ds_buf_2) is still OK.
I can increase and decrease delay LED using slice block without any problem.
But in the future, i still want to know how to use proper output buffer differential.
This is my second FPGA project and first time with this particular device, so my question is very basic.
When I run the TCL script ” make_project.tcl” in Vivado 2016.2 I get an error:
WARNING: [Device 21-436] No parts matched ‘xc7z010clg400-1’
ERROR: [Coretcl 2-106] Specified part could not be found.
I havent created a project, so I’m wondering how do I specify the part to Vivado..by creating a project or do I need to import this part ?
Thanks for any help in getting me started. I look forward to moving up the learning curve.
I am pleased to have solved this simple question.
I have installed Vivado Design Suite 2016.2, but not the full SDK.
To install this particular Zinq device if you do not have it,open Vivado > Help > Add design tools or parts > select the Zinq-7000 devices. These will be inserted into Vivado and then the make_project.tcl script will run without this error.
I am happy you found a solution.
Thank you for posting it here, it might be helpful to others as well.
I tried following your steps and generated the wrapper.bit file also.
When I tried SCP command I am getting error regarding led_blink.bit file
ipr@ipr-pc:~/github_guide/redpitaya_guide/tmp/1_led_blink/1_led_blink.runs/impl_1$ scp system_wrapper.bit email@example.com:tmp/fpga.bit
scp: tmp/fpga.bit: No such file or directory”
Can you pls suggest what correction I have to follow
Hi, there is probably no tmp/ folder on the targeted side. I would suggest to try uploading bit file with WinSCP program.
I’m trying to follow the steps in this particular project, but i got stocked in the
” scp system_wrapper.bit root@your_rp_ip:tmp/led_blink.bit” part, in the firts place becasue the file that Vivado is generating is a .tcl file, and secondable, when I try to use the ‘scp’ command, the Vivado console just don’t recognize it as a valid one.
I’m using Vivado 2018, on a Windows 10 computer.
If you successfully complete all the steps in Vivado the resulting file is system_wrapper.bit. Once you obtain this file you need to copy it to the linux running on your Red Pitaya. You can do this with several programs such as scp, WinScp, etc, but not in Vivado.
Thnaks for the quick reply
I noticed that I was using the Vivado HLS, and the Vivado tcl command promt instead of Vivado and its tcl console. I deleted the generated files and tried to generate the bitstream again, and I ended up with a system_wrapper.tcl file one more time. Is there any setting on Vivado that I need to change in order to get a .bit file?
Hi, I didn’t have to set anything special to generate a bit file. Try to follow the steps correctly and check the tcl output for any potential errors.