... 60% of the time
Packaging either a new or an existing IP with Vivado is really simple and in this post I will show you how to package the RISC-V RV64G rocket core I produced with the rocket-chip generator. I am using the Vivado 2015.4 but this short tutorial will (probably!) work with any tool version you might have as long as you are able to make slight changes based on what you see on your tool.
As you can see from the plethora of screenshots that follow this is a graphical way of packaging your IP using the Vivado GUI. A preferable method would be to create Vivado Tcl scripts so that you can integrate this IP packaging in your own scripted flow, interoperate with other tools you might use etc. For the GSoC project I work on I choose to do both GUI and Tcl packaging. I chose to first use the Vivado GUI for learning the needed Tcl commands since the Tcl console on the bottom of the GUI provides all the commands needed to produce Tcl scripts with identical functionality when run inside a script which is one of Vivado's great strenghts. One can then place these commands inside a script for actual inclusion in a project and commiting this script to the project's Github repository, something that Il try to explain in a future post.
So let's begin by launching Vivado and clicking Tasks -> Manage IP -> New IP location.
Choose your FPGA device in Part. I chose the Parallella Desktop FPGA device which is xc7z020clg400-1. If you have a different Parallella board just choose the smaller device xc7z010clg400-1. Keep the rest of the settings as seen below and choose your desired folder to store the IP.
Vivado should open an empty project with just an IP Catalog. Proceed by selecting Tools -> Create and Package IP in main menu.
Select the Create a new AXI4 peripheral task:
On the following window is where you define your IP's details and location to save it. Don't overthink the details because you can always change them later.
Your IP is an AXI4 peripheral and thus it needs to have some I/O ports defined. Our RISC-V core needs only two AXI4 (full, not Lite nor Stream) ports. One master port to initiate memory transactions (memory I/O) with Zynq's processing system DDR controller and one slave port to accept host commands from the frontend server software (fesvr) running on the ARM CPU.
Besides selecting interface type: Full for both the Master and Slave ports do not change the data width or other options as these are pretty constrained here (e.g we cannot select the needed 64bit data width for the M_AXI port) and we will fix them later.
Select Edit IP before clicking Finish:
Your new IP project will now open. The first thing to do is deleting the 3 Verilog source files that Vivado auto-generated for use since we will use our own wrappers and of-course the RISC-V RV64G core Verilog RTL (non human readable Verilog produced by Chisel compiler).
From the flow navigator on your left select Project Manager -> Add Sources:
Click Add Files on the bottom of the new window and select the 4 source files that you can download from here. Don't forget to select Copy source into IP directory. In case you are wondering what these source files are here is a short decription of them:
RISCV_Rocket_Core_RV64G.v - The top level wrapper that just instantiates the above AXI module.
You should now have the sources inside your IP project.
The category that your IP will be placed in the IP catalog can be selected from the Identification section. Just click the + / - icons to add a new / remove an IP category. For example I selected Embedded Processing and Processor but feel free to select the categories you desire for your own IP. From the same section you can update the IP details (vendor, library, name, version etc) that you filled previously.
Before packaging the IP we need to correct the issues shown on the right. You can identify those because they don't have a checkmark. For example the File Groups section is problematic and we need to click on Merge Changes from File Groups Wizard.
Do the same for the rest until everything is resolved. The Ports and Interfaces section will produce an error because our Verilog RTL has defined a 64bit data width for the AXI Master port but the default IP parameters have a 32bit limit on this port's data width. Edit the C_M_AXI_DATA_WIDTH parameter and change it's range from 32bit to 64bit by double clicking on the number.
Your are now ready to package the IP. Click on Review and Package section and then on the Re-Package IP button. You can edit some packaging options by clicking the edit links in this section. For example you have the ability to select whether to also create a zip archive of the IP, whether to delete the IP project after completion etc.
When done close the project by clickng yes on the popup.
That's all and now you should have your new IP saved in the folder you selected during its creation. It contains various folders that most of them can be ignored. The most important folder is the one containing your source files (named src or hdl) and the component.xml file which describes your IP in IP-XACT, a vendor neutral format for such IP descriptions.
You can add this IP in any new project of yours as with any other IP you have already added. Just create a block design in your project, click the Add IP button (or right click -> Add IP) and then search for the IP's name (type RV64G and Vivado will find it). In order for Vivado to find your IP you must first make sure to have the IP repo containing your IP (in our case the RV64G core) added in the new project's IP repositores. This can be done by going in the main menu at Tools -> Project Settings and then selecting the IP -> Repository Manager tab. On my next post I will show you how to automate all of this (packaging, new project, adding the IP in it, building a bitstream) with Tcl scripting, a process that is much easier, robust and reproducible than using Vivado's GUI.
You can find the zip archive of the IP I created while writing this post here.