/********************************************** _ _ Cook Darwin __
_ descript: author : Cook.Darwin Version: VERA.0.0 creaded: 2016/11/19 madified: ***********************************************/ `timescale 1ns/1ps module width_combin #(
parameter DSIZE = 1, parameter NSIZE = 8
)(
input clock, input rst_n, input [DSIZE-1:0] wr_data, input wr_vld, output logic wr_ready, input wr_last, input wr_align_last, output logic[DSIZE*NSIZE-1:0] rd_data, output logic rd_vld, input rd_ready, output logic rd_last
);
assign wr_ready = rd_ready;
localparam RSIZE = (NSIZE<16)? 4 :
(NSIZE<32)? 5 : (NSIZE<64)? 6 : (NSIZE<128)? 7 : 8;
logic last_point;
always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) last_point <= 1'b0; else begin if(wr_vld && wr_ready && wr_last) last_point <= 1'b1; else if(rd_vld && rd_ready && last_point) last_point <= 1'b0; else last_point <= last_point; end
reg [RSIZE-1:0] point;
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) point <= {RSIZE{1'b0}}; else begin if(last_point)begin if(wr_vld && wr_ready) point <= {RSIZE{1'b0}} +1'b1; else point <= '0; end else if(wr_vld && wr_ready)begin if(wr_align_last || wr_last) // if(wr_align_last) point <= {RSIZE{1'b0}}; else begin if(point == NSIZE-1) point <= {RSIZE{1'b0}}; else point <= point + 1'b1; end end else point <= point;
end end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) rd_data <= {(DSIZE*NSIZE){1'b0}}; else begin if(wr_vld && wr_ready) rd_data[DSIZE*(NSIZE-point)-1-:DSIZE] <= wr_data; else if (last_point && !rd_vld) // rd_data <= {rd_data[DSIZE*NSIZE-1-DSIZE:0],rd_data[DSIZE*NSIZE-1-:DSIZE]}; rd_data[DSIZE*(NSIZE-point)-1-:DSIZE] <= wr_data; else rd_data[DSIZE*(NSIZE-point)-1-:DSIZE] <= rd_data[DSIZE*(NSIZE-point)-1-:DSIZE]; end
end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) rd_vld <= 1'b0; else begin if(point==(NSIZE-1) && wr_vld && wr_ready ) rd_vld <= 1'b1; else if(wr_vld && wr_ready && wr_last) rd_vld <= 1'b1; else if(last_point && !rd_vld) rd_vld <= 1'b1; else if(rd_vld && rd_ready) rd_vld <= 1'b0; else rd_vld <= rd_vld; end
end
always@(posedge clock/*,negedge rst_n*/)begin
if(~rst_n) rd_last <= 1'b0; else begin // if(point==(NSIZE-1) && wr_vld && wr_ready ) if(wr_vld && wr_ready ) rd_last <= wr_last; else if(last_point && !rd_last) rd_last <= 1'b1; else if(rd_vld && rd_ready) rd_last <= 1'b0; else rd_last <= rd_last; end
end
endmodule