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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [PCIe/] [sim/] [src/] [riffa_bfm_class_pkg.sv] - Rev 39

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 riffa_bfm_class_pkg;

  // --------------------------------------------------------------------
  //
  import q_pkg::*;


  // --------------------------------------------------------------------
  //
  class riffa_transaction_class #(N);

    rand logic [31:0] len;
    rand logic [30:0] off;
    rand logic last;
    rand logic [(8*N)-1:0] data[];


    //--------------------------------------------------------------------
    //
    function int get_data_size(int len);
      int words = ((len * 4) % N == 0) ? ((len * 4) / N) : ((len * 4) / N) + 1;
      // $display("^^^ %16.t | N     = %d", $time, N);
      // $display("^^^ %16.t | len   = %d", $time, len);
      // $display("^^^ %16.t | mod   = %d", $time, (len * 4) % N);
      // $display("^^^ %16.t | words = %d", $time, words);
      return(words);
    endfunction: get_data_size


    //--------------------------------------------------------------------
    //
    function void constant(int len, int off, bit last, logic [(8*N)-1:0] value);
      this.data = new[get_data_size(len)];
      this.len = len;
      this.off = off;
      this.last = last;
      foreach(this.data[i])
        this.data[i] = value;
    endfunction: constant


    //--------------------------------------------------------------------
    //
    function void counting(int len, int off, bit last);
      this.data = new[get_data_size(len)];
      this.len = len;
      this.off = off;
      this.last = last;
      foreach(this.data[i])
        this.data[i] = i;
    endfunction: counting


    //--------------------------------------------------------------------
    //
    function void hex(string str, int off, bit last);
      string rev_str;
      string char;
      int w, c;
      this.len  = (str.len() % (2 * 4)) == 0
                ? (str.len() / (2 * 4))
                : (str.len() / (2 * 4)) + 1;
      this.data = new[get_data_size(this.len)];
      this.off = off;
      this.last = last;
      rev_str = {<<8{str}}; // reverse string
      for(w = 0; w < rev_str.len(); w += (N * 2))
        for(c = 0; c < (N * 2); c++)
        begin
          char = string'(rev_str.getc(w + c));
          if(char == "")
            this.data[w / (N * 2)][(c * 4) +: 4] = 0;
          else
            this.data[w / (N * 2)][(c * 4) +: 4] = char.atohex();
        end
    endfunction: hex


    //--------------------------------------------------------------------
    //
    function void random(int len, int off, bit last);
      this.data = new[get_data_size(len)];
      assert(this.randomize() with
      {
        this.len == len;  // why not working?
        this.off == off;
        this.last == last;
      });
      this.len = len;
      this.off = off;
      this.last = last;
    endfunction: random


    //--------------------------------------------------------------------
    //
    function void compare(riffa_transaction_class #(N) to, int max_mismatches = 8);
      int error_count = 0;
      $display("!!! %16.t | %m", $time);
      if(this.len != to.len)
        $display("!!! %16.t | ERROR! len mismatch", $time);

      if(this.off != to.off)
        $display("!!! %16.t | ERROR! off mismatch", $time);

      if(this.last != to.last)
        $display("!!! %16.t | ERROR! last mismatch", $time);

      foreach(this.data[i])
      begin
        if(error_count > max_mismatches)
          break;
        if(this.data[i] !== to.data[i])
        begin
          $display("!!! %16.t | ERROR! | 0x%x | this != to | 0x%x != 0x%x", $time, i, this.data[i], to.data[i]);
          error_count++;
        end
      end
    endfunction: compare


    // // --------------------------------------------------------------------
    // //
    // function void copy(ref riffa_transaction_class #(N) from);
      // this.len = from.len;
      // this.off = from.off;
      // this.last = from.last;
    // endfunction: copy


    // // --------------------------------------------------------------------
    // //
    // function riffa_transaction_class #(N) clone();
      // clone = new(0, 0, 0);
      // clone.copy(this);
    // endfunction: clone


    //--------------------------------------------------------------------
    function new(int len, int off, bit last);
      this.data = new[get_data_size(len)];
      this.len  = len;
      this.off  = off;
      this.last = last;
    endfunction: new


  // --------------------------------------------------------------------
  //
  endclass: riffa_transaction_class


  // --------------------------------------------------------------------
  // root port tx
  class rp_tx_bfm_class #(N)
    extends blocking_transmission_q_class #(riffa_transaction_class #(N));

    virtual riffa_chnl_if #(.N(N)) chnl_bus;

    // --------------------------------------------------------------------
    //
    task set_default;

      chnl_bus.cb_rp_tx.rx <= 0;
      chnl_bus.cb_rp_tx.rx_last <= 'bx;
      chnl_bus.cb_rp_tx.rx_len <= 'bx;
      chnl_bus.cb_rp_tx.rx_off <= 'bx;
      chnl_bus.cb_rp_tx.rx_data <= 'bx;
      chnl_bus.cb_rp_tx.rx_data_valid <= 0;

    endtask: set_default


    // --------------------------------------------------------------------
    //
    event tx_done;

    task transmit(ref Q_T tr_h);

      @(chnl_bus.cb_rp_tx);
      chnl_bus.cb_rp_tx.rx_len <= tr_h.len;  // must be => 4
      chnl_bus.cb_rp_tx.rx_off <= tr_h.off;
      chnl_bus.cb_rp_tx.rx_last <= tr_h.last;
      chnl_bus.cb_rp_tx.rx <= 1;

      @(chnl_bus.cb_rp_tx iff chnl_bus.cb_rp_tx.rx_ack);
      chnl_bus.cb_rp_tx.rx_data_valid <= 1;

      foreach(tr_h.data[i])
      begin
        chnl_bus.cb_rp_tx.rx_data <= tr_h.data[i];
        @(chnl_bus.cb_rp_tx iff chnl_bus.cb_rp_tx.rx_data_ren);
      end

      set_default();
      ->tx_done;
    endtask: transmit


    //--------------------------------------------------------------------
    //
    function new(virtual riffa_chnl_if #(.N(N)) chnl_bus);
      this.chnl_bus = chnl_bus;
      fork
        set_default();
      join_none
    endfunction: new


    // --------------------------------------------------------------------
    //
  endclass: rp_tx_bfm_class


  // --------------------------------------------------------------------
  // root port rx
  class rp_rx_bfm_class #(N)
    extends blocking_transmission_q_class #(riffa_transaction_class #(N));

    virtual riffa_chnl_if #(.N(N)) chnl_bus;
    mailbox #(riffa_transaction_class #(N)) rx_q;


    // --------------------------------------------------------------------
    //
    task set_default;

      chnl_bus.cb_rp_rx.tx_ack <= 0;
      chnl_bus.cb_rp_rx.tx_data_ren <= 0;

    endtask: set_default


    // --------------------------------------------------------------------
    //
    event rx_done;

    task automatic transmit(ref Q_T tr_h);
      int last;
      int len;
      int off;

      @(chnl_bus.cb_rp_rx iff chnl_bus.cb_rp_rx.tx);

      last = chnl_bus.cb_rp_rx.tx_last;
      len = chnl_bus.cb_rp_rx.tx_len; // must be => 4
      off = chnl_bus.cb_rp_rx.tx_off;
      tr_h = new(len, off, last);

      chnl_bus.cb_rp_rx.tx_ack <= 1;
      chnl_bus.cb_rp_rx.tx_data_ren <= 1;

      fork
        @(chnl_bus.cb_rp_rx)
          chnl_bus.cb_rp_rx.tx_ack <= 0;
      join_none

      foreach(tr_h.data[i])
      begin
        @(chnl_bus.cb_rp_rx iff chnl_bus.cb_rp_rx.tx_data_valid)
          tr_h.data[i] <= chnl_bus.cb_rp_rx.tx_data;
        // $display("^^^ %16.t | %d | %h", $time, i, chnl_bus.cb_rp_rx.tx_data);
      end

      rx_q.put(tr_h);
      set_default();
      ->rx_done;
    endtask: transmit


    //--------------------------------------------------------------------
    //
    function new(virtual riffa_chnl_if  #(.N(N)) chnl_bus);
      this.chnl_bus = chnl_bus;
      this.rx_q = new();
      fork
        set_default();
      join_none
    endfunction: new


    // --------------------------------------------------------------------
    //
  endclass: rp_rx_bfm_class

// --------------------------------------------------------------------
//
endpackage: riffa_bfm_class_pkg

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.