AXI自定义IP之UART调试
1、实验原理
前面的自定义IP中已经将AXI总线的大部分接口设置都一一验证了。基本掌握了关键接受寄存器slv_reg和发送寄存器data_reg_out,可以基本实现简单的PL和PS的联合设计。但是,限于开发板的测试手段有限,只有一个按键和四个LED灯,限制了对复杂设计的测试能力。这里将PS端的一些常用接口利用起来,用于满足测试需求。本次实验使用的是UART串口显示。这个串口可以联系到上位机,可以有效提高测试能力。还有一些其他的资源也会用到,但是比较简单,比如GPIO的使用,调用一个IP就可以了,就不会设置专门的实验验证了。
2、实验操作
(1)hw(hardware硬件)界面操作
新建一个自建IP所需的verilog模块,这里这是复习前面的调用PL的模块,所以设计比较简单。
module multi_n( input wire [31:0] numb_n1, input wire [31:0] numb_n2, output wire [31:0] result_and, output wire [31:0] result_or, output wire [31:0] result_not ); assign result_and = numb_n1 & numb_n2; assign result_or = numb_n1 | numb_n2; assign result_not = ~numb_n1; endmodule
(2)IP界面的操作
这里需要通过新建一个自定义AXI的IP进入IP界面。进入IP设计后,在二级模块调用hw界面中新建的文件(先要添加到IP编辑界面),注意暂存信号的位宽设置。
修改部分:(注意声明信号前置)
//user wire [31:0] slv_reg2_wire; wire [31:0] slv_reg3_wire; wire [31:0] slv_reg4_wire; //end user always @(*) begin // Address decoding for reading registers case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) 3'h0 : reg_data_out <= slv_reg0; 3'h1 : reg_data_out <= slv_reg1; 3'h2 : reg_data_out <= slv_reg2_wire; 3'h3 : reg_data_out <= slv_reg3_wire; 3'h4 : reg_data_out <= slv_reg4_wire; 3'h5 : reg_data_out <= slv_reg5; default : reg_data_out <= 0; endcase end multi_n U1( .numb_n1(slv_reg0), .numb_n2(slv_reg1), .result_and(slv_reg2_wire), .result_or(slv_reg3_wire), .result_not(slv_reg4_wire) );
修改完后就可以打包文件,创建IP。这里总是需要打包两次才能将做好(代码总是容易出问题)。在第二次重复操作时出现IP在某个具体设计bd文件中锁死的情况,这个时候删除重来新调用IP就可以。
(3)hw界面的bd窗口设计
bd设计没有需要外连的端口,直接调用后自连自引即可。最后刷新IP和创建实例module,生成bit流即可实现硬件平台的设计。
(4)sw(software软件)界面的设计
直接建立C语言工程,可以直接使用helloworld的模版,可以快速添加所需的头文件。
#include <stdio.h> #include "platform.h" #include "xil_printf.h" #include "xil_io.h" #include "xparameters.h" #define ADR_BASE XPAR_MYIP_V1_0_0_BASEADDR #define ADR_REG0 0 #define ADR_REG1 4 #define ADR_REG2 8 #define ADR_REG3 12 #define ADR_REG4 16 int main() { init_platform(); unsigned int a; unsigned int b; unsigned int c; unsigned int d; unsigned int e; print("Hello World\n\r"); a=2; b=3; Xil_Out32(ADR_BASE+ADR_REG0,a); Xil_Out32(ADR_BASE+ADR_REG1,b); c=Xil_In32(ADR_BASE+ADR_REG2); d=Xil_In32(ADR_BASE+ADR_REG3); e=Xil_In32(ADR_BASE+ADR_REG4); printf("and= %d\n" ,c); printf("or= %d\n" ,d); printf("not= %d\n" ,e); cleanup_platform(); return 0; }
这个设计就是通过操作五个缓存寄存器实现自定义IP的功能测试。
图中使用的函数比较好理解,就不详细说明了。
(5)Teminal窗口观测
在windows》terminal就可以选择设置,读取串口数据。注意选择serial terminal,这个模式才是串口模式。其他模式暂时没有接触过,暂时不了解。结果会随着调试显示在对应的位置。
3、实验结果
板级测试的结果符合预期。不过由于前面的自定义IP的二级模块的端口声明没有注意位宽,导致显示的数据只有一位。但是与或非输出都符合预期。
======== ======\\ ======= -
|| || \\ // \\ /-\
|| || || // // \\
|| || // || // \\
====== ======= || === ========
|| || || \\ // \\
|| || \\ || // \\
|| || \\ // // \\
|| || ======= // \\
作者:绿叶落秋风,专注FPGA技术分析和分享,转载请注明原文链接:https://www.cnblogs.com/electricdream/p/13281611.html,文中资源链接如下:
1. GITHUB开源仓库