1. 工程代码下载:
2. 利用Mark_debug 抓取的波形如下:
图1 写波形
图2 读波形
3. 测试源程序
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2020/05/12 17:45:17 // Design Name: // Module Name: ddr_rd_wrrd_wr // Project Name: ddr3_intf // Target Devices: Artix 7 100T // Tool Versions: // Description: // // Dependencies: // clock ratio 4:1 // DDR clock frequency 400Mhz // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module ddr_rd_wr( // input [127:0] data_in, (* MARK_DEBUG="true" *) output reg [26:0] app_addr , (* MARK_DEBUG="true" *) output reg [2:0] app_cmd , (* MARK_DEBUG="true" *) output reg app_en , (* MARK_DEBUG="true" *) input app_rdy , (* MARK_DEBUG="true" *) output reg [127:0] app_wdf_data , output reg [15:0] app_wdf_mask , (* MARK_DEBUG="true" *) output app_wdf_end , (* MARK_DEBUG="true" *) output reg app_wdf_wren , (* MARK_DEBUG="true" *) input app_wdf_rdy , (* MARK_DEBUG="true" *) input [127:0] app_rd_data , (* MARK_DEBUG="true" *) input app_rd_data_end , (* MARK_DEBUG="true" *) input app_rd_data_valid , input clk , input rst_n , (* MARK_DEBUG="true" *) output reg error_flag = 0 , output reg end_flag = 0 ); parameter BURST_WR_128BIT = 16777216 ; //0x100_0000 测试写容量 parameter BURST_RD_128BIT = 16777216 ; //0x100_0000 测试读容量 parameter DATA = 128'habcdef1234567890abcdef1234567890 ; //测试数据 // Read and write once every 1 second (* MARK_DEBUG="true" *) reg [27:0] scnt = 0 ; // 分频 ,将100M时钟分频成 周期2秒的方波,高电平和低电平各1秒。 always @ (posedge clk) if (!rst_n) begin scnt <= 0 ; end_flag <= 0 ; end else if (scnt < 28'd199_999_999) begin scnt <= scnt + 1; end_flag <= 0 ; end else begin scnt <= 0 ; end_flag <= ~end_flag ; end (* MARK_DEBUG="true" *) wire time_wrreq = ( scnt == 28'd100_000_000 ) ; (* MARK_DEBUG="true" *) wire time_rdreq = ( scnt == 28'd000_000_000) ; (* MARK_DEBUG="true" *) reg[1:0] cstate; //current state reg[1:0] nstate; //next state (* MARK_DEBUG="true" *) reg [31:0] num = 0 ; (* MARK_DEBUG="true" *) reg [31:0] wrnum = 0 ; always @ (posedge clk ) if (!rst_n) cstate <= 0 ; else cstate <=nstate ; always @(cstate , time_wrreq ,time_rdreq ,num ,app_rdy ,app_wdf_rdy) case (cstate) 0 : begin if ( time_wrreq ) //write request nstate <= 1 ; else if (time_rdreq ) nstate <= 2 ; else nstate <= 0 ; end 1: begin if (( wrnum >= BURST_WR_128BIT) && (num >=BURST_WR_128BIT ) ) nstate <= 3 ; else nstate <= 1 ; end 2: begin if (num >= BURST_RD_128BIT) nstate <= 3 ; else nstate <= 2 ; end 3: begin nstate <= 0 ; end endcase always @ (posedge clk) if (!rst_n) num <= 32'd0 ; else if (cstate ==1) begin if ( app_rdy & app_en ) num <= num+ 1 ; end else if ( cstate == 2) begin if (app_rdy & app_en) num <= num +1 ; end else num <= 0 ; always @ ( posedge clk) if (!rst_n) wrnum <= 32'd0 ; else if (cstate == 1) begin if (app_wdf_rdy & app_wdf_wren) begin wrnum <= wrnum +1 ; end end else wrnum <= 0 ; //////////////////////////////////////////////////// //地址命令 //reg[27:0] app_addr, //DDR3地址总线 //reg[2:0] app_cmd, //DDR3命令总线: 3‘b000--写;3'b001--读; //reg app_en, //地址命令使能,高电平有效 // 读写数据 always@ (posedge clk ) if (~rst_n) begin app_cmd <= 3'd0 ; app_en <= 1'b0 ; app_addr <=27'd0 ; end else begin if ( cstate == 1) begin app_cmd <= 3'b000 ; //write data to ddr3 if ( num < BURST_WR_128BIT ) app_en <= 1 ; else app_en <= 0 ; if (app_rdy & app_en) app_addr[26:3] <= app_addr[26:3]+1 ; // app_addr[10:3] +1'b1 ; 8 data ,16bits end else begin if (cstate == 2) begin if (num <BURST_RD_128BIT) app_en <= 1'b1 ; else app_en <= 1'b0 ; if (app_rdy&app_en) begin app_cmd <= 3'b001 ; app_addr[26:3] <= app_addr[26:3] + 1 ; end end else begin app_cmd <= 3'd0 ; app_en <= 1'b0 ; app_addr <= 27'd0 ; end end end // always @ ( posedge clk) if (!rst_n) begin app_wdf_data <= 128'd0 ; app_wdf_mask<=16'd0; app_wdf_wren <= 0 ; end else begin app_wdf_mask<=16'd0; if(cstate == 1) begin app_wdf_data <= DATA ;//prepare the data if (wrnum <= BURST_WR_128BIT ) app_wdf_wren <= 1'b1 ; else app_wdf_wren <= 1'b0 ; if (app_wdf_rdy & app_wdf_wren) app_wdf_data <= DATA ; end else begin app_wdf_data <= 128'd0 ; app_wdf_wren <= 0 ; end end assign app_wdf_end = 1'b1; always @(posedge clk or negedge rst_n) if(!rst_n) begin error_flag <= 0; end else begin if(app_rd_data_valid&&(app_rd_data!= DATA)) error_flag <= 1 ; else error_flag <=0 ; end endmodule
老师好,在学习时遇到一个问题,请老师解答:
1、本文中定义常量BURST_RD_128BIT=16777216,请问老师这里的数值(16777216)代表什么含义,是如何计算得到的呢?请老师详细讲解一下,谢谢老师!
FII-PRX100-D硬件上所使用的DDR芯片型号为MT41J128M16HA-125,容量为256M bytes。BURST_RD_128BIT = 16777216 表示 2 ^24(16777216) * 128bit = 2 ^24 * 128/ 8 bytes = 256M bytes。可以实现对全片进行测试。
老师,请教一下,我们ddr3控制器的地址映射选择的是ROW+BANK+COLUMN, 上面测试程序里面的app_addr[26:3] +1 如果第一行的列地址加完,再加一不是直接加在了bank上面么,按道理应该是这一行的列写完,就应该下一行的第一列开始。地址映射应该是BANK+ROW+COLUMN 才对?
app_wdf_rdy写成了输入 是否有误
老师 wr_num 和num是什么区别?