I want to try to impliment the retry buffer design in system verilog

In this i want to impliment timeout and retry the txn wrt to ack_nack sigal but in this counter and retry_failed is not happening proprly.can anyone help on this issue.

module retry_buf_d (
   //global signals
   input   clk,
   input   reset,
   input   [2:0]  retry_num,
   input   [9:0]  timeout_val,

   output reg time_out_occured,
   output reg retry_failed,
   output reg [3:0] error_seq_num,

   //Tx related signals
   input       tx_valid,
   output reg  tx_ready,
   input       [31:0] tx_data_in,
   input       [3:0] tx_seq_num,

   //RX related signals
   output reg   rx_valid,
   input        rx_ready,
   output reg   [31:0] rx_data_out,
   output reg   [3:0] rx_seq_num,
   input        ack_nack );

   reg [31:0] data [16];
   typedef enum {IDLE,VALID,COUNTER,DATA,TIME_OUT_ERR,NACK_ERR} STATE;
   STATE  CS_ITER[16] , NS_ITER[16];

   logic [31:0] data_arry [16];
   logic [31:0] data_in_array [16];
   logic [3:0]  tx_seq_num_arry [16];
   logic [3:0]  tx_seq_num_two [16];
   logic [15:0] active_req;    //
   logic [15:0] active_timeout_transmit; //
   logic [15:0] tx_ready_array_r;
   logic [15:0] rx_valid_array_r;
   logic [15:0] timeout_err_arry_r;
   logic [3:0]  error_seq_arry_r[16]; //
   logic [3:0]  rx_seq_num_arry_r[16];
   logic [3:0]  rx_seq_num_arry_two[16];
   logic [15:0] retry_failed_array_r;
   logic [31:0] cntr[16] , retry_counter[16];

   logic [3:0]  retry_failed_seq_num[16];
   logic [31:0] data_out_r[16];//
   logic [31:0] reg_data[16];//
   logic [31:0] data_out[16];//
   logic ack_nack_r[16];

   logic [9:0] max_cntr_val;
   logic [2:0] max_retry_num;
   assign max_cntr_val  = 'ha;
   //assign max_cntr_val  = timeout_val;
   assign max_retry_num = retry_num;

   generate   begin : gen_block
      for(genvar i=0; i< 16; i=i+1) begin
         always @(posedge clk or posedge reset) begin
            if (reset) begin
               CS_ITER[i] <= IDLE;
            end   else begin
               CS_ITER[i] <= NS_ITER[i];

               case (CS_ITER[i])
                  IDLE  :  begin
                     if(tx_valid ) begin
                        NS_ITER[i] <= VALID;
                     end else begin
                        NS_ITER[i] <= IDLE;
                     end
                     cntr[i] <= 32'b0;
                     retry_counter[i] <= max_retry_num ;
                  end
                  VALID :  begin
                     NS_ITER[i] <= COUNTER;
                  end
                  COUNTER :  begin
                     NS_ITER[i] <= DATA;
                  end
                  DATA: begin
                     if (ack_nack == 1) begin
                        NS_ITER[i] <= NACK_ERR;
                     end
                     if(cntr[i] == max_cntr_val) begin
                        $display("time_out_error[%0d]=%0d  ",i,timeout_err_arry_r[i]);
                        NS_ITER[i] <= TIME_OUT_ERR;
                     end else begin
                        cntr[i] <= ((cntr[i])+ 1);
                        $display("counter value[%0d]=%0d  ",i,cntr[i]);
                        NS_ITER [i] <= DATA;
                     end
                  end
                 TIME_OUT_ERR : begin
                     if(retry_counter[i] == 32'b0) begin
                        retry_failed_seq_num[i] <= i;
                        NS_ITER[i] <= IDLE;
                     end
                     else begin
                        retry_counter[i] <= retry_counter[i] - 32'b1;
                        $display("retry counter value[%0d]=%0d  ",i,retry_counter[i]);
                        NS_ITER[i] <= DATA;
                     end
                  end
                  NACK_ERR : begin
                     if(retry_counter[i] != 32'b0 ) begin
                        NS_ITER[i] <= DATA;
                     end
                     else begin
                        NS_ITER [i] <= COUNTER;
                     end
                  end
                  default :  CS_ITER[i] <= IDLE;
               endcase
              end
         end  //aways_b
         //end // ini_always

      assign tx_ready_array_r[i]     = (!reset && CS_ITER[i] <= VALID) ? (NS_ITER[i] <= COUNTER ? 1 : 0) : 0;
      //assign data_arry[i]            = tx_valid ? ((tx_ready_array_r[i] && (CS_ITER[i] <= COUNTER)) ? tx_data_in : 0 ) : 0;
      assign data_arry[i]            =  (CS_ITER[i] <= COUNTER) ?  (tx_valid ? tx_data_in : 0 ) : 32'hxx;
      assign data_in_array[i]            =  (CS_ITER[i] <= COUNTER) ?  (tx_valid ? tx_data_in : 0 ) : 32'hxx;
      //assign tx_seq_num_arry[i]     = (!reset && (CS_ITER[i] <= COUNTER)) ? ((tx_ready_array_r[i] && tx_valid)  ? tx_seq_num  : 0) : 0;
      assign tx_seq_num_arry[i]     = (!reset && (CS_ITER[i] <= COUNTER)) ? ( tx_valid  ? tx_seq_num  : 0) : 0;
      assign tx_seq_num_two[i]     = (!reset && (CS_ITER[i] <= COUNTER)) ? ( tx_valid  ? tx_seq_num  : 0) : 0;

      assign rx_valid_array_r[i]     = (!reset && CS_ITER[i] <= DATA)  ? (NS_ITER[i]  <= DATA ?  1 : 0 ) : 0; //  : 0;
      //assign rx_seq_num_arry_r[i]    = (!reset && CS_ITER[i] <= DATA ) ? (NS_ITER[i] <= DATA ? tx_seq_num : 0 ) : 0 ;
      assign rx_seq_num_arry_r[i]    = (!reset && CS_ITER[i] <= DATA ) ? (rx_ready ? tx_seq_num_arry[i]   : 0 ) : 0 ;
      assign rx_seq_num_arry_two[i]    = (!reset && CS_ITER[i] <= DATA ) ? (rx_ready ? tx_seq_num_two[i]   : 0 ) : 0 ;
      assign data_out_r[i]           = (!reset && CS_ITER[i] <= DATA ) ? (rx_ready ? data_arry[i] : 32'hxxxx) : 0 ;
      assign reg_data [i]           = (!reset && CS_ITER[i] <= DATA ) ? (rx_ready ? data_in_array[i] : 32'hzzzz) : 0 ;
     // assign data_out_r[i]           = (!reset && CS_ITER[i] <= DATA ) ? ((rx_valid_array_r[i] && rx_ready && !ack_nack) ? data_arry[i] : 32'hxxxx) : 0 ;

     // assign timeout_err_arry_r[i]   = (CS_ITER[i] <= DATA) ? (NS_ITER [i] <=TIME_OUT_ERR && cntr[i]== max_cntr_val  ? 1 : 0) : 0 ;
      assign timeout_err_arry_r[i]   = (CS_ITER[i] <= DATA) ? (cntr[i]== max_cntr_val  ? 1 : 0) : 0 ;
      assign retry_failed_array_r[i] = (CS_ITER[i] <= TIME_OUT_ERR) ? (retry_counter[i]== 32'b0  ? 1 : 0 ) : 0;
     // assign data_out[i]                = data_out_r[i];
         always @(posedge clk) begin
             if(rx_valid_array_r[i] || rx_ready)begin
               rx_valid <= |rx_valid_array_r[i];
            end else if(rx_ready == 0) begin
               rx_valid <= 'b0;
            end else begin
               rx_valid <= 'b0;
            end
            if(tx_valid ==1) begin
               tx_ready <= |tx_ready_array_r[i];
            end else begin
               tx_ready <= 'b0;
            end

         end
         always @* begin
            if(rx_ready && rx_valid_array_r[i]) begin
               if(!ack_nack && timeout_err_arry_r[i]==0) begin
                  //rx_seq_num <= rx_seq_num_arry_r[i];
                  rx_seq_num <= rx_seq_num_arry_r[i];
                  rx_data_out <= data_out_r[rx_seq_num_arry_r[i]];
                  $display("rx_data_out ==%0d rx_data_array[%0d]=%0d  rx_seq_num==%0d ",rx_data_out,i,data_arry[i], rx_seq_num);
               end else if(timeout_err_arry_r[i] ==1 && !ack_nack ) begin //|| i== tx_seq_num_arry[i]) begin
                  rx_seq_num <= rx_seq_num_arry_two[i];
                  rx_data_out <=reg_data[rx_seq_num_arry_two[i]];
               end else if (retry_counter[i] != 32'b0 && !ack_nack ) begin // i== rx_seq_num_arry_two[i]) begin
                  rx_seq_num <= rx_seq_num_arry_two[i];
                  rx_data_out <=reg_data[rx_seq_num_arry_two[i]];
               end else begin
                  rx_seq_num <= 'hxz;
                  rx_data_out <= 'hxz;
               end
            end
            if(retry_failed_array_r[i]  ) begin
                error_seq_num <= rx_seq_num_arry_r[i];
                //error_seq_num <= retry_failed_seq_num[i];
             end else error_seq_num <= 'hx;

         end

      end //forloop
      end
   endgenerate

   //assign tx_ready = |(tx_ready_array_r);
   //assign rx_valid = |(rx_valid_array_r);
   assign retry_failed = |(retry_failed_array_r);
   assign time_out_occured = |(timeout_err_arry_r);


endmodule

In reply to ramesh_varma:

You haven’t explained what “properly” is supposed to mean. And that’s a lot of code without a testbench to look through.

In reply to dave_59:

In this design tx_data input to dut and tx_ready tx_valid happens fine. But rx_valid &rx_ready handshake is not happening properly w.r.t to TB code.In RX side time_out is happening for every sequence num and retry is failed for every sequence num. In this both Tx and Rx are working at same instance.How I want to implement this design is
step1:tx_part

1)tx_data, tx_seq_number with tx_valid(tx_valid==1) send to retry_buffer.
2)retry_buffer will send tx_ready(tx_ready==1) and comlete the handshake( like master and slave handshake).

step2: rx_part

  1. once the tx_data is entry to the buffer , rx_valid (rx_valid==1 only when valid data is availabl in buffer) will become 1 and waiting for rx_ready .
  2. once the retry buffer recive the ready from the rx , rx handshake completed.

step3: timer part

  1. when rx_data is transfer from buffer to rx_side , then counter is started .
  2. user apply send the max_time_val ,
  3. if(counter == max_time_val)
    time_out;
    check the retry number (if retry_number !=0) and retry the data with new transaction;
    if(counter < max_time_val)
    {
    retry buffer is waiting ack from rx
    apply pos or neg ack
    if pos ack , data is transfered crt.
    if neg ack , data is wrg, check the retry number and retry the data with new transaction ( repeat step2 and 3);
    }

step4: retry_failed
1)if rx is send neg_ack , but retry number==0 then retry_buffer will send the retry_failed==1,
if(retry_number>0)
{
retry the data;
retry_number-1;
}
else
{
retry failed;
}