Files
IC_PRJ/rtl/array_status_ctrl.v

163 lines
5.4 KiB
Verilog

module array_status_ctrl(
input clk,
input rst_n,
input axi2array_frame_valid,
input [152:0] axi2array_frame_data,
output axi2array_frame_ready,
output array_wr_frame_valid,
output [151:0] array_wr_frame_data,
input array_wr_frame_ready,
input array_wr_done,
output array_rd_frame_valid,
output [151:0] array_rd_frame_data,
input array_rd_frame_ready,
input array_rd_done,
output array_ref_start,
input array_ref_done,
output [1:0] array_mux_sel,
input mc_work_en,
input array_ref_en,
input [24:0] array_inner_tref0,
input [24:0] array_inner_tref1,
input array_inner_ref_sel
);
reg [1:0] cur_state,next_state;
localparam [1:0] ARRAY_STA_IDLE = 2'b00;
localparam [1:0] ARRAY_STA_WR = 2'b10;
localparam [1:0] ARRAY_STA_RD = 2'b11;
localparam [1:0] ARRAY_STA_REF = 2'b01;
reg mc_work_en_r ,mc_work_en_sync;
reg array_ref_en_r ,array_ref_en_sync;
reg array_inner_ref_sel_r,array_inner_ref_sel_sync;
reg array_ref_req;
reg [24:0] array_ref_cnt;
wire [24:0] array_inner_tref;
wire array_wr_req ,array_rd_req;
assign axi2array_frame_ready = ((cur_state == ARRAY_STA_WR) && array_wr_frame_ready) || ((cur_state == ARRAY_STA_RD) && array_rd_frame_ready);
assign array_wr_frame_valid = ((cur_state == ARRAY_STA_WR) && axi2array_frame_valid);
assign array_rd_frame_valid = ((cur_state == ARRAY_STA_RD) && axi2array_frame_valid);
assign array_wr_frame_data = axi2array_frame_data[151:0];
assign array_rd_frame_data = axi2array_frame_data[151:0];
assign array_ref_start = ((cur_state == ARRAY_STA_IDLE && array_ref_req));
assign array_mux_sel = cur_state;
assign array_inner_tref = array_inner_ref_sel_sync ?array_inner_tref1:array_inner_tref0;
assign array_wr_req = axi2array_frame_valid && axi2array_frame_data[152];
assign array_rd_req = axi2array_frame_valid && !axi2array_frame_data[152];
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cur_state <= ARRAY_STA_IDLE;
end else begin
cur_state <= next_state;
end
end
always@(*) begin
case(cur_state)
ARRAY_STA_IDLE : begin
if(array_ref_req) begin
next_state = ARRAY_STA_REF;
end else if(array_wr_req) begin
next_state = ARRAY_STA_WR;
end else if(array_rd_req) begin
next_state = ARRAY_STA_RD;
end else begin
next_state = ARRAY_STA_IDLE;
end
end
ARRAY_STA_WR : begin
if(array_wr_done) begin
next_state = ARRAY_STA_IDLE;
end else begin
next_state = ARRAY_STA_WR;
end
end
ARRAY_STA_RD : begin
if(array_rd_done) begin
next_state = ARRAY_STA_IDLE;
end else begin
next_state = ARRAY_STA_RD;
end
end
ARRAY_STA_REF : begin
if(array_ref_done) begin
next_state = ARRAY_STA_IDLE;
end else begin
next_state = ARRAY_STA_REF;
end
end
default : next_state = ARRAY_STA_IDLE;
endcase
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
mc_work_en_r <= 'd0;
mc_work_en_sync <= 'd0;
end else begin
mc_work_en_r <= mc_work_en;
mc_work_en_sync <= mc_work_en_r;
end
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
array_ref_en_r <= 'd0;
array_ref_en_sync <= 'd0;
end else begin
array_ref_en_r <= array_ref_en;
array_ref_en_sync <= array_ref_en_r;
end
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
array_inner_ref_sel_r <= 'd0;
array_inner_ref_sel_sync <= 'd0;
end else begin
array_inner_ref_sel_r <= array_inner_ref_sel;
array_inner_ref_sel_sync <= array_inner_ref_sel_r;
end
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
array_ref_req <= 'd0;
end else if(mc_work_en) begin
array_ref_req <= (array_ref_cnt >= array_inner_tref && mc_work_en_sync &&
array_ref_en_sync) ? 1:0;
end else if(cur_state == ARRAY_STA_IDLE) begin
array_ref_req <= 'd0;
end
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
array_ref_cnt <= 'd0;
end else if(mc_work_en && array_ref_en) begin
if(array_ref_cnt >= array_inner_tref) begin
array_ref_cnt <= 'd0;
end else begin
array_ref_cnt <= array_ref_cnt + 1'b1;
end
end else begin
array_ref_cnt <= 'd0;
end
end
endmodule