March 3, 2023

EBAZ4205 - A Vivado "cheat sheet" for projects with blocks

Much of this is the same as my "simple project" cheat sheet. The main difference is the section in the middle that deals with the Block Design under IP integrator.

I used to have all kinds of problems when I was using Vivado 2019.1. I label these in my past write-ups as "vivado train wrecks. The most famous of these was the following error when you tried to generate a bitstream:

"No constraints selected for write".
It turns out these were bugs in Vivado -- and the worst of these (perhaps all, but that seems unlikely) have been fixed. I am now using Vivado 2022.2 without any problems.

You need blocks for Zynq projects that require clocks, at least for the Ebaz which has no clock directly connected to an FPGA pin. You also need blocks for Zynq projects which want to use some kind of AXI interface to allow the PS to talk to the PL. And you probably need it for all kinds of things I haven't gotten into yet.

Starting vivado

To start vivado, I type "vivado" on the command line. This starts vivado 2022.2.

New Project

I use File -- Project -- New which gives me a new project "wizard". I give the project a name (ez_blink). My "vivado" script always starts vivado in /home/tom/vivado which causes it to put all the projects there, which is ideal. I call it an RTL project. A checkbox now lets me skip adding files at this stage, which I like and is what I always do. We add them later as needed.

Select the board (not the part)

The next wizard dialog takes some care. It gives me a menu with a long list of parts, but I want to switch to "Boards" at the top of this dialog. Then I pull down the "vendor" menu and scan for "miner", when I select that, the Ebaz is the only choice (this is because I added "board files" many months ago.). Now I finish the new project dialog and I am in Vivado proper.

Editing

An important side note. I often edit external to vivado using vim. I also configure vivado to use vim (via Tools -- Settings). Sadly this runs vim in an xterm with a while background and it is more or less unreadable with the vim colorscheme. Type :colo desert for a much more reasonable setup. Or type :syntax off.

I used to do my editing external to vivado using Vim. You can certainly do this and the editor is nicer than when using a funky old xterm, but for simple things it is just easier to stay inside vivado. Vivado knows where the files are and that makes it easy. Doing the editing externally means walking through the vivado generated file structure to find the source file which is somewhat of a pain.

Add the constraint file

Use the "+" button at the top of the Sources tab.

I keep my master constraint files at:

/u1/Projects/FPGA/Ebaz/Ebaz_Master.xdc
/u1/Projects/FPGA/Zedboard/Zedboard-Master.xdc
/u1/Projects/Zybo/ZYBO_Master.xdc

Be sure to copy it, not just let vivado link to it. There should be a check box to request this before you finish up with the "add constraint file" dialog. If vivado is stubborn and just makes a link (as it sometimes does), there is a menu entry when you right click on the file that says "copy file into project" that will fix things for you.

Then you will want to edit it and uncomment those signals you intend to use (my master file for the Ebaz has all signals commented out).

This file is also on my Github page:

Take note of the "official" names for the actual pins you intend to use in the constraint file. These will need to match signal names in your verilog code or on output ports.

Add a verilog file

Not all projects with blocks even need user written verilog, but if you do, this is how you add it.

Use the "+" button as you did for the constraint file, but select "design source". RTL is "register transfer language" and in my case is verilog.

Adding a verilog file is much the same game as adding the constraint file. You can add the file and follow the dialog for ports and it will set up a "prototype" file with declarations for the ports, or if you are a veteran you will know what to do and and skip all that and write your own verilog.

Here is an example:

module blinker(
    input input,
    output led1,
    output led2
    );

    assign led1 = input;
    assign led2 = ~input;
endmodule
Note that "input", "led1", and "led2" will need to match pin names in the constraint file.

IP integrator and Block design

Click "Create block design" and give it a name. I have yet to find a situation where the name mattered in any way, so just taking the default seems sensible (design_1).

Use the "+" button to add the Zynq processing system. If you click "run block automation" it will connect it to DDR and FIXED_IO, but leave all kinds of other stuff unconnected.

What other blocks you add depend on what you want to do. I have various examples in my detailed notes on specific projects. As an example, you might add an AXI GPIO block. Launch "run block automation" again, but before actually run it, uncheck "GPIO". If you don't do this it will try to connect GPIO to "led_2bits" or some such, which has always been entirely wrong. Running block automation this second time will pull in two other blocks (AXI peripheral and ps7 system reset) and connect them up.

Clicking the circle thing to "tidy" the diagram is helpful and is always an option.

If you have verilog to add, here is how you add it to the block diagram. Go to sources, right click on the verilog file and select "Add module to block design". It should appear. Connect it up.

I connect its input to FCLK_CLK0. The two outputs should go to the red_led and green_led signals specified in the constraint file. I could just use these names in the verilog and have a block with one input and no outputs, but I don't.

I click on the canvas background to get a menu and select "create port". I give it a name, select output, and select type "data". I do this for red_led and green_led and connect them up.

The block diagram now looks good. Now for a vital and important step. Go to sources and find "design_1", right click to get a menu and select:

 select: "Create HDL wrapper".
A note. If you need to go back later and make changes to a project (which is fairly common), you won't be able to create the HDL wrapper, but what you should do is in the very same menu, select "refresh hierarchy".

The end game

Generate block design
Run synthesis
Run implementation (skip "open implemented design"
Generate bitstream
Each of these takes considerable time. Keep an eye on the upper right corner of Vivado where messages appear telling you what it is doing (along with a spinning circle arrow to indicate that it is busy and things are in progress).

Run the design

If you have the proper "cable" (in the Xilinx lingo, a cable is some kind of cable and gadget that connects to the chip FPGA) you can have Vivado load and run the generated bitstream. Here is how you do it:

When generate bitstream finishes, it typically offers to just open hardware manager for you.

For the Ebaz there are some non-obvious steps. First you need to have the pico USB gadget plugged in on the JTAG port and the xvcd-pico server running in some window and listening on port 2542 (which is what it does by default). Then in the vivado hardware manager, click on localhost(0) to get a menu and select "Add Xilinx Virtual Cable". Enter (select) localhost in the popup this yields. It will default to port 2542 and should show you a JTAG hierarchy, with xc7z010_1 already selected. Click on "program device" near the top of the screen and it should bring up a dialog to select the bitstream file (with the one and only bitstream already selected). Confirm this and you get a progress bar and Success!.

I test flew all this with the Ebaz on 2/25/2023.

The Zybo (and Zedboard) have built in "cables" (i.e. USB to JTAG gateways), so you just connect to them with a USB cable and don't need to run any special server.

For the Zybo -- go to Hardware manager, it should offer blue text "open target". Do this and select autoconnect. You should next be offered "program device" along with a hardware hierarchy (you almost certainly want xc7z010_1). A dialog will allow you to select a bitstream (and there will almost certainly be just one). Click the "program" button. It should load and run your bitstream. Keep an eye on the Green LED (DONE) next to the Zynq.

You should be running your design.

Old bugs in 2019.1

As per these discussions this is now fixed.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org