Wednesday, October 26, 2016

SystemVerilog 101.

Design
  • RTL
  • blocks
  • modules
  • vectors
  • assignments
  • arrays

Verification
  • signals, states
  • interfaces
  • clocking block
  • scheduling
  • functions
  • tasks
  • class
  • random
  • constraints
  • coverage
  • queues and arrays

Methodology
  • objects
  • components
  • messaging
  • virtual interfaces
  • TLM ports
  • field macros
  • event pool
  • transaction recording
  • phases
  • transactions
  • sequence item
  • sequences
  • parameterization
  • callbacks
  • configuration-db
  • factory
  • register model

Concepts
  • Test Layer and Functional Coverage
  • Scenario Layer
    • Generator / Virtual Sequence
    • Environment
  • Functional Layer
    • Agent
    • Scoreboard
    • Checker
  • Command Layer
    • Driver
    • Assertions
    • Monitor
  • Signal Layer
    • Dut
    • Interface
  • Phases
    • Build phase
      • Generate configuration: 
        • Randomize the configuration of the DUT
        • Randomize the surrounding environment
      • Build environment
        • Allocate and connect the test bench components based on the configuration
        • A testbench component exists in the testbench as opposed to physical components in the design.
      • Reset DUT
      • Configure DUT
        • load DUT command registers
        • Initialization
    • Run phase
      • Start Environment
        • Run the test bench components, BFMs and stimulus generators.
      • Run the test
        • Start the test and wait for doneness.
          • For random test, use the testbench layers as a guide. Wait for a layer to drain all the inputs from the previous layer and become idle. Then wait for the next lower layer.
          • Use time-out checkers to make sure it doesn't lock-up.
    • Wrap-up phase
      • Sweep
        • After the lower layer completes, wait for the final transactions to drain out of the DUT
      • Report
        • Once the DUT is idle, sweep the testbench for lost data
        • Check scoreboard for leftover transactions held that never came out.
        • Create the final report on whether the test passed.
        • If it failed, delete incorrect functional coverage results.
  • Constrained-random test with a test plan
    • First, build layered test bench, including self-checking portion.
    • Second, creating stimulus specific to a goal in test plan.
      • Error injection
    • Third,  add instrumentation to the environment and gathers functional coverage data.
    • Fourth, analyze the results to see if the goals are met.

Data Types
  • 4-state: logic, reg, integer, time
    • use $isunknown(some_logic_port) == 1 to check
  • 2-state: bit, byte, int, shortint, longint, real
  • String Methods

Arrays
  • Fixed-size Arrays
  • Dynamic Arrays
  • Queues
  • Associative Arrays

