Jump to content

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!

Link to comment
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.

Link to comment
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!

Link to comment
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.

Link to comment
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.

Link to comment
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

Link to comment
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?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...