XIlinx MIG 控制DDR3 SO-DIMM内存条(三):MIG IP核仿真与调试过程

之前写这个系列的时候忘记上传了,刚好五一补一下。

1 MIG IP核的接口

想应用IP核,首先学习IP核的接口。

在这里插入图片描述

内存控制器可以使用AXI4 slave、UI、或者直接使用native接口进行连接。

  • AXI4从接口提供了一个符合AXI4内存映射的从接口,用于连接到处理器子系统。AXI4从接口将其事务转换为在UI上传递它们。
  • UI类似于一个简单的FIFO接口,并且总是按顺序返回数据。
  • native接口在某些情况下提供了更高的性能,但使用起来更难。

native接口不包含缓冲区并尽快返回数据,但返回的数据可能顺序错误。如果使用native接口并启用了重新排序,应用程序必须在内部重新排序接收到的数据。下面的章节描述了每个接口的时序协议以及应该如何控制它们。

1.1 AXI4 slave 接口

来自AXI master的AXI地址是一个byte address。AXI shim根据AXI SIZE和存储器数据宽度将地址从AXI master地址转换到存储器地址。根据存储器阵列的数据宽度,AXI byte address的LSB被屏蔽为0。如果存储器阵列是64bit位宽(8字节),则AXI address[2:0]=0。如果存储器阵列是16bit位宽(2字节),则AXI address[0]=0。

DDR3 DRAM以8个DRAM word的块访问,burst长度为8。UI数据端口宽为8个DRAM word,PHY到内存控制器(MC)时钟比例为4:1,PHY到MC时钟比例为2:1。

在这里插入图片描述

1.2 Upsizing

当User Interface侧的数据宽度大于AXI Interface侧的数据宽度时,在AXI Shim接口中进行放大。对INCR和
WRAP burst执行数据打包。

在最终向User Interface端发出的事务中,因为数据位宽更大,所以数据拍数相应减少:

  • 对于写,发生数据合并。
  • 对于读,发生数据串行化。

这里是理解错了还是手册写反了,User Interface端更大的位宽,不应该进行数据串行化后发给AXI Interface吗?

1.3 User Interface

User Interface 与物理存储器row、bank、column地址的映射关系是可以配置的,两种映射方式:

  1. Bank- Row-Column
    在这里插入图片描述

  2. Row-Bank-Column
    在这里插入图片描述

1.3.1 Command Path

当用户逻辑的app_en信号被断言 且 UI的app_rdy信号被断言时,UI接受一个命令并写入到FIFO。

在这里插入图片描述

发出一个非back-to-back的写命令,下图描述了app_wdf_data、app_wdf_wren和app_wdf_end信号的三种场景,如下所示:

  1. 写数据与相应的写命令一起出现。
  2. 写数据出现在相应的写命令之前。
  3. 写数据出现在相应的写命令之后。但不应超过两个时钟周期的限制。

在这里插入图片描述

对于写命令寄存后输出的写数据,情景3,最大延迟为两个时钟周期。

*什么是back-to-back?
背靠背是两个不同的事务连续执行,中间不经历总线的idle态。突发是一个事务中地址连续的数据的连续传输。

1.3.2 Write Path

当断言app_wdf_wren且app_wdf_rdy为High时,写入数据寄存在写入FIFO中。如果app_wdf_rdy被解除断言,用户逻辑需要保持app_wdf_wren和app_wdf_end High以及有效的app_wdf_data值,直到app_wdf_rdy被断言。app_wdf_data数据可以在app_cmd“写命令”之前被断言。唯一的条件是,对于每个app_cmd“写命令”,关联的app_wdf_data“写数据”必须存在。app_wdf_mask信号可用于屏蔽要写入外部内存的字节。

在写数据和相关的写命令之间的单个写的最大延迟是两个时钟周期。

app_wdf_end信号必须用于指示内存写入突发的结束。对于2:1模式下的8内存突发类型,app_wdf_end信号必须在第二个写入数据字上断言。

1.3.3 Read Path

读取的数据由UI以请求的顺序返回,并且在断言app_rd_data_valid时有效。app_rd_data_end信号表示每个读命令突发的结束,在用户逻辑中不需要这个信号。

