在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4794|回复: 6

[求助] 求DDR2大神帮助啊! 老是仿真不出来

[复制链接]
发表于 2013-4-25 13:01:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
小弟毕业设计就要做DDR2控制,芯片是sp6,用的ise13.2,以前也只用FPGA做过一些小玩意儿,没有做过DDR2这种复杂控制,所以没经验,总的来说,我就是个菜鸟,到现在还没仿真出基本读写时序,中英文资料也看了好多了,什么ug388,什么什么。。。半懂半不懂的,时间比较紧了,求大神指点我一下,能弄出基本读写就行了。由于时间关系,我就没去仔细读DDR2协议了,直接看的xilinx的MCB控制器文档,目前我知道的,就是操作命令端、用户端的FIFO,至于后面的DDR2接口,肯定是接硬件的,内部时序也由MCB自动完成,我只需要按照MCB的读写时序操作就行了,不知道是不是?
我用的MT开头的RAM,位宽16bit,128M。
在MIG工具里,我用port2做写端(只写),用port3做读端(只读),时间参数就是默认(小弟也不懂啊,没有按照RAM的真实参数设置,不会影响仿真吧?),然后就生成了一个MCB核。
我就用传统观的调用ipcore的方式,写一个“外套”,里面例华一个MCB核,然后把各输入输出接口对应上(下面是代码,不知道对不对,mcb_tst就是我自己起的MCB核名字)

/**************************************************************************************/
module mcb(
   inout  [15:0]                     
mcb3_dram_dq,
   output [13:0]                     
mcb3_dram_a,
   output [2:0]                     
    mcb3_dram_ba,
   output                                           mcb3_dram_ras_n,
   output                                           mcb3_dram_cas_n,
   output                                           mcb3_dram_we_n,
   output                                           mcb3_dram_odt,
   output                                           mcb3_dram_cke,
   output                                           mcb3_dram_dm,
   inout                                            mcb3_dram_udqs,
   inout                                            mcb3_dram_udqs_n,
   inout                                            mcb3_rzq,
   inout                                            mcb3_zio,
   output                                           mcb3_dram_udm,
   input                                            c3_sys_clk,
   input                                            c3_sys_rst_i,
   output                                           c3_calib_done,
   output                                           c3_clk0,
   output                                           c3_rst0,
   inout                                            mcb3_dram_dqs,
   inout                                            mcb3_dram_dqs_n,
   output                                           mcb3_dram_ck,
   output                                           mcb3_dram_ck_n,


      input
c3_p2_cmd_clk,
      input
c3_p2_cmd_en,
      input [2:0]
c3_p2_cmd_instr,
      input [5:0]
c3_p2_cmd_bl,
      input [29:0]
c3_p2_cmd_byte_addr,
      output
c3_p2_cmd_empty,
      output
c3_p2_cmd_full,
      input
c3_p2_wr_clk,
      input
c3_p2_wr_en,
      input [3:0]
c3_p2_wr_mask,
      input [31:0]
c3_p2_wr_data,
      output
c3_p2_wr_full,
      output
c3_p2_wr_empty,
      output [6:0]
c3_p2_wr_count,
      output
c3_p2_wr_underrun,
      output
c3_p2_wr_error,


      input
c3_p3_cmd_clk,
      input
c3_p3_cmd_en,
      input [2:0]
c3_p3_cmd_instr,
      input [5:0]
c3_p3_cmd_bl,
      input [29:0]
c3_p3_cmd_byte_addr,
      output
c3_p3_cmd_empty,
      output
c3_p3_cmd_full,
      input
c3_p3_rd_clk,
      input
c3_p3_rd_en,
      output [31:0]
c3_p3_rd_data,
      output
c3_p3_rd_full,
      output
c3_p3_rd_empty,
      output [6:0]
c3_p3_rd_count,
      output
c3_p3_rd_overflow,
      output
c3_p3_rd_error
);

//例化MCB核:


mcb_tst mcb1(

.mcb3_dram_dq(mcb3_dram_dq),

.mcb3_dram_a(mcb3_dram_a),

.mcb3_dram_ba(mcb3_dram_ba),

.mcb3_dram_ras_n(mcb3_dram_ras_n),

.mcb3_dram_cas_n(mcb3_dram_cas_n),

.mcb3_dram_we_n(mcb3_dram_we_n),

.mcb3_dram_odt(mcb3_dram_odt),

.mcb3_dram_cke(mcb3_dram_cke),

.mcb3_dram_dm(mcb3_dram_dm),

   .mcb3_dram_udqs(mcb3_dram_udqs),

.mcb3_dram_udqs_n(mcb3_dram_udqs_n),

.mcb3_rzq(mcb3_rzq),

.mcb3_zio(mcb3_zio),

.mcb3_dram_udm(mcb3_dram_udm),

.c3_sys_clk(c3_sys_clk),

.c3_sys_rst_i(c3_sys_rst_i),

.c3_calib_done(c3_calib_done),

.c3_clk0(c3_clk0),

.c3_rst0(c3_rst0),

.mcb3_dram_dqs(mcb3_dram_dqs),

   .mcb3_dram_dqs_n(mcb3_dram_dqs_n),

.mcb3_dram_ck(mcb3_dram_ck),

.mcb3_dram_ck_n(mcb3_dram_ck_n),



.c3_p2_cmd_clk(c3_p2_cmd_clk),

.c3_p2_cmd_en(c3_p2_cmd_en),

.c3_p2_cmd_instr(c3_p2_cmd_instr),

.c3_p2_cmd_bl(c3_p2_cmd_bl),

.c3_p2_cmd_byte_addr(c3_p2_cmd_byte_addr),

.c3_p2_cmd_empty(c3_p2_cmd_empty),

.c3_p2_cmd_full(c3_p2_cmd_full),

.c3_p2_wr_clk(c3_p2_wr_clk),

.c3_p2_wr_en(c3_p2_wr_en),

.c3_p2_wr_mask(c3_p2_wr_mask),

.c3_p2_wr_data(c3_p2_wr_data),

.c3_p2_wr_full(c3_p2_wr_full),

.c3_p2_wr_empty(c3_p2_wr_empty),

.c3_p2_wr_count(c3_p2_wr_count),

.c3_p2_wr_underrun(c3_p2_wr_underrun),

.c3_p2_wr_error(c3_p2_wr_error),



.c3_p3_cmd_clk(c3_p3_cmd_clk),

.c3_p3_cmd_en(c3_p3_cmd_en),

.c3_p3_cmd_instr(c3_p3_cmd_instr),

.c3_p3_cmd_bl(c3_p3_cmd_bl),

.c3_p3_cmd_byte_addr(c3_p3_cmd_byte_addr),

.c3_p3_cmd_empty(c3_p3_cmd_empty),

.c3_p3_cmd_full(c3_p3_cmd_full),

.c3_p3_rd_clk(c3_p3_rd_clk),

.c3_p3_rd_en(c3_p3_rd_en),

.c3_p3_rd_data(c3_p3_rd_data),

.c3_p3_rd_full(c3_p3_rd_full),

.c3_p3_rd_empty(c3_p3_rd_empty),

.c3_p3_rd_count(c3_p3_rd_count),

.c3_p3_rd_overflow(c3_p3_rd_overflow),

.c3_p3_rd_error(c3_p3_rd_error)

);

endmodule


/**************************************************************************/
然后就写了个简单的testbench,想写一个32位的数到MCB里去,用ise自带的仿真工具仿真(因为最近更换ise,所以绑一起的modelsim给卸载了,只好暂时用ise自带的仿真工具)

我的testbech思路是这样的:
1、复位
2、向port2的写端fifo写入一个数据(写fifo时钟有效--->准备数据--->写使能)
3、向port2的命令端发送写入命令(命令端fifo时钟有效--->准备地址、突发长度、写入命令--->写命令使能)
下面是testbench代码:

/**************************************************************************/
module rx_tb;


// Inputs

reg c3_sys_clk;

reg c3_sys_rst_i;

reg c3_p2_cmd_clk;

reg c3_p2_cmd_en;

reg [2:0] c3_p2_cmd_instr;

reg [5:0] c3_p2_cmd_bl;

reg [29:0] c3_p2_cmd_byte_addr;

reg c3_p2_wr_clk;

reg c3_p2_wr_en;

reg [3:0] c3_p2_wr_mask;

