215 lines
6.7 KiB
Verilog
215 lines
6.7 KiB
Verilog
module rchannel (
|
|
input clk,
|
|
input rst_n,
|
|
input axi_s_arvalid,
|
|
input [7:0] axi_s_arlen,
|
|
input [25:0] axi_s_araddr,
|
|
output axi_s_arready,
|
|
output axi_s_rvalid,
|
|
output axi_s_rlast,
|
|
output [63:0] axi_s_rdata,
|
|
output rframe_valid,
|
|
output [159:0] rframe_data,
|
|
input rframe_ready,
|
|
input array2axi_rdata_valid,
|
|
input [127:0] array2axi_rdata
|
|
);
|
|
|
|
wire rsof,reof;
|
|
reg [15:0] rraddr;
|
|
reg [5:0] rcaddr;
|
|
wire [127:0] wdata;
|
|
wire [7:0] arlen;
|
|
|
|
wire [15:0] arraddr;
|
|
wire [5:0] arcaddr;
|
|
|
|
reg [6:0] rframe_cnt;
|
|
reg [7:0] rdata_cnt;
|
|
|
|
|
|
reg [1:0] cur_state,next_state;
|
|
localparam [1:0] RCH_IDLE = 2'b00;
|
|
localparam [1:0] RCH_GET_RADDR = 2'b01;
|
|
localparam [1:0] RCH_SD_RADDR = 2'b10;
|
|
|
|
|
|
|
|
|
|
wire sync_fifo_ar_wr_en;
|
|
wire sync_fifo_ar_rd_en;
|
|
wire sync_fifo_ar_full;
|
|
wire sync_fifo_ar_empty;
|
|
wire [29:0] sync_fifo_ar_wr_data;
|
|
wire [29:0] sync_fifo_ar_rd_data;
|
|
|
|
|
|
sync_fifo #(.DATA_WIDTH(30),
|
|
.FIFO_DEPTH(4)
|
|
) sync_fifo_ar (
|
|
.clk (clk),
|
|
.rst_n (rst_n),
|
|
.wr_en (sync_fifo_ar_wr_en),
|
|
.wr_data (sync_fifo_ar_wr_data),
|
|
.full (sync_fifo_ar_full),
|
|
.rd_en (sync_fifo_ar_rd_en),
|
|
.rd_data (sync_fifo_ar_rd_data),
|
|
.empty (sync_fifo_ar_empty)
|
|
);
|
|
|
|
wire sync_fifo_arlen_wr_en;
|
|
wire sync_fifo_arlen_rd_en;
|
|
wire sync_fifo_arlen_full;
|
|
wire sync_fifo_arlen_empty;
|
|
wire [7:0] sync_fifo_arlen_wr_data;
|
|
wire [7:0] sync_fifo_arlen_rd_data;
|
|
|
|
|
|
sync_fifo #(.DATA_WIDTH(8),
|
|
.FIFO_DEPTH(4)
|
|
) sync_fifo_arlen (
|
|
.clk (clk),
|
|
.rst_n (rst_n),
|
|
.wr_en (sync_fifo_arlen_wr_en),
|
|
.wr_data (sync_fifo_arlen_wr_data),
|
|
.full (sync_fifo_arlen_full),
|
|
.rd_en (sync_fifo_arlen_rd_en),
|
|
.rd_data (sync_fifo_arlen_rd_data),
|
|
.empty (sync_fifo_arlen_empty)
|
|
);
|
|
|
|
wire sync_fifo_r_wr_en;
|
|
wire sync_fifo_r_rd_en;
|
|
wire sync_fifo_r_full;
|
|
wire sync_fifo_r_empty;
|
|
wire [127:0]sync_fifo_r_wr_data;
|
|
wire [63:0] sync_fifo_r_rd_data;
|
|
|
|
|
|
sync_fifo_128_to_64 #(.DATA_IN_WIDTH(128),
|
|
.FIFO_DEPTH(8),
|
|
.DATA_OUT_WIDTH(64)
|
|
) sync_fifo_r (
|
|
.clk (clk),
|
|
.rst_n (rst_n),
|
|
.wr_en (sync_fifo_r_wr_en),
|
|
.wr_data (sync_fifo_r_wr_data),
|
|
.full (sync_fifo_r_full),
|
|
.rd_en (sync_fifo_r_rd_en),
|
|
.rd_data (sync_fifo_r_rd_data),
|
|
.empty (sync_fifo_r_empty)
|
|
);
|
|
|
|
|
|
assign axi_s_arready = !sync_fifo_ar_full;
|
|
assign rframe_valid = (cur_state == RCH_SD_RADDR);
|
|
assign rframe_data = {rsof,reof,rraddr,rcaddr,128'b0,arlen};
|
|
assign axi_s_rvalid = !sync_fifo_r_empty;
|
|
assign axi_s_rdata = sync_fifo_r_rd_data;
|
|
assign axi_s_rlast = axi_s_rvalid && (rdata_cnt == sync_fifo_arlen_rd_data);
|
|
|
|
assign sync_fifo_ar_wr_en = axi_s_arvalid && axi_s_arready;
|
|
assign sync_fifo_ar_wr_data = {axi_s_araddr[25:4],axi_s_arlen};
|
|
assign sync_fifo_ar_rd_en = rframe_ready && rframe_valid &&
|
|
rframe_cnt == arlen>>1'b1 && !sync_fifo_ar_empty;
|
|
|
|
assign {arraddr , arcaddr, arlen} = sync_fifo_ar_rd_data;
|
|
assign sync_fifo_arlen_wr_en = rframe_valid && rframe_ready &&
|
|
rframe_cnt == arlen >> 1'b1;
|
|
assign sync_fifo_arlen_wr_data = arlen;
|
|
assign sync_fifo_arlen_rd_en = axi_s_rlast && axi_s_rvalid;
|
|
assign rsof = rframe_valid && (rframe_cnt == 7'b0);
|
|
assign reof = rframe_valid && (rframe_cnt == arlen >>1'b1);
|
|
|
|
|
|
assign sync_fifo_r_wr_en = array2axi_rdata_valid && !sync_fifo_r_full;
|
|
assign sync_fifo_r_wr_data = array2axi_rdata;
|
|
assign sync_fifo_r_rd_en = !sync_fifo_r_empty;
|
|
|
|
|
|
always@(posedge clk or negedge rst_n) begin
|
|
if(!rst_n) begin
|
|
cur_state <= RCH_IDLE;
|
|
end else begin
|
|
cur_state <= next_state;
|
|
end
|
|
end
|
|
|
|
always@(*) begin
|
|
case(cur_state)
|
|
RCH_IDLE: begin
|
|
if(sync_fifo_ar_wr_en) begin
|
|
next_state <= RCH_GET_RADDR;
|
|
end else begin
|
|
next_state <= RCH_IDLE;
|
|
end
|
|
end
|
|
RCH_GET_RADDR: begin
|
|
next_state <= RCH_SD_RADDR;
|
|
end
|
|
RCH_SD_RADDR: begin
|
|
if(rframe_ready && rframe_valid && rframe_cnt == arlen >>1) begin
|
|
next_state <= RCH_IDLE;
|
|
end else begin
|
|
next_state <= RCH_SD_RADDR;
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
|
|
always@(posedge clk or negedge rst_n) begin
|
|
if(!rst_n) begin
|
|
rraddr <= 'd0;
|
|
end else if(cur_state == RCH_GET_RADDR) begin
|
|
rraddr <= arraddr;
|
|
if(rframe_valid && rframe_ready) begin
|
|
if(rcaddr == 6'b111111) begin
|
|
rraddr <= rraddr + 1'b1;
|
|
end else begin
|
|
rraddr <= rraddr;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
always@(posedge clk or negedge rst_n) begin
|
|
if(!rst_n) begin
|
|
rcaddr <= 'd0;
|
|
end else if (cur_state == RCH_GET_RADDR) begin
|
|
rcaddr <= arcaddr;
|
|
if(rframe_valid && rframe_ready) begin
|
|
if(rcaddr == 6'b111111) begin
|
|
rcaddr <= 'd0;
|
|
end else begin
|
|
rcaddr <= rcaddr + 1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
always@(posedge clk or negedge rst_n) begin
|
|
if(!rst_n) begin
|
|
rframe_cnt <= 'd0;
|
|
end else if (rframe_valid && rframe_ready) begin
|
|
if(rframe_cnt == arlen>>1'b1) begin
|
|
rframe_cnt <= 'd0;
|
|
end else begin
|
|
rframe_cnt <= rframe_cnt + 1'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always@(posedge clk or negedge rst_n) begin
|
|
if(!rst_n) begin
|
|
rdata_cnt <= 'd0;
|
|
end else if(axi_s_rvalid) begin
|
|
if(rdata_cnt == sync_fifo_arlen_rd_data) begin
|
|
rdata_cnt <= 'd0;
|
|
end else begin
|
|
rdata_cnt <= rdata_cnt + 1'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|