zoukankan      html  css  js  c++  java
  • 回看《例说FPGA》---DDR2控制器集成与读写测试

    回看《例说FPGA》

                                                                     ---DDR2控制器集成与读写测试

    1.DDR2 IP核的配置

    需要弄清楚的选项主要有:

    PLL reference clock frequency

    Memory clock frequency

    Controller data rate

    对于DDR2 芯片的选型,可以在Memory Presets 里面选择,如果没有符合的器件,可以任意选中一个器件,点击modify parameters 按钮,在 preset Editor 里面进行参数配置。

     2.片上RAM的配置

     

    需要设置的选项有:

    输出数据的位宽

    存储器的深度

    双时钟或单时钟

    双时钟意味着输入输出采用不同的时钟:

    regs/clken/byte enable/aclrs选项卡中,需要设置的是:

    Which ports should be registered?  ‘ q output port’,如果选中,则在输出端加上一个触发器,输出数据时候,就会用clock信号打节拍。如果不选中,则:

     3.数据源产生模块

    实验的整体框图如下图所示:

     

    数据源产生模块实现的功能为:

    每秒定时DDR2数据写入控制;

    每秒定时DDR2数据读出控制;

    将读出的数据写入片上RAM中(RAM IP核在此模块中进行实例化);

    此模块主要用来与DDR2 controller IP核进行通信,首先需要对DDR2 controller的信号多一些了解:

     

     1 module ddr2_contral (
     2     local_address,
     3     local_write_req,
     4     local_read_req,
     5     local_burstbegin,
     6     local_wdata,
     7     local_be,
     8     local_size,
     9     global_reset_n,
    10     pll_ref_clk,
    11     soft_reset_n,
    12     local_ready,
    13     local_rdata,
    14     local_rdata_valid,
    15     local_refresh_ack,
    16     local_init_done,
    17     reset_phy_clk_n,
    18     mem_odt,
    19     mem_cs_n,
    20     mem_cke,
    21     mem_addr,
    22     mem_ba,
    23     mem_ras_n,
    24     mem_cas_n,
    25     mem_we_n,
    26     mem_dm,
    27     phy_clk,
    28     aux_full_rate_clk,
    29     aux_half_rate_clk,
    30     reset_request_n,
    31     mem_clk,
    32     mem_clk_n,
    33     mem_dq,
    34     mem_dqs);
    35 
    36 
    37     input    [22:0]    local_address;
    38     input        local_write_req;
    39     input        local_read_req;
    40     input        local_burstbegin;
    41     input    [63:0]    local_wdata;
    42     input    [7:0]    local_be;
    43     input    [2:0]    local_size;
    44     input        global_reset_n;
    45     input        pll_ref_clk;
    46     input        soft_reset_n;
    47     output        local_ready;
    48     output    [63:0]    local_rdata;
    49     output        local_rdata_valid;
    50     output        local_refresh_ack;
    51     output        local_init_done;
    52     output        reset_phy_clk_n;
    53     output    [0:0]    mem_odt;
    54     output    [0:0]    mem_cs_n;
    55     output    [0:0]    mem_cke;
    56     output    [12:0]    mem_addr;
    57     output    [1:0]    mem_ba;
    58     output        mem_ras_n;
    59     output        mem_cas_n;
    60     output        mem_we_n;
    61     output    [1:0]    mem_dm;
    62     output        phy_clk;
    63     output        aux_full_rate_clk;
    64     output        aux_half_rate_clk;
    65     output        reset_request_n;
    66     inout    [0:0]    mem_clk;
    67     inout    [0:0]    mem_clk_n;
    68     inout    [15:0]    mem_dq;
    69     inout    [1:0]    mem_dqs;

     

    ddr2 controller模块的接口可以分为三类:

    第一类:系统接口,包含系统或PLL的复位,时钟等接口;

    第二类:以local开头的接口,是DDR2 IP核与用户逻辑间的接口;(数据源产生模块主要用到的就是这类接口信号,需要弄懂这些信号的操作时序)

    第三类:以mem开头的接口,是DDR2 IP核与FPGA外部DDR2芯片的接口;(只需要做引脚锁定,编程基本用不到)

    关于使用DDR2 IP核用户外部逻辑操作loca信号的时序图如下:

    在遇到local_ready拉低的读操作,下列信号必须保持到local_ready拉高为止:

    local_read_req;

    local_size;

    local_addr;

    写数据的时候,整个过程中,必须保持local_write_req信号一直有效。

    逻辑代码:

      1 module data_source(
      2             clk,         //75MHz
      3             rst_n,
      4             local_address,
      5             local_write_req,
      6             local_read_req,
      7             local_wdata,
      8             local_ready,
      9             local_rdata,
     10             local_rdata_valid,
     11             local_init_done
     12 );
     13 
     14 // 1/75MHz = 13.33ns;
     15     input        clk;            
     16     input       rst_n;
     17     output   [22:0]local_address;    
     18     output   local_write_req;    
     19     output   local_read_req;        
     20     output    [63:0]local_wdata;    
     21     input        local_ready;         
     22     input       [63:0]local_rdata;    
     23     input        local_rdata_valid;        
     24     input        local_init_done;
     25 
     26 reg[26:0] scnt; 
     27 reg[7:0] times;    
     28 
     29 //计数器,当local_init_done有效时,计数器scnt开始计数
     30 always @(posedge clk or negedge rst_n)
     31     if(!rst_n) scnt <= 27'd0;
     32     else if(local_init_done) scnt <= scnt+1'b1;
     33 
     34 wire timer_wrreq = (scnt == 27'h00_001_000);     //  55us
     35 wire timer_rdreq = (scnt == 27'h00_005_000);     //  273us
     36 
     37 //每当timer_rdreq有效时,计数器times增加1,此模块用来计数读取数据的个数
     38 always @(posedge clk or negedge rst_n)
     39     if(!rst_n) times <= 8'd0;
     40     else if(timer_rdreq) times <= times+1'b1;   
     41 
     42 //状态机
     43 parameter SIDLE = 4'd0;
     44 parameter SWRDB = 4'd1;
     45 parameter SRDDB = 4'd2;
     46 parameter SSTOP = 4'd3;
     47     
     48 reg[3:0] cstate;
     49 reg[8:0] num;
     50 
     51 always @(posedge clk or negedge rst_n)
     52     if(!rst_n) cstate <= SIDLE;
     53     else begin
     54         case(cstate)
     55             SIDLE: begin       //控制状态机的跳转,timer_wrreq有效,则跳转到SWRDB,timer_rdreq有效,则跳转到SRDDB
     56                 if(timer_wrreq) cstate <= SWRDB;
     57                 else if(timer_rdreq) cstate <= SRDDB;
     58                 else cstate <= SIDLE;
     59             end
     60             SWRDB: begin       //如果写入255个数据,并且local_ready有效,则状态结束
     61                 if((num == 9'd255) && local_ready) cstate <= SSTOP;
     62                 else cstate <= SWRDB;
     63             end
     64             SRDDB: begin      ////如果读取255个数据,并且local_ready有效,则状态结束
     65                 if((num == 9'd255) && local_ready) cstate <= SSTOP;
     66                 else cstate <= SRDDB;
     67             end
     68             SSTOP: cstate <= SIDLE;
     69             default: cstate <= SIDLE;
     70         endcase
     71     end
     72 
     73 always @(posedge clk or negedge rst_n)
     74     if(!rst_n) num <= 9'd0;
     75     else if((cstate == SWRDB) || (cstate == SRDDB)) begin     //如果状态处在SWRDB或者是SRDDB时,进入下一个判断阶段
     76         if(local_ready) num <= num+1'b1;                       //如果local_ready有效时,num开始计数
     77         else ;
     78     end
     79     else num <= 9'd0; 
     80 
     81 assign local_address = (cstate == SWRDB) ? {13'h0a55,2'd1,num[7:0]}:{13'h0a55,2'd1,num[7:0]};   //地址采用num这个寄存器来进行地址偏移
     82 assign local_wdata = {times,{num[5:0],2'b00},times,{num[5:0],2'b01},times,{num[5:0],2'b10},times,{num[5:0],2'b11}};        
     83 assign local_write_req = (cstate == SWRDB);        //当状态机处在SWRDB时,发出写请求
     84 assign local_read_req = (cstate == SRDDB);       //当状态机处在SRDDB时,发出读请求
     85                 
     86 reg[7:0] ram_addr;
     87 always @(posedge clk or negedge rst_n)
     88     if(!rst_n) ram_addr <= 8'd0;
     89     else if(timer_rdreq) ram_addr <= 8'd0;      //当timer_rdreq读数请求有效时,ram_addr清零,即读数据请求到来时,ram_addr指向第一个地址
     90     else if(local_rdata_valid) ram_addr <= ram_addr+1'b1;   //当local_rdata_valid信号有效时候,片上ram_addr开始偏移
     91     else ;
     92         
     93 //此ram只写入,不输出
     94 ram_1port u1 (
     95         .address(ram_addr),
     96         .clock(clk),
     97         .data(local_rdata),
     98         .wren(local_rdata_valid),
     99         .q()
    100 );        
    101 
    102 endmodule

    综合结果,RTL图:

  • 相关阅读:
    【转载】关于sql server 代理(已禁用代理xp)
    Silverlight中将WriteableBitmap互转byte数组
    思迅Pay PC ,WIN7 ,KB3042058
    微软新Edge浏览器 WIN7 无法登录
    List<SelectListItem> 转为 SelectList
    图片jpg,png转为BASE64编码
    “Newtonsoft.Json”已拥有为“Microsoft.CSharp”定义的依赖项。
    mac os 10.15.1 懒人 .CDR
    微信刷脸SDK获取sub_openid
    win7 安装 visual studio 2019 时闪退(VS2019)
  • 原文地址:https://www.cnblogs.com/chensimin1990/p/6429235.html
Copyright © 2011-2022 走看看