Verification Guild
A Community of Verification Professionals

 Create an AccountHome | Calendar | Downloads | FAQ | Links | Site Admin | Your Account  

Login
Nickname

Password

Security Code: Security Code
Type Security Code
BACKWARD

Don't have an account yet? You can create one. As a registered user you have some advantages like theme manager, comments configuration and post comments with your name.

Modules
· Home
· Downloads
· FAQ
· Feedback
· Recommend Us
· Web Links
· Your Account

Advertising

Who's Online
There are currently, 41 guest(s) and 1 member(s) that are online.

You are Anonymous user. You can register for free by clicking here

  
Verification Guild: Forums

 Forum FAQForum FAQ   SearchSearch   UsergroupsUsergroups   ProfileProfile  ProfileDigest    Log inLog in 

what is the best practice for modeling reset in BFM

 
Post new topic   Reply to topic    Verification Guild Forum Index -> Main
View previous topic :: View next topic  
Author Message
edalearner
Senior
Senior


Joined: Apr 02, 2007
Posts: 75
Location: Shanghai, China

PostPosted: Fri May 25, 2012 11:38 am    Post subject: what is the best practice for modeling reset in BFM Reply with quote

Hi folks,

I didn't have this issue until I run uvm w/ questa recently. The story is a simple one. I would like to model the reset functionality in my driver BFM. When reset signal asserts, all the internal storage is cleaned up and bus is driven to its idle or reset state immediately. So I declared the signal type in the interface as "logic" and modport contains async port list and sync clocking block.

The interface is defined as follows,
Code:

interface foobar( input clk );
    logic [31:0] sig_addr;
    logic [31:0] sig_data;
    logic valid;
    logic ack;
   
    clocking drv_cb @(posedge clk);
        output sig_addr;
        output sig_data;
        output valid;
        input ack;
    endclocking

   clocking resp_cb @(posedge clk);
        input sig_addr;
        input sig_data;
        input valid;
        output ack;
    endclocking

    modport TB_DRV ( output sig_addr, output sig_data, output valid, input ack,  clocking drv_cb );
    modport TB_RESP ( input sig_addr, input sig_data, input valid, output ack, clocking resp_cb );
    modport DUT_RESP ( input sig_addr, input sig_data, input valid, output ack );

endinterface: foobar


In driver code, modport TB_DRV is used. (And TB_RESP can be used by responder BFM.)

    when reset occurs or in uvm connect_phase phase, drive the signals asynchronously. drv_vif.sig_addr = '0;
    when real traffic occurs, drive the signals synchronously. drv_vif.drv_cb.sig_addr <= <val>;


In DUT connection side, I declared a dut wrapper module.
Code:

module dut_wrap ( foobar.DUT_RESP foobar_if );
     dut u_dut (
          .addr ( foobar_if.sig_addr ),
          .data ( foobar_if.sig_data ),
          .valid ( foobar_if.valid),
          .ack   ( foobar_if.ack ) );
endmodule


Until now we can find the issue that, in the interface instance the ack signal is multiply driven by continuous assignment and procedural assignment.


    the DUT ack output port drive the ack by port connection
    the resp_cb clocking block drive the ack procedurally


We can re-declare the signal type in interface to be "wire". This issue can be gone. Another issue comes that we can't do the async signal reset any longer. The following code hence doesn't compile.
Code:

    drv_vif.sig_addr = '0;


Any solution for this? and more generally, what is the best practice for modeling the reset functionality in a driver BFM.

Thanks in advance,
Robert
Back to top
View user's profile
dave_59
Senior
Senior


Joined: Jun 22, 2004
Posts: 974
Location: Fremont, CA

PostPosted: Fri May 25, 2012 5:38 pm    Post subject: Reply with quote

