108 lines
3.4 KiB
Verilog
108 lines
3.4 KiB
Verilog
module array_ref (
|
|
input clk,
|
|
input rst_n,
|
|
|
|
input array_ref_start,
|
|
output array_ref_done,
|
|
|
|
output array_ref_csn,
|
|
output reg [15:0] array_ref_raddr,
|
|
|
|
input [7:0] array_inner_tras,
|
|
input [7:0] array_inner_trp
|
|
);
|
|
|
|
reg [1:0] cur_state,next_state;
|
|
localparam [1:0] ARR_REF_IDLE = 2'b00;
|
|
localparam [1:0] ARR_REF_RCVRADDR = 2'b01;
|
|
localparam [1:0] ARR_REF_RAS = 2'b10;
|
|
localparam [1:0] ARR_REF_RP = 2'b11;
|
|
|
|
reg [7:0] ref_ras_cnt;
|
|
reg [7:0] ref_rp_cnt;
|
|
|
|
assign array_ref_done = (array_ref_raddr == 16'hffff) && (cur_state == ARR_REF_RP) &&
|
|
(ref_rp_cnt == 'd0);
|
|
assign array_ref_csn = !(cur_state == ARR_REF_RAS);
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
cur_state <= ARR_REF_IDLE;
|
|
end else begin
|
|
cur_state <= next_state;
|
|
end
|
|
end
|
|
|
|
always @(*) begin
|
|
case (cur_state)
|
|
ARR_REF_IDLE : begin
|
|
if (array_ref_start) begin
|
|
next_state = ARR_REF_RCVRADDR;
|
|
end else begin
|
|
next_state = ARR_REF_IDLE;
|
|
end
|
|
end
|
|
ARR_REF_RCVRADDR : begin
|
|
next_state = ARR_REF_RAS;
|
|
end
|
|
ARR_REF_RAS : begin
|
|
if (ref_ras_cnt == 'd0) begin
|
|
next_state = ARR_REF_RP;
|
|
end else begin
|
|
next_state = ARR_REF_RAS;
|
|
end
|
|
end
|
|
ARR_REF_RP : begin
|
|
if (ref_rp_cnt == 'd0) begin
|
|
if (array_ref_raddr == 16'hffff) begin
|
|
next_state = ARR_REF_IDLE;
|
|
end else begin
|
|
next_state = ARR_REF_RCVRADDR;
|
|
end
|
|
end else begin
|
|
next_state = ARR_REF_RP;
|
|
end
|
|
end
|
|
default : next_state = ARR_REF_IDLE;
|
|
endcase
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
array_ref_raddr <= 'd0;
|
|
end else if (cur_state == ARR_REF_IDLE) begin
|
|
array_ref_raddr <= 'd0;
|
|
end else if (cur_state == ARR_REF_RP && next_state == ARR_REF_RCVRADDR) begin
|
|
array_ref_raddr <= array_ref_raddr + 1'b1;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
ref_ras_cnt <= 'd0;
|
|
end else if (cur_state == ARR_REF_RCVRADDR) begin
|
|
ref_ras_cnt <= array_inner_tras - 1'b1;
|
|
end else if (cur_state == ARR_REF_RAS) begin
|
|
if (ref_ras_cnt == 'd0) begin
|
|
ref_ras_cnt <= ref_ras_cnt;
|
|
end else begin
|
|
ref_ras_cnt <= ref_ras_cnt - 1'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
ref_rp_cnt <= 'd0;
|
|
end else if (cur_state == ARR_REF_RCVRADDR) begin
|
|
ref_rp_cnt <= array_inner_trp - 1'b1;
|
|
end else if (cur_state == ARR_REF_RP) begin
|
|
if (ref_rp_cnt == 'd0) begin
|
|
ref_rp_cnt <= ref_rp_cnt;
|
|
end else begin
|
|
ref_rp_cnt <= ref_rp_cnt - 1'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule |