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

posted on 2017-05-12 16:59  清霜一梦  阅读(4648)  评论(5编辑  收藏  举报