Jump to content
Sign in to follow this  
wilsony

reuse driver on various interfaces, diff by data width only

Recommended Posts

I would like to reuse my driver code for, say 2, different interfaces that differ in data width only. Anyone can recommend the best way to architect it?

I see solution using parameterized interface and sequence_item. However, parameterized classes seem to have more restrictions(on assignment, casting, etc) that negates the benefit of this reusable driver. My first question is:

1) For those who had experience with parameterized classes, would you still recommend building this reusable driver this way?

Let's assuming this is the way to go. My second question is:

2) I assume there has to be 2 parameterized interface in this env. How does the driver select which interface to drive? (let me show some ugly code here to illustrate my confusion):

class driver extend uvm_driver #(base_item);

virtual interface IF_64_WIDTH vif64;

virtual interface IF_128_WIDTH vif128;

int width=64;

...

if (width==64) begin

vif64.data <= base_item.data; // for example purpose, ignore potential casting needed for base_item

end else if (width==128) begin

vif128.data <= base_item.data;

end

Thanks!

Share this post


Link to post
Share on other sites

Don't use parameterized width: you won't be able to write generic code for the width-independent code without having to constantly pass parameters through. Not only does it complicates the code, this will slow down your compilation.

Much easier to use a MAX_WIDTH macro that the user can redefine at compile-time and let Verilog do its automatic truncation/extension.

Share this post


Link to post
Share on other sites

Thanks for the pointer, Janick!

However, my 2 interfaces (width=64, and width=128) are both used in the same simulation. As a result, MAX_WIDTH macro is not going to work in this case, right? Seems like I'm back to using parameterized interface. Or there's another solution?

Thanks!

Share this post


Link to post
Share on other sites

It is going to work just fine. Both instances will be 128 bits, but the upper half of the one connected to the 64-bit version will go nowhere and be silently truncated and/or filled with 0's.

It may be a good idea to have a configuration variable that specifies the number of bits actually used so you can detect lost bits.

Share this post


Link to post
Share on other sites

Using a parametrized driver simplifies the design, bring up and debug of the driver and the sequences.

The downside is that sequences have to pass the parameter(s) along and will be less easily reusable. This becomes a problem when the sequence library gets big and there's many parameters.

Commercial VIPs use non parametrized classes. It's probably a good reason to use them...or maybe not.

Share this post


Link to post
Share on other sites

I agree with Janick. I *hate* dragging parameters all over the place.

Here's a recipe for a driver task with a configurable width. For this driver, it must drive 16 bits of data over what could be a 1, 2, or 4-bit interface. The interface itself is the maximum 4 bits, but only the least significant bits are attached to DUTs that are skinnier. If this darn site supported code formatting, you'd be able to read it.

task driver(int width);

chan_cred_item_c item;

bit buffer[];

int idx = 0;

bit [3:0] tmp;

forever begin

seq_item_port.get_next_item(item);

item.pack(buffer);

idx = 0;

repeat(16/width) begin

@(iface.drv_cb);

tmp = 0;

repeat(width) begin

tmp = tmp<<1;

tmp[0] = buffer[idx];

idx++;

end

iface.drv_cb.data <= tmp;

end

@(iface.drv_cb);

iface.drv_cb.data <= 0;

seq_item_port.item_done();

end

endtask : driver

Share this post


Link to post
Share on other sites

I agree the concept of parameterized driver(or class) facilitates cleaner code. However, currently the extra baggage (e.g "constantly pass parameter through") negates that benefit. Wish there is a way to enhance in the future.

Janick, Thanks for the pointers on driver. I agree that's the best approach we can have for now.

I do have a follow on concern, regarding the sequence_item that I had put aside so far in the discussion:

3) Do we do the same as declaring the data width in sequence_item.data as MAX_WIDTH, and randomize/capture portion of it? or there's a better approach when it comes to sequence_item?

- sequence_item usage has a bigger impact than interface. Many instances of sequence_item are maintained throughout simulation. e.g. a MAX_WIDTH=240 interface seems to post heavy penalty on a smaller interface with data_width=16. Should that be a concern?

Share this post


Link to post
Share on other sites

Using abstract classes instead of virtual interfaces decouples the interface parameters from the class parameters. There have been a number of DVCon papers on this topic. Here is a link to the latest. Other techniques will be presented at this years DVCon. 1P.8 Deploying Parameterized Interface with UVM

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×