reg [31:0] c3_p2_wr_data;

reg c3_p3_cmd_clk;

reg c3_p3_cmd_en;

reg [2:0] c3_p3_cmd_instr;

reg [5:0] c3_p3_cmd_bl;

reg [29:0] c3_p3_cmd_byte_addr;

reg c3_p3_rd_clk;

reg c3_p3_rd_en;


// Outputs

wire [13:0] mcb3_dram_a;

wire [2:0] mcb3_dram_ba;

wire mcb3_dram_ras_n;

wire mcb3_dram_cas_n;

wire mcb3_dram_we_n;

wire mcb3_dram_odt;

wire mcb3_dram_cke;

wire mcb3_dram_dm;

wire mcb3_dram_udm;

wire c3_calib_done;

wire c3_clk0;

wire c3_rst0;

wire mcb3_dram_ck;

wire mcb3_dram_ck_n;

wire c3_p2_cmd_empty;

wire c3_p2_cmd_full;

wire c3_p2_wr_full;

wire c3_p2_wr_empty;

wire [6:0] c3_p2_wr_count;

wire c3_p2_wr_underrun;

wire c3_p2_wr_error;

wire c3_p3_cmd_empty;

wire c3_p3_cmd_full;

wire [31:0] c3_p3_rd_data;

wire c3_p3_rd_full;

wire c3_p3_rd_empty;

wire [6:0] c3_p3_rd_count;

wire c3_p3_rd_overflow;

wire c3_p3_rd_error;


// Bidirs

wire [15:0] mcb3_dram_dq;

wire mcb3_dram_udqs;

wire mcb3_dram_udqs_n;

wire mcb3_rzq;

wire mcb3_zio;

wire mcb3_dram_dqs;

wire mcb3_dram_dqs_n;


// Instantiate the Unit Under Test (UUT)

mcb uut (

.mcb3_dram_dq(mcb3_dram_dq),

.mcb3_dram_a(mcb3_dram_a),

.mcb3_dram_ba(mcb3_dram_ba),

.mcb3_dram_ras_n(mcb3_dram_ras_n),

.mcb3_dram_cas_n(mcb3_dram_cas_n),

.mcb3_dram_we_n(mcb3_dram_we_n),

.mcb3_dram_odt(mcb3_dram_odt),

.mcb3_dram_cke(mcb3_dram_cke),

.mcb3_dram_dm(mcb3_dram_dm),

.mcb3_dram_udqs(mcb3_dram_udqs),

.mcb3_dram_udqs_n(mcb3_dram_udqs_n),

.mcb3_rzq(mcb3_rzq),

.mcb3_zio(mcb3_zio),

.mcb3_dram_udm(mcb3_dram_udm),

.c3_sys_clk(c3_sys_clk),

.c3_sys_rst_i(c3_sys_rst_i),

.c3_calib_done(c3_calib_done),

.c3_clk0(c3_clk0),

.c3_rst0(c3_rst0),

.mcb3_dram_dqs(mcb3_dram_dqs),

.mcb3_dram_dqs_n(mcb3_dram_dqs_n),

.mcb3_dram_ck(mcb3_dram_ck),

.mcb3_dram_ck_n(mcb3_dram_ck_n),

.c3_p2_cmd_clk(c3_p2_cmd_clk),

.c3_p2_cmd_en(c3_p2_cmd_en),

.c3_p2_cmd_instr(c3_p2_cmd_instr),

.c3_p2_cmd_bl(c3_p2_cmd_bl),

.c3_p2_cmd_byte_addr(c3_p2_cmd_byte_addr),

.c3_p2_cmd_empty(c3_p2_cmd_empty),

.c3_p2_cmd_full(c3_p2_cmd_full),

.c3_p2_wr_clk(c3_p2_wr_clk),

.c3_p2_wr_en(c3_p2_wr_en),

.c3_p2_wr_mask(c3_p2_wr_mask),

.c3_p2_wr_data(c3_p2_wr_data),

.c3_p2_wr_full(c3_p2_wr_full),

.c3_p2_wr_empty(c3_p2_wr_empty),

.c3_p2_wr_count(c3_p2_wr_count),

.c3_p2_wr_underrun(c3_p2_wr_underrun),

.c3_p2_wr_error(c3_p2_wr_error),

.c3_p3_cmd_clk(c3_p3_cmd_clk),

.c3_p3_cmd_en(c3_p3_cmd_en),

.c3_p3_cmd_instr(c3_p3_cmd_instr),

.c3_p3_cmd_bl(c3_p3_cmd_bl),

.c3_p3_cmd_byte_addr(c3_p3_cmd_byte_addr),

.c3_p3_cmd_empty(c3_p3_cmd_empty),

.c3_p3_cmd_full(c3_p3_cmd_full),

.c3_p3_rd_clk(c3_p3_rd_clk),

.c3_p3_rd_en(c3_p3_rd_en),

.c3_p3_rd_data(c3_p3_rd_data),

.c3_p3_rd_full(c3_p3_rd_full),

.c3_p3_rd_empty(c3_p3_rd_empty),

.c3_p3_rd_count(c3_p3_rd_count),

.c3_p3_rd_overflow(c3_p3_rd_overflow),

.c3_p3_rd_error(c3_p3_rd_error)

);

