黑金核心板32bitDDR3 MIG核UI接口仿真模型搭建
图2-4-1为黑金开发板上两片DDR3原理图。
1. 搭建仿真模型时需要例化两个ddr3_model,不然仿真时init_calib_complete信号会一直低。
2.还要考虑信号的延时,需要例化WireDelay模块,如Xilinx官方中给的例程中所示,不然app_rd_data数据一直是红色的。
3.自己顶层模块中例化的MIG核中的app_wdf_mask信号一定要给32‘d0,不然读出的app_rd_data数据一直是乱的。
下面贴出test_bench顶层代码
`timescale 1ps/100fs
module tb_ddr3_rw_top();//***************************************************************************// Traffic Gen related parameters//***************************************************************************parameter SIMULATION = "TRUE";parameter PORT_MODE = "BI_MODE";parameter DATA_MODE = 4'b0010;parameter TST_MEM_INSTR_MODE = "R_W_INSTR_MODE";parameter EYE_TEST = "FALSE";parameter DATA_PATTERN = "DGEN_ALL";parameter CMD_PATTERN = "CGEN_ALL";parameter BEGIN_ADDRESS = 32'h00000000;parameter END_ADDRESS = 32'h00000fff;parameter PRBS_EADDR_MASK_POS = 32'hff000000;parameter COL_WIDTH = 10;parameter CS_WIDTH = 1;parameter DM_WIDTH = 4;parameter DQ_WIDTH = 32;parameter DQS_WIDTH = 4;parameter DQS_CNT_WIDTH = 2;parameter DRAM_WIDTH = 8;parameter ECC = "OFF";parameter RANKS = 1;parameter ODT_WIDTH = 1;parameter ROW_WIDTH = 15;parameter ADDR_WIDTH = 29;//***************************************************************************// The following parameters are mode register settings//***************************************************************************parameter BURST_MODE = "8";parameter CA_MIRROR = "OFF";parameter CLKIN_PERIOD = 5000;parameter SIM_BYPASS_INIT_CAL = "FAST";parameter TCQ = 100;parameter RST_ACT_LOW = 1;parameter REFCLK_FREQ = 200.0;parameter tCK = 2500;parameter nCK_PER_CLK = 4;parameter DEBUG_PORT = "OFF";parameter DRAM_TYPE = "DDR3";localparam real TPROP_DQS = 0.00;localparam real TPROP_DQS_RD = 0.00;localparam real TPROP_PCB_CTRL = 0.00;localparam real TPROP_PCB_DATA = 0.00;localparam real TPROP_PCB_DATA_RD = 0.00;localparam MEMORY_WIDTH = 16;localparam NUM_COMP = DQ_WIDTH/MEMORY_WIDTH;localparam ECC_TEST = "OFF" ;localparam ERR_INSERT = (ECC_TEST == "ON") ? "OFF" : ECC ;localparam real REFCLK_PERIOD = (1000000.0/(2*REFCLK_FREQ));localparam RESET_PERIOD = 200000;localparam real SYSCLK_PERIOD = tCK;reg sys_rst_n;wire sys_rst;reg sys_clk_i;wire sys_clk_i_n;reg clk_ref_i;wire ddr3_reset_n;wire [DQ_WIDTH-1:0] ddr3_dq_fpga;wire [DQS_WIDTH-1:0] ddr3_dqs_p_fpga;wire [DQS_WIDTH-1:0] ddr3_dqs_n_fpga;wire [ROW_WIDTH-1:0] ddr3_addr_fpga;wire [3-1:0] ddr3_ba_fpga;wire ddr3_ras_n_fpga;wire ddr3_cas_n_fpga;wire ddr3_we_n_fpga;wire [1-1:0] ddr3_cke_fpga;wire [1-1:0] ddr3_ck_p_fpga;wire [1-1:0] ddr3_ck_n_fpga;wire init_calib_complete;wire tg_compare_error;wire [(CS_WIDTH*1)-1:0] ddr3_cs_n_fpga;wire [DM_WIDTH-1:0] ddr3_dm_fpga;wire [ODT_WIDTH-1:0] ddr3_odt_fpga;reg [(CS_WIDTH*1)-1:0] ddr3_cs_n_sdram_tmp;reg [DM_WIDTH-1:0] ddr3_dm_sdram_tmp;reg [ODT_WIDTH-1:0] ddr3_odt_sdram_tmp;wire [DQ_WIDTH-1:0] ddr3_dq_sdram;reg [ROW_WIDTH-1:0] ddr3_addr_sdram [0:1];reg [3-1:0] ddr3_ba_sdram [0:1];reg ddr3_ras_n_sdram;reg ddr3_cas_n_sdram;reg ddr3_we_n_sdram;wire [(CS_WIDTH*1)-1:0] ddr3_cs_n_sdram;wire [ODT_WIDTH-1:0] ddr3_odt_sdram;reg [1-1:0] ddr3_cke_sdram;wire [DM_WIDTH-1:0] ddr3_dm_sdram;wire [DQS_WIDTH-1:0] ddr3_dqs_p_sdram;wire [DQS_WIDTH-1:0] ddr3_dqs_n_sdram;reg [1-1:0] ddr3_ck_p_sdram;reg [1-1:0] ddr3_ck_n_sdram;//**************************************************************************//// Reset Generation//**************************************************************************//initial beginsys_rst_n = 1'b0;#RESET_PERIODsys_rst_n = 1'b1;endassign sys_rst = RST_ACT_LOW ? sys_rst_n : ~sys_rst_n;//**************************************************************************//// Clock Generation//**************************************************************************//initialsys_clk_i = 1'b0;alwayssys_clk_i = #(CLKIN_PERIOD/2.0) ~sys_clk_i;assign sys_clk_i_n = ~sys_clk_i;initialclk_ref_i = 1'b0;alwaysclk_ref_i = #REFCLK_PERIOD ~clk_ref_i;always @( * ) beginddr3_ck_p_sdram <= #(TPROP_PCB_CTRL) ddr3_ck_p_fpga;ddr3_ck_n_sdram <= #(TPROP_PCB_CTRL) ddr3_ck_n_fpga;ddr3_addr_sdram[0] <= #(TPROP_PCB_CTRL) ddr3_addr_fpga;ddr3_addr_sdram[1] <= #(TPROP_PCB_CTRL) (CA_MIRROR == "ON") ?{ddr3_addr_fpga[ROW_WIDTH-1:9],ddr3_addr_fpga[7], ddr3_addr_fpga[8],ddr3_addr_fpga[5], ddr3_addr_fpga[6],ddr3_addr_fpga[3], ddr3_addr_fpga[4],ddr3_addr_fpga[2:0]} :ddr3_addr_fpga;ddr3_ba_sdram[0] <= #(TPROP_PCB_CTRL) ddr3_ba_fpga;ddr3_ba_sdram[1] <= #(TPROP_PCB_CTRL) (CA_MIRROR == "ON") ?{ddr3_ba_fpga[3-1:2],ddr3_ba_fpga[0],ddr3_ba_fpga[1]} :ddr3_ba_fpga;ddr3_ras_n_sdram <= #(TPROP_PCB_CTRL) ddr3_ras_n_fpga;ddr3_cas_n_sdram <= #(TPROP_PCB_CTRL) ddr3_cas_n_fpga;ddr3_we_n_sdram <= #(TPROP_PCB_CTRL) ddr3_we_n_fpga;ddr3_cke_sdram <= #(TPROP_PCB_CTRL) ddr3_cke_fpga;endalways @( * )ddr3_cs_n_sdram_tmp <= #(TPROP_PCB_CTRL) ddr3_cs_n_fpga;assign ddr3_cs_n_sdram = ddr3_cs_n_sdram_tmp;always @( * )ddr3_dm_sdram_tmp <= #(TPROP_PCB_DATA) ddr3_dm_fpga;//DM signal generationassign ddr3_dm_sdram = ddr3_dm_sdram_tmp;always @( * )ddr3_odt_sdram_tmp <= #(TPROP_PCB_CTRL) ddr3_odt_fpga;assign ddr3_odt_sdram = ddr3_odt_sdram_tmp;// Controlling the bi-directional BUSgenvar dqwd;generatefor (dqwd = 1;dqwd < DQ_WIDTH;dqwd = dqwd+1) begin : dq_delayWireDelay #(.Delay_g (TPROP_PCB_DATA),.Delay_rd (TPROP_PCB_DATA_RD),.ERR_INSERT ("OFF"))u_delay_dq(.A (ddr3_dq_fpga[dqwd]),.B (ddr3_dq_sdram[dqwd]),.reset (sys_rst_n),.phy_init_done (init_calib_complete));endWireDelay #(.Delay_g (TPROP_PCB_DATA),.Delay_rd (TPROP_PCB_DATA_RD),.ERR_INSERT ("OFF"))u_delay_dq_0(.A (ddr3_dq_fpga[0]),.B (ddr3_dq_sdram[0]),.reset (sys_rst_n),.phy_init_done (init_calib_complete));endgenerategenvar dqswd;generatefor (dqswd = 0;dqswd < DQS_WIDTH;dqswd = dqswd+1) begin : dqs_delayWireDelay #(.Delay_g (TPROP_DQS),.Delay_rd (TPROP_DQS_RD),.ERR_INSERT ("OFF"))u_delay_dqs_p(.A (ddr3_dqs_p_fpga[dqswd]),.B (ddr3_dqs_p_sdram[dqswd]),.reset (sys_rst_n),.phy_init_done (init_calib_complete));WireDelay #(.Delay_g (TPROP_DQS),.Delay_rd (TPROP_DQS_RD),.ERR_INSERT ("OFF"))u_delay_dqs_n(.A (ddr3_dqs_n_fpga[dqswd]),.B (ddr3_dqs_n_sdram[dqswd]),.reset (sys_rst_n),.phy_init_done (init_calib_complete));endendgenerate//============================< 被测试模块例化 >===============================
//例化DDR3读写测试-------------------
ddr3_rw_top ddr3_rw_top_inst(.ddr3_dq (ddr3_dq_fpga ), //DDR3 数据.ddr3_dqs_n (ddr3_dqs_n_fpga ), //DDR3 dqs负.ddr3_dqs_p (ddr3_dqs_p_fpga ), //DDR3 dqs正 .ddr3_addr (ddr3_addr_fpga ), //DDR3 地址.ddr3_ba (ddr3_ba_fpga ), //DDR3 banck 选择.ddr3_ras_n (ddr3_ras_n_fpga ), //DDR3 行选择.ddr3_cas_n (ddr3_cas_n_fpga ), //DDR3 列选择.ddr3_we_n (ddr3_we_n_fpga ), //DDR3 读写选择.ddr3_reset_n (ddr3_reset_n ), //DDR3 复位.ddr3_ck_p (ddr3_ck_p_fpga ), //DDR3 时钟正.ddr3_ck_n (ddr3_ck_n_fpga ), //DDR3 时钟负.ddr3_cke (ddr3_cke_fpga ), //DDR3 时钟使能.ddr3_cs_n (ddr3_cs_n_fpga ), //DDR3 片选.ddr3_dm (ddr3_dm_fpga ), //DDR3_dm.ddr3_odt (ddr3_odt_fpga ), //DDR3_odt.sys_clk_p (sys_clk_i ), //system clock positive on board.sys_clk_n (sys_clk_i_n ), //system clock negative on board.rst_n (sys_rst ), //reset ,low active.error_flag (tg_compare_error ) //错误标志
); //**************************************************************************//// Memory Models instantiations//**************************************************************************////**************************************************************************//// Memory Models instantiations//**************************************************************************//genvar r,i;generatefor (r = 0; r < CS_WIDTH; r = r + 1) begin: mem_rnkif(DQ_WIDTH/16) begin: memfor (i = 0; i < NUM_COMP; i = i + 1) begin: gen_memddr3_model u_comp_ddr3(.rst_n (ddr3_reset_n),.ck (ddr3_ck_p_sdram),.ck_n (ddr3_ck_n_sdram),.cke (ddr3_cke_sdram[r]),.cs_n (ddr3_cs_n_sdram[r]),.ras_n (ddr3_ras_n_sdram),.cas_n (ddr3_cas_n_sdram),.we_n (ddr3_we_n_sdram),.dm_tdqs (ddr3_dm_sdram[(2*(i+1)-1):(2*i)]),.ba (ddr3_ba_sdram[r]),.addr (ddr3_addr_sdram[r]),.dq (ddr3_dq_sdram[16*(i+1)-1:16*(i)]),.dqs (ddr3_dqs_p_sdram[(2*(i+1)-1):(2*i)]),.dqs_n (ddr3_dqs_n_sdram[(2*(i+1)-1):(2*i)]),.tdqs_n (),.odt (ddr3_odt_sdram[r]));endendif (DQ_WIDTH%16) begin: gen_mem_extrabitsddr3_model u_comp_ddr3(.rst_n (ddr3_reset_n),.ck (ddr3_ck_p_sdram),.ck_n (ddr3_ck_n_sdram),.cke (ddr3_cke_sdram[r]),.cs_n (ddr3_cs_n_sdram[r]),.ras_n (ddr3_ras_n_sdram),.cas_n (ddr3_cas_n_sdram),.we_n (ddr3_we_n_sdram),.dm_tdqs ({ddr3_dm_sdram[DM_WIDTH-1],ddr3_dm_sdram[DM_WIDTH-1]}),.ba (ddr3_ba_sdram[r]),.addr (ddr3_addr_sdram[r]),.dq ({ddr3_dq_sdram[DQ_WIDTH-1:(DQ_WIDTH-8)],ddr3_dq_sdram[DQ_WIDTH-1:(DQ_WIDTH-8)]}),.dqs ({ddr3_dqs_p_sdram[DQS_WIDTH-1],ddr3_dqs_p_sdram[DQS_WIDTH-1]}),.dqs_n ({ddr3_dqs_n_sdram[DQS_WIDTH-1],ddr3_dqs_n_sdram[DQS_WIDTH-1]}),.tdqs_n (),.odt (ddr3_odt_sdram[r]));endendendgenerateendmodule
ddr3_rw_top.v(借用他人的demo)
`timescale 1ns / 1psmodule ddr3_rw_top(
// Inouts
inout [31:0] ddr3_dq, //ddr3 data
inout [3:0] ddr3_dqs_n, //ddr3 dqs negative
inout [3:0] ddr3_dqs_p, //ddr3 dqs positive
// Outputs
output [14:0] ddr3_addr, //ddr3 address
output [2:0] ddr3_ba, //ddr3 bank
output ddr3_ras_n, //ddr3 ras_n
output ddr3_cas_n, //ddr3 cas_n
output ddr3_we_n, //ddr3 write enable
output ddr3_reset_n, //ddr3 reset,
output [0:0] ddr3_ck_p, //ddr3 clock negative
output [0:0] ddr3_ck_n, //ddr3 clock positive
output [0:0] ddr3_cke, //ddr3_cke,
output [0:0] ddr3_cs_n, //ddr3 chip select,
output [3:0] ddr3_dm, //ddr3_dm
output [0:0] ddr3_odt, //ddr3_odt
input sys_clk_p, //system clock positive on board
input sys_clk_n, //system clock negative on board
input rst_n , //reset ,low active
//标志相关------------------------------output error_flag //错误指示信号
);//============================< 信号定义 >======================================
//parameter define
parameter integer WR_LEN = 512 ; //读、写长度
parameter integer DATA_WIDTH = 256 ; //数据位宽,突发长度为8,32bit,共256bit
parameter integer ADDR_WIDTH = 29 ; //根据MIG例化而来
//wire define
wire ui_clk ; //用户时钟
wire [ADDR_WIDTH - 1:0] app_addr ; //DDR3 地址
wire [2:0] app_cmd ; //用户读写命令
wire app_en ; //MIG IP核使能
wire app_rdy ; //MIG IP核空闲
wire [DATA_WIDTH - 1:0] app_rd_data ; //用户读数据
wire app_rd_data_end ; //突发读当前时钟最后一个数据
wire app_rd_data_valid ; //读数据有效
wire [DATA_WIDTH - 1:0] app_wdf_data ; //用户写数据
wire app_wdf_end ; //突发写当前时钟最后一个数据
wire [31:0] app_wdf_mask ; //写数据屏蔽
wire app_wdf_rdy ; //写空闲
wire app_wdf_wren ; //DDR3 写使能
wire app_sr_active;
wire app_ref_ack;
wire app_zq_ack;
//wire clk_ref_i ; //DDR3参考时钟
//wire sys_clk_i ; //MIG IP核输入时钟
wire sys_clk_200MHz ; //200M时钟
wire ui_clk_sync_rst ; //用户复位信号
wire init_calib_complete ; //校准完成信号//*****************************************************************************************
//** main code
//*****************************************************************************************//============================< 例化DDR3读写测试模块 >======================================ddr3_rw #(.WR_LEN (WR_LEN ),.DATA_WIDTH (DATA_WIDTH ),.ADDR_WIDTH (ADDR_WIDTH ))u_ddr3_rw(.ui_clk (ui_clk ), .ui_clk_sync_rst (ui_clk_sync_rst ), .init_calib_complete (init_calib_complete ),.app_rdy (app_rdy ),.app_wdf_rdy (app_wdf_rdy ),.app_rd_data_valid (app_rd_data_valid ),.app_rd_data (app_rd_data ), .app_addr (app_addr ),.app_en (app_en ),.app_wdf_wren (app_wdf_wren ),.app_wdf_end (app_wdf_end ),.app_cmd (app_cmd ),.app_wdf_data (app_wdf_data ),.error_flag (error_flag ));IBUFDS sys_clk_ibufgds
(
.O (sys_clk_200MHz ),
.I (sys_clk_p ),
.IB (sys_clk_n )
);
//============================< 例化MIG IP核 >===============================================ddr3 u_ddr3_inst (// Memory interface ports.ddr3_addr (ddr3_addr ), // output [14: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 [28: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 (app_sr_active ), // output app_sr_active.app_ref_ack (app_ref_ack ), // output app_ref_ack.app_zq_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 (32'd0 ), // input [31:0] app_wdf_mask ***** must be set to zero ****// System Clock Ports.sys_clk_i (sys_clk_200MHz ),.sys_rst (rst_n ) // input sys_rst);ila_ddr3_32 u_ila (.clk (ui_clk ), // input wire clk.probe0 (app_rd_data_valid ), // input wire [0:0] probe0 .probe1 (app_rd_data ) // input wire [255:0] probe1
); endmodule
ddr3_rw.v(借用他人demo)
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/06/01 21:41:11
// Design Name:
// Module Name: ddr3_rw
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module ddr3_rw #
( parameter integer WR_LEN = 1024 , //读、写长度parameter integer DATA_WIDTH = 256 , //数据位宽,突发长度为8,32bit,共256bitparameter integer ADDR_WIDTH = 29 //根据MIG例化而来
)(
//DDR3相关 ------------------------------------------------------ input ui_clk , //用户时钟input ui_clk_sync_rst , //复位,高有效input init_calib_complete , //DDR3初始化完成
//DDR3相关 ------------------------------------------------------ input app_rdy , //MIG 命令接收准备好标致input app_wdf_rdy , //MIG数据接收准备好input app_rd_data_valid , //读数据有效input [DATA_WIDTH - 1:0] app_rd_data , //用户读数据output reg [ADDR_WIDTH - 1:0] app_addr , //DDR3地址 output app_en , //MIG IP发送命令使能output app_wdf_wren , //用户写数据使能output app_wdf_end , //突发写当前时钟最后一个数据 output [2:0] app_cmd , //MIG IP核操作命令,读或者写output reg [DATA_WIDTH - 1:0] app_wdf_data , //用户写数据
//指示 ---------------------------------------------------------- output reg error_flag //读写错误标志);//============================< 信号定义 >======================================
//测试状态机-----------------------------------------
localparam IDLE = 4'b0001 ; //空闲状态
localparam WRITE = 4'b0010 ; //写状态
localparam WAIT = 4'b0100 ; //读到写过度等待
localparam READ = 4'b1000 ; //读状态
//reg define ----------------------------------------
reg [3:0] cur_state ; //三段式状态机现态
reg [3:0] next_state ; //三段式状态机次态
reg [ADDR_WIDTH - 1:0] rd_addr_cnt ; //用户读地址计数
reg [ADDR_WIDTH - 1:0] wr_addr_cnt ; //用户写地址计数
reg [ADDR_WIDTH - 1:0] rd_cnt ; //实际读地址标记
//wire define ---------------------------------------
wire error ; //读写错误标记
wire rst_n ; //复位,低有效
wire wr_proc ; //拉高表示写过程进行
wire wr_last ; //拉高表示写入最后一个数据
wire rd_addr_last ; //拉高表示是最后一个读地址//*********************************************************************************************
//** main code
//**********************************************************************************************
//==========================================================================
//== 信号赋值
//==========================================================================
assign rst_n = ~ui_clk_sync_rst;
//当MIG准备好后,用户同步准备好
assign app_en = app_rdy && ((cur_state == WRITE && app_wdf_rdy) || cur_state == READ);
//写指令,命令接收和数据接收都准备好,此时拉高写使能
assign app_wdf_wren = (cur_state == WRITE) && wr_proc;
//由于DDR3芯片时钟和用户时钟的分频选择4:1,突发长度为8,故两个信号相同
assign app_wdf_end = app_wdf_wren;
assign app_cmd = (cur_state == READ) ? 3'd1 :3'd0; //处于读的时候命令值为1,其他时候命令值为0
assign wr_proc = ~app_cmd && app_rdy && app_wdf_rdy; //拉高表示写过程进行
//处于写使能且是最后一个数据
assign wr_last = app_wdf_wren && (wr_addr_cnt == WR_LEN - 1) ;
//处于读指令、读有效且是最后一个数据
assign rd_addr_last = (rd_addr_cnt == WR_LEN - 1) && app_rdy && app_cmd;//==========================================================================
//== 状态机
//========================================================================== always @(posedge ui_clk or negedge rst_n) beginif(~rst_n)cur_state <= IDLE;elsecur_state <= next_state;
endalways @(*) beginif(~rst_n)next_state = IDLE;elsecase(cur_state)IDLE:if(init_calib_complete) //MIG IP核初始化完成 next_state = WRITE; else next_state = IDLE; WRITE: if(wr_last) //写入最后一个数据next_state = WAIT; else next_state = WRITE; WAIT: next_state = READ; READ: if(rd_addr_last) //写入最后一个读地址,数据读出需要时间next_state = IDLE;elsenext_state = READ; default:;endcase
endalways @(posedge ui_clk or negedge rst_n) beginif(~rst_n) begin app_wdf_data <= 0; wr_addr_cnt <= 0; rd_addr_cnt <= 0; app_addr <= 0; endelsecase(cur_state)IDLE:beginapp_wdf_data <= 0; wr_addr_cnt <= 0; rd_addr_cnt <= 0; app_addr <= 0;endWRITE:beginif(wr_proc)begin //写条件满足app_wdf_data <= app_wdf_data + 1; //写数据自加wr_addr_cnt <= wr_addr_cnt + 1; //写地址自加app_addr <= app_addr + 8; //DDR3 地址加8endelse begin //写条件不满足,保持当前值app_wdf_data <= app_wdf_data; wr_addr_cnt <= wr_addr_cnt;app_addr <= app_addr; endendWAIT:begin rd_addr_cnt <= 0; //读地址复位app_addr <= 0; //DDR3读从地址0开始endREAD:begin //读到设定的地址长度 if(app_rdy)begin //若MIG已经准备好,则开始读rd_addr_cnt <= rd_addr_cnt + 1'd1; //用户地址每次加一app_addr <= app_addr + 8; //DDR3地址加8endelse begin //若MIG没准备好,则保持原值rd_addr_cnt <= rd_addr_cnt;app_addr <= app_addr; endenddefault:beginapp_wdf_data <= 0;wr_addr_cnt <= 0;rd_addr_cnt <= 0;app_addr <= 0;endendcase
end
//==========================================================================
//== 其他
//==========================================================================//读信号有效,且读出的数不是写入的数时,将错误标志位拉高
assign error = (app_rd_data_valid && (rd_cnt!=app_rd_data)); //寄存状态标志位
always @(posedge ui_clk or negedge rst_n) beginif(~rst_n) error_flag <= 0;else if(error)error_flag <= 1;
end//对DDR3实际读数据个数编号计数
always @(posedge ui_clk or negedge rst_n) beginif(~rst_n) rd_cnt <= 0;//若计数到读写长度,且读有效,地址计数器则置0 else if(app_rd_data_valid && rd_cnt == WR_LEN - 1)rd_cnt <= 0; else if (app_rd_data_valid ) //读有效情况下每个时钟+1rd_cnt <= rd_cnt + 1;
endendmodule
仿真结果如下图所示:
黑金核心板32bitDDR3 MIG核UI接口仿真模型搭建相关推荐
- NXP i.MX 8M Mini核心板(4核 ARM Cortex-A53)规格软硬件说明资料
今日与大家分享基于NXP i.MX 8M Mini处理器的创龙科技-新款异构多核工业级开发板,它采用了四核ARM Cortex-A53 + 单核ARM Cortex-M4异构多核处理器设计,是创龙科技 ...
- 全国产!全志T3+Logos FPGA核心板(4核ARM Cortex-A7)规格书
核心板简介 创龙科技SOM-TLT3F是一款基于全志科技T3四核ARM Cortex-A7处理器 + 紫光同创Logos PGL25G/PGL50G FPGA设计的异构多核全国产工业核心板,ARM C ...
- 国产!全志科技T507-H工业核心板( 4核ARM Cortex-A5)规格书
1核心板简介 创龙科技 SOM-TLT507 是一款基于全志科技 T507-H 处理器设计的 4 核 ARM Cortex-A 53 全国产工业核心板,主频高达 1.416GHz .核心板 CPU . ...
- 全国产!全志A40i+Logos FPGA核心板(4核ARM Cortex-A7)硬件说明
硬件资源 SOM-TLA40iF核心板板载ARM.FPGA.ROM.RAM.晶振.电源.LED等硬件资源,并通过B2B连接方式引出IO.核心板所有器件(包括B2B连接器)均采用国产工业级方案,国产化率 ...
- 【FPGA黑金开发板】发布第二代黑金核心板 HJ-II-CORE
一.核心板采用更高级的FPGA EP3C16Q240,资源更多,性能更强: 二.核心板采用四层PCB 设计,更稳定,更专业!可以用到工业领域产品上: 三.宽电源输入(7.5V~16V)设计,含防插反功 ...
- Cortex-A72核心板 | RK3399六核
64位6核"服务器级"处理器 基于瑞芯微国产RK3399处理器设计,集成2颗1.8GHz ARM Cortex-A72内核.4颗1.4GHz ARM Cortex-A53内核,64 ...
- 全志A40i工业核心板,100%国产4核ARM Cortex-A7,支持“双屏异显”【显示接口能力,工业HMI首选方案】
1 多核国产工业平台,支持国产ARM处理器发展 创龙科技SOM-TLA40i是一款基于全志科技A40i处理器设计的4核ARM Cortex-A7国产工业核心板,每核主频高达1.2GHz. 图 1 SO ...
- 「科技与安全」RK3568J核心板让隔离网闸更强大
一句"科技与狠活"让食品安全的话题冲上了热搜,其实除了食品安全,生活中还有很多安全问题值得我们注意.在信息数字化给我们的生活带来种种便利的同时,信息泄露的风险也大大增加.如何有效地 ...
- 瑞芯微RK3568系列-飞凌嵌入式FET3568-C核心板已发布
近年来,国产芯片产业发展迅速,国内主流IC厂商陆续推出了诸多备受市场认可的嵌入式处理器,在各领域得到了广泛应用.结合电力.医疗等行业愈发明显的国产化趋势,国产处理器在本土市场已然崛起.Rockchip ...
最新文章
- 黄皓之后,计算机科学上帝Don Knuth仅用一页纸证明布尔函数敏感度猜想
- python利器怎么编程-C++和Python混合编程的利器
- 九十一、动态规划系列 背包问题之混合背包
- 二十一、Python中的Scipy统计库
- 【Linux】一步一步学Linux——halt命令(196)
- 如何通过 Excel import 的方式导入测试数据到 SAP Commerce Cloud 服务器
- 【渝粤题库】陕西师范大学201721 数学教育学 作业(专升本)
- python center函数对齐方式_Python如何对齐字符串
- Sunscreen(POJ-3416)
- java枚举来实现单例_枚举实现单例模式
- Keil(MDK-ARM-STM32)系列教程(四)工程目标选项配置(Ⅱ)
- 解决报错(4种情况):0x00007FF614F73B96 处(位于 XXX.exe 中)引发的异常: Microsoft C++ 异常: cv::Exception,位于内存位置 0x000XXX
- MySql修改默认端口
- Cocos Creator 实现虚拟摇杆
- 进销存excel_Excel小技巧|手把手教你制作简易的进销存管理系统
- 网孔型高级维修电工实训装置
- PR转场插件 MAC版 FilmImpact Transition Pack v1-v2
- linux内核贡献排名,谷歌ARM靠边站!Linux内核贡献,华为反超Intel全球第一
- 基于Stacey模型的变革小招式:强有力的提议
- 论文阅读笔记《Locality Preserving Matching》
热门文章
- 简师网:新录用公务员试用期限满一年可转正!
- 修改Echarts源码实现柱状图的炫彩闪烁效果
- 新时达电梯服务器维修,常见的新时达电梯维修时问题分析
- 最新上海个人养老保险缴费信息查询步骤
- 前端css实现左侧盒子宽度固定,右侧宽度自适应布局
- 图解通信原理与案例分析-29:埃隆.马斯克的“星链”Starlink计划是卫星语音通信向卫星互联网的演进
- 计算文本相似度-Word2Vec计算
- Ubuntu 16.04+ROS+ORB-SLAM2配置以及相关问题
- 如何打造自己有创意的平面设计灵魂作品
- 第三方测试什么意思?国内知名第三方测试公司排名