ContributionsMost RecentMost LikesSolutionsRe: Stratix 10 PAC HSSI example Hi, I tried implementing a word aligner by sending a pattern (0xF0000000). because of the bitslip, the RX then will receive a different value (e.g 0x003c0000). But then it turns out that the bitslip is not constant throughout the transfer. To prove that there's are bitslips happening, I took a screenshot of the receiving part. This time, the prbs_din is sync using resync. The expected sequence of the 5 first word are: 0x55555555, 0x5fffffff, 0x2a000000, 0x17a00000, 0x0aaa0000. But if you see the screenshot, you can see that the words are getting mixed, for example 0xfd555555 is parts of the first and second correct sequence. thus showing a bit slip. Although the prbs check is shows no error, the data itself is not correct. To reproduce this error, you can compile hssi_prbs example with the attached prbs_top.v and hssi.stp within src.zip. Is there any pattern to this bitslip? How do I fix this bitslips? I really need this to work, my goal is just simply moving data from 1 fpga to another. Please advise a way to correct the received data. Re: Stratix 10 PAC HSSI example Hi, I'm extracting simulation files from Stratix 10 Native PHY IP, then simulate it in modelsim. In the simulation, i tried using resync block for the receiver data, and some data is missing. Re: Stratix 10 PAC HSSI example Hello, I tried simulating (in ModelSim 10.6d) using the native PHY PCS direct with the same parameter as in ug-20211 and the same prbs_top, prbs_gen, prbs_ver_pipelined from the hssi_prbs example. I tried simulating the same steps as in hssi_prbs.c (reset, serial loopback, and unpause tx & rx). But in the simulator itself, the data received is not the same. (comparing prbs_din with prbs_dout). Is there any special instructions or configurations or technique that I need to implement in order to use PCS direct? Can someone help me with this? Re: Stratix 10 PAC HSSI example In the rtl I provided, I was not sure what the data_locked is used for, and its function is not clear in the example. However, in the screenshot I sent you I used the example design (prbs pattern_generator) and not my own pattern generator (counter). In the rx_pattern_ver waveform, we can see that the data is check before the data locked, (the pause_chk is low and the data_locked is still lo). But, even there the rx_data is not equal to tx_data. Re: Stratix 10 PAC HSSI example I compared the data in tx_parallel_data[0..31] with rx_parallel_data[0..31]. To make it clear, I attached the screenshot of logic analyzer showing the difference in tx_parallel_data and rx_parallel_data. Re: Stratix 10 PAC HSSI example Yes I can confirm that those signal is asserted if given enough time. But why is the data on the receiving end differs from the transmitter? I observed a kind of shifted value on the receiving end. Do I have to implement an error correction module? Re: Stratix 10 PAC HSSI example After several seconds, the RX_READY seems to assert well. but I couldn't found the correct data in the rx_parallel_data. using the same code. Also, in the code, bit no 79 is always set high. Is it not working if we have a valid signal for that particular signal? Re: Stratix 10 PAC HSSI example Yes i have that additional port, however i didn't use it yet to keep it the same with the original pattern_gen.v the prbs_top look like this. // `include "pr_hssi_if.vh" module prbs_top #( parameter NUM_HSSI_RAW_PR_IFCS = 2, parameter NUM_HSSI_LN = 4, parameter PRBS_DATA_WIDTH = 8, parameter PRBS_INITIAL_VALUE = 97, parameter PRBS_TAP = 31, parameter PRBS_XAUI_PATTERN = 97, parameter PRBS_NUM_CYCLES_FOR_LOCK = 8'd31, parameter PRBS_PIPELINE = 3 ) ( input logic clk, // Primary CCI-P interface clock. input logic clk_125, input logic softReset, // Raw HSSI interface pr_hssi_if.to_fiu hssi [NUM_HSSI_RAW_PR_IFCS], // HSSI control signals input logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] rx_seriallpbken, // PRBS control signals input logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] prbs_insert_error, input logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] prbs_pause_tx, input logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] prbs_pause_rx, // PRBS status signals output logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] prbs_lock, // HSSI feedback signals output logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] tx_ready, output logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] rx_ready, // PRBS counters output logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0][31:0] prbs_tx_count, output logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0][31:0] prbs_tx_err_count, output logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0][31:0] prbs_rx_count, output logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0][31:0] prbs_rx_err_count, // Resets input logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] cr2hssi_reset, input logic [NUM_HSSI_RAW_PR_IFCS-1:0][NUM_HSSI_LN-1:0] cr2ctr_reset, output logic [PRBS_DATA_WIDTH-1:0] rx_prbs_02, output logic [PRBS_DATA_WIDTH-1:0] tx_prbs_02 ); // logic to stage sync for output logic [31:0] prbs_tx_count_d [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_tx_count_en [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [31:0] prbs_rx_count_d [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_rx_count_en [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [31:0] prbs_tx_err_count_d [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_tx_err_count_en [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [31:0] prbs_rx_err_count_d [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_rx_err_count_en [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; // logic operating on hssi if clocks logic [31:0] prbs_tx_count_hssi [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [31:0] prbs_rx_count_hssi [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [31:0] prbs_tx_err_count_hssi [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [31:0] prbs_rx_err_count_hssi [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_pause_hssi_tx [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_pause_hssi_rx [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_gen_data_valid [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_pause_gen [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_pause_chk [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_pause_chk_sync [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_insert_error_hssi [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_insert_error_hssi_q [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_insert_error_hssi_e [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_lock_hssi_rx [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_lock_hssi_rx_sync [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic shift_lock_hssi_rx [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic shift_lock_hssi_tx [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_seriallpbken_hssi [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic hssi_reset [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; // PRBS outputs logic [PRBS_DATA_WIDTH-1:0] prbs_dout [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [PRBS_DATA_WIDTH-1:0] shift_dout [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [PRBS_DATA_WIDTH-1:0] prbs_din [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic [PRBS_DATA_WIDTH-1:0] prbs_din_sync [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_error_flag [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic prbs_error_flag_sync [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; //TX XCVR Clock Shared for 4 channels per QSFP logic tx_clk [NUM_HSSI_RAW_PR_IFCS]; logic tx_arst_n [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic tx_arst_n_d [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; //RX_CLKOUT 4 independent clocks per QSFP logic rx_clk [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_arst_n [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_arst_n_d [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic plls_locked [NUM_HSSI_RAW_PR_IFCS]; logic rx_data_valid [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic cr2hssi_reset_sync [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic cr2ctr_tx_reset_n [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic cr2ctr_rx_reset_n [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic tx_count_reset_n [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_count_reset_n [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic hssi_ch_reset [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic pll_arst_n [NUM_HSSI_RAW_PR_IFCS]; logic tx_analogreset [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic tx_digitalreset [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_analogreset [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_digitalreset [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_analogreset_stat [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_digitalreset_stat [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic tx_analogreset_stat [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic tx_digitalreset_stat [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_is_lockedtodata [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic tx_cal_busy [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; logic rx_cal_busy [NUM_HSSI_RAW_PR_IFCS][NUM_HSSI_LN]; genvar ch_idx, if_idx; generate for (if_idx = 0; if_idx < NUM_HSSI_RAW_PR_IFCS; if_idx = if_idx + 1) begin : HSSI_IF assign tx_clk[if_idx] = hssi[if_idx].f2a_tx_parallel_clk_x2; assign plls_locked[if_idx] = hssi[if_idx].f2a_atxpll_locked & hssi[if_idx].f2a_fpll_locked; resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_async_reset ( .clk (clk_125), .reset (~plls_locked[if_idx]), .d (1'b1), .q (pll_arst_n[if_idx]) ); for (ch_idx = 0; ch_idx < 4; ch_idx = ch_idx + 1) begin : HSSI_CH resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_tx_ctr_reset_sync ( .clk (tx_clk[if_idx]), .reset (cr2ctr_reset [if_idx][ch_idx]), .d (1'b1), .q (cr2ctr_tx_reset_n [if_idx][ch_idx]) ); resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_rx_ctr_reset_sync ( .clk (rx_clk[if_idx][ch_idx]), .reset (cr2ctr_reset [if_idx][ch_idx]), .d (1'b1), .q (cr2ctr_rx_reset_n [if_idx][ch_idx]) ); resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_prbs_pause_tx_sync ( .clk (tx_clk[if_idx]), .reset (1'b0), .d (prbs_pause_tx [if_idx][ch_idx]), .q (prbs_pause_hssi_tx [if_idx][ch_idx]) ); resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_prbs_pause_rx_sync ( .clk (rx_clk[if_idx][ch_idx]), .reset (1'b0), .d (prbs_pause_rx [if_idx][ch_idx]), .q (prbs_pause_hssi_rx [if_idx][ch_idx]) ); resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_prbs_ins_err_sync ( .clk (tx_clk[if_idx]), .reset (1'b0), .d (prbs_insert_error [if_idx][ch_idx]), .q (prbs_insert_error_hssi [if_idx][ch_idx]) ); resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_prbs_lock_sync ( .clk (clk), .reset (1'b0), .d (prbs_lock_hssi_rx [if_idx][ch_idx]), .q (prbs_lock [if_idx][ch_idx]) ); resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_shift_lock_sync ( .clk (tx_clk[if_idx]), .reset (1'b0), .d (shift_lock_hssi_rx [if_idx][ch_idx]), .q (shift_lock_hssi_tx [if_idx][ch_idx]) ); // reset signal outputs assign hssi[if_idx].a2f_tx_analogreset [ch_idx] = tx_analogreset [if_idx][ch_idx]; assign hssi[if_idx].a2f_tx_digitalreset [ch_idx] = tx_digitalreset [if_idx][ch_idx]; assign hssi[if_idx].a2f_rx_analogreset [ch_idx] = rx_analogreset [if_idx][ch_idx]; assign hssi[if_idx].a2f_rx_digitalreset [ch_idx] = rx_digitalreset [if_idx][ch_idx]; // reset status inputs assign rx_analogreset_stat [if_idx][ch_idx] = hssi[if_idx].f2a_rx_analogreset_stat [ch_idx]; assign rx_digitalreset_stat [if_idx][ch_idx] = hssi[if_idx].f2a_rx_digitalreset_stat [ch_idx]; assign tx_analogreset_stat [if_idx][ch_idx] = hssi[if_idx].f2a_tx_analogreset_stat [ch_idx]; assign tx_digitalreset_stat [if_idx][ch_idx] = hssi[if_idx].f2a_tx_digitalreset_stat [ch_idx]; assign rx_is_lockedtodata [if_idx][ch_idx] = hssi[if_idx].f2a_rx_is_lockedtodata [ch_idx]; assign tx_cal_busy [if_idx][ch_idx] = hssi[if_idx].f2a_tx_cal_busy [ch_idx]; assign rx_cal_busy [if_idx][ch_idx] = hssi[if_idx].f2a_rx_cal_busy [ch_idx]; resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_async100_reset ( .clk (clk_125), .reset (1'b0), .d (cr2hssi_reset[if_idx][ch_idx]), .q (cr2hssi_reset_sync[if_idx][ch_idx]) ); assign hssi_ch_reset[if_idx][ch_idx] = !pll_arst_n[if_idx] | cr2hssi_reset_sync[if_idx][ch_idx]; reset_controller inst_reset_controller ( .clock (clk_125), .reset (hssi_ch_reset[if_idx][ch_idx]), .tx_ready (tx_ready[if_idx][ch_idx]), // out to FME and to PR boundary .rx_ready (rx_ready[if_idx][ch_idx]), // out to FME and to PR boundary .pll_locked (plls_locked[if_idx]), // both ATX and fPLL are locked .pll_select (1'b0), .tx_analogreset (tx_analogreset [if_idx][ch_idx]), .tx_digitalreset (tx_digitalreset [if_idx][ch_idx]), .rx_analogreset (rx_analogreset [if_idx][ch_idx]), .rx_digitalreset (rx_digitalreset [if_idx][ch_idx]), .rx_analogreset_stat (rx_analogreset_stat [if_idx][ch_idx]), .rx_digitalreset_stat (rx_digitalreset_stat [if_idx][ch_idx]), .tx_analogreset_stat (tx_analogreset_stat [if_idx][ch_idx]), .tx_digitalreset_stat (tx_digitalreset_stat [if_idx][ch_idx]), .rx_is_lockedtodata (rx_is_lockedtodata [if_idx][ch_idx]), .tx_cal_busy (tx_cal_busy [if_idx][ch_idx]), .rx_cal_busy (rx_cal_busy [if_idx][ch_idx]) ); always_ff @(posedge tx_clk[if_idx] or negedge tx_arst_n[if_idx][ch_idx]) begin if(~tx_arst_n[if_idx][ch_idx]) begin prbs_insert_error_hssi_q[if_idx][ch_idx] <= '0; prbs_insert_error_hssi_e[if_idx][ch_idx] <= '0; end else begin prbs_insert_error_hssi_q[if_idx][ch_idx] <= prbs_insert_error_hssi[if_idx][ch_idx]; prbs_insert_error_hssi_e[if_idx][ch_idx] <= prbs_insert_error_hssi[if_idx][ch_idx] & !prbs_insert_error_hssi_q[if_idx][ch_idx]; end end resync #( .SYNC_CHAIN_LENGTH (2), .WIDTH (1), .INIT_VALUE (0), .NO_CUT (0) ) inst_prbs_seriallpbken_sync ( .clk (rx_clk[if_idx][ch_idx]), .reset (1'b0), .d (rx_seriallpbken [if_idx][ch_idx]), .q (rx_seriallpbken_hssi [if_idx][ch_idx]) ); // assign the rxclk assign rx_clk[if_idx][ch_idx] = hssi[if_idx].f2a_rx_clkout[ch_idx]; // Generate resets based off PLL locks assign hssi_reset[if_idx][ch_idx] = !plls_locked[if_idx] | cr2hssi_reset[if_idx][ch_idx]; always_ff @(posedge tx_clk[if_idx] or posedge hssi_reset[if_idx][ch_idx]) begin if(hssi_reset[if_idx][ch_idx]) begin {tx_arst_n[if_idx][ch_idx],tx_arst_n_d[if_idx][ch_idx]} <= '0; end else begin {tx_arst_n[if_idx][ch_idx],tx_arst_n_d[if_idx][ch_idx]} <= {tx_arst_n_d[if_idx][ch_idx],1'b1}; end end always_ff @(posedge rx_clk[if_idx][ch_idx] or posedge hssi_reset[if_idx][ch_idx]) begin if(hssi_reset[if_idx][ch_idx]) begin {rx_arst_n[if_idx][ch_idx],rx_arst_n_d[if_idx][ch_idx]} <= '0; end else begin {rx_arst_n[if_idx][ch_idx],rx_arst_n_d[if_idx][ch_idx]} <= {rx_arst_n_d[if_idx][ch_idx],1'b1}; end end // when tx are constant value, rx_value stays asserted // Bolt-up PRBS generator to TX side of PHY always_ff @(posedge tx_clk[if_idx] or negedge tx_arst_n[if_idx][ch_idx]) begin if(!tx_arst_n[if_idx][ch_idx]) begin hssi[if_idx].a2f_tx_parallel_data[(ch_idx*80)+79:(ch_idx*80)] <= '0; end else begin hssi[if_idx].a2f_tx_parallel_data[(ch_idx*80)+31:(ch_idx*80)] <= prbs_dout[if_idx][ch_idx];//{prbs_dout[if_idx][ch_idx][31:1], // prbs_dout[if_idx][ch_idx][0] ^ prbs_insert_error_hssi_e[if_idx][ch_idx]}; hssi[if_idx].a2f_tx_parallel_data[(ch_idx*80)+36] <= 1'b1; // tx_enh_data_valid hssi[if_idx].a2f_tx_parallel_data[(ch_idx*80)+79] <= 1'b1; // tx_fifo_wr_en end end // Bolt-up RX side of PHY to PRBS checker and drive serial loopback low for now always_ff @(posedge rx_clk[if_idx][ch_idx] or negedge rx_arst_n[if_idx][ch_idx]) begin if(!rx_arst_n[if_idx][ch_idx]) begin hssi[if_idx].a2f_rx_seriallpbken[ch_idx] <= '0; prbs_din[if_idx][ch_idx] <= '0; rx_data_valid[if_idx][ch_idx] <= '0; end else begin hssi[if_idx].a2f_rx_seriallpbken[ch_idx] <= rx_seriallpbken_hssi[if_idx][ch_idx]; prbs_din[if_idx][ch_idx] <= hssi[if_idx].f2a_rx_parallel_data[(ch_idx*80)+31:(ch_idx*80)]; rx_data_valid[if_idx][ch_idx] <= hssi[if_idx].f2a_rx_parallel_data[(ch_idx*80)+79]; end end assign prbs_pause_gen[if_idx][ch_idx] = prbs_pause_hssi_tx[if_idx][ch_idx]; assign prbs_pause_chk[if_idx][ch_idx] = prbs_pause_hssi_rx[if_idx][ch_idx] | !rx_data_valid[if_idx][ch_idx]; assign tx_count_reset_n[if_idx][ch_idx] = cr2ctr_tx_reset_n[if_idx][ch_idx] & tx_arst_n[if_idx][ch_idx]; assign rx_count_reset_n[if_idx][ch_idx] = cr2ctr_rx_reset_n[if_idx][ch_idx] & rx_arst_n[if_idx][ch_idx]; pattern_gen #( .MAX (32'hFFFF_FFFF), .prbs_initial_value (32'h5555_5555), .width (PRBS_DATA_WIDTH), .pattern ("prbs31") ) inst_pattern_gen ( .clk (tx_clk [if_idx]), .reset (~tx_arst_n [if_idx][ch_idx]), .data_out (prbs_dout [if_idx][ch_idx]), .enable (~prbs_pause_gen [if_idx][ch_idx]), .valid (prbs_gen_data_valid [if_idx][ch_idx]) ); pattern_ver_pipelined #( .MAX (32'hFFFF_FFFF), .prbs_initial_value (PRBS_INITIAL_VALUE), .width (PRBS_DATA_WIDTH), .pattern ("prbs31") ) inst_pattern_ver ( .clk (rx_clk [if_idx][ch_idx]), .reset (~rx_arst_n [if_idx][ch_idx]), .data_in (prbs_din [if_idx][ch_idx]), .data_locked (prbs_lock_hssi_rx [if_idx][ch_idx]), .error (prbs_error_flag [if_idx][ch_idx]), .enable (~prbs_pause_chk [if_idx][ch_idx]) ); // rx/tx counters always_ff @(posedge tx_clk[if_idx] or negedge tx_count_reset_n[if_idx][ch_idx]) begin if(!tx_count_reset_n[if_idx][ch_idx]) begin prbs_tx_count_hssi[if_idx][ch_idx] <= '0; end else if (!(prbs_pause_gen[if_idx][ch_idx])) begin prbs_tx_count_hssi[if_idx][ch_idx] <= prbs_tx_count_hssi[if_idx][ch_idx] + 1; end end always_ff @(posedge tx_clk[if_idx] or negedge tx_count_reset_n[if_idx][ch_idx]) begin if(!tx_count_reset_n[if_idx][ch_idx]) begin prbs_tx_err_count_hssi[if_idx][ch_idx] <= '0; end else if (prbs_insert_error_hssi_e[if_idx][ch_idx]) begin prbs_tx_err_count_hssi[if_idx][ch_idx] <= prbs_tx_err_count_hssi[if_idx][ch_idx] + 1; end end always_ff @(posedge rx_clk[if_idx][ch_idx] or negedge rx_count_reset_n[if_idx][ch_idx]) begin if(!rx_count_reset_n[if_idx][ch_idx]) begin prbs_rx_count_hssi[if_idx][ch_idx] <= '0; end else if (!(prbs_pause_chk[if_idx][ch_idx] | prbs_error_flag[if_idx][ch_idx])) begin prbs_rx_count_hssi[if_idx][ch_idx] <= prbs_rx_count_hssi[if_idx][ch_idx] + 1; end end always_ff @(posedge rx_clk[if_idx][ch_idx] or negedge rx_count_reset_n[if_idx][ch_idx]) begin if(!rx_count_reset_n[if_idx][ch_idx]) begin prbs_rx_err_count_hssi[if_idx][ch_idx] <= '0; end else if (prbs_error_flag[if_idx][ch_idx] & !prbs_pause_chk[if_idx][ch_idx]) begin prbs_rx_err_count_hssi[if_idx][ch_idx] <= prbs_rx_err_count_hssi[if_idx][ch_idx] + 1; end end avst_sync tx_count_bridge ( .in_clk(tx_clk[if_idx]), .in_reset(!tx_count_reset_n[if_idx][ch_idx]), .out_clk(clk), .out_reset(softReset), .in_ready(), .in_valid('1), .in_data(prbs_tx_count_hssi[if_idx][ch_idx]), .out_ready('1), .out_valid(prbs_tx_count_en[if_idx][ch_idx]), .out_data(prbs_tx_count_d[if_idx][ch_idx]) ); avst_sync tx_err_count_bridge ( .in_clk(tx_clk[if_idx]), .in_reset(!tx_count_reset_n[if_idx][ch_idx]), .out_clk(clk), .out_reset(softReset), .in_ready(), .in_valid('1), .in_data(prbs_tx_err_count_hssi[if_idx][ch_idx]), .out_ready('1), .out_valid(prbs_tx_err_count_en[if_idx][ch_idx]), .out_data(prbs_tx_err_count_d[if_idx][ch_idx]) ); avst_sync rx_count_bridge ( .in_clk(rx_clk[if_idx][ch_idx]), .in_reset(!rx_count_reset_n[if_idx][ch_idx]), .out_clk(clk), .out_reset(softReset), .in_ready(), .in_valid('1), .in_data(prbs_rx_count_hssi[if_idx][ch_idx]), .out_ready('1), .out_valid(prbs_rx_count_en[if_idx][ch_idx]), .out_data(prbs_rx_count_d[if_idx][ch_idx]) ); avst_sync rx_err_count_bridge ( .in_clk(rx_clk[if_idx][ch_idx]), .in_reset(!rx_count_reset_n[if_idx][ch_idx]), .out_clk(clk), .out_reset(softReset), .in_ready(), .in_valid('1), .in_data(prbs_rx_err_count_hssi[if_idx][ch_idx]), .out_ready('1), .out_valid(prbs_rx_err_count_en[if_idx][ch_idx]), .out_data(prbs_rx_err_count_d[if_idx][ch_idx]) ); always_ff @(posedge clk) begin if(softReset) begin prbs_tx_count[if_idx][ch_idx] <= '0; end else if (prbs_tx_count_en[if_idx][ch_idx]) begin prbs_tx_count[if_idx][ch_idx] <= prbs_tx_count_d[if_idx][ch_idx]; end end always_ff @(posedge clk) begin if(softReset) begin prbs_tx_err_count[if_idx][ch_idx] <= '0; end else if (prbs_tx_err_count_en[if_idx][ch_idx]) begin prbs_tx_err_count[if_idx][ch_idx] <= prbs_tx_err_count_d[if_idx][ch_idx]; end end always_ff @(posedge clk) begin if(softReset) begin prbs_rx_count[if_idx][ch_idx] <= '0; end else if (prbs_rx_count_en[if_idx][ch_idx]) begin prbs_rx_count[if_idx][ch_idx] <= prbs_rx_count_d[if_idx][ch_idx]; end end always_ff @(posedge clk) begin if(softReset) begin prbs_rx_err_count[if_idx][ch_idx] <= '0; end else if (prbs_rx_err_count_en[if_idx][ch_idx]) begin prbs_rx_err_count[if_idx][ch_idx] <= prbs_rx_err_count_d[if_idx][ch_idx]; end end end // block: HSSI_CH end // block: HSSI_IF endgenerate endmodule // prbs_top Re: Stratix 10 PAC HSSI example I'm not sure what is DCP 2.0.1, but the Pr Interface Id is 9346116d-a52d-5ca8-b06a-a9a389ef7c8d, which correspond to acceleration stack version 2.0.1 Stratix 10 PAC HSSI example I'm trying to understand how to use the hssi interface in stratix 10 PAC. I had some problem on rx_data_valid (PCS Direct on serial loopback) But unable to reproduce the issue, so i'm creating a new issue to ask how to use it properly. I tried modifying the hssi_prbs example code, to be more precise i'm trying to change the pattern_gen.v and pattern_ver_pipelined.v into just a simple counter. However, after changing both of them, the rx_ready is always fluctuating, and never stable at 0xff. So, i'm at loss on how to actually use this hssi interface. I tried looking into the transceiver user guide but still don't understand how to use it. Can someone please advise me how to use the interface correctly? here are the modifications to pattern_gen.v and pattern_ver_pipelined.v // pattern_gen.v `timescale 1ps/1ps module pattern_gen #( parameter MAX = 'hffff, //width parameter width = 16, //width parameter low_freq_len = 8, // (width/(low_freq_len*2)) must be a whole number parameter pattern = "prbs7", // prbs7, prbs9, prbs15, prbs23, prbs31 parameter prbs_initial_value = 97 ) ( input wire clk, input wire reset, input wire enable, output wire [width-1:0] data_out, output wire valid ); reg [width-1:0] counter; always @(posedge clk) begin if (reset) counter <= 'd0; else if (enable) counter <= (counter == MAX) ? counter : counter + 'd1; else counter <= counter; end assign valid = enable & ~(counter == MAX); assign data_out = valid ? counter : 'h0; endmodule // pattern_ver_pipelined.v `timescale 1ps/1ps module pattern_ver_pipelined #( parameter MAX = 'hffff, //width parameter width = 16, // width parameter pattern = "prbs7", // prbs7, prbs9, prbs15, prbs23, prbs31 parameter prbs_initial_value = 97 ) ( input clk, input reset, input enable, input [width-1:0] data_in, output data_locked, output reg error ); reg [width-1:0] ref_value; always @(posedge clk) begin if (reset) ref_value <= 'd0; else if (enable) ref_value <= (ref_value == MAX) ? ref_value : ref_value + 'd1; else ref_value <= ref_value; end reg [width-1:0] err_count; always @(posedge clk) begin if (reset) err_count <= 'd0; else if (enable && (ref_value == data_in)) err_count <= err_count + 'd1; else err_count <= err_count; end always @(posedge clk) begin if (reset) error <= 'd0; else if (data_locked) error <= err_count > 'd0; else error <= error; end assign data_locked = ref_value == MAX; endmodule