Search:

PmWiki

pmwiki.org

edit SideBar

Main / Ipcore

Back to FPGAs

Nice primer on the AXI interconnect: https://www.allaboutcircuits.com/technical-articles/what-are-axi-interconnects-tutorial-master-slave-digital-logic/

How do I add an existing custom IP core to my new project?

Create a folder in your project folder to hold custom IP blocks. For example

cd <vivado-project-name>
mkdir <company-name>-ip

Then copy the folder of the custom IP into the folder you just created

cp -a <custom-ip-path> <company-name>-ip/

Recall that you'll need to do the same for any sub-layer custom IPs that are components of this top level custom IP.

Now go to the Vivado settings and under Project Settings select IP->Repository. Add the newly created folder to the list. Now go back to the IP Catalog and the custom IP should show up.

Git for Custom IP

Per Vivado design flow user guide:
Managing Custom IP Repositories
When you package a custom IP and share it among several projects, you should use a custom IP repository. In this case, the project used to create and package the custom IP should be revision controlled following the methodology specified in this chapter. The packaged IP with the component.xml file should reside in a custom revision controlled IP repository managed by you. The project that uses the IP should contain a pointer to your custom IP repository and an XCI file with the desired customizations applied to the IP. The script to recreate the project should set the IP repository to the custom IP repository path and add the XCI file as a source to the project. When the project is recreated, similar to a project with Xilinx IP, Vivado would copy the RTL and constraints from your custom IP repository to your local project directory and applies the parameters from the XCI file. The XCI files along with your custom IP repository are sufficient to regenerate the complete project.

BRAM

The addressing works according to the depth, so each address points to a word of width matching the data width. No concept of byte addressability.

AXI GPIO Control

Apparently in simulation the pin direction control registers always read 0xffffffff which would indicate inputs, but you can still get output to work.

Quirks

Note that although Verilog allows it, the Vivado IP packager cannot handle port definitions that call a custom function. For example, it won't like this with lfsr_count defined as a custom function:

module lfsr_counter #(
	parameter M = 4
) (
	input clk,
	input reset,
	input ce,
	output reg [M-1:0] count = lfsr_count(M, 0)
);
//...
endmodule

Per UG118 The IP packager currently supports Verilog and VHDL as a top-level; if you have a SystemVerilog top-level design file, create a Verilog wrapper file prior to packaging. Apparently this also applies to adding a module. This is a limitation with RTL module referencing, top-level of the RTL module(called as "Add Module") should not be VHDL 2008 or SystemVerilog. Can you try to create a wrapper and try?

Updates to top level ports aren't automatic

The custom IP packager struggles to see that you've made any changes to the ports at the top level of the block. To force it, use the Tcl command: ipx::merge_project_changes ports [ipx::current_core] which should work in either temporary Edit mode or standing Vivado instance mode.

Subsystem IP and XCI files

Looking at the IP Sources, you see the XCI for the child IP with output products in the Synthesis folder for the parent IP. During OOC synthesis per IP, after the synthesis of the children IP is completed, they are linked together to create the combined DCP for the IP.

Creating an AXI-enabled IP

Building on AXI is an option in the main menu for creating a new IP block, but once I do that and open up the new IP packager GUI, how do I add new ports to the block? According to what I'm reading (https://support.xilinx.com/s/question/0D52E00006hpdxdSAA/custom-axi-ip-with-additional-io-ports-how-to-add-io-ports-apart-of-axi-ms-interface-?language=en_US), the only option for doing this is modifying the source code at the top level and adding the ports.

So what is the easier approach if I have an existing RTL block without an AXI interface, and I want to make it into a packaged IP core WITH an AXI interface?

If I try creating a blank AXI IP, I have the problem that none of my RTL is there with all the ports I need. Can I add an AXI interface if I start with the existing RTL and then package it? The good news is that this puts all my IP block ports in the "physical ports" listing, so I have those available for mapping. Now I have to add a new AXI bus interface... but that isn't very helpful because it doesn't generate all the interface code that the new AXI-enabled IP creation process gives me. Thus, there are still no new AXI ports for me to map the interface I just created.

Are there templates available? Clicking on language templates, there is a IP Integrator HDL-> AXI listing but it's just port instantiation and doesn't have all the same stuff I miss. So the answer is it appears I could grab the ports for the mapping, but they wouldn't connect to anything.

Finally, I'm left with creating a new AXI IP block and copying the AXI code that it generates. Close it down and copy that code over to the IP packaging I do of the existing project.

Here's an article on starting from scratch with AXI lite: https://www.hackster.io/whitney-knitter/axi4-lite-interface-wrapper-for-custom-rtl-in-vivado-2021-2-8a7009

FIFOs

For common clock low-depth applications, Vivado suggests the Shift Register based FIFO for best speed and space optimization. It goes down to a minimum depth of 16. The Built-In FIFO by comparison has a minimum depth of 512 (2017.4).

Note that for the Xilinx asynchronous AXI FIFOs, the reset signal must be held for at least three cycles of the slowest of the input clocks or you won't get a TREADY out of the slave side. https://support.xilinx.com/s/question/0D52E00006iHlqmSAC/proper-reset-for-axi4stream-data-fifo?language=en_US

AXI-Stream Data Width Converter

The first output of the smaller side will be the lowest 3 bytes of the input, the next cycle will output bytes 5-3, then either byte 0 of the next input transfer, if the input has TLAST de-assert, and 7,6 of the first transfer OR an unused byte and byte 7-6 of the first transfer and the TLAST if TLAST was asserted at the input.

So presumably going from smaller to bigger, the LSB will be filled in first.

RTL-Design Mode (Not Block Design)

If you want to add an IP block to the inside of an RTL module, note that not all available blocks are present in the Language Templates library. You can open the IP Catalog and find the block, double-click to open and condfigure it, then you are presented with the option to generate the output products. When you do that, a language template is created. Go into the IP Sources window and look for the .vho or .veo files.


Page last modified on April 20, 2023, at 02:02 PM