[Combat experience] --Xilinx - IPcore - MCB (DDR3) use

1. Background and Introduction

  1) In the new arrangement of the task supervisor, uses a 2G size DDR3 (MT41K128M16JT-107). Intended as before with the same SDRAM write their own initialization, read and write module, but the brothers told me that you can use Xilinx built-in MCB to control, it will be a lot easier, so own the Internet to find some information, and explore a lot, then in the practical application, he wrote this essay.

  2) We look at the MCB internal structure, focus on the two parts User Logic and PHY.

    PHY is an external IO interface, the interface is directly connected and DDR3;

    The corresponding part of the User Logic is the part I need to write a user, it can be seen from the figure: the user simply control CMD and data can be, and CMD here is not complicated, Xilinx will make it very simple, users only need to sends corresponding read, write, write with a refresh, refresh with a reading can be, relatively speaking, is still very simple to use. 

 

 2. Generate the IP core

  1) How to generate IP core is not to say, remember to call Memory Interface Generator on the line directly into the Settings section.

  2) select a compatible platform, according to the needs of the user's own choice, I've no other expansion, therefore no choice.

  3) Select bank area, the user data according to the manual introduction, preference left / lower left side. (Click on the map the user data can be obtained in the lower left area)

  4) Select DDR3 chip model, if not, you can define your own one, but it needs attention is to select a similar chip interface as a template.

  5) define its own chip, the chip is my MT41K128M16JT-107, which represents the 128M16 128Meg * 16, -107 indicates the speed that can be backwards compatible (-125, -15E, -187E) in the datasheet species so choose MT41J128M16XX -125, so something needs to be changed very less.

First attach the chip I used some parameters

    

    

 

I then attach a chip-defined, almost no visible changes.

 6) here without changes, keep the default value.

 7)此处有几种选择,我选择是128bit,既一次写入/读取128bit数据,具体如何设置,可以查看用户手册ug388.pdf。

 8)此处设置终端补偿电阻PIN脚(保持默认或者看自己板上怎么连接的),单时钟输入。

 9)最后一路NEXT到底,点击Generate,一个MCB的IP核就生成了。

10)IP核生成后,我们会在其目录下看见三个文件夹,其中内容如图所示。

11)我们打开user_design文件夹,其中par与rtl最为重要,par中包含UCF文件,这会让我们定义端口容易很多,而rtl则包含设计的.v文件

 

3.使用

  1)将生成的MCB移出(右键--remove),再将uesr_design中rtl下文件手动添加至工程中(右键--add source)。(为的是使用PLL生成的时钟)

  2)修改memc3_infrastructure_inst 中的时钟

      先注释掉这一部分(这是MCB生成时钟的部分)

          将这里的时钟换成sys_clk(原来是sys_clk_ibufg)

  3)接下来我们来了解一下MCB DDR3的接口 

 1 MCB_TEST # (
 2     .C3_P0_MASK_SIZE(16),
 3     .C3_P0_DATA_PORT_SIZE(128),
 4     .DEBUG_EN(0),
 5     .C3_MEMCLK_PERIOD(3000),        //change
 6     .C3_CALIB_SOFT_IP("TRUE"),
 7     .C3_SIMULATION("FALSE"),
 8     .C3_RST_ACT_LOW(0),
 9     .C3_INPUT_CLK_TYPE("SINGLE_ENDED"),
