基于XDMA的CRC8_D8实验

        最近在老师的指点下学习了PCIE相关的知识点,同时做一个测试练练手,在这个过程中学习了axis总线,linux使用等,收获颇丰,在此总结一下。

开发设备:装载win10的PC一台

        装载ubuntu18的PC一台(PCIE接口)

        FPGA开发板(PCIE接口)

        vivado18.3

        tera term 用于在win上登录ubuntu PC

        实验任务:在win上搭建fpga工程上板。编写XDMA的驱动文件达到对数据的读写,至于fpga工程,使用的是之前的读写测试模块,添加了一个CRC的处理模块。关于XDMA的相关知识请查看链接内容https://blog.csdn.net/Njustxiaobai/article/details/132874083

        需要解决的问题:① 将自己写的CRC计算模块做成AXI Stream接口

                                    ② XDMA 用128位 crc模块是8位,转换位宽

以下是CRC8_D8模块的代码

module crc8_D8 #(
    parameter DATA_WIDTH = 8  // 数据宽度
)(
    input  wire                        aclk,       // 时钟
    input  wire                        aresetn,    // 复位信号,低电平有效
    input  wire [DATA_WIDTH-1:0]      s_axis_tdata, // 接收数据
    input  wire                        s_axis_tlast, // 标识数据包的最后一个字节
    input  wire                        s_axis_tvalid, // 有效信号,表明数据和用户信号是有效的
    output wire                        s_axis_tready, // 准备就绪信号,表明模块可以接收数据
    output wire [DATA_WIDTH-1:0]      m_axis_tdata, // 发送数据
    output wire                        m_axis_tlast,  // 标识数据包的最后一个字节
    output wire                        m_axis_tvalid, // 有效信号,表明数据是有效的
    input  wire                        m_axis_tready  // 准备就绪信号,表明接收模块可以接收数据
);

// 内部信号定义
reg [DATA_WIDTH-1:0]    data_reg;
reg                     last_reg;
reg                     valid_reg;
reg                     ready_reg;
reg [DATA_WIDTH-1:0] lfsr_c ;
reg [DATA_WIDTH-1:0] lfsr_q ;
// 状态机,处理AXI Stream数据流
always @(posedge aclk) begin
    if (!aresetn) begin
        valid_reg <= 1'b0;
        ready_reg <= 1'b1;
    end else begin
        if (s_axis_tvalid & ready_reg) begin
            data_reg <= lfsr_q;
            last_reg <= s_axis_tlast;
            valid_reg <= 1'b1;
        end else if (m_axis_tready & valid_reg) begin
            valid_reg <= 1'b0;
        end
        ready_reg <= m_axis_tready;
    end
end

