module byte_combine
(
input rst_n,
input clk,
input sop,
input eop,
input data_valid,
input [3:0] byte_valid,
input [63:0] data_in,
output reg sop_out,
output reg eop_out,
output reg data_valid_out,
output reg [3:0] byte_valid_out,
output reg [63:0] data_out,
output reg [6:0] dma_type_packet_cnt
);
reg wr_en;
reg [3:0] mod_byte;
wire [3:0] total_byte;
reg [63:0] data_remain;
reg [3:0] byte_acc;
reg eop_dly;
reg data_valid_dly;
//----------------------------------------------------------------------------//
assign total_byte = sop? byte_valid: (mod_byte + byte_valid);
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
mod_byte <= 4'd0;
else if (sop == 1'b1)
mod_byte <= {1'b0,byte_valid[2:0]};
else if (total_byte[3] == 1'b1)
mod_byte <= {1'b0,total_byte[2:0]};
else
mod_byte <= total_byte;
end
always @ (*)
begin
if ((eop == 1'b1) && (mod_byte + byte_valid < 4'd8))
wr_en = 1'b1;
else if (total_byte[3] && data_valid)
wr_en = 1'b1;
else
wr_en = 1'b0;
end
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
data_remain <= 64'd0;
else if (sop == 1'b1)
begin
if (byte_valid == 4'd8)
data_remain <= 64'd0;
else
data_remain <= data_in >> {8 - byte_valid, 3'd0};
end
else if (wr_en == 1'b1)
data_remain <= data_in >> {4'd8 - mod_byte, 3'd0};
else
data_remain <= data_remain | data_in << {mod_byte,3'd0};
end
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
data_out <= 64'd0;
else if (sop == 1'b1)
begin
if (byte_valid == 4'd8)
data_out <= data_in;
else
data_out <= 64'd0;
end
else if (eop_dly == 1'b1)
data_out <= data_remain;
else if (wr_en == 1'b1)
data_out <= data_remain | data_in << {mod_byte,3'd0};
else
data_out <= 64'd0;
end
//----------------------------------------------------------------------------//
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
byte_acc <= 4'd0;
else if (sop == 1'b1)
byte_acc <= byte_valid;
else if (byte_acc < 4'd8)
byte_acc <= byte_acc + byte_valid ;
else ;
end
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
sop_out <= 1'b0;
else if ((sop == 1'b1) && (byte_valid == 4'd8))
sop_out <= 1'b1;
else if ((byte_acc < 4'd8) && (byte_acc + byte_valid >= 4'd8))
sop_out <= 1'b1;
else
sop_out <= 1'b0;
end
//----------------------------------------------------------------------------//
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
eop_dly <= 1'b0;
else
eop_dly <= eop;
end
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
eop_out <= 1'b0;
else if ((eop == 1'b1) && (byte_valid + mod_byte <= 4'd8))
eop_out <= 1'b1;
else if ((eop_dly == 1'b1) && (eop_out == 1'b0))
eop_out <= 1'b1;
else
eop_out <= 1'b0;
end
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
data_valid_dly <= 1'b0;
else
data_valid_dly <= data_valid;
end
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
data_valid_out <= 1'b0;
else if (data_valid_dly && eop_dly && (~eop_out))
data_valid_out <= 1'b1;
else
data_valid_out <= wr_en;
end
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
byte_valid_out <= 4'd0;
else if ((eop == 1'b1) && (total_byte < 4'd8))
byte_valid_out <= total_byte;
else if (wr_en == 1'b1)
byte_valid_out <= 4'd8;
else if (data_valid_dly && eop_dly && (~eop_out))
byte_valid_out <= mod_byte;
else
byte_valid_out <= 4'd0;
end
//----------------------------------------------------------------------------//
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
dma_type_packet_cnt <= 7'd0;
else if ((sop == 1'b1) && (byte_valid == 4'd8))
dma_type_packet_cnt <= 7'd0;
else if ((byte_acc < 4'd8) && (byte_acc + byte_valid >= 4'd8))
dma_type_packet_cnt <= 7'd0;
else if ((wr_en == 1'b1) || ((eop == 1'b1) && (total_byte < 4'd8)) || (data_valid_dly && eop_dly && (~eop_out)))
dma_type_packet_cnt <= dma_type_packet_cnt + 7'd1;
else ;
end
//----------------------------------------------------------------------------//
endmodule