AXI自定义IP之UART调试

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

");

    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
" ,c);
    printf("or= %d
" ,d);
    printf("not= %d
" ,e);

    cleanup_platform();
    return 0;
}

这个设计就是通过操作五个缓存寄存器实现自定义IP的功能测试。

图中使用的函数比较好理解,就不详细说明了。

(5)Teminal窗口观测

在windows》terminal就可以选择设置,读取串口数据。注意选择serial terminal,这个模式才是串口模式。其他模式暂时没有接触过,暂时不了解。结果会随着调试显示在对应的位置。

3、实验结果

板级测试的结果符合预期。不过由于前面的自定义IP的二级模块的端口声明没有注意位宽,导致显示的数据只有一位。但是与或非输出都符合预期。

原文地址:https://www.cnblogs.com/electricdream/p/13281611.html