Xilinx VIVADO中DDR3 IP核的使用(3)

Zarah ·
更新时间:2024-11-11
· 774 次阅读

VIVADO 中基于mig IP、USB3.0完成图片的上位机显示项目简述项目流程框图模块读写控制时序图DDR3封装模块代码DDR3封装模块测试代码DDR3封装模块测试仿真项目代码项目测试模块代码下板结果总结 项目简述

我们前面的两篇文章已经介绍了VIVADO中MIG IP的调用、用户接口、读写时序,相信大家从前面两篇文章的学习中已经可以掌握MIG的使用。那么为了巩固MIG的使用,我们将介绍一个DDR3的典型应用。
该项目的简述是:
1、FPGA产生图像数据,存储到DDR3中
2、从DDR3中读取数据,经过USB3.0接口发送到上位机,并在上位机显示
本来该实验使用OV5640摄像头的效果最好,但是因为在家,硬件不够,所以实行了该策略
本次实验所用到的软硬件环境,如下:
软件环境:VIVADO2019.1软件、Modelsim10.7仿真环境
硬件环境:米联客MA7035FA(100T)开发板
上位机:米联客自带的USB3.0上位机

项目流程框图

在这里插入图片描述
我们首先将vivado的MIG IP封装成ISE中MIG的形式,系统框图如上图。这样做的原因是,ISE中MIG的操作比较方便,用命令FIFO与数据FIFO,而vivado的MIG用户接口没有那么方便,所以这里我们先将MIG进行进一步的封装。整个项目的流程图如下:
在这里插入图片描述

模块读写控制时序图

上面整个DDR封装包括如下:
在这里插入图片描述
在这里插入图片描述
写DDR3模块的封装图形如下:
在这里插入图片描述
在这里插入图片描述
对应上述写模块的时序图如下:
在这里插入图片描述
读DDR3模块的封装图形如下:
在这里插入图片描述
上述读模块的时序图如下:
在这里插入图片描述
仲裁模块的状态机如下:
在这里插入图片描述
仲裁模块的时序图如下:
在这里插入图片描述

DDR3封装模块代码

我们将vivdado得MIG封装成了4个接口,前两个是写接口,后两个是读接口,代码如下,供大家学习:
ddr3_top模块

