Verification of ASYNCHRONOUS FIFO

Hi guys,

I’m trying to verify ASYNCHRONOUS-FIFO,
I have listed couple of cases below,

Following are done using UVM Methodology based Verification environment

  1. Only read
  2. Only write
  3. Read and write simultaneously
  4. write full
  5. read empty
  6. full and empty are mutually exclusive
  7. simultaneously write_full and read_empty are active ( When read-side-clk is deactivated and other side it is writing)
  8. check reset behavior
  9. check reset to read/write wake up

I’m considering 2 agents (one for write side and another for read side), can any one let me know their view when and how i can make a decision to used multiple agents/Virtual sequence(er), in this case is it right ??

for case 1 and 2 how can i use virtual sequence ?? ( eg. for third case i use fork-join)
How do i divide its verification phases ?? (not uvm/systemverilog phases literally)

In addition, Structural check is done using Assertions !!

I have several reactions to your ideas.

  1. On number of agents:> I’m considering 2 agents (one for write side and another for read side), can any one let me know their view when and how i can make a decision to used multiple agents/Virtual sequence(er), in this case is it right ??
    I think that one agent is better because it is easier to maintain the actual count of the flags for full and empty flags. From my Real Chip Design and Verification book, below is a quick review of those flags, and how they are typically handled:
    “Since full and empty flags are generated by pointers, where at least one of the pointers must be synchronized into a second clock domain, clock-cycle accurate assertion and de-assertion of full and empty flags is not completely possible. One FIFO design technique is to insure that a full or empty flag is asserted exactly when full or empty conditions occur, but de-asserting the flags might come a few clock cycles late. This is sometimes referred to as pessimistic full and empty flags.
    A pessimistic full flag is a full signal that is asserted immediately when a FIFO becomes full, but is de-asserted late (i.e., it is not de-asserted until a few read-clock cycles later). Because the write pointer does not have to be synchronized before testing for a full condition, the full flag will be asserted immediately when the FIFO goes full. The FIFO might not actually be completely full because the read pointer might have incremented (i.e., extracted data already), but the new read pointer value might not have been synchronized into the write clock domain. Using the block diagram shown in Figure 3.5.5, the READ pointer synchronized into the WRITE clock domain is always two WRITE clocks behind the actual READ pointer value, so the full flag might be asserted for two extra write clocks. This typically is not a problem since the full flag is simply holding off transmission of more data from the data sending source for two extra write clock cycles”.

  1. On your suggested scenarios, they look OK, but are you really using constrained-random tests or directed tests? Maybe constrained-random tests with various weighted constraints would be better.
  2. On verification, I would put that effort into the interface with SVA. I would copy from the class into the interface the values of those pointers for calculating the full/empty flags. See my White paper: “Using SVA for scoreboarding and TB designs”
    http://SystemVerilog.us/papers/sva4scoreboarding.pdf
    and a related issue at the Verification Academy the following paper
    “Assertions Instead of FSMs/logic for Scoreboarding and Verification”
    available in the verification-horizons October-2013-volume-9-issue-3
    http://verificationacademy.com/verification-horizons/october-2013-volume-9-issue-3
    and “SVA in a UVM Class-based Environment”
    https://verificationacademy.com/verification-horizons/february-2013-volume-9-issue-1/SVA-in-a-UVM-Class-based-Environment

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us


In reply to ben@SystemVerilog.us:

Hi Ben,

Apologize for re-opening this thread after 2 years. I’m just now becoming active on forums.

In my view, 2-agents would be a better choice(Please correct, if not)

  • Independent WRITE and READ agents sequences of which can be coordinated in the virtual sequence.

  • Monitors of both the agents shall feed the Scoreboard.

  • Scoreboard will have a FIFO which itself is the high level model of the DUT.

  • Scoreboard (being an uvm_component) in addition to data integrity check shall also generate FULL and EMPTY events using the FIFO size. These events (on SV interface) in turn shall be used to implement SVA.

Please help me understand if we miss anything BIG with such architecture.

Thanks,
Prem

In reply to PREMKUMAR DHANABALAN:
Your suggestions are very good, and on second thoughts, I agree with you. One advantage is that the driver agents can be identical, but with different arguments in terms of clock rate and randomness for the read/write events.
Hey, unlike some well known US politician, when I am wrong I don’t double-down on my initial statement just to make myself right :)
Use SVA where applicable.
Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr


  1. VF Horizons:PAPER: SVA Alternative for Complex Assertions | Verification Academy
  2. http://systemverilog.us/vf/SolvingComplexUsersAssertions.pdf
  3. “Using SVA for scoreboarding and TB designs”
    http://systemverilog.us/papers/sva4scoreboarding.pdf
  4. “Assertions Instead of FSMs/logic for Scoreboarding and Verification”
    October 2013 | Volume 9, Issue 3 | Verification Academy
  5. SVA in a UVM Class-based Environment
    SVA in a UVM Class-based Environment | Verification Horizons | Verification Academy

In reply to ben@SystemVerilog.us:

Thanks, Ben!

Regards,
Prem

In reply to ben@SystemVerilog.us:

Hi Ben,
I have a doubt . If you use only one agent , one driver , one sequencer then how will you drive read and write operations simultaneously ?

In reply to Maitri@07:

