Search:

PmWiki

pmwiki.org

edit SideBar

Main / Vivado

Back to FPGAs

There are three (primary) stages to generating a design:

  • Synthesis converts your RTL code to an interconnected netlist of cells (LUTs, FFs, etc...)
  • Placement maps those cells to physical locations on the FPGA die
  • Route maps the connections between the cells to physical routing channels on the FPGA die

The first operation is done as part of "Synthesize Design" and the last two as part of "Implement Design"

Vivado In Focus

After installation, there are a couple steps to do before first run:
http://mboers.github.io/zynq-notes/3-running-vivado/

Note that Xilinx is stupid in that they don't allow you launch Vivado on Linux using a symbolic link (https://support.xilinx.com/s/question/0D52E00006hpgbiSAA/bug-vivado-fails-to-start-when-called-via-symlink?language=en_US)

Vivado vs Vitis: https://blog.digilentinc.com/whats-different-between-vivado-and-vitis/

The Vivado Project File is the .xpr file inside the project folder. The .hdf is an archive that includes the bitstream file if that option is selected.

Project Management Modes

You can choose a Tcl script-based compilation style method in which you manage sources and the design process yourself, also known as Non-Project Mode. Alternatively, you can use a project-based method to automatically manage your design process and design data using projects and project states, also known as Project Mode. Either of these methods can be run using a Tcl scripted batch mode or run interactively in the Vivado IDE.

Constraints

Kept in the .xdc file.

For external pins, customers need to set IOSTANDARD and PACKAGE_PIN, in order to protect devices from accidental damage that could be caused by the tools randomly choosing a pin location or IOSTANDARD without knowledge of the board voltage or connections.

At what point can you create constraints? After synthesis. The constraints wizard is available under Open Synthesized Design.

Properties

  • IOSTANDARD sets the IO type like LVTTL, LVCMOS18, LVCMOS25, LVCMOS33, LVDS, LVDS_25
  • PACKAGE_PIN specifies the assignment of a design port to a pin of the target device package.

It's hard to find help for getting started with constraints. Here are some samples:

set_property IOSTANDARD LVDS [get_ports CH0_DATA_CLK_P]
set_property IOSTANDARD LVDS [get_ports CH0_DATA_CLK_N]
set_property DIFF_TERM TRUE [get_ports CH0_DATA_CLK_P]
set_property DIFF_TERM TRUE [get_ports CH0_DATA_CLK_N]

set_property PACKAGE_PIN AC13 [get_ports LED0]

create_clock -period 12.500 -name CH0_rx_clk [get_ports CH0_DATA_CLK_P]

Recommend Constraints Sequence:

## Timing Assertions Section 
# Primary clocks
# Virtual clocks
# Generated clocks 
# Clock Groups
# Bus Skew constraints
# Input and output delay constraints

## Timing Exceptions Section 
# False Paths
# Max Delay / Min Delay 
# Multicycle Paths
# Case Analysis 
# Disable Timing

## Physical Constraints Section
# located anywhere in the file, preferably before or after the timing
constraints or stored in a separate constraint file

Floorplanning

This is a way to contain the logic physically and lock things in place for consistency between builds. The pblock is for physical block.

Settings

To change the simulation duration, go to PROJECT MANAGER Settings -> Simulation -> Simulation and change xsim.simulate.runtime.

Debug

There are at least 3 ways to add debug nets.

Add MARK_DEBUG attribute to HDL files.

VHDL:
attribute mark_debug : string;
attribute mark_debug of sine : signal is "true";
Verilog:
(* mark_debug = "true" *) wire sine;
(* mark_debug = "true" *) wire sineSel;

Right-click to Mark Debug on a synthesized netlist.

Right-click to Mark Debug on a block diagram, followed by using the Set Up Debug option in an open synthesis view.

Use a Tcl prompt to set the MARK_DEBUG attribute on a synthesized netlist with set_property mark_debug true [get_nets -hier [list {sine[*]}]]

Project Files

The .prj file is a holdover from ISE, and was the XST project file. It is text. It contains a "comprehensive list of all files to be synthesized by Vivado synthesis", supposedly as an alternative to using the GUI.

A Vivado simulator project script specifies design source files and libraries to parse and compile for simulation. This method is useful to create a simulation project script that can be run repeatedly over the course of project development.

The format for a Vivado simulator project script (prj file) is as follows:

verilog | vhdl| sv <library_name> {<file_name>.v|.vhd}

Where:

verilog | vhdl | sv specifies whether the design source is a Verilog, VHDL, or SV file.
<library_name>: Specifies the library into which you may compile the source file. If
unspecified, the default library for compilation is work.
<file_name>.v|.vhd: Specifies the name of the design source file to compile.

A Vivado project file is the .xpr. There are also several folders:

  • .data = netlists
  • .srcs = HTML source files, netlists, XTC files?
  • .runs = all run data?

The stuff in .srcs in sources_1, constrs_1, sim_1 folders are Vivado "filesets" which are design suite objects. The constraints set are .xdc files.

Terminology

The Generate Block Design command creates the HDL files from the block diagram layout.

Implementation is the second step of the build and includes translation, mapping and place/route. This step sets you up for the final bitstream generation. Perhaps analogous to software linking. Contrast with synthesis which produces just the netlist, and is more analogous to software compiling.

The way slack is reported is a bit misleading, because a positive time can be reported for "worst X slack" even for "worst negative slack". This is good, it means timing is met. The problem arises when this value is truly negative. As long as the worst is positive, then the total will be 0.

An "interface port" is a grouping of signals that share a common function, like an AXI "port" which is really multiple wires.

Simulation

Behavioral (AKA RTL) Simulation: mostly for code verification using simplified models of IP cores and carried out prior to synthesis. No timing information involved.

Post-Synth Simulation: sim using synthesized (compiled) netlist instead of code to verify functional design, although you can add estimated timing to this simuation.

Post-Implementation Simulation: you can do timing OR functional simulation after place/route.

Functional vs Timing Simulation: you can do a functional sim without timing information to verify the code works as intended, but with timing you are getting closer to how the logic performs on-chip; the timing refers to the latch setup and hold times and wire delays, etc; the timing simulation can find problems with constraints or optimizations or bus collisions, that wouldn't be found during functional sim.

Simulation Libraries and Locations

UNISIMVerilog<Vivado_Install_Dir>/data/verilog/src/unisims
 VHDL<Vivado_Install_Dir>/data/vhdl/src/unisims
UNIFASTVerilog<Vivado_Install_Dir>/data/verilog/src/unifast
 VHDL<Vivado_Install_Dir>/data/vhdl/src/unifast
UNIMACROVerilog<Vivado_Install_Dir>/data/verilog/src/unimacro
 VHDL<Vivado_Install_Dir>/data/vhdl/src/unimacro
SECUREIPVerilog<Vivado_Install_Dir>/data/secureip/

A Zynq PS in your design?
It seems nearly impossible to find documentation on this. One poster said "there is no way to simulate the PS / PL other than using the QEMU models for the Zynq or by using the Zynq Bus Functional Models." The easiest way thus far to validate logic has been to create a sim-only design that has no Zynq PS block, and just create a wrapper around the stuff you want to test. Use AXI VIP blocks to run the AXI interfaces.

Elaborated Design

This gives you access to I/O planning. Must run DRC here! Note when pin planning that ground bounce is a transistor switching issue where the gate voltage can appear to drop below GND. Enables analysis views like netlist, schematic, hierachy graph.

If you've been just simulating a new design, you can use this to find some synthesizable problems.

Synthesis

This process takes RTL and creates a netlist.

Bottom-Up Synth
Starting 2013.1, bottom-up synthesis flow can be automatically set within the tool by selecting any HDL object as a separate Out-of-context module. This is achieved by right-clicking on the HDL object and selecting the "Set as Out-of-Context Module". This will set a new run in the tool which can be executed by right clicking and selecting "Launch Runs". This action sets the lower-level as a top module and runs synthesis on that module without creating I/O buffers.

Note that Vivado synthesis will stupidly complain about things it shouldn't, like the set_clock_groups constraint for legit clocks in certain cases:

So, how come it complains it during synthesis and implementation?
If you are using OOC synthesis for the MMCM, then Vivado synthesis 
will complain about not finding the clock or pin of MMCM.  
You can ignore the synthesis complaints but you cannot ignore the implementation complaints.

Implementation

This process uses the netlist and carries out place and route. The net delays here are accurate.

System Level Files and Workflow

Start with Vivado PL design and then after you generate the new bitstream, you move over to the XSDK (or Vitis). Note that to do this you must export the hardware definitions via the menu, which creates a new .hdf file. If you Launch XSDK from the menu it will then generate a platform folder you automatically. If you launch the XSDK independently, you'll have to instead open a new hardware platform specification and point to the .hdf.

If done correctly, a new set of critical files are put into the System_wrapper_hw_platform folder:

  • ps7_init.c/h = init routines and codes and constants, called by the FSBL to set up the PS, generated by Vivado based on the configuration of the PS block; C equivalent of ps7_init.tcl
  • ps7_init.tcl = pre-initialization file that is to be sourced and executed before any application is downloaded onto the target, contains the clock, pll and ddr initialization code
  • <design-name>.bit = the FPGA bitstream
  • system.hdf = handoff design file, sometimes called hardware definition file, a platform spec generated by Vivado and deprecated in later versions; contains all the information required by Xilinx SDK to create the corresponding software project for your design; created when you export your design; the hardware is exported in a ZIP file (<project wrapper>.hdf) and when SDK launches, the file unzips automatically, and you can find all the files in the SDK project hardware platform folder
  • ps7_init_gpl.c/h = U-Boot SPL requires to initialize the processor system using the hardware specific initialization code; these files are part of the HDF created by the Vivado tool when exporting the design, and needs to be placed in the board folder within U-Boot code
  • ps7_init.html = ??
  • <block_design_name>.tcl = ??

These files are copied over to a folder of the same name in the XSDK project workspace and added as a project in the IDE. They can then be used by the XSDK PS FW build system.

Troubleshooting

Concerning the Export Hardware command

Vivado 2016.4 has a weird quirk where it won't generate the System_wrapper_hw_platform_X folder with all the ps7 init stuff and bitstream until you go and launch the SDK right after. Then you can just close the SDK once it opens up and generates that stuff through auto-import.

Failure to connect to board

The hw_server application does not end when you quit Vivado, so you may get complaints about an obsolete hw_server (total BS) if it's already running and Vivado is trying to connect again. Must kill the app manually and try again.

Board_part definition nonsense

[Board 49-71] The board_part definition was not found for augustusaerospace.com:ponderosa2:part0:0.1. The project's board_part property was not set, but the project's part property was set to xc7z045ifbg676-2L. Valid board_part values can be retrieved with the 'get_board_parts' Tcl command. Check if board.repoPaths parameter is set and the board_part is installed from the tcl app store.

Solution found here: https://support.xilinx.com/s/question/0D52E00006lLBqpSAG/setting-board-file-fails-with-error-board-4971-the-boardpart-definition-was-not-found?language=en_US. Refresh the board store with:

xhub::refresh_catalog [xhub::get_xstores xilinx_board_store]

xhub::install [xhub::get_xitems]

set_param board.repoPaths [get_property LOCAL_ROOT_DIR [xhub::get_xstores xilinx_board_store]]

Sim suddenly breaks and you don't know why

Besides the xvlog.log file under <proj>.sim/sim_1/behav/ there is another under <proj>.sim/sim_1/behav/xsim/ so be careful to check all these different logs for hints on errors.

[DRC 23-20] Rule violation (REQP-1712) Input clock driver - Unsupported PLLE2_ADV connectivity. The signal system1/clk_wiz_1/inst/clk_in1 on the system1/clk_wiz_1/inst/plle2_adv_inst/CLKIN1 pin of system1/clk_wiz_1/inst/plle2_adv_inst with COMPENSATION mode ZHOLD must be driven by a clock capable IO.
This problem is unexplained, and appears to be a Vivado bug when the clock wizard is given a PS-PL clock as input. I solved the problem by overriding the PLL setting with BUF_IN compensation. I also had to delete and re-create the AXI Interconnect.

Inexplicably cannot use the AXI interface anymore on the target

