通過上 一節的學習已經能夠實現通過ISE搭建DDR IP CORE並且順利通例程的仿真,那么接下來的這一一節我們就要根據ISE給的Example 來搭建自己所需要的仿真平台。
第一:對ISE給定的Example 要有所了解,包括結構和內容;如圖所示:其中docs 文件中是DDR IPCore的使用手冊和指導文檔;example_design存放的是ISE官方給出的仿真例程,即一個完整的DDR IP的工程,user_design 文件下存放的是與DDR IP 相關的一些文件。這里我們用到的example _design 文件多一些。
第二:開始搭建仿真平台;
(1)將上文提到的example _design 文件拷貝到 一個相對獨立的路徑下面,如下圖所示;
(2)創建ISE工程,把創建的工程路徑放到我們拷貝的example _ design 文件下。然后添加example_design->rtl文件下(包括rtl下子文件里面的所有)的所有.v文件;添加xample_design->par文件下的example_design.ucf 文件;添加example_design->sim->function文件下的(ddr3_model_c3.v仿真模型文件,ddr3_model_pararmeters_c3.v模型參數文件,sim_tb_top文件激勵文件),點擊MODESIM開始仿真
(2)仿真的時候會出現需要把,仿真模型的參數文件拷貝到example_design所在的文件夾下,(就是在色的仿真路徑下),還會出現一些其他錯誤,對應的修改一下就好。仿真過后會出現一些錯誤,當出現TESTpassed時,說明搭建成功。
第三: 接下來就是搭建自己的所DDR工程了
(1)添加ddr_top.v文件。就添加在之前我們建好的USB工程當中,如下圖所示。
(2)在這個ddr_top.v 中對DDR IPcore例化進來,就是加入mig_39_2.xco文件。找到其中的例化模板,復制到ddr_top.v 文件當中。如下圖所示,其中包括ddr對一些參數的設置。
(3)例化DDR中對參數的設置如下;當然這些事工程自己生成的,你也可以更改一些,
1 mig_39_2 # ( 2 .C3_P0_MASK_SIZE(8), 3 .C3_P0_DATA_PORT_SIZE(64), 4 .C3_P1_MASK_SIZE(8), 5 .C3_P1_DATA_PORT_SIZE(64), 6 .DEBUG_EN(0), 7 .C3_MEMCLK_PERIOD(3200),//當前的時鍾周期 8 .C3_CALIB_SOFT_IP("TRUE"), 9 .C3_SIMULATION("TRUE"),//仿真 10 .C3_RST_ACT_LOW(1),//復位信號的配置 11 .C3_INPUT_CLK_TYPE("SINGLE_ENDED"),//時鍾模式 12 .C3_MEM_ADDR_ORDER("BANK_ROW_COLUMN"),//內存讀取的順序模式 13 .C3_NUM_DQ_PINS(16), 14 .C3_MEM_ADDR_WIDTH(13), 15 .C3_MEM_BANKADDR_WIDTH(3) 16 )
DDR的接口介紹;
(c3_calib_done), //全局完成初始化標志,在此信號沒有拉高之前,不能對DDR3進行操作。,從代碼中可以看出,DDR3的端口分成了兩部分,分別是DDR3的芯片接口以及提供給用戶的邏輯操作接口。
1 u_mig_39_2 ( 2 //DDR3 的接口 3 .c3_sys_clk (c3_sys_clk),//input DDR3的參考時鍾 4 .c3_sys_rst_i (c3_sys_rst_i), //input DDR3的復位信號 5 6 .mcb3_dram_dq (mcb3_dram_dq), 7 .mcb3_dram_a (mcb3_dram_a), 8 .mcb3_dram_ba (mcb3_dram_ba), 9 .mcb3_dram_ras_n (mcb3_dram_ras_n), 10 .mcb3_dram_cas_n (mcb3_dram_cas_n), 11 .mcb3_dram_we_n (mcb3_dram_we_n), 12 .mcb3_dram_odt (mcb3_dram_odt), 13 .mcb3_dram_cke (mcb3_dram_cke), 14 .mcb3_dram_ck (mcb3_dram_ck), 15 .mcb3_dram_ck_n (mcb3_dram_ck_n), 16 .mcb3_dram_dqs (mcb3_dram_dqs), 17 .mcb3_dram_dqs_n (mcb3_dram_dqs_n), 18 .mcb3_dram_udqs (mcb3_dram_udqs), // for X16 parts 19 .mcb3_dram_udqs_n (mcb3_dram_udqs_n), // for X16 parts 20 .mcb3_dram_udm (mcb3_dram_udm), // for X16 parts 21 .mcb3_dram_dm (mcb3_dram_dm), 22 .mcb3_dram_reset_n (mcb3_dram_reset_n), 23 24 25 26 27 //sppourt for user 28 .c3_clk0 (c3_clk0),//output 輸出給用戶提供的 29 .c3_rst0 (c3_rst0),//output 輸出給用戶提供的 30 31 32 33 .c3_calib_done (c3_calib_done), //全局完成初始化標志 34 .mcb3_rzq ( mcb3_rzq ), 35 36 .mcb3_zio (mcb3_zio ), 37 38 //P0,p1表示兩個用戶會接口 39 /*********************command path****************************/ 40 .c3_p0_cmd_clk (c3_clk0 ), //命令FIFO的用戶時鍾。 FIFO信號是 在這個時鍾的上升沿捕獲。 41 .c3_p0_cmd_en (p0_cmd_en), //該高電平有效信號是用於寫入的寫入使能信號命令FIFO。 42 .c3_p0_cmd_instr (p0_cmd_instr), //當前指令的命令代碼。 位0表示READ / WRITE選擇,Bit 1為Auto預充電啟用,位2代表刷新總是優先考慮 43 .c3_p0_cmd_bl (p0_cmd_bl), //當前用戶字數的突發長度交易。 突發長度編碼為0到63,代表1到64個用戶詞(例如,6'b00011 是一個突發長度4的交易)。 用戶字寬等於端口寬度(例如,突發長度為3 64位端口傳輸3 x 64位用戶字= 192位 總)。 44 /*當前事務的字節起始地址。地址 45 必須與端口大小對齊: 46 32位端口:低兩位必須為0。 47 64位端口:低三位必須為0。 48 128位端口:低4位必須為0*/ 49 .c3_p0_cmd_byte_addr (p0_cmd_addr), 50 51 .c3_p0_cmd_empty ( ), //這個命令FIFO的高電平有效空標志 52 .c3_p0_cmd_full ( ), //此高電平有效輸出是命令的man標志 53 54 /*********************write cmd****************************/ 55 .c3_p0_wr_clk (c3_clk0 ),//該信號是寫數據FIFO的用戶時鍾 56 /*該高電平有效信號是寫使能 57 用於寫數據FIFO。它表明了 58 pX_wr_data上的值有效 59 加載到FIFO。數據已加載 60 pX_wr_clk的上升沿時 61 pX_wr_en = 1且pX_wr_full = 0。*/ 62 .c3_p0_wr_en (p0_wr_en), 63 .c3_p0_wr_mask (p0_wr_mask),//寫數據的掩碼, 64 /*寫入要寫入的數據值 65 數據FIFO並發送到內存。 PX_SIZE 66 可以是32位,64位或128位,具體取決於 67 端口配置*/ 68 .c3_p0_wr_data (p0_wr_data), 69 .c3_p0_wr_full ( ), //高有效的滿信號 70 .c3_p0_wr_empty ( ),//高有效的空信號 71 /*寫入數據FIFO的計數值。這個 72 輸出表示有多少用戶單詞 73 在FIFO中(從1到64)。計數值為 74 0表示FIFO為空。這個信號 75 延遲的延遲比 76 pX_wr_empty標志。因此,FIFO 77 可能是空的或經歷不足 78 即使計數不為0。*/ 79 .c3_p0_wr_count ( ), 80 .c3_p0_wr_underrun ( ),//高電平有效,欠載標志。 81 .c3_p0_wr_error ( ), 82 /*********************read cmd****************************/ 83 .c3_p0_rd_clk (c3_p0_rd_clk ),//該信號是du數據FIFO的用戶時鍾 84 .c3_p0_rd_en (c3_p0_rd_en ), 85 .c3_p0_rd_data (c3_p0_rd_data ), 86 .c3_p0_rd_full (c3_p0_rd_full ), 87 .c3_p0_rd_empty (c3_p0_rd_empty), 88 .c3_p0_rd_count (c3_p0_rd_count), 89 .c3_p0_rd_overflow (c3_p0_rd_overflow), 90 .c3_p0_rd_error (c3_p0_rd_error ), 91 /********************P1 user port************************/ 92 .c3_p1_cmd_clk (c3_p1_cmd_clk ), 93 .c3_p1_cmd_en (c3_p1_cmd_en ), 94 .c3_p1_cmd_instr (c3_p1_cmd_instr ), 95 .c3_p1_cmd_bl (c3_p1_cmd_bl ), 96 .c3_p1_cmd_byte_addr (c3_p1_cmd_byte_addr), 97 .c3_p1_cmd_empty (c3_p1_cmd_empty ), 98 .c3_p1_cmd_full (c3_p1_cmd_full ), 99 .c3_p1_wr_clk (c3_p1_wr_clk), 100 .c3_p1_wr_en (c3_p1_wr_en), 101 .c3_p1_wr_mask (c3_p1_wr_mask), 102 .c3_p1_wr_data (c3_p1_wr_data), 103 .c3_p1_wr_full (c3_p1_wr_full), 104 .c3_p1_wr_empty (c3_p1_wr_empty), 105 .c3_p1_wr_count (c3_p1_wr_count), 106 .c3_p1_wr_underrun (c3_p1_wr_underrun), 107 .c3_p1_wr_error (c3_p1_wr_error), 108 .c3_p1_rd_clk (c3_p1_rd_clk), 109 .c3_p1_rd_en (c3_p1_rd_en), 110 .c3_p1_rd_data (c3_p1_rd_data), 111 .c3_p1_rd_full (c3_p1_rd_full), 112 .c3_p1_rd_empty (c3_p1_rd_empty), 113 .c3_p1_rd_count (c3_p1_rd_count), 114 .c3_p1_rd_overflow (c3_p1_rd_overflow), 115 .c3_p1_rd_error (c3_p1_rd_error) 116 );
(3)從上文中所提到的Example_design 文件中把DDr所有的頂層接口復制到ddr_top.v文件中:
1 //sysyterm interface 2 input c3_sys_clk , 3 input c3_sys_rst_i , 4 //ddr3 interface 5 inout [15:0] mcb3_dram_dq , 6 output wire [12:0] mcb3_dram_a , 7 output wire [2:0] mcb3_dram_ba , 8 output wire mcb3_dram_ras_n , 9 output wire mcb3_dram_cas_n , 10 output wire mcb3_dram_we_n , 11 output wire mcb3_dram_odt , 12 output wire mcb3_dram_reset_n , 13 output wire mcb3_dram_cke , 14 output wire mcb3_dram_dm , 15 inout mcb3_dram_udqs , 16 inout mcb3_dram_udqs_n , 17 inout mcb3_rzq , 18 inout mcb3_zio , 19 output wire mcb3_dram_udm , 20 inout mcb3_dram_dqs , 21 inout mcb3_dram_dqs_n , 22 output wire mcb3_dram_ck , 23 output wire mcb3_dram_ck_n ,
其中例程中給出的為如下所示:
1 module example_top # 2 ( 3 parameter C3_P0_MASK_SIZE = 8, 4 parameter C3_P0_DATA_PORT_SIZE = 64, 5 parameter C3_P1_MASK_SIZE = 8, 6 parameter C3_P1_DATA_PORT_SIZE = 64, 7 parameter DEBUG_EN = 0, 8 // # = 1, Enable debug signals/controls, 9 // = 0, Disable debug signals/controls. 10 parameter C3_MEMCLK_PERIOD = 3200, 11 // Memory data transfer clock period 12 parameter C3_CALIB_SOFT_IP = "TRUE", 13 // # = TRUE, Enables the soft calibration logic, 14 // # = FALSE, Disables the soft calibration logic. 15 parameter C3_SIMULATION = "FALSE", 16 // # = TRUE, Simulating the design. Useful to reduce the simulation time, 17 // # = FALSE, Implementing the design. 18 parameter C3_HW_TESTING = "FALSE", 19 // Determines the address space accessed by the traffic generator, 20 // # = FALSE, Smaller address space, 21 // # = TRUE, Large address space. 22 parameter C3_RST_ACT_LOW = 0, 23 // # = 1 for active low reset, 24 // # = 0 for active high reset. 25 parameter C3_INPUT_CLK_TYPE = "DIFFERENTIAL", 26 // input clock type DIFFERENTIAL or SINGLE_ENDED 27 parameter C3_MEM_ADDR_ORDER = "BANK_ROW_COLUMN", 28 // The order in which user address is provided to the memory controller, 29 // ROW_BANK_COLUMN or BANK_ROW_COLUMN 30 parameter C3_NUM_DQ_PINS = 16, 31 // External memory data width 32 parameter C3_MEM_ADDR_WIDTH = 13, 33 // External memory address width 34 parameter C3_MEM_BANKADDR_WIDTH = 3 35 // External memory bank address width 36 ) 37 38 ( 39 output calib_done, 40 output error, 41 inout [C3_NUM_DQ_PINS-1:0] mcb3_dram_dq, 42 output [C3_MEM_ADDR_WIDTH-1:0] mcb3_dram_a, 43 output [C3_MEM_BANKADDR_WIDTH-1:0] mcb3_dram_ba, 44 output mcb3_dram_ras_n, 45 output mcb3_dram_cas_n, 46 output mcb3_dram_we_n, 47 output mcb3_dram_odt, 48 output mcb3_dram_reset_n, 49 output mcb3_dram_cke, 50 output mcb3_dram_dm, 51 inout mcb3_dram_udqs, 52 inout mcb3_dram_udqs_n, 53 inout mcb3_rzq, 54 inout mcb3_zio, 55 output mcb3_dram_udm, 56 input c3_sys_clk_p, 57 input c3_sys_clk_n, 58 input c3_sys_rst_i, 59 inout mcb3_dram_dqs, 60 inout mcb3_dram_dqs_n, 61 output mcb3_dram_ck, 62 output mcb3_dram_ck_n 63 );
第四:創建TB激勵文件;主要是根據歷程中來創建的。
`timescale 1ps/1ps module tb_ddr_top ; reg ddr3_ref_clk ; reg ddr3_rst_n ; //bebug signals reg wr_trig ; wire c3_calib_done ; //ddr3 interface wire [15:0] mcb3_dram_dq ; wire [12: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_reset_n ; wire mcb3_dram_cke ; wire mcb3_dram_dm ; wire mcb3_dram_udqs ; wire mcb3_dram_udqs_n ; wire mcb3_rzq ; wire mcb3_zio ; wire mcb3_dram_udm ; wire mcb3_dram_dqs ; wire mcb3_dram_dqs_n ; wire mcb3_dram_ck ; wire mcb3_dram_ck_n ; parameter C3_MEMCLK_PERIOD = 3200; initial begin ddr3_ref_clk = 1; ddr3_rst_n = 0; #20000; ddr3_rst_n = 1; end //produce debug signals initial begin wr_trig <= 0; @(posedge c3_calib_done) #100000 wr_trig <= 1; #25600 wr_trig <= 0; end always #(C3_MEMCLK_PERIOD/2) ddr3_ref_clk = ~ddr3_ref_clk ; ddr_top ddr_top_inst( //sysyterm interface .c3_sys_clk (ddr3_ref_clk ), .c3_sys_rst_i (ddr3_rst_n ), //ddr3 interface .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_reset_n (mcb3_dram_reset_n ), .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 ), .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 ), //debug signals .wr_trig (wr_trig) , .c3_calib_done (c3_calib_done) ); ddr3_model_c3 u_mem_c3( .ck (mcb3_dram_ck), .ck_n (mcb3_dram_ck_n), .cke (mcb3_dram_cke), .cs_n (1'b0), .ras_n (mcb3_dram_ras_n), .cas_n (mcb3_dram_cas_n), .we_n (mcb3_dram_we_n), .dm_tdqs ({mcb3_dram_udm,mcb3_dram_dm}), .ba (mcb3_dram_ba), .addr (mcb3_dram_a), .dq (mcb3_dram_dq), .dqs ({mcb3_dram_udqs,mcb3_dram_dqs}), .dqs_n ({mcb3_dram_udqs_n,mcb3_dram_dqs_n}), .tdqs_n (), .odt (mcb3_dram_odt), .rst_n (mcb3_dram_reset_n) ); // The PULLDOWN component is connected to the ZIO signal primarily to avoid the // unknown state in simulation. In real hardware, ZIO should be a no connect(NC) pin. PULLDOWN zio_pulldown3 (.O(zio3)); PULLDOWN rzq_pulldown3 (.O(rzq3)); endmodule
這樣自己搭建的就好了。有些細節小問題,沒講,不懂得化聯系我吧,一起進步;