达芬奇pro开发板DDR3读写实验

参考正点原子视频及例程

模块:顶层、MigIP核、时钟IP核、ddr3读写模块

一、MIG核

1.1mig核介绍   

具体了解参考快速上手Xilinx DDR3 IP核(1)----MIG IP核的介绍及配置(Native接口)_migip核_孤独的单刀的博客-CSDN博客

MIG IP 核对外分出了两组接口。左侧是用户接口,就是 用户(FPGA)同 MIG 交互的接口,用户只有充分掌握了这些接口才能操作 MIG。右侧为 DDR 物理芯片 接口,负责产生具体的操作时序,并直接操作芯片管脚。这一侧用户只负责分配正确的管脚,其他不用关心。

1.2具体引脚讲解参考Xilinx FPGA平台DDR3设计保姆式教程(3)MIG IP核使用教程及DDR读写时序_ddr3读写时序图_子墨祭的博客-CSDN博客

 DDR写数据信号归类
①前提条件

app_rdy
app_wdf_rdy
app_en
②地址和命令

app_cmd
app_addr
③写数据

app_wdf_wren
app_wdf_data
app_wdf_end
app_wdf_mask  :一般不用,直接置0
        想要写数据到DDR?必须在①前提条件全部为高时,给出②地址和命令(app_cmd = 3’b000),然后给出③写数据的信号,就成功写入数据到DDR了;

        注意:①②时序严格对齐!③相对①②可以提前1拍,或最多延迟2拍,但是最好跟①②对齐,不容易出错。(结合后文时序图更容易理解)
 

1.3需要注意DDR3实验涉及多个不同时钟。(重要)参考(很详细)Xilinx FPGA平台DDR3设计保姆式教程(2)DDR3各时钟频率及带宽分析_ddr3时钟频率_子墨祭的博客-CSDN博客

DDR时钟400M

图上有个4:1,说明MIG 输出到app接口上的时钟ui_clk =  800M/4=200M ,即到时我们在写RTL逻辑代码时操作MIG核时,用的就是这个200M时钟;

input clock period 对应的时钟就是MIG核的系统时钟,由PLL/MMCM输入;对应到例化代码就是:

.sys_clk_i         (sys_clk_i ),    //系统时钟输入

我们配置MIG核时选择多少M时钟,那么这里就要输入多少M

 二、DDR3读写模块

正点原子官方例程中,状态机描述采用了一段式代码,不建议这样使用。

改为三段式状态机,代码如下

 //3段式状态机
always@(posedge ui_clk or negedge rst_n)
    if(!rst_n) current_state<=S0_IDLE;
    else current_state<=next_state;
  
always@(*)begin
  case(current_state)
    S0_IDLE:
        if(init_calib_complete)//初始化完成
            next_state<=S1_WRITE;
        else
            next_state<=S0_IDLE;
    S1_WRITE:
        if(wr_addr_cnt == TEST_LENGTH - 1 )
            next_state<=S2_WAIT;
        else
            next_state<=S1_WRITE;
    S2_WAIT:
            next_state<=S3_READ;
    S3_READ:
        if(rd_addr_cnt == TEST_LENGTH - 1 && app_rdy)
            next_state<=S0_IDLE;
        else
            next_state<=S3_READ;
    default:
            next_state<=S0_IDLE;
   endcase
   end
   
always@(posedge ui_clk or negedge rst_n)begin
    if((!rst_n)||(error_flag)) begin 
         app_wdf_data <= 128'd0;     
         wr_addr_cnt  <= 24'd0;      
         rd_addr_cnt  <= 24'd0;       
         app_addr     <= 28'd0;
    end
    else case(current_state)
            S0_IDLE:begin
                 app_wdf_data <= 256'd0;   
                 wr_addr_cnt  <= 24'd0;     
                 rd_addr_cnt  <= 24'd0;       
                 app_addr     <= 28'd0; 
                    end
           S1_WRITE:begin
                    if(app_rdy && app_wdf_rdy)begin   //写条件满足
                     app_wdf_data <= app_wdf_data + 1;  //写数据自加
                     wr_addr_cnt  <= wr_addr_cnt + 1;   //写地址自加
                     app_addr     <= app_addr + 8;      //DDR3 地址加8
                                            end
                 else begin                             //写条件不满足,保持当前值
                     app_wdf_data <= app_wdf_data;      
                     wr_addr_cnt  <= wr_addr_cnt;
                     app_addr     <= app_addr; 
                     end 
                    end
            S2_WAIT:begin
                    rd_addr_cnt <= 24'd0;                //读地址复位
                    app_addr    <= 28'd0;                //DDR3读从地址0开始
               end
            S3_READ:begin
                 if(app_rdy)begin                  //若MIG已经准备好,则开始读
                     rd_addr_cnt <= rd_addr_cnt + 1'd1; //用户地址每次加一
                     app_addr    <= app_addr + 8;       //DDR3地址加8
                 end
                 else begin                             //若MIG没准备好,则保持原值
                     rd_addr_cnt <= rd_addr_cnt;
                     app_addr    <= app_addr; 
                  end
                 end
             default:begin
                 app_wdf_data <= 256'd0;
                 wr_addr_cnt  <= 24'd0;
                 rd_addr_cnt  <= 24'd0;
                 app_addr     <= 28'd0;
                 end
                 endcase
      end
 

遇到的问题及学习难点:

IP核和ddr3引脚信号太多,刚接触很折磨。

IP核有自己的例化模板,不用自己写。路径:IP SOURCE-IP核-ip_name.veo

不清楚各信号位宽(这点现在还是一知半解)

按照视频完成的工程生成比特流不成功,报错如下图。在xdc文件中添加

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets sys_clk]

[Place 30-575] Sub-optimal placement for a clock-capable IO pin and MMCM pair.   If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING.   However, the use of this override is highly discouraged.   These examples can be used directly in the .xdc file to override this clock rule.
< set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_nets clk_wiz_0_u/inst/clk_in1_clk_wiz_0] >

clk_wiz_0_u/inst/clkin1_ibufg (IBUF.O) is locked to IOB_X1Y74
clk_wiz_0_u/inst/mmcm_adv_inst (MMCME2_ADV.CLKIN1) is provisionally placed by clockplacer on MMCME2_ADV_X1Y2

The above error could possibly be related to other connected instances.   Following is a list of
all the related clock rules and their respective instances.

Clock Rule: rule_mmcm_bufg
Status: PASS
Rule Description: An MMCM driving a BUFG must be placed on the same half side (top/bottom) of the device
clk_wiz_0_u/inst/mmcm_adv_inst (MMCME2_ADV.CLKFBOUT) is provisionally placed by clockplacer on MMCME2_ADV_X1Y2
and clk_wiz_0_u/inst/clkf_buf (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y31

实验仅仅通过LED灯亮灭验证成功与否,不够直观,最好编写testbench观察具体数据波形。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值