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]) |