AXI4 icon indicating copy to clipboard operation
AXI4 copied to clipboard

WaitForTransaction on AXIS Receiver returns after 1 delta - either add a warning or wait until an actual transaction occurs.

Open SkydiverTricky opened this issue 11 months ago • 7 comments

Currently, the AXIS Receiver waits for a single delta when the user calls WaitForTransaction(rx_transrec)

https://github.com/OSVVM/AXI4/blob/2233256b2b9d8816ccc67ae36e847de38f42c054/AxiStream/src/AxiStreamReceiver.vhd#L224

This returns after a single delta with no warnings etc that this is what is happening.

For me, it would make more sense if it returned after an AXI transaction has occured. Any reason you cannot simply do the following?

when WAIT_FOR_TRANSACTION =>
          
          wait until rising_edge(clk) and TValid = '1' and TReady = '1';
          wait for 0 ns;                -- possibly wait the extra delta to allow internal queues to get filled

My use case here: I am using an external Queue of data for checking because OSVVM does not currently support CheckAsync functionality. I was hoping I could simply wait until a transaction had occured in the AXIS interface to synchronise to the VC.

SkydiverTricky avatar Jan 15 '25 10:01 SkydiverTricky

The current purpose of WaitForTransaction is to wait until any queued transactions have completed.

I am missing something. If we created a WaitForTransaction that blocks until a transaction has completed, and then get the data and check it, why not just do a Get, GetBurst, Check, CheckBurst as they all block and return (or check) something.

JimLewis avatar Jan 15 '25 18:01 JimLewis

There is also a GotBurst to check and see if a burst is available, but does not block.

I will boost up CheckAsync on my list.

JimLewis avatar Jan 15 '25 18:01 JimLewis

Currently, I have a stim_proc that generates the source data and generates the expected data from that. Because I need a constant stream of source data, I cannot do a check after a send(), so I have a separate process setup that pulls data out of a ScoreBoard simply to then call a series of check on the receiver. CheckAsync would remove the need for this process. I was trying to use the WaitOnTransaction on the receiver to deduce when the CheckFifo in testbench had data, as I know by this point in time it should have expected data waiting. otherwise, I have to do the following:

checker_loop : while runTest loop

  while empty(CheckFifo) loop
    waitForClock(rx_transrec);
  end loop;

  while not empty(CheckFifo) loop
    check(rx_transrec, CheckFifo.pop() );
  end loop
end loop checker_loop;

I was hoping I could replace the above with

WaitOnTransaction(rx_transrec);

SkydiverTricky avatar Jan 15 '25 19:01 SkydiverTricky

You will find this pattern in my classes and presentations:

architecture Test of Tb is
  signal SB : OSVVM.scoreboardPkg_slv.ScoreboardIDType ; 
begin
  InitProc : process
  begin
    SB<= NewID("SB") ;  -- most simulators allow this as an initialization of SB, but technically I think VHDL says no.
    wait ; 
  end process InitProc ; 

  TxProc : process
    variable TxData : std_logic_vector(7 downto 0) ; 
    variable RV : RandomType  := InitSeed(RV'Path_Name) ; -- 2019
  begin
    wait for 0 ns ; -- allow SB to init
    loop 
      TxData := RandSlv(RV, 0 255) ; 
      Push(SB, TxData) ; 
      Send(TRec, TxData) ;
      exit when SomethingHappens ; 
    end loop ;
  end process TxProc ; 

  RxProc : process 
    variable RxData : std_logic_vector(7 downto 0) ; 
  begin
    wait for 0 ns ; -- allow SB to init
    loop 
      Get(RRec, RxData ) ;
      Check(SB, RxData ) ; 
      exit when SomethingHappens ; 
    end loop ;
  end process RxProc ; 

On the TX side, we always push data into the SB before sending. Hence, on the RX side, if we receive data, the value can be checked against what is in the SB - no need to check for IsEmpty (IsEmpty being the updated name for Empty - but Empty will keep working) on the SB.

Some care needs to be done coordinating the ending as RX may finish after TX (easy) or before TX (like in a UART when it center samples).

This also supports packetizing TX and RX operations with bursts and delays between bursts - or allows that to be handled internally to the VC with Delay Coverage (if the VC supports it).

This pattern will work with SendBurst/CheckBurst - provided we know the packet boundaries (for AxiStream this currently means using TLast). Then Data becomes an array of SLV sized to be the maximum size of a burst. There is a corresponding PushBurstVector (in osvvm_common library) to support this sort of operation. This is not necessarily any better or worse than doing it word by word.

JimLewis avatar Jan 16 '25 00:01 JimLewis

The issue I have with this pattern, is you're wasting all the checking capabilities and reporting already built into the VC, and in the case of the AXIS VC, thats a lot of checking you then have to re-create (tlast, tuser etc)

SkydiverTricky avatar Jan 16 '25 07:01 SkydiverTricky

There is no difference between a FIFO and a Scoreboard. If you are checking TDest, TID, and TUser, then there is that. TUser can be in the FIFO if it changes with every data word.

JimLewis avatar Jan 16 '25 22:01 JimLewis

I have thought about all data handling being done by the FIFO. That would allow Tx to push directly to the RRec.BurstFifo and then do a check operation against it. It could also potentially break some things depending on how bursts and single word transfers were built and mixed.

It would also mean someone would need to know that single word checks could be done via the FIFO interface - unless the single word checks were treated as one word bursts - which I suppose is possible.

JimLewis avatar Jan 16 '25 23:01 JimLewis