10     .C3_MEM_ADDR_ORDER("ROW_BANK_COLUMN"),
11     .C3_NUM_DQ_PINS(16),
12     .C3_MEM_ADDR_WIDTH(15),
13     .C3_MEM_BANKADDR_WIDTH(3)
14 )
15 u_MCB_MIG (
16    .c3_sys_clk             (clk_ddr3_sys),        //DDR3时钟333MHz对应3000ps 
17    .c3_sys_rst_i           (rst_ddr3_sys),      //复位信号 高有效
18 //物理接口,不用管 
19    .mcb3_dram_dq           (mcb3_dram_dq),      //读写数据 
20    .mcb3_dram_a            (mcb3_dram_a),          //读写地址 
21    .mcb3_dram_ba           (mcb3_dram_ba),        //bank选择 
22    .mcb3_dram_ras_n        (mcb3_dram_ras_n),   //行使能 低有效                   
23    .mcb3_dram_cas_n        (mcb3_dram_cas_n),   //列使能 低有效          
24    .mcb3_dram_we_n         (mcb3_dram_we_n),    //使能 低有效             
25    .mcb3_dram_odt          (mcb3_dram_odt),        //PHYIO 
26    .mcb3_dram_cke          (mcb3_dram_cke),      //PHYIO                        
27    .mcb3_dram_ck           (mcb3_dram_ck),      //PHYIO                        
28    .mcb3_dram_ck_n         (mcb3_dram_ck_n),      //PHYIO     
29    .mcb3_dram_dqs          (mcb3_dram_dqs),     //PHYIO                         
30    .mcb3_dram_dqs_n        (mcb3_dram_dqs_n),    //PHYIO
31    .mcb3_dram_udqs         (mcb3_dram_udqs),    // for X16 parts                        
32    .mcb3_dram_udqs_n       (mcb3_dram_udqs_n),  // for X16 parts
33    .mcb3_dram_udm          (mcb3_dram_udm),     // for X16 parts
34    .mcb3_dram_dm           (mcb3_dram_dm),        //PHYIO
35    .mcb3_dram_reset_n      (mcb3_dram_reset_n),    //PHYIO
36    .c3_clk0                    (c3_clk0),          //PHYIO
37    .c3_rst0                    (c3_rst0),          //PHYIO
38     .c3_calib_done          (c3_calib_done),        //goes High to indicate that calibration has completed
39    .mcb3_rzq               (mcb3_rzq),  
40    .mcb3_zio               (mcb3_zio),
41     
42     //command path signals
43    .c3_p0_cmd_clk          (clk_ddr3),          //用户读写MCB内部FIFO时钟 
44    .c3_p0_cmd_en           (mcb3_cmd_en),       //high signal is the write-enable signal for command fifo
45    .c3_p0_cmd_instr        (mcb3_cmd_instr),    //CMD
46    .c3_p0_cmd_bl           (mcb3_cmd_bl),       //突发长度,大小为0-63,代表1-64的突发长度(即连续读/写多少次) (for example, 6'b00011 is a burst length 4 transaction). The user word width equals the port width (for example, a burst length of 3 on a 64-bit port transfers 3 x 64-bit user words = 192 bits total).
47    .c3_p0_cmd_byte_addr    (mcb3_cmd_byte_addr),//MCB的读写地址,写的时候等于写地址,读的时候等于读地址 
48    .c3_p0_cmd_empty        (mcb3_cmd_empty),    //MCB空 
49    .c3_p0_cmd_full         (mcb3_cmd_full),     //MCB满 
50     //write datapath
51    .c3_p0_wr_clk           (clk_ddr3),          //等于上面的时钟; 
52    .c3_p0_wr_en            (mcb3_wr_en),        //Data is loaded on the rising edge of pX_wr_clk when pX_wr_en = 1 and pX_wr_full = 0.
53    .c3_p0_wr_mask          (mcb3_wr_mask),        //when a mask bit is high, the corresponding bte of data is masked.
54    .c3_p0_wr_data          (mcb3_wr_data),        //write data, size can be 32,64,128 bits, depending on port configuration. 
55    .c3_p0_wr_full          (mcb3_wr_full),
56    .c3_p0_wr_empty         (mcb3_wr_empty),
57    .c3_p0_wr_count         (mcb3_wr_count),        //output indicates how many user words are in the FIFO(0-64)0 means fifo empty 
58    .c3_p0_wr_underrun      (mcb3_wr_underrun),    //indicates there was not enough data in write data fifo to complete the transacion.
59    .c3_p0_wr_error         (mcb3_wr_error),        
60    //read datapath
61     .c3_p0_rd_clk           (clk_ddr3),                
62    .c3_p0_rd_en            (mcb3_rd_en),
63    .c3_p0_rd_data          (mcb3_rd_data),
64    .c3_p0_rd_full          (mcb3_rd_full),
65    .c3_p0_rd_empty         (mcb3_rd_empty),
66    .c3_p0_rd_count         (mcb3_rd_count),
67    .c3_p0_rd_overflow      (mcb3_rd_overflow),
68    .c3_p0_rd_error         (mcb3_rd_error)
69 );
MCB_接口

     总的来说,和用户编写读写程序紧密相关的只有一下接口:

      1*命令相关

        //command path signals

           .c3_p0_cmd_clk          (clk_ddr3),
           .c3_p0_cmd_en           (mcb3_cmd_en),
           .c3_p0_cmd_instr        (mcb3_cmd_instr), 
           .c3_p0_cmd_bl           (mcb3_cmd_bl),   
           .c3_p0_cmd_byte_addr    (mcb3_cmd_byte_addr),
           .c3_p0_cmd_empty        (mcb3_cmd_empty),
           .c3_p0_cmd_full         (mcb3_cmd_full),

          以en、instr、byte_addr为主,当进行读写操作时,这三个要同时变化;
       2*读写相关

        //write datapath
           .c3_p0_wr_clk           (clk_ddr3),  
           .c3_p0_wr_en            (mcb3_wr_en), 
           .c3_p0_wr_mask          (mcb3_wr_mask), 
           .c3_p0_wr_data          (mcb3_wr_data), 
           .c3_p0_wr_full          (mcb3_wr_full),
           .c3_p0_wr_empty         (mcb3_wr_empty),
           .c3_p0_wr_count         (mcb3_wr_count), 
           .c3_p0_wr_underrun      (mcb3_wr_underrun), 
           .c3_p0_wr_error         (mcb3_wr_error),  
         //read datapath
           .c3_p0_rd_clk           (clk_ddr3),    
           .c3_p0_rd_en            (mcb3_rd_en),
           .c3_p0_rd_data          (mcb3_rd_data),
           .c3_p0_rd_full          (mcb3_rd_full),
           .c3_p0_rd_empty         (mcb3_rd_empty),
           .c3_p0_rd_count         (mcb3_rd_count),
           .c3_p0_rd_overflow      (mcb3_rd_overflow),
           .c3_p0_rd_error         (mcb3_rd_error)

          以en、data、full为主;

  4)简单举例:

     1*先说指令

       localparam    MCB_CMD_WR    = 3'b000; //mcb write cmd
       localparam    MCB_CMD_RD    = 3'b001; //mcb read cmd
       localparam    MCB_CMD_WP    = 3'b010; //mcb write with auto precharge cmd
       localparam    MCB_CMD_RP    = 3'b011; //mcb read with auto precharge cmd
       localparam    MCB_CMD_RF    = 3'b100; //mcb refresh cmd

     2*简单举例(以写为例,代码不全,领会思路)

 1 //先将数据存入MCB的FIFO中;
 2     if(cnt_fifo_rd>=7'd64) begin   //write 64 at one time 1KB
 3         cnt_fifo_rd <= cnt_fifo_rd;
 4         ad_fifo_rd_en_r <= 1'b0;    //去读本地fifo中的数据
 5         end
 6     else begin
 7         cnt_fifo_rd <= cnt_fifo_rd + 1'b1;
 8         ad_fifo_rd_en_r <= 1'b1;
 9     end
10 assign mcb3_wr_en = ad_fifo_rd_en_r;  //实际上要延迟一个时钟,这里做演示就不延迟了。
11 assign mcb3_wr_data = ad_fifo_rd_data;  //同时传数据
12 //产生写命令的请求
13     if(!rst_n)
14         u_wr_cmd_en <= 1'b0;
15     else if(u_wr_cmd_done)                //检测到指令发送完成,清除标志信号?
16           u_wr_cmd_en <= 1'b0; //clear 
17     else if(cnt_fifo_rd==7'd63)            //写入63次后产生写命令请求(提前一个产生,等存够64次后刚好产生写请求
18         u_wr_cmd_en <= 1'b1; //enable
19     else
20           u_wr_cmd_en <= u_wr_cmd_en;
21 end
22 //检测到写命令请求,发出写指令
23   if(u_wr_cmd_en) begin //write 
24         mcb3_cmd_instr_r     <= MCB_CMD_WP;
25         mcb3_cmd_byte_addr_r <= u_wr_addr;
26         mcb3_cmd_bl_r      <= mcb3_wr_bl; 
27     mcb3_cmd_wr_p      <= 1'b1;
28     mcb3_cmd_rd_p      <= 1'b0;
29   end
30   assign u_wr_cmd_done0 = mcb3_cmd_en&(mcb3_cmd_instr== MCB_CMD_WP);    // 用户写指令发送完成,产生标志信号
MCB_WR_EXAMPLE

 

 

            

 

 

Guess you like

Origin www.cnblogs.com/yjw951012/p/10998521.html