`ifndef _AXI4_INTERFACE_
`define _AXI4_INTERFACE_
`timescale 1ns/1ps

interface axi4_interface (input logic ACLK, ARESETn);
  //AW Channel
  wire[31:0]   AWADDR;
  wire[7:0]    AWLEN;
  wire[2:0]    AWSIZE;
  wire[1:0]    AWBURST;  
  wire         AWREADY;
  wire         AWVALID;
  wire[3:0]    AWID;
  wire[2:0]    AWPROT;
  wire[3:0]    AWCACHE;
  wire[3:0]    AWQOS;
  wire[3:0]    AWREGION;
  logic[7:0]   AWUSER;
  wire	       AWLOCK;
  //W channel
  wire[31:0]   WDATA;
  wire         WVALID;
  wire         WREADY;
  wire[3:0]    WSTRB;
  wire         WLAST;
  logic[7:0]   WUSER;
  //B Channel
  wire         BREADY;
  wire         BVALID;
  wire [1:0]   BRESP;
  logic[3:0]   BID;
  logic[7:0]   BUSER;
  //AR channel
  wire         ARVALID;
  wire         ARREADY;
  wire[31:0]   ARADDR;
  wire[7:0]    ARLEN;
  wire[2:0]    ARSIZE;
  wire[1:0]    ARBURST;
  wire[3:0]    ARID;
  wire[2:0]    ARPROT;
  wire[3:0]    ARCACHE;
  wire[3:0]    ARREGION;
  wire[3:0]    ARQOS;
  logic[7:0]   ARUSER;
  wire	       ARLOCK;
  //R Channel
  wire         RVALID;
  wire         RREADY;
  wire[31:0]   RDATA;
  wire[1:0]    RRESP;
  logic[3:0]   RID;
  wire         RLAST;
  logic[7:0]   RUSER;

  clocking master_cb @(posedge ACLK);
    default input #1 output #1;
    //AW
    output AWADDR;
    output AWLEN;
    output AWSIZE;
    output AWBURST;
    output AWID;
    output AWPROT;
    output AWCACHE;
    output AWREGION;
    output AWQOS;
    output AWUSER;
    output AWVALID;
    output AWLOCK;
    input  AWREADY;
    //W
    output WDATA;
    output WVALID;
    input  WREADY;
    output WSTRB;
    output WLAST;
    output WUSER;
    //B
    output BREADY;
    input  BVALID;
    input  BRESP;
    input  BID;
    input  BUSER;
    //ar
    output ARADDR;
    output ARLEN;
    output ARSIZE;
    output ARBURST;
    output ARID;
    output ARVALID;
    output ARCACHE;
    output ARQOS;
    output ARPROT;
    output ARREGION;
    output ARUSER;
    output ARLOCK;
    input  ARREADY;
    //R
    input  RVALID;
    output RREADY;
    input  RDATA;
    input  RRESP;
    input  RID;
    input  RLAST;
    input  RUSER;

  endclocking
  
  clocking slave_cb @(posedge ACLK);
    default input #1 output #1;
    //AW
    input AWADDR;
    input AWLEN;
    input AWSIZE;
    input AWBURST;
    input AWID;
    input AWPROT;
    input AWCACHE;
    input AWREGION;
    input AWQOS;
    input AWUSER;
    input AWVALID;
    input AWLOCK;
    output   AWREADY;
    //W
    input WDATA;
    input WVALID;
    input WSTRB;
    input WLAST;
    input WUSER;
    output  WREADY;
    //B
    input BREADY;
    output  BVALID;
    output  BRESP;
    output  BID;
    output  BUSER;
    //ar
    input ARADDR;
    input ARLEN;
    input ARSIZE;
    input ARBURST;
    input ARID;
    input ARVALID;
    input ARCACHE;
    input ARQOS;
    input ARPROT;
    input ARREGION;
    input ARUSER;
    input ARLOCK;
    output  ARREADY;
    //R
    output  RVALID;
    output  RDATA;
    output  RRESP;
    output  RID;
    output  RLAST;
    output  RUSER;
    input RREADY;

  endclocking

  clocking monitor_cb @(posedge ACLK);
    default input #1 output #1;
    //AW
    input AWADDR;
    input AWLEN;
    input AWSIZE;
    input AWBURST;
    input AWID;
    input AWPROT;
    input AWCACHE;
    input AWREGION;
    input AWQOS;
    input AWUSER;
    input AWVALID;
    input AWLOCK;
    input AWREADY;
    //W
    input WDATA;
    input WVALID;
    input WSTRB;
    input WLAST;
    input WUSER;
    input WREADY;
    //B
    input BREADY;
    input BVALID;
    input BRESP;
    input BID;
    input BUSER;
    //ar
    input ARADDR;
    input ARLEN;
    input ARSIZE;
    input ARBURST;
    input ARID;
    input ARVALID;
    input ARCACHE;
    input ARQOS;
    input ARPROT;
    input ARREGION;
    input ARUSER;
    input ARLOCK;
    input ARREADY;
    //R
    input RVALID;
    input RDATA;
    input RRESP;
    input RID;
    input RLAST;
    input RUSER;
    input RREADY;

  endclocking


  modport MASTER_DRIVER (clocking master_cb, input ACLK, ARESETn);
  modport SLAVE_DRIVER (clocking slave_cb, input ACLK, ARESETn);
  modport MONITOR (clocking monitor_cb, input ACLK, ARESETn);



endinterface
`endif
