/********************************************** _ _ Cook Darwin __
_ descript: author : Cook.Darwin Version: VERA.0.0 creaded: ###### Thu Apr 30 11:38:38 CST 2020 madified: ***********************************************/ `timescale 1ns/1ps (* axi_stream = “true” *) module axi_stream_packet_long_fifo #(
parameter DEPTH = 2, //2-4 parameter BYTE_DEPTH = 8096, parameter USE_KEEP = "OFF"
)(
(* up_stream = "true" *) axi_stream_inf.slaver axis_in, (* down_stream = "true" *) axi_stream_inf.master axis_out
);
assign axis_out.axis_tuser = '0;
//—>> NATIVE FIFO IP <<—————————— // (* dont_touch = “true” *) logic data_fifo_full; // (* dont_touch = “true” *) logic data_fifo_empty; logic [axis_in.DSIZE-1:0] stream_fifo_data;
generate
if(USE_KEEP=="OFF" || USE_KEEP=="FALSE")begin fifo_36kb_long #( .DSIZE (axis_out.DSIZE ), .DEPTH (BYTE_DEPTH ) )fifo_36kb_long_inst( /* input */ .wr_clk (axis_in.aclk ), /* input */ .wr_rst (~axis_in.aresetn ), /* input */ .rd_clk (axis_out.aclk ), /* input */ .rd_rst (~axis_out.aresetn ), /* input [DSIZE-1:0] */ .din (axis_in.axis_tdata ), /* input */ .wr_en ((axis_in.axis_tvalid && !data_fifo_full && axis_in.axis_tready) ), /* input */ .rd_en ((axis_out.axis_tvalid && !data_fifo_empty && axis_out.axis_tready) ), /* output [DSIZE-1:0] */ .dout (axis_out.axis_tdata ), /* output */ .full (data_fifo_full ), /* output */ .empty (data_fifo_empty ) ); end else begin fifo_36kb_long #( .DSIZE (axis_out.DSIZE+axis_out.KSIZE ), .DEPTH (BYTE_DEPTH ) )fifo_36kb_long_inst( /* input */ .wr_clk (axis_in.aclk ), /* input */ .wr_rst (~axis_in.aresetn ), /* input */ .rd_clk (axis_out.aclk ), /* input */ .rd_rst (~axis_out.aresetn ), /* input [DSIZE-1:0] */ .din ({axis_in.axis_tkeep, axis_in.axis_tdata} ), /* input */ .wr_en ((axis_in.axis_tvalid && !data_fifo_full && axis_in.axis_tready) ), /* input */ .rd_en ((axis_out.axis_tvalid && !data_fifo_empty && axis_out.axis_tready) ), /* output [DSIZE-1:0] */ .dout ({axis_out.axis_tkeep, axis_out.axis_tdata} ), /* output */ .full (data_fifo_full ), /* output */ .empty (data_fifo_empty ) ); end
endgenerate
// assign axis_out.axis_tdata = axis_out.axis_tvalid? stream_fifo_data : '0; //—<< NATIVE FIFO IP >>——————————
//—>> PACKET <<————————————– // (* dont_touch = “true” *) logic packet_fifo_full; // (* dont_touch = “true” *) logic packet_fifo_empty; logic [15:0] w_bytes_total; logic [15:0] r_bytes_total; logic w_total_eq_1; logic r_total_eq_1;
assign w_total_eq_1 = w_bytes_total=='0;
localparam IDEPTH = (DEPTH<4)? 4 : DEPTH;
independent_clock_fifo #(
.DEPTH (IDEPTH ), .DSIZE (16+1 )
)independent_clock_fifo_inst( /* input */ .wr_clk (axis_in.aclk ), /* input */ .wr_rst_n (axis_in.aresetn ), /* input */ .rd_clk (axis_out.aclk ), /* input */ .rd_rst_n (axis_out.aresetn ), /* input [DSIZE-1:0] */ .wdata ({w_total_eq_1,w_bytes_total} ), /* input */ .wr_en ((axis_in.axis_tvalid && axis_in.axis_tlast && axis_in.axis_tready) ), /* output logic */ .rdata ({r_total_eq_1,r_bytes_total} ), /* input */ .rd_en ((axis_out.axis_tvalid && axis_out.axis_tlast && axis_out.axis_tready) ), /* output logic */ .empty (packet_fifo_empty ), /* output logic */ .full (packet_fifo_full ) );
logic cc_fifo_wr_data; logic cc_fifo_rd_data; logic cc_fifo_wr_en; logic cc_fifo_rd_en; logic cc_fifo_full; logic cc_fifo_empty;
independent_clock_fifo #(
.DEPTH (IDEPTH ), .DSIZE (1 )
)independent_clock_delay_cc_wr_fifo_inst( /* input */ .wr_clk (axis_in.aclk ), /* input */ .wr_rst_n (axis_in.aresetn ), /* input */ .rd_clk (axis_out.aclk ), /* input */ .rd_rst_n (axis_out.aresetn ), /* input [DSIZE-1:0] */ .wdata (cc_fifo_wr_data ), /* input */ .wr_en (cc_fifo_wr_en ), /* output logic */ .rdata (cc_fifo_rd_data ), /* input */ .rd_en (cc_fifo_rd_en ), /* output logic */ .empty (cc_fifo_empty ), /* output logic */ .full (cc_fifo_full ) );
assign cc_fifo_wr_en = 1'b1; assign cc_fifo_wr_data = (axis_in.axis_tvalid && axis_in.axis_tlast && axis_in.axis_tready);
assign cc_fifo_rd_en = 1'b1;
logic cc_fifo_rd_data_lat;
latency #(
.LAT (6), .DSIZE (1)
)latency_inst( /* input */ .clk (axis_out.aclk ), /* input */ .rst_n (axis_out.aresetn ), /* input [DSIZE-1:0] */ .d (cc_fifo_rd_data ), /* output */ .q (cc_fifo_rd_data_lat) );
logic delay_fifo_empty; logic delay_fifo_full;
independent_clock_fifo #(
.DEPTH (IDEPTH ), .DSIZE (1 )
)independent_clock_delay_fifo_inst( /* input */ .wr_clk (axis_out.aclk ), /* input */ .wr_rst_n (axis_out.aresetn ), /* input */ .rd_clk (axis_out.aclk ), /* input */ .rd_rst_n (axis_out.aresetn ), /* input [DSIZE-1:0] */ .wdata (1'b0 ), /* input */ .wr_en (cc_fifo_rd_data_lat ), /* output logic */ .rdata (), /* input */ .rd_en ((axis_out.axis_tvalid && axis_out.axis_tlast && axis_out.axis_tready) ), /* output logic */ .empty (delay_fifo_empty ), /* output logic */ .full (delay_fifo_full ) );
assign axis_in.axis_tready = !packet_fifo_full && !data_fifo_full; assign axis_out.axis_tvalid = !packet_fifo_empty && !data_fifo_empty && !delay_fifo_empty; //—<< PACKET >>————————————– //—>> bytes counter <<——————————- logic reset_w_bytes; assign #1 reset_w_bytes = axis_in.axis_tvalid && axis_in.axis_tlast && axis_in.axis_tready;
always@(posedge axis_in.aclk,negedge axis_in.aresetn)
if(~axis_in.aresetn) w_bytes_total <= '0; else begin // if(axis_in.axis_tvalid && axis_in.axis_tlast && axis_in.axis_tready) if(reset_w_bytes) w_bytes_total <= '0; else if(axis_in.axis_tvalid && axis_in.axis_tready) w_bytes_total <= w_bytes_total + 1'b1; else w_bytes_total <= w_bytes_total; end
logic [15:0] out_cnt;
always@(posedge axis_out.aclk,negedge axis_out.aresetn)
if(~axis_out.aresetn) out_cnt <= '0; else begin if(axis_out.axis_tvalid && axis_out.axis_tlast && axis_out.axis_tready) out_cnt <= '0; else if(axis_out.axis_tvalid && axis_out.axis_tready) out_cnt <= out_cnt + 1'b1; else out_cnt <= out_cnt; end
//—<< bytes counter >>——————————- //—>> READ LAST <<———————————– logic native_last;
always@(posedge axis_out.aclk,negedge axis_out.aresetn)
if(~axis_out.aresetn) native_last <= 1'b0; else begin if(axis_out.axis_tvalid && native_last && axis_out.axis_tready) native_last <= 1'b0; else if(out_cnt == (r_bytes_total-1) && axis_out.axis_tvalid && axis_out.axis_tready) native_last <= 1'b1; else native_last <= native_last; end
assign axis_out.axis_tlast = native_last || r_total_eq_1; //—<< READ LAST >>———————————– //— >> ASSER <<————————————– initial begin
wait(axis_out.aresetn); forever begin repeat(10) @(posedge axis_out.aclk); wait(data_fifo_full); assert(packet_fifo_full == 1) else begin $error("long fifo full ,data stream is too long"); $stop; end end
end //— << ASSER >>————————————– endmodule