DDR4读写控制模块
module ddr4_control#(
parameter MEM_DATA_BITS = 512 ,
parameter ADDR_BITS = 26 ,
parameter BUSRT_BITS = 10 ,//突发的位宽长度
parameter BURST_LEN = 5
)
(
input i_sys_clk ,
input i_sys_rst ,
input i_wr_data_rdy ,
output reg [MEM_DATA_BITS-1:0] o_wr_data ,
output reg o_wr_ddr4_req ,
input i_rd_data_vaild ,
input [MEM_DATA_BITS-1:0] i_rd_ddr4_data ,
output reg o_rd_ddr4_req ,
output [BUSRT_BITS-1:0] o_wr_burst_length ,
output [BUSRT_BITS-1:0] o_rd_burst_length ,
output reg [ADDR_BITS-1:0] o_wr_base_ddr4_addr ,
output reg [ADDR_BITS-1:0] o_rd_base_ddr4_addr ,
input i_wr_finished ,
input i_rd_finished
);
localparam IDLE = 3'b000 ;
localparam WRITE = 3'b001 ;
localparam READ = 3'b011 ;
reg [11:0] wr_data_count ;
reg [11:0] rd_data_count ;
reg [2:0] current_state ;
reg [2:0] next_state ;
assign o_wr_burst_length = BURST_LEN;
assign o_rd_burst_length = BURST_LEN;
always @(posedge i_sys_clk or posedge i_sys_rst) begin
if(i_sys_rst) begin
current_state <= IDLE;
end
else begin
current_state <= next_state;
end
end
always @(*) begin
case(current_state)
IDLE: begin
next_state = WRITE;
end
WRITE: begin
if(i_wr_finished) begin
next_state = READ;
end
else begin
next_state = WRITE;
end
end
READ: begin
if(i_rd_finished) begin
next_state = IDLE;
end
else begin
next_state = READ;
end
end
default:begin
next_state = IDLE;
end
endcase
end
always @(posedge i_sys_clk or posedge i_sys_rst) begin
if(i_sys_rst) begin
o_wr_ddr4_req <= 1'd0;
o_rd_ddr4_req <= 1'd0;
end
else if( current_state == IDLE || (current_state == READ && i_rd_finished))begin
o_wr_ddr4_req <= 1'd1;
o_rd_ddr4_req <= 1'd0;
end
else if( current_state == WRITE && i_wr_finished)begin
o_wr_ddr4_req <= 1'd0;
o_rd_ddr4_req <= 1'd1;
end
else begin
o_wr_ddr4_req <= o_wr_ddr4_req;
o_rd_ddr4_req <= o_rd_ddr4_req;
end
end
always @(posedge i_sys_clk or posedge i_sys_rst) begin
if(i_sys_rst) begin
wr_data_count <= 12'd0;
end
else if(current_state == WRITE && wr_data_count == BURST_LEN - 12'd1 || current_state == IDLE ) begin
wr_data_count <= 12'd0;
end
else if(current_state == WRITE && i_wr_data_rdy ) begin
wr_data_count <= wr_data_count + 12'd1;
end
else begin
wr_data_count <= wr_data_count;
end
end
always @(posedge i_sys_clk or posedge i_sys_rst) begin
if(i_sys_rst) begin
o_wr_data <= {MEM_DATA_BITS{1'd0}};
end