Quick index
aims
Hello there!
Prerequisite knowledge
we
Project example
-
Create a blank project. For the creation process, please refer to
https://blog.csdn.net/malcolm_110/article/details/107222944 -
Creak block design
-
Add zynq block
-
Add an AXI_GPIO module
-
Add click automatic routing
, tick in the pop-up window
-
The effect is as follows, we can see that the system will
自动添加了一个AXI转换器
connect one end to the ARM core and one end to the AXI device. Here we use the GPIO device. If multiple slave devices are connected to the AXI bus, just double-click AXI Interconnect and reconfigure the number of ports. In this example, two slave devices are set, one is used for GPIO output, and the other is connected to RAM.
-
You can click Regenerate Layout to re-layout the module.
-
Add an ILA module, which is equivalent to a built-in logic analyzer for online data monitoring. The
clock is connected to the system clock, and the input signal is connected to the second slave port of AXI.
-
Continue to add a VIO module to monitor the IO output. Modify the configuration, only need to input, 4bit width; no need to output. Connect the wires.
Remember to configure the parameters of the arm core, ddr model/delay data, etc.
After setting, click validate design -
Modify the axi io port to axi_lite type, and associate the clock.
In the address space allocation, you can select automatic, and the depth can be selected as 4k -
Create project header file
12. Perform compilation
-
Next, develop the PL side, Add Sources, and create an empty verilog file, which can be named soc_axi_ctrl.v.
-
Double-click design_system_wrapper to pop up a verilog file of the IP project. We instantiate the port of this file to soc_axi_ctrl.v.
-
Create a RAM Block to verify the reading and writing of AXI.
First select the type as AXI4 to
enter the configuration bar of AXI4, select AXI4 Lite as the type, and you can rename it, axi_ram_blk. After clicking OK, the pop-up window has default options, and the system will execute the compilation. Just click yes/OK.
There is an additional column "IP" in Sources, find the file with the suffix of veo, which contains the port instantiation we need, and copy the soc_axi_ctrl.v file created above.
Final code
`timescale 1ns / 1ps
//
// Company:
// Engineer: malcolm_119
//
// Create Date: 2020/09/11 11:26:11
// Design Name:
// Module Name: soc_axi_ctl
// Project Name:
// Target Devices: xc7z030ffg-2
// Tool Versions: Vivado 2015.5
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module soc_axi_ctl_top(
inout [14:0] DDR_addr,
inout [ 2:0] DDR_ba,
inout DDR_cas_n,
inout DDR_ck_n,
inout DDR_ck_p,
inout DDR_cke,
inout DDR_cs_n,
inout [ 3:0] DDR_dm,
inout [31:0] DDR_dq,
inout [ 3:0] DDR_dqs_n,
inout [ 3:0] DDR_dqs_p,
inout DDR_odt,
inout DDR_ras_n,
inout DDR_reset_n,
inout DDR_we_n,
inout FIXED_IO_ddr_vrn,
inout FIXED_IO_ddr_vrp,
inout [53:0] FIXED_IO_mio,
inout FIXED_IO_ps_clk,
inout FIXED_IO_ps_porb,
inout FIXED_IO_ps_srstb,
output [3:0] led
);
wire fclk;
wire rstn;
wire [31 : 0] s_axi_awaddr;
wire s_axi_awvalid;
wire s_axi_awready;
wire [31 : 0] s_axi_wdata;
wire [3 : 0] s_axi_wstrb;
wire s_axi_wvalid;
wire s_axi_wready;
wire [1 : 0] s_axi_bresp;
wire s_axi_bvalid;
wire s_axi_bready;
wire [31 : 0] s_axi_araddr;
wire s_axi_arvalid;
wire s_axi_arready;
wire [31 : 0] s_axi_rdata;
wire [1 : 0] s_axi_rresp;
wire s_axi_rvalid;
wire s_axi_rready;
design_system_wrapper design_system_wrapper(
.DDR_addr ( DDR_addr ),// inout [14:0]DDR_addr;
.DDR_ba ( DDR_ba ),// inout [2:0]DDR_ba;
.DDR_cas_n ( DDR_cas_n ),// inout DDR_cas_n;
.DDR_ck_n ( DDR_ck_n ),// inout DDR_ck_n;
.DDR_ck_p ( DDR_ck_p ),// inout DDR_ck_p;
.DDR_cke ( DDR_cke ),// inout DDR_cke;
.DDR_cs_n ( DDR_cs_n ),// inout DDR_cs_n;
.DDR_dm ( DDR_dm ),// inout [3:0]DDR_dm;
.DDR_dq ( DDR_dq ),// inout [31:0]DDR_dq;
.DDR_dqs_n ( DDR_dqs_n ),// inout [3:0]DDR_dqs_n;
.DDR_dqs_p ( DDR_dqs_p ),// inout [3:0]DDR_dqs_p;
.DDR_odt ( DDR_odt ),// inout DDR_odt;
.DDR_ras_n ( DDR_ras_n ),// inout DDR_ras_n;
.DDR_reset_n ( DDR_reset_n ),// inout DDR_reset_n;
.DDR_we_n ( DDR_we_n ),// inout DDR_we_n;
.FIXED_IO_ddr_vrn ( FIXED_IO_ddr_vrn ),// inout FIXED_IO_ddr_vrn;
.FIXED_IO_ddr_vrp ( FIXED_IO_ddr_vrp ),// inout FIXED_IO_ddr_vrp;
.FIXED_IO_mio ( FIXED_IO_mio ),// inout [53:0]FIXED_IO_mio;
.FIXED_IO_ps_clk ( FIXED_IO_ps_clk ),// inout FIXED_IO_ps_clk;
.FIXED_IO_ps_porb ( FIXED_IO_ps_porb ),// inout FIXED_IO_ps_porb;
.FIXED_IO_ps_srstb ( FIXED_IO_ps_srstb ),// inout FIXED_IO_ps_srstb;
.axi_lite_ram_araddr ( s_axi_araddr ),// output [31:0]axi_lite_ram_araddr;
.axi_lite_ram_arprot ( ),// output [2:0]axi_lite_ram_arprot;
.axi_lite_ram_arready ( s_axi_arready ),// input [0:0]axi_lite_ram_arready;
.axi_lite_ram_arvalid ( s_axi_arvalid ),// output [0:0]axi_lite_ram_arvalid;
.axi_lite_ram_awaddr ( s_axi_awaddr ),// output [31:0]axi_lite_ram_awaddr;
.axi_lite_ram_awprot ( ),// output [2:0]axi_lite_ram_awprot;
.axi_lite_ram_awready ( s_axi_awready ),// input [0:0]axi_lite_ram_awready;
.axi_lite_ram_awvalid ( s_axi_awvalid ),// output [0:0]axi_lite_ram_awvalid;
.axi_lite_ram_bready ( s_axi_bready ),// output [0:0]axi_lite_ram_bready;
.axi_lite_ram_bresp ( s_axi_bresp ),// input [1:0]axi_lite_ram_bresp;
.axi_lite_ram_bvalid ( s_axi_bvalid ),// input [0:0]axi_lite_ram_bvalid;
.axi_lite_ram_rdata ( s_axi_rdata ),// input [31:0]axi_lite_ram_rdata;
.axi_lite_ram_rready ( s_axi_rready ),// output [0:0]axi_lite_ram_rready;
.axi_lite_ram_rresp ( s_axi_rresp ),// input [1:0]axi_lite_ram_rresp;
.axi_lite_ram_rvalid ( s_axi_rvalid ),// input [0:0]axi_lite_ram_rvalid;
.axi_lite_ram_wdata ( s_axi_wdata ),// output [31:0]axi_lite_ram_wdata;
.axi_lite_ram_wready ( s_axi_wready ),// input [0:0]axi_lite_ram_wready;
.axi_lite_ram_wstrb ( s_axi_wstrb ),// output [3:0]axi_lite_ram_wstrb;
.axi_lite_ram_wvalid ( s_axi_wvalid ),// output [0:0]axi_lite_ram_wvalid;
.axi_fclk ( fclk ),// output fclk;
.gpo ( led ),// output [3:0]gpo;
.ext_rst ( rstn ) // output [0:0]rstn;
);
axi_ram_blk axi_ram_blk (
.s_aclk ( fclk ),// input wire s_aclk
.s_aresetn ( rstn ),// input wire s_aresetn
.s_axi_awaddr ( s_axi_awaddr ),// input wire [31 : 0] s_axi_awaddr
.s_axi_awvalid ( s_axi_awvalid ),// input wire s_axi_awvalid
.s_axi_awready ( s_axi_awready ),// output wire s_axi_awready
.s_axi_wdata ( s_axi_wdata ),// input wire [31 : 0] s_axi_wdata
.s_axi_wstrb ( s_axi_wstrb ),// input wire [3 : 0] s_axi_wstrb
.s_axi_wvalid ( s_axi_wvalid ),// input wire s_axi_wvalid
.s_axi_wready ( s_axi_wready ),// output wire s_axi_wready
.s_axi_bresp ( s_axi_bresp ),// output wire [1 : 0] s_axi_bresp
.s_axi_bvalid ( s_axi_bvalid ),// output wire s_axi_bvalid
.s_axi_bready ( s_axi_bready ),// input wire s_axi_bready
.s_axi_araddr ( s_axi_araddr ),// input wire [31 : 0] s_axi_araddr
.s_axi_arvalid ( s_axi_arvalid ),// input wire s_axi_arvalid
.s_axi_arready ( s_axi_arready ),// output wire s_axi_arready
.s_axi_rdata ( s_axi_rdata ),// output wire [31 : 0] s_axi_rdata
.s_axi_rresp ( s_axi_rresp ),// output wire [1 : 0] s_axi_rresp
.s_axi_rvalid ( s_axi_rvalid ),// output wire s_axi_rvalid
.s_axi_rready ( s_axi_rready ) // input wire s_axi_rready
);
endmodule
- Add pin constraint file, right click on constraint, select Add Sources
#led
set_property PACKAGE_PIN W17 [get_ports {
led[0]}]
set_property PACKAGE_PIN W15 [get_ports {
led[1]}]
set_property PACKAGE_PIN W14 [get_ports {
led[2]}]
set_property PACKAGE_PIN W16 [get_ports {
led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
led[3]}]
- Compilation The
compilation process is a bit long, we can check some compilation status
====================================
- Import information into the SDK environment
File–Export–Export Hardware, and then pop up the following window
to continue File–Launch SDK
19. After entering the SDK, execute File–New–Application to
enter the project name, and select a blank project in next.
After it is built, right-click on src and create a new c file. The
file name must have a .c suffix.
/*
* led_ram.c
*
* Created on: 2020年9月11日
* Author: malcolm_119
*/
#include "xparameters.h"
#include "xil_io.h"
#define TRI 0x00000004
#define DATA 0x00000000
#define GPIO_BASE_ADDR XPAR_AXI_GPIO_0_BASEADDR
#define RAM_BASE_ADDR XPAR_AXI_LITE_RAM_BASEADDR
int main()
{
u8 data=0x11;
u8 data_temp;
u32 receive;
volatile int Delay;
u8 data_cnt;
u32 receive_data[32];
Xil_Out32(GPIO_BASE_ADDR+TRI,0x0);
receive = Xil_In32(GPIO_BASE_ADDR+DATA);
receive = receive & 0xFFFFFF00;
receive = receive | data;
Xil_Out32(GPIO_BASE_ADDR+DATA,receive);
while(1)
{
for(Delay=0;Delay<100000;Delay++);
receive = Xil_In32(GPIO_BASE_ADDR+DATA);
data_temp = data>>7;
data = (data<<1) | data_temp;
receive = receive & 0xFFFFFF00;
receive = receive | data;
Xil_Out32(GPIO_BASE_ADDR+DATA,receive);
for(data_cnt=0;data_cnt<32;data_cnt++)
Xil_Out32(RAM_BASE_ADDR + data_cnt*4,data_cnt);
for(data_cnt=0;data_cnt<32;data_cnt++)
receive_data[data_cnt] = Xil_In32(RAM_BASE_ADDR + data_cnt*4);
}
return 0;
}
After the code is written, power on the lower board and burn the file to facilitate online debugging later to
call up the debugging window.
Press F8 to execute the program, and you can see the results of some registers.
At the same time, in vivado, use vio and ila tools to monitor the operation and
add the port.
You can see that the IO value is cyclically jumping.
Next look at ILA
Press and hold ctrl to add multiple signals
Set monitoring conditions
Set monitoring length
Click to run