Driver body mechanism

Hi, Can somebody please explain in the main task how the driver is driving signal? (working of main task)
Why there are multiple @(posedge vif.clk) written in the code?

class driver;

//used to count the number of transactions
int no_transactions;

//creating virtual interface handle
virtual intf vif;

//creating mailbox handle
mailbox gen2driv;

//constructor
function new(virtual intf vif,mailbox gen2driv);
//getting the interface
this.vif = vif;
//getting the mailbox handles from environment
this.gen2driv = gen2driv;
endfunction

//Reset task, Reset the Interface signals to default/initial values
task reset;
wait(vif.reset);
$display(“[ DRIVER ] ----- Reset Started -----”);
vif.a <= 0;
vif.b <= 0;
vif.valid <= 0;
wait(!vif.reset);
$display(“[ DRIVER ] ----- Reset Ended -----”);
endtask

//drivers the transaction items to interface signals
task main;
forever begin
transaction trans;
gen2driv.get(trans);
@(posedge vif.clk);
vif.valid <= 1;
vif.a <= trans.a;
vif.b <= trans.b;
@(posedge vif.clk);
vif.valid <= 0;
trans.c = vif.c;
@(posedge vif.clk);
trans.display(“[ Driver ]”);
no_transactions++;
end
endtask

endclass

In reply to mr.kry:

Hi,

to update data on different clock edge.


task main;

//Continue in loop
forever begin
//Instance of transection
transaction trans;

//Getting transection
gen2driv.get(trans);

//Driving data on first rising clock edge  
@(posedge vif.clk);
vif.valid <= 1;
vif.a <= trans.a;
vif.b <= trans.b;

//Driving and sampling data on second rising clock edge 
@(posedge vif.clk);
//Driving
vif.valid <= 0;
//Sampling 
trans.c = vif.c; 

//Driving data on third rising clock edge 
@(posedge vif.clk);
trans.display("[ Driver ]");

//incrementing trans counter
no_transactions++;

end
endtask

Regards,
Harsh

In reply to mr.kry:

@(posedge vif.clk) - waits for posedge of clk which is inside the interface.

 
 task main;
    forever begin
      transaction trans;
      gen2driv.get(trans);
      @(posedge vif.clk);// waits for posedge of clk 
      vif.valid <= 1;// now at posedge of clk driving valid,a,b to interface
      vif.a     <= trans.a;
      vif.b     <= trans.b;
      @(posedge vif.clk);// waiting for next posedge of clk
      vif.valid <= 0;// and driving valid  to 0 on interface
      trans.c   = vif.c;// sampling the value of c from interface
      @(posedge vif.clk);// then again waiting for next posedge of clk 
      trans.display("[ Driver ]");// and calling the display method
      no_transactions++;
    end
  endtask

But if you have included a clocking block inside the interface (clocking blocks are used to avoid race between DUT & TB) its not recommended to access raw clk from the interface directly instead you have to use clocking block.


interface intf(clk);

logic valid,a,b,c;
...
clocking cb(@posedge clk);//clocking block
output a,b,valid;
input c;
endclocking

...
endinterface

// now in driver to wait for posedge of clk we have to use clocking block as shown below
 task main;
    forever begin
      transaction trans;
      gen2driv.get(trans);
      @(vif.cb);// waits for posedge of clk 
      vif.cb.valid <= 1;// now at posedge of clk driving valid,a,b on to interface
      vif.cb.a     <= trans.a;
      vif.cb.b     <= trans.b;
      @(vif.cb);// waiting for next posedge of clk
      vif.cb.valid <= 0;// and driving valid on interface
      trans.c   = vif.cb.c;// sampling c from innterface
      @(vif.cb);// then again waiting for next posedge of clk 
      trans.display("[ Driver ]");// and calling the display method
      no_transactions++;
    end
  endtask


Thank you shanthi for the response
one more doubt is that why we are taking valid bit differently in different clock pulse,when valid is 0 why we are not driving input signal a &b, and which posedge of clk will run first among the three?

In reply to mr.kry:

Thank you shanthi for the response
one more doubt is that why we are taking valid bit differently in different clock pulse,when valid is 0 why we are not driving input signal a &b, and which posedge of clk will run first among the three?

The logic to Drive the data on to interface depends on the DUT protocol, so for driving logic refer to the DUT protocol that you are verifying.

And secondly, as the driving logic is enclosed within begin end block the code executes sequentially.

In reply to shanthi:

thank you shanthi