当前位置:网站首页>Use of DDR3 (axi4) in Xilinx vivado (4) incentive design
Use of DDR3 (axi4) in Xilinx vivado (4) incentive design
2022-07-28 20:30:00 【chylinne】
1、 summary
The purpose of writing the incentive program in this paper is to integrate the incentive module with the encapsulated MIG IP The core is made into a top layer (top), And burn it into the development board for testing . Reading and writing of incentive module I/O The interface needs to be directly connected with MIG The package modules are connected , The parameter configuration interface can directly configure the constants required by users from the top , The clock signal can be generated by the frequency divider at the top .
2、 Design idea of incentive module
2.1 Parametric design
(1) Read / write data bit width :DDR_RAM_WIDTH = 10'd256, Company :bit;
(2)MIG Kernel data bit width :DATA_NUM = 3'd5, because 32 = 2^5,32 Is the memory address increment , Company :bit;
(3) Test data scale :WRITE_SIZE = 28'h00800000, Company :bit;
(4) Number of test data :WRITE_NUM = WRITE_SIZE << DATA_NUM, It's equivalent to dividing by 32, Company : individual ;
(5) Write - Read status interval :DELAY_TIME = 16’d100, Company :clk;
(6) State machine cycle mode ( Write + Read alternate mode ):loop_all;
(7) State machine cycle mode ( Write at once + Cyclic read mode ):loop_read.
2.2 State machine design
The design of the state machine of the excitation module is shown in the figure below :

