Connecting device to processor
This section will focus on connecting our own device to the processor. Next section will explain how to design software to access/control our own device.
Introduction
In last article, how to design basic standalone hardware on FPGA with Xilinx Vivado is explained. In this section, the focus will be on connecting our own device to the processor (how to make it visible to the processing system). Then how to develop software to access/control our own device will be explained in next section.
Instantiating Processing System
Firstly, ARM cortex-A9 processor has to be instantiated in the project. Create new project, then click “IP Integrator” → “Create Block Design”.
Input “Design name” and “OK”.
Click “+” icon in “Diagram” window, then search / select “Zynq Processing System”, then “processing_system7_0” module will be appeared in the window.
Click “Run Block Automation” in green bar at the top.
In the diagram, some output signals and connection to external DDR (DRAM) and Fixed I/O are added. If you need to customize IP, then right click on PS module and select “Customize Block”.
If proper board design was selected when this project was created, MIO (Mulxiplexed I/O) port and peripheral I/O pins are configured appropriately. If you don’t have board design, and selected SoC device name, then you would have to configure MIO and peripheral I/O as necessary.
In this example, it is assumed that the block design automation is done properly.
Connecting own device to processing system
AXI (Advanced EXtensible Interface) bus will be used to connect our own device to the processor. If the device is connected to the processor via AXI bus, the device will be appeared as Memory Mapped I/O. So you can access your device by specifying the device address.
The easiest way to connect device via AXI bus is, wrapping our own module into new IP. Click “Tools” →”Create and Package New IP”.
Select “Create a new AXI4 peripheral”.
Use your own module name. In this example, the module name is set to “my_adder”. New IP will be added to “ip_repo” directory which is created automatically in project directory.
This step is important. You have to choose “Lite” in “Interface Type”. It will add AXI4 Lite interface. Interface Mode: “Slave”, Data Width: “32”, and Number of Registers: “4” should be choosen. You might want to change number of registers for the future project. But for now, 3 (input source A, B and output Y) should be enough, but just in case, choose 4.
“Next” → “Finish”, then Click “IP Catalog” or “+” icon in block design. Now you can search your own IP. In my case, it’s “my_adder”. Select it and place it in block diagram.
My IP appeared in my block design. Click “Run Connection Automation” in green bar, then Vivado will automatically connect my device to the PS via AXI interconnect module. It also connects clocks and reset signals.
This system should work. But I want to add output for my own module, and connect it to LEDs to make it easier to debug.
Right click your module (in this case, “my_adder_0”), and select “Edit in IP Packager”. It will ask you the project name, but default should be fine.
When this module is created, my_adder_v1_0.v was added automatically. Edit this file.
The top module is “my_adder_v1_0”, but it’s just a wrapper. The actual logic is in “my_adder_v1_0_S00_AXI” module. Open my_adder_v1_0_S00_AXI.v.
There are 2 comment lines like this below;
// Users to add ports here
// User ports ends
Add new output here. I added “output wire [7:0] LED_OUT,” here.
Also, I want to change the register name. If you scroll down a little bit, you will see line like this below;
// — Number of Slave Registers 4
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3;
Let’s change this.
// — Number of Slave Registers 4
reg [C_S_AXI_DATA_WIDTH-1:0] input_a_reg;
reg [C_S_AXI_DATA_WIDTH-1:0] input_b_reg;
reg [C_S_AXI_DATA_WIDTH-1:0] output_reg;
reg [C_S_AXI_DATA_WIDTH-1:0] spare_reg;
So replace all “slv_reg*” to new name. Next, I want to make “output_reg” as read only. Comment out the line like this below;
Don’t forget to add output port in top module. Open my_adder_v1_0.v and add output.
Preparation is done. Let’s add our own module and connect. Right click “Design Sources” and select “Add sources”.
Add adder4.v from the last section. Open my_adder_v1_0_S00_AXI.v again, and add lines in between “Add user logic here” and “User logic ends” comments like below;
If there’s no syntax errors appearing, then go to DRC (Design Rule Check). Open “Project Summary” tab in Project Manager, then click “Run Implementation” below “DRC Violations”.
If there’s no errors, then synthesis and implementation should be completed.
To complete IP designing, open “Package IP -my_adder” tab in project manager.
Look at “Packaging steps”, some of them are checked, but some of them aren’t. Click unchecked lines, and click “Merge changes from group wizard” in all of them. If everything is checked, go to “Review and Package”, then click “Re-Package IP”.
When this process is finished, there is an yellow bar appears at the top. Click “Repot IP status”, then click “upgrade Selected” at the bottom.
If upgrade is successfully done, then new module with output “led_out” will be appeared.
If the output “led_out” is not added, then re-do the same step (right click the module and edit it). Make sure your works has been saved.
New output from the module “led_out” should be connected to the output port of this top design. Right click on new output port in the diagram (make sure that mouse cursor becomes pencil icon), then click “Make external”. Then this output will be connected to the output of this top module.
Get back to the “Sources” tab, and right click the top module (the one right below “Design Sources”), then select those accordingly.
- Generate Output Products
- Create HDL wrapper
Then, new Verilog source file is automatically generated, and marked as a “top module”.
Add Constraints
To make all the inputs/outputs connected to the physical pins, click “RUN ANALYSIS” → “Open Elaborated Design”. After elaborating design, “I/O Ports” tab will appear at the bottom. Connect [7:0]led_out to LEDs (No slide switches this time). Please refer to the previous section for the detail.
Synthesis, Implementation and bitstream generation
These steps are the same as previous section.