返回的读数据总是与地址/控制总线上发出的请求顺序相同。

在这里插入图片描述

1.4 Native interface

native interface协议:

在这里插入图片描述

请求以地址和命令的形式呈现给本机接口。地址由bank, row, 和 column输入组成。该命令在cmd输入中编码。

上图,在使用use_addr信号进行验证之前,地址和命令给Native interface一个状态。memory interface通过断言accept信号指示接受请求。当use_addr和accept都在同一个时钟周期中断言时,请求被确认为接受。如果use_addr被断言,但是accept没有,请求将不被接受,必须重复。

在这里插入图片描述

请求1和2通常被接受。第一次提出请求3时,accept被驱动为Low,请求不被接受。用户设计重试请求3,该请求在下一次尝试时被接受。请求4随后在第一次尝试时被接受。

data_buf_addr总线必须与请求一起提供。这个地址总线是一个指向用户设计中存在的缓冲区的地址指针。它告诉IP核在处理写命令时把数据放在哪里,在处理读命令时把数据放在哪里。当IP核处理一个命令时,IP核将data_buf_addr反馈给由wr_data_addr(写命令)和rd_data_addr(读命令)组成的用户设计。这种行为如下图所示。写数据必须在断言wr_data_en的同一时钟周期内提供。

在这里插入图片描述

可以使用 non-activity间隙间隔传输,也可以使用没有间隙的长时间突发。用户设计可以通过监视rd_data_en和wr_data_en信号来确定何时处理请求以及何时结束请求。当rd_data_en信号被断言时,内存控制器已经完成了一个读命令请求的处理。类似地,当wr_data_en信号被断言时,内存控制器正在处理一个写命令请求。

当NORM排序模式启用时,内存控制器重新排序接收到的请求,以优化FPGA和内存设备之间的吞吐量。数据以处理的顺序而不是收到的顺序返回给用户设计。用户设计可以通过监视rd_data_addr和wr_data_addr来识别正在处理的特定请求。这些字段对应于用户设计向native interface提交请求时提供的data_buf_addr。

1.5 Physical Layer Interface

在这里插入图片描述

2 仿真

2.1 模块结构

在这里插入图片描述

(控制/数据)流产生操作:

包含于可综合 testbench 上的 traffic generator module可以被参数化,以创建用于存储器设计的各种激励模式。它可以产生用于验证设计完整性的重复测试模式,以及仿真真实世界流的伪随机数据流。

可以通过BEGIN_ADDRESS和END_ADDRESS参数定义地址范围。Init Memory Pattern Control块引导流生成器按顺序遍历地址空间中的所有地址,根据所选的数据模式将适当的数据值写入存储器器件中的各位置。默认情况下,testbench 使用地址作为 数据 ,但是这个示例设计中的数据模式可以使用vio_data_mode信号进行修改,该信号可以在Vivado逻辑分析器特性中进行修改。

当存储器被初始化后,流产生器开始激励用户接口端口来创建进出存储器设备的流。缺省情况下,流生成器向端口发送伪随机命令,即指令序列(R/W、R、W)和地址由流量生成器模块中的PRBS生成器逻辑决定。

从存储器设备返回的读数据由流生成器通过用户接口读数据端口访问,并与内部生成的数据进行比较。如果检测到错误(即读取数据和预期数据之间存在不匹配),则断言错误信号,并将回读地址、回读数据和预期数据锁存到error_status输出中。

可以修改示例设计的参数进行不同的仿真。

2.2 mig_7series_v4_2_traffic_gen_top

这个模块可以产生很多模式的数据流,可以通过参数和VIO配置。

参数列表

