May 18, 2022

Xilinx Vivado - Connecting the PS and PL tutorial

I ran across this pair of tutorials several months ago, and now with a working FPGA setup for my EBAZ along with some experience with Vivado, I feel ready to try to tackle them and follow along. My first problem is that I don't yet have any kind of button or switch wired up as an input to the EBAZ. I could stop right now and wire something up. Or I could switch to using my Zedboard. What I am going to do instead is to just press forward with the EBAZ.

The tutorial uses a Digilent "Arty-Z710" which has handy switches and lights like my Zedboard.

I launch Vivado 2021.2. (He uses 2019.1 which still has the SDK included) I create a new project "ebaz_pspl_1". It is an RTL project and I selected the ebaz board.

I add a source file flip.v, and skip the port setup dialog like he does. I type in the following verilog.

module flip(
    input red_ps,
    output red_led
    );
    assign red_led = ! red_ps;
endmodule
My intention is that the "red_led" output will drive the LED and the "res_ps" input will be a signal coming from the PS (and learning how that happens is the object of this game). Note that I invert the signal to the red_led (since it is active low, this lets writing a "1" from the PS turn the led on.)

Some shortcuts the fellow in the tutorial uses. Ctrl-S saves the file when we finish editing. Also there is a "+" icon at the top of the "Sources" box to add sources.

He mentions that there are both physical and timing constraints. No timing constraints are needed in this project. I use the "+" icon to create a constraint file "pspl.xdc". He goes to the master physical constraint file for his "Arty-Z7", which is certainly the right way to do things. Then he just uncomments the lines for signals he is actually using and changes their port names to match his verilog. I don't have such a thing for the EBAZ, so I just copy the single line for the red LED. I copy the line for the green LED also, in case I get additional ideas.

set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports { red_led }];
set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { green_led }];
(Note - when I first did this I had faulty constraint file entries without IOSTANDARD declarations and that yielded a bunch of trouble when I tried to finish the design and generate the bitstream).

Now something new for me, "create block design" under "IP integrator". I call the design "pspl". Next I use the "+" button in the Block design diagram and add the Zynq7 processing system. Once the block appears, I click on "Run Block Automation". I accept the defaults to interface to DDR and IO and click OK. Connections to DDR and FIXED_IO appear on the diagram.

a problem

Now I go to the sources tab, select "flip.v" and right click it. Now I have a problem. The entry "Add Module to block design" is greyed out. I get lucky. I click on "refresh hierarchy" and it is no longer greyed out. Well, it worked once. In the time it took to type this, it is greyed out again and is now being stubborn. This looks like either a bug, or something badly designed in Vivado.

Some online searching suggests the following. Click on a blank area in the Diagram to get a menu, then select "Add Module". This brings up a dialog asking me to select a module but nothing is offered to select. Perhaps my flip.v is not a valid module for some reason. I click on "Run Synthesis" to see if it finds something to complain about, but it is happy.

Finally, I exit Vivado and start over. This does no good. The guy in the video has no trouble like this. I originally called my verilog "pspl.v", maybe this causes a conflict? I change the name to flip.v and see if this makes things better. It doesn't, but I keep the name flip.v.

I clicked on "Open File" and some magic happened. The "Add Module to block design" is no longer greyed out, so I rush and click it and there it is in my block model. On with the show.

Add an AXI gpio block

Continuing with the tutorial. I click the "+" at the top of the block design diagram. I select "AXI GPIO" and hit return. The tutorial has two, but I will use just one. I click on "run connection automation", select all, then unclick GPIO, and OK.

Now I double click on the GPIO block. This brings up a big dialog. You have to be very careful where you click in the block. Pick a blank area or you will end up with a dialog to configure a specific pin. My version of Vivado seems somewhat different from his. I go to "IP configuration", select "all outputs" and a GPIO width of 1.

Now, back at the diagram, I hover over the GPIO label on my GPIO block where I expect to see outputs and I get a "thing" that appears labeled gpio_io_o[0:0] and I can use the pencil to connect it to the "red_ps" side of my flip_0 block.

Now I click on the output of my "flip" block, so it changes color (indicating that it is "active" or "selected", then click Ctrl-T and we get a "tab" to connect to the outside world. (A menu entry called "make external" does the same as Ctrl-T). Clicking on this gives use a dialog to fiddle with "External port properties". I change the name from red_led_0 to "red_led" to match the constraint file. Be sure to type return and confirm the change of name on the diagram.

Now at the top of the Diagram I click the arrow in a circle icon (regenerate layout) and the whole mess looks somewhat neater. I click Ctrl-S in the block diagram to save it. I go up to "sources", select the design (pspl.bd) and right click to get a menu, select "create HDL wrapper", then "let vivado manage and auto update" and OK.

At the very top of Vivado is an icon with some green an what looks like 4 boxes in a 2x2 arrangement. This is "generate bitstream". I click on this, it tells me that the synthesis and implementation are out of date and need to be rerun. I click OK and wait the usual long time. Note that the upper left of vivado tells you what it is doing and I see a spinning green arrow and the words "Running ...", so I know to just be patient. The long time is longer than usual with all the AXI blocks.

When I first did this I had a typo in one of the external signal names. I fixed this, then had to click the "generate bitstream" icon again. It offers to save the project for me (nice). Away it goes and it does not need to redo the Sythesis and Implementation, so it is quick.

I go to "file -- export" and select "export hardware". I get an export wizard (different than the video). I select "include bitstream". It says I can export for petalinux or vitis.

I am doing this with Vivado 2021.2, which no longer includes the SDK. Sad, like so many things in this life. It is going to write /home/tom/ebaz_pspl_1/pspl_wrapper.xsa And I click finish.

What about the SDK?

Xilinx got rid of the SDK after Vivado 2019.1. So if you want the SDK, you must stick with 2019.1. Or you can use the current Vivado along with Vitis (or just use Vitis). I have no idea yet about Vitis, but it is what Xilinx wants you to use these days in cases where you itch to use the SDK. The vibe you get reading this is that Xilinx takes care of select big customers and everyone else just should be happy to get what they get. Also this is perhaps why people like FPGA products with open source toolchains (like Lattice). People say Altera has better software than Xilinx, but I cannot say at this point. I have Xilinx hardware, so I have little choice but to use their tools.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org