设计文件
module sdram_read(
input clk,
input rst_n,
input init_end,
input rd_en,
input [23:0] rd_addr,
input [15:0] rd_data,
input [9:0] rd_burst_len,
output wire rd_ack,
output wire rd_end,
output reg [3:0] read_cmd,
output reg [1:0] read_bank,
output reg [12:0] read_addr,
output wire [15:0] rd_sdram_data
);
parameter TRCD = 10'd2 ,
TCL = 10'd3 ,
TRP = 10'd4 ;
parameter RD_IDLE = 4'b0000 ,
RD_ACT = 4'b0001 ,
RD_TRCD = 4'b0011 ,
RD_READ = 4'b0010 ,
RD_CL = 4'b0100 ,
RD_DATA = 4'b0101 ,
RD_PRE = 4'b0111 ,
RD_TRP = 4'b0110 ,
RD_END = 4'b1100 ;
parameter NOP = 4'b0111 ,
ACTIVE = 4'b0011 ,
READ = 4'b0101 ,
BURST_STOP = 4'b0110 ,
PRECHARGE = 4'b0010 ;
reg [8:0] state;
reg [8:0] next_state;
reg [9:0] cnt_cmd;
reg [15:0] rd_data_reg;
wire trcd_end;
wire tcl_end;
wire tread_end;
wire trp_end;
wire rdburst_end;
wire cnt_cmd_reset;
assign trcd_end = ((state == RD_TRCD) && (cnt_cmd == TRCD -1))?1'd1:1'd0;
assign tcl_end = ((state == RD_CL) && (cnt_cmd == TCL -1))?1'd1:1'd0;
assign tread_end = ((state == RD_DATA) && (cnt_cmd == rd_burst_len -1 + TCL))?1'd1:1'd0;
assign trp_end = ((state == RD_TRP) && (cnt_cmd == TRP -1))?1'd1:1'd0;
assign rdburst_end = ((state == RD_DATA) && (cnt_cmd == rd_burst_len - 3'd4))?1'd1:1'd0;
assign cnt_cmd_reset = ((state == RD_IDLE) || (state == RD_TRCD) || (state == RD_END) || trcd_end || tcl_end || tread_end || trp_end)?1'd1:1'd0;
assign rd_ack = ((state == RD_DATA) && (cnt_cmd >= 10'd1) && (cnt_cmd <= 10'd11))?1'd1:1'd0;
assign rd_end = ((state == RD_END)) ? 1'd1 : 1'd0;
assign rd_sdram_data = (rd_ack) ? rd_data_reg : 16'd0;
always@(posedge clk or negedge rst_n)begin
if(!rst_n )begin
cnt_cmd <= 10'd0;
end
else if(cnt_cmd_reset)begin
cnt_cmd <= 10'd0;
end
else
cnt_cmd <= cnt_cmd + 10'd1;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n )begin
rd_data_reg <= 16'd0;
end
else
rd_data_reg <= rd_data;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n )begin
state <= RD_IDLE;
end
else
state <= next_state;
end
always@(*)begin
next_state = RD_IDLE;
case(state)
RD_IDLE:
if(rd_en && init_end)
next_state = RD_ACT;
else
next_state = RD_IDLE;
RD_ACT:
next_state = RD_TRCD;
RD_TRCD:
if(trcd_end)
next_state = RD_READ;
else
next_state = RD_TRCD;
RD_READ:
next_state = RD_CL;
RD_CL:
if(tcl_end)
next_state = RD_DATA;
else
next_state = RD_CL;
RD_DATA:
if(tread_end)
next_state = RD_PRE;
else
next_state = RD_DATA;
RD_PRE:
next_state = RD_TRP;
RD_TRP:
if(trp_end)
next_state = RD_END;
else
next_state = RD_TRP;
RD_END:
next_state = RD_IDLE;
default:next_state = RD_IDLE;
endcase
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n )begin
read_cmd <= NOP;
read_bank <= 2'b11;
read_addr <= 13'h1fff;
end
else
case(state)
RD_IDLE : begin
read_cmd <= NOP;
read_bank <= 2'b11;
read_addr <= 13'h1fff;
end
RD_ACT : begin
read_cmd <= ACTIVE;
read_bank <= rd_addr[23:22];
read_addr <= rd_addr[21:9];
end
RD_TRCD : begin
read_cmd <= NOP;
read_bank <= 2'b11;
read_addr <= 13'h1fff;
end
RD_READ : begin
read_cmd <= READ;
read_bank <= rd_addr[23:22];
read_addr <= {{4{1'b0}},rd_addr[8:0]};
end
RD_DATA : begin
read_bank <= 2'b11;
read_addr <= 13'h1fff;
if(rdburst_end)
read_cmd <= BURST_STOP;
else
read_cmd <= NOP;
end
RD_PRE : begin
read_cmd <= PRECHARGE;
read_bank <= rd_addr[23:22];
read_addr <= 13'h0400;
end
RD_TRP: begin
read_cmd <= NOP;
read_bank <= 2'b11;
read_addr <= 13'h1fff;
end
RD_END: begin
read_cmd <= NOP;
read_bank <= 2'b11;
read_addr <= 13'h1fff;
end
default:begin
read_cmd <= NOP;
read_bank <= 2'b11;
read_addr <= 13'h1fff;
end
endcase
end
endmodule