`default_nettype none
int cs[16];
int sc[15:0];
int array0 [7:0][3:0]; // packed, int=32bit
int array1[4] = '{0,1,2,3};
int descent[5] = '{9,8,default:0};
int addr[] = new[4];
array0[7][3] = 1;
bit [7:0] b_unpack[3]; // unpacked
bit [3:0][7:0] test[1:10]; // 10 entries of 4 bytes packed into 32bits
// packed array
bit [1:0] [2:0] [3:0] barray;
barray = '{'{4’h6, 4’h5, 4’h4}, '{4’h3, 4’h2, 4’h1}};

bit [3:0] nibble[];
integer mem[]; // dynamic array of integers

// Array Operations
for (int i=0; i<$size(array1); i++) array1[i] = i;
foreach (descent[j]) descent[j] = array1[j] * 4;
foreach (array0[i,j]) 
   $display ("@%0t: array[%0d][%0d] = %0d", $time, i, j, array0[i][j]);
array0 = '{'{9,8,7}, '{3{'5}}}; // tick - packed
int md[2][3] = ‘{‘{0,1,2}, ‘{3,4,5}};
foreach (md[i,j]) $display(“%d “, md[i][j]);
foreach (md[,j]) $display(“%d “, md[1][j]);
bit [31:0] src[5] = '{5{5}};
$displayb(src[0],, src[0][0],, src[2][2:1]);

// Dynamic Arrays
int dyn[], d2[];
dyn = new[5];
d2=new[20](dyn);
dyn=new[100];
dyn = ‘{dyn,5};
// shrinking
dyn = dyn[1:3];

integer addr[];
addr = new[100];
addr = new[200](addr); // double the size and preserving previous values.
addr = new [addr.size()*4](addr); // quadruple addr array
addr.delete; // delete all contents
addr.delete();
// var = $size(addr);

//
// Associative Arrays 
// Unused elements don't use memory, unlike standard array
//
int item[*]; // not recommended
int item[string];
int item[integer];
int item[classname];

item [ 2'b3 ] = 1;
item[ 16’hffff ] = 2;
item[ 4b’1000 ] = 3;
$display( "%0d entries\n", item.num ); // prints "3 entries"
// item.num = 3; // returns only number of assigned elements
item.delete; // remove all entries
item.delete (2'b3); // remove index 3
byte unsigned assoc[int], idx = 1;

int map [string];
map["is"] = 2;
map.delete["easy"];
if (map.exists("is")) map["is"] +=1;
// map.first(s) // assign map[s] to be the first value
// map.last(s)
// map.next(s)
// map.prev(s)

// Queues
int q[$] = {1,2,3,5,8}; //unbounded queue, initialized with 5 locations;
typedef struct {int a, b; bit flag} packet_t;
packet_t q3 [$:16]; //a bounded queue, with a maximum size of 16

// Queue Methods
// insert(value)
// delete(value)
// push_front(value)
// push_back(value)
// var = pop_front()
// var = pop_back()
// var = q[index]
// var = size()




UVM Scoreboard Methodology.

Principles and Concepts
  • Verify transaction functional correctness with the following approaches
    • constrained-randomization
    • coverage driven
    • transaction-level compartment
    • Use sequences
    • Use scoreboard
    • Use configuration-db
  • Use SystemVerilog to provide aggregate types for transaction storage and search
    • Dynamic Arrays, Associative Arrays, Queues, Classes
  • UVM analysis ports is easier to use than callbacks
  • UVM_transaction provides compare() / do_compare() methods
  • UVM factor for extension, replacement and reuse.

Plan of Attack
  • Analysis_port
    • port, export and imp classes used for transaction analysis
    • uvm_analysis_port - broadcasts a value to all subscribers implementing a uvm_analysis_imp
    • uvm_analysis_imp - receives all transactions broadcasted by a uvm_analysis_port.
  • Transaction Predictor
    • Required when the compared transaction is not the same format as input (ex. protocol bridges)
    • Design transforms data (ex. encryption, filter, encoder)
    • To Re-Use
      • encapsulation : a separate class
      • uvm_analysis_port / imp to connect
      • UVM factory to extend, replace existing objects
      • Replace complex predictors with several simpler scoreboards
  • Storage (for read scoreboard and for write scoreboard)
    • FIFO : queues
    • OOO : dynamic arrays, queues
    • MEM : associative array (indexed by address)
    • Associative array of queues
  • TLM Model
    • Used when you have multiple different transaction paths/routes
    • Used when behavior depends on the address or opcodes or other attributes of transactions
  • Using Factory
  • Interconnect
  • Automate by Randomization
  • Checks and Coverage
  • Assertions
  • Pool



Transactions
  • Transaction content
    • Data, address, Attributes, Opcode, Response, 
    • Data types:
      • memory -> scalar, bytes, integers, 
    • Data path:
      • Scalar
      • Transaction Item Class
  • Transaction ordering
    • FIFO
    • OOO
    • Precedence relationship
  • Test Data/Transactions -> Item of Sequences -> Sequences -> Sequencer -> Driver -> VIF -> DUT
  • DUT -> monitor -> Analysys_ports -> Scoreboard




Monday, October 24, 2016

UVM / System Verilog - Threads and Synchronization.


  • In SystemVerilog, when you instantiate static modules, you create multiple threads running the procedures within each instances.
  • Synchronization
    • Mailbox
    • Streams
    • Semaphore
    • Use Ports, Exports and TLM_FIFOs
      • uvm_put_port # (int) p1;
        p1 = new("put_port", this);
      • uvm_get_port #(int) p2;
      • uvm_tlm_fifl #(int) p3;
      • m1.p1.connect (p3.put_export);
        m2.p2.connect (p3.get_export);
      • // in f1.svh, for class c1
           uvm_put_port # (int) p1;
           p1 = new("put_port", this);
        // in f2.svh, for class c2
           uvm_get_port #(int) p2;
           p2 = new("p2", this);
        // in f3.svh, which contains the 
        //     test env for c1 and c2
           uvm_tlm_fifo #(int) p3;
           p3 = new("p3", this);
           c1.p1.connect (p3.put_export);
           c2.p2.connect (p3.get_export0;
        
        // c1.p1 -> (put_export of env)
        //               ->(p3)->
        //          (get_export of env) -> c2.p2
        
           
        endtask : run
        
    • Put shared variable in a package, together with all the classes that share that variable (using `include);
    • virtual task run();
         integer i;
         for (i = 1; i < cnt; i++) begin : loop
            uvm_report_info ("run", $psprintf(...));
            my_pkg::shared = i; // used by other classes 
                                // for synchronization
            // i = my_pkg::shared; // to read from the shared
         end : loop
      endtask : run
      
      
    • Blocking Methods vs Non-Blocking Methods
      • blocking method
        • myport.put(<data>);
        • myport.get(<data>);
      • non-blocking method (returns 0 if failed)
        • myport.try_put();
        • myport.try_get();

