February 23, 2023

EBAZ4205 - "ez_blink" in 2023

The idea here was to blink the two LED from a fabric clock. Actually the idea was to put together a "cheat sheet" for using Vivado, but this went horribly astray as it never did work. I started this with good intentions, but it turned into just another Vivado project with various twists and turns.

Starting vivado

To start vivado, I type "vivado" on the command line. This starts vivado 2019.1 -- I don't see any compelling reason to upgrade, though a Xilinx popup has suggested it many times.

New Project

I use File -- Project -- New which gives me a new project "wizard". I give the project a name (ez_blink). I let it use the usual /home/tom/vivado as the location. I call it an RTL project. I skip "add sources" for now.

I did add a constraints file at this time, but doing so did not work out well. I wanted it to copy my constraint file, but it just recorded the path to it. I need/want to edit it for each project.

/u1/Projects/FPGA/Ebaz/Ebaz_Master.xdc
(This is also on my Github page in "master").

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.

Add the constraint file

I was going to delete it, then add it being sure to copy it, but there was a menu entry that said "copy file into project". I clicked that and, my problem was solved. I find it now at:
/u1/home/tom/vivado/ez_blink/ez_blink.srcs/constrs_1/imports/Ebaz/Ebaz_Master.xdc

This path is somewhat ridiculous, but whatever. I edit this file. I uncomment two lines (for red_led and green_led). These are the "official" names for the actual pins that drive the LED, so I need to use those names in the block model.

Block design

This is under "IP Integrator" in the left column. It asks for a design name -- I call it "mine". Now I have a blank canvas to build my block design in.
The "+" button up top lets me add stuff.

Now I am fooling around. I select "Clocking wizard" and run block automation. It finds a 100 Mhz clock and connects it to the input of the clocking wizard block. The 100 Mhz clock may be all I need and no doubt there is a way to get it directly. I click on connection automation and it wants to also connect the reset input, when I just hit "OK" if finds a signal "reset_rtl_0" and connects to that. Now it is sort of satisfied.

Some notes I have indicate there are 4 clocks available in the PL fabric and they are in now way dependent on the PS. Something to learn more about.

I can click on the "canvas" background, get a menu, and select "create port". I do this twice, specify an output port for each and call them red and green. These will ultimately be told to connect to the LED (via names in the constraint file).

The "official" names in the constraint file are "red_led" and "green_led", so I right click on each port in the model and use "External port properties" to make the names so. Be sure to hit return and verify that the names change on the block model. Type Ctrl-S to save.

Now I use File -- Save block design.
Then I use File -- Exit.
I relaunch Vivado and use File -- Project -- Open, and select ez_blink. This gives a menu of files and I need to select the ".xpr" file to open my project. I select "Open Block Design" in the left column, and I am back where I started.

Add a verilog file

RTL is "register transfer language" and in my case is verilog.

I click on "Add sources", create file and tell it I want to create "blinker.v". Then we get a define module dialog. We could skip this and do it by hand in the verilog file, but let us play along. The module name is "blinker" and I add 3 IO ports -- clk as input, led1 and led2 as output.

This is now in ..../sources_1/new/blinker.v with an absurd editor color scheme when I find it and double click to view it. All the more reason to use an external editor to modify it.

Adding a custom block (with my RTL inside)

Now that the source is in place, I can right click on it to get a menu, then "add module to block design", and voila! A block with one input and two outputs appears on the block design.

It is just that easy.

Now, to edit the verilog. This is at:

/u1/home/tom/vivado/ez_blink/ez_blink.srcs/sources_1/new/blinker.v
I make it this for now. Clearly it is not going to work to send a 100 Mhz signal to the LED, but I just want to figure out the Vivado workflow.
module blinker(
    input clk,
    output led1,
    output led2
    );

    assign led1 = clk;
    assign led2 = clk;
endmodule

Connect everything up

I can get things done by thrashing around with the mouse, but there must be a better way. I have the "locked" output on the Clocking Wizard unconnected

A very handy button at the top of the block design "canvas" is a circle with an arrow called "regenerate layout". Click this and everything will look nice and neat.

The end game

I go to "generate block design", select "Global" (in lieu of "out of context") and away it goes with no errors. Next I go to "Run synthesis" and it is busy for quite a while, but finishes without errors. I have no idea what the "clocking wizard" is doing or how to configure it. It reports "Synthesis successfully completed" and offers to "Run implementation". I cancel this (it is offered in the left column anyway if I change my mind).

I click on "generate bitstream" near the bottom of the left column. It gets busy doing all kinds of stuff (look at the upper right to see if it is busy and what it is doing).

It fails with "No constraints selected for write". This is something I have encountered before. As I remember it is something confusing and badly designed in Vivado.

Back again the next day

First, I do some significant editing to my verilog file (blinker.v). I add a counter and blink the lights at a visible rate (2 Hz).

Next I launch vivado. I find "ez_blink" in Recent Projects and select it. There is a yellow warning at the top about modules being out of date. I click "refresh" and it is now complaining about a syntax error in my new verilog. The problem was a missing semicolon at the end of a parameter statement.

I did some reading through my notes on past projects and rediscovered a critical step that I skipped on my first go at this (above). I go to Sources -- Design Sources and find "mine" (this is the block that contains blinker.v". I select this, right click to get a menu and

 select: "Create HDL wrapper".
I have missed this before and suffered accordingly. Once I do this I can do the usual sequence:
Run Synthesis
Run Implementation
Create Bitstream
I am still getting "No constraints selected for write" when I try to create the bitstream.
I hate this.

I explore a bit among the various tabs at the bottom of the Vivado screen. By default it shows me "Log", but when I look at "Messages" I get more information. It complains about all of my IO ports in two ways:

It is as if it is not finding my constraint file. This is a surprise for red_led and green_led. In the case of the input signal "clk_100Mhz" that the clock wizard pulled out of the wind, I am not surprised at all.

So I give up. I am going to start over fresh and just call this a "warm-up".


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org