Verification of ASYNCHRONOUS FIFO

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.

1 Like

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.

1 Like

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.

1 Like

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:

In reply to MLearner:

There are more questions to answer. Considering your port list only 1 agent is needed. And I believe your FIFO is not able to do an read and a write at the same time. It has to happen exclusively.

In reply to chr_sue:

Hi chr_sue,

In case if the FIFO design supports simultaneous reads and writes. Does having one agent work? We can use fork join_non in the driver to drive rd pins and wr pins in i/f simultaneously but was wondering what is the best way to code an agent. I have two transaction items one for reads and one for writes but a single interface.

How do we implement the scoreboard. We have two txn types sen to SB via analysis port. then we maintain a local queue and do a comparison? I was trying to use the analysis FIFO as a structure to replicate the FIFO design on the tb side.

Thanks!