If you have only one agent, one driver, one sequencer, then you must start the sequences (2 sequences for RD and WR) with the same sequencer simultaneously (using fork/join_none). In your driver, you get the generated transactions which can be identified as RD or WR, and depending on type of transaction, you driver the virtual interface respectively. To drive RD and WR simultaneously, you must use fork/join_none in driver.

But from my perspective, I prefer 2 agents.

In reply to Maitri@07:

In reply to ben@SystemVerilog.us:
Hi Ben,
I have a doubt . If you use only one agent , one driver , one sequencer then how will you drive read and write operations simultaneously ?

If you have 1 agent then you get interleaved seq_items, starting maybe with RD followed by WR. If you have a real dual port RAM which allows RD and WR at the same time, then you need 2 agents. But I’d not say a RD agent and a WR agent. I’d design only 1 agent but instantiate the same agent twice, each connected to the corresponding virtual interface.

In reply to chris_le:

Even though if I use fork/join_none in driver then also it will not be simultaneous operations. As at a time either RD/WR would be driven. Correct me if I am wrong.

1 Like

In reply to Maitri@07:

This is exactly what I was saying in my last contribution. It generates interleaved seq_items, either starting with RD or WR. But they are not generated at the same time. If you want to have this you need 2 instances of the agent. Each of them is connected to 1 of the ports of your dual port device.

BTW you do not need in your example and what chris is proposing the fork/join_none. fork/join work perfectly.

In reply to chr_sue:

But for my code I think instantiation of the same agen will not work as you already know that in my driver code only I generating wrclk , rdclk and rd/wr tasks . What I think that It would be more convenient to have 2 different agents with specific functionality. So respective agent’s driver will do only one task read or write.Please correct me if my understanding is wrong.

In reply to Maitri@07:

If you have a dedicated read and another write port then you can use the same agent, one configured for RD and the other one for WR. Think in terms of reusability. Your driver has in its run_phase a RD and a WR part.

In reply to chr_sue:

Agree with shr_sue, that’s the best solution for now.

In reply to Maitri@07:

In reply to chr_sue:
But for my code I think instantiation of the same agen will not work as you already know that in my driver code only I generating wrclk , rdclk and rd/wr tasks . What I think that It would be more convenient to have 2 different agents with specific functionality. So respective agent’s driver will do only one task read or write.Please correct me if my understanding is wrong.

If you are interested I can provide you an UVM example testbench for a dual port RAM.

In reply to ben@SystemVerilog.us:
Thanks a lot, learn much.

In reply to chr_sue:

I really appreciate this. I want to do it by myself first . If I get stuck I will surely ask. Thank you so much once again.

In reply to chr_sue:

In reply to Maitri@07:
If you are interested I can provide you an UVM example testbench for a dual port RAM.

Hi chr_sue, I am trying to solve a similar problem too. I like the idea of same agent instantiated twice. Would you be able to show me an example UVM TB for a dual port RAM please? Thanks.

In reply to Maitri@07:

In reply to chr_sue:
…my driver code only I generating wrclk , rdclk and rd/wr tasks …

It is usually not recommended to generate clocks from a ‘class’ to feed an RTL/DUT. It will be good if you move you clock generation to your interface. You shall have some good methods/APIs (say set_period, start, stop) in the interface to control the clocks.

You shall control the clock through these APIs from the desired UVM phase in the env by dot traversing the virtual interface handle.

Hi ALL,
I am just starting to implement this of my own and in a very initial stage of testbench development.

i have few questions regarding the thread discussion, appreciate if someone can help me understand the pros/cons of each method of implementation.
for synchronous FIFO:
my FIFO ports are :
input clk, reset, rd, wr, data_in
output data_out, empty, full
here in this case i can drive rd and wr simultaneously as i am reading out on data_out and writing on data_in.

what would be the ideal case of implementation.
i feel having one agent with different sequences for different use cases should work just fine and doesnt need multiple agents.
i can use fork join in order to force both the operation at one time.
Does that makes sense ?

also are there any different methods of implementation that i can try?
Appreciate your help and guidance here.
Thanks

In reply to Blitzz0418:
This is an opinion: Use whatever works for you. The difference I see between the two solutions is how the test environment emulates the real world.
**TWO AGENTS:**These agents are independent from each other and emulate the real world where one device pumps or produces data at its own rate and will, and the other consumes data on an as-needed basis. If the production is faster than the consumption, the producer must stop when a limit is reached. Conversely, if the consumer absorbs more data than produced, it must wait till there is something to consume.
With two agents, the model can be based on independent constraints for the rates of production and consumption. This can answer questions like:

  • What if the rate of production is changed x and the rate of consumption is y?
    How does this affect the latencies and performance of the system?
  • What if I go 2 * x?

Changes to respond to these questions become trivial because of the independent models of the agents.
ONE AGENT: One agent can be used to emulate the consumer and producer, but changing the statistics becomes more complicated and may be harder to support.

Bottom line, I prefer the two-agent method because it emulates the real world, and tuning the rates and statistics can provide system performance information; it can even answer the question: How deep should this FIFO be?

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats | Verification Academy
  2. Free books: Component Design by Example FREE BOOK: Component Design by Example … A Step-by-Step Process Using VHDL with UART as Vehicle | Verification Academy
    Real Chip Design and Verification Using Verilog and VHDL($3) Amazon.com
  3. Papers: