Tlm fifo as shifter register

Hi all,

I’m trying to use the tlm fifo shifter register to implement a delay (like a shifter register);
in my example I’d like to have a 10 clk tick delay. What I see is that the delay works only for first 10 clock ticks.
Have anybode also tried this way? I can’t find my issue :(
Here is my code



 traffic_passive_item trans_collected, trans_collected_delay;
  
  uvm_analysis_port #(traffic_passive_item)     analysis_loop_port;
  uvm_tlm_analysis_fifo #(traffic_passive_item) traffic_buffer_fifo;

  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase (phase);
	  
    trans_collected       = traffic_passive_item::type_id::create("trans_collected");
    trans_collected_delay = traffic_passive_item::type_id::create("trans_collected_delay");
    analysis_loop_port    = new("analysis_loop_port", this);
    traffic_buffer_fifo   = new ("traffic_buffer_fifo", this);

   endfunction: build_phase

   forever begin
	  fork  
            get_vif_signals();
	    buffer_data();
            send_data_to_mbox();
	  join_any 
    end
 task buffer_data();	  
      @(posedge vif.clk);
      if(vif.en_ck) begin
        if(vif.data_en) begin	          
          traffic_buffer_fifo.try_put(trans_collected);
	end                                     
      end
      else
	      wr_en_debug = 1'b0;
  endtask
   
  task send_data_to_mbox();
      @(posedge vif.clk);
      if (vif.reset_n == 1'b0) begin
        fifo_level       = 0;
      end
      else begin
        if(vif.en_ck) begin
          fifo_level      = traffic_buffer_fifo.used();  
	      if(fifo_level > 10) begin 
                trans_collected_delay = new();   
	        traffic_buffer_fifo.try_get(trans_collected_delay);
      	        analysis_loop_port.write(trans_collected_delay);
          end  
        end    
      end  
  endtask

  task get_vif_signals();	  	          
      @(posedge vif.clk);
	 data_dut_out_1          = vif.data_1; 
         data_dut_out_2          = vif.data_2; 
	  
	 trans_collected         = new();
         trans_collected.data_1  = vif.data_1;
         trans_collected.data_2  = vif.data_2; 	  
  endtask

thanks to all


In reply to alexkidd84:

Unfortunately I do not really understand why you need 10 clock cycles delay. Transactions are intended for use in transaction-level-modelling. On the transaction level you do not think in terms of clock cycles There is only the order of transactions important. When you need a transaction for further processing you can perform a get on a tlm_fifo and you’ll get it when there is one.

In reply to alexkidd84:

It would really help to explain what your code does after 10 clock cycles since we cannot run it ourselves.

I think this code is a lot more complicated than it needs to be. First, I would have used a simple queue instead of a tlm_fifo.

Next, the way you have structured your fork/join_any(which should be a simple fork/join) creates a few race conditions. There is a race between the traffic_buffer_fifo.try_put and traffic_buffer_fifo.try_get, and there is a race between the
trans_collected = new();
and
traffic_buffer_fifo.try_put(trans_collected);
I would not do the
fork[/fork] at all, or you need to add non-blocking assignments to remove the races.

Also, there is never a need to construct trans_collected_delay; you do both a create() and a new() unnecessarily.

Finally, you have
if (reset_n==0) fifo_level = 0;
which is unnecessary as well.

In reply to dave_59:

thanks dave, i refactored and rearranged my code and now it works.