264 lines
8.9 KiB
Verilog
264 lines
8.9 KiB
Verilog
module array_rd (
|
|
input clk,
|
|
input rst_n,
|
|
|
|
input array_rd_frame_valid,
|
|
input [151:0] array_rd_frame_data,
|
|
output array_rd_frame_ready,
|
|
output array_rd_done,
|
|
|
|
output reg array_rd_csn,
|
|
output reg [15:0] array_rd_raddr,
|
|
|
|
output reg array_caddr_vld_rd,
|
|
output reg [5:0] array_caddr_rd,
|
|
input array_rdata_vld,
|
|
input [127:0] array_rdata,
|
|
|
|
input [7:0] array_inner_tras,
|
|
input [7:0] array_inner_trp,
|
|
input [7:0] array_inner_trcd_rd,
|
|
input [7:0] array_inner_trtp,
|
|
|
|
output array2axi_rdata_valid,
|
|
output [127:0] array2axi_rdata
|
|
);
|
|
|
|
reg [2:0] cur_state,next_state;
|
|
localparam [2:0] ARR_RD_IDLE = 3'b000;
|
|
localparam [2:0] ARR_RD_LOWCS = 3'b001;
|
|
localparam [2:0] ARR_RD_RCD = 3'b010;
|
|
localparam [2:0] ARR_RD_HIGHVLD = 3'b011;
|
|
localparam [2:0] ARR_RD_RADDRLAST = 3'b100;
|
|
localparam [2:0] ARR_RD_RADDR = 3'b101;
|
|
localparam [2:0] ARR_RD_RTP = 3'b110;
|
|
localparam [2:0] ARR_RD_RP = 3'b111;
|
|
|
|
wire rsof,reof;
|
|
wire [15:0] rraddr;
|
|
wire [5:0] rcaddr;
|
|
wire [127:0] wdata;
|
|
|
|
reg [7:0] rd_ras_cnt;
|
|
reg [7:0] rd_rcd_cnt;
|
|
reg [7:0] rd_rtp_cnt;
|
|
reg [7:0] rd_rp_cnt;
|
|
reg single_flag_rd;
|
|
reg array_raddr_eof;
|
|
|
|
wire async_fifo_r_wr_clk;
|
|
wire async_fifo_r_wr_rst_n;
|
|
wire async_fifo_r_wr_en;
|
|
wire [127:0] async_fifo_r_wr_data;
|
|
wire async_fifo_r_full;
|
|
wire async_fifo_r_rd_clk;
|
|
wire async_fifo_r_rd_rst_n;
|
|
wire async_fifo_r_rd_en;
|
|
wire [127:0] async_fifo_r_rd_data;
|
|
wire async_fifo_r_empty;
|
|
|
|
async_fifo #(.FIFO_DEPTH(4),
|
|
.DATA_WIDTH(128)
|
|
) async_fifo_r (
|
|
.wr_clk (async_fifo_r_wr_clk),
|
|
.wr_rst_n (async_fifo_r_wr_rst_n),
|
|
.wr_en (async_fifo_r_wr_en),
|
|
.wr_data (async_fifo_r_wr_data),
|
|
.full (async_fifo_r_full),
|
|
.rd_clk (async_fifo_r_rd_clk),
|
|
.rd_rst_n (async_fifo_r_rd_rst_n),
|
|
.rd_en (async_fifo_r_rd_en),
|
|
.rd_data (async_fifo_r_rd_data),
|
|
.empty (async_fifo_r_empty)
|
|
);
|
|
|
|
assign {rsof,reof,rraddr,rcaddr,wdata} = array_rd_frame_data;
|
|
assign array_rd_frame_ready = (cur_state == ARR_RD_IDLE || ((cur_state == ARR_RD_RADDR) &&
|
|
!array_caddr_vld_rd));
|
|
assign array_rd_done = (cur_state == ARR_RD_RP) && rd_rp_cnt == 'd0;
|
|
assign array2axi_rdata_valid = !async_fifo_r_empty;
|
|
assign array2axi_rdata = async_fifo_r_rd_data;
|
|
|
|
assign async_fifo_r_wr_clk = array_rdata_vld;
|
|
assign async_fifo_r_wr_rst_n = rst_n;
|
|
assign async_fifo_r_wr_en = 1'b1;
|
|
assign async_fifo_r_wr_data = array_rdata;
|
|
assign async_fifo_r_rd_clk = clk;
|
|
assign async_fifo_r_rd_rst_n = rst_n;
|
|
assign async_fifo_r_rd_en = !async_fifo_r_empty;
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
cur_state <= ARR_RD_IDLE;
|
|
end else begin
|
|
cur_state <= next_state;
|
|
end
|
|
end
|
|
|
|
always @(*) begin
|
|
case (cur_state)
|
|
ARR_RD_IDLE : begin
|
|
if (array_rd_frame_valid && rsof) begin
|
|
next_state = ARR_RD_LOWCS;
|
|
end else begin
|
|
next_state = ARR_RD_IDLE;
|
|
end
|
|
end
|
|
ARR_RD_LOWCS : begin
|
|
next_state = ARR_RD_RCD;
|
|
end
|
|
ARR_RD_RCD : begin
|
|
if (rd_rcd_cnt == 'd0) begin
|
|
next_state = ARR_RD_HIGHVLD;
|
|
end else begin
|
|
next_state = ARR_RD_RCD;
|
|
end
|
|
end
|
|
ARR_RD_HIGHVLD : begin
|
|
if (single_flag_rd) begin
|
|
next_state = ARR_RD_RADDRLAST;
|
|
end else begin
|
|
next_state = ARR_RD_RADDR;
|
|
end
|
|
end
|
|
ARR_RD_RADDRLAST : begin
|
|
next_state = ARR_RD_RTP;
|
|
end
|
|
ARR_RD_RADDR : begin
|
|
if (array_raddr_eof) begin
|
|
next_state = ARR_RD_RTP;
|
|
end else begin
|
|
next_state = ARR_RD_RADDR;
|
|
end
|
|
end
|
|
ARR_RD_RTP : begin
|
|
if (rd_ras_cnt == 'd0 && rd_rtp_cnt == 'd0) begin
|
|
next_state = ARR_RD_RP;
|
|
end else begin
|
|
next_state = ARR_RD_RTP;
|
|
end
|
|
end
|
|
ARR_RD_RP : begin
|
|
if (rd_rp_cnt == 'd0) begin
|
|
next_state = ARR_RD_IDLE;
|
|
end else begin
|
|
next_state = ARR_RD_RP;
|
|
end
|
|
end
|
|
default : begin
|
|
next_state = ARR_RD_IDLE;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
array_rd_csn <= 1'b1;
|
|
end else if (cur_state == ARR_RD_LOWCS) begin
|
|
array_rd_csn <= 1'b0;
|
|
end else if (cur_state == ARR_RD_RTP && next_state == ARR_RD_RP) begin
|
|
array_rd_csn <= 1'b1;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
array_rd_raddr <= 'b0;
|
|
end else if (array_rd_frame_valid && array_rd_frame_ready) begin
|
|
array_rd_raddr <= rraddr;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
array_caddr_rd <= 'b0;
|
|
end else if (array_rd_frame_valid && array_rd_frame_ready) begin
|
|
array_caddr_rd <= rcaddr;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
array_caddr_vld_rd <= 'd0;
|
|
end else if (array_caddr_vld_rd == 1'b1) begin
|
|
array_caddr_vld_rd <= 1'b0;
|
|
end else if (cur_state == ARR_RD_HIGHVLD || (cur_state == ARR_RD_RADDR &&
|
|
array_rd_frame_valid && array_rd_frame_ready)) begin
|
|
array_caddr_vld_rd <= 1'b1;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
rd_ras_cnt <= 'd0;
|
|
end else if (cur_state == ARR_RD_LOWCS) begin
|
|
rd_ras_cnt <= array_inner_tras - 1'b1;
|
|
end else if (rd_ras_cnt == 'd0) begin
|
|
rd_ras_cnt <= rd_ras_cnt;
|
|
end else begin
|
|
rd_ras_cnt <= rd_ras_cnt - 1'b1;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
rd_rcd_cnt <= 'd0;
|
|
end else if (cur_state == ARR_RD_LOWCS) begin
|
|
rd_rcd_cnt <= array_inner_trcd_rd - 2'b10;
|
|
end else if (cur_state == ARR_RD_RCD) begin
|
|
if (rd_rcd_cnt == 'd0) begin
|
|
rd_rcd_cnt <= rd_rcd_cnt;
|
|
end else begin
|
|
rd_rcd_cnt <= rd_rcd_cnt - 1'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
rd_rtp_cnt <= 'd0;
|
|
end else if (cur_state == ARR_RD_LOWCS) begin
|
|
rd_rtp_cnt <= array_inner_trtp - 1'b1;
|
|
end else if (cur_state == ARR_RD_RTP) begin
|
|
if (rd_rtp_cnt == 'd0) begin
|
|
rd_rtp_cnt <= rd_rtp_cnt;
|
|
end else begin
|
|
rd_rtp_cnt <= rd_rtp_cnt - 1'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
rd_rp_cnt <= 'd0;
|
|
end else if (cur_state == ARR_RD_LOWCS) begin
|
|
rd_rp_cnt <= array_inner_trp - 1'b1;
|
|
end else if (cur_state == ARR_RD_RP) begin
|
|
if (rd_rp_cnt == 'd0) begin
|
|
rd_rp_cnt <= rd_rp_cnt;
|
|
end else begin
|
|
rd_rp_cnt <= rd_rp_cnt - 1'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
single_flag_rd <= 'd0;
|
|
end else if (cur_state == ARR_RD_IDLE && array_rd_frame_valid && rsof) begin
|
|
single_flag_rd <= reof;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
array_raddr_eof <= 'd0;
|
|
end else if (array_rd_frame_valid && array_rd_frame_ready) begin
|
|
array_raddr_eof <= reof;
|
|
end else begin
|
|
array_raddr_eof <= 'd0;
|
|
end
|
|
end
|
|
|
|
|
|
endmodule |