AXI VIP CDMA(小位宽及非整数位宽验证) - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

验证目的

  • cdma以及bram的位宽是128,我们想验证如果发送的数据<128bits怎么样?这个时候观察WLAST信号的行为。
  • 我们还想验证DMA的SR寄存器,它的行为,这将为软件判断标志位提供帮助。
task test_cdma_bram2bram_short;
    input [31:0] length;
    base_addr = 32'h41000000;

    addr = 32'h18;  data = 32'hC000_0000; //配置源地址
    master_agent.AXI4LITE_WRITE_BURST(base_addr + addr,0,data,resp);

    addr = 32'h20;  data = 32'hC000_1000; //配置目的地址
    master_agent.AXI4LITE_WRITE_BURST(base_addr + addr,0,data,resp);    

    addr = 32'h28;  data = length;   //配置传输长度,以byte为单位
    master_agent.AXI4LITE_WRITE_BURST(base_addr + addr,0,data,resp);        
endtask  
task read_sr;
    input [31:0] reg_addr;
    repeat(20) begin
        master_agent.AXI4LITE_READ_BURST(reg_addr,0,data,resp);  
        $display("read sr=%x", data);
    end  
endtask

task write_sr;
    input [31:0] reg_addr;
    input [31:0] reg_val;
     master_agent.AXI4LITE_WRITE_BURST(reg_addr,0,reg_val,resp);  
endtask
    read_sr(32'h41000004); 
    #40us;
    test_cdma_bram2bram_short(10);
    #40us;
    write_sr(32'h41000004,1<<12);
    test_cdma_bram2bram_short(20);
    #40us;
    write_sr(32'h41000004,1<<12);    
    test_cdma_bram2bram_short(16*32);  
    read_sr(32'h41000004);  

传输的波形(cdma的两侧)

image 第一次cdma传输,size=10。可以看到axi_m_wstrb[15:0]就是byte_mask。axi_m_wstrb=0x3ff指示当前传输有10个bytes是有效的。 注意到cdma只有一个axi_m接口,因此对bram的读写是同时进行的。 注意axi总线,只有写的byte_mask信号axi_m_wstrb[15:0],没有读的axi_m_rstrb[15:0]信号。因此读只能一次性读出整个word字长的数据。这个结论在之前的研究其实已经发现了。

image 第二次cdma传输,由于size=20,超过了一次传输最大16的限制,因此自动拆分成了2次。因此axi_m_wstrb[15:0]第1次是0xffff,也就是16bytes,第2次是0x000f,也就是4bytes。因此总和是20bytes。 由于axi总线读没有axi_m_rstrb[15:0]信号,因此读了2次,读出了2行完整的bram数据,但是写的时候不一样,写的时候需要用axi_m_wstrb[15:0],限制写的内容。这个是合理的。

image 第三次cdma传输(size=16*32bytes),需要拆分成32次发送。由于是整数没有小数,因此32次传输axi_m_wstrb[15:0]=0xffff,符合预期。 我们还注意到,在cdma传输期间,S_AXI_LITE接口还在不停的读,其实是在轮询sr寄存器。这是我们程序的功能。

image image 可以看到sr读的结果,当cdma传输完成后,sr的IDLE_bit=1。这个行为与dma几乎完全一样。

CDMA的内部波形(主要观察cr/sr寄存器)

image image image image

  1. cdma跟dma不一样,它的cr没有RS_bit,因此cdma没有使能,一直是开的,随时可以用。
  2. 当最后写入长度(sig_btt)后,就会启动dma传输,这个时候reg_idle_clr会产生pulse。传输完成后reg_idle_set和reg_ioc_irq_set会产生pulse。这些pulse会改变sr寄存器的相应的bit。
  3. 因此dma也是要用IDLE_bit来判断dma传输是否完成。

当配置了irq后

    read_sr(32'h41000004); 
    #40us;
    test_cdma_bram2bram_short(10);
    #40us;
    write_sr(32'h41000004,1<<12);
    test_cdma_bram2bram_short(20);
    #40us;
    write_sr(32'h41000004,1<<12);    
    write_sr(32'h41000000,(1<<12)+(1<<13)+(1<<14));  //配置irq
    test_cdma_bram2bram_short(16*32);  
    read_sr(32'h41000004);  

image 观察最后一轮的cdma传输,可以看到会产生ioc_irq中断。 我们注意到,其实idle信号与ioc_irq中断是同时发生的,两者之间没有延迟。

心得

  • reg_idle_set/clr,这是因为idle_bit完全是RO类型,完全由硬件set和clr。
  • reg_ioc_irq_set, reg_dly_irq_set,这是因为这些bits是R/WC类型,由硬件set,由软件clr。