参数含义描述
FAMILY器件族类型VIRTEX7只有VIRTEX6和VIRTEX7两个选项,使用的是k7,这个参数也是VIRTEX7
MEM_TYPE存储器控制器类型DDR3
TST_MEM_INSTR_MODE测试模式R_W_INSTR_MODER_W_INSTR_MODE:读写测试。FIXED_INSTR_R_MODE:只读。FIXED_INSTR_W_MODE:只写。FIXED_INSTR_R_EYE_MODE:读眼图测试
nCK_PER_CLK存储器时钟与此逻辑时钟的比例4设置IP核的时候设置的
NUM_DQ_PINS存储器DQ引脚的位宽64
MEM_BURST_LEN存储器数据突发长度8必须为8
MEM_COL_WIDTH存储器列地址的位宽10取决于选的存储器
DATA_WIDTHuser interface数据总线的位宽512DATA_WIDTH = NUM_DQ_PINS × nCK_PER_CLK x2
ADDR_WIDTHuser interface地址总线的位宽29RANK_WIDTH + BANK_WIDTH + ROW_WIDTH + COL_WIDTH
MASK_SIZEuser interface数据总线的掩码位宽64DATA_WIDTH/8
PORT_MODE端口模式BI_MODE生成WRITE数据模式并监视READ数据进行比较。
BEGIN_ADDRESS设置存储器起始地址32’h00000000Bits[3:0]无效
END_ADDRESS设置存储器结束地址32’h00ffffffBits[3:0]无效
PRBS_EADDR_MASK_POS设置结束地址32位AND掩码位置32’hff000000该参数与伪随机位序列(pseudo-random bit sequence, PRBS)地址生成器配合使用,将随机地址向下移动到端口地址空间中, PRBS_EADDR_MASK_POS 是 PRBS address的掩码。END_ADDRESS 与 PRBS address相与
PRBS_SADDR_MASK_POS设置结束地址32位OR掩码位置PRBS_EADDR_MASK_POS该参数与伪随机位序列(pseudo-random bit sequence, PRBS)地址生成器配合使用,将随机地址向上移动到端口地址空间中, PRBS_SADDR_MASK_POS 是 PRBS address的掩码。START_ADDRESS 与 PRBS address相与
CMD_PATTERN这个参数设置要生成的命令模式电路。这个参数设置要生成的命令模式电路。CGEN_FIXED: 地址、突发长度和指令直接从fixed_addr_i、fixed_bl_i和fixed_instr_i输入中获取。CGEN_SEQUENTIAL: 地址按顺序递增,增量大小由数据端口大小决定。CGEN_PRBS:32级线性反馈移位寄存器(LFSR)产生伪随机地址、突发长度和指令序列。可以从32位的cmd_seed输入设置种子。CGEN_ALL (默认): 该选项将打开上述所有选项,并允许addr_mode_i、instr_mode_i和bl_mode_i在运行时选择生成类型。
DATA_PATTERN该参数设置通过RTL逻辑生成的数据模式电路。DGEN_ALLADDR:地址用作数据模式。HAMMER: DQS上升沿DQ引脚上都是1,DQS下降沿DQ引脚上都是0。WALKING1: 在DQ引脚上移动1s,1的起始位置取决于地址值。WALKING0: 在DQ引脚上移动0s,0的起始位置取决于地址值。NEIGHBOR: HAMMER模式,但是有一个DQ pin异常,地址决定了异常引脚的位置。PRBS:32级LFSR生成随机数据,并由起始地址作为种子。DGEN_ALL: 这个选项打开所有可用选项
CMDS_GAP_DELAY这个参数允许每个用户突发命令之间的暂停延迟。6’d00 到 32
SEL_VICTIM_LINE选择一个异常DQ线,其状态总是在逻辑高8此参数仅适用于Hammer模式。此参数的有效设置为0到NUM_DQ_PINS。当value = NUM_DQ_PINS时,所有DQ引脚具有相同的Hammer模式。
EYE_TEST强制流生成器只生成对单个位置的写操作,不生成读事务FALSE该参数的有效设置是“TRUE”和“FALSE”。当设置为“TRUE”时,vio_instr_mode_value中的任何设置都将被覆盖

VIO控制列表