Try deleting the AXI interconnect and re-create it.

Cannot launch SDK from Vivado due to path issues

You can launch manually with the Tcl command exec C:/Xilinx/SDK/2015.4/bin/xsdk -workspace <project_sdkdir>.sdk -hwspec <project_sdkdir>sdk/System_wrapper.hdf

The HDL wrapper fails to update

When you change the ports in the BD, you may have to try a reset_project and delete the wrapper, re-generate the output products, and re-create the wrapper.

Taking a slice of data out to a GPIO pin produces junk

In one example, Vivado synthesis did some very strange logic for what seemed a simple need. Wanted to pipe out one bit of a four-bit data bus from a block out to a GPIO pin for test.

clkB is a slower clock derived from clkA and is synchronized with new DATA_OUT values. With this code Vivado counter intuitively separately latched the DATA_OUT[3] line inside the DATA_BLOCK instead of outside and then routed it back to join the other data bits for the later logic. This resulted in the data path being intact, but the GPIO pin bit was putting out the wrong values. The change that fixed the problem, was to use clkA for the debug process driving the GPIO pin instead of clkB.

// top level
//...
  input clkA,
  output reg [3:0] counted_data_out,
  output reg gpio_pin
);

wire clkB;
wire data_out[3:0];

// debug: get the wire we want to observe
always @(posedge clkB) begin
  gpio_pin <= data_out[3];
end

// do some counting logic and other stuff on the primary data path
always @(posedge clkA) begin
  counted_data_out <= data_out;
end

// data block
DATA_BLOCK
(
  .CLK(clkA),
  .DATA_OUT(data_out),
  .SAMP_OUT(clkB)
);

So there may be something to learn here about using two different clocks on the same wire latched in two different processes?

VHDL library/package problem

This error packagename is not compiled in library xil_defaultlib could come from the compile order of files if the file is properly formed and present in the library. Look in the Project Manager at the Sources and Compile Order tabs and files can be rearranged.

Silent failure and/or crash on elaborate design or synthesis

If your system runs out of memory, you may see a log message with something like

/tools/Xilinx/Vivado/2017.4/bin/rdiArgs.sh: line 194:  6945 Killed                  "$RDI_PROG" "$@"

And blaming the parent process for exiting. If Vivado doesn't crash, you may see that synthesis fails but there are no real Error messages.

To get around this, I had to increase my Linux swap space to an enormous number, more than what was suggested in forum posts reporting this problem (Try 50GB).

Swap space instructions: https://askubuntu.com/questions/178712/how-to-increase-swap-space

Vivado and IP Cores

Note that the IP catalog will only show cores that your active device can support.

Address Editor

What does _DDR_LOWOCM mean in base address names? This is to indicate how to map accesses to the DDR off-chip memory along with OCM, provided the low-memory location of the OCM (like at 0x0). But there's also the high-memory option for OCM location and in that case _DDR_LOWOCM only refers to the DDR which probably starts at 0x0.

Block Automation

Assists in PS incorporation and making connections between blocks and to external interfaces. Used with the IP Integrator block design.

Adding an IP Block

Generating Output Products
After IP customization is complete, the Generate Output Products dialog box opens. Output products delivered by the IP are listed in the Preview area. To generate the listed output products, click Generate. By default, the Vivado IDE creates an XCI and a DCP for the IP when you generate the output products, as well as a change log, a behavioral simulation model, and an instantiation template.

The Xilinx recommendation that an XCI or XCIX file should be used as the source file for all Xilinx IP cores and that users should not replace these files with the generated out of context (OOC) checkpoint (DCP). The XCI file is an XML file that captures all the configuration settings for the IP core. The XCI file points Vivado to all of the files generated for the IP core, including - the DCP, synthesis, constraints, memory initialization and simulation files. The XCI file is how Vivado determines if the IP is fully generated or if there are any files missing. Simulation is also slower using a DCP vs an XCI.

