OpenCores
URL https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [axi4_stream_lib/] [sim/] [tests/] [tb_axis_gear_box/] [axis_pkg.sv] - Rev 40

Go to most recent revision | Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2017 Authors and OPENCORES.ORG                 ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////

// --------------------------------------------------------------------
//
package axis_pkg;

  // --------------------------------------------------------------------
  //
  import uvm_pkg::*;
  `include "uvm_macros.svh"
  import axis_pkg::*;

  // --------------------------------------------------------------------
  //
  typedef struct packed
  {
    int unsigned N; // data bus width in bytes
    int unsigned I; // TID width
    int unsigned D; // TDEST width
    int unsigned U; // TUSER width
    bit USE_TSTRB; // set to 1 to enable, 0 to disable
    bit USE_TKEEP; // set to 1 to enable, 0 to disable
    bit USE_ROUTING; // set to 1 to enable, 0 to disable
  } axis_config_t;

  // --------------------------------------------------------------------
  //
  class axis_sequence_item #(axis_config_t cfg)
    extends uvm_sequence_item;
    `uvm_object_param_utils(axis_sequence_item #(cfg))

    // --------------------------------------------------------------------
    //
    localparam N = cfg.N;
    localparam I = cfg.I;
    localparam D = cfg.D;
    localparam U = cfg.U;
    localparam USE_TSTRB = cfg.USE_TSTRB;
    localparam USE_TKEEP = cfg.USE_TKEEP;
    localparam USE_ROUTING = cfg.USE_ROUTING;

    // --------------------------------------------------------------------
    //
    rand logic [(8*N)-1:0]  tdata;
    rand logic [N-1:0]      tstrb;
    rand logic [N-1:0]      tkeep;
    rand logic              tlast;
    rand logic [I-1:0]      tid;
    rand logic [D-1:0]      tdest;
    rand logic [U-1:0]      tuser;
    
    // --------------------------------------------------------------------
    //
    function new(string name = "");
      super.new(name);
    endfunction : new

    // --------------------------------------------------------------------
    //
    function bit do_compare(uvm_object rhs, uvm_comparer comparer);
      axis_sequence_item #(cfg) tested;
      bit same;

      if (rhs==null)
        `uvm_fatal(get_type_name(), "| %m | comparison to a null pointer");

      if (!$cast(tested,rhs))
        same = 0;
      else
        same  = super.do_compare(rhs, comparer)
              & (tested.tdata == tdata)
              & (USE_TSTRB ? (tested.tstrb == tstrb) : 1)
              & (USE_TKEEP ? (tested.tkeep == tkeep) : 1)
              & (tested.tlast == tlast)
              & (USE_ROUTING ? (tested.tid == tid) : 1)
              & (USE_ROUTING ? (tested.tdest == tdest) : 1)
              & (tested.tuser == tuser);
      return same;
    endfunction : do_compare

    // --------------------------------------------------------------------
    //
    function void do_copy(uvm_object rhs);
      axis_sequence_item #(cfg) item;
      assert(rhs != null) else
        `uvm_fatal(get_type_name(), "| %m | copy null transaction");
      super.do_copy(rhs);
      assert($cast(item,rhs)) else
        `uvm_fatal(get_type_name(), "| %m | failed cast");
      tdata = item.tdata;
      tstrb = item.tstrb;
      tkeep = item.tkeep;
      tlast = item.tlast;
      tid   = item.tid;
      tdest = item.tdest;
      tuser = item.tuser;
    endfunction : do_copy

    // --------------------------------------------------------------------
    //
    function string convert2string();
      string s0, s1;
      s0 = $sformatf("| tdata: %h\n" ,tdata);
      s1 = $sformatf("| tlast: %1h | tuser: %h" , tlast, tuser);
      return {s1, s0};
    endfunction : convert2string

  // --------------------------------------------------------------------
  //
  endclass : axis_sequence_item

  // --------------------------------------------------------------------
  //
  class axis_driver #(parameter axis_config_t cfg) 
    extends uvm_driver #(axis_sequence_item #(cfg));
     `uvm_component_param_utils(axis_driver#(cfg))
     
    // --------------------------------------------------------------------
    //
    localparam N = cfg.N;
    localparam I = cfg.I;
    localparam D = cfg.D;
    localparam U = cfg.U;
    localparam USE_TSTRB = cfg.USE_TSTRB;
    localparam USE_TKEEP = cfg.USE_TKEEP;
    localparam USE_ROUTING = cfg.USE_ROUTING;

    // --------------------------------------------------------------------
    //
    virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_bus;
        
    //--------------------------------------------------------------------
    //
    function void set_default;
      axis_bus.cb_m.tvalid  <= 0;
      axis_bus.cb_m.tdata   <= 'bx;
      axis_bus.cb_m.tstrb   <= 'bx;
      axis_bus.cb_m.tkeep   <= 'bx;
      axis_bus.cb_m.tlast   <= 'bx;
      axis_bus.cb_m.tid     <= 'bx;
      axis_bus.cb_m.tdest   <= 'bx;
      axis_bus.cb_m.tuser   <= 'bx;
    endfunction: set_default

    
    //--------------------------------------------------------------------
    //
    virtual task run_phase(uvm_phase phase);
      axis_sequence_item #(cfg) item;
      super.run_phase(phase);
      
      $display("^^^ %16.t | %m | ", $time);

      set_default();

      @(axis_bus.cb_m) forever 
      begin
        // seq_item_port.try_next_item(item);
        seq_item_port.get_next_item(item);
              
        axis_bus.cb_m.tvalid  <= 1;
        axis_bus.cb_m.tdata   <= item.tdata;
        axis_bus.cb_m.tstrb   <= 0;
        axis_bus.cb_m.tkeep   <= 0;
        axis_bus.cb_m.tlast   <= item.tlast;
        axis_bus.cb_m.tid     <= 0;
        axis_bus.cb_m.tdest   <= 0;
        axis_bus.cb_m.tuser   <= item.tuser;

        @(axis_bus.cb_m);
        wait(axis_bus.cb_m.tready);
        // @(axis_bus.cb_m iff axis_bus.cb_m.tready);

        set_default();

        seq_item_port.item_done();
      end
    endtask : run_phase


    //--------------------------------------------------------------------
    //
    function new(string name, uvm_component parent);
      super.new(name, parent);
    endfunction
    
  // --------------------------------------------------------------------
  //
  endclass : axis_driver
  
  
  // --------------------------------------------------------------------
  //
  class axis_sequencer #(axis_config_t cfg)
    extends uvm_sequencer #(axis_sequence_item #(cfg));
    `uvm_component_param_utils(axis_sequencer #(cfg))
    
    // --------------------------------------------------------------------
    //
    function new(string name, uvm_component parent);
      super.new(name, parent);
      $display("^^^ %16.t | %m | ", $time);
    endfunction

  // --------------------------------------------------------------------
  //
  endclass : axis_sequencer
  
  // --------------------------------------------------------------------
  //
  class axis_counting_sequence #(axis_config_t cfg) 
    extends uvm_sequence #(axis_sequence_item #(cfg));
     `uvm_object_param_utils(axis_counting_sequence #(cfg))

    // --------------------------------------------------------------------
    //
    localparam LENGTH = 16;
        
    // --------------------------------------------------------------------
    //
    virtual task body();
      axis_sequence_item #(cfg) item;
      
      $display("^^^ %16.t | %m | ", $time);
      
      for(int i = 0; i < LENGTH; i++)
      begin
        item = axis_sequence_item #(cfg)::type_id::create("axis_sequence_item");
        
        item.tdata = i;
        item.tlast = (i == LENGTH - 1);

        start_item (item);
        finish_item(item);
      end
    endtask
     
    // --------------------------------------------------------------------
    //
    function new(string name = "axis_counting_sequence");
      super.new(name);
    endfunction

  // --------------------------------------------------------------------
  //
  endclass : axis_counting_sequence
  
  // --------------------------------------------------------------------
  //
  class axis_agent #(axis_config_t cfg) 
    extends uvm_agent;
     `uvm_component_param_utils(axis_agent #(cfg))

    // --------------------------------------------------------------------
    //
    localparam N = cfg.N;
    localparam I = cfg.I;
    localparam D = cfg.D;
    localparam U = cfg.U;
    localparam USE_TSTRB = cfg.USE_TSTRB;
    localparam USE_TKEEP = cfg.USE_TKEEP;
    localparam USE_ROUTING = cfg.USE_ROUTING;

    // --------------------------------------------------------------------
    //
    // virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_bus;
    virtual tb_dut_if #(.IN_N(N), .OUT_N(N), .I(I), .D(D), .U(U)) dut_bus;

     axis_driver #(cfg) driver;
     // my_monitor    #(cfg) monitor;
     axis_sequencer #(cfg) sequencer;
     
    // --------------------------------------------------------------------
    //
    virtual function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      
      $display("^^^ %16.t | %m | ", $time);

      if (!uvm_config_db #(virtual tb_dut_if #(.IN_N(N), .OUT_N(N), .I(I), .D(D), .U(U)))::get(this, "", "dut_bus", dut_bus))
         `uvm_fatal(get_name(), "Could not get the virtual interface handle from the config database.")

      driver = axis_driver #(cfg)::type_id::create("driver", this);
      // monitor   = my_monitor  #(cfg)::type_id::create("monitor"  , this);
      sequencer = axis_sequencer #(cfg)::type_id::create("sequencer", this);
    endfunction

    // --------------------------------------------------------------------
    //
    virtual function void connect_phase(uvm_phase phase);
      super.connect_phase(phase);
      
      $display("^^^ %16.t | %m | ", $time);

      driver.axis_bus = dut_bus.axis_in;
      // monitor.vif = vif;

      driver.seq_item_port.connect(sequencer.seq_item_export);
    endfunction
     
    // --------------------------------------------------------------------
    //
     function new(string name, uvm_component parent);
        super.new(name, parent);
     endfunction

  // --------------------------------------------------------------------
  //
  endclass : axis_agent
  
  // --------------------------------------------------------------------
  //
  
  class my_test extends uvm_test;
     `uvm_component_utils(my_test)

    localparam axis_config_t cfg_a =  '{ 1, 1, 1, 1, 0, 0, 0};
          
     axis_agent #(cfg_a) agent_h;
     // my_agent#(cfg_b) agent_b;
     
     function new(string name = "my_test", uvm_component parent);
        super.new(name, parent);
     endfunction

     virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        
      $display("^^^ %16.t | %m | ", $time);

        agent_h = axis_agent #(cfg_a)::type_id::create("agent_h", this);
        // agent_b = my_agent#(cfg_b)::type_id::create("agent_b", this);
     endfunction

     virtual function void end_of_elaboration_phase(uvm_phase phase);
        uvm_phase run_phase = uvm_run_phase::get();
        run_phase.phase_done.set_drain_time(this, 300ns);
     endfunction

     virtual task run_phase(uvm_phase phase);
        axis_counting_sequence #(cfg_a) seq_a;
        super.run_phase(phase);
        
      $display("^^^ %16.t | %m | ", $time);

        phase.raise_objection(this);

        // fork
           // repeat (3) begin
              seq_a = axis_counting_sequence #(cfg_a)::type_id::create("seq_a");
              seq_a.start(agent_h.sequencer);
           // end

           // repeat (3) begin
              // my_sequence#(cfg_b) seq_b = my_sequence#(cfg_b)::type_id::create("seq_b");
              // seq_b.start(agent_b.sequencer);
           // end
        // join

        phase.drop_objection(this);
     endtask
  endclass  
  

// --------------------------------------------------------------------
//
endpackage: axis_pkg

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2019 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.