/********************************************** _ _ Cook Darwin __
_ descript: author : Cook.Darwin Version: VERA.1.0
add user signal
creaded: 2016/11/21 madified: ***********************************************/ `timescale 1ns/1ps module width_destruct_A1 #(
parameter DSIZE = 1, parameter NSIZE = 8, parameter USIZE = 1
)(
input clock, input rst_n, input [DSIZE*NSIZE-1:0] wr_data, input wr_vld, output logic wr_ready, input [USIZE-1:0] wr_user, input wr_last, output logic[DSIZE-1:0] rd_data, output logic rd_vld, output logic rd_last, output logic[USIZE-1:0] rd_user, input rd_ready
);
// assign rd_vld = wr_vld;
localparam RSIZE = (NSIZE<16)? 4 :
(NSIZE<32)? 5 : (NSIZE<64)? 6 : (NSIZE<128)? 7 : 8;
// reg [RSIZE-1:0] point;
logic [DSIZE-1:0] overflow_data; logic overflow; logic overflow_last;
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) point <= {RSIZE{1'b0}}; else begin // if(rd_vld && rd_ready && rd_last) // point <= {RSIZE{1'b0}}; if(wr_vld && wr_ready && wr_last) point <= {RSIZE{1'b0}}; else if(overflow && rd_ready) point <= {RSIZE{1'b0}}; else if(wr_vld && rd_ready)begin if(point == NSIZE-1) point <= {RSIZE{1'b0}}; else point <= point + 1'b1; end else point <= point;
end end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) wr_ready <= 1'b0; else begin if(point==(NSIZE-2) && wr_vld && rd_ready) wr_ready <= 1'b1; else if(wr_ready && wr_vld) wr_ready <= 1'b0; else wr_ready <= wr_ready; end
end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) overflow_data <= '0; else begin if((wr_ready & wr_vld) && (!rd_ready & rd_vld) ) overflow_data <= wr_data[DSIZE-1:0]; else overflow_data <= overflow_data; end
end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) overflow <= '0; else begin if((wr_ready & wr_vld) && (!rd_ready & rd_vld) ) overflow <= 1'b1; else if(overflow && rd_ready) overflow <= 1'b0; else overflow <= overflow; end
end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) overflow_last <= '0; else begin if((wr_ready & wr_vld) && (!rd_ready & rd_vld) ) overflow_last <= wr_last; else if(overflow && rd_ready && overflow_last) overflow_last <= 1'b0; else overflow_last <= overflow_last; end
end
// logic last_byte; // // always@(posedge clock/*,negedge rst_n*/)begin // if(~rst_n) last_byte <= 1'b0; // else begin // if(point==(NSIZE-1) && wr_vld && rd_ready) // last_byte <= 1'b1; // else if(last_byte && wr_vld) // last_byte <= 1'b0; // else last_byte <= last_byte; // end // end
// always@(posedge clock/*,negedge rst_n*/)begin // if(~rst_n) rd_data <= {DSIZE{1'b0}}; // else begin // // if(wr_vld && rd_ready) // if(wr_vld) // rd_data <= wr_data; // else rd_data <= rd_data; // // // rd_data <= wr_data; // end // end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) rd_data <= {DSIZE{1'b0}}; else begin case({overflow,wr_vld,rd_vld,rd_ready}) 4'b1000: rd_data <= rd_data; 4'b1001: rd_data <= overflow_data; 4'b1010: rd_data <= rd_data; 4'b1011: rd_data <= overflow_data; 4'b1100: rd_data <= rd_data; 4'b1101: rd_data <= overflow_data; 4'b1110: rd_data <= rd_data; 4'b1111: rd_data <= overflow_data; 4'b0000: rd_data <= rd_data; 4'b0001: rd_data <= rd_data; 4'b0010: rd_data <= rd_data; 4'b0011: rd_data <= rd_data; 4'b0100: rd_data <= rd_data; 4'b0101: rd_data <= wr_data[DSIZE*(NSIZE-point)-1-:DSIZE]; 4'b0110: rd_data <= rd_data; 4'b0111: rd_data <= wr_data[DSIZE*(NSIZE-point)-1-:DSIZE]; default: rd_data <= rd_data; endcase end
end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) rd_vld <= 1'b0; else begin // if(wr_vld && wr_ready && wr_last) // rd_vld <= 1'b0; // else case({overflow,wr_vld,rd_vld,rd_ready}) 4'b1000: rd_vld <= 1'b0; 4'b1001: rd_vld <= 1'b1; 4'b1010: rd_vld <= 1'b1; 4'b1011: rd_vld <= 1'b1; 4'b1100: rd_vld <= 1'b0; 4'b1101: rd_vld <= 1'b1; 4'b1110: rd_vld <= 1'b1; 4'b1111: rd_vld <= 1'b1; 4'b0000: rd_vld <= 1'b0; 4'b0001: rd_vld <= 1'b0; 4'b0010: rd_vld <= 1'b1; 4'b0011: rd_vld <= 1'b0; 4'b0100: rd_vld <= 1'b0; 4'b0101: rd_vld <= 1'b1; 4'b0110: rd_vld <= 1'b1; 4'b0111: rd_vld <= 1'b1; default: rd_vld <= 1'b0; endcase end
end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) rd_last <= 1'b0; else begin case({overflow,wr_vld,rd_vld,rd_ready}) 4'b1000: rd_last <= 1'b0; 4'b1001: rd_last <= overflow_last; 4'b1010: rd_last <= rd_last; 4'b1011: rd_last <= overflow_last; 4'b1100: rd_last <= 1'b0; 4'b1101: rd_last <= overflow_last; 4'b1110: rd_last <= rd_last; 4'b1111: rd_last <= overflow_last; 4'b0000: rd_last <= 1'b0; 4'b0001: rd_last <= 1'b0; 4'b0010: rd_last <= rd_last; 4'b0011: rd_last <= 1'b0; 4'b0100: rd_last <= 1'b0; 4'b0101: rd_last <= point==(NSIZE-1) && wr_last; 4'b0110: rd_last <= rd_last; 4'b0111: rd_last <= point==(NSIZE-1) && wr_last; default: rd_last <= 1'b0; endcase end
end
logic [USIZE-1:0] overflow_user;
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) overflow_user <= '0; else begin if((wr_ready & wr_vld) && (!rd_ready & rd_vld) ) overflow_user <= wr_user; else overflow_user <= overflow_user; end
end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) rd_user <= {USIZE{1'b0}}; else begin case({overflow,wr_vld,rd_vld,rd_ready}) 4'b1000: rd_user <= rd_user; 4'b1001: rd_user <= overflow_user; 4'b1010: rd_user <= rd_user; 4'b1011: rd_user <= overflow_user; 4'b1100: rd_user <= rd_user; 4'b1101: rd_user <= overflow_user; 4'b1110: rd_user <= rd_user; 4'b1111: rd_user <= overflow_user; 4'b0000: rd_user <= rd_user; 4'b0001: rd_user <= rd_user; 4'b0010: rd_user <= rd_user; 4'b0011: rd_user <= rd_user; 4'b0100: rd_user <= rd_user; 4'b0101: rd_user <= wr_user; 4'b0110: rd_user <= rd_user; 4'b0111: rd_user <= wr_user; default: rd_user <= rd_user; endcase end
end
endmodule