OSVVM 2020.08 New user experience

Why OSVVM™? Forums OSVVM OSVVM 2020.08 New user experience

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #1709
    Chengshan
    Member

    Hi I just created my very first OSVVM test bench based on the example.
    It was with release 2020.08.

    Here are my experience/questions, mostly about the newly released AXI4 models:

    1. Could the test bench be stopped gracefully by stopping all clocks?
    I don’t feel like the idea of using assertion or std.env.stop to end the simulation.
    Stopping the clock would let simulator see “no more events”.

    The AXI responder was not very friendly to a stopped clock. It’s calling procedure DoAxiReadyHandshake which will throw out a time out error. I had to comment out the time out part to make the SIM end gracefully.

    2. The AXI4 master procedure GetWriteBurstData() assumes byte-wise narrow burst.
    The example test bench broke as soon as I changed the data width and pushed data wider than 8-bits to WriteBurstFifo from the master process.
    The narrow burst was nice but I had to comment out to make it work with a wider data bus.

    3. Looks like the AXI responder is still AXI-Lite only as of r2020.08?
    Write burst is working but read burst is broke. It sent out the first read data then stopped there, waiting for a new address. It is assuming # of address must equal to # of data.
    Luckily the AXI memory is functional for read burst. I got around by not using the AXI responder model.

    4. Typo? AxRegion is 4 bits only per AXI4 standard. It was defined 8 bits in Axi4InterfacePkg.
    I had to change the width to make it compile.

    #1710
    Jim Lewis
    Member

    Hi Chengshan,
    First, thanks for the feedback.

    Are you using this with a particular design?

    You have four questions, so I will give 4 separate answers.

    Best Regards,
    Jim

    #1711
    Jim Lewis
    Member

    Hi Chengshan,

    4. Typo! You are correct, AxRegion should be 4 bits. I will fix that
    in the next release. Anything else like that is an issue?

    What do you mean you had to change the width to make it compile? Is this to
    connect it to your design? It compiles and runs fine with the OSVVM models
    which all use the same incorrectly sized AwRegion/ArRegion.

    In general, as an example of how to handle a situation like this, take a
    look at Axi4/testbench/TbAxi4.vhd. Any composite interface can be mapped
    element by element – provided all the elements are mapped and that once you
    start mapping an array element that you finish mapping all of it. In this
    case, that means that if you did not (or could not modify the other code)
    you could connect a 4 bit “dummy” signal to the unused bits of AwRegion/ArRegion.

    Based on the example from TbAxi4.vhd, if you run into a problem like this
    with other models (and you don’t have access to edit them), you can do the
    following:

      Axi4Minion_1 : Axi4Responder
      port map (
        -- Globals
        Clk         => Clk,
        nReset      => nReset,
    
        -- Testbench Transaction Interface
        TransRec    => AxiMinionTransRec,
    
        -- AXI Master Functional Interface
        AxiBus.WriteAddress.Addr       => AWAddr  ,
        AxiBus.WriteAddress.Prot       => AWProt  ,
        AxiBus.WriteAddress.Valid      => AWValid ,
        AxiBus.WriteAddress.Ready      => AWReady ,
        AxiBus.WriteAddress.ID         => AWID    ,
        AxiBus.WriteAddress.Len        => AWLen   ,
        AxiBus.WriteAddress.Size       => AWSize  ,
        AxiBus.WriteAddress.Burst      => AWBurst ,
        AxiBus.WriteAddress.Lock       => AWLock  ,
        AxiBus.WriteAddress.Cache      => AWCache ,
        AxiBus.WriteAddress.QOS        => AWQOS   ,
        AxiBus.WriteAddress.Region(7 downto 4)     => ErrorAwRegion(3 downto 0),  -- the erroneous piece
        AxiBus.WriteAddress.Region(3 downto 0)     => AWRegion,                   -- the correct piece
        AxiBus.WriteAddress.User       => AWUser  ,

    Thanks again for catching this. I have already edited my private
    dev branch. Will push it to the github dev branch as soon as I
    test it.

    #1712
    Jim Lewis
    Member

    Hi Chengshan,

    2. The test sequencer interface to AXI verification component burst FIFO is 8 bits. The AXI verification component assembling this into the size of the data bus. So you will always push bytes into the FIFO – even if you make the data bus bigger or smaller. It was tested with a 32 bit AXI data bus, however, it is intended to work with any legal AXI width data bus.

    It was not tested with a 64 bit interface. What width are you using?

    Can you send me a test case – my email address jim at synthworks.com.

    #1713
    Jim Lewis
    Member

    Hi Chengshan,

    3. Correct. The 2020.08 Axi4Responder_Transactor.vhd is intended to be a register access model and does not support bursting. As you noted, Axi4Memory.vhd, implements memory models and does support bursting. This is noted in the README.md at: https://github.com/osvvm/AXI4.

    Do you need a transactor that supports bursting? It is on my long term goals – but there are numerous things ahead of it.

    #1714
    Jim Lewis
    Member

    Hi Chengshan,

    >1. Could the test bench be stopped gracefully by stopping all clocks?
    Do you have a method to gracefully stop clocks? Everything I have seen
    has overhead incurred at least once per clock cycle (or some multiple of
    the clock cycle).

    OTOH, I really like std.env.stop. It only incurs overhead when
    it is actually stopping the testbench. Going further, it allows you to
    return a value to the calling script by doing:

    std.env.stop(GetAlertCount) ;

    The one you are looking at is there because, in general,
    verification models should not hang. Hence, wait statements
    must have provisions for time out clauses in them.

    OTOH, Axi Ready is a special case, often it does not need a
    timeout. This is certainly true in the responder for
    WriteAddress, WriteData, and ReadAddress, however, in the
    master/initiator WriteResponse and ReadData both require
    the timeout.

    Hence, for AXI the overhead on DoAxiReadyHandshake could be avoided
    by having two separate versions, however, I would need significant
    convincing that clock stopping would remain a viable methodology
    in large scale testbenches – consider that there can be a multitude
    of clocks to stop.

    #1715
    Chengshan
    Member

    Hi Jim,

    Thanks for the quick response.

    #2 – Some learning experience here.
    I started the journey by studying the example test bench TbAxi4_BasicBurst.
    The example went broken as soon as I changed AXI_DATA_WIDTH to a wider one in TbAxi4.
    Looking back, it was probably the test cases.
    But at that time I did not realized that the test was doing narrow burst.
    I attempted to fix the problem by WriteBurstFifo.Push() wider data in AxiSuperProc.
    That change immediately throw out some size mismatch error in procedure GetWriteBurstData().

    My use case did not really require narrow burst so I commented out the feature in the end:
    aWriteStrb := (others => ‘1’) ;
    aWriteData := WriteBurstFifo.Pop ; –Note data sized AXI_DATA_WIDTH was pushed
    in GetWriteBurstData().

    IMHO, address aligned, full-width burst might be more appropriate for a “Basic” burst example.
    The narrow burst can be in an “advanced” burst example.

    #1716
    Chengshan
    Member

    #1 – If stopping the simulation with assertion or std.env.stop, it was not a “real” stop.
    Hitting the “run all” button in the simulator would let the test bench continue to run endlessly.
    Personally I don’t feel like this behavior.

    Stopping the clock is the true end. When the simulator stops, there is nothing more to simulate.
    Hitting the “run all” button would not do anything.
    Modelsim simply stops.
    Aldec is even nicer by printing a message saying “no more events”.

    I have an enable signal for the clock process. The test process disable the clock in the end.
    The AXI responder was not friendly to this approach of stopping the simulation.

    #1717
    Jim Lewis
    Member

    #1 I use “run all” to run my tests. Std.env.stop will stop the test. However, stop works much like a breakpoint, so the simulation can be continued. I am ok with this.

    If you wanted to prohibit the testbench from running further after it stops, use std.env.finish instead. It also allows an integer parameter, so you can call it as:
    std.env.finish(GetAlertCount) ;

    #1718
    Jim Lewis
    Member

    #2 Did you run the testbench examples before modifying them? The test TbAxi4_MemoryBurst (which runs when you do build ../OsvvmLibraries/AXI4/Axi4/testbench) does bursts. The first burst in the test is 3 32 bit words – IE 12 bytes and the address is word aligned.

    What is 1 wider? Did you mean 64 bits? AXI data supports a power of 2 bytes in a transfer (ie: 1, 2, 4, 8, 16, …).
    I am not sure what you mean by narrow transfers. At the end of TbAxi4_MemoryBurst, oddly small bursts are being tested. This is not meant to demonstrate how to do bursts – instead it is intended to verify that the model supports small bursts – as it is required to do.

    #1736
    Richard Head
    Member

    If you wanted to prohibit the testbench from running further after it stops, use std.env.finish instead. It also allows an integer parameter, so you can call it as:
    std.env.finish(GetAlertCount) ;

    Given @Chengshan mentioned Aldec, I thought I would mention that ActiveHDL in batch mode doesnt currently return the value from finish() or stop() or assertion failures to the system, so you cannot use this to detect a test failure. Ive worked around it by having a process that sets a “tb_fail” signal to ‘1’ at the end of the test, and use the surrounding tcl to examine its value after the test finishes. This is then thrown from tcl as an error.

    My ticket says its targeted for ActiveHDL 11.2, but I raised it 18 months ago.

    #1740
    Jim Lewis
    Member

    Hi Richard,
    I have been thinking about package that would have some global signaling events – such as

    signal TestDone : integer_barrier;
    signal  ResetDone : integer_barrier;
    

    We could add something like:
    signal TestErrorCount : integer ;

    The idea is that if all tests had access to something like this, then it could be picked up automatically by the OSVVM scripts. I suspect that all simulators provide a mechanism to read signal values. It may also be nice to return the test name, although I suspect we already know it in the scripts. If you look at OSVVM scripts, this is something that could be added to the simulate procedure.

    I have been wondering how to get this information into a format for the CI tools.

    Best Regards,
    Jim

Viewing 12 posts - 1 through 12 (of 12 total)
  • You must be logged in to reply to this topic.