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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [axi4_lib/] [sim/] [src/] [axi4_bfm/] [axi4_slave_bfm_if.sv] - Rev 29

Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2015 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                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////


interface
  axi4_slave_bfm_if
  #(
    A = 32, // address bus width
    N = 8,  // data bus width in bytes
    I = 1   // ID width
  )
  (
    axi4_if axi4_m,
    input   aresetn,
    input   aclk
  );

  logic [(A-1):0]    araddr;
  logic [1:0]        arburst;
  logic [3:0]        arcache;
  logic [(I-1):0]    arid;
  logic [7:0]        arlen;
  logic              arlock;
  logic [2:0]        arprot;
  logic [3:0]        arqos;
  logic              arready;
  logic [3:0]        arregion;
  logic [2:0]        arsize;
  logic              arvalid;
  logic [(A-1):0]    awaddr;
  logic [1:0]        awburst;
  logic [3:0]        awcache;
  logic [(I-1):0]    awid;
  logic [7:0]        awlen;
  logic              awlock;
  logic [2:0]        awprot;
  logic [3:0]        awqos;
  logic              awready;
  logic [3:0]        awregion;
  logic [2:0]        awsize;
  logic              awvalid;
  logic [(I-1):0]    bid;
  logic              bready;
  logic [1:0]        bresp;
  logic              bvalid;
  logic [(8*N)-1:0]  rdata;
  logic [(I-1):0]    rid;
  logic              rlast;
  logic              rready;
  logic [1:0]        rresp;
  logic              rvalid;
  logic [(8*N)-1:0]  wdata;
  logic [(I-1):0]    wid;
  logic              wlast;
  logic              wready;
  logic [N-1:0]      wstrb;
  logic              wvalid;


  // --------------------------------------------------------------------
  //
  default clocking cb @(posedge aclk);
    input   arid;
    input   araddr;
    input   arburst;
    input   arcache;
    input   awid;
    input   arlen;
    input   arlock;
    input   arprot;
    input   arqos;
    output  arready;
    input   arregion;
    input   arsize;
    input   arvalid;
    input   awaddr;
    input   awburst;
    input   awcache;
    input   awlen;
    input   awlock;
    input   awprot;
    input   awqos;
    output  awready;
    input   awregion;
    input   awsize;
    input   awvalid;
    input   bready;
    output  bid;
    output  bresp;
    output  bvalid;
    output  rdata;
    output  rid;
    output  rlast;
    input   rready;
    output  rresp;
    output  rvalid;
    input   wdata;
    input   wid;
    input   wlast;
    output  wready;
    input   wstrb;
    input   wvalid;
    input   aresetn;
    input   aclk;
  endclocking


  // --------------------------------------------------------------------
  //
  assign arid           = axi4_m.arid;
  assign araddr         = axi4_m.araddr;
  assign arburst        = axi4_m.arburst;
  assign arcache        = axi4_m.arcache;
  assign awid           = axi4_m.awid;
  assign arlen          = axi4_m.arlen;
  assign arlock         = axi4_m.arlock;
  assign arprot         = axi4_m.arprot;
  assign arqos          = axi4_m.arqos;
  assign axi4_m.arready = arready;
  assign arregion       = axi4_m.arregion;
  assign arsize         = axi4_m.arsize;
  assign arvalid        = axi4_m.arvalid;
  assign awaddr         = axi4_m.awaddr;
  assign awburst        = axi4_m.awburst;
  assign awcache        = axi4_m.awcache;
  assign awlen          = axi4_m.awlen;
  assign awlock         = axi4_m.awlock;
  assign awprot         = axi4_m.awprot;
  assign awqos          = axi4_m.awqos;
  assign axi4_m.awready = awready;
  assign awregion       = axi4_m.awregion;
  assign awsize         = axi4_m.awsize;
  assign awvalid        = axi4_m.awvalid;
  assign bready         = axi4_m.bready;
  assign axi4_m.bid     = bid;
  assign axi4_m.bresp   = bresp;
  assign axi4_m.bvalid  = bvalid;
  assign axi4_m.rdata   = rdata;
  assign axi4_m.rid     = rid;
  assign axi4_m.rlast   = rlast;
  assign rready         = axi4_m.rready;
  assign axi4_m.rresp   = rresp;
  assign axi4_m.rvalid  = rvalid;
  assign wdata          = axi4_m.wdata;
  assign wlast          = axi4_m.wlast;
  assign axi4_m.wready  = wready;
  assign wstrb          = axi4_m.wstrb;
  assign wvalid         = axi4_m.wvalid;


  // --------------------------------------------------------------------
  //
  function void
    ar_default;

    cb.arready <= 0;

  endfunction: ar_default


  // --------------------------------------------------------------------
  //
  function void
    aw_default;

    cb.awready <= 0;

  endfunction: aw_default


  // --------------------------------------------------------------------
  //
  function void
    r_default;

    cb.rdata  <= 'bx;
    cb.rid    <= 'bx;
    cb.rlast  <= 'bx;
    cb.rresp  <= 0;
    cb.rvalid <= 0;

  endfunction: r_default


  // --------------------------------------------------------------------
  //
  function void
    w_default;

    cb.wready  <= 0;

  endfunction: w_default


  // --------------------------------------------------------------------
  //
  function void
    b_default;

    cb.bid     <= 0;
    cb.bresp   <= 0;
    cb.bvalid  <= 0;

  endfunction: b_default


  // --------------------------------------------------------------------
  //
  function void
    init;

    ar_default();
    r_default();
    aw_default();
    w_default();
    b_default();

  endfunction: init


  // --------------------------------------------------------------------
  //
  task
    zero_cycle_delay;

    ##0;

  endtask: zero_cycle_delay


  // --------------------------------------------------------------------
  //
  import tb_bfm_pkg::*;
  import axi4_transaction_pkg::*;


  // --------------------------------------------------------------------
  //
  class r_slave_transaction_class #(A = 32, N = 8, I = 1)
    extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));

    // --------------------------------------------------------------------
    //
    task automatic
      transaction
      (
        ref T tr_h
      );

      ->this.start;

      foreach(tr_h.payload_h.w[i])
      begin
        ##(tr_h.delay_h.next());

        cb.rdata   <= tr_h.payload_h.w[i];
        cb.rresp   <= tr_h.resp;
        cb.rid     <= tr_h.id;

        if(i < tr_h.payload_h.w.size - 1)
          cb.rlast   <= 0;
        else
          cb.rlast   <= 1;

        cb.rvalid  <= 1;
        ##1;

        wait(cb.rready);
        ##0;

        $display("^^^ %16.t | %m   | slave R transaction  | %d | 0x%016x |", $time, i, tr_h.payload_h.w[i]);
        r_default();
      end

      ->this.done;

    endtask: transaction


  // --------------------------------------------------------------------
  //
  endclass: r_slave_transaction_class


  // --------------------------------------------------------------------
  //
  r_slave_transaction_class #(.A(A), .N(N), .I(I)) r_h;

  class ar_slave_transaction_class #(A = 32, N = 8, I = 1)
    extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));

    // --------------------------------------------------------------------
    //
    task automatic
      transaction
      (
        ref T tr_h
      );

      ->this.start;

      ##(tr_h.delay_h.next());

      cb.arready  <= 1;
      ##1;

      wait(cb.arvalid);

      ##0;
      r_h.put(tr_h);
      ar_default();

      $display("^^^ %16.t | %m   | slave AR transaction @ 0x%08x  | 0x%016x |", $time, tr_h.addr, tr_h.payload_h.w[0]);

      ->this.done;

    endtask: transaction


  // --------------------------------------------------------------------
  //
  endclass: ar_slave_transaction_class


  // --------------------------------------------------------------------
  //
  class aw_slave_transaction_class #(A = 32, N = 8, I = 1)
    extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));

    semaphore aw_semaphore;


    //--------------------------------------------------------------------
    function new;

      super.new();
      this.aw_semaphore = new(0);

    endfunction: new


    // --------------------------------------------------------------------
    //
    task automatic
      transaction
      (
        ref T tr_h
      );

      ->this.start;

      ##(tr_h.delay_h.next());

      cb.awready  <= 1;
      ##1;

      wait(cb.awvalid);

      ##0;
      this.aw_semaphore.put();
      aw_default();

      $display("^^^ %16.t | %m   | slave AW transaction @ 0x%08x  | 0x%016x |", $time, tr_h.addr, tr_h.payload_h.w[0]);

      ->this.done;

    endtask: transaction

  // --------------------------------------------------------------------
  //
  endclass: aw_slave_transaction_class


  // --------------------------------------------------------------------
  //
  aw_slave_transaction_class #(.A(A), .N(N), .I(I)) aw_h;

  class b_slave_transaction_class #(A = 32, N = 8, I = 1)
    extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));

    // --------------------------------------------------------------------
    //
    task automatic
      transaction
      (
        ref T tr_h
      );

      ->this.start;

      // Error: AXI4_ERRS_BRESP_AW: A slave must not give a write response before the write address.
      //        Spec: section A3.3.1 and figure A3-7.
      aw_h.aw_semaphore.get();  // better way to do this???

      ##(tr_h.delay_h.next());

      cb.bresp   <= tr_h.resp;
      cb.bid     <= tr_h.id;

      cb.bvalid  <= 1;
      ##1;

      wait(cb.bready);
      ##0;

      $display("^^^ %16.t | %m | slave B transaction  |", $time);
      b_default();

      ->this.done;

    endtask: transaction

  // --------------------------------------------------------------------
  //
  endclass: b_slave_transaction_class


  // --------------------------------------------------------------------
  //
  b_slave_transaction_class #(.A(A), .N(N), .I(I)) b_h;

  class w_slave_transaction_class #(A = 32, N = 8, I = 1)
    extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));

    // --------------------------------------------------------------------
    //
    task automatic
      transaction
      (
        ref T tr_h
      );

      ->this.start;

      tr_h.data_h = new(tr_h.len);

      foreach(tr_h.payload_h.w[i])
      begin
        ##(tr_h.delay_h.next());

        cb.wready  <= 1;
        ##1;

        wait(cb.wvalid);
        ##0;

        tr_h.data_h.w[i] <= cb.wdata;
        $display("^^^ %16.t | %m   | slave W transaction  | %d | 0x%016x |", $time, i, cb.wdata);
        w_default();
      end

      b_h.put(tr_h);

      ->this.done;

    endtask: transaction


  // --------------------------------------------------------------------
  //
  endclass: w_slave_transaction_class


  // --------------------------------------------------------------------
  //
  ar_slave_transaction_class #(.A(A), .N(N), .I(I)) ar_h;
  w_slave_transaction_class #(.A(A), .N(N), .I(I)) w_h;

  initial
  begin
    init();
    ar_h = new;
    ar_h.init();
    r_h = new;
    r_h.init();
    aw_h = new;
    aw_h.init();
    w_h = new;
    w_h.init();
    b_h = new;
    b_h.init();
  end


// --------------------------------------------------------------------
//

endinterface


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.