wilsony Posted January 30, 2013 Report Share Posted January 30, 2013 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! Quote Link to comment Share on other sites More sharing options...
janick Posted January 30, 2013 Report Share Posted January 30, 2013 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. Quote Link to comment Share on other sites More sharing options...
wilsony Posted January 30, 2013 Author Report Share Posted January 30, 2013 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! Quote Link to comment Share on other sites More sharing options...
janick Posted January 30, 2013 Report Share Posted January 30, 2013 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. Quote Link to comment Share on other sites More sharing options...
uvmcraft Posted January 30, 2013 Report Share Posted January 30, 2013 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. Quote Link to comment Share on other sites More sharing options...
bhunter1972 Posted January 30, 2013 Report Share Posted January 30, 2013 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 Quote Link to comment Share on other sites More sharing options...
wilsony Posted January 30, 2013 Author Report Share Posted January 30, 2013 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? Quote Link to comment Share on other sites More sharing options...
dave_59 Posted January 30, 2013 Report Share Posted January 30, 2013 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 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.