We have also modified how IP OOC synthesis runs work. In order to avoid redundant application of constraints, beginning in 2017.1, the OOC DCP will no longer contain any constraints. By removing the constraints from the DCP, we can ensure that there will be no duplicates. If you follow our recommendations, and use the IP .xci file, the original constraints, will be re-applied to the IP. A DCP for an IP core cannot and should not be used standalone unless constraints are manually re-applied. If a user generates an IP core in Vivado 2017.1 or later and takes the DCP out of the OOC synth directory and uses it directly, it will not contain constraints.

IP Packager

When you create a new IP package, outputs are:

  • the component.xml file based on the IP-XACT standard, and all associate files of a custom IP are relative to this.
  • XGUI customization Tcl file, the settings box for the IP
  • /src, /sim, and /doc folders and files

When you want to add your new IP block to a separate project, open that other project and add the top level dir (containing the component.xml file) as a repository in the Project Settings IP page. Now you can find the new block when you add from the IP catalog in the block designer.

Vivado can auto-generate IP core structure in which you can then insert custom code. A dialog box with several options comes up when you start this process. You can find that same interface if you go to Design Sources -> IP-XACT -> component.xml and open that up. Vivado will display it in the GUI rather than as an XML.

When you make custom code changes, they aren't published to the IP core in the catalog automatically. You have to do the re-packaging manually using the interface and the above XML file to do the "Review and Package" step and then the Re-Package IP button.

Understanding Hierarchical IP
Some IP are designed to use other IP as design sources. Depending on how the parent IP was created there can be out-of-context synthesis runs for the children IP. The following are types of IP with a parent-child relationship:

  • IP which reference another IP as a library of files (subcore reference)
  • IP which are packaged with XCI files for child IP (static IP)
  • IP which dynamically create child IP and HDL (dynamic IP)
  • IP which use IP Integrator technologies to dynamically create and interconnect IP (subsystem IP)
  • Subcore reference: Have one out-of-context synthesis run. In the IP Sources there will be no sub IP shown, there is only one XCI. Is this always shown as locked in the upper integrated level? It appears that if a child is locked, the parent will also be locked.
  • Static IP are those that were packaged with XCI files for other IP, and have one out-of-context synthesis run because all the IP are synthesized together.
  • Those which dynamically create children IP (dynamic IP), have one out-of-context synthesis run as all the IP are synthesized together. Similar to the static IP, you see multiple XCI in the IP sources.
  • Subsystem IP are the IP that the IP integrator technology creates. These IP have out-of-context synthesis runs for the children IP. In the IP Sources, you see the block design and children XCI also.

For a list of IP output products, see the section IP-Generated Directories and Files in https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_2/ug896-vivado-ip.pdf

What if you change something at top level and then you get a complaint about some parameter not matching to what's set for a custom IP core?
You might be able to fix this in the Edit IP instance of Vivado without having to go back to the custom IP project and manually importing it. Go to the ports/interfaces window and edit the entity in question. You have the option to add parameters here and put in a value. It may be that your parameter is not here and you can add it from a drop down selection. Then you can re-package and go back to the top level and upgrade the selected IP, and it should validate. If you click on the port on the IP block you'll see the updated parameter and value in the Properties window.

Constants

With constant blocks, you can enter the value as decimal, hex (0x), or binary (0b).

Status/Control Registers

Use an AXI GPIO block and hook the pins up to status and control lines, including constants if you want to create a version register.

ILA (ChipScope)

The debug wizard has a problem because it does not help you connect the debug system to a "free running" clock. If you don't hook it up manually, the debugging won't recognize the ILA and you can't connect. A free running clock means one that's not generated via reliance on other signals. A externally-sourced oscillator signal into the FPGA seems to fit the bill, and the PS clock may work as well once it's initiated in the ps7 init (or post_config) code from the Zynq ARM boot process.

It's not easy to dig up the secret that in order to connect the debug hub to a good clock, you have to use the connect_debug_port command like so:

connect_debug_port dbg_hub/clk [get_nets u_ila_0_FCLK_CLK0]

where the assignment is to the correct free running clock.

To generate the probes.ltx that is needed for the Hardware Manager to see the signals, run at the Tcl prompt write_debug_probes <filename.ltx>.

