OpenCores
URL https://opencores.org/ocsvn/openhmc/openhmc/trunk

Subversion Repositories openhmc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openhmc/trunk/openHMC/rtl/hmc_controller/tx
    from Rev 11 to Rev 15
    Reverse comparison

Rev 11 → Rev 15

/tx_crc_combine.v
89,7 → 89,7
end
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 [FPW-1:0] d_in_tail_dly;
reg [FPW-1:0] d_in_hdr_dly;
123,7 → 123,7
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
endgenerate
endgenerate
 
//------------------------------------------------------------------------------------Data Pipeline signals
reg [DWIDTH-1:0] crc_data_pipe_in_data [1:0];
132,7 → 132,7
 
generate
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
endgenerate
 
214,10 → 214,10
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(d_in_hdr[i_f])begin
 
if(i_f+lng(d_in_flit[i_f])>FPW) begin
//If the current packet spreads over multiple cycles
 
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
d_in_flit_target_crc[i_f] <= 3'h0;
235,7 → 235,7
if(swap_crc && !(d_in_hdr > d_in_tail)) begin
d_in_flit_target_crc[i_f] <= i_f-1;
end
 
end
end
end
247,22 → 247,32
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
d_in_flit_lng_dly[i_f] <= 4'h0;
 
//------------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
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
d_in_flit_lng_dly[i_f] <= 4'h0;
end
d_in_tail_dly <= {FPW{1'b0}};
d_in_hdr_dly <= {FPW{1'b0}};
end else
`endif
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]);
end
d_in_tail_dly <= d_in_tail;
d_in_hdr_dly <= d_in_hdr;
end
d_in_data_dly <= {DWIDTH{1'b0}};
d_in_tail_dly <= {FPW{1'b0}};
d_in_hdr_dly <= {FPW{1'b0}};
end else 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]);
end
d_in_data_dly <= d_in_data;
d_in_tail_dly <= d_in_tail;
d_in_hdr_dly <= d_in_hdr;
end
end
 
//====================================================================
//---------------------------------Inter CRC stage, CRC assignment Logic
270,9 → 280,19
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
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
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_tail[i_f] <= {FPW{1'b0}};
payload_remain[i_f] <= 4'h0;
280,7 → 300,7
end else 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_tail[i_f] <= 4'h0;
end
288,7 → 308,7
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
//First go through accu crcs
 
if(|payload_remain[i_f]) begin
if(|payload_remain[i_f]) begin
 
if(payload_remain[i_f] > FPW) begin
crc_accu_in_valid[i_f] <= {FPW{1'b1}};
296,15 → 316,15
end else begin
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);
payload_remain[i_f] <= 4'h0;
payload_remain[i_f] <= 4'h0;
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
//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);
crc_accu_in_valid[i_f] <= {FPW{1'b1}} >> i_f2 << i_f2;
end else begin
324,33 → 344,46
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) 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_tail[i_c] <= {FPW{1'b0}};
//------------Data Propagation
`ifdef RESET_ALL
if (!res_n) begin
for(i_c=0;i_c<2;i_c=i_c+1)begin
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
//----------------------------
 
for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
target_crc_per_tail1[i_f] <= 3'h0;
end
end else begin
`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}};
end
 
for(i_f=0;i_f<(FPW);i_f=i_f+ 1) begin
target_crc_per_tail1[i_f] <= {LOG_FPW{1'b0}};
end
end else
`endif
begin
 
//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];
end
 
//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;
 
//Data Pipeline propagation
for(i_c=0;i_c<(1);i_c=i_c+1)begin
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];
crc_data_pipe_in_tail[1] <= crc_data_pipe_in_tail[0];
end
end
end
 
//====================================================================
//---------------------------------At the end of the data pipeline get and add CRCs
359,16 → 392,14
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data_rdy_flit[i_f] <= {128{1'b0}};
end
 
end else 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}};
end else
`endif
begin
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
375,8 → 406,8
data_rdy_flit[i_f][128-1:128-32] <= crc_per_flit[target_crc_per_tail1[i_f]];
end
end
end
end
end
 
//=====================================================================================================
//-----------------------------------------------------------------------------------------------------
389,7 → 420,9
crc_128_init crc_init_I
(
.clk(clk),
.res_n(res_n),
`ifdef RESET_ALL
.res_n(res_n),
`endif
.inData(d_in_flit[f]),
.crc(crc_init_out[f])
);
408,7 → 441,6
.res_n(res_n),
.tail(crc_accu_in_tail[f]),
.d_in(crc_accu_in_combined[f]),
.valid(crc_accu_in_valid[f]),
.crc_out(crc_per_flit[f])
);
end
/tx_run_length_limiter.v
132,22 → 132,30
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
 
`ifdef RESET_ALL
if(!res_n) begin
data_out <= {DWIDTH {1'b0}};
end else
`endif
begin
if (enable && bit_flip) begin
data_out <= {data_in[LANE_WIDTH-1:1], ~data_in[0]};
end else begin
data_out <= data_in;
end
end
if (!res_n) begin
count_bottom_d1 <= { COUNT_BITS {1'b0}};
no_flip_bottom_d1 <= 1'b0;
data_in_bottom_d1 <= 1'b0;
rf_bit_flip <= 1'b0;
data_out <= {LANE_WIDTH{1'b0}};
end else begin
count_bottom_d1 <= count_bottom;
no_flip_bottom_d1 <= no_flip[NUM_CHUNKS-1];
data_in_bottom_d1 <= data_in[LANE_WIDTH-1];
 
if (enable && bit_flip) begin
data_out <= {data_in[LANE_WIDTH-1:1], ~data_in[0]};
rf_bit_flip <= bit_flip;
end else begin
data_out <= data_in;
end
end
end
/tx_scrambler.v
61,7 → 61,7
`default_nettype none
 
module tx_scrambler #(
parameter LANE_WIDTH = 16,
parameter LANE_WIDTH = 16,
parameter HMC_RX_AC_COUPLED = 1
)
(
84,33 → 84,25
wire [LANE_WIDTH-1:0] run_length_d_out;
reg [14:0] lfsr; // LINEAR FEEDBACK SHIFT REGISTER
wire [14:0] lfsr_steps [LANE_WIDTH-1:0]; // LFSR values for serial time steps
reg seed_set;
 
// SEQUENTIAL PROCESS
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if (!res_n) begin
seed_set <= 1'b0;
lfsr[14:0] <= 15'h0;
data_out <= {LANE_WIDTH {1'b0}};
end
else
`ifdef RESET_ALL
if(!res_n) begin
data_out <= {LANE_WIDTH{1'b0}};
end else
`endif
begin
if(!seed_set) begin
lfsr[14:0] <= seed;
seed_set <= 1'b1;
end else begin
if (disable_scrambler) begin
lfsr[14:0] <= 15'h0;
end else begin
lfsr[14:0] <= lfsr_steps[LANE_WIDTH-1];
end
end
data_out <= run_length_d_out;
end
end // serial shift right with left input
 
if(!res_n) lfsr <= seed;
else lfsr <= disable_scrambler ? {15{1'b0}} : lfsr_steps[LANE_WIDTH-1];
 
end
 
// SCRAMBLE
genvar j;
generate
/tx_link.v
46,11 → 46,16
parameter FPW = 4,
parameter DWIDTH = FPW*128,
parameter NUM_LANES = 8,
parameter HMC_PTR_SIZE = 8,
parameter HMC_RF_RWIDTH = 64,
parameter RF_COUNTER_SIZE = 64,
parameter HMC_RX_AC_COUPLED = 1,
parameter MAX_RTC_RET_LOG = 8,
parameter LOG_MAX_RX_TOKENS = 8,
parameter LOG_MAX_HMC_TOKENS= 10,
parameter LOG_IRTRY_TIMOUT = 8,
parameter XIL_CNT_PIPELINED = 0,
//Debug
parameter DBG_RX_TOKEN_MON = 1
parameter DBG_RX_TOKEN_MON = 1,
parameter OPEN_RSP_MODE = 0
) (
 
//----------------------------------
67,8 → 72,8
//----------------------------------
//----HMC IF
//----------------------------------
output reg hmc_LxRXPS,
input wire hmc_LxTXPS,
output reg LXRXPS,
input wire LXTXPS,
 
//----------------------------------
//----Input data
87,9 → 92,9
input wire rx_force_tx_retry,
input wire rx_error_abort_mode,
input wire rx_error_abort_mode_cleared,
input wire [HMC_PTR_SIZE-1:0] rx_hmc_frp,
input wire [HMC_PTR_SIZE-1:0] rx_rrp,
input wire [7:0] rx_returned_tokens,
input wire [7:0] rx_hmc_frp,
input wire [7:0] rx_rrp,
input wire [MAX_RTC_RET_LOG-1:0] rx_returned_tokens,
input wire [LOG_FPW:0] rx_hmc_tokens_to_return,
input wire [LOG_FPW:0] rx_hmc_poisoned_tokens_to_return,
 
98,9 → 103,9
//----------------------------------
//Monitoring 1-cycle set to increment
output reg rf_cnt_retry,
output reg [HMC_RF_RWIDTH-1:0] rf_sent_p,
output reg [HMC_RF_RWIDTH-1:0] rf_sent_np,
output reg [HMC_RF_RWIDTH-1:0] rf_sent_r,
output wire [RF_COUNTER_SIZE-1:0] rf_sent_p,
output wire [RF_COUNTER_SIZE-1:0] rf_sent_np,
output wire [RF_COUNTER_SIZE-1:0] rf_sent_r,
output reg rf_run_length_bit_flip,
output reg rf_error_abort_not_cleared,
 
109,24 → 114,17
input wire rf_hmc_received_init_null,
input wire rf_descramblers_aligned,
output wire [1:0] rf_tx_init_status,
output reg [9:0] rf_hmc_tokens_av,
output reg rf_hmc_is_in_sleep,
output reg [9:0] rf_rx_tokens_av,
output reg [LOG_MAX_HMC_TOKENS-1:0]rf_hmc_tokens_av,
output wire [LOG_MAX_RX_TOKENS-1:0]rf_rx_tokens_av,
 
//Control
input wire rf_hmc_sleep_requested,
//input wire rf_warm_reset,
input wire rf_hmc_init_cont_set,
input wire rf_warm_reset,
input wire rf_scrambler_disable,
input wire [9:0] rf_rx_buffer_rtc,
input wire [2:0] rf_first_cube_ID,
input wire [LOG_MAX_RX_TOKENS-1:0]rf_rx_buffer_rtc,
input wire [4:0] rf_irtry_to_send,
input wire rf_run_length_enable,
input wire rf_run_length_enable
 
//Debug Register
input wire rf_dbg_dont_send_tret,
input wire rf_dbg_halt_on_error_abort,
input wire rf_dbg_halt_on_tx_retry
);
 
`include "hmc_field_functions.h"
138,7 → 136,6
//=====================================================================================================
//------------------------------------------------------------------------------------General Assignments
localparam LANE_WIDTH = (DWIDTH/NUM_LANES);
localparam NULL_FLIT = {128{1'b0}};
 
integer i_f; //counts to FPW
integer i_t; //counts to number of TS1 packets in a word
151,6 → 148,8
localparam PKT_P_WRITE = 3'b011;
localparam PKT_MISC_P_WRITE = 3'b100;
 
localparam CMD_IRTRY = 6'b000011;
 
//------------------------------------------------------------------------------------Scrambler
wire [14:0] seed_lane [NUM_LANES-1:0];
 
176,42 → 175,44
end
endgenerate
 
wire [NUM_LANES-1:0] bit_was_flipped;
wire [NUM_LANES-1:0] bit_was_flipped;
 
//------------------------------------------------------------------------------------FSM and States
reg [3:0] state;
localparam TX_NULL_1 = 4'b0001;
localparam TX_TS1 = 4'b0010;
localparam TX_NULL_2 = 4'b0011;
localparam IDLE = 4'b1000;
localparam TX = 4'b1001;
localparam HMC_RTRY = 4'b1010;
localparam SLEEP = 4'b1011;
localparam WAIT_FOR_HMC = 4'b1100;
localparam LNK_RTRY = 4'b1101;
localparam FATAL_ERROR = 4'b1110;
localparam DEBUG = 4'b1111;
reg [2:0] state;
reg [1:0] init_state;
localparam INIT_TX_NULL_1 = 2'b00;
localparam INIT_TX_TS1 = 2'b01;
localparam INIT_TX_NULL_2 = 2'b11;
localparam INIT_DONE = 2'b10;
 
assign rf_tx_init_status = state[3] ? 0 : state[1:0];
localparam INIT = 3'b000;
localparam IDLE = 3'b001;
localparam TX = 3'b010;
localparam HMC_RTRY = 3'b011;
localparam SLEEP = 3'b100;
localparam WAIT_FOR_HMC = 3'b101;
localparam LNK_RTRY = 3'b110;
localparam DEBUG = 3'b111;
 
assign rf_tx_init_status = init_state;
 
reg rtc_rx_initialize;
 
//------------------------------------------------------------------------------------DATA and ORDERING
//reorder incoming data to FLITs
wire [128-1:0] d_in_flit [FPW-1:0];
wire [127:0] d_in_flit [FPW-1:0];
genvar f;
generate
for(f = 0; f < (FPW); f = f + 1) begin : reorder_input_data_to_flits
assign d_in_flit[f] = d_in_data[128-1+(f*128):f*128];
assign d_in_flit[f] = d_in_data[127+(f*128):f*128];
end
endgenerate
 
//Create a mask and an input buffer that is necessary if packet transmission is interrupted and packets remain untransmitted
reg d_in_use_buf;
reg [128-1:0] d_in_buf_flit [FPW-1:0];
reg [FPW-1:0] d_in_buf_flit_is_hdr;
reg [FPW-1:0] d_in_buf_flit_is_tail;
reg [FPW-1:0] d_in_buf_flit_is_valid;
reg [127:0] d_in_buf_flit [FPW-2:0];
reg [FPW-2:0] d_in_buf_flit_is_hdr;
reg [FPW-2:0] d_in_buf_flit_is_valid;
 
//Reorder the data per lane
wire [DWIDTH-1:0] data_rdy;
227,13 → 228,16
endgenerate
 
//------------------------------------------------------------------------------------Init Regs
localparam TS1_SEQ_INC_VAL_PER_CYCLE = (NUM_LANES==8) ? FPW : (FPW/2);
localparam NUM_NULL_TO_SEND_BEFORE_IDLE = 50; //see HMC spec, 32 is minimum
localparam TS1_SEQ_INC_VAL_PER_CYCLE = (NUM_LANES==8) ? FPW : (FPW/2);
localparam LOG_CYCLES_NULL_TO_SEND = (FPW == 2) ? 4 :
(FPW == 4) ? 3 :
(FPW == 6) ? 3 :
2;
 
wire [(NUM_LANES*4)-1:0] ts1_seq_part_reordered [TS1_SEQ_INC_VAL_PER_CYCLE-1:0]; //ts1 seq is 4 bits
reg [3:0] ts1_seq_nr_per_flit [TS1_SEQ_INC_VAL_PER_CYCLE-1:0];
wire [128-1:0] ts1_flit [FPW-1:0];
reg [5:0] num_init_nulls_sent;
wire [127:0] ts1_flit [FPW-1:0];
reg [LOG_CYCLES_NULL_TO_SEND-1:0] num_null_cycles_sent;
 
generate
for(f = 0; f < TS1_SEQ_INC_VAL_PER_CYCLE; f = f + 1) begin : generate_lane_dependent_ts1_sequence
243,42 → 247,27
end
 
if(NUM_LANES==8) begin
 
assign ts1_flit[f] = {
32'hffffffff,32'h0,1'h1,7'h0,7'b1111111,1'h0,7'h0,1'h1,1'h0,7'b1111111,ts1_seq_part_reordered[f]
};
 
end else begin
 
assign ts1_flit[f*2] = {
assign ts1_flit[f*2+1] = {
64'hffffffffffffffff,64'h0
};
assign ts1_flit[f*2+1] = {
15'h7fff,1'h0,1'h1,16'h0,15'h7fff,15'h0,1'h1,ts1_seq_part_reordered[f]
assign ts1_flit[f*2] = {
16'h8000,16'hfffe,16'h0001,16'h7fff,ts1_seq_part_reordered[f]
};
 
end
 
end
endgenerate
 
//------------------------------------------------------------------------------------SEQ and FRP Stage
reg [128-1:0] data2seq_frp_stage_flit [FPW-1:0];
reg [128-1:0] data2seq_frp_stage_flit_comb [FPW-1:0];
reg [FPW-1:0] data2seq_frp_stage_flit_is_hdr;
reg [FPW-1:0] data2seq_frp_stage_flit_is_tail;
reg [FPW-1:0] data2seq_frp_stage_flit_is_valid;
reg [FPW-1:0] data2seq_frp_stage_is_flow;
reg data2seq_frp_stage_force_tx_retry;
 
//------------------------------------------------------------------------------------Counter variables
reg [LOG_FPW:0] rf_sent_p_comb;
reg [LOG_FPW:0] rf_sent_np_comb;
reg [LOG_FPW:0] rf_sent_r_comb;
 
 
//------------------------------------------------------------------------------------SEQ and FRP Stage
reg [128-1:0] data2rtc_stage_flit [FPW-1:0];
//------------------------------------------------------------------------------------SEQ FRP RTC Stage
reg [127:0] data2rtc_stage_flit [FPW-1:0];
reg [FPW-1:0] data2rtc_stage_flit_is_hdr;
reg [FPW-1:0] data2rtc_stage_flit_is_tail;
reg [FPW-1:0] data2rtc_stage_flit_is_valid;
285,28 → 274,32
reg data2rtc_stage_is_flow;
reg data2rtc_stage_force_tx_retry;
 
reg [127:0] data2seq_frp_stage_flit [FPW-1:0];
reg [FPW-1:0] data2seq_frp_stage_flit_is_hdr;
reg [FPW-1:0] data2seq_frp_stage_flit_is_tail;
reg [FPW-1:0] data2seq_frp_stage_flit_is_valid;
reg data2seq_frp_stage_is_flow;
reg data2seq_frp_stage_force_tx_retry;
 
//Information used to fill the retry buffer
reg [LOG_FPW-1:0] target_temp [FPW:0];
reg [LOG_FPW-1:0] next_target;
reg [LOG_FPW-1:0] target [FPW-1:0];
 
reg [LOG_FPW:0] tx_seqnum_inc;
reg [2:0] tx_seqnum_temp [FPW-1:0];
 
//------------------------------------------------------------------------------------RETRY
//HMC
//Amount of cycles to wait until start HMC retry is issued again (when RX error abort is not cleared)
localparam CYCLES_TO_CLEAR_ERR_ABORT_MODE = 254; //safe value
reg [7:0] error_abort_mode_clr_cnt;
reg force_hmc_retry;
reg [5:0] irtry_start_retry_cnt;
//Number of cycles to wait until start HMC retry is issued again (when RX error abort is not cleared)
reg [LOG_IRTRY_TIMOUT-1:0] error_abort_mode_clr_cnt;
reg force_hmc_retry;
reg [4:0] irtry_start_retry_cnt;
reg [4:0] irtry_clear_error_cnt;
wire [63:0] irtry_hdr;
assign irtry_hdr = {6'h0,34'h0,9'h0,4'h1,4'h1,1'h0,6'b000011};
 
//Memory Controller
reg [5:0] irtry_clear_error_cnt;
wire [63:0] irtry_hdr;
assign irtry_hdr = {rf_first_cube_ID,3'h0,34'h0,9'h0,4'h1,4'h1,1'h0,6'b000011};
 
//------------------------------------------------------------------------------------Retry Buffer
reg [128-1:0] data2ram_flit [FPW-1:0];
reg [128-1:0] data2ram_flit_temp [FPW-1:0];
reg [FPW-1:0] data2ram_flit_is_hdr;
reg [FPW-1:0] data2ram_flit_is_tail;
reg [FPW-1:0] data2ram_flit_is_valid;
reg data2ram_is_flow;
reg data2ram_force_tx_retry;
 
localparam RAM_ADDR_SIZE = (FPW == 2) ? 7 :
(FPW == 4) ? 6 :
(FPW == 6) ? 5 :
313,10 → 306,22
(FPW == 8) ? 5 :
1;
 
reg ram_w_en, ram_r_en;
reg [RAM_ADDR_SIZE-1:0] ram_w_addr;
reg [127:0] data2ram_flit [FPW-1:0];
reg [127:0] data2ram_flit_temp [FPW-1:0];
reg [FPW-1:0] data2ram_flit_is_hdr;
reg [FPW-1:0] data2ram_flit_is_tail;
reg [FPW-1:0] data2ram_flit_is_valid;
reg data2ram_force_tx_retry;
 
//Header/Tail fields, and at the same time form the RAM read pointer
reg [RAM_ADDR_SIZE-1:0] tx_frp_adr [FPW-1:0];
reg [2:0] tx_seqnum;
 
 
reg [FPW-1:0] ram_w_en ;
reg ram_r_en;
wire [RAM_ADDR_SIZE-1:0] ram_w_addr_next;
assign ram_w_addr_next = ram_w_addr + 1;
assign ram_w_addr_next = tx_frp_adr[0] + 1;
reg [RAM_ADDR_SIZE-1:0] ram_r_addr_temp;
reg [FPW-1:0] ram_r_mask;
wire [128+3-1:0] ram_r_data [FPW-1:0];
323,32 → 328,16
reg [128+3-1:0] ram_w_data [FPW-1:0];
 
wire [RAM_ADDR_SIZE-1:0] ram_r_addr;
assign ram_r_addr = rx_rrp[HMC_PTR_SIZE-1:HMC_PTR_SIZE-RAM_ADDR_SIZE];
assign ram_r_addr = rx_rrp[7:8-RAM_ADDR_SIZE];
 
//Avoid overwriting not acknowleged FLITs in the retry buffer
wire [RAM_ADDR_SIZE-1:0] ram_result;
assign ram_result = ram_r_addr - ram_w_addr_next;
 
//A safe value since ram_w_addr is calculated some cycles after packets were accepted
//A safe value since ram_w_addr_next is calculated some cycles after packets were accepted
wire ram_full;
assign ram_full = (ram_result<9 && ram_result>0) ? 1'b1 : 1'b0 ;
 
 
//Header/Tail fields, and at the same time form the RAM read pointer
reg [RAM_ADDR_SIZE-1:0] tx_frp_adr;
reg [2:0] tx_seqnum;
reg tx_frp_adr_incr_temp;
reg [LOG_FPW:0] tx_seqnum_temp;
 
//variable to construct the frp
wire [HMC_PTR_SIZE-RAM_ADDR_SIZE-1:0] tx_frp_ram [FPW-1:0];
 
generate
for(f = 0; f < (FPW); f = f + 1) begin : assign_ram_addresses
assign tx_frp_ram[f] = f;
end
endgenerate
 
//Regs for TX Link retry handling
reg tx_retry_finished;
reg tx_retry_ongoing;
355,16 → 344,21
reg tx_link_retry_request; //Sample the retry request
 
//------------------------------------------------------------------------------------RRP Stage
reg [128-1:0] data2rrp_stage_flit [FPW-1:0];
reg [127:0] data2rrp_stage_flit [FPW-1:0];
reg [FPW-1:0] data2rrp_stage_flit_is_hdr;
reg [FPW-1:0] data2rrp_stage_flit_is_tail;
reg [FPW-1:0] data2rrp_stage_flit_is_valid;
reg data2rrp_stage_is_flow;
 
reg [7:0] last_transmitted_rx_hmc_frp;
`ifdef SIMULATION
//We dont want to crash a simulation run because PRETs are still travelling upon test completion, so we include a trigger to only send PRETs when necessary in simulation
//In hardware, PRETs will be sent whenever there is no valid FLIT on position 0 -> reduces the overall pointer return delay
reg [7:0] last_transmitted_rx_hmc_frp;
`else
reg send_prets;
`endif
 
//------------------------------------------------------------------------------------CRC
reg [128-1:0] data2crc_flit [FPW-1:0];
reg [127:0] data2crc_flit [FPW-1:0];
wire [DWIDTH-1:0] data2crc;
reg [FPW-1:0] data2crc_flit_is_hdr;
reg [FPW-1:0] data2crc_flit_is_tail;
371,7 → 365,7
 
generate
for(f = 0; f < (FPW); f = f + 1) begin : concatenate_flits_to_single_reg
assign data2crc[(f*128)+128-1:(f*128)] = data2crc_flit[f];
assign data2crc[(f*128)+127:(f*128)] = data2crc_flit[f];
end
endgenerate
 
378,27 → 372,31
//------------------------------------------------------------------------------------FLOW PACKETS
//TRET
wire [63:0] tret_hdr;
assign tret_hdr = {rf_first_cube_ID,3'h0,34'h0,9'h0,4'h1,4'h1,1'h0,6'b000010};
assign tret_hdr = {6'h0,34'h0,9'h0,4'h1,4'h1,1'h0,6'b000010};
//PRET
wire [63:0] pret_hdr ;
assign pret_hdr = {rf_first_cube_ID,3'h0,34'h0,9'h0,4'h1,4'h1,1'h0,6'b000001};
wire [63:0] pret_hdr;
assign pret_hdr = {6'h0,34'h0,9'h0,4'h1,4'h1,1'h0,6'b000001};
 
//------------------------------------------------------------------------------------RTC HANDLING
//Registers for the RTC field in request packets
reg rtc_return;
reg [4:0] rtc_return_val;
reg rtc_return_sent;
 
//A safe value to not send more FLITs than the HMC can buffer
reg [LOG_FPW:0] flits_in_buf;
reg [LOG_FPW:0] flits_transmitted;
reg [9:0] remaining_tokens;
reg [LOG_FPW-1:0] num_flits_in_buf;
reg [LOG_FPW:0] num_flits_transmitted;
reg [LOG_MAX_RX_TOKENS-1:0]remaining_tokens;
localparam TOKENS_THRESHOLD= (FPW == 2) ? 11 :
(FPW == 4) ? 15 :
(FPW == 6) ? 23 :
(FPW == 8) ? 23 :
1;
wire hmc_tokens_av;
assign hmc_tokens_av = ((rf_hmc_tokens_av+flits_in_buf) > 8+(2*FPW)) ? 1'b1 : 1'b0;
assign hmc_tokens_av = ((rf_hmc_tokens_av+num_flits_in_buf+rx_returned_tokens) > TOKENS_THRESHOLD) ? 1'b1 : 1'b0;
 
//Return a maximum of 31 tokens
wire [4:0] outstanding_tokens_to_return;
assign outstanding_tokens_to_return = remaining_tokens > 31 ? 31 : remaining_tokens;
assign outstanding_tokens_to_return = (OPEN_RSP_MODE==0) ? (remaining_tokens > 31 ? 31 : remaining_tokens[4:0]) : 5'h0;
 
//=====================================================================================================
//-----------------------------------------------------------------------------------------------------
424,7 → 422,7
//====================================================================
//Track the remaining tokens in the rx input buffer. This is optional since the HMC must make sure not to send more tokens than RX can buffer, useful for debugging
generate
if(DBG_RX_TOKEN_MON==1) begin : Tokens_in_RX_buf
if(DBG_RX_TOKEN_MON==1 && OPEN_RSP_MODE==0) begin : Tokens_in_RX_buf
 
reg [6:0] sum_requested_tokens; //Count the amount of tokens requested from the HMC
reg [6:0] sum_requested_tokens_temp; //Use this register for combinational logic
461,26 → 459,27
end
 
//Monitor remaining tokens in the openHMC RX input buffer
reg [LOG_MAX_RX_TOKENS-1:0] rx_tokens_av;
assign rf_rx_tokens_av = rx_tokens_av;
 
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
rf_rx_tokens_av <= {10{1'b0}};
rx_tokens_av <= {LOG_MAX_RX_TOKENS{1'b0}};
end else begin
if(state==TX_NULL_1)begin
if(state==INIT_TX_NULL_1)begin
//initialize token counts when HMC init is not done
rf_rx_tokens_av <= rf_rx_buffer_rtc;
rx_tokens_av <= rf_rx_buffer_rtc;
end else begin
//calculate remaining tokens in RX buffers
rf_rx_tokens_av <= rf_rx_tokens_av + rx_hmc_tokens_to_return - sum_requested_tokens;
rx_tokens_av <= rx_tokens_av + rx_hmc_tokens_to_return - sum_requested_tokens;
end
end
end
 
end else begin
always @(posedge clk) begin
rf_rx_tokens_av <= 10'h0;
end
assign rf_rx_tokens_av = {LOG_MAX_RX_TOKENS{1'b0}};
end
endgenerate
 
490,11 → 489,130
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
//----Data
if(!res_n) begin
 
//----Init Regs
for(i_t=0;i_t<TS1_SEQ_INC_VAL_PER_CYCLE;i_t=i_t+1) begin //set
ts1_seq_nr_per_flit[i_t]<= i_t;
end
num_null_cycles_sent <= {LOG_CYCLES_NULL_TO_SEND{1'b0}};
 
//General
init_state <= INIT_TX_NULL_1;
rtc_rx_initialize <= 1'b1;
end
else begin
case(init_state)
//---------------------------------INIT. Refer to Initialization section in the specification
 
INIT_TX_NULL_1: begin
//---init_state---
if(rf_hmc_received_init_null)begin
init_state <= INIT_TX_TS1;
end
 
end
 
INIT_TX_TS1: begin
 
rtc_rx_initialize <= 1'b0;
for(i_t=0;i_t<TS1_SEQ_INC_VAL_PER_CYCLE;i_t=i_t+1) begin
ts1_seq_nr_per_flit[i_t] <= ts1_seq_nr_per_flit[i_t] + TS1_SEQ_INC_VAL_PER_CYCLE;
end
 
//---init_state---
if(rf_descramblers_aligned)begin
init_state <= INIT_TX_NULL_2;
end
 
end
 
INIT_TX_NULL_2: begin
//Issue at least 32 NULL FLITs before going active
if(&num_null_cycles_sent && rf_link_is_up) begin
init_state <= INIT_DONE;
end
num_null_cycles_sent <= num_null_cycles_sent + 1;
end
default: begin
end
endcase
 
if(!LXTXPS || rf_warm_reset) begin
init_state <= INIT_TX_NULL_1;
if(rf_warm_reset)
rtc_rx_initialize <= 1'b1;
end
 
end
end
 
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
 
`ifdef RESET_ALL
if(!res_n) begin
for(i_f=0;i_f<FPW;i_f=i_f+1) data2rtc_stage_flit[i_f] <= {128{1'b0}};
for(i_f=0;i_f<FPW-1;i_f=i_f+1) d_in_buf_flit[i_f] <= {128{1'b0}};
end else
`endif
begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2rtc_stage_flit[i_f] <= {128{1'b0}};
end
 
case(state)
 
INIT: begin
if(init_state == INIT_TX_TS1) begin
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2rtc_stage_flit[i_f] <= ts1_flit[i_f];
end
end
end
 
IDLE: begin
if(|remaining_tokens && !ram_full)begin
data2rtc_stage_flit[0] <= {{64{1'b0}},tret_hdr};
end
end
 
TX: begin
//Choose the data source
if(d_in_use_buf) begin
for(i_f=0;i_f<FPW-1;i_f=i_f+1) begin
data2rtc_stage_flit[i_f+1] <= d_in_buf_flit[i_f];
end
end else begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2rtc_stage_flit[i_f] <= d_in_flit[i_f];
end
end
 
for(i_f=0;i_f<FPW-1;i_f=i_f+1)begin
//No matter what, fill the buffer
d_in_buf_flit[i_f] <= d_in_flit[i_f+1];
end
end
 
HMC_RTRY: begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin //Send IRTRY start retry
data2rtc_stage_flit[i_f] <= {48'h0,8'b00000001,8'h00,irtry_hdr};
end
end
 
LNK_RTRY: begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin //Send IRTRY clear error abort
data2rtc_stage_flit[i_f] <= {48'h0,8'b00000010,8'h00,irtry_hdr};
end
end
endcase
end
 
if(!res_n) begin
data2rtc_stage_flit_is_hdr <= {FPW{1'b0}};
data2rtc_stage_flit_is_tail <= {FPW{1'b0}};
data2rtc_stage_flit_is_valid <= {FPW{1'b0}};
504,36 → 622,24
d_in_shift_out <= 1'b0;
 
//----Reset the input buffer reg
d_in_buf_flit_is_hdr <= {FPW{1'b0}};
d_in_buf_flit_is_tail <= {FPW{1'b0}};
d_in_buf_flit_is_valid <= {FPW{1'b0}};
d_in_buf_flit_is_hdr <= {FPW-1{1'b0}};
d_in_buf_flit_is_valid <= {FPW-1{1'b0}};
d_in_use_buf <= 1'b0;
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
d_in_buf_flit[i_f] <= {128{1'b0}};
end
 
//----Init Regs
for(i_t=0;i_t<TS1_SEQ_INC_VAL_PER_CYCLE;i_t=i_t+1) begin
ts1_seq_nr_per_flit[i_t] <= i_t;
end
num_init_nulls_sent <= 6'h0;
 
//General
state <= TX_NULL_1;
rtc_rx_initialize <= 1'b1;
state <= INIT;
 
//Token Flow Control
remaining_tokens <= {10{1'b0}};
remaining_tokens <= {LOG_MAX_RX_TOKENS{1'b0}};
rtc_return_val <= {5{1'b0}};
rtc_return <= 1'b0;
 
//Retry
irtry_start_retry_cnt <= {6{1'b0}};
irtry_clear_error_cnt <= {6{1'b0}};
irtry_start_retry_cnt <= {5{1'b0}};
irtry_clear_error_cnt <= {5{1'b0}};
 
//HMC Control
hmc_LxRXPS <= 1'b1;
rf_hmc_is_in_sleep <= 1'b0;
LXRXPS <= 1'b1;
 
//Flow Control
tx_link_retry_request <= 1'b0;
544,25 → 650,17
//---------------------------------INIT
//====================================================================
//Reset control signals
d_in_shift_out <= 1'b0;
rtc_rx_initialize <= 1'b0;
d_in_shift_out <= 1'b0;
irtry_start_retry_cnt <= {5{1'b0}};
irtry_clear_error_cnt <= {5{1'b0}};
 
//HMC Control
hmc_LxRXPS <= 1'b1;
rf_hmc_is_in_sleep <= 1'b0;
LXRXPS <= 1'b1;
 
if(rx_force_tx_retry)begin
tx_link_retry_request <= 1'b1;
end
 
//Warm Reset
// if(rf_warm_reset) begin
// //in case of a warm reset request, continue at TX_NULL_2 sequence and intialize tokens to be returned
// state <= TX_NULL_2;
// num_init_nulls_sent <= {6{1'b0}};
// rtc_rx_initialize <= 1'b1;
// end
 
//RTC
rtc_return <= 1'b0;
//Initialize rtc to be transmitted after reset and warm reset
579,61 → 677,10
data2rtc_stage_is_flow <= 1'b0;
data2rtc_stage_force_tx_retry <= 1'b0;
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2rtc_stage_flit[i_f] <= 128'h0;
end
rtc_return_val <= outstanding_tokens_to_return;
 
case(state)
 
//---------------------------------INIT. Refer to Initialization section in the specification
 
TX_NULL_1: begin
 
num_init_nulls_sent <= 6'h0;
 
//---State---
if(rf_hmc_received_init_null)begin
state <= TX_TS1;
end
 
end
 
TX_TS1: begin
 
data2rtc_stage_is_flow <= 1'b1;
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2rtc_stage_flit[i_f] <= ts1_flit[i_f];
end
 
for(i_t=0;i_t<TS1_SEQ_INC_VAL_PER_CYCLE;i_t=i_t+1) begin
ts1_seq_nr_per_flit[i_t] <= ts1_seq_nr_per_flit[i_t] + TS1_SEQ_INC_VAL_PER_CYCLE;
end
 
//---State---
if(rf_descramblers_aligned)begin
state <= TX_NULL_2;
end
 
end
 
TX_NULL_2: begin
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2rtc_stage_flit[i_f] <= NULL_FLIT;
end
 
//Issue at least 32 NULL FLITs before going active
if(num_init_nulls_sent+FPW > NUM_NULL_TO_SEND_BEFORE_IDLE) begin
if(rf_link_is_up)begin
state <= IDLE;
end
end else begin
num_init_nulls_sent <= num_init_nulls_sent + FPW;
end
 
end
 
//====================================================================
//---------------------------------Normal operation (including init TRETs)
//====================================================================
640,23 → 687,24
// Some branches to other states may be removed in HMC_RTRY for instance.
// Saves logic if an additional cycle in IDLE is acceptable
 
INIT: begin
if(init_state==INIT_DONE) state <= IDLE;
end
 
IDLE: begin
//Issue NULL Flits if there's nothing else to do
 
//SEND TRET PACKET even if there are no tokens available
if(remaining_tokens && !ram_full && !tx_retry_ongoing && !rf_dbg_dont_send_tret)begin
//RTC will be added in the RTC stage
data2rtc_stage_flit[0] <= {{64{1'b0}},tret_hdr};
if(|remaining_tokens && !ram_full)begin
data2rtc_stage_flit_is_hdr[0] <= 1'b1;
data2rtc_stage_flit_is_tail[0] <= 1'b1;
data2rtc_stage_flit_is_valid[0] <= 1'b1;
 
remaining_tokens <= remaining_tokens + rx_hmc_tokens_to_return + rx_hmc_poisoned_tokens_to_return - outstanding_tokens_to_return;
rtc_return_val <= outstanding_tokens_to_return;
rtc_return <= 1'b1;
end
 
//---State---
// //---State---
if(force_hmc_retry) begin
state <= HMC_RTRY;
end else if(tx_link_retry_request) begin
678,65 → 726,52
d_in_shift_out <= 1'b1;
 
//Fill the buffer
d_in_buf_flit_is_hdr <= d_in_flit_is_hdr;
d_in_buf_flit_is_tail <= d_in_flit_is_tail;
d_in_buf_flit_is_valid <= d_in_flit_is_valid;
d_in_buf_flit_is_hdr <= d_in_flit_is_hdr[FPW-1:1];
d_in_buf_flit_is_valid <= d_in_flit_is_valid[FPW-1:1];
 
//If there is data buffered - use it
data2rtc_stage_flit_is_hdr <= d_in_use_buf ? d_in_buf_flit_is_hdr : d_in_flit_is_hdr;
data2rtc_stage_flit_is_tail <= d_in_use_buf ? d_in_buf_flit_is_tail : d_in_flit_is_tail;
data2rtc_stage_flit_is_valid <= d_in_use_buf ? d_in_buf_flit_is_valid : d_in_flit_is_valid;
data2rtc_stage_flit_is_hdr <= d_in_use_buf ? {d_in_buf_flit_is_hdr,1'b0} : d_in_flit_is_hdr;
data2rtc_stage_flit_is_tail <= d_in_use_buf ? {FPW{1'b0}} : d_in_flit_is_tail;
data2rtc_stage_flit_is_valid <= d_in_use_buf ? {d_in_buf_flit_is_valid,1'b0} : d_in_flit_is_valid;
 
//Set RTC to be added in the next step
if( remaining_tokens &&
//if buffer should be used -> take buffered tail information
((d_in_use_buf && |d_in_buf_flit_is_tail) ||
//otherwise use regular data input
(!d_in_use_buf && |d_in_flit_is_tail))
if( |remaining_tokens &&
(!d_in_use_buf && |d_in_flit_is_tail)
) begin
remaining_tokens <= remaining_tokens + rx_hmc_tokens_to_return + rx_hmc_poisoned_tokens_to_return - outstanding_tokens_to_return;
rtc_return_val <= outstanding_tokens_to_return;
rtc_return <= 1'b1;
end
 
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
//Choose the data source
data2rtc_stage_flit[i_f] <= !d_in_use_buf ? d_in_flit[i_f] : d_in_buf_flit[i_f];
//No matter what, fill the buffer
d_in_buf_flit[i_f] <= d_in_flit[i_f];
end
 
 
//Exit state if seen a tail and exit condition occured
if( ((!d_in_use_buf && |d_in_flit_is_tail) || (d_in_use_buf && |d_in_buf_flit_is_tail)) &&
if( ((!d_in_use_buf && |d_in_flit_is_tail)) &&
(force_hmc_retry || ram_full || tx_link_retry_request || !hmc_tokens_av || d_in_a_empty)) begin
 
d_in_shift_out <= 1'b0;
 
if(force_hmc_retry) begin
state <= HMC_RTRY;
end else if(tx_link_retry_request) begin
state <= LNK_RTRY;
end else begin
state <= IDLE;
end
 
case ({force_hmc_retry,tx_link_retry_request})
2'b00: state <= IDLE;
2'b01: state <= LNK_RTRY;
default: state <= HMC_RTRY;
endcase
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if((d_in_use_buf && d_in_buf_flit_is_tail[i_f]) || (!d_in_use_buf && d_in_flit_is_tail[i_f]))begin
if(!d_in_use_buf && d_in_flit_is_tail[i_f])begin
data2rtc_stage_flit_is_valid <= {FPW{1'b1}} >> {FPW-1-i_f};
d_in_buf_flit_is_hdr <= d_in_flit_is_hdr & ({FPW{1'b1}} << (i_f + 1));
d_in_buf_flit_is_tail <= d_in_flit_is_tail & ({FPW{1'b1}} << (i_f + 1));
d_in_buf_flit_is_valid <= d_in_flit_is_valid & ({FPW{1'b1}} << (i_f + 1));
end
end
 
for(i_f=1;i_f<FPW;i_f=i_f+1)begin
if(d_in_flit_is_tail[i_f])begin
d_in_buf_flit_is_hdr <= d_in_flit_is_hdr[FPW-1:1] & ({FPW-1{1'b1}} << i_f);
d_in_buf_flit_is_valid <= d_in_flit_is_valid[FPW-1:1] & ({FPW-1{1'b1}} << i_f);
end
end
 
//Use buf next time TX state is entered if there is a packet pending
if((!d_in_use_buf && (d_in_flit_is_hdr[FPW-1:1] > d_in_flit_is_tail[FPW-1:1])) ||
(d_in_use_buf && (d_in_buf_flit_is_hdr[FPW-1:1] > d_in_buf_flit_is_tail[FPW-1:1])) )begin
if(!d_in_use_buf && (d_in_flit_is_hdr[FPW-1:1] > d_in_flit_is_tail[FPW-1:1]))begin
d_in_use_buf <= 1'b1;
end
 
end
end
 
743,31 → 778,13
//---------------------------------An error in RX path occured - send irtry start packets
HMC_RTRY: begin
 
data2rtc_stage_flit_is_hdr <= {FPW{1'b1}};
data2rtc_stage_flit_is_tail <= {FPW{1'b1}};
data2rtc_stage_flit_is_valid <= {FPW{1'b1}};
data2rtc_stage_is_flow <= 1'b1;
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin //Send IRTRY start retry
data2rtc_stage_flit[i_f] <= {48'h0,8'b00000001,8'h00,irtry_hdr};
end
 
irtry_start_retry_cnt <= irtry_start_retry_cnt + FPW;
 
if(irtry_start_retry_cnt+FPW >= rf_irtry_to_send)begin
irtry_start_retry_cnt <= {6{1'b0}};
 
//---State---
if(rf_dbg_halt_on_error_abort) begin
state <= DEBUG;
end else if(tx_link_retry_request) begin
state <= LNK_RTRY;
end else if(!d_in_empty && !ram_full && hmc_tokens_av)begin
state <= TX;
d_in_shift_out <= ~d_in_use_buf;
end else begin
state <= IDLE;
end
irtry_start_retry_cnt <= {5{1'b0}};
state <= IDLE;
end
 
end
777,17 → 794,12
// re-send all valid packets in RAM after sending clear error packets
LNK_RTRY: begin
 
if(!tx_retry_ongoing && (tx_link_retry_request || irtry_clear_error_cnt>0)) begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin //Send IRTRY clear error abort
data2rtc_stage_flit[i_f] <= {48'h0,8'b00000010,8'h00,irtry_hdr};
end
data2rtc_stage_flit_is_hdr <= {FPW{1'b1}};
data2rtc_stage_flit_is_tail <= {FPW{1'b1}};
data2rtc_stage_flit_is_valid <= {FPW{1'b1}};
if(!tx_retry_ongoing && (tx_link_retry_request || |irtry_clear_error_cnt)) begin
 
data2rtc_stage_is_flow <= 1'b1;
 
if(irtry_clear_error_cnt+FPW >= rf_irtry_to_send)begin
irtry_clear_error_cnt <= {6{1'b0}};
irtry_clear_error_cnt <= {5{1'b0}};
data2rtc_stage_force_tx_retry <= 1'b1;
end else begin
irtry_clear_error_cnt <= irtry_clear_error_cnt + FPW;
795,20 → 807,10
end
 
if(tx_retry_finished && !tx_link_retry_request) begin
//---State---
if(rf_dbg_halt_on_tx_retry) begin
state <= DEBUG;
end else if(force_hmc_retry) begin
state <= HMC_RTRY;
end else if(!d_in_empty && !ram_full && hmc_tokens_av) begin
state <= TX;
d_in_shift_out <= ~d_in_use_buf;
end else begin
state <= IDLE;
end
state <= IDLE;
end
 
if(!tx_retry_ongoing) begin
if(!tx_retry_ongoing && !rx_force_tx_retry) begin
tx_link_retry_request <= 1'b0;
end
end
816,45 → 818,30
//---------------------------------Power State Management
SLEEP: begin
 
hmc_LxRXPS <= 1'b0;
 
if(!hmc_LxTXPS) begin
rf_hmc_is_in_sleep <= 1'b1;
if(rf_hmc_sleep_requested) begin
LXRXPS <= 1'b0;
end else begin
state <= WAIT_FOR_HMC;
end
 
if(!rf_hmc_sleep_requested) begin
state <= WAIT_FOR_HMC;
hmc_LxRXPS <= 1'b1;
end
 
end
 
WAIT_FOR_HMC: begin
 
rf_hmc_is_in_sleep <= 1'b1;
 
if(hmc_LxTXPS) begin
state <= TX_NULL_1;
if(LXTXPS) begin
state <= INIT;
end
 
end
 
DEBUG: begin
//Freeze execution to debug in hardware
if(!(rf_dbg_halt_on_tx_retry || rf_dbg_halt_on_error_abort)) begin
state <= IDLE;
end else begin
state <= DEBUG;
end
end
 
endcase
 
if(!rf_hmc_init_cont_set) begin
state <= TX_NULL_1;
num_init_nulls_sent <= 6'h0;
rtc_rx_initialize <= 1'b1;
//Warm Reset
if(rf_warm_reset) begin
//in case of a warm reset request, continue at INIT_TX_NULL_2 sequence and intialize tokens to be returned
state <= INIT;
end
 
end
end
 
865,15 → 852,17
//This always block remains combinational to save one cycle
always @(*) begin
 
flits_transmitted = {LOG_FPW+1{1'b0}};
flits_in_buf = {LOG_FPW+1{1'b0}};
num_flits_transmitted = {LOG_FPW+1{1'b0}};
num_flits_in_buf = {LOG_FPW{1'b0}};
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(d_in_flit_is_valid[i_f] && d_in_shift_out) begin
flits_transmitted = flits_transmitted + {{LOG_FPW{1'b0}},1'b1};
num_flits_transmitted = num_flits_transmitted + 1;
end
end
for(i_f=0;i_f<FPW-1;i_f=i_f+1)begin
if(d_in_buf_flit_is_valid[i_f] && d_in_use_buf) begin
flits_in_buf = flits_in_buf + {{LOG_FPW{1'b0}},1'b1};
num_flits_in_buf = num_flits_in_buf + 1;
end
end
end
882,14 → 871,14
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
rf_hmc_tokens_av <= {10{1'b0}};
rf_hmc_tokens_av <= {LOG_MAX_HMC_TOKENS{1'b0}};
end else begin
rf_hmc_tokens_av <= rf_hmc_tokens_av + rx_returned_tokens - flits_transmitted;
rf_hmc_tokens_av <= rf_hmc_tokens_av + rx_returned_tokens - num_flits_transmitted;
end
end
 
//====================================================================
//---------------------------------Counter in the RF , right now only data transactions are counted
//---------------------------------Counter in the RF, currently only data transactions are counted
//====================================================================
always @(*) begin
 
921,20 → 910,61
end
end
 
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
rf_sent_p <= {HMC_RF_RWIDTH{1'b0}};
rf_sent_np <= {HMC_RF_RWIDTH{1'b0}};
rf_sent_r <= {HMC_RF_RWIDTH{1'b0}};
end else begin
rf_sent_p <= rf_sent_p + {{HMC_RF_RWIDTH-LOG_FPW-1{1'b0}},rf_sent_p_comb};
rf_sent_np <= rf_sent_np + {{HMC_RF_RWIDTH-LOG_FPW-1{1'b0}},rf_sent_np_comb};
rf_sent_r <= rf_sent_r + {{HMC_RF_RWIDTH-LOG_FPW-1{1'b0}},rf_sent_r_comb};
end
end
 
 
`ifdef XILINX
openhmc_counter48_wrapper_xilinx #(
.INC_SIZE(LOG_FPW+1),
.PIPELINED(XIL_CNT_PIPELINED)
) cnt_sent_p (
.clk(clk),
.res_n(res_n),
.inc_value(rf_sent_p_comb),
.value(rf_sent_p)
);
 
openhmc_counter48_wrapper_xilinx #(
.INC_SIZE(LOG_FPW+1),
.PIPELINED(XIL_CNT_PIPELINED)
) cnt_sent_np (
.clk(clk),
.res_n(res_n),
.inc_value(rf_sent_np_comb),
.value(rf_sent_np)
);
 
openhmc_counter48_wrapper_xilinx #(
.INC_SIZE(LOG_FPW+1),
.PIPELINED(XIL_CNT_PIPELINED)
) cnt_sent_r (
.clk(clk),
.res_n(res_n),
.inc_value(rf_sent_r_comb),
.value(rf_sent_r)
);
`else
reg [RF_COUNTER_SIZE-1:0] rf_sent_p_temp;
reg [RF_COUNTER_SIZE-1:0] rf_sent_np_temp;
reg [RF_COUNTER_SIZE-1:0] rf_sent_r_temp;
assign rf_sent_p = rf_sent_p_temp;
assign rf_sent_np = rf_sent_np_temp;
assign rf_sent_r = rf_sent_r_temp;
 
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
rf_sent_p_temp <= {RF_COUNTER_SIZE{1'b0}};
rf_sent_np_temp <= {RF_COUNTER_SIZE{1'b0}};
rf_sent_r_temp <= {RF_COUNTER_SIZE{1'b0}};
end else begin
rf_sent_p_temp <= rf_sent_p_temp + {{RF_COUNTER_SIZE-LOG_FPW-1{1'b0}},rf_sent_p_comb};
rf_sent_np_temp <= rf_sent_np_temp + {{RF_COUNTER_SIZE-LOG_FPW-1{1'b0}},rf_sent_np_comb};
rf_sent_r_temp <= rf_sent_r_temp + {{RF_COUNTER_SIZE-LOG_FPW-1{1'b0}},rf_sent_r_comb};
end
end
`endif
 
//====================================================================
//---------------------------------HMC Retry Logic
//====================================================================
952,7 → 982,7
rf_error_abort_not_cleared <= 1'b0;
 
if(rx_error_abort_mode)begin
error_abort_mode_clr_cnt <= error_abort_mode_clr_cnt + 1;
error_abort_mode_clr_cnt <= error_abort_mode_clr_cnt + 1; //decrement counter
end
 
if(rx_error_abort_mode_cleared) begin
959,13 → 989,13
error_abort_mode_clr_cnt <= {8{1'b0}};
end
 
if((rx_error_abort_mode && state!=HMC_RTRY && error_abort_mode_clr_cnt==0) || (error_abort_mode_clr_cnt > CYCLES_TO_CLEAR_ERR_ABORT_MODE))begin
if(&error_abort_mode_clr_cnt) begin
rf_error_abort_not_cleared <= 1'b1;
end
 
if((rx_error_abort_mode && state!=HMC_RTRY && |error_abort_mode_clr_cnt==1'b0) || (&error_abort_mode_clr_cnt))begin
force_hmc_retry <= 1'b1;
error_abort_mode_clr_cnt <= {8{1'b0}};
if(error_abort_mode_clr_cnt > CYCLES_TO_CLEAR_ERR_ABORT_MODE) begin
rf_error_abort_not_cleared <= 1'b1;
end
 
end else begin
if(state==HMC_RTRY)begin
force_hmc_retry <= 1'b0;
978,71 → 1008,105
//====================================================================
//---------------------------------RTC Stage
//====================================================================
always @(*) begin
rtc_return_sent = 0;
generate
if(OPEN_RSP_MODE==0) begin : RTC_stage
reg [4:0] data2seq_frp_stage_flit_rtc [FPW-1:0];
reg rtc_return_sent;
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2seq_frp_stage_flit_comb[i_f] = data2rtc_stage_flit[i_f];
always @(*) begin
rtc_return_sent = 0;
 
if(data2rtc_stage_flit_is_tail[i_f] && !data2rtc_stage_is_flow && !rtc_return_sent && rtc_return) begin
//Return outstanding tokens, but only once per cycle
data2seq_frp_stage_flit_comb[i_f][64+31:64+27] = rtc_return_val;
rtc_return_sent = 1'b1;
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(data2rtc_stage_flit_is_tail[i_f] && !rtc_return_sent && rtc_return) begin
//Return outstanding tokens, but only once per cycle
data2seq_frp_stage_flit_rtc[i_f] = rtc_return_val;
rtc_return_sent = 1'b1;
end else begin
data2seq_frp_stage_flit_rtc[i_f] = 5'h00;
end
end
end
end
 
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
data2seq_frp_stage_flit_is_hdr <= {FPW{1'b0}};
data2seq_frp_stage_flit_is_tail <= {FPW{1'b0}};
data2seq_frp_stage_flit_is_valid <= {FPW{1'b0}};
data2seq_frp_stage_is_flow <= 1'b0;
data2seq_frp_stage_force_tx_retry <= 1'b0;
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2seq_frp_stage_flit[i_f] <= {128{1'b0}};
`ifdef ASYNC_RES
if(!res_n)
data2seq_frp_stage_flit[i_f] <= {128{1'b0}};
else
`endif
begin
data2seq_frp_stage_flit[i_f] <= data2rtc_stage_flit[i_f];
if(data2rtc_stage_flit_is_tail[i_f]) begin
data2seq_frp_stage_flit[i_f][64+31:64+27] <= data2seq_frp_stage_flit_rtc[i_f];
end
end
end
end
end else begin
data2seq_frp_stage_flit_is_hdr <= data2rtc_stage_flit_is_hdr & data2rtc_stage_flit_is_valid;
data2seq_frp_stage_flit_is_tail <= data2rtc_stage_flit_is_tail & data2rtc_stage_flit_is_valid;
data2seq_frp_stage_flit_is_valid <= data2rtc_stage_flit_is_valid;
data2seq_frp_stage_is_flow <= data2rtc_stage_is_flow;
data2seq_frp_stage_force_tx_retry <= data2rtc_stage_force_tx_retry;
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2seq_frp_stage_flit[i_f] <= data2seq_frp_stage_flit_comb[i_f];
 
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
`ifdef ASYNC_RES
if(!res_n)
data2seq_frp_stage_flit[i_f] <= {128{1'b0}};
else
`endif
begin
data2seq_frp_stage_flit[i_f] <= data2rtc_stage_flit[i_f];
end
end
end
end
end
endgenerate
 
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
`ifdef RESET_ALL
if(!res_n) begin
data2seq_frp_stage_flit_is_hdr <= {FPW{1'b0}};
data2seq_frp_stage_flit_is_tail <= {FPW{1'b0}};
data2seq_frp_stage_flit_is_valid <= {FPW{1'b0}};
data2seq_frp_stage_is_flow <= 1'b0;
data2seq_frp_stage_force_tx_retry <= 1'b0;
end else
`endif
begin
data2seq_frp_stage_flit_is_hdr <= data2rtc_stage_flit_is_hdr & data2rtc_stage_flit_is_valid;
data2seq_frp_stage_flit_is_tail <= data2rtc_stage_flit_is_tail & data2rtc_stage_flit_is_valid;
data2seq_frp_stage_flit_is_valid <= data2rtc_stage_flit_is_valid;
data2seq_frp_stage_is_flow <= data2rtc_stage_is_flow;
data2seq_frp_stage_force_tx_retry <= data2rtc_stage_force_tx_retry;
end
end
 
//====================================================================
//---------------------------------Seqnum and FRP Stage
//====================================================================
 
always @(*) begin
tx_seqnum_temp = {LOG_FPW+1{1'b0}};
 
//Set data flits
tx_seqnum_inc = {LOG_FPW{1'b0}};
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(data2seq_frp_stage_flit_is_valid[i_f] | data2seq_frp_stage_is_flow) begin
data2ram_flit_temp[i_f] = data2seq_frp_stage_flit[i_f];
end else begin
data2ram_flit_temp[i_f] = {128{1'b0}};
tx_seqnum_temp[i_f] = 0;
if(data2seq_frp_stage_flit_is_tail[i_f])begin
tx_seqnum_inc = tx_seqnum_inc + 1;
tx_seqnum_temp[i_f] = tx_seqnum + tx_seqnum_inc;
end
end
 
//Increment ram addr(also frp) if there is a valid FLIT that is not flow
if(|data2seq_frp_stage_flit_is_valid && !data2seq_frp_stage_is_flow)begin
tx_frp_adr_incr_temp = 1'b1;
end else begin
tx_frp_adr_incr_temp = 1'b0;
end
target_temp[0] = next_target;
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(data2seq_frp_stage_flit_is_tail[i_f] && !data2seq_frp_stage_is_flow && data2seq_frp_stage_flit_is_valid[i_f])begin
tx_seqnum_temp = tx_seqnum_temp + 1;
//Assign the FRP, combined of the ram selected and the RAM address
data2ram_flit_temp[i_f][64+15+3:64+8] = {tx_seqnum+tx_seqnum_temp,tx_frp_adr+tx_frp_adr_incr_temp,tx_frp_ram[i_f]};
if(data2rtc_stage_flit_is_valid[i_f]) begin
target_temp[i_f+1] = target_temp[i_f] + 1;
if(target_temp[i_f+1]==FPW)
target_temp[i_f+1]=0;
end else begin
target_temp[i_f+1] = target_temp[i_f];
end
end
end
1051,12 → 1115,20
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
//Reset frp and seqnum
tx_frp_adr <= {LOG_FPW{1'b0}};
//Reset the target RAM location and seqnum
tx_seqnum <= {LOG_FPW{1'b0}};
next_target <= {LOG_FPW{1'b0}};
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
target[i_f] <= {FPW{1'b0}};
end
end else begin
tx_frp_adr <= tx_frp_adr + tx_frp_adr_incr_temp;
tx_seqnum <= tx_seqnum + tx_seqnum_temp;
tx_seqnum <= tx_seqnum + tx_seqnum_inc;
if(!data2rtc_stage_is_flow) begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
target[i_f] <= target_temp[i_f];
end
next_target <= target_temp[FPW];
end
end
end
 
1064,24 → 1136,44
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
data2ram_flit_is_hdr <= {FPW{1'b0}};
data2ram_flit_is_tail <= {FPW{1'b0}};
data2ram_flit_is_valid <= {FPW{1'b0}};
data2ram_is_flow <= 1'b0;
data2ram_force_tx_retry <= 1'b0;
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2ram_flit[i_f] <= {128{1'b0}};
`ifdef RESET_ALL
if(!res_n) data2ram_flit[i_f] <= {128{1'b0}};
else
`endif
begin
data2ram_flit[i_f] <= data2seq_frp_stage_flit[i_f];
 
if(data2seq_frp_stage_flit_is_tail[i_f]) begin
data2ram_flit[i_f][64+15+3:64+8] <= {tx_seqnum_temp[i_f],tx_frp_adr[target[i_f]],target[i_f]};
end
end
end
end else begin
data2ram_flit_is_hdr <= data2seq_frp_stage_flit_is_hdr;
 
data2ram_flit_is_hdr <= data2seq_frp_stage_flit_is_hdr | {FPW{data2seq_frp_stage_is_flow}};
data2ram_flit_is_tail <= data2seq_frp_stage_flit_is_tail;
data2ram_flit_is_valid <= data2seq_frp_stage_flit_is_valid;
data2ram_is_flow <= data2seq_frp_stage_is_flow ;
data2ram_flit_is_valid <= data2seq_frp_stage_flit_is_valid | {FPW{data2seq_frp_stage_is_flow}};
data2ram_force_tx_retry <= data2seq_frp_stage_force_tx_retry;
if(!res_n) begin
`ifdef RESET_ALL
data2ram_flit_is_hdr <= {FPW{1'b0}};
data2ram_flit_is_tail <= {FPW{1'b0}};
data2ram_flit_is_valid <= {FPW{1'b0}};
data2ram_force_tx_retry <= 1'b0;
`endif
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2ram_flit[i_f] <= data2ram_flit_temp[i_f];
tx_frp_adr[i_f] <= {RAM_ADDR_SIZE{1'b0}};
end
end else begin
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(data2seq_frp_stage_flit_is_valid[i_f]) begin
tx_frp_adr[target[i_f]] <= tx_frp_adr[target[i_f]] + 1;
end
end
 
end
end
 
1092,44 → 1184,30
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
ram_w_data[i_f] <= {128+3{1'b0}};
end
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
ram_w_data[target[i_f]] <= { data2seq_frp_stage_flit_is_valid[i_f],
data2seq_frp_stage_flit_is_tail[i_f],
data2seq_frp_stage_flit_is_hdr[i_f],
data2seq_frp_stage_flit[i_f]
};
 
end else begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(!data2ram_is_flow)begin
ram_w_data[i_f] <= { data2ram_flit_is_valid[i_f],
data2ram_flit_is_tail[i_f],
data2ram_flit_is_hdr[i_f],
data2ram_flit[i_f]
};
if(data2seq_frp_stage_flit_is_tail[i_f])begin
ram_w_data[target[i_f]][64+15+3:64+8] <= {tx_seqnum_temp[i_f],tx_frp_adr[target[i_f]],target[i_f]};
end
end
end
end
end
 
//-- Write to RAM and increment the address if there are valid FLITs to be written
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
if(!res_n) begin
//Reset control signals
ram_w_addr <= {RAM_ADDR_SIZE{1'b0}};
ram_w_en <= 1'b1;
end else begin
 
//Reset control signals
ram_w_en <= 1'b0;
 
if(|data2ram_flit_is_valid && !data2ram_is_flow) begin
ram_w_addr <= ram_w_addr + 1;
ram_w_en <= 1'b1;
if(!res_n) begin
ram_w_en <= {FPW{1'b0}};
end else begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(data2seq_frp_stage_flit_is_valid[i_f]) begin
ram_w_en[target[i_f]] <= 1'b1;
end else begin
ram_w_en[target[i_f]] <= 1'b0;
end
end
end
 
end
end
 
//====================================================================
//---------------------------------Select Data Source: Valid sources are the Retry Buffers or regular data stream.
1137,6 → 1215,24
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
`ifdef RESET_ALL
if(!res_n) data2rrp_stage_flit[i_f] <= {128{1'b0}};
else
`endif
begin
if(tx_retry_ongoing) begin
//-- If there's a TX retry ongoing increment read address until it equals the write address
data2rrp_stage_flit[i_f] <= ram_r_data[i_f][127:0];
end else begin
//Propagate data from normal packet stream
data2rrp_stage_flit[i_f] <= data2ram_flit[i_f];
end
end
end
 
if(!res_n) begin
//Reset control signals
tx_retry_finished <= 1'b0;
1146,52 → 1242,43
//Ram
ram_r_en <= 1'b0;
ram_r_addr_temp <= {RAM_ADDR_SIZE{1'b0}};
ram_r_mask <= {FPW{1'b1}};
ram_r_mask <= {FPW{1'b0}};
 
//Data propagation
data2rrp_stage_flit_is_hdr <= {FPW{1'b0}};
data2rrp_stage_flit_is_tail <= {FPW{1'b0}};
data2rrp_stage_flit_is_valid <= {FPW{1'b0}};
data2rrp_stage_is_flow <= 1'b0;
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2rrp_stage_flit[i_f] <= {128{1'b0}};
end
 
end else begin
tx_retry_finished <= 1'b0;
tx_retry_ongoing <= 1'b0;
rf_cnt_retry <= 1'b0;
 
data2rrp_stage_is_flow <= 1'b0;
ram_r_en <= 1'b0;
ram_r_addr_temp <= {RAM_ADDR_SIZE{1'b0}};
ram_r_mask <= {FPW{1'b0}};
 
//if there is a retry request coming set the ram address to last received rrp
if(data2rtc_stage_force_tx_retry) begin
if(data2seq_frp_stage_force_tx_retry) begin
ram_r_en <= 1'b1;
ram_r_addr_temp <= ram_r_addr;
ram_r_mask <= ({FPW{1'b1}}) << (rx_rrp[HMC_PTR_SIZE-RAM_ADDR_SIZE-1:0]);
ram_r_addr_temp <= ram_r_addr+1;
end
 
if(!tx_retry_ongoing) begin
 
//Propagate data from normal packet stream
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2rrp_stage_flit[i_f] <= data2ram_flit[i_f];
end
data2rrp_stage_flit_is_hdr <= data2ram_flit_is_hdr;
data2rrp_stage_flit_is_tail <= data2ram_flit_is_tail;
data2rrp_stage_flit_is_valid <= data2ram_flit_is_valid;
data2rrp_stage_is_flow <= data2ram_is_flow;
 
 
//Switch to retry if requested
if(data2ram_force_tx_retry) begin
 
if(ram_r_addr_temp == ram_w_addr_next) begin //if the next address is the write address -> no retry. That should never happen
if(ram_r_addr_temp == ram_w_addr_next) begin //if the next address is the write address -> no retry.
tx_retry_finished <= 1'b1;
tx_retry_ongoing <= 1'b0;
ram_r_en <= 1'b0;
end else begin
ram_r_addr_temp <= ram_r_addr_temp + 1;
ram_r_mask <= ({FPW{1'b1}}) << (rx_rrp[8-RAM_ADDR_SIZE-1:0]);
ram_r_addr_temp <= ram_r_addr_temp+1;
ram_r_en <= 1'b1;
rf_cnt_retry <= 1'b1;
tx_retry_ongoing <= 1'b1;
end
1202,28 → 1289,25
ram_r_mask <= {FPW{1'b1}};
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(ram_r_mask[i_f])begin
//Within the first cycle of retry, choose only the proper flit sources
data2rrp_stage_flit[i_f] <= ram_r_data[i_f][128-1:0];
data2rrp_stage_flit_is_hdr[i_f] <= ram_r_data[i_f][128];
data2rrp_stage_flit_is_tail[i_f] <= ram_r_data[i_f][128+1];
data2rrp_stage_flit_is_valid[i_f] <= ram_r_data[i_f][128+2];
end else begin
//And reset all other FLITs because they're not meant to be retransmitted
data2rrp_stage_flit[i_f] <= {128{1'b0}};
data2rrp_stage_flit_is_hdr[i_f] <= 1'b0;
data2rrp_stage_flit_is_tail[i_f] <= 1'b0;
data2rrp_stage_flit_is_valid[i_f] <= 1'b0;
end
end
data2rrp_stage_flit_is_hdr[i_f] <= ram_r_mask[i_f] ? ram_r_data[i_f][128] :1'b0 ;
data2rrp_stage_flit_is_tail[i_f] <= ram_r_mask[i_f] ? ram_r_data[i_f][128+1] :1'b0 ;
data2rrp_stage_flit_is_valid[i_f] <= ram_r_mask[i_f] ? ram_r_data[i_f][128+2] :1'b0 ;
end
 
//if the next address is the write address -> retry finished
if((ram_r_addr_temp) == ram_w_addr_next) begin
if(ram_r_addr_temp == ram_w_addr_next) begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
if(i_f >= target[0] && !(tx_frp_adr[0]==tx_frp_adr[FPW-1]))begin
data2rrp_stage_flit_is_hdr[i_f] <= 1'b0;
data2rrp_stage_flit_is_tail[i_f] <= 1'b0;
data2rrp_stage_flit_is_valid[i_f] <= 1'b0;
end
end
tx_retry_finished <= 1'b1;
tx_retry_ongoing <= 1'b0;
ram_r_en <= 1'b0;
end else begin
ram_r_addr_temp <= ram_r_addr_temp + 1;
ram_r_addr_temp <= ram_r_addr_temp + 1;
tx_retry_ongoing <= 1'b1;
ram_r_en <= 1'b1;
end
 
end
1237,51 → 1321,74
`ifdef ASYNC_RES
always @(posedge clk or negedge res_n) begin `else
always @(posedge clk) begin `endif
 
`ifdef RESET_ALL
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2crc_flit[i_f] <= {128{1'b0}};
end
`endif
begin
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2crc_flit[i_f] <= (data2rrp_stage_flit_is_valid[i_f] || !init_state[1]) ? data2rrp_stage_flit[i_f] : {128{1'b0}};
 
//Add the RRP
if(data2rrp_stage_flit_is_tail[i_f] || (data2rrp_stage_flit_is_hdr[i_f] && is_req_flow(data2rrp_stage_flit[i_f])))begin
data2crc_flit[i_f][64+7:64] <= rx_hmc_frp;
end
 
//Increment the FRP by 1, It points to the next possible FLIT position -> retry will start there
if(data2rrp_stage_flit_is_tail[i_f])begin
data2crc_flit[i_f][64+15:64+8] <= data2rrp_stage_flit[i_f][64+15:64+8] + 1;
end
 
end
`ifdef SIMULATION
if((last_transmitted_rx_hmc_frp != rx_hmc_frp) && !data2rrp_stage_flit_is_valid[0])begin `else
if(!data2rrp_stage_flit_is_valid[0] && send_prets)begin `endif
data2crc_flit[0][63:0] <= pret_hdr;
data2crc_flit[0][64+7:64] <= rx_hmc_frp;
end
end
 
if(!res_n) begin
//----Reset control signals
last_transmitted_rx_hmc_frp <= {HMC_PTR_SIZE{1'b0}};
`ifdef SIMULATION
//----Reset control signals
last_transmitted_rx_hmc_frp <= {8{1'b0}};
`else
send_prets <= 1'b0;
`endif
 
//----Data
data2crc_flit_is_hdr <= {FPW{1'b0}};
data2crc_flit_is_tail <= {FPW{1'b0}};
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
data2crc_flit[i_f] <= {128{1'b0}};
end
 
end else begin
 
//Propagate signals
data2crc_flit_is_hdr <= data2rrp_stage_flit_is_hdr;
data2crc_flit_is_tail <= data2rrp_stage_flit_is_tail;
data2crc_flit_is_tail <= data2rrp_stage_flit_is_tail | ((data2rrp_stage_flit_is_hdr[FPW-1] && cmd(data2rrp_stage_flit[FPW-1])==CMD_IRTRY) ? {FPW{1'b1}} : {FPW{1'b0}}) ;
 
for(i_f=0;i_f<FPW;i_f=i_f+1)begin
 
data2crc_flit[i_f] <= data2rrp_stage_flit[i_f];
 
//Add the RRP
if(data2rrp_stage_flit_is_tail[i_f])begin
data2crc_flit[i_f][64+7:64] <= rx_hmc_frp;
`ifdef SIMULATION
//If there is a tail, remember the last transmitted RRP. Otherwise generate PRET if there is a new RRP
if(|data2rrp_stage_flit_is_tail)begin
last_transmitted_rx_hmc_frp <= rx_hmc_frp;
end
if((last_transmitted_rx_hmc_frp != rx_hmc_frp) && !data2rrp_stage_flit_is_valid[0])begin
data2crc_flit_is_hdr[0] <= 1'b1;
data2crc_flit_is_tail[0] <= 1'b1;
last_transmitted_rx_hmc_frp <= rx_hmc_frp;
end
`else
 
//Increment the FRP by 1, It points to the next possible FLIT position -> retry will start there
if(data2rrp_stage_flit_is_tail[i_f] && !data2rrp_stage_is_flow)begin
data2crc_flit[i_f][64+15:64+8] <= data2rrp_stage_flit[i_f][64+15:64+8] + 1;
end
if(|data2crc_flit_is_hdr) send_prets <= 1'b1;
if(rf_hmc_sleep_requested || rf_warm_reset) send_prets <= 1'b0;
if(!data2rrp_stage_flit_is_valid[0] && send_prets)begin
data2crc_flit_is_hdr[0] <= 1'b1;
data2crc_flit_is_tail[0] <= 1'b1;
end
`endif
 
end
 
//If there is a tail, remember the last transmitted RRP. Otherwise generate PRET if there is a new RRP
if(|data2rrp_stage_flit_is_tail)begin
last_transmitted_rx_hmc_frp <= rx_hmc_frp;
end else if((last_transmitted_rx_hmc_frp != rx_hmc_frp) && !(|data2rrp_stage_flit_is_valid))begin //else send a PRET
data2crc_flit_is_hdr[0] <= 1'b1;
data2crc_flit_is_tail[0] <= 1'b1;
data2crc_flit[0][63:0] <= pret_hdr;
data2crc_flit[0][64+7:64] <= rx_hmc_frp;
last_transmitted_rx_hmc_frp <= rx_hmc_frp;
end
 
end
end
 
1295,15 → 1402,15
generate
for(f=0;f<FPW;f=f+1)begin : retry_buffer_gen
openhmc_ram #(
.DATASIZE(128+3), //FLIT + flow/valid/hdr/tail indicator
.DATASIZE(128+3), //FLIT + tail/hdr/valid indicator
.ADDRSIZE(RAM_ADDR_SIZE)
)
retry_buffer_per_lane_I
(
.clk(clk),
.wen(ram_w_en),
.wen(ram_w_en[f]),
.wdata(ram_w_data[f]),
.waddr(ram_w_addr),
.waddr(tx_frp_adr[f]),
.ren(ram_r_en),
.raddr(ram_r_addr_temp),
.rdata(ram_r_data[f])

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.