Files
IC_PRJ/rtl/wchannel.v
Core_kingdom 163d200aae v1.0
2025-08-06 13:42:13 +08:00

169 lines
5.1 KiB
Verilog

module wchannel(
input clk,
input rst_n,
input axi_s_awvalid,
input [7:0] axi_s_awlen,
input [25:0] axi_s_awaddr,
output axi_s_awready,
input axi_s_wvalid,
input axi_s_wlast,
input [63:0] axi_s_wdata,
output axi_s_wready,
output wframe_valid,
output [159:0] wframe_data,
input wframe_ready
);
wire wsof,weof;
reg [15:0] wraddr;
reg [5:0] wcaddr;
wire [127:0] wdata;
wire [7:0] awlen;
wire [15:0] awraddr;
wire [5:0] awcaddr;
reg [6:0] wframe_cnt;
reg [1:0] cur_state,next_state;
localparam [1:0] WCH_IDLE = 2'b01;
localparam [1:0] WCH_SD_WADDR = 2'b10;
localparam [1:0] WCH_SD_WDATA = 2'b11;
wire sync_fifo_aw_wr_en;
wire [29:0] sync_fifo_aw_wr_data;
wire sync_fifo_aw_rd_en;
wire [29:0] sync_fifo_aw_rd_data;
wire sync_fifo_aw_full;
wire sync_fifo_aw_empty;
wire sync_fifo_w_wr_en;
wire [63:0] sync_fifo_w_wr_data;
wire sync_fifo_w_rd_en;
wire [127:0] sync_fifo_w_rd_data;
wire sync_fifo_w_full;
wire sync_fifo_w_empty;
assign sync_fifo_aw_wr_en = axi_s_awvalid && axi_s_awready;
assign sync_fifo_aw_wr_data = {axi_s_awaddr[25:4],axi_s_awlen};
assign sync_fifo_aw_rd_en = wframe_ready && weof && !sync_fifo_aw_empty;
assign {awraddr,awcaddr,awlen} = sync_fifo_aw_rd_data;
assign axi_s_awready = !sync_fifo_aw_full;
assign sync_fifo_w_wr_en = axi_s_wvalid && axi_s_wready;
assign sync_fifo_w_wr_data = axi_s_wdata;
assign sync_fifo_w_rd_en = wframe_valid && wframe_ready;
assign wdata = sync_fifo_w_rd_data;
assign axi_s_wready = !sync_fifo_w_full;
assign wsof = wframe_valid && (wframe_cnt == 7'd0);
assign weof = wframe_valid && ((wframe_cnt == awlen >> 1'b1));
assign wframe_data = {wsof,weof,wraddr,wcaddr,wdata,awlen};
assign wframe_valid = !sync_fifo_w_empty && (cur_state == WCH_SD_WDATA);
sync_fifo #(.DATA_WIDTH(30),
.FIFO_DEPTH(4)
) sync_fifo_aw (.clk (clk),
.rst_n (rst_n),
.wr_en (sync_fifo_aw_wr_en),
.wr_data (sync_fifo_aw_wr_data),
.rd_en (sync_fifo_aw_rd_en),
.rd_data (sync_fifo_aw_rd_data),
.full (sync_fifo_aw_full),
.empty (sync_fifo_aw_empty)
);
sync_fifo_64_to_128 #(
.DATA_IN_WIDTH(64),
.DATA_OUT_WIDTH(128),
.FIFO_DEPTH(8)
) sync_fifo_w (.clk (clk),
.rst_n (rst_n),
.wr_en (sync_fifo_w_wr_en),
.wr_data (sync_fifo_w_wr_data),
.rd_en (sync_fifo_w_rd_en),
.rd_data (sync_fifo_w_rd_data),
.full (sync_fifo_w_full),
.empty (sync_fifo_w_empty)
);
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wframe_cnt <= 'd0;
end else if (sync_fifo_w_rd_en) begin
if (wframe_cnt == (awlen >> 1'b1)) begin
wframe_cnt <= 'd0;
end else begin
wframe_cnt <= wframe_cnt + 1'b1;
end
end
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cur_state <= WCH_IDLE;
end else begin
cur_state <= next_state;
end
end
always@(*) begin
case(cur_state)
WCH_IDLE: begin
if(sync_fifo_aw_wr_en) begin
next_state <= WCH_SD_WADDR;
end else begin
next_state <= WCH_IDLE;
end
end
WCH_SD_WADDR: begin
next_state <= WCH_SD_WDATA;
end
WCH_SD_WDATA: begin
if(sync_fifo_w_rd_en && (wframe_cnt == (awlen >> 1))) begin
next_state <= WCH_IDLE;
end else begin
next_state <= WCH_SD_WDATA;
end
end
default : begin
next_state <= WCH_IDLE;
end
endcase
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wcaddr <= 'd0;
end else if (cur_state == WCH_SD_WADDR) begin
wcaddr <= awcaddr;
end else if (sync_fifo_w_rd_en) begin
if (wcaddr == 6'h3f) begin
wcaddr <= 'd0;
end else begin
wcaddr <= wcaddr + 1'b1;
end
end
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wraddr <= 'd0;
end else if (cur_state == WCH_SD_WADDR) begin
if (sync_fifo_w_rd_en && (wcaddr == 6'h3f)) begin
wraddr <= wraddr + 1'b1;
end else begin
wraddr <= wraddr;
end
end
end
endmodule