reqrsp_intf.sv 4.15 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
// Copyright 2020 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51

// Fabian Schuiki <fschuiki@iis.ee.ethz.ch>

/// A simple two channel interface.
///
/// This interface provides two channels, one for requests and one for
/// responses. Both channels have a valid/ready handshake. The sender sets the
/// channel signals and pulls valid high. Once pulled high, valid must remain
/// high and none of the signals may change. The transaction completes when both
/// valid and ready are high. Valid must not depend on ready. The master can
/// request a read or write on the `q` channel. The slave responds on the `p`
/// channel once the action has been completed. Every transaction returns a
/// response. For write transaction the datum on the response channel is
/// invalid. For read and atomic transaction the value corresponds to the
/// un-modified value (the value read before an operation was performed).For
/// further details see docs/index.md

interface REQRSP_BUS #(
  /// The width of the address.
  parameter int ADDR_WIDTH = -1,
  /// The width of the data.
  parameter int DATA_WIDTH = -1
);

  import reqrsp_pkg::*;

  localparam int unsigned StrbWidth = DATA_WIDTH / 8;

  typedef logic [ADDR_WIDTH-1:0] addr_t;
  typedef logic [DATA_WIDTH-1:0] data_t;
  typedef logic [StrbWidth-1:0] strb_t;
  /// The request channel (Q).
  addr_t   q_addr;
  /// 0 = read, 1 = write, 1 = amo fetch-and-op
  logic    q_write;
  amo_op_e q_amo;
  data_t   q_data;
  /// Byte-wise strobe
  strb_t   q_strb;
  size_t   q_size;
  logic    q_valid;
  logic    q_ready;

  /// The response channel (P).
  data_t   p_data;
  /// 0 = ok, 1 = error
  logic    p_error;
  logic    p_valid;
  logic    p_ready;


  modport in  (
    input  q_addr, q_write, q_amo, q_size, q_data, q_strb, q_valid, p_ready,
    output q_ready, p_data, p_error, p_valid
  );
  modport out (
    output q_addr, q_write, q_amo, q_size, q_data, q_strb, q_valid, p_ready,
    input  q_ready, p_data, p_error, p_valid
  );

endinterface

// The DV interface additionally caries a clock signal.
interface REQRSP_BUS_DV #(
  /// The width of the address.
  parameter int ADDR_WIDTH = -1,
  /// The width of the data.
  parameter int DATA_WIDTH = -1
) (
  input logic clk_i
);

  import reqrsp_pkg::*;

  localparam int unsigned StrbWidth = DATA_WIDTH / 8;

  typedef logic [ADDR_WIDTH-1:0] addr_t;
  typedef logic [DATA_WIDTH-1:0] data_t;
  typedef logic [StrbWidth-1:0] strb_t;
  /// The request channel (Q).
  addr_t   q_addr;
  /// 0 = read, 1 = write, 1 = amo fetch-and-op
  logic    q_write;
  amo_op_e q_amo;
  data_t   q_data;
  /// Byte-wise strobe
  strb_t   q_strb;
  size_t   q_size;
  logic    q_valid;
  logic    q_ready;

  /// The response channel (P).
  data_t   p_data;
  /// 0 = ok, 1 = error
  logic    p_error;
  logic    p_valid;
  logic    p_ready;

  modport in  (
    input  q_addr, q_write, q_amo, q_size, q_data, q_strb, q_valid, p_ready,
    output q_ready, p_data, p_error, p_valid
  );
  modport out (
    output q_addr, q_write, q_amo, q_size, q_data, q_strb, q_valid, p_ready,
    input  q_ready, p_data, p_error, p_valid
  );
  modport monitor (
    input q_addr, q_write, q_amo, q_size, q_data, q_strb, q_valid, p_ready,
          q_ready, p_data, p_error, p_valid
  );

  // pragma translate_off
  `ifndef VERILATOR
  assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_addr)));
  assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_write)));
  assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_amo)));
  assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_size)));
  assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_data)));
  assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_strb)));
  assert property (@(posedge clk_i) (q_valid && !q_ready |=> q_valid));

  assert property (@(posedge clk_i) (p_valid && !p_ready |=> $stable(p_data)));
  assert property (@(posedge clk_i) (p_valid && !p_ready |=> $stable(p_error)));
  assert property (@(posedge clk_i) (p_valid && !p_ready |=> p_valid));
  `endif
  // pragma translate_on

endinterface