1.背景と紹介
1)タスク・スーパバイザの新しい構成では、2GサイズDDR3(MT41K128M16JT-107)を使用します。同じSDRAMで、その後、モジュールの読み書きを、自分自身の初期設定を書きますが、兄弟はあなたがコントロールする組み込みのMCBザイリンクスを使用することができることを私に言った、それは非常に簡単になるので、いくつかの情報を見つけるためにインターネットを所有し、多くのことを探求する前にとして意図実用的なアプリケーションでは、彼はこのエッセイを書きました。
2)我々は2つの部品ユーザ・ロジックとPHYに焦点を当て、MCB内部構造を見てください。
PHYは、外部IOインターフェースであるインターフェースは、直接接続およびDDR3れます。
ユーザロジックの対応する部分は、私は、ユーザーを作成する必要が一部であり、それが図から見ることができます。ユーザーは単にCMDおよびデータをすることができ制御し、ここでCMDは、ユーザーがのみに必要な、ザイリンクスは、それは非常にシンプルになり、複雑ではありません対応する読み取りを送り、書き込み、リフレッシュして書き込み、読み取りをリフレッシュすることができ、相対的に言っては、まだ使用することは非常に簡単です。
2. IPコアを生成します
1)直接設定]セクションにライン上にメモリインターフェイスジェネレータをコールすることを忘れない、と言うことではないどのようにIPコアを生成することです。
2)利用者自身の選択のニーズに応じて、互換性のあるプラットフォームを選択し、私は他の拡張、したがって、選択の余地をしたん。
3)嗜好が下/左を左、手動導入によると、ユーザデータをバンク領域を選択します。(ユーザデータが左下の領域で得ることができる地図をクリックして)
4)、DDR3チップのモデルを選択していない場合、あなたはあなた自身のものを定義することができますが、それは注意が必要テンプレートとして同様のチップ・インタフェースを選択することです。
5)チップは自分である、独自のチップを画定するようMT41J128M16XXを選択してデータシート種で(-125、-15E、-187E)、16 * MT41K128M16JT-107、128M16 128Megを表す-107は、下位互換性とすることができる速度を示し-125、その何かが非常に少ない変更する必要があります。
まず、私はいくつかのパラメータを使用するチップを取り付け
私はその後、チップに定義され、ほとんど目に見える変化を添付します。
6)ここで変更することなく、デフォルト値を保持します。
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 );
总的来说,和用户编写读写程序紧密相关的只有一下接口:
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); // 用户写指令发送完成,产生标志信号