//testbench的逻辑代码:


initial begin

// Initialize Inputs

c3_sys_clk = 0;

c3_sys_rst_i = 0;

c3_p2_cmd_clk = 0;

c3_p2_cmd_en = 0;

c3_p2_cmd_instr = 0;

c3_p2_cmd_bl = 0;

c3_p2_cmd_byte_addr = 0;

c3_p2_wr_clk = 0;

c3_p2_wr_en = 0;

c3_p2_wr_mask = 0;

c3_p2_wr_data = 0;

c3_p3_cmd_clk = 0;

c3_p3_cmd_en = 0;

c3_p3_cmd_instr = 0;

c3_p3_cmd_bl = 0;

c3_p3_cmd_byte_addr = 0;

c3_p3_rd_clk = 0;

c3_p3_rd_en = 0;


// Wait 100 ns for global reset to finish

forever begin

#1 c3_sys_clk = ~c3_sys_clk;                            //系统时钟,单时钟

c3_p2_wr_clk = ~c3_p2_wr_clk;                 //port2写端fifo时钟

c3_p2_cmd_clk = ~c3_p2_cmd_clk;            //port2命令端fifo时钟

end


// Add stimulus here


end



initial begin

#5 c3_sys_rst_i = 1;

#5 c3_sys_rst_i = 0;                        //复位



#200 c3_p2_wr_data = 32'b10101010101010101010101010101010;         //准备数据
   
#2 c3_p2_wr_en = 1;
                                                                     //使能写端fifo                          

#2 c3_p2_wr_en = 0;
                                          




#5 c3_p2_cmd_byte_addr = 0;                                                          //送地址

c3_p2_cmd_bl = 0;                                                                  //送突发长度0,代表写入32位?
                        c3_p2_cmd_instr = 0;
                                                             //发送写入命令000

#2 c3_p2_cmd_en = 1;                                                                           //使能命令端fifo

#2 c3_p2_cmd_en = 0;



end

endmodule


/*******************************************************************************/


仿真后完全就和ug388上的时序不对啊,而且为什么port2写端fifo的full和empty同时为1 ? 也不知道究竟数据写入了fifo没有,下面给仿真图:
timing.jpg

求大神交我简单的MCB操作步骤吧,我都要崩溃了。。
发表于 2013-4-26 09:32:56 | 显示全部楼层
没用过那个ip,不过看你的描述,似乎FIFO端就是错的。建议先看看FIFO内部的一些时序
发表于 2013-5-1 17:46:37 | 显示全部楼层
还是得多看DDR2的SPEC吧
发表于 2014-3-20 17:13:33 | 显示全部楼层
你好,你用的DDR2是哪个型号的呢?能否把DDR2的仿真文件发给我呢,谢谢啊。
发表于 2014-3-20 21:49:30 | 显示全部楼层
看手册,重点是接口时序,一般不难的~~
发表于 2014-3-21 09:00:56 | 显示全部楼层
首先看自带的仿真程序,看看自带的接口时序,然后照着弄就行了
发表于 2014-8-26 21:23:04 | 显示全部楼层
我最近也在搞,搞不懂。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-9-28 17:35 , Processed in 0.038300 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表