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