`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : nnzhang1996@foxmail.com // Website : // Module Name : ddr3_top.v // Create Time : 2020-02-27 23:16:16 // Editor : sublime text3, tab size (4) // CopyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module ddr3_top( //System Interfaces input rst_n , input locked , input clk_200m , //DDR3 Interfaces output wire [13:0] ddr3_addr , output wire [ 2:0] ddr3_ba , output wire ddr3_cas_n , output wire ddr3_ck_n , output wire ddr3_ck_p , output wire ddr3_cke , output wire ddr3_ras_n , output wire ddr3_reset_n , output wire ddr3_we_n , inout [31:0] ddr3_dq , inout [ 3:0] ddr3_dqs_n , inout [ 3:0] ddr3_dqs_p , output wire [ 0:0] ddr3_cs_n , output wire [ 3:0] ddr3_dm , output wire [ 0:0] ddr3_odt , //User Interfaces input c3_p0_cmd_clk , input c3_p0_cmd_en , input [ 6:0] c3_p0_cmd_bl , input [27:0] c3_p0_cmd_byte_addr , output wire c3_p0_cmd_empty , output wire c3_p0_cmd_full , input c3_p0_wr_clk , input c3_p0_wr_en , input [31:0] c3_p0_wr_mask , input [255:0] c3_p0_wr_data , output wire c3_p0_wr_full , output wire c3_p0_wr_empty , output wire [10:0] c3_p0_wr_count , input c3_p1_cmd_clk , input c3_p1_cmd_en , input [ 6:0] c3_p1_cmd_bl , input [27:0] c3_p1_cmd_byte_addr , output wire c3_p1_cmd_empty , output wire c3_p1_cmd_full , input c3_p1_wr_clk , input c3_p1_wr_en , input [31:0] c3_p1_wr_mask , input [255:0] c3_p1_wr_data , output wire c3_p1_wr_full , output wire c3_p1_wr_empty , output wire [10:0] c3_p1_wr_count , input c3_p2_cmd_clk , input c3_p2_cmd_en , input [ 6:0] c3_p2_cmd_bl , input [27:0] c3_p2_cmd_byte_addr , output wire c3_p2_cmd_empty , output wire c3_p2_cmd_full , input c3_p2_rd_clk , input c3_p2_rd_en , output wire [255:0] c3_p2_rd_data , output wire c3_p2_rd_full , output wire c3_p2_rd_empty , output wire [10:0] c3_p2_rd_count , input c3_p3_cmd_clk , input c3_p3_cmd_en , input [ 6:0] c3_p3_cmd_bl , input [27:0] c3_p3_cmd_byte_addr , output wire c3_p3_cmd_empty , output wire c3_p3_cmd_full , input c3_p3_rd_clk , input c3_p3_rd_en , output wire [255:0] c3_p3_rd_data , output wire c3_p3_rd_full , output wire c3_p3_rd_empty , output wire [10:0] c3_p3_rd_count ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ //mig_7series_0_inst wire init_calib_complete ; wire [27:0] app_addr ; wire [ 2:0] app_cmd ; wire app_en ; wire [255:0] app_wdf_data ; wire app_wdf_end ; wire app_wdf_wren ; wire [255:0] app_rd_data ; wire app_rd_data_end ; wire app_rd_data_valid ; wire app_rdy ; wire app_wdf_rdy ; wire [31:0] app_wdf_mask ; wire ui_clk ; wire ui_clk_sync_rst ; //a7_wr_ctrl_inst1 wire app_en_wr1 ; wire [ 3:0] app_cmd_wr1 ; wire [27:0] app_addr_wr1 ; wire app_wdf_wren_wr1 ; wire [255:0] app_wdf_data_wr1 ; wire [31:0] app_wdf_mask_wr1 ; wire app_wdf_end_wr1 ; wire a7_wr_start_wr1 ; wire [ 6:0] a7_wr_bl_wr1 ; wire [27:0] a7_wr_init_addr_wr1 ; wire [255:0] a7_wr_data_wr1 ; wire [31:0] a7_wr_mask_wr1 ; wire a7_wr_end_wr1 ; wire a7_wr_req_wr1 ; //a7_wr_ctrl_inst2 wire app_en_wr2 ; wire [ 3:0] app_cmd_wr2 ; wire [27:0] app_addr_wr2 ; wire app_wdf_wren_wr2 ; wire [255:0] app_wdf_data_wr2 ; wire [31:0] app_wdf_mask_wr2 ; wire app_wdf_end_wr2 ; wire a7_wr_start_wr2 ; wire [ 6:0] a7_wr_bl_wr2 ; wire [27:0] a7_wr_init_addr_wr2 ; wire [255:0] a7_wr_data_wr2 ; wire [31:0] a7_wr_mask_wr2 ; wire a7_wr_end_wr2 ; wire a7_wr_req_wr2 ; //a7_rd_ctrl_inst1 wire app_en_rd1 ; wire [ 3:0] app_cmd_rd1 ; wire [27:0] app_addr_rd1 ; wire app_rd_data_valid_rd1 ; wire a7_rd_start_rd1 ; wire [ 6:0] a7_rd_bl_rd1 ; wire [27:0] a7_rd_init_addr_rd1 ; wire [255:0] a7_rd_data_rd1 ; wire a7_rd_data_valid_rd1 ; wire a7_rd_end_rd1 ; //a7_rd_ctrl_inst2 wire app_en_rd2 ; wire [ 3:0] app_cmd_rd2 ; wire [27:0] app_addr_rd2 ; wire app_rd_data_valid_rd2 ; wire a7_rd_start_rd2 ; wire [ 6:0] a7_rd_bl_rd2 ; wire [27:0] a7_rd_init_addr_rd2 ; wire [255:0] a7_rd_data_rd2 ; wire a7_rd_data_valid_rd2 ; wire a7_rd_end_rd2 ; //arbit_inst //wire c3_p0_cmd_empty ; //wire c3_p1_cmd_empty ; //wire c3_p2_cmd_empty ; //wire c3_p3_cmd_empty ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ mig_7series_0 mig_7series_0_inst ( // Memory interface ports .ddr3_addr (ddr3_addr ), // output [13:0] ddr3_addr .ddr3_ba (ddr3_ba ), // output [2:0] ddr3_ba .ddr3_cas_n (ddr3_cas_n ), // output ddr3_cas_n .ddr3_ck_n (ddr3_ck_n ), // output [0:0] ddr3_ck_n .ddr3_ck_p (ddr3_ck_p ), // output [0:0] ddr3_ck_p .ddr3_cke (ddr3_cke ), // output [0:0] ddr3_cke .ddr3_ras_n (ddr3_ras_n ), // output ddr3_ras_n .ddr3_reset_n (ddr3_reset_n ), // output ddr3_reset_n .ddr3_we_n (ddr3_we_n ), // output ddr3_we_n .ddr3_dq (ddr3_dq ), // inout [31:0] ddr3_dq .ddr3_dqs_n (ddr3_dqs_n ), // inout [3:0] ddr3_dqs_n .ddr3_dqs_p (ddr3_dqs_p ), // inout [3:0] ddr3_dqs_p .init_calib_complete (init_calib_complete ), // output init_calib_complete .ddr3_cs_n (ddr3_cs_n ), // output [0:0] ddr3_cs_n .ddr3_dm (ddr3_dm ), // output [3:0] ddr3_dm .ddr3_odt (ddr3_odt ), // output [0:0] ddr3_odt // Application interface ports .app_addr (app_addr ), // input [27:0] app_addr .app_cmd (app_cmd ), // input [2:0] app_cmd .app_en (app_en ), // input app_en .app_wdf_data (app_wdf_data ), // input [255:0] app_wdf_data .app_wdf_end (app_wdf_end ), // input app_wdf_end .app_wdf_wren (app_wdf_wren ), // input app_wdf_wren .app_rd_data (app_rd_data ), // output [255:0] app_rd_data .app_rd_data_end (app_rd_data_end ), // output app_rd_data_end .app_rd_data_valid (app_rd_data_valid ), // output app_rd_data_valid .app_rdy (app_rdy ), // output app_rdy .app_wdf_rdy (app_wdf_rdy ), // output app_wdf_rdy .app_sr_req (1'b0 ), // input app_sr_req .app_ref_req (1'b0 ), // input app_ref_req .app_zq_req (1'b0 ), // input app_zq_req .app_sr_active ( ), // output app_sr_active .app_ref_ack ( ), // output app_ref_ack .app_zq_ack ( ), // output app_zq_ack .ui_clk (ui_clk ), // output ui_clk .ui_clk_sync_rst (ui_clk_sync_rst ), // output ui_clk_sync_rst .app_wdf_mask (app_wdf_mask ), // input [31:0] app_wdf_mask // System Clock Ports .sys_clk_i (clk_200m ), .sys_rst (locked ) // input sys_rst ); arbit arbit_inst( //System Interfaces .rst_n (init_calib_complete ), //DDR3 Interfaces .ui_clk (ui_clk ), .app_addr (app_addr ), .app_cmd (app_cmd ), .app_en (app_en ), .app_wdf_data (app_wdf_data ), .app_wdf_end (app_wdf_end ), .app_wdf_wren (app_wdf_wren ), .app_rd_data_valid (app_rd_data_valid ), .app_wdf_mask (app_wdf_mask ), //a7_wr_ctrl_inst1 .app_en_wr1 (app_en_wr1 ), .app_cmd_wr1 (app_cmd_wr1 ), .app_addr_wr1 (app_addr_wr1 ), .app_wdf_wren_wr1 (app_wdf_wren_wr1 ), .app_wdf_data_wr1 (app_wdf_data_wr1 ), .app_wdf_mask_wr1 (app_wdf_mask_wr1 ), .app_wdf_end_wr1 (app_wdf_end_wr1 ), .a7_wr_start_w1 (a7_wr_start_wr1 ), .a7_wr_end_wr1 (a7_wr_end_wr1 ), .c3_p0_cmd_empty (c3_p0_cmd_empty ), //a7_wr_ctrl_inst1 .app_en_wr2 (app_en_wr2 ), .app_cmd_wr2 (app_cmd_wr2 ), .app_addr_wr2 (app_addr_wr2 ), .app_wdf_wren_wr2 (app_wdf_wren_wr2 ), .app_wdf_data_wr2 (app_wdf_data_wr2 ), .app_wdf_mask_wr2 (app_wdf_mask_wr2 ), .app_wdf_end_wr2 (app_wdf_end_wr2 ), .a7_wr_start_w2 (a7_wr_start_wr2 ), .a7_wr_end_wr2 (a7_wr_end_wr2 ), .c3_p1_cmd_empty (c3_p1_cmd_empty ), //a7_rd_ctrl_inst1 .app_en_rd1 (app_en_rd1 ), .app_cmd_rd1 (app_cmd_rd1 ), .app_addr_rd1 (app_addr_rd1 ), .app_rd_data_valid_rd1 (app_rd_data_valid_rd1 ), .a7_rd_start_rd1 (a7_rd_start_rd1 ), .a7_rd_end_rd1 (a7_rd_end_rd1 ), .c3_p2_cmd_empty (c3_p2_cmd_empty ), //a7_rd_ctrl_inst2 .app_en_rd2 (app_en_rd2 ), .app_cmd_rd2 (app_cmd_rd2 ), .app_addr_rd2 (app_addr_rd2 ), .app_rd_data_valid_rd2 (app_rd_data_valid_rd2 ), .a7_rd_start_rd2 (a7_rd_start_rd2 ), .a7_rd_end_rd2 (a7_rd_end_rd2 ), .c3_p3_cmd_empty (c3_p3_cmd_empty ) ); a7_wr_ctrl a7_wr_ctrl_inst1( //System Interfaces .rst_n (init_calib_complete ), //DDR3 Interfaces .ui_clk (ui_clk ), .app_rdy (app_rdy ), .app_wdf_rdy (app_wdf_rdy ), .app_en (app_en_wr1 ), .app_cmd (app_cmd_wr1 ), .app_addr (app_addr_wr1 ), .app_wdf_wren (app_wdf_wren_wr1 ), .app_wdf_data (app_wdf_data_wr1 ), .app_wdf_mask (app_wdf_mask_wr1 ), .app_wdf_end (app_wdf_end_wr1 ), //Communication Interfaces .a7_wr_start (a7_wr_start_wr1 ), .a7_wr_bl (a7_wr_bl_wr1 ), .a7_wr_init_addr (a7_wr_init_addr_wr1 ), .a7_wr_data (a7_wr_data_wr1 ), .a7_wr_mask (a7_wr_mask_wr1 ), .a7_wr_end (a7_wr_end_wr1 ), .a7_wr_req (a7_wr_req_wr1 ) ); fifo_generator_0 cmd_wr1_fifo ( .rst (~init_calib_complete ), // input wire rst .wr_clk (c3_p0_cmd_clk ), // input wire wr_clk .rd_clk (ui_clk ), // input wire rd_clk .din ({c3_p0_cmd_bl,c3_p0_cmd_byte_addr}), // input wire [38 : 0] din .wr_en (c3_p0_cmd_en ), // input wire wr_en .rd_en (a7_wr_start_wr1 ), // input wire rd_en .dout ({a7_wr_bl_wr1,a7_wr_init_addr_wr1}), // output wire [38 : 0] dout .full (c3_p0_cmd_full ), // output wire full .empty (c3_p0_cmd_empty ) ); fifo_generator_1 data_wr1_fifo ( .rst (~init_calib_complete ), // input wire rst .wr_clk (c3_p0_wr_clk ), // input wire wr_clk .rd_clk (ui_clk ), // input wire rd_clk .din ({c3_p0_wr_mask,c3_p0_wr_data} ), // input wire [287 : 0] din .wr_en (c3_p0_wr_en ), // input wire wr_en .rd_en (a7_wr_req_wr1 ), // input wire rd_en .dout ({a7_wr_mask_wr1,a7_wr_data_wr1}), // output wire [287 : 0] dout .full (c3_p0_wr_full ), // output wire full .empty (c3_p0_wr_empty ), // output wire empty .wr_data_count (c3_p0_wr_count ) // output wire [10 : 0] wr_data_count ); a7_wr_ctrl a7_wr_ctrl_inst2( //System Interfaces .rst_n (init_calib_complete ), //DDR3 Interfaces .ui_clk (ui_clk ), .app_rdy (app_rdy ), .app_wdf_rdy (app_wdf_rdy ), .app_en (app_en_wr2 ), .app_cmd (app_cmd_wr2 ), .app_addr (app_addr_wr2 ), .app_wdf_wren (app_wdf_wren_wr2 ), .app_wdf_data (app_wdf_data_wr2 ), .app_wdf_mask (app_wdf_mask_wr2 ), .app_wdf_end (app_wdf_end_wr2 ), //Communication Interfaces .a7_wr_start (a7_wr_start_wr2 ), .a7_wr_bl (a7_wr_bl_wr2 ), .a7_wr_init_addr (a7_wr_init_addr_wr2 ), .a7_wr_data (a7_wr_data_wr2 ), .a7_wr_mask (a7_wr_mask_wr2 ), .a7_wr_end (a7_wr_end_wr2 ), .a7_wr_req (a7_wr_req_wr2 ) ); fifo_generator_0 cmd_wr2_fifo ( .rst (~init_calib_complete ), // input wire rst .wr_clk (c3_p1_cmd_clk ), // input wire wr_clk .rd_clk (ui_clk ), // input wire rd_clk .din ({c3_p1_cmd_bl,c3_p1_cmd_byte_addr}), // input wire [38 : 0] din .wr_en (c3_p1_cmd_en ), // input wire wr_en .rd_en (a7_wr_start_wr2 ), // input wire rd_en .dout ({a7_wr_bl_wr2,a7_wr_init_addr_wr2}), // output wire [38 : 0] dout .full (c3_p1_cmd_full ), // output wire full .empty (c3_p1_cmd_empty ) ); fifo_generator_1 data_wr2_fifo ( .rst (~init_calib_complete ), // input wire rst .wr_clk (c3_p1_wr_clk ), // input wire wr_clk .rd_clk (ui_clk ), // input wire rd_clk .din ({c3_p1_wr_mask,c3_p1_wr_data} ), // input wire [287 : 0] din .wr_en (c3_p1_wr_en ), // input wire wr_en .rd_en (a7_wr_req_wr2 ), // input wire rd_en .dout ({a7_wr_mask_wr2,a7_wr_data_wr2}), // output wire [287 : 0] dout .full (c3_p1_wr_full ), // output wire full .empty (c3_p1_wr_empty ), // output wire empty .wr_data_count (c3_p1_wr_count ) // output wire [10 : 0] wr_data_count ); a7_rd_ctrl a7_rd_ctrl_inst1( //System Interfaces .rst_n (init_calib_complete ), //DDR3 Interfaces .ui_clk (ui_clk ), .app_en (app_en_rd1 ), .app_cmd (app_cmd_rd1 ), .app_addr (app_addr_rd1 ), .app_rd_data (app_rd_data ), .app_rd_data_valid (app_rd_data_valid_rd1 ), .app_rdy (app_rdy ), //Communication Interfaces .a7_rd_start (a7_rd_start_rd1 ), .a7_rd_bl (a7_rd_bl_rd1 ), .a7_rd_init_addr (a7_rd_init_addr_rd1 ), .a7_rd_data (a7_rd_data_rd1 ), .a7_rd_data_valid (a7_rd_data_valid_rd1 ), .a7_rd_end (a7_rd_end_rd1 ) ); fifo_generator_0 cmd_rd1_fifo ( .rst (~init_calib_complete ), // input wire rst .wr_clk (c3_p2_cmd_clk ), // input wire wr_clk .rd_clk (ui_clk ), // input wire rd_clk .din ({c3_p2_cmd_bl,c3_p2_cmd_byte_addr}), // input wire [38 : 0] din .wr_en (c3_p2_cmd_en ), // input wire wr_en .rd_en (a7_rd_start_rd1 ), // input wire rd_en .dout ({a7_rd_bl_rd1,a7_rd_init_addr_rd1}), // output wire [38 : 0] dout .full (c3_p2_cmd_full ), // output wire full .empty (c3_p2_cmd_empty ) ); fifo_generator_2 data_rd1_fifo ( .rst (~init_calib_complete ), // input wire rst .wr_clk (ui_clk ), // input wire wr_clk .rd_clk (c3_p2_rd_clk ), // input wire rd_clk .din (a7_rd_data_rd1 ), // input wire [255 : 0] din .wr_en (a7_rd_data_valid_rd1 ), // input wire wr_en .rd_en (c3_p2_rd_en ), // input wire rd_en .dout (c3_p2_rd_data ), // output wire [255 : 0] dout .full (c3_p2_rd_full ), // output wire full .empty (c3_p2_rd_empty ), // output wire empty .rd_data_count (c3_p2_rd_count ) // output wire [10 : 0] rd_data_count ); a7_rd_ctrl a7_rd_ctrl_inst2( //System Interfaces .rst_n (init_calib_complete ), //DDR3 Interfaces .ui_clk (ui_clk ), .app_en (app_en_rd2 ), .app_cmd (app_cmd_rd2 ), .app_addr (app_addr_rd2 ), .app_rd_data (app_rd_data ), .app_rd_data_valid (app_rd_data_valid_rd2 ), .app_rdy (app_rdy ), //Communication Interfaces .a7_rd_start (a7_rd_start_rd2 ), .a7_rd_bl (a7_rd_bl_rd2 ), .a7_rd_init_addr (a7_rd_init_addr_rd2 ), .a7_rd_data (a7_rd_data_rd2 ), .a7_rd_data_valid (a7_rd_data_valid_rd2 ), .a7_rd_end (a7_rd_end_rd2 ) ); fifo_generator_0 cmd_rd2_fifo ( .rst (~init_calib_complete ), // input wire rst .wr_clk (c3_p3_cmd_clk ), // input wire wr_clk .rd_clk (ui_clk ), // input wire rd_clk .din ({c3_p3_cmd_bl,c3_p3_cmd_byte_addr}), // input wire [38 : 0] din .wr_en (c3_p3_cmd_en ), // input wire wr_en .rd_en (a7_rd_start_rd2 ), // input wire rd_en .dout ({a7_rd_bl_rd2,a7_rd_init_addr_rd2}), // output wire [38 : 0] dout .full (c3_p3_cmd_full ), // output wire full .empty (c3_p3_cmd_empty ) ); fifo_generator_2 data_rd2_fifo ( .rst (~init_calib_complete ), // input wire rst .wr_clk (ui_clk ), // input wire wr_clk .rd_clk (c3_p3_rd_clk ), // input wire rd_clk .din (a7_rd_data_rd2 ), // input wire [255 : 0] din .wr_en (a7_rd_data_valid_rd2 ), // input wire wr_en .rd_en (c3_p3_rd_en ), // input wire rd_en .dout (c3_p3_rd_data ), // output wire [255 : 0] dout .full (c3_p3_rd_full ), // output wire full .empty (c3_p3_rd_empty ), // output wire empty .rd_data_count (c3_p3_rd_count ) // output wire [10 : 0] rd_data_count ); endmodule

a7_wr_ctrl模块:

`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : nnzhang1996@foxmail.com // Website : // Module Name : a7_wr_ctrl.v // Create Time : 2020-02-29 22:19:50 // Editor : sublime text3, tab size (4) // CopyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module a7_wr_ctrl( //System Interfaces input rst_n , //DDR3 Interfaces input ui_clk , input app_rdy , input app_wdf_rdy , output wire app_en , output wire [ 3:0] app_cmd , output reg [27:0] app_addr , output wire app_wdf_wren , output wire [255:0] app_wdf_data , output wire [31:0] app_wdf_mask , output wire app_wdf_end , //Communication Interfaces input a7_wr_start , input [ 6:0] a7_wr_bl , input [27:0] a7_wr_init_addr , input [255:0] a7_wr_data , input [31:0] a7_wr_mask , output reg a7_wr_end , output wire a7_wr_req ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ reg [ 6:0] wr_bl ; reg wr_flag ; reg [ 6:0] bl_cnt ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ assign app_en = wr_flag && app_rdy && app_wdf_rdy; assign app_wdf_end = app_en; assign app_wdf_wren = app_en; assign app_wdf_data = a7_wr_data; assign a7_wr_req = app_en; assign app_wdf_mask = a7_wr_mask; assign app_cmd = 3'd0; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) wr_flag <= 1'b0; else if(bl_cnt == wr_bl && app_en == 1'b1) wr_flag <= 1'b0; else if(a7_wr_start == 1'b1) wr_flag <= 1'b1; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) wr_bl <= 7'd0; else if(a7_wr_start == 1'b1) wr_bl <= a7_wr_bl; else wr_bl <= wr_bl; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) app_addr <= 28'd0; else if(a7_wr_start == 1'b1) app_addr <= a7_wr_init_addr; else if(app_en == 1'b1) app_addr <= app_addr + 8; else app_addr <= app_addr; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) bl_cnt <= 7'd0; else if(bl_cnt == wr_bl && app_en == 1'b1 && wr_flag == 1'b1) bl_cnt <= 7'd0; else if(wr_flag == 1'b1 && app_en == 1'b1) bl_cnt <= bl_cnt + 1'b1; else bl_cnt <= bl_cnt; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) a7_wr_end <= 1'b0; else if(bl_cnt == wr_bl && app_en == 1'b1) a7_wr_end <= 1'b1; else a7_wr_end <= 1'b0; endmodule

a7_rd_ctrl模块:

`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : nnzhang1996@foxmail.com // Website : // Module Name : a7_rd_ctrl.v // Create Time : 2020-03-01 14:32:05 // Editor : sublime text3, tab size (4) // CopyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module a7_rd_ctrl( //System Interfaces input rst_n , //DDR3 Interfaces input ui_clk , output reg app_en , output wire [ 3:0] app_cmd , output reg [27:0] app_addr , input [255:0] app_rd_data , input app_rd_data_valid , input app_rdy , //Communication Interfaces input a7_rd_start , input [ 6:0] a7_rd_bl , input [27:0] a7_rd_init_addr , output reg [255:0] a7_rd_data , output reg a7_rd_data_valid , output reg a7_rd_end ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ reg [ 6:0] rd_bl ; reg [ 6:0] cmd_cnt ; reg rd_flag ; reg [ 6:0] data_cnt ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ assign app_cmd = 3'd1; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) rd_bl <= 7'd0; else if(a7_rd_start == 1'b1) rd_bl <= a7_rd_bl; else rd_bl <= a7_rd_bl; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) app_en <= 1'b0; else if(a7_rd_start == 1'b1) app_en <= 1'b1; else if(cmd_cnt == rd_bl && app_rdy == 1'b1) app_en <= 1'b0; else app_en <= app_en; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) cmd_cnt <= 7'd0; else if(rd_flag == 1'b1 && cmd_cnt == rd_bl && app_rdy == 1'b1) cmd_cnt <= 7'd0; else if(rd_flag == 1'b1 && app_rdy == 1'b1 && app_en == 1'b1) cmd_cnt <= cmd_cnt + 1'b1; else cmd_cnt <= cmd_cnt; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) rd_flag <= 1'b0; else if(a7_rd_start == 1'b1) rd_flag <= 1'b1; else if(data_cnt == rd_bl && app_rd_data_valid == 1'b1) rd_flag <= 1'b0; else rd_flag <= rd_flag; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) app_addr <= 28'd0; else if(a7_rd_start == 1'b1) app_addr <= a7_rd_init_addr; else if(rd_flag == 1'b1 && app_rdy == 1'b1) app_addr <= app_addr + 8; else app_addr <= app_addr; always @(posedge ui_clk) a7_rd_data <= app_rd_data; always @(posedge ui_clk) a7_rd_data_valid <= app_rd_data_valid; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) a7_rd_end <= 1'b0; else if(data_cnt == rd_bl && app_rd_data_valid == 1'b1) a7_rd_end <= 1'b1; else a7_rd_end <= 1'b0; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) data_cnt <= 7'd0; else if(data_cnt == rd_bl && rd_flag == 1'b1 && app_rd_data_valid == 1'b1) data_cnt <= 7'd0; else if(rd_flag == 1'b1 && app_rd_data_valid == 1'b1) data_cnt <= data_cnt + 1'b1; else data_cnt <= data_cnt; endmodule

arbit模块:

`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2020/03/01 15:17:14 // Design Name: // Module Name: arbit // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module arbit( //System Interfaces input rst_n , //DDR3 Interfaces input ui_clk , output reg [27:0] app_addr , output reg [ 2:0] app_cmd , output reg app_en , output reg [255:0] app_wdf_data , output reg app_wdf_end , output reg app_wdf_wren , input app_rd_data_valid , output reg [31:0] app_wdf_mask , //a7_wr_ctrl_inst1 input app_en_wr1 , input [ 3:0] app_cmd_wr1 , input [27:0] app_addr_wr1 , input app_wdf_wren_wr1 , input [255:0] app_wdf_data_wr1 , input [31:0] app_wdf_mask_wr1 , input app_wdf_end_wr1 , output reg a7_wr_start_w1 , input a7_wr_end_wr1 , input c3_p0_cmd_empty , //a7_wr_ctrl_inst1 input app_en_wr2 , input [ 3:0] app_cmd_wr2 , input [27:0] app_addr_wr2 , input app_wdf_wren_wr2 , input [255:0] app_wdf_data_wr2 , input [31:0] app_wdf_mask_wr2 , input app_wdf_end_wr2 , output reg a7_wr_start_w2 , input a7_wr_end_wr2 , input c3_p1_cmd_empty , //a7_rd_ctrl_inst1 input app_en_rd1 , input [ 3:0] app_cmd_rd1 , input [27:0] app_addr_rd1 , output reg app_rd_data_valid_rd1 , output reg a7_rd_start_rd1 , input a7_rd_end_rd1 , input c3_p2_cmd_empty , //a7_rd_ctrl_inst2 input app_en_rd2 , input [ 3:0] app_cmd_rd2 , input [27:0] app_addr_rd2 , output reg app_rd_data_valid_rd2 , output reg a7_rd_start_rd2 , input a7_rd_end_rd2 , input c3_p3_cmd_empty ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ parameter IDLE = 6'b000001 ; parameter ARBIT = 6'b000010 ; parameter WR1 = 6'b000100 ; parameter WR2 = 6'b001000 ; parameter RD1 = 6'b010000 ; parameter RD2 = 6'b100000 ; reg [ 5:0] state ; reg [ 2:0] rand_cnt ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) rand_cnt <= 3'd0; else if(rand_cnt == 3'd3) rand_cnt <= 3'd0; else rand_cnt <= rand_cnt + 1'b1; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) state <= IDLE; else case(state) IDLE : state <= ARBIT; ARBIT : if(c3_p0_cmd_empty == 1'b0 && rand_cnt == 3'd0) state <= WR1; else if(c3_p1_cmd_empty == 1'b0 && rand_cnt == 3'd1) state <= WR2; else if(c3_p2_cmd_empty == 1'b0 && rand_cnt == 3'd2) state <= RD1; else if(c3_p3_cmd_empty == 1'b0 && rand_cnt == 3'd3) state <= RD2; else state <= state; WR1 : if(a7_wr_end_wr1 == 1'b1) state <= ARBIT; else state <= state; WR2 : if(a7_wr_end_wr2 == 1'b1) state <= ARBIT; else state <= state; RD1 : if(a7_rd_end_rd1 == 1'b1) state <= ARBIT; else state <= state; RD2 : if(a7_rd_end_rd2 == 1'b1) state <= ARBIT; else state <= state; default : state <= IDLE; endcase always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) a7_wr_start_w1 <= 1'b0; else if(state == ARBIT && c3_p0_cmd_empty == 1'b0 && rand_cnt == 3'd0) a7_wr_start_w1 <= 1'b1; else a7_wr_start_w1 <= 1'b0; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) a7_wr_start_w2 <= 1'b0; else if(state == ARBIT && c3_p1_cmd_empty == 1'b0 && rand_cnt == 3'd1) a7_wr_start_w2 <= 1'b1; else a7_wr_start_w2 <= 1'b0; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) a7_rd_start_rd1 <= 1'b0; else if(state == ARBIT && c3_p2_cmd_empty == 1'b0 && rand_cnt == 3'd2) a7_rd_start_rd1 <= 1'b1; else a7_rd_start_rd1 <= 1'b0; always @(posedge ui_clk or negedge rst_n) if(rst_n == 1'b0) a7_rd_start_rd2 <= 1'b0; else if(state == ARBIT && c3_p3_cmd_empty == 1'b0 && rand_cnt == 3'd3) a7_rd_start_rd2 <= 1'b1; else a7_rd_start_rd2 <= 1'b0; always @(*) case(state) WR1 : begin app_addr = app_addr_wr1; app_cmd = app_cmd_wr1; app_en = app_en_wr1; app_wdf_data = app_wdf_data_wr1; app_wdf_end = app_wdf_end_wr1; app_wdf_wren = app_wdf_wren_wr1; app_wdf_mask = app_wdf_mask_wr1; end WR2 : begin app_addr = app_addr_wr2; app_cmd = app_cmd_wr2; app_en = app_en_wr2; app_wdf_data = app_wdf_data_wr2; app_wdf_end = app_wdf_end_wr2; app_wdf_wren = app_wdf_wren_wr2; app_wdf_mask = app_wdf_mask_wr2; end RD1 : begin app_addr = app_addr_rd1; app_cmd = app_cmd_rd1; app_en = app_en_rd1; app_rd_data_valid_rd1 = app_rd_data_valid; end RD2 : begin app_addr = app_addr_rd2; app_cmd = app_cmd_rd2; app_en = app_en_rd2; app_rd_data_valid_rd2 = app_rd_data_valid; end default : begin app_addr = 28'd0; app_cmd = 3'd0; app_en = 1'b0; app_wdf_data = 256'd0; app_wdf_end = 1'b0; app_wdf_wren = 1'b0; app_rd_data_valid_rd1 = 1'b0; app_rd_data_valid_rd2 = 1'b0; app_wdf_mask = 32'd0; end endcase endmodule

从上面得代码中,我们便把vivado得MIG封装成了双读双写得ISE中的MIG接口。

DDR3封装模块测试代码

top模块:

`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : nnzhang1996@foxmail.com // Website : // Module Name : top.v // Create Time : 2020-03-01 20:33:42 // Editor : sublime text3, tab size (4) // CopyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module top( //System Interfaces input sclk , input rst_n , //DDR3 Interfaces output wire [13:0] ddr3_addr , output wire [ 2:0] ddr3_ba , output wire ddr3_cas_n , output wire ddr3_ck_n , output wire ddr3_ck_p , output wire ddr3_cke , output wire ddr3_ras_n , output wire ddr3_reset_n , output wire ddr3_we_n , inout [31:0] ddr3_dq , inout [ 3:0] ddr3_dqs_n , inout [ 3:0] ddr3_dqs_p , output wire [ 0:0] ddr3_cs_n , output wire [ 3:0] ddr3_dm , output wire [ 0:0] ddr3_odt , //Debug input test_trig ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ //clk_wiz_0_inst wire clk_200m ; wire locked ; wire clk_100m ; //ddr3_drive_inst wire c3_p0_cmd_clk ; wire c3_p0_cmd_en ; wire [ 2:0] c3_p0_cmd_instr ; wire [27:0] c3_p0_cmd_byte_addr ; wire [ 6:0] c3_p0_cmd_bl ; wire c3_p0_wr_clk ; wire c3_p0_wr_en ; wire [31:0] c3_p0_wr_mask ; wire [255:0] c3_p0_wr_data ; wire [ 6:0] c3_p0_wr_count ; wire c3_p1_cmd_clk ; wire c3_p1_cmd_en ; wire [ 2:0] c3_p1_cmd_instr ; wire [27:0] c3_p1_cmd_byte_addr ; wire [ 6:0] c3_p1_cmd_bl ; wire c3_p1_rd_clk ; wire c3_p1_rd_en ; wire [255:0] c3_p1_rd_data ; wire [ 6:0] c3_p1_rd_count ; wire [20:0] err_cnt ; wire err_done ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ clk_wiz_0 clk_wiz_0_inst( // Clock out ports .clk_out1 (clk_200m ), // output clk_out1 .clk_out2 (clk_100m ), // Status and control signals .reset (~rst_n ), // input reset .locked (locked ), // output locked // Clock in ports .clk_in1 (sclk ) ); // input clk_in1 ddr3_top ddr3_top_inst( //System Interfaces .rst_n (rst_n ), .locked (locked ), .clk_200m (clk_200m ), //DDR3 Interfaces .ddr3_addr (ddr3_addr ), .ddr3_ba (ddr3_ba ), .ddr3_cas_n (ddr3_cas_n ), .ddr3_ck_n (ddr3_ck_n ), .ddr3_ck_p (ddr3_ck_p ), .ddr3_cke (ddr3_cke ), .ddr3_ras_n (ddr3_ras_n ), .ddr3_reset_n (ddr3_reset_n ), .ddr3_we_n (ddr3_we_n ), .ddr3_dq (ddr3_dq ), .ddr3_dqs_n (ddr3_dqs_n ), .ddr3_dqs_p (ddr3_dqs_p ), .ddr3_cs_n (ddr3_cs_n ), .ddr3_dm (ddr3_dm ), .ddr3_odt (ddr3_odt ), //User Interfaces .c3_p0_cmd_clk (c3_p0_cmd_clk ), .c3_p0_cmd_en (c3_p0_cmd_en ), .c3_p0_cmd_bl (c3_p0_cmd_bl ), .c3_p0_cmd_byte_addr (c3_p0_cmd_byte_addr ), .c3_p0_cmd_empty ( ), .c3_p0_cmd_full ( ), .c3_p0_wr_clk (c3_p0_wr_clk ), .c3_p0_wr_en (c3_p0_wr_en ), .c3_p0_wr_mask (c3_p0_wr_mask ), .c3_p0_wr_data (c3_p0_wr_data ), .c3_p0_wr_full ( ), .c3_p0_wr_empty ( ), .c3_p0_wr_count (c3_p0_wr_count ), .c3_p1_cmd_clk ('d0 ), .c3_p1_cmd_en ('d0 ), .c3_p1_cmd_bl ('d0 ), .c3_p1_cmd_byte_addr ('d0 ), .c3_p1_cmd_empty ( ), .c3_p1_cmd_full ( ), .c3_p1_wr_clk ('d0 ), .c3_p1_wr_en ('d0 ), .c3_p1_wr_mask ('d0 ), .c3_p1_wr_data ('d0 ), .c3_p1_wr_full ( ), .c3_p1_wr_empty ( ), .c3_p1_wr_count ( ), .c3_p2_cmd_clk (c3_p1_cmd_clk ), .c3_p2_cmd_en (c3_p1_cmd_en ), .c3_p2_cmd_bl (c3_p1_cmd_bl ), .c3_p2_cmd_byte_addr (c3_p1_cmd_byte_addr ), .c3_p2_cmd_empty ( ), .c3_p2_cmd_full ( ), .c3_p2_rd_clk (c3_p1_rd_clk ), .c3_p2_rd_en (c3_p1_rd_en ), .c3_p2_rd_data (c3_p1_rd_data ), .c3_p2_rd_full ( ), .c3_p2_rd_empty ( ), .c3_p2_rd_count (c3_p1_rd_count ), .c3_p3_cmd_clk ('d0 ), .c3_p3_cmd_en ('d0 ), .c3_p3_cmd_bl ('d0 ), .c3_p3_cmd_byte_addr ('d0 ), .c3_p3_cmd_empty ( ), .c3_p3_cmd_full ( ), .c3_p3_rd_clk ('d0 ), .c3_p3_rd_en ('d0 ), .c3_p3_rd_data ( ), .c3_p3_rd_full ( ), .c3_p3_rd_empty ( ), .c3_p3_rd_count ( ) ); ddr3_drive ddr3_drive_inst( //System Interfaces .sclk (clk_100m ), .rst_n (locked ), //DDR3 Interfaces .c3_p0_cmd_clk (c3_p0_cmd_clk ), .c3_p0_cmd_en (c3_p0_cmd_en ), .c3_p0_cmd_instr (c3_p0_cmd_instr ), .c3_p0_cmd_byte_addr (c3_p0_cmd_byte_addr ), .c3_p0_cmd_bl (c3_p0_cmd_bl ), .c3_p0_wr_clk (c3_p0_wr_clk ), .c3_p0_wr_en (c3_p0_wr_en ), .c3_p0_wr_mask (c3_p0_wr_mask ), .c3_p0_wr_data (c3_p0_wr_data ), .c3_p0_wr_count (c3_p0_wr_count ), .c3_p1_cmd_clk (c3_p1_cmd_clk ), .c3_p1_cmd_en (c3_p1_cmd_en ), .c3_p1_cmd_instr (c3_p1_cmd_instr ), .c3_p1_cmd_byte_addr (c3_p1_cmd_byte_addr ), .c3_p1_cmd_bl (c3_p1_cmd_bl ), .c3_p1_rd_clk (c3_p1_rd_clk ), .c3_p1_rd_en (c3_p1_rd_en ), .c3_p1_rd_data (c3_p1_rd_data ), .c3_p1_rd_count (c3_p1_rd_count ), //Debug .test_trig (test_trig ), .err_cnt (err_cnt ), .err_done (err_done ) ); endmodule

ddr3_drive模块:

`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : nnzhang1996@foxmail.com // Website : // Module Name : ddr3_drive.v // Create Time : 2020-02-22 11:41:08 // Editor : sublime text3, tab size (4) // CopyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module ddr3_drive( //System Interfaces input sclk , input rst_n , //DDR3 Interfaces output c3_p0_cmd_clk , output wire c3_p0_cmd_en , output wire [ 2:0] c3_p0_cmd_instr , output reg [27:0] c3_p0_cmd_byte_addr , output wire [ 6:0] c3_p0_cmd_bl , output c3_p0_wr_clk , output reg c3_p0_wr_en , output wire [31:0] c3_p0_wr_mask , output reg [255:0] c3_p0_wr_data , input [ 6:0] c3_p0_wr_count , output c3_p1_cmd_clk , output reg c3_p1_cmd_en , output wire [ 2:0] c3_p1_cmd_instr , output reg [27:0] c3_p1_cmd_byte_addr , output wire [ 6:0] c3_p1_cmd_bl , output c3_p1_rd_clk , output reg c3_p1_rd_en , input [255:0] c3_p1_rd_data , input [ 6:0] c3_p1_rd_count , //Debug input test_trig , output reg [20:0] err_cnt , output reg err_done ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ //parameter BURST_NUM = 1048576 ; parameter BURST_NUM = 100 ; parameter BURST_LENFTH = 7'd15 ; reg flag_done ; reg test_trig_r ; reg [ 3:0] wr_cnt ; reg c3_p0_wr_en_r ; reg c3_p1_rd_en_r ; wire c3_p1_rd_en_nege ; reg [20:0] burst



ip核 ddr3 vivado ddr xilinx ip

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章