zoukankan      html  css  js  c++  java
  • ddr3调试经验分享(三)——KC705_MIG_app接口设计

      网上有位大神写了《xilinx平台DDR3设计教程之XX篇》,一共五篇。稍微百度一下就能出来。最后也给出了具体的app接口的控制方式,只是没有code而已。这里做个小笔记,表示自己的实现方案

      ddr3_app_ctrl 是app控制器 

    wdata_in 仅仅是将 16bit的有效数据转换成64bit数据,然后在存入到FIFO中。额,之所以不用16bit位宽进 512位宽出的FIFO,是因为xilinx的FIFO如果设定为512bit出最小输入位宽是64bit。没办法,所以多了这个小模块。

    xilinx_fifo2ddr 当然就是一个fifo了。异步 64bit进 512bit出 ,深度够存自己的东西就好。
    // ********************************************************* 
    ddr3_app_ctrl  ddr3_app_ctrl(
            .clk_in         (~clk), 
            .rst_n          (!sys_rst),
            .v_bling        (v_bling),
    // ----------app interface 
            .app_ini        (init_calib_complete),
            .app_rdy        (app_rdy),
            .app_wdf_rdy    (app_wdf_rdy),
            //output 
            .app_cmd        (app_cmd),
            .app_wdf_mask   (app_wdf_mask),
            .ddr_addr       (app_addr),
            .app_en         (app_en),
            .app_wdf_wren   (app_wdf_wren),
            .app_wdf_end    (app_wdf_end),
    // ----------wr fifo interface    
            .wr_fifo_wcnt   (wr_data_count),
            .wr_ddr_en      (wr_ddr_en)
            );        
    // ****************************************************
    wdata_in      wdata_in(
            .clk         (v_clk),
            .rst_n       (!sys_rst),
            .data_valid  (val_flag), //1:数据有效标志位
            .data_in     (val_data), //有效数据 16bit
                    
            .wr_clk      (wr_clk),
            .wr_en       (wr_en),
            .wr_data     (wr_data)  //64bit
            );    
    // ----------------------------------------------------
    xilinx_fifo2ddr   fifo_data2ddr(
            .rst        (sys_rst),
            .wr_clk     (wr_clk),
            .rd_clk     (clk),
            .din        (wr_data),   //(63 DOWNTO 0);
            .wr_en      (wr_en),   
            .rd_en      (wr_ddr_en),
            
            .dout       (app_wdf_data), //(511 DOWNTO 0);
            .full       (fifo_full),
            .empty      (wr_empty),   
            .rd_data_count() ,   //(5 DOWNTO 0);
            .wr_data_count(wr_data_count)    //(8 DOWNTO 0)
            );    

     2,现在来看看 app控制模块 

    我的实现要求是存一行,读一行。一行1920*16bit个数据,写到FIFO中就有480 个64bit的数据。

    v_bling :我需要这个信号,是想在 bt1120格式 的图像数据在blank期换bank存储。所以在 48~62 之间就是在干这个换bank的事情。但是62行是替换了61行,项目中是运行61行。62行是为了仿真的。

    MIG中输入时钟是差分200M,经过MIG中倍频到800M ,又因为ddr是双沿触发,所以数据传输速率为1600M

      1 `define          FIFO_ADD_CNT     480   // 1920*16/64=480
      2 `define           DDR_ADD_CNT      60    // 1920*2byte/8=60 
      3 // ********************************
      4 module ddr3_app_ctrl (
      5                 clk_in, 
      6                 rst_n,
      7                 v_bling,
      8 // ----------app interface 
      9                 app_ini,
     10                 app_rdy,
     11                 app_wdf_rdy,
     12                 //output 
     13                 app_cmd ,
     14                 app_wdf_mask,
     15                 ddr_addr,
     16                 app_en,
     17                 app_wdf_wren,
     18                 app_wdf_end,
     19 // ----------wr fifo interface    
     20                 wr_fifo_wcnt ,
     21                 wr_ddr_en,
     22 //-----------rd fifo interface
     23 //                rd_fifo_rcnt  
     24                 );
     25 input                 clk_in ,    rst_n ; 
     26 input                 v_bling ; 
     27 // app interface 
     28 input                 app_ini ; 
     29 input                 app_rdy; //read enable  active high
     30 input                  app_wdf_rdy; //write enable  active high
     31 output reg    [2:0]     app_cmd ; //000 write   001 read
     32 output         [63:0]     app_wdf_mask ; 
     33 output reg    [27:0]     ddr_addr ; //rank+bank+row+column=1+3+14+10=28
     34 output reg            app_en   ; //address enable  active high
     35 output reg             app_wdf_wren ;
     36 output                 app_wdf_end ;  //write data enable active high 
     37 // wr fifo interface
     38 input         [8:0]     wr_fifo_wcnt ; 
     39 output                 wr_ddr_en;
     40 // rd fifo interface
     41 // input         [8:0]      rd_fifo_rcnt ; 
     42 // ***************************************************
     43 assign  app_wdf_mask = 64'd0 ; 
     44 assign     app_wdf_end = app_wdf_wren ; 
     45 // ***************************************************
     46 // ddr bank change when v_bling negedge. read ddr must be finish when v
     47 // blank over.
     48 reg                 v_reg ; 
     49 wire                 v_neg ; 
     50 always @(posedge clk_in or negedge rst_n)
     51     if(!rst_n)     v_reg <= 1'd0 ; 
     52     else         v_reg <= v_bling ;
     53 assign v_neg = v_reg&(!v_bling);
     54 // --- generate write bank and read bank --------------
     55 reg [2:0] value;
     56 wire [3:0]        wr_bank ,rd_bank ;
     57 always @(posedge clk_in or negedge rst_n) //must have rst_n signal
     58     if(!rst_n) value <=3'b100;
     59     else if (v_neg) value <= {value[1:0],value[2]};
     60 assign     wr_bank={2'b00,value[1:0]}; //0000  0001  0010  0000
     61 //assign  rd_bank={2'b00,value[2:1]}; //0010  0000  0001  0010
     62 assign  rd_bank={2'b00,value[1:0]}; //0010  0000  0001  0010   //for test
     63 // *****************************************************
     64 reg             wr_ddr3_en,rd_ddr3_en  ;
     65 reg  [20:0]        wr_ddr_addr, rd_ddr_addr; 
     66 wire             rd_ddr_en ; 
     67 wire [27:0]        wr_addr,     rd_addr;
     68 // -----------------------------------
     69 reg [4:0]         ctrl_sta ; 
     70 reg [6:0]         add_cnt ;  
     71 always@(posedge clk_in or negedge rst_n)
     72     if(!rst_n) begin 
     73             rd_ddr3_en     <= 1'd0 ; 
     74             wr_ddr3_en     <= 1'd0 ; 
     75             wr_ddr_addr <= 21'd0 ; 
     76             rd_ddr_addr <= 21'd0 ;
     77             add_cnt     <= 7'd0 ;
     78             ctrl_sta <= 5'd0 ; 
     79             end 
     80     else if(app_wdf_rdy&app_rdy)
     81         case (ctrl_sta) 
     82             4'd0: 
     83                 if (app_ini)begin 
     84                         rd_ddr3_en  <= 1'd0 ; 
     85                         wr_ddr3_en  <= 1'd0 ; 
     86                         wr_ddr_addr <= 21'h1f_ffff ;
     87                         rd_ddr_addr <= 21'h1f_ffff ;                
     88                         add_cnt     <= 7'd0 ;
     89                         ctrl_sta <= ctrl_sta+5'd1 ; 
     90                         end 
     91                 else  begin 
     92                         rd_ddr3_en  <= 1'd0 ; 
     93                         wr_ddr3_en  <= 1'd0 ; 
     94                         wr_ddr_addr <= 21'd0 ; 
     95                         rd_ddr_addr <= 21'd0 ;
     96                         add_cnt     <= 7'd0 ;
     97                         ctrl_sta <=5'd0 ;
     98                         end 
     99             4'd1: //waite for data in FIFO_1 finish
    100                 if(wr_fifo_wcnt==`FIFO_ADD_CNT) begin 
    101                         rd_ddr3_en  <= 1'd0 ;  
    102                         wr_ddr3_en  <= 1'b1; 
    103                         wr_ddr_addr <= wr_ddr_addr + 21'd1 ; 
    104                         //rd_ddr_addr  <= ;   //keep address 
    105                         add_cnt     <= add_cnt + 7'd1 ;                 
    106                         ctrl_sta <= ctrl_sta+5'd1 ;         
    107                         end 
    108                 else begin 
    109                         rd_ddr3_en  <= 1'd0 ; 
    110                         wr_ddr3_en  <= 1'd0 ; 
    111                         add_cnt     <= 7'd0 ; 
    112                         //wr_ddr_addr  <=  ; 
    113                         //rd_ddr_addr  <=  ;
    114                         end 
    115             4'd2: //write ddr 
    116                 if(add_cnt==`DDR_ADD_CNT) begin 
    117                         rd_ddr3_en  <= 1'd0 ;   // 
    118                         wr_ddr3_en  <= 2'd0 ;   
    119                         add_cnt     <= 7'd0 ;          
    120                         //wr_ddr_addr  <= ;     //
    121                         //rd_ddr_addr  <= ;                    
    122                         ctrl_sta <= ctrl_sta+5'd1 ;         
    123                         end 
    124                 else begin 
    125                         rd_ddr3_en  <= 1'd0 ; 
    126                         wr_ddr3_en  <= 1'b1;
    127                         wr_ddr_addr <= wr_ddr_addr + 21'd1 ; 
    128                         //rd_ddr_addr  <=  ;
    129                         add_cnt     <= add_cnt+7'd1 ;                         
    130                         end 
    131             4'd3:  // read ddr3 
    132                 if(add_cnt==`DDR_ADD_CNT) begin 
    133                         rd_ddr3_en  <= 1'd0 ;   
    134                         wr_ddr3_en  <= 2'd0 ;   
    135                         add_cnt     <= 7'd0 ;                     
    136                         //wr_ddr_addr  <=  ;    
    137                         //rd_ddr_addr  <=  ;                            
    138                         ctrl_sta <= ctrl_sta+5'd1 ;         
    139                         end 
    140                 else begin 
    141                         rd_ddr3_en  <= 1'd1 ; 
    142                         wr_ddr3_en  <= 1'b0;
    143                         //wr_ddr_addr  <=  ; 
    144                         rd_ddr_addr <= rd_ddr_addr +21'd1 ;
    145                         add_cnt  <= add_cnt+7'd1 ;                         
    146                         end 
    147             4'd4: //frame change -- bank change 
    148                 if(v_bling) begin  //  
    149                         rd_ddr3_en  <= 1'd0 ; 
    150                         wr_ddr3_en  <= 1'd0;  //1'd1 ; 
    151                         wr_ddr_addr <= 21'h1f_ffff ;    
    152                         rd_ddr_addr <= 21'h1f_ffff ;
    153                         add_cnt     <= 7'd0 ;                             
    154                         ctrl_sta <= 5'd1 ;         
    155                         end 
    156                 else begin 
    157                         rd_ddr3_en  <= 1'd0 ; 
    158                         wr_ddr3_en  <= 1'd0 ; 
    159                         //wr_ddr_addr  <=    //keep address 
    160                         //rd_ddr_addr  <=
    161                         add_cnt     <= 7'd0 ;     
    162                         ctrl_sta <= 5'd1 ;                             
    163                         end 
    164             endcase 
    165 // *******************************************************************    
    166 assign wr_ddr_en =  wr_ddr3_en&app_wdf_rdy&app_rdy ; //read fifo enable &write ddr enable
    167 assign rd_ddr_en =  rd_ddr3_en&app_wdf_rdy&app_rdy ; //read ddr enable 
    168 // ---------------------------------------------                
    169 assign  wr_addr = {wr_bank,wr_ddr_addr,3'b000};    
    170 assign  rd_addr = {rd_bank,rd_ddr_addr,3'b000};    
    171 // ---------------------------------------------    
    172 always @(posedge clk_in or negedge rst_n)
    173     if(!rst_n)    ddr_addr <= 28'd0 ; 
    174     else if (wr_ddr3_en) ddr_addr <= wr_addr; 
    175     else if (rd_ddr3_en) ddr_addr <= rd_addr;         
    176  // -------------------------------------------
    177 always @(posedge clk_in or negedge rst_n)
    178     if(!rst_n) app_en <= 1'd0 ; 
    179     else if ((rd_ddr_en)|(wr_ddr_en))app_en <= 1'd1 ; 
    180     else app_en <= 1'd0 ; 
    181 // ---------------------------------------------
    182 always @(posedge clk_in or negedge rst_n)
    183     if(!rst_n) app_cmd <= 3'b000 ; 
    184     else if(wr_ddr3_en) app_cmd <= 3'b000 ; // wr enable
    185     else if(rd_ddr3_en) app_cmd <= 3'b001 ; //rd enable
    186     else app_cmd <= 3'b100 ; //free
    187 //---------------------------------------------
    188 always @(posedge clk_in or negedge rst_n)
    189     if(!rst_n) app_wdf_wren <= 1'd0 ; 
    190     else if (wr_ddr_en) app_wdf_wren <= 1'd1 ;
    191     else  app_wdf_wren <= 1'd0 ;
    192 
    193 endmodule 

     23行的接口是不需要的,因为对于从ddr读出来的数据也是接一个fifo。到时候把 app_rd_data接到FIFO的数据接口,app_rd_data_valid接到fifo的写使能端口

    欢迎加入: FPGA广东交流群:162664354

          FPGA开发者联盟: 485678884

  • 相关阅读:
    /etc/init.d/functions: No such file or directory报错问题
    在Linux上安装Python3.7.1
    python 使用openpyxl实现读写xlsx文件
    Git 撤销本地修改
    element的el-table表格自定义表头,slot="header"内,数据不更新的问题
    记录下本地修改文件名称大小写问题线上说找不到文件
    解决国内访问github慢的问题笔记
    vue项目中使用echarts实现疫情地图
    uni-app项目搭建
    uniapp引入uni-ui组件报错TypeError: this.getOptions is not a function
  • 原文地址:https://www.cnblogs.com/sepeng/p/6829504.html
Copyright © 2011-2022 走看看