Example
class c1 extends uvm_agent;
   uvm_put_port #(int)p1;
   `uvm_component_utils(c1)

   function new...

   virtual function void build_phase (uvm_phase phase);
      super.build_phase(phase);
      p1 = new("p1", this);
   endfunction : build_phase

   virtual task run_phase (uvm_phase phase);
      phase.raise_objection(this);
      for (int i = 0; i < cnt; i++) begin
         p1.put(i);
         uvm_report_info("run_phase",...);
      end : loop
      phase.drop_objection(this);
   endtask : run_phase
endclass : c1

class c2 extends uvm_agent;
   uvm_put_port #(int)p2;
   `uvm_component_utils(c2)

   function new...

   virtual function void build_phase (uvm_phase phase);
      super.build_phase(phase);
      p2 = new("p2", this);
   endfunction : build_phase

   virtual task run_phase (uvm_phase phase);
      int i;
      forever begin : loop
         p2.get(i);
         uvm_report_info("run_phase",...);
      end : loop
   endtask : run_phase
endclass : c2

class c3 extends uvm_agent;

   `uvm_component_utils(c3)

   c1 p1;
   c2 p2;
   uvm_tlm_fifo #(int) p3;

   function new...

   virtual function void build_phase (uvm_phase phase);
      super.build_phase(phase);
      p1 = c1::type_id::create("p1", this);
      p2 = c2::type_id::create("p2", this);
      p3 = new("p3", this);
   endfunction : build_phase

   virtual function void connect_phase (uvm_phase phase);
      super.connect_phase(phase);
      c1.p1.connect(p3.put_export);
      c2.p2.connect(p3.get_export);
   endfunction : connect_phase

   virtual task run_phase (uvm_phase phase);
   endtask : run_phase

endclass : c3


Example : Blocking Communication vs Non-blocking Communication
// blocking
// @(posedge clk); // this could be missed 
//                   and block the following
// my_port.get(data);
// bus <= data; 

// non-blocking
// @(posedge clk)
// my_port.try_get(data); // won't suspend
// bus <= data;
//

class c1 extends uvm_agent;

   `uvm_component_utils(c1)
   uvm_put_port #(int)p1;

   function new...

   virtual function void build_phase (uvm_phase phase);
      super.build_phase(phase);
      p1 = new("p1", this);
   endfunction : build_phase

   virtual task run_phase (uvm_phase phase);
      phase.raise_objection(this);
      for (int i = 0; i < cnt; i++) begin
         // p1.put(i);
         // uvm_report_info("run_phase",...);
         #UNIT_DELAY; // to delay this thread so the following
                      // is always slower than p2 and 
                      // should never fail
         assert (p1.try_put(i)) else
            uvm_report_info("run_phase: p1 not connected");
         uvm_report_info("run_phase", $psprintf("put: %0d",i));
      end : loop
      phase.drop_objection(this);
   endtask : run_phase
endclass : c1

class c2 extends uvm_agent;

   `uvm_component_utils(c2)
   uvm_put_port #(int)p2;

   function new...

   virtual function void build_phase (uvm_phase phase);
      super.build_phase(phase);
      p2 = new("p2", this);
   endfunction : build_phase

   virtual task run_phase (uvm_phase phase);
      int i;
      forever begin : loop
         // p2.get(i);
         // uvm_report_info("run_phase",...);
         if (p2.try_get(i))
            uvm_report_info ("run",
               $psprintf ("got: %0d",i));
         else
            uvm_report_info ("run","got nothing");
      end : loop
   endtask : run_phase
endclass : c2



UVM - Scoreboard, Checking and Reporting.


  • Scoreboard
  • Reporting printer
  • Using create

Scoreboard

  • Scoreboard could hold the entire self-checking structure including the transfer function or reference model, the expected data storage mechanism and the output comparison function . It could also be limited to the data structure used to hold the expected data for ease of comparison against the monitored output values.
  • Stimulus Generator or Sequencer
    • DUT -> Response Monitor
    • TLM or transfer function
  • Output from the DUT responses are compared with expected result from transfer model

class scoreboard extends uvm_agent;
   `uvm_component_utils(scoreboard)

   virtual interface mem_if vif;
   logic [15:0] exp [2**16-1:0];

   function new (string name = "scoreboard", uvm_component parent = null);
      super.new (name, parent);
   endfunction : new

   task run_phase (uvm_phase phase);
      forever begin
         @ (vif.cb)
         if (vif.rd) begin
            #`UNIT_DELAY
            assert (vif.data === exp[vif.addr]) else
               uvm_report_error ("run",
                  $psprintf("expected %0h  actual: %0h",
                      exp[vif.addr], vif.data));
         end
         if (vif.wr) begin
            exp[vif.addr] = vif.data;
         end
      end
   endtask : run_phase 


Reporting
class reporter extends uvm_agent;

   `uvm_component_utils (reporter)
   virtual interface mem_if vif;

   function new (string name = "reporter", uvm_component parent = null);
      super.new (name parent);
   endfunction : new

   task run_phase (uvm_phase phase);
      forever begin
         @(vif.cb);
         uvm_report_info ("run",
            $psprintf ("addr: %1h  data:%4h  rd:%1b  wr: %1b",
               vif.addr, vif.data, vif.rd, vif.wr));
      end
   endtask : run_phase
endclass : reporter

class bucket extends reporter;

   `uvm_component_util(bucket)

   function new ...

   task run_phase (uvm_phase phase); // override to do nothing
   endtask : run_phase

endclass : bucket



Create Tests
// In the test class file
class test1 extends uvm_test;

   `uvm component_utils(test1)

   test_env tenv;

   function new (string name, uvm_component parent);
      super.new(name, parent);
   endfunction : new

   virtual function void build_phase (uvm_phase phase);
      tenv = test_env::type_id::create("tenv", this);
   endfunction : build_phase

endclass

class test2 extends uvm_test;

   `uvm component_utils(test2)

   test_env tenv;

   function new (string name, uvm_component parent);
      super.new(name, parent);
   endfunction : new

   virtual function void build_phase (uvm_phase phase);
      // When you call the overriding run_phase in bucket,
      // the test will run without printing line by line data in
      // in default reporter.run_phase
      reporter::type_id::set_type_override(bucket::get_type());
      tenv = test_env::type_id::create("tenv", this);
   endfunction : build_phase

endclass : test2

class test_env extends uvm_env;

   `uvm_component_utils (test_env)

   driver drv;
   scoreboard sb;
   reporter rpt;

   function new ...

   virtual function void build_phase (uvm_phase phase);
      drv = driver::type_id::create("drv", this);
      sb  = scoreboard::type_id::create("sb", this);
      rpt = reporter::type_id::create("rpt", this);
   endfunction : build_phase

endclass



UVM Connections.

Using Interface
  • Virtual interface
  • Static interface

Example 1
`include "uvm_macros.svh"

package my_pkg;
   import uvm_pkg::*;
   int shared_int;
   int shared_count;

   virtual interface mem_if global_vmi;
   `include "uvm_macros.svh"
   `include "test_1.svh"
   `include "test_2.svh"

endpackage: my_pkg

import uvm_pkg::*;
import my_pkg::*;

module top;
   mem_if mi();
   sram dut (mi.mem_modport);

   initial begin
      string test_name;
      my_pkg::global_vmi = mi;
     run_test();
   end

endmodule: top

// typedef struct packed
typedef struct {
   bit     sign;
   bit[24:0] mantissa;
   bit[ 5:0] exponent;
} ieee_sp_float;

union packed {
   bit [7:0] data[1500];
   struct packed {
      bit [7:0] dsap;
      bit [7:0] ssap;
      bit [7:0] control;
      bit [7:0] data[1497];
   } label;
} payload;

class test_1 extends uvm_test;
   `uvm_component_utils(test_1)

   ieee_sp_float v1, v2;
   v1 = {1, 24'h800, 6'h0};
   v1 = abs(v1);
   virtual interface mem_if mi;

   function new (string name, uvm_component base);
      super.new(name, base);
   endfunction : new

   virtual function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      mi = my_pkg::global_vmi;
   endfunction : build_phase

   virtual task run_phase(uvm_phase phase);

      int cnt=5;
      logic [3:0] sub_addr;
      rand logic [11:0] upper_addr;
      sub_addr = $urandom($random);
      phase.raise_objection(this);
      mi.wr = 1'b1;
      mi.rd = ~mi.wr;
      mi.wr_data = $urandom($random);
      `uvm_info("TESTER", 
         $psprintf("addr: %2h  data: %2h  rd: %1b  wr: %1b", 
         mi.addr, mi.data, mi.rd, mi.wr), UVM_INFO);

      super.run();
      mi.addr = {upper_addr, sub_addr};

      repeat (cnt) begin
         @(posedge mi.clk);
         ...
      end
         @(posedge mi.clk);

         phase.drop_objection(this);

   endtask // run_phase


Example 2
import my_pkg::*;

// Virtual interface in driver
class my_driver extends uvm_driver #(my_transaction); 

   `uvm_component_utils(my_driver)

   virtual dut_if dut_vi;

   function new(string name, uvm_component parent); 
      super.new(name, parent);
   endfunction: new

   // function void build;
   virtual function void build_phase (uvm_phase phase);
      super.build();
      dut_vi = global_dutvi;
   endfunction : build_phase

   // task run;
   task run_phase (uvm_phase phase);
      repeat(4)
      begin
         phase.raise_objection(this);
         my_transaction tx;
         @(posedge dut_vi.clock);

         // Driver consumes the transactions generated by
         // my_transaction and wiggles the pins on the DUT
         seq_item_port.get(tx);

         // Pin Wiggling
         dut_vi.cmd  = tx.cmd;
         dut_vi.addr = tx.addr;
         dut_vi.data = tx.data;

      end
      @(posedge dut_vi.clock) top.stop_request();
      phase.drop_objection(this);

   endtask: run

endclass : my_driver


Example 3, connecting sequencer to driver
class my_sequencer extends uvm_sequencer;
   ...
   uvm_put_port #(int) port1;
   port1 = new ("port1", this);

endclass

class my_driver extends uvm_driver;
   ...
   uvm_get_port #(int) port2;
   port2 = new ("port2", this);

endclass

class my_agent extends uvm_agent; 
   `uvm_component_utils(my_agent) // register for type_id

   my_sequencer my_sequencer_h;
   my_driver my_driver_h;

   function new(string name, uvm_component parent); 
      super.new(name, parent);
   endfunction: new

   function void build;
      super.build(); 
      my_sequencer_h = 
         my_sequencer::type_id::create("my_sequencer_h", this);
                                     // instance name,   parent
      my_driver_h =
         my_driver::type_id::create  ("my_driver_h" , this);

   endfunction: build

   // Lower level connection in another function is good practice
   // seq_item_port is the handler of the ports

   function void connect; 
      my_driver_h.seq_item_port.connect(
         my_sequencer_h.seq_item_export ); 
   endfunction: connect

endclass : my_agent


Example 4, connecting through top module
`timescale 1ns/1ns

module top;

   mem_if mi();
   sram dut (mi.mem_modport);
   tester tst (mi.test_modport);

endmodule // top

interface mem_if;
   bit clk, rd, wr;
   logic [15:0] wr_data;
   wire  [15:0] data;
   logic [15:0] addr;

   modport mem_modport (
      inout data,
      input addr,
      input clk,
      input rd,
      input wr
   );

   modport test_modport (
      input clk,
      output wr_data,
      output addr,
      output rd,
      output wr
   );

   clocking cb @ (negedge clk);
      output data <= ...;
      output addr <= ...;
   endclocking: cb

   initial begin
      @(cb) ; wr_data <= ...;
      @(cb) ; wr <= $urandom;
   end

   assign rd = ~wr;
   assign data = (wr) ? wr_data : 16'hzzzz;

   initial begin
      clk = 0;
      $monitor ();
   end

   always #10 clk = ~clk;

endinterface // mem_if


Example 5, connecting in tester
module top;

   mem_if mi();
   sram dut (mi.mem_modport);
   tester tst;

   initial begin
      tst = new(mi);
      fork
         tst.run;
      join_none
   end

endmodule // top

class tester; // driver

   logic [3:0] sub_addr;
   virtual interface mem_if tmi;

   function new (virtual interface mem_if vmi);
      tmi = vmi;
   endfunction // new

   task run;
      // generate transaction data
      tmi.wr = 1'b1;

      @ (posedge tmi.clk); 
      repeat (100) begin
         @ (posedge tmi.clk); 
         tmi.wr = $random;
         tmi.rd = ~tmi.wr;
         tmi.addr = $random;
         tmi.wr_data = $urandom($random);
      end
      $stop;
   endtask // run

endclass // tester


Example 6, use wrapper_if
module top;

import uvm_pkg::*;
import my_pkg::*;

   mem_if mi();
   sram dut (mi.mem_modport);
   // tester tst; // replaced by if_wrapper

   initial begin: blk
      dut_if_wrapper if_wrapper = new ("if_wrapper", dut_if_inst1);
                   // path  field_name        value      0: don't clone
      set_config_object("*", "dut_if_wrapper", if_wrapper, 0);

      run_test ("my_test");
   end

endmodule : top

class dut_if_wrapper extends uvm_object;

   virtual dut_if dut_vi;
   function new (string s, virtual dut_if if_arg); 
      super.new(s);
      dut_vi = if_arg;
   endfunction : new

   // you can have task run; here

endclass : dut_if_wrapper

`include "uvm_macros.svh"

package my_pkg;
import uvm_pkg::*;

// Fixed test environment
class my_env extends uvm_env;
    `uvm_component_utils (my_env)

    virtual dut_if dut_virtual_if_inst;

    // constructor
    function new (string s, uvm_component inst_parent);
        super.new (s, inst_parent);
    endfunction : new

    function void build;
        super.build ();
        begin
            uvm_object obj;
            dut_if_wrapper if_wrapper; 
            get_config_object("dut_if_wrapper", obj, 0);
            assert( $cast(if_wrapper, obj) );
            dut_virtual_if_inst = if_wrapper.dut_vi;
        end
    endfunction : build

    task run;
        #10 dut_virtual_if_inst.data = 0;
        #10 dut_virtual_if_inst.data = 1;
        #10 stop_request();
    endtask : run

endclass : my_env


Example 7, use uvm_get_port and uvm_put_port in tlm_fifo / tlm_analysis_fifo
class producer extends uvm_agent;
   uvm_put_port #(int) phone1;
   ...

   virtual function void build_phase (uvm_phase phase);
      super.build_phase(phase);
      phone1 = new("phone1", this);
   endfunction

   virtual task run_phase (uvm_phase phase);
      phase.raise_objection(this);
      for (int i = 0; i < count; i++) begin : loop
         phone1.put(i);
         uvm_report_into ("run_phase", $psprintf("...");
      end : loop
      phase.drop_objection(this);
   endtask : run_phase

endclass : producer

class consumer extends uvm_agent;
   uvm_get_port #(int) phone2;
   ...

   virtual function void build_phase (uvm_phase phase);
      super.build_phase(phase);
      phone2 = new("phone2", this);
   endfunction

   virtual task run_phase (uvm_phase phase);
      phase.raise_objection(this);
      for (int i = 0; i < count; i++) begin : loop
         phone1.put(i);
         uvm_report_into ("run_phase", $psprintf("...");
      end : loop
      phase.drop_objection(this);
   endtask : run_phase

endclass : producer

class test_env extends uvm_env;

   producer p;
   consumer c;
   uvm_tlm_fifo #(int) tlmff;

   function new () ...

   virtual function void build_phase (uvm_phase phase);
      super.build_phase (phase);
      p = producer::type_id::create ("p", this);
      p = producer::type_id::create ("p", this);
      tlmff = new ("tlmff", this);
   endfunction : build_phase

   virtual function void connect_phase (uvm_phase phase);
      super.connect_phase (phase);
      p.phone1.connect (tlmff.put_export);
      c.phone2.connect (tlmff.get_export);
   endfunction : connect_phase


Example 8, using uvm_config_db
module top;
   ...
   dut_if dut_if1 ();
   initial
   begin: blk
      //             type of value        prefix   path
      uvm_config_db #(virtual dut_if)::set(null, “uvm_test_top”, 
                  "dut_vi", dut_if1);
      //          field name, value
      run_test("my_test");
   end
endmodule: top

class my_test extends uvm_test;
   ...
   my_dut_config dut_config_0; 
   ...

   function void build_phase(uvm_phase phase);
      dut_config_0 = new();
      //             type of value    prefix   path
      if(!uvm_config_db #(dut_if)::get( this, “”, 
                        “dut_vi”, dut_config_0.dut_vi))
             `uvm_fatal(“MY_TEST”, “No DUT_IF”);

      // other DUT configuration settings
      uvm_config_db#(my_dut_config)::set(this, “*”, “dut_config”,
                                       dut_config_0);     
    endfunction
endclass

class my_driver extends uvm_driver;
   `uvm_component_utils(my_driver)
   virtual dut_if dut_vi;

   function new(string name, uvm_component parent); ...

   function void build_phase(uvm_phase phase); ...

   task run_phase(uvm_phase phase);
      phase.raise_objection(this);
      #10 dut_vi.data = 0;
      #10 dut_vi.data = 1;
      #10 phase.drop_objection(this); 
   endtask: run_phase

endclass


Sunday, October 23, 2016

Java Data Structure - Collections.

Collections

  • Autoboxing
  • Array List vs Linked List vs Queue
  • Hash map vs Tree map
  • untyped collections and wrapper class with untyped collections
  • Wrapper classes for primitive types
    • Byte (byte)
    • Short (short)
    • Integer (int)
    • Long (long)
    • Float (float)
    • Double (double)
    • Character (char)
    • Boolean (boolean)
  • Java Collection Framework (Collections is the basic methods):
    • Lists (ordered) - ArrayList and LinkedList
    • Sets  (no dupicate) - HashSet
    • Mapes (key value pair) - HashMap and TreeMap
  • How it's different from Arrays
    • Collections are classes in Java API, array is a Java Language feature.
    • Collection classes have methods.
    • Collections are varied in size.
    • Collections are containers for objects, not for primitive types.
    • Collections can process without indices while indices are usually required to process arrays.
  • Generic collections
    • ex. ArrayList<String> al = new ArrayList<String>();

Example
// This is an untyped array list
ArrayList al = new ArrayList();
al.add("item1");
al.add("item2");
for (Object o : al)
    { ... }

ArrayList p = new ArrayList();
p.add (new className (...));

for (int i = 0; i < p.size(); i++) {
    className c = (className)p.get(i);
    ...
}

// untyped array list will result in compiler warning
// Note: file.java uses unchecked or unsafe operations.
// Note: Recompile with -Xlint:unchecked for details.


ArrayList Numbers = new ArrayList();
numbers.add(new Interger(1));
numbers.add("Mary");

//
// and gives run time errors:
// Exception in thread "main" java.lang.ClassCastException: java.lang.String 
// cannot be cast to java.lang.Integer at Demo.main(file.java:37)

        ArrayList numbers = new ArrayList();
           numbers.add(new Integer(1));
           numbers.add(new Integer(2));
           numbers.add("Mary");
           numbers.add("Helen");

        for (int i = 0; i < numbers.size(); i++)
           {
               int number = (Integer)numbers.get(i);
               System.out.println(number);
           }



// Use collection in a generic array

ArrayList<String> codes = new ArrayList<String>();
codes.add("Mary");
codes.add("Helen");
codes.add("Raymond");
codes.add(100); //compiler error, wrong type, has to be String
System.out.println(codes);


// Using wrappers for primitives
ArrayList Numbers = new ArrayList();
numbers.add(new Integer(1));


Classes and Packages

  • java.util.Arrays
  • java.util.ArrayList
    • Constructors
      • ArrayList<E>()
      • ArrayList<E>(intCapacity)
      • ArrayList<E>(Collection)
    • Methods:
      • add(object)
      • add(index, object)
      • clear()
      • contains(object)
      • get(index)
      • indexOf(object)
      • isEmpty()
      • remove(index)
      • remove(object)
      • set(index, object)
      • size()
      • toArray()


Java Data Structure - Arrays.

Arrays
  • Array is aggregate data types that contains elements of the items in an array.
  • Built-in in Java for primitives or references.
  • Jagged array vs Retangular array
  • Enhanced for loop
  • Array Class: java.util.Arrays
    • fill (arrayName, value) // Fill out all elements to "value"
    • fill (arrayName, fromIndex, toIndes_plus_1, value)
    • equals (array1, array2)
    • copyOf (arrayFrom,  length) // JDK 1.6+ shallow copy for ref type
    • copyOfRange (arrayFrom,  fromIndes, toIndex_plus_one) // JDK 1.6+
    • sort (arrayName) // MUST implememts Comparable Interface
    • sort (arrayName, fromIndex, toIndex)
    • binarySearch (arrayName, value) // Must have compareTo, sort or binarySearch method defined and must do Arrays.sort first for binarySearch

Example
String [] sArray;
String sArray[];
sArray = new String[];
sArray = new String[10];
sArray = new String[10][];

String [] SArray = new String[];
String sArray [] = {"Mary", "Susan", "Raymond"};
double [] dArray = new double[10];
double [] prices = {12.95, 11.95, 10.95};

final int TOTAL_STUDENTS = 50;
Scanner sc = new Scanner(System.in);
int totalStudents = sc.nextInt();
String [] StudentsA = new String[TOTAL_STUDENTS];
String [] StudentsB = new String[totalStudents];

StudentsA[0] = "Mary";

String[] name1 = {"Forrest Gump", "A Beautiful Mind"};
String[] name2 = {"Forrest Gump", "A Beautiful Mind"};
// if (name1 == name2) ==> gives "false"
// if (Arrays.equals(name1, name2) ==> gives "true"

Public interface Comparable {
    int compareTo (Object obj);
}

class Item implements Comparable {
    private int number;
    private String name;
    public Item (int n, String s) {
        this.number = n;
        this.name = s;
    }

    public int getNumber () {
        return number;
    }

    // This overriding compareTo compares the first field
    //     which is the item.number in this case
    //     can be altered by supplementing with another
    //     class implementing "Comparator" interface
    //     to compare by name
    //
    @Ovrride
    public int compareTo(Object o) {
        if (o instanceof Item) {
            Item i = (Item) o;
            if (this.getNumber() < i.getNumber()) {
                return -1;
            } else if (this.getNumber() > i.getNumber()) {
                return 1;
            }
            return 0; 
        }
    }
}

public class ItemOtherCompare implements Comparator {
    public int compare (Object o1, Objece o2) {
        int i1 = ((Item) o1).getOtherField();
        int i2 = ((Item) o2).getOtherField();
        if (i1 > i2) return 1;
        if (i2 > i2) return -1;
        return 0;
    }

    public boolean equals (Object o1, Object o2) {
        int i1 = ((Item) o1).getOtherField();
        int i2 = ((Item) o2).getOtherField();
        return (i1 == i2);
        return false;
    }
}

// Arrays.sort(items); // this will sort by first field data
// Arrays.sort(items, new ItemOtherCompare()); // this will sort by other field