当前位置: 首页 > ai >正文

从零开始讲DDR(8)——AXI 接口MIG 使用(1)

一、前言

        在之前的系列文章中,我们已经讨论过了MIG ip的接口内容,配置方式和modelsim独立仿真相关的内容,因此,本文对于之前已经讨论过的相关内容只做简单描述,着重介绍AXI 接口MIG使用上与普通ui接口的不同之处。感兴趣的读者可以自行阅读之前的相关系列文章。

二、MIG配置

        在配置上,我们选择AXI4 Interface。

        在AXI接口的选择上选择64bit,写优先模式。然后就是通过打开xilinx提供的example project,并导出modelsim独立仿真所需要的相关文件,构建自己的独立仿真工程。

三、AXI 接口MIG仿真文件解析

        从example project导出的仿真文件中,我们可以看到如下的一系列测试平台列表

3.1 sim_tb_top.sv

3.1.1 注释说明

        根据官方给出的注释说明,我们可以看到这部分的内容主要的功能是:(1)整个测试平台的顶层模块(2)例化了内存模型(3)生成了时钟和复位逻辑。

3.1.2 代码解析

        sim_tb_top.sv中首先完成了一些必要信号的定义,然后就是进行了复位信号和时钟信号的产生,接下来就是例化了example_top模块,再之后就是例化的内存模型。这里我们并不需要关心内存模型是怎么实现的,我们只需要理解在sim_tb_top中核心功能就是例化了example_top模块。

        而如果我们希望仿真我们自己独立的代码逻辑,有2种可行的方式:(1)把自己的逻辑替换example_top模块(2)注释掉example_top模块,把相关的数据线从内部逻辑转换成input/output/inout的形式,形成对外的接口,这样我们就可以把整个sim_tb_top模块当做一个例化了内存模型,能自主进行复位和时钟产生的DDR测试模型,这样把我们自己的代码逻辑接到此文件,就可以进行独立的DDR模型仿真了。

3.2 example_top

        在编写我们自己独立的DDR读写逻辑之前,学习一下官方给出的示例工程还是非常必要的,我们知道在sim_tb_top中主要的功能是例化了example_top模块,因此,我们接下来来学习example_top模块。

3.2.1 注释说明

        从注释中我们可以发现, example_top模块的主要功能是作为一个测试的顶层文件,允许用户自定义他们的设计。主要例化了DDR MIG(就是我们生成的IP)和一个可综合测试平台,用于建模用户的后端逻辑和传输不同的流量模式。

3.2.2 代码解析

        从代码角度看,首先还是一些必要参数和信号定义,然后就是实例化了一个DDR MIG的ip模型,接下来例化了一个ddr4_v2_2_8_axi_tg_top模块。tg就是Traffic Generator的缩写。

        首先可以看到的是对于 c0_init_calib_complete 信号的一个寄存,这里的主要目的是为了在c0_init_calib_complete信号拉高后,生成一个boot_mode_start的pulse信号。简单推测就是在c0_init_calib_complete拉高后,开始进行boot mode的流量测试。

        接下来就是对于ddr4_v2_2_8_axi_tg_top的例化,ddr4_v2_2_8_axi_tg_top从接口上来看,主要包含3个部分:(1)AXI tg Input control signals (2)AXI MIG接口(3)Axi tg Error status signals。AXI MIG接口相对简单,就是用来和MIG进行连接的interface。Axi tg Error status signals看起来是和debug相关的,我们后面有需要的时候再详细展开,AXI tg Input control signal这里我们稍微关注一下:

        从信号的名称来看,大概指的是这个 Traffic Generator 支持的3种模式,分别是boot,custom和prbs。这里的执行逻辑是 custom 模式暂时没有使用,首先在c0_init_calib_complete 拉高后进行boot模式,然后,在boot_mode_done之后,boot_mode_done被接到了prbs_mode_start接口上,意味着在完成boot模式后,执行prbs模式。

3.3 ddr4_v2_2_8_axi_tg_top

        接下来我们来重点关注ddr4_v2_2_8_axi_tg_top模块

3.3.1 注释说明

        这个模块实例化了boot/prbs/custom-mode_gen模块。 根据用户输入,这些模式中的任何一个都可以处于运行状态,运行模式将驱动axi_opcode_gen模块的输入,该模块为AXI 从接口测试生成符合AXI4协议的流量。

  • *_mode_start->模式启动
  • *_mode_stop->模式停止
  • *_mode_done->为高表示用户停止模式或模式完成其表中的所有指令,可以通过断言任*_mode_start来清除

        简单判断就是提供了3种不同的模式,每种模式有各自的一组控制信号start,stop和done

3.3.2 代码解析

        首先还是进行一系列的参数和信号定义,然后我们关注下图中的代码逻辑,这里设置了running信号,用来表示当时正在执行的时什么模式。

        接下来,以running信号为依据,将正在运行的模式的相关控制信号,接到axi_opcode_gen的信号组上。

         然后就是一组模块的实例化,分别例化了boot_mode_gen,prbs_mode_gen,custom_mode_gen和axi_opcode_gen。功能分析起来也并不复杂,首先用户通过start,stop和done控制运行的模式(同一时间只能运行一种模式),然后boot_mode_gen,prbs_mode_gen,custom_mode_gen是各自模式的激励生成器,会生成对应模式的测试激励,然后根据running信号,选择对应的激励驱动到axi_opcode_gen的输入端接口,axi_opcode_gen会将激励转换成符合axi4协议规范的信号,驱动到MIG的AXI4从接口上。

        梳理清楚了核心逻辑,我们还需要关注一下最后的一部分自动化测试逻辑。

        首先是watch_dog ,它的功能是检测AXI总线是否卡死——如果超过C_TG_WATCH_DOG_MAX_CNT个时钟周期没有读写活动,触发watch_dog_hang信号,终止仿真并报错($finish)。

localparam C_TG_WATCH_DOG_MAX_CNT = 16'hFFFF;
reg [15:0] watch_dog_cnt;
wire watch_dog_enable;
reg watch_dog_rst;
wire watch_dog_hang;assign watch_dog_enable = 1'b1; // 看门狗常启// 任何AXI读写活动都会复位计数器
always@(posedge clk) beginwatch_dog_rst <= #TCQ ((axi_awready && axi_awvalid) || // 写地址通道活动(axi_wready && axi_wvalid) ||    // 写数据通道活动(axi_bready && axi_bvalid) ||    // 写响应通道活动(axi_arready && axi_arvalid) ||  // 读地址通道活动(axi_rready && axi_rvalid));     // 读数据通道活动
end// 看门狗计数逻辑
always@(posedge clk) beginif (tg_rst | watch_dog_rst) begin           // 全局复位或AXI活动时清零watch_dog_cnt <= #TCQ 'h0;endelse if (watch_dog_enable && ~watch_dog_hang && (vio_axi_tg_boot_mode_running ||     // 在TG运行模式下递增计数vio_axi_tg_custom_mode_running || vio_axi_tg_prbs_mode_running)) beginwatch_dog_cnt <= #TCQ watch_dog_cnt + 'h1;end
end
assign watch_dog_hang = (watch_dog_cnt == C_TG_WATCH_DOG_MAX_CNT); // 超时标志

        然后是错误状态记录与VIO调试接口,它的作用是记录首次发生的数据不匹配错误,并通过VIO接口输出详细的错误上下文(地址、ID、数据差异等),方便硬件调试。类似地处理写响应错误(vio_axi_tg_write_resp_error)和读响应错误(vio_axi_tg_read_resp_error)。

// 同步错误状态到VIO(Virtual Input/Output)可观察信号
always @(posedge clk) beginif (tg_rst) begin  // 全局复位时清零vio_axi_tg_mismatch_error      <= #TCQ 0;   // 数据不匹配错误vio_axi_tg_expected_bits       <= #TCQ 0;   // 预期数据值vio_axi_tg_actual_bits         <= #TCQ 0;   // 实际收到的数据值vio_axi_tg_error_bits          <= #TCQ 0;   // 出错的数据位掩码vio_axi_tg_error_status_id     <= #TCQ 0;   // 错误交易IDvio_axi_tg_error_status_addr   <= #TCQ 0;   // 错误地址vio_axi_tg_error_status_len    <= #TCQ 0;   // 错误交易长度vio_axi_tg_error_status_size   <= #TCQ 0;   // 错误数据大小(字节)vio_axi_tg_error_status_burst  <= #TCQ 0;   // 错误突发类型endelse if(axi_tg_mismatch_error && ~vio_axi_tg_mismatch_error) begin// 捕获第一次出现的错误(Sticky Error)vio_axi_tg_mismatch_error      <= #TCQ 1;vio_axi_tg_expected_bits       <= #TCQ axi_tg_expected_bits;vio_axi_tg_actual_bits         <= #TCQ axi_tg_actual_bits;// ...其他信号赋值省略...end  
end

        接下来是仿真调试输出,用来在仿真中实时报告错误,并在测试完成后统计成功率。