If you want to drive a signal both synchronously and asynchronously (which doesn't make much sense to me) then you need to put in the glue logic to resolve when the asynchronously drive is not active.

In your interface, add
Code:

wire  [31:0] sig_addr;
logic [31:0] sig_addr_reg;
assign  sig_addr = sig_addr_reg;

modport TB_DRV ( output sig_addr_reg, input sig_addr, output sig_data, output valid, input ack,  clocking drv_cb );



Then in your testbench code you use

Code:
drv_vif.sig_addr_reg = '0; // forcing asynchronous assignment
drv_vif.sig_addr_reg = 'z; // releasing asynchronous assignment
drv_vif.drv_cb.sig_addr <= '0; // for synchronous assignment

sig_addr_reg must be 'z to make a synchronous assignment and cb_drv.sig_addr must be 'z to make an asynchronous assignment, otherwise you will get 'x if there is a conflict.
Back to top
View user's profile Send e-mail Visit poster's website
edalearner
Senior
Senior


Joined: Apr 02, 2007
Posts: 75
Location: Shanghai, China

PostPosted: Fri May 25, 2012 7:52 pm    Post subject: Reply with quote

Hi Dave,

This solution is interesting. It does resolve the multiple drive issue. I code a piece of pseudo code as follows.

Code:

while ( 1 ) begin
    wait ( reset_n == 1'b0 );
    drv_vif.drv_cb.sig_addr <= 'z; // <=== see below
    drv_vif.sig_addr_reg = '0;
   
    wait ( reset_n == 1'b1 );
    drv_vif.sig_addr_reg = 'z;
end


However there is one question here. Since the requirement is that when reset asserts, the signals would be reset to IDLE state at once. That means,
Code:

    drv_vif.drv_cb.sig_addr <= 'z;

doesn't work here since it doesn't put the sig_addr driver in clocking block into high-z state at once. There will be a conflict until the next clock edge event occurs.

Thanks,
Robert
Back to top
View user's profile
dave_59
Senior
Senior


Joined: Jun 22, 2004
Posts: 974
Location: Fremont, CA

PostPosted: Sat May 26, 2012 1:14 am    Post subject: Reply with quote

You can change the clocking block output to procedurally drive the variable sig_addr_reg instead the resolved wire sig_addr.
Back to top
View user's profile Send e-mail Visit poster's website
Logger
Senior
Senior


Joined: Jun 15, 2004
Posts: 340
Location: MN

PostPosted: Sat May 26, 2012 12:15 pm    Post subject: Reply with quote

If the problem really is just the multiple driver restriction on a logic type signal, what about declaring the signals in the interface as reg, instead of logic or wire? You can no longer use a continuous assign, but you can "always" work around that.
Back to top
View user's profile
edalearner
Senior
Senior


Joined: Apr 02, 2007
Posts: 75
Location: Shanghai, China

PostPosted: Sat May 26, 2012 10:24 pm    Post subject: Reply with quote

Hi Logger,

The idea is great. So let me rewrite the dut wrap like this.
Code:

module dut_wrap ( foobar.DUT_RESP foobar_if );
     // signal decls
     wire ack;

     // DUT output connection
     always @(*) begin
           foobar_if.ack = ack;
     end

     dut u_dut
     (
        .sig_addr ( foobar_port.sig_addr ),
        .sig_data ( foobar_port.sig_data ),
        .valid      ( foobar_port.valid      ),
        .*   // for all DUT output
     );
endmodule


The workaround is working at the only cost of breaking the consistency of coding style. However, IMO this is acceptable if we make the root cause explicit in the document for the verification component. After all, we need to code the dut wrapper module only once in a project.

BTW, the 'logic' type in interface definition doesn't have to replaced to 'reg' type necessarily. The two are exactly the same in SV semantics.
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    Verification Guild Forum Index -> Main All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Verification Guild © 2006 Janick Bergeron
Web site engine's code is Copyright © 2003 by PHP-Nuke. All Rights Reserved. PHP-Nuke is Free Software released under the GNU/GPL license.
Page Generation: 0.195 Seconds