3、 Implementation code
Incentive module Verilog The code is as follows :
`timescale 1ns / 1ps
module ddr_traffic_gen # (
parameter DDR_RAM_WIDTH = 256
)(
input arst_n,
input ddr3_user_clk,
output reg ddr3_user_wr_en,
output reg [31:0] ddr3_user_wr_addr,
output reg [31:0] ddr3_user_wr_datalen,
input ddr3_user_wr_busy,
output reg [(DDR_RAM_WIDTH-1):0] ddr3_user_wr_data,
output reg ddr3_user_wr_last,
output reg ddr3_user_wr_valid,
input ddr3_user_wr_ready,
output reg ddr3_user_rd_en,
output reg [31:0] ddr3_user_rd_addr,
output reg [31:0] ddr3_user_rd_datalen,
input ddr3_user_rd_busy,
input [(DDR_RAM_WIDTH-1):0] ddr3_user_rd_data,
input ddr3_user_rd_last,
input ddr3_user_rd_valid,
output ddr3_user_rd_ready,
input [31:0] WRITE_SIZE,
input loop_all,
input loop_read,
output reg [31:0] wr_trans_time,
output reg [31:0] rd_trans_time,
output reg [31:0] error_count
);
localparam DELAY_TIME = 16'd100;
localparam DATA_NUM = (DDR_RAM_WIDTH == 512) ? 6 :
(DDR_RAM_WIDTH == 256) ? 5 :
(DDR_RAM_WIDTH == 128) ? 4 :
(DDR_RAM_WIDTH == 64) ? 3 : 2;
localparam P_IDLE = 4'd0;
localparam P_WR_ADDR = 4'd1;
localparam P_WR_DATA = 4'd2;
localparam P_WR_DLY = 4'd6;
localparam P_RD_ADDR = 4'd3;
localparam P_RD_DATA = 4'd4;
localparam P_WAIT = 4'd5;
reg [3:0] c_state;
reg [31:0] wr_data;
reg [31:0] data_len_cnt;
reg delay_finish;
reg [15:0] cnt_delay;
wire [31:0] WRITE_NUM;
wire [31:0] data1;
wire [31:0] data2;
reg [31:0] data_dly1;
reg [31:0] data_dly2;
reg [31:0] sub1;
reg [31:0] sub2;
reg [31:0] time_count;
assign ddr3_user_rd_ready = 1'b1;
assign data1 = ddr3_user_rd_data[31:0];
assign data2 = ddr3_user_rd_data[(DDR_RAM_WIDTH-1):(DDR_RAM_WIDTH-32)];
assign WRITE_NUM = WRITE_SIZE >> DATA_NUM;
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
c_state <= P_IDLE;
else
begin
if(ddr3_user_wr_ready)
begin
case(c_state)
P_IDLE:
begin
if(!ddr3_user_wr_busy)
c_state <= P_WR_ADDR;
else
c_state <= P_IDLE;
end
P_WR_ADDR:c_state <= P_WR_DATA;
P_WR_DATA:
begin
if(data_len_cnt == (WRITE_NUM - 1'b1))
c_state <= P_WR_DLY;
else
c_state <= P_WR_DATA;
end
P_WR_DLY:
begin
if(delay_finish)
c_state <= P_RD_ADDR;
else
c_state <= P_WR_DLY;
end
P_RD_ADDR:
begin
if(!ddr3_user_rd_busy)
c_state <= P_RD_DATA;
else
c_state <= P_RD_ADDR;
end
P_RD_DATA:
begin
if(ddr3_user_rd_last & ddr3_user_rd_valid)
c_state <= P_WAIT;
else
c_state <= P_RD_DATA;
end
P_WAIT: begin
if (loop_all)
c_state <= P_IDLE;
else if (loop_read)
c_state <= P_RD_ADDR;
else ;
end
default:c_state <= P_IDLE;
endcase
end
else ;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
begin
ddr3_user_wr_en <= 1'b0;
ddr3_user_wr_addr <= 32'd0;
ddr3_user_wr_datalen <= 32'b0;
end
else
begin
if(c_state == P_WR_ADDR)
begin
ddr3_user_wr_en <= 1'b1;
ddr3_user_wr_addr <= 32'd0;
ddr3_user_wr_datalen <= WRITE_SIZE;
end
else
ddr3_user_wr_en <= 1'b0;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
begin
ddr3_user_wr_valid <= 1'b0;
ddr3_user_wr_last <= 1'b0;
ddr3_user_wr_data <= 512'b0;
wr_data <= 32'b0;
data_len_cnt <= 32'b0;
end
else
begin
if(ddr3_user_wr_ready)
begin
if(c_state == P_WR_DATA)
begin
data_len_cnt <= data_len_cnt + 1'b1;
wr_data <= wr_data + 1'b1;
if(data_len_cnt < (WRITE_NUM -32'd1))
begin
ddr3_user_wr_valid <= 1'b1;
ddr3_user_wr_last <= 1'b0;
ddr3_user_wr_data <= {8{wr_data}};
end
else
begin
ddr3_user_wr_valid <= 1'b1;
ddr3_user_wr_last <= 1'b1;
ddr3_user_wr_data <= {8{wr_data}};
end
end
else
begin
ddr3_user_wr_valid <= 1'b0;
ddr3_user_wr_last <= 1'b0;
data_len_cnt <= 32'd0;
end
end
else ;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
begin
delay_finish <= 1'b0;
cnt_delay <= 16'd0;
end
else
begin
if(c_state == P_WR_DLY)
begin
if(cnt_delay == DELAY_TIME)
delay_finish <= 1'b1;
else
cnt_delay <= cnt_delay + 1'b1;
end
else
begin
delay_finish <= 1'b0;
cnt_delay <= 16'd0;
end
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
begin
ddr3_user_rd_en <= 1'b0;
ddr3_user_rd_addr <= 32'd0;
ddr3_user_rd_datalen <= 32'b0;
end
else
begin
if(c_state == P_RD_ADDR)
begin
if(!ddr3_user_rd_busy)
begin
ddr3_user_rd_en <= 1'b1;
ddr3_user_rd_addr <= 32'd0;
ddr3_user_rd_datalen <= WRITE_SIZE;
end
else
ddr3_user_rd_en <= 1'b0;
end
else
ddr3_user_rd_en <= 1'b0;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
begin
data_dly1 <= 32'b0;
data_dly2 <= 32'b0;
end
else
begin
if(ddr3_user_rd_valid)
begin
data_dly1 <= data1;
data_dly2 <= data2;
end
else ;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
begin
sub1 <= 32'b0;
sub2 <= 32'b0;
end
else
begin
if(ddr3_user_rd_valid)
begin
sub1 <= data1 - data_dly1;
sub2 <= data2 - data_dly2;
end
else ;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
error_count <= 32'd0;
else
begin
if(ddr3_user_rd_valid)
begin
if (((sub1 == 32'd1) & (sub2 == 32'd1)) | ((sub1 == 32'd0) & (sub2 == 32'd0)))
error_count <= error_count;
else
error_count <= error_count + 1'b1;
end
else ;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
time_count <= 32'd0;
else
begin
if(ddr3_user_wr_en | ddr3_user_rd_en)
time_count <= 32'd0;
else
time_count <= time_count + 1'b1;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
wr_trans_time <= 32'd0;
else
begin
if(ddr3_user_wr_ready & ddr3_user_wr_valid & ddr3_user_wr_last)
wr_trans_time <= time_count;
else ;
end
end
[email protected](posedge ddr3_user_clk or negedge arst_n)
begin
if(!arst_n)
rd_trans_time <= 32'd0;
else
begin
if(ddr3_user_rd_ready & ddr3_user_rd_valid & ddr3_user_rd_last)
rd_trans_time <= time_count;
else ;
end
end
endmodulethen , Will motivate the module (ddr_traffic_gen) And encapsulated MIG modular (ddr_ram) Example into the top ddr_test_top, Used for board test .
`timescale 1ns / 1ps
module ddr_test_top(
input fpga_sysclk_p,
input fpga_sysclk_n,
inout [31:0] ddr3_dq,
inout [3:0] ddr3_dqs_n,
inout [3:0] ddr3_dqs_p,
output [14:0] ddr3_addr,
output [2:0] ddr3_ba,
output ddr3_ras_n,
output ddr3_cas_n,
output ddr3_we_n,
output ddr3_reset_n,
output [0:0] ddr3_ck_p,
output [0:0] ddr3_ck_n,
output [0:0] ddr3_cke,
output [0:0] ddr3_cs_n,
output [3:0] ddr3_dm,
output [0:0] ddr3_odt
);
wire fpga_sysclk_ibuf;
wire fpga_sysclk_in;
wire clk_10m;
wire clk_100m;
wire clk_200m;
wire locked;
wire init_calib_complete;
wire ddr_user_clk;
wire ddr_user_wr_en;
wire [31:0] ddr_user_wr_addr;
wire [31:0] ddr_user_wr_datalen;
wire ddr_user_wr_busy;
wire [255:0] ddr_user_wr_data;
wire ddr_user_wr_last;
wire ddr_user_wr_valid;
wire ddr_user_wr_ready;
wire ddr_user_rd_en;
wire [31:0] ddr_user_rd_addr;
wire [31:0] ddr_user_rd_datalen;
wire ddr_user_rd_busy;
wire [255:0] ddr_user_rd_data;
wire ddr_user_rd_last;
wire ddr_user_rd_valid;
wire ddr_user_rd_ready;
wire ddr_test_en;
wire [31:0] wr_trans_time;
wire [31:0] rd_trans_time;
wire [31:0] error_count;
IBUFDS #(
.DIFF_TERM("FALSE"),
.IBUF_LOW_PWR("TRUE"),
.IOSTANDARD("DEFAULT")
) IBUFDS_inst (
.O(fpga_sysclk_ibuf),
.I(fpga_sysclk_p),
.IB(fpga_sysclk_n)
);
BUFG BUFG_inst (
.O(fpga_sysclk_in),
.I(fpga_sysclk_ibuf)
);
clk_wiz_0 u_clk_wiz_0 (
.clk_out1(clk_10m),
.clk_out2(clk_100m),
.clk_out3(clk_200m),
.locked(locked),
.clk_in1(fpga_sysclk_in)
);
ddr_ram u_ddr_ram (
.ddr3_dq(ddr3_dq),
.ddr3_dqs_n(ddr3_dqs_n),
.ddr3_dqs_p(ddr3_dqs_p),
.ddr3_addr(ddr3_addr),
.ddr3_ba(ddr3_ba),
.ddr3_ras_n(ddr3_ras_n),
.ddr3_cas_n(ddr3_cas_n),
.ddr3_we_n(ddr3_we_n),
.ddr3_reset_n(ddr3_reset_n),
.ddr3_ck_p(ddr3_ck_p),
.ddr3_ck_n(ddr3_ck_n),
.ddr3_cke(ddr3_cke),
.ddr3_cs_n(ddr3_cs_n),
.ddr3_dm(ddr3_dm),
.ddr3_odt(ddr3_odt),
.sys_clk_i(clk_200m),
.clk_ref_i(clk_200m),
.init_calib_complete(init_calib_complete),
.arst_n(locked),
.ddr_user_clk(ddr_user_clk),
.ddr_user_wr_en(ddr_user_wr_en),
.ddr_user_wr_addr(ddr_user_wr_addr),
.ddr_user_wr_datalen(ddr_user_wr_datalen),
.ddr_user_wr_busy(ddr_user_wr_busy),
.ddr_user_wr_data(ddr_user_wr_data),
.ddr_user_wr_last(ddr_user_wr_last),
.ddr_user_wr_valid(ddr_user_wr_valid),
.ddr_user_wr_ready(ddr_user_wr_ready),
.ddr_user_rd_en(ddr_user_rd_en),
.ddr_user_rd_addr(ddr_user_rd_addr),
.ddr_user_rd_datalen(ddr_user_rd_datalen),
.ddr_user_rd_busy(ddr_user_rd_busy),
.ddr_user_rd_data(ddr_user_rd_data),
.ddr_user_rd_last(ddr_user_rd_last),
.ddr_user_rd_valid(ddr_user_rd_valid),
.ddr_user_rd_ready(ddr_user_rd_ready)
);
ddr_traffic_gen u_ddr_traffic_gen (
.arst_n(init_calib_complete & ddr_test_en),
.ddr3_user_clk(ddr_user_clk),
.ddr3_user_wr_en(ddr_user_wr_en),
.ddr3_user_wr_addr(ddr_user_wr_addr),
.ddr3_user_wr_datalen(ddr_user_wr_datalen),
.ddr3_user_wr_busy(ddr_user_wr_busy),
.ddr3_user_wr_data(ddr_user_wr_data),
.ddr3_user_wr_last(ddr_user_wr_last),
.ddr3_user_wr_valid(ddr_user_wr_valid),
.ddr3_user_wr_ready(ddr_user_wr_ready),
.ddr3_user_rd_en(ddr_user_rd_en),
.ddr3_user_rd_addr(ddr_user_rd_addr),
.ddr3_user_rd_datalen(ddr_user_rd_datalen),
.ddr3_user_rd_busy(ddr_user_rd_busy),
.ddr3_user_rd_data(ddr_user_rd_data),
.ddr3_user_rd_last(ddr_user_rd_last),
.ddr3_user_rd_valid(ddr_user_rd_valid),
.ddr3_user_rd_ready(ddr_user_rd_ready),
.WRITE_SIZE(32'h0080000),
.loop_all(1'b1),
.loop_read(1'b0),
.wr_trans_time(wr_trans_time),
.rd_trans_time(rd_trans_time),
.error_count(error_count)
);
vio_ddr u_vio_ddr (
.clk(ddr_user_clk),// input wire clk
.probe_in0(init_calib_complete),// input wire [0 : 0] probe_in0
.probe_in1(wr_trans_time),// input wire [31 : 0] probe_in1
.probe_in2(rd_trans_time),// input wire [31 : 0] probe_in2
.probe_in3(error_count),// input wire [31 : 0] probe_in3
.probe_out0(ddr_test_en)// output wire [0 : 0] probe_out0
);
endmoduleHere we are , The incentive module is written , The next step is to connect the excitation module with the encapsulated MIG IP Example into a top In file , Burn the data into the development board to check the correctness of the read-write data .
边栏推荐
- 数据挖掘(数据预处理篇)--笔记
- Who cares about the safety of the battery when it ignites in a collision? SAIC GM has something to say
- WPF--实现WebSocket服务端
- [C language] shutdown game [loop and switch statement]
- 七种轮询介绍(后附实践链接)
- C language - data type
- Torch. NN. Linear() function
- Explain RESNET residual network in detail
- Other IPS cannot connect to the local redis problem solving and redis installation
- 1. C language variable type, global variable, local variable
猜你喜欢

Raspberrypico analytic PWM

Multi-Modal Knowledge Graph Construction and Application: A Survey

Pop up modal box

Explain RESNET residual network in detail

Configure Windows Server + install MySQL database on the server + Remote Access database
![最大交换[贪心思想&单调栈实现]](/img/ad/8f0914f23648f37e1d1ce69086fd2e.png)
最大交换[贪心思想&单调栈实现]

Raspberrypico serial communication

Related concepts of multitasking programming

七种轮询介绍(后附实践链接)

What is the variance?
随机推荐
Pytorch model parameter assignment - tensor.copy_ () method
C language - data type
[experiment sharing] CCIE BGP reflector experiment
Extract China map from global.Nc data and calculate regional CO2 value based on acgis
What is the variance?
弹出模态框
CNN convolutional neural network structure
6. Functions of C language, why functions are needed, how functions are defined, and the classification of functions
Install keras, tensorflow, and add the virtual environment to the Jupiter notebook
lattice
9. Pointer of C language (3) classic program, exchange the value of two numbers for deep analysis, (easy to understand), are formal parameters and arguments a variable?
Residual network RESNET source code analysis - pytoch version
[fasttext -- Summary notes]
Method number problem for solving sum of numbers (knapsack problem)
Quick sort template
数据挖掘(数据预处理篇)--笔记
Array out of bounds
关于链接到其他页面的标题
5. Difference between break and continue (easy to understand version)
Teach you how to draw a map with ArcGIS [thermal map]