/*
|
/*
|
* .--------------. .----------------. .------------.
|
* .--------------. .----------------. .------------.
|
* | .------------. | .--------------. | .----------. |
|
* | .------------. | .--------------. | .----------. |
|
* | | ____ ____ | | | ____ ____ | | | ______ | |
|
* | | ____ ____ | | | ____ ____ | | | ______ | |
|
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
|
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
|
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
|
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
|
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
|
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
|
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
|
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
|
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
|
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
|
* | | | | | | | | | | | |
|
* | | | | | | | | | | | |
|
* |_| | '------------' | '--------------' | '----------' |
|
* |_| | '------------' | '--------------' | '----------' |
|
* '--------------' '----------------' '------------'
|
* '--------------' '----------------' '------------'
|
*
|
*
|
* openHMC - An Open Source Hybrid Memory Cube Controller
|
* openHMC - An Open Source Hybrid Memory Cube Controller
|
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
|
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
|
* www.ziti.uni-heidelberg.de
|
* www.ziti.uni-heidelberg.de
|
* B6, 26
|
* B6, 26
|
* 68159 Mannheim
|
* 68159 Mannheim
|
* Germany
|
* Germany
|
*
|
*
|
* Contact: openhmc@ziti.uni-heidelberg.de
|
* Contact: openhmc@ziti.uni-heidelberg.de
|
* http://ra.ziti.uni-heidelberg.de/openhmc
|
* http://ra.ziti.uni-heidelberg.de/openhmc
|
*
|
*
|
* This source file is free software: you can redistribute it and/or modify
|
* This source file is free software: you can redistribute it and/or modify
|
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
* (at your option) any later version.
|
* (at your option) any later version.
|
*
|
*
|
* This source file is distributed in the hope that it will be useful,
|
* This source file is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
*
|
*
|
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
|
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
|
*
|
*
|
*
|
*
|
* Module name: tx_crc_combine
|
* Module name: tx_crc_combine
|
*
|
*
|
*/
|
*/
|
|
|
`default_nettype none
|
`default_nettype none
|
|
|
module tx_crc_combine #(
|
module tx_crc_combine #(
|
parameter LOG_FPW = 2,
|
parameter LOG_FPW = 2,
|
parameter FPW = 4,
|
parameter FPW = 4,
|
parameter DWIDTH = 512
|
parameter DWIDTH = 512
|
) (
|
) (
|
|
|
//----------------------------------
|
//----------------------------------
|
//----SYSTEM INTERFACE
|
//----SYSTEM INTERFACE
|
//----------------------------------
|
//----------------------------------
|
input wire clk,
|
input wire clk,
|
input wire res_n,
|
input wire res_n,
|
|
|
//----------------------------------
|
//----------------------------------
|
//----Input data
|
//----Input data
|
//----------------------------------
|
//----------------------------------
|
input wire [FPW-1:0] d_in_hdr,
|
input wire [FPW-1:0] d_in_hdr,
|
input wire [FPW-1:0] d_in_tail,
|
input wire [FPW-1:0] d_in_tail,
|
input wire [DWIDTH-1:0] d_in_data,
|
input wire [DWIDTH-1:0] d_in_data,
|
|
|
//----------------------------------
|
//----------------------------------
|
//----Outputs
|
//----Outputs
|
//----------------------------------
|
//----------------------------------
|
output wire [DWIDTH-1:0] d_out_data
|
output wire [DWIDTH-1:0] d_out_data
|
|
|
);
|
);
|
|
|
//=====================================================================================================
|
//=====================================================================================================
|
//-----------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//---------WIRING AND SIGNAL STUFF---------------------------------------------------------------------
|
//---------WIRING AND SIGNAL STUFF---------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//=====================================================================================================
|
//=====================================================================================================
|
|
|
`include "hmc_field_functions.h"
|
`include "hmc_field_functions.h"
|
//------------------------------------------------------------------------------------General Assignments
|
//------------------------------------------------------------------------------------General Assignments
|
integer i_f; //counts to FPW
|
integer i_f; //counts to FPW
|
integer i_f2; //counts to FPW inside another i_f loop
|
integer i_f2; //counts to FPW inside another i_f loop
|
integer i_c; //depth of the crc data pipeline
|
integer i_c; //depth of the crc data pipeline
|
|
|
genvar f, f2;
|
genvar f, f2;
|
|
|
//------------------------------------------------------------------------------------Split input data into FLITs
|
//------------------------------------------------------------------------------------Split input data into FLITs
|
wire [128-1:0] d_in_flit [FPW-1:0];
|
wire [128-1:0] d_in_flit [FPW-1:0];
|
generate
|
generate
|
for(f = 0; f < (FPW); f = f + 1) begin
|
for(f = 0; f < (FPW); f = f + 1) begin
|
assign d_in_flit[f] = d_in_data[(f*128)+128-1:f*128];
|
assign d_in_flit[f] = d_in_data[(f*128)+128-1:f*128];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
reg [3:0] d_in_flit_lng_dly [FPW-1:0];
|
reg [3:0] d_in_flit_lng_dly [FPW-1:0];
|
reg [DWIDTH-1:0] d_in_data_dly;
|
reg [DWIDTH-1:0] d_in_data_dly;
|
reg [FPW-1:0] d_in_tail_dly;
|
reg [FPW-1:0] d_in_tail_dly;
|
reg [FPW-1:0] d_in_hdr_dly;
|
reg [FPW-1:0] d_in_hdr_dly;
|
reg [LOG_FPW-1:0] d_in_flit_target_crc [FPW-1:0];
|
reg [LOG_FPW-1:0] d_in_flit_target_crc [FPW-1:0];
|
|
|
//------------------------------------------------------------------------------------CRC Target Assignment
|
//------------------------------------------------------------------------------------CRC Target Assignment
|
reg swap_crc;
|
reg swap_crc;
|
|
|
//Retrieve the target crc from the header and assign to corresponding tail
|
//Retrieve the target crc from the header and assign to corresponding tail
|
reg [LOG_FPW-1:0] target_crc_per_tail [FPW-1:0];
|
reg [LOG_FPW-1:0] target_crc_per_tail [FPW-1:0];
|
reg [LOG_FPW-1:0] target_crc_per_tail1 [FPW-1:0];
|
reg [LOG_FPW-1:0] target_crc_per_tail1 [FPW-1:0];
|
reg [LOG_FPW-1:0] target_crc_per_tail_comb [FPW-1:0];
|
reg [LOG_FPW-1:0] target_crc_per_tail_comb [FPW-1:0];
|
reg [LOG_FPW-1:0] target_crc_comb;
|
reg [LOG_FPW-1:0] target_crc_comb;
|
reg [LOG_FPW-1:0] target_crc_temp;
|
reg [LOG_FPW-1:0] target_crc_temp;
|
|
|
//------------------------------------------------------------------------------------CRC Modules Input stage
|
//------------------------------------------------------------------------------------CRC Modules Input stage
|
wire [31:0] crc_init_out [FPW-1:0];
|
wire [31:0] crc_init_out [FPW-1:0];
|
reg [31:0] crc_accu_in [FPW-1:0];
|
reg [31:0] crc_accu_in [FPW-1:0];
|
reg [FPW-1:0] crc_accu_in_valid [FPW-1:0];
|
reg [FPW-1:0] crc_accu_in_valid [FPW-1:0];
|
reg [FPW-1:0] crc_accu_in_tail [FPW-1:0];
|
reg [FPW-1:0] crc_accu_in_tail [FPW-1:0];
|
wire [31:0] crc_per_flit [FPW-1:0];
|
wire [31:0] crc_per_flit [FPW-1:0];
|
|
|
|
|
//------------------------------------------------------------------------------------Inter CRC stage
|
//------------------------------------------------------------------------------------Inter CRC stage
|
reg [3:0] payload_remain [FPW-1:0];
|
reg [3:0] payload_remain [FPW-1:0];
|
|
|
wire [(FPW*32)-1:0] crc_accu_in_combined [FPW-1:0];
|
wire [(FPW*32)-1:0] crc_accu_in_combined [FPW-1:0];
|
generate
|
generate
|
for(f=0;f<FPW;f=f+1) begin
|
for(f=0;f<FPW;f=f+1) begin
|
for(f2=0;f2<FPW;f2=f2+1) begin
|
for(f2=0;f2<FPW;f2=f2+1) begin
|
assign crc_accu_in_combined[f][(f2*32)+31:(f2*32)] = crc_accu_in_valid[f][f2] ? crc_accu_in[f2] : 32'h0;
|
assign crc_accu_in_combined[f][(f2*32)+31:(f2*32)] = crc_accu_in_valid[f][f2] ? crc_accu_in[f2] : 32'h0;
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
//------------------------------------------------------------------------------------Data Pipeline signals
|
//------------------------------------------------------------------------------------Data Pipeline signals
|
reg [DWIDTH-1:0] crc_data_pipe_in_data [1:0];
|
reg [DWIDTH-1:0] crc_data_pipe_in_data [1:0];
|
reg [FPW-1:0] crc_data_pipe_in_tail [1:0];
|
reg [FPW-1:0] crc_data_pipe_in_tail [1:0];
|
wire [128-1:0] crc_data_pipe_out_data_flit [FPW-1:0];
|
wire [128-1:0] crc_data_pipe_out_data_flit [FPW-1:0];
|
|
|
generate
|
generate
|
for(f = 0; f < (FPW); f = f + 1) begin : assign_data_pipe_output
|
for(f = 0; f < (FPW); f = f + 1) begin : assign_data_pipe_output
|
assign crc_data_pipe_out_data_flit[f] = crc_data_pipe_in_data[1][(f*128)+128-1:f*128];
|
assign crc_data_pipe_out_data_flit[f] = crc_data_pipe_in_data[1][(f*128)+127:f*128];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
reg [128-1:0] data_rdy_flit [FPW-1:0];
|
reg [128-1:0] data_rdy_flit [FPW-1:0];
|
generate
|
generate
|
for(f = 0; f < (FPW); f = f + 1) begin : reorder_flits_to_word
|
for(f = 0; f < (FPW); f = f + 1) begin : reorder_flits_to_word
|
assign d_out_data[(f*128)+128-1:(f*128)] = data_rdy_flit[f];
|
assign d_out_data[(f*128)+128-1:(f*128)] = data_rdy_flit[f];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
//==================================================================================
|
//==================================================================================
|
//---------------------------------Retrieve the lengths to invalide FLITs
|
//---------------------------------Retrieve the lengths to invalide FLITs
|
//==================================================================================
|
//==================================================================================
|
always @(*) begin
|
always @(*) begin
|
//Retrieve the length from the header and assign it to the tail. This information will be used in the
|
//Retrieve the length from the header and assign it to the tail. This information will be used in the
|
//invalidation stage to the correct number of FLITs
|
//invalidation stage to the correct number of FLITs
|
|
|
target_crc_comb = target_crc_temp;
|
target_crc_comb = target_crc_temp;
|
|
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
|
|
if(d_in_hdr_dly[i_f]) begin
|
if(d_in_hdr_dly[i_f]) begin
|
target_crc_comb = d_in_flit_target_crc[i_f];
|
target_crc_comb = d_in_flit_target_crc[i_f];
|
end
|
end
|
|
|
if(d_in_tail_dly[i_f]) begin
|
if(d_in_tail_dly[i_f]) begin
|
target_crc_per_tail_comb[i_f] = target_crc_comb;
|
target_crc_per_tail_comb[i_f] = target_crc_comb;
|
end else begin
|
end else begin
|
target_crc_per_tail_comb[i_f] = {4{1'b0}};
|
target_crc_per_tail_comb[i_f] = {4{1'b0}};
|
end
|
end
|
|
|
end
|
end
|
end
|
end
|
|
|
//Register combinational values
|
//Register combinational values
|
`ifdef ASYNC_RES
|
`ifdef ASYNC_RES
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk) begin `endif
|
always @(posedge clk) begin `endif
|
if(!res_n) begin
|
if(!res_n) begin
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
target_crc_per_tail[i_f] <= 0;
|
target_crc_per_tail[i_f] <= 0;
|
end
|
end
|
target_crc_temp <= {4{1'b0}};
|
target_crc_temp <= {4{1'b0}};
|
end else begin
|
end else begin
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
target_crc_per_tail[i_f] <= target_crc_per_tail_comb[i_f];
|
target_crc_per_tail[i_f] <= target_crc_per_tail_comb[i_f];
|
end
|
end
|
target_crc_temp <= target_crc_comb;
|
target_crc_temp <= target_crc_comb;
|
end
|
end
|
end
|
end
|
|
|
//=====================================================================================================
|
//=====================================================================================================
|
//-----------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//---------LOGIC STARTS HERE---------------------------------------------------------------------------
|
//---------LOGIC STARTS HERE---------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//=====================================================================================================
|
//=====================================================================================================
|
//====================================================================
|
//====================================================================
|
//---------------------------------Assign input data stream to target CRCs
|
//---------------------------------Assign input data stream to target CRCs
|
//====================================================================
|
//====================================================================
|
`ifdef ASYNC_RES
|
`ifdef ASYNC_RES
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk) begin `endif
|
always @(posedge clk) begin `endif
|
if(!res_n) begin
|
if(!res_n) begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
d_in_flit_target_crc[i_f] <= {LOG_FPW{1'b0}};
|
d_in_flit_target_crc[i_f] <= {LOG_FPW{1'b0}};
|
end
|
end
|
swap_crc <= 1'b0;
|
swap_crc <= 1'b0;
|
end else begin
|
end else begin
|
|
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
d_in_flit_target_crc[i_f] <= {LOG_FPW{1'b0}};
|
d_in_flit_target_crc[i_f] <= {LOG_FPW{1'b0}};
|
end
|
end
|
|
|
//Reset if seen a tail
|
//Reset if seen a tail
|
if(|d_in_tail) begin
|
if(|d_in_tail) begin
|
swap_crc <= 1'b0;
|
swap_crc <= 1'b0;
|
end
|
end
|
|
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
if(d_in_hdr[i_f])begin
|
if(d_in_hdr[i_f])begin
|
|
|
if(i_f+lng(d_in_flit[i_f])>FPW) begin
|
if(i_f+lng(d_in_flit[i_f])>FPW) begin
|
//If the current packet spreads over multiple cycles
|
//If the current packet spreads over multiple cycles
|
|
|
if(swap_crc) begin
|
if(swap_crc) begin
|
//If the last packet was swapped and the current packet also spreads over the more than 1 cycle use crc 0 now
|
//If the last packet was swapped and the current packet also spreads over the more than 1 cycle use crc 0 now
|
d_in_flit_target_crc[i_f] <= 3'h0;
|
d_in_flit_target_crc[i_f] <= 3'h0;
|
end else begin
|
end else begin
|
d_in_flit_target_crc[i_f] <= FPW-1'b1;
|
d_in_flit_target_crc[i_f] <= FPW-1'b1;
|
swap_crc <= 1'b1;
|
swap_crc <= 1'b1;
|
end
|
end
|
|
|
end else begin
|
end else begin
|
|
|
d_in_flit_target_crc[i_f] <= i_f;
|
d_in_flit_target_crc[i_f] <= i_f;
|
|
|
//If the highest order CRC contains a data packet that ends in this cycle, dont use this crc
|
//If the highest order CRC contains a data packet that ends in this cycle, dont use this crc
|
//It's ok always to decrement by 1 since we know the lowest order CRC would not be used (at least FLIT0 goes to highest order CRC)
|
//It's ok always to decrement by 1 since we know the lowest order CRC would not be used (at least FLIT0 goes to highest order CRC)
|
if(swap_crc && !(d_in_hdr > d_in_tail)) begin
|
if(swap_crc && !(d_in_hdr > d_in_tail)) begin
|
d_in_flit_target_crc[i_f] <= i_f-1;
|
d_in_flit_target_crc[i_f] <= i_f-1;
|
end
|
end
|
|
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
end
|
end
|
end
|
end
|
|
|
//Register input values to be used in CRC assignment logic after crc init stage
|
//Register input values to be used in CRC assignment logic after crc init stage
|
`ifdef ASYNC_RES
|
`ifdef ASYNC_RES
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk) begin `endif
|
always @(posedge clk) begin `endif
|
|
|
|
//------------Data Propagation
|
|
`ifdef RESET_ALL
|
|
if(!res_n) d_in_data_dly <= {DWIDTH{1'b0}};
|
|
else
|
|
`endif
|
|
d_in_data_dly <= d_in_data;
|
|
//----------------------------
|
|
|
|
`ifdef RESET_ALL
|
if(!res_n) begin
|
if(!res_n) begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
d_in_flit_lng_dly[i_f] <= 4'h0;
|
d_in_flit_lng_dly[i_f] <= 4'h0;
|
end
|
end
|
d_in_data_dly <= {DWIDTH{1'b0}};
|
|
d_in_tail_dly <= {FPW{1'b0}};
|
d_in_tail_dly <= {FPW{1'b0}};
|
d_in_hdr_dly <= {FPW{1'b0}};
|
d_in_hdr_dly <= {FPW{1'b0}};
|
end else begin
|
end else
|
|
`endif
|
|
begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
d_in_flit_lng_dly[i_f] <= lng(d_in_flit[i_f]);
|
d_in_flit_lng_dly[i_f] <= lng(d_in_flit[i_f]);
|
end
|
end
|
d_in_data_dly <= d_in_data;
|
|
d_in_tail_dly <= d_in_tail;
|
d_in_tail_dly <= d_in_tail;
|
d_in_hdr_dly <= d_in_hdr;
|
d_in_hdr_dly <= d_in_hdr;
|
end
|
end
|
end
|
end
|
|
|
//====================================================================
|
//====================================================================
|
//---------------------------------Inter CRC stage, CRC assignment Logic
|
//---------------------------------Inter CRC stage, CRC assignment Logic
|
//====================================================================
|
//====================================================================
|
`ifdef ASYNC_RES
|
`ifdef ASYNC_RES
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk) begin `endif
|
always @(posedge clk) begin `endif
|
|
|
|
//------------Data Propagation
|
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
|
`ifdef RESET_ALL
|
|
if(!res_n) crc_accu_in[i_f] <= {32{1'b0}};
|
|
else
|
|
`endif
|
|
crc_accu_in[i_f] <= crc_init_out[i_f];
|
|
end
|
|
//----------------------------
|
|
|
if(!res_n) begin
|
if(!res_n) begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
crc_accu_in[i_f] <= {32{1'b0}};
|
|
crc_accu_in_valid[i_f] <= {FPW{1'b0}};
|
crc_accu_in_valid[i_f] <= {FPW{1'b0}};
|
crc_accu_in_tail[i_f] <= {FPW{1'b0}};
|
crc_accu_in_tail[i_f] <= {FPW{1'b0}};
|
payload_remain[i_f] <= 4'h0;
|
payload_remain[i_f] <= 4'h0;
|
end
|
end
|
end else begin
|
end else begin
|
|
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
crc_accu_in[i_f] <= crc_init_out[i_f];
|
|
crc_accu_in_valid[i_f] <= 4'h0;
|
crc_accu_in_valid[i_f] <= 4'h0;
|
crc_accu_in_tail[i_f] <= 4'h0;
|
crc_accu_in_tail[i_f] <= 4'h0;
|
end
|
end
|
|
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
//First go through accu crcs
|
//First go through accu crcs
|
|
|
if(|payload_remain[i_f]) begin
|
if(|payload_remain[i_f]) begin
|
|
|
if(payload_remain[i_f] > FPW) begin
|
if(payload_remain[i_f] > FPW) begin
|
crc_accu_in_valid[i_f] <= {FPW{1'b1}};
|
crc_accu_in_valid[i_f] <= {FPW{1'b1}};
|
payload_remain[i_f] <= payload_remain[i_f]-FPW;
|
payload_remain[i_f] <= payload_remain[i_f]-FPW;
|
end else begin
|
end else begin
|
crc_accu_in_valid[i_f] <= {FPW{1'b1}} >> (FPW-payload_remain[i_f]);
|
crc_accu_in_valid[i_f] <= {FPW{1'b1}} >> (FPW-payload_remain[i_f]);
|
crc_accu_in_tail[i_f] <= 1'b1 << (payload_remain[i_f]-1);
|
crc_accu_in_tail[i_f] <= 1'b1 << (payload_remain[i_f]-1);
|
payload_remain[i_f] <= 4'h0;
|
payload_remain[i_f] <= 4'h0;
|
end
|
end
|
end
|
end
|
|
|
for(i_f2=0;i_f2<FPW;i_f2=i_f2+1)begin
|
for(i_f2=0;i_f2<FPW;i_f2=i_f2+1)begin
|
if(i_f==d_in_flit_target_crc[i_f2] && d_in_hdr_dly[i_f2]) begin
|
if(i_f==d_in_flit_target_crc[i_f2] && d_in_hdr_dly[i_f2]) begin
|
//Then go through all input crcs from the init crc and find the crc's that must be assigned to the currently selected crc
|
//Then go through all input crcs from the init crc and find the crc's that must be assigned to the currently selected crc
|
|
|
if( (i_f2+d_in_flit_lng_dly[i_f2]) >FPW ) begin
|
if( (i_f2+d_in_flit_lng_dly[i_f2]) >FPW ) begin
|
payload_remain[i_f] <= (d_in_flit_lng_dly[i_f2]-FPW+i_f2);
|
payload_remain[i_f] <= (d_in_flit_lng_dly[i_f2]-FPW+i_f2);
|
crc_accu_in_valid[i_f] <= {FPW{1'b1}} >> i_f2 << i_f2;
|
crc_accu_in_valid[i_f] <= {FPW{1'b1}} >> i_f2 << i_f2;
|
end else begin
|
end else begin
|
crc_accu_in_tail[i_f] <= 1'b1 << d_in_flit_lng_dly[i_f2]+i_f2-1;
|
crc_accu_in_tail[i_f] <= 1'b1 << d_in_flit_lng_dly[i_f2]+i_f2-1;
|
crc_accu_in_valid[i_f] <= ({FPW{1'b1}} >> (FPW-i_f2-d_in_flit_lng_dly[i_f2])) >> i_f2 << i_f2;
|
crc_accu_in_valid[i_f] <= ({FPW{1'b1}} >> (FPW-i_f2-d_in_flit_lng_dly[i_f2])) >> i_f2 << i_f2;
|
end
|
end
|
end
|
end
|
|
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
//====================================================================
|
//====================================================================
|
//---------------------------------Constant propagation of the data pipeline
|
//---------------------------------Constant propagation of the data pipeline
|
//====================================================================
|
//====================================================================
|
`ifdef ASYNC_RES
|
`ifdef ASYNC_RES
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk) begin `endif
|
always @(posedge clk) begin `endif
|
|
|
|
//------------Data Propagation
|
|
`ifdef RESET_ALL
|
if(!res_n) begin
|
if(!res_n) begin
|
for(i_c=0;i_c<2;i_c=i_c+1)begin
|
for(i_c=0;i_c<2;i_c=i_c+1)begin
|
crc_data_pipe_in_data[i_c] <= {DWIDTH{1'b0}};
|
crc_data_pipe_in_data[i_c] <= {DWIDTH{1'b0}};
|
|
end
|
|
end else
|
|
`endif
|
|
begin
|
|
crc_data_pipe_in_data[0] <= d_in_data_dly;
|
|
crc_data_pipe_in_data[1] <= crc_data_pipe_in_data[0];
|
|
end
|
|
//----------------------------
|
|
|
|
`ifdef RESET_ALL
|
|
if(!res_n) begin
|
|
for(i_c=0;i_c<2;i_c=i_c+1)begin
|
crc_data_pipe_in_tail[i_c] <= {FPW{1'b0}};
|
crc_data_pipe_in_tail[i_c] <= {FPW{1'b0}};
|
end
|
end
|
|
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
target_crc_per_tail1[i_f] <= 3'h0;
|
target_crc_per_tail1[i_f] <= {LOG_FPW{1'b0}};
|
end
|
end
|
end else begin
|
end else
|
|
`endif
|
|
begin
|
|
|
//We keep the tails per FLIT so they are not part of the data pipe
|
//We keep the tails per FLIT so they are not part of the data pipe
|
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
|
for(i_f=0;i_f<(FPW);i_f=i_f+ 1) begin
|
target_crc_per_tail1[i_f] <= target_crc_per_tail[i_f];
|
target_crc_per_tail1[i_f] <= target_crc_per_tail[i_f];
|
end
|
end
|
|
|
//Set the first stage of the data pipeline
|
//Set the first stage of the data pipeline
|
crc_data_pipe_in_data[0] <= d_in_data_dly;
|
|
crc_data_pipe_in_tail[0] <= d_in_tail_dly;
|
crc_data_pipe_in_tail[0] <= d_in_tail_dly;
|
|
|
//Data Pipeline propagation
|
//Data Pipeline propagation
|
for(i_c=0;i_c<(1);i_c=i_c+1)begin
|
crc_data_pipe_in_tail[1] <= crc_data_pipe_in_tail[0];
|
crc_data_pipe_in_data[i_c+1] <= crc_data_pipe_in_data[i_c];
|
|
crc_data_pipe_in_tail[i_c+1] <= crc_data_pipe_in_tail[i_c];
|
|
end
|
|
end
|
end
|
end
|
end
|
|
|
//====================================================================
|
//====================================================================
|
//---------------------------------At the end of the data pipeline get and add CRCs
|
//---------------------------------At the end of the data pipeline get and add CRCs
|
//====================================================================
|
//====================================================================
|
//Data Pipeline output stage to final FLIT reg
|
//Data Pipeline output stage to final FLIT reg
|
`ifdef ASYNC_RES
|
`ifdef ASYNC_RES
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk or negedge res_n) begin `else
|
always @(posedge clk) begin `endif
|
always @(posedge clk) begin `endif
|
if(!res_n) begin
|
|
|
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
|
`ifdef RESET_ALL
|
|
if(!res_n) begin
|
data_rdy_flit[i_f] <= {128{1'b0}};
|
data_rdy_flit[i_f] <= {128{1'b0}};
|
end
|
end else
|
|
`endif
|
end else begin
|
begin
|
|
|
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
|
|
|
|
data_rdy_flit[i_f] <= crc_data_pipe_out_data_flit[i_f];
|
data_rdy_flit[i_f] <= crc_data_pipe_out_data_flit[i_f];
|
|
|
if(crc_data_pipe_in_tail[1][i_f])begin //Finally add the crc
|
if(crc_data_pipe_in_tail[1][i_f])begin //Finally add the crc
|
data_rdy_flit[i_f][128-1:128-32] <= crc_per_flit[target_crc_per_tail1[i_f]];
|
data_rdy_flit[i_f][128-1:128-32] <= crc_per_flit[target_crc_per_tail1[i_f]];
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
//=====================================================================================================
|
//=====================================================================================================
|
//-----------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//---------INSTANTIATIONS HERE-------------------------------------------------------------------------
|
//---------INSTANTIATIONS HERE-------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
//=====================================================================================================
|
//=====================================================================================================
|
//Init CRC: Calculate the remainders of each input FLIT individually
|
//Init CRC: Calculate the remainders of each input FLIT individually
|
generate
|
generate
|
for(f=0;f<FPW;f=f+1) begin : crc_init_gen
|
for(f=0;f<FPW;f=f+1) begin : crc_init_gen
|
crc_128_init crc_init_I
|
crc_128_init crc_init_I
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
|
`ifdef RESET_ALL
|
.res_n(res_n),
|
.res_n(res_n),
|
|
`endif
|
.inData(d_in_flit[f]),
|
.inData(d_in_flit[f]),
|
.crc(crc_init_out[f])
|
.crc(crc_init_out[f])
|
);
|
);
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
//Calculate the actual CRC over all valid remainders
|
//Calculate the actual CRC over all valid remainders
|
generate
|
generate
|
for(f=0;f<FPW;f=f+1) begin : crc_accu_gen
|
for(f=0;f<FPW;f=f+1) begin : crc_accu_gen
|
crc_accu #(
|
crc_accu #(
|
.FPW(FPW)
|
.FPW(FPW)
|
)
|
)
|
crc_accu_I
|
crc_accu_I
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
.res_n(res_n),
|
.res_n(res_n),
|
.tail(crc_accu_in_tail[f]),
|
.tail(crc_accu_in_tail[f]),
|
.d_in(crc_accu_in_combined[f]),
|
.d_in(crc_accu_in_combined[f]),
|
.valid(crc_accu_in_valid[f]),
|
|
.crc_out(crc_per_flit[f])
|
.crc_out(crc_per_flit[f])
|
);
|
);
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|