信号含义描述
vio_modify_enable允许vio_xxxx_mode_value改变流模式。1’b0不允许
vio_data_mode_value[3:0]数据流模式,DATA_PATTERN开启的模式4’b00101: FIXED data mode。2: DGEN_ADDR,地址作为数据。3: DGEN_HAMMER。4: DGEN_NEIGHBOR。5: DGEN_WALKING1。6: DGEN_WALKING0。7: DGEN_PRBS。
vio_addr_mode_value[2:0]地址流模式,CMD_PATTERN开启的模式3’b0111: Fixed_address。2: PRBS address。3: Sequential address。
vio_instr_mode_value[3:0]指令模式,CMD_PATTERN开启的模式4’b0010
vio_bl_mode_value[3:0]突发长度,CMD_PATTERN开启的模式2’b101: Fixed 突发长度;2: PRBS 突发长度,如果为2,addr_mode强制为2以产生PRBS地址。
vio_fixed_instr_valuefixed指令的值,0x0: Write指令,0x1: Read指令3’b001
vio_fixed_bl_value突发长度的值,1-2568’d16
vio_pause_traffic即时(on-the-fly)暂停动态流生成1’b0
vio_data_mask_gen数据掩码产生使能1’b0此模式仅在数据模式模式为address as data时使用。如果启用此选项,则在存储器模式填充到存储器后将生成一个随机memc_wr_mask。如果断言对应的memc_write_mask,则写入数据字节通道将被8’hFF阻塞。

修改端口地址空间

端口的地址空间可以通过更改顶层testbench文件中的BEGIN_ADDRESS和END_ADDRESS参数来修改。这两个值必须与端口的数据位宽对齐。另外还有两个额外的参数,PRBS_SADDR_MASK_POS和PRBS_EADDR_MASK_POS,用于默认的PRBS地址模式确保没有向端口发送超出范围的地址。
PRBS_SADDR_MASK_POS创建一个OR掩码,该掩码将PRBS生成的值低于BEGIN_ADDRESS的地址向上移动到端口的有效地址空间中。PRBS_SADDR_MASK_POS应该设为与BEGIN_ADDRESS参数相等的32位值。掩码高电平有效,小于开始地址的值与掩码(起始地址)或逻辑运算之后,就会大于起始地址。

PRBS_EADDR_MASK_POS创建一个AND掩码,该掩码将PRBS生成的具有END_ADDRESS以上值的地址向下移动到端口的有效地址空间中。PRBS_EADDR_MASK_POS应该设为32位值,其中END_ADDRESS的最高有效地址位之上的所有位都被设置为1,其余的位都被设置为0。这个掩码是对应位低电平有效,将地址值与END_ADDRESS对应位AND运算,使得到的地址值小于结束地址。

//path: [component name]_ex\imports\mig_7series_v4_2_cmd_prbs_gen.v
for(i = logb2(MEM_BURST_LEN) - 2; i <= SEED_WIDTH - 1; i = i + 1)
    for(i = 3; i <= SEED_WIDTH - 1; i = i + 1)
       if(PRBS_SADDR_MASK_POS[i] == 1)
          prbs[i] = PRBS_SADDR[i] | lfsr_q[i+1];
       else if(PRBS_EADDR_MASK_POS[i] == 0)
          prbs[i] = PRBS_EADDR[i] & lfsr_q[i+1];
       else
          prbs[i] = 1'b0;// lfsr_q[i+1];
        prbs[logb2(MEM_BURST_LEN)-3:0] = 'b0;//{logb2(MEM_BURST_LEN) -3{1'b0}};
    end

工作过程

这个测试程序非常庞大,因为可以设置很多测试类型进行测试,导致逻辑也非常复杂。大致了解示例的控制流程即可。

  1. 首先等待IP核校准初始化完成(memc_init_done == 1’b1)。

  2. 初始化后mig_7series_v4_2_init_mem_pattern_ctr中的状态机根据参数的设置设置测试的模式。

  3. mig_7series_v4_2_memc_traffic_gen根据设置的测试模式产生对应的数据流。

总体时序图:

在这里插入图片描述

2.2.1 mig_7series_v4_2_init_mem_pattern_ctr

功能:这个模块有一个FSM来控制memc_traffic_gen模块的操作。它首先用选定的DATA模式填充内存,然后启动内存测试状态。

首先根据输入的参数获取本模块的指令模式:

assign test_mem_instr_mode = (vio_instr_mode_value[3:2] == 2'b11) ? 4'b1111:
                             (vio_instr_mode_value[3:2] == 2'b10) ? 4'b1011:
                             (TST_MEM_INSTR_MODE == "BRAM_INSTR_MODE")  ? 4'b0000:
                             (TST_MEM_INSTR_MODE == "FIXED_INSTR_R_MODE"  ||
                              TST_MEM_INSTR_MODE == "FIXED_INSTR_W_MODE")              ? 4'b0001:
                             (TST_MEM_INSTR_MODE == "R_W_INSTR_MODE")                                    ? 4'b0010:
                             (TST_MEM_INSTR_MODE == "RP_WP_INSTR_MODE"         && FAMILY == "SPARTAN6")  ? 4'b0011:
                             (TST_MEM_INSTR_MODE == "R_RP_W_WP_INSTR_MODE"     && FAMILY == "SPARTAN6")  ? 4'b0100:
                             (TST_MEM_INSTR_MODE == "R_RP_W_WP_REF_INSTR_MODE" && FAMILY == "SPARTAN6")  ? 4'b0101:
                             4'b0010;
  1. IDLE
    上电为空闲状态。
    当初始化完成memc_init_done_reg == 1’b1。因为vio_instr_mode_value == 4’b0010 且 TST_MEM_INSTR_MODE == “R_W_INSTR_MODE”, 所以工作模式为4’b0010。
    又PORT_MODE = “BI_MODE”,所以下一状态为INIT_MEM_WRITE。
  2. INIT_MEM_WRITE
    addr_mode = SEQUENTIAL_ADDR;地址模式设置为连续地址。
    upper_end_matched && lower_end_matched,下一状态为TEST_MEM
  3. TEST_MEM
    进行内存读写测试。

在这里插入图片描述

2.2.2 mig_7series_v4_2_memc_traffic_gen

这是存储区数据/控制流生成器的顶层模块,可以对存储器控制器核心产生不同的CMD_PATTERN和DATA_PATTERN。

3 调试

因为为了IP核的简洁所以在配置IP核时没有加默认的VIO和ILA。所以直接把User Interface的app_*读写信号以及对比结果信号tg_compare_error抓出来分析就行。

在这里插入图片描述

默认的测试模式是地址顺序增加,然后地址值作为数据。对比读写的地址和数据值是否一致以及对比结果即可。
测试调通之后就可以进行自己项目的开发了。

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Xilinx FPGA平台DDR3设计保姆式教程(3)是关于使用MIG IP核DDR读写时序的教程。 首先,MIG(Memory Interface Generator)是Xilinx提供的IP核,用于简化DDR3控制器接口的设计。在使用MIG IP核前,需要根据DDR3芯片的规格参数,使用MIG生成一个适用于特定器件的IP核文件。生成IP核文件后,可以将其添加到设计中。 使用MIG IP核时,需要正确设置IP核的参数,以满足设计需求。这些参数包括时钟频率、数据宽度、时序参数等。为了正确设置这些参数,可以参考DDR3芯片的数据手册和Xilinx提供的MIG IP核使用手册。 在DDR3读写时序中,有多个重要的信号需要注意。首先是时钟信号,它用于同步数据的传输。时钟信号的频率应根据DDR3规格进行设置,通常为DDR3规格中指定的频率(比如900MHz)的一半。然后是地址信号,它用于指定要读写的存储单元的位置。地址信号的宽度应根据DDR3规格进行设置,通常为规定的位数(比如13位)。接下来是控制信号,包括读使能信号和写使能信号,用于控制读写操作的进行。最后是数据信号,用于实际的数据传输。数据信号的宽度应根据DDR3规格和设计需求进行设置。 在设计中,需要根据DDR3芯片的时序要求,来设置合适的读写延迟和时序参数。这些参数可以通过MIG IP核的配置界面进行设置。此外,还需要根据DDR3芯片要求,使用适当的芯片选择信号和刷新操作,以确保DDR3的正常工作。 综上所述,使用Xilinx FPGA平台进行DDR3设计时,可以使用MIG IP核来简化接口设计,并根据DDR3规格和时序要求来设置相关参数。合理设置这些参数,可以保证DDR3的正常读写操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lu-ming.xyz

觉得有用的话点个赞吧 :)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值