Note in the schematic generated after synthesis it will show the ILA blocks and the dbg_hub block. Check carefully the clock driving dbg_hub. It must be 2.5x faster at least than the JTAG frequency. To set a new JTAG freq if your clock is really slow, you can close out the HW Manager and open a new target option, then select the new JTAG freq from a drop down menu. Otherwise you'll get an error saying something about a mismatch between your ILA and the .ltx file that defines the probes.

Source Control (i.e. Git)

Vivado is notoriously difficult to get working with Git. An interesting idea of exporting a TCL build script and only controlling the script and the HDL sources is proposed here: https://www.fpgadeveloper.com/2014/08/version-control-for-vivado-projects.html/

Reset: Building Someone Else's Project

  • reset_project = Tcl command cleans out all the output files generated during synthesis, simulation and implementation and resets the state of the project to the start of the design flow

You can also right-click on the .bd Source and choose 'Reset Output Products'.

.gitignore

Working on a definitive understanding of what needs to go in here. Worth noting that when you store a Vivado project, the bulk of the stored data is in the <projname>/<projname>.srcs/ folder.

Here's an example .gitignore from Xilinx: https://support.xilinx.com/s/article/61232?language=en_US but I think there are a few mistakes in here. A revised version here: Vivado gitignore sample

From the Xilinx Design Flows Manual

Script-based Revision Control Methodology
The following steps outline how revision controlling a project using a script-based method can be achieved.

  • Keep source files external to the project. Ideally, the source files are kept outside of the Vivado build directory.
  • Revision control the source repository. All sources should be managed by the revision control system.
  • Important: When Vivado is using the source files, they should be writable.
  • Generate a script to recreate the design.
  • Revision control the script. Once the script is created, it is important to manage this file as a source too. As the design changes, this script must be updated to accommodate new sources or to capture new design configurations. It is important that this script is managed like any other design source.
  • Test your methodology. Ideally, to ensure no files are missed and the design rebuilds completely from design sources using a script, the design would be regressed at a regular cadence. By rebuilding the design regularly, any issues with the revision control methodology can be caught and addressed in a timely manner.

Adding new IP cores

By default, Vivado will stick the files for new cores you add to your project deep inside the working project directory, which is supposed to be a temporary workspace only when using Tcl project script based SCM. When the GUI comes up to configure the core, you can click on the IP Location tab to set a better location in your permanent file storage for the repo.

If you miss that step, note that you cannot rename the instance nor is it simple to relocate to a source controlled location. Instead, you must use the copy option in the right-click menu of the core and then delete the original.

Other resources

https://github.com/barbedo/vivado-git
https://github.com/Digilent/Arty/blob/master/Projects/XADC_Demo/proj/create_project.tcl

Licensing

If you have lost the voucher that came with your board or used a voucher and the license has failed, you have no choice but to try to connect with help at Xilinx.

If your voucher has already redeemed but the license doesn't appear in the Manage license tab, then you'd need to raise an Electronic Fulfillment SR with the Xilinx Customer Service team (by logging in to https://www.xilinx.com/support.html#serviceportal -> LICENSING), and they will then be able to help you to redeem this voucher code. They are the only people who can sort this out for you in your situation described above.

You have to request access, and it takes a couple days.

License Tools, Server

Vivado installation comes with lmutil (apparently just installing it with lsb or lsb-core install, as many have suggested, doesn't work for Ubuntu 20). You must look in /tools/Xilinx/Vivado/2016.4/bin/unwrapped/lnx64.o/ and there's an executable there. Have to run with ./lmutil.

JTAG

To use the Digilent HSX series of micro USB JTAG adapters for Xilinx systems on Linux, you need to install the Digilent drivers:
https://digilent.com/reference/programmable-logic/guides/install-cable-drivers

Otherwise the Ubuntu machine will only see the FTDI device and nothing more.

Libraries

When you create a package and want to use it, you'll add a use instruction at the top of the file like: use work.packagenamepkg.all;. Work is not a library itself - it is the current working library. Until recently (2017/18 I think) Xilinx got this wrong and built a specific library called work, which is against the VHDL spec. You could almost think of "work" as the "local library". Now these packages would live in a library called xil_defaultlib. Despite the confusion from Xilinx, you should use work and not xil_defaultlib in the use statement.


Page last modified on September 05, 2023, at 12:39 PM