SystemVerilog note (3)

SystemVerilog TestBench Example - ADDER

Part 1 Transaction

  • Fields required to generate the stimulus are declared in the transaction class.
  • Transaction class can also be used as the placeholder for the activity monitored by the monitor on DUT signals.
    class transaction;        //declaring the transaction items
      rand bit [3:0] a;
      rand bit [3:0] b;
           bit [6:0] c;
      function void display(string name);
        $display("- %s ",name);
        $display("- a = %0d, b = %0d",a,b);
        $display("- c = %0d",c);
      endfunction
    endclass

    Part 2 Generator

  • Generating the stimulus by randomizing the transaction class
  • Sending the randomized class to driver
    class generator;
       
      rand transaction trans;   //declaring transaction class
       
      mailbox gen2driv;         //declaring mailbox
     
      event ended;             //event, to indicate the end of transaction generation
     
      //constructor
      function new(mailbox gen2driv);
        this.gen2driv = gen2driv;          //getting the mailbox handle from env
      endfunction
       
      //main task, generates(create and randomizes) the packets and puts into mailbox
      task main();
          trans = new();
          if( !trans.randomize() ) $fatal("Gen:: trans randomization failed");
          gen2driv.put(trans);     //put data into mailbox
          -> ended; //triggering indicatesthe end of generation
      endtask   
    endclass

    Part 3 Interface

  • The interface will group the signals
    interface myintf(input logic clk,reset);   
      //declaring the signals
      logic       valid;
      logic [3:0] a;
      logic [3:0] b;
      logic [6:0] c;   
    endinterface

    Part 4 Driver

  • receive the stimulus generated from generator and drive to DUT by assigning transaction class values to interface signals. 
    class driver;
      
      //used to count the number of transactions
      int no_transactions;
       
      //creating virtual interface handle  定义虚接口
      virtual myintf vif;
       
      //creating mailbox handle
      mailbox gen2driv;
       
      //constructor
      function new(virtual myintf 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

    Part 5 Environment

  • Environment is container class contains MailboxGenerator and Driver
    class environment;
       
      generator gen;       //generator and driver instance
      driver    driv;
       
      mailbox gen2driv;    //mailbox handle's
       
      virtual myintf vif;    //virtual interface
       
      //constructor
      function new(virtual myintf vif);
        this.vif = vif;     //get the interface from test    
        //creating the mailbox (Same handle will be shared across generator and driver)
        gen2driv = new();
        gen  = new(gen2driv);        //creating generator and driver
        driv = new(vif,gen2driv);
      endfunction
       
      //
      task pre_test();
        driv.reset();     //function in driver class
      endtask
       
      task test();
        fork
        gen.main();
        driv.main();
        join_any
      endtask
       
      task post_test();
        wait(gen.ended.triggered);
        wait(gen.repeat_count == driv.no_transactions);
      endtask 
       
      //run task
      task run;
        pre_test();
        test();
        post_test();
        $finish;
      endtask
       
    endclass

    Part 6 Test

  • Creating the environment.
  • Configuring the testbench i.e, setting the type and number of transactions to be generated. 
  • Initiating the stimulus driving.
    `include "environment.sv"
    program test(myintf);
       
      environment env;     //declaring environment instance
       
      initial begin
        env = new(myintf);      //creating environment
         
        //setting the repeat count of generator as 10, means to generate 10 packets
        env.gen.repeat_count = 10;
         
        //calling run of env, it interns calls generator and driver main tasks.
        env.run();
      end
    endprogram

    Part 7 Top

  • This is the topmost file, which connects the DUT and TestBench. 
  • TestBench top consists of DUT, Test and Interface instances.
  • The interface connects the DUT and TestBench.
    `include "interface.sv"
    `include "random_test.sv"
     
    module tbench_top;
       
      bit clk;
      bit reset;
        
      always #5 clk = ~clk;    //generate clk
       
      //reset Generation
      initial begin
        reset = 1;
        #5 reset =0;
      end   
       
      //creatinng instance of interface, inorder to connect DUT and testcase 实例interface
      myintf i_intf(clk,reset);
       
      //实例 test class
      test t1(i_intf);
       
      //DUT instance, interface signals are connected to the DUT ports
      adder DUT (
        .clk(i_intf.clk),
        .reset(i_intf.reset),
        .a(i_intf.a),
        .b(i_intf.b),
        .valid(i_intf.valid),
        .c(i_intf.c)
       );
       
      //enabling the wave dump
      initial begin
        $dumpfile("dump.vcd"); $dumpvars;
      end
    endmodule

猜你喜欢

转载自blog.csdn.net/weixin_40038116/article/details/81113392