// 仿真时打印错误信息
always @(posedge clk) beginif(axi_tg_mismatch_error) begin$display("ERROR::数据不匹配");$display("地址='h%h, 长度='d%0d, 数据大小='d%0d, 突发类型='b%2b",...);endelse if(axi_tg_write_resp_error) begin$display("ERROR:: 时间 %t 写响应错误", $time);end// ...读响应错误处理类似...
end// 看门狗超时终止仿真
always @(posedge clk) beginif(watch_dog_hang) begin$display("ERROR:: 看门狗超时,AXI总线无响应");$finish; // 强制结束仿真end
end// 测试结束总结
initial beginwait(prbs_mode_done == 1); // 等待测试模式完成if(mismatch_err_cnt == 0) $display("测试通过");else $display("测试失败,错误次数 = %0d", mismatch_err_cnt);$finish;
end

        最后是窄突发(Narrow Burst)断言检查,作用是当DDR控制器不支持窄突发(Narrow Burst)时,强制检查所有AXI传输的awsize/arsize是否等于全数据宽度(避免配置错误导致数据错位)。

generate 
if((C_AXI_NBURST_SUPPORT == 0) && (APP_DATA_WIDTH == C_AXI_DATA_WIDTH)) begin// 检查写请求的突发大小是否符合限制property narrow_burst_disabled_check_size_for_writes;@(posedge clk) disable iff (tg_rst) (axi_awready && axi_awvalid) |-> (axi_awsize == C_WSTRB_WIDTH_LOG2);endpropertyassert property(narrow_burst_disabled) else $error("错误:控制器不支持窄突发时发送了不匹配的AXI写请求大小(h%0h)",axi_awsize);// 读请求也有类似检查
end
endgenerate

四、小结

        至此,我们已经简单拆解了MIG AXI接口中测试文件的整体框架,首先在sim_tb_top.sv文件中例化了DDR模型和example_top。在example_top中,又例化了MIG IP和一个流量产生器ddr4_v2_2_8_axi_tg_top。在ddr4_v2_2_8_axi_tg_top中的主要功能是分别例化了boot_mode_gen,prbs_mode_gen,custom_mode_gen和axi_opcode_gen。用户通过start,stop和done控制运行的模式(同一时间只能运行一种模式),boot_mode_gen,prbs_mode_gen,custom_mode_gen是各自模式的激励生成器,会生成对应模式的测试激励,然后根据running信号,选择对应的激励驱动到axi_opcode_gen的输入端接口,axi_opcode_gen会将激励转换成符合axi4协议规范的信号,驱动到MIG的AXI4从接口上。在后面的文章中,我们将继续展开介绍boot_mode_gen,prbs_mode_gen,custom_mode_gen和axi_opcode_gen的原理。

http://www.xdnf.cn/news/3548.html

相关文章:

  • 主机Windows和虚拟机ubuntu和开发板三者互ping学习记录
  • Allegro23.1新功能之如何使用文件预览功能操作指导
  • 改进算法超详细:双变异樽海鞘群算法:从最优性能设计到分析
  • 数字智慧方案6185丨智慧银行解决方案(51页PPT)(文末有下载方式)
  • 【quantity】5 derive_more库 2.0 版介绍
  • 预订接口优化:使用本地消息表保证订单生成、库存扣减的一致性
  • 人工智能项目开发项目
  • SSH秘钥管理指南
  • Nginx核心功能及正则表达
  • 第T8周:猫狗识别
  • 【免费】2010-2019年上市公司排污费数据
  • 纯原生Java实现:获取整个项目中指定接口所有的实现类
  • 每天一道算法题——推多米诺
  • 使用xlwings计算合并单元格的求和
  • Cesium 环境搭建
  • 组件通信-$attrs
  • 5个实用工具软件详细介绍
  • 多线程基础:线程创建、启动与生命周期管理
  • 【阿里云大模型高级工程师ACP学习笔记】2.9 大模型应用生产实践 (上篇)
  • ESP32 在Platform Arduino平台驱动外部PSAM,进行内存管理
  • 数字智慧方案5846丨智慧广场整体解决方案(91页PPT)(文末有下载方式)
  • mindyolo填坑
  • 应用接入Stripe支付实战【2025版+配置+服务端+客户端+生产级+架构图+代码】
  • 表管理(约束)实验
  • C语言与指针3——基本数据类型
  • Learning vtkjs之TubeFilter
  • TMI投稿指南(四):投稿相关网址
  • 【Linux】Linux基础命令
  • 27.电源和地的单点串并联接线隐患及对EMC的影响分析
  • 数字智慧方案6206丨智慧园区大数据整体解决方案(45页PPT)(文末有下载方式)