Transactions

Now we’re truly going OO with this testbench. Up until this point, 2 classes (that did something useful) were added : driver and monitor. Adding more classes for generators, checkers, … should not be too much of a challenge, from a coding point-of-view.

The structure, however, should become clear by now:

  1. The generator generates a testvector
  2. This testvector is sent to the driver and the checker
  3. The driver translates the input to pin-wiggles
  1. The monitor translates the output pin-wiggles to something readable.
  2. The monitor forwards its output to the checker
  3. The checker verifies the correctness
  4. The scoreboard is updated by the checker’s ruling

Transactions

To use the testbench in a generic way to enhance reusability, it is important that the generated testvectors are described in a generic form. Well … let’s use a class for that as well.

class transaction;
  byte instruction;

  function new();
    this.instruction = 8'h8c;
  endfunction : new

  function string toString();
    return $sformatf("Instruction: %08x", this.instruction);
  endfunction : toString

endclass : transaction;


This class describes the transaction. It has only a single property: instruction

Upon construction, the value for this object’s instruction is fixed (for now) to 0x8C (aka ADC H`)

There is a function toString( ) that, as the name suggests, makes a sting from the object’s property values.

Make sure you spot the return-value type string in the toString( ) method.

Generator

The generator is the object that will create the aforementioned transactions. While making an object this class nothing else happens (for now).

Furthermore, it has a function run( ) which … well … generates a transaction and displays which instruction was generated. This is repeated for 10 times.

`include "transaction.sv"

class generator;

  function new;

  endfunction : new

  task run;
    transaction tra;

    for(int i=0; i<10; i++)
    begin
      tra = new();
      $display("%s", tra.toString());
    end
  endtask : run

endclass : generator

To glue everything together, a small test is set up which creates a generator and triggers it’s run( ) function. The result is shown below.

`include "generator.sv"

program test();

  generator gen = new();

  initial
  begin
    gen.run();
  end

endprogram : test


Result of the code above

Great !! Now you can generate all the testvectors that you want 😃 Only … they are all the same and only live within the generator. Let’s fix that with mailing transactions around.