always @(posedge aclk or negedge aresetn) begin
    if (!aresetn) begin
        lfsr_q <= {DATA_WIDTH{1'b1}}; // 异步复位
    end else begin
        lfsr_q <= lfsr_c; // 每个时钟周期更新lfsr_q
    end
end
// 根据状态机输出信号
assign m_axis_tdata = data_reg;
assign m_axis_tlast = last_reg;
assign m_axis_tvalid = valid_reg;
assign s_axis_tready = ready_reg;


  always @(*) begin
    lfsr_c[0] = lfsr_q[0] ^ lfsr_q[1] ^ lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[6] ^ s_axis_tdata[0] ^ s_axis_tdata[1] ^ s_axis_tdata[2] ^ s_axis_tdata[3] ^ s_axis_tdata[4] ^ s_axis_tdata[5] ^ s_axis_tdata[6];
    lfsr_c[1] = lfsr_q[0] ^ lfsr_q[7] ^ s_axis_tdata[0] ^ s_axis_tdata[7];
    lfsr_c[2] = lfsr_q[1] ^ s_axis_tdata[1];
    lfsr_c[3] = lfsr_q[2] ^ s_axis_tdata[2];
    lfsr_c[4] = lfsr_q[3] ^ s_axis_tdata[3];
    lfsr_c[5] = lfsr_q[4] ^ s_axis_tdata[4];
    lfsr_c[6] = lfsr_q[5] ^ s_axis_tdata[5];
    lfsr_c[7] = lfsr_q[0] ^ lfsr_q[1] ^ lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[5] ^ s_axis_tdata[0] ^ s_axis_tdata[1] ^ s_axis_tdata[2] ^ s_axis_tdata[3] ^ s_axis_tdata[4] ^ s_axis_tdata[5];

  end 
  


  
  // always

  // always @(posedge clk, negedge rst_n) begin
  //   if(!rst_n) begin
  //     lfsr_q <= {8{1'b1}};
  //   end
  //   else begin
  //     lfsr_q <= crc_en ? lfsr_c : lfsr_q;
  //   end
  // end // always
endmodule // crc

        在自行设计axis接口时有一个小技巧,可以去tools里找到自定义/封装ip功能,创建一个axis接口的ip,创建成功后,vivado会自动生成v文件,可以打开看看,作为参考,另外正点原子也有关于自定义IP的教程,可以看一下。注意一点,设计此类接口不能只创建接口而不管接口逻辑,如果没有的话在后续生成bit流文件可能会有问题。当时笔者设计的时候不小心把tready接口弄反了,导致综合的时候报错某一个LUT没有数据,最后打开网表图一层一层找到LUT才发现的问题,所以一开始设计就要规划好。

        接下来就是整个设计的block design图

        图中可以看到,从H2C接口出来的信号先进入一个axis fifo,然后进入了  axis_dwidth_converter这个IP,这个ip的作用是将128位的数据截成8位交给crc模块处理,所以在后面同样有一个axis_converter,用于8位合并成128位的数据到C2H接口。

        由于这次的实验没办法像之前的实验那样写一个tb文件去做仿真,所以在老师的指点下学习了debug的方法,本工程内运用的是ila,教程移步链接:https://blog.csdn.net/unique_ZRF/article/details/127715565

        需要注意的是,每个slot,都有不同的模板,在本实验中由于所有的接口基本上都是axis的,所以选用axis rtl模板,否则无法链接接口。

        由于这是之前的工程,所以综合排错以后就不需要做管脚约束和时序约束,直生成bit流文件上版。接下来移步ubuntu。

linux端:

        使用tera term在win上对linux远程操作,不需要GUI界面。注意通过网络连接要求两台设备同一IP域中。

        登录后输入lspci查看pcie设备,发现并没有xilinx设备。了解资料后发现需要reboot一下。

        重启后成功识别设备。

        安装驱动,过程如下。

        检查xdma设备,至此,我们的设备成功安装了驱动并且检测到了pcie设备。

        关于驱动:

简单概括,data文件夹存放测试用的数据和测试完的输出数据文件;

dma_memory_mapped_test.sh是地址映射脚本

dma_streaming_test.sh是流传输脚本

load_driver.sh是加载驱动脚本

perform_hwcount.sh是对性能的评估脚本

run_test.sh为测试脚本

        主要的关注点就是测试脚本和流传输脚本,打开测试脚本我们可以了解驱动的工作原理:首先会根据用户编写的fpga项目来判断是流传输模式还是地址映射模式,根据不同的模式选择不同的测试方案,而测试方案将data中的数据文件用于测试,最后输出文件至文件夹,并给出性能评估。对于本次实验,笔者用的是stream传输模式,因此只需要修改dma_streaming_test.sh即可。

        修改好以后,打包dma_streaming_test.sh和数据文件通过tera term的scp传输给linux。

        linux,将文件替换进XDMA下的tests文件。至此,就可以开始测试了。

        运行run_test即可完成测试。

        回到正文,装好驱动以后,通过ila去debug工程。

        这是一个漫长的工作过程,但是方法只有一个,就是一个接口一个接口的反复去抓信号,确定哪个接口的数据出了问题,然后修改,再抓,调试完毕后,通过scp输出rx和tx文件做对比,如下(二进制文件用notepad++打开)

        收获与反思:在这次实验里,接触了PCIE,axis总线协议,在线debug等许多知识,让我离独立开发项目又近了一步,但是与此同时,我发现此次实验大多还是基于以前的工程,如管脚约束和时序约束,尤其是时序约束,没有亲手去操作一下。

  • 30
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值