mempool_cluster.sv 14.1 KB
Newer Older
sakundu committed
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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
// Copyright 2021 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51

module mempool_cluster
  import mempool_pkg::*;
  import cf_math_pkg::idx_width;
#(
  // TCDM
  parameter addr_t       TCDMBaseAddr  = 32'b0,
  // Boot address
  parameter logic [31:0] BootAddr      = 32'h0000_0000,
  // Dependant parameters. DO NOT CHANGE!
  parameter int unsigned NumAXIMasters = NumGroups
) (
  // Clock and reset
  input  logic                               clk_i,
  input  logic                               rst_ni,
  input  logic                               testmode_i,
  // Scan chain
  input  logic                               scan_enable_i,
  input  logic                               scan_data_i,
  output logic                               scan_data_o,
  // Wake up signal
  input  logic           [NumCores-1:0]      wake_up_i,
  // AXI Interface
  output axi_tile_req_t  [NumAXIMasters-1:0] axi_mst_req_o,
  input  axi_tile_resp_t [NumAXIMasters-1:0] axi_mst_resp_i
);

  /************
   *  Groups  *
   ************/

  // TCDM interfaces
  // North
  tcdm_slave_req_t   [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_north_req;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_north_req_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_north_req_ready;
  tcdm_master_resp_t [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_north_resp;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_north_resp_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_north_resp_ready;
  tcdm_slave_req_t   [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_north_req;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_north_req_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_north_req_ready;
  tcdm_master_resp_t [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_north_resp;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_north_resp_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_north_resp_ready;
  // East
  tcdm_slave_req_t   [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_east_req;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_east_req_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_east_req_ready;
  tcdm_master_resp_t [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_east_resp;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_east_resp_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_east_resp_ready;
  tcdm_slave_req_t   [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_east_req;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_east_req_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_east_req_ready;
  tcdm_master_resp_t [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_east_resp;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_east_resp_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_east_resp_ready;
  // Northeast
  tcdm_slave_req_t   [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_northeast_req;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_northeast_req_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_northeast_req_ready;
  tcdm_master_resp_t [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_northeast_resp;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_northeast_resp_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_northeast_resp_ready;
  tcdm_slave_req_t   [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_northeast_req;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_northeast_req_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_northeast_req_ready;
  tcdm_master_resp_t [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_northeast_resp;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_northeast_resp_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_northeast_resp_ready;
  // Bypass
  tcdm_slave_req_t   [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_bypass_req;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_bypass_req_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_bypass_req_ready;
  tcdm_master_resp_t [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_bypass_resp;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_bypass_resp_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_master_bypass_resp_ready;
  tcdm_slave_req_t   [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_bypass_req;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_bypass_req_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_bypass_req_ready;
  tcdm_master_resp_t [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_bypass_resp;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_bypass_resp_valid;
  logic              [NumGroups-1:0][NumTilesPerGroup-1:0] tcdm_slave_bypass_resp_ready;

  for (genvar g = 0; unsigned'(g) < NumGroups; g++) begin: gen_groups
    mempool_group #(
      .TCDMBaseAddr(TCDMBaseAddr),
      .BootAddr    (BootAddr    )
    ) i_group (
      .clk_i                             (clk_i                                            ),
      .rst_ni                            (rst_ni                                           ),
      .testmode_i                        (testmode_i                                       ),
      .scan_enable_i                     (scan_enable_i                                    ),
      .scan_data_i                       (/* Unconnected */                                ),
      .scan_data_o                       (/* Unconnected */                                ),
      .group_id_i                        (g[idx_width(NumGroups)-1:0]                      ),
      // TCDM Master interfaces
      .tcdm_master_north_req_o           (tcdm_master_north_req[g]                         ),
      .tcdm_master_north_req_valid_o     (tcdm_master_north_req_valid[g]                   ),
      .tcdm_master_north_req_ready_i     (tcdm_master_north_req_ready[g]                   ),
      .tcdm_master_north_resp_i          (tcdm_master_north_resp[g]                        ),
      .tcdm_master_north_resp_valid_i    (tcdm_master_north_resp_valid[g]                  ),
      .tcdm_master_north_resp_ready_o    (tcdm_master_north_resp_ready[g]                  ),
      .tcdm_master_east_req_o            (tcdm_master_east_req[g]                          ),
      .tcdm_master_east_req_valid_o      (tcdm_master_east_req_valid[g]                    ),
      .tcdm_master_east_req_ready_i      (tcdm_master_east_req_ready[g]                    ),
      .tcdm_master_east_resp_i           (tcdm_master_east_resp[g]                         ),
      .tcdm_master_east_resp_valid_i     (tcdm_master_east_resp_valid[g]                   ),
      .tcdm_master_east_resp_ready_o     (tcdm_master_east_resp_ready[g]                   ),
      .tcdm_master_northeast_req_o       (tcdm_master_northeast_req[g]                     ),
      .tcdm_master_northeast_req_valid_o (tcdm_master_northeast_req_valid[g]               ),
      .tcdm_master_northeast_req_ready_i (tcdm_master_northeast_req_ready[g]               ),
      .tcdm_master_northeast_resp_i      (tcdm_master_northeast_resp[g]                    ),
      .tcdm_master_northeast_resp_valid_i(tcdm_master_northeast_resp_valid[g]              ),
      .tcdm_master_northeast_resp_ready_o(tcdm_master_northeast_resp_ready[g]              ),
      .tcdm_master_bypass_req_o          (tcdm_master_bypass_req[g]                        ),
      .tcdm_master_bypass_req_valid_o    (tcdm_master_bypass_req_valid[g]                  ),
      .tcdm_master_bypass_req_ready_i    (tcdm_master_bypass_req_ready[g]                  ),
      .tcdm_master_bypass_resp_i         (tcdm_master_bypass_resp[g]                       ),
      .tcdm_master_bypass_resp_valid_i   (tcdm_master_bypass_resp_valid[g]                 ),
      .tcdm_master_bypass_resp_ready_o   (tcdm_master_bypass_resp_ready[g]                 ),
      // TCDM banks interface
      .tcdm_slave_north_req_i            (tcdm_slave_north_req[g]                          ),
      .tcdm_slave_north_req_valid_i      (tcdm_slave_north_req_valid[g]                    ),
      .tcdm_slave_north_req_ready_o      (tcdm_slave_north_req_ready[g]                    ),
      .tcdm_slave_north_resp_o           (tcdm_slave_north_resp[g]                         ),
      .tcdm_slave_north_resp_valid_o     (tcdm_slave_north_resp_valid[g]                   ),
      .tcdm_slave_north_resp_ready_i     (tcdm_slave_north_resp_ready[g]                   ),
      .tcdm_slave_east_req_i             (tcdm_slave_east_req[g]                           ),
      .tcdm_slave_east_req_valid_i       (tcdm_slave_east_req_valid[g]                     ),
      .tcdm_slave_east_req_ready_o       (tcdm_slave_east_req_ready[g]                     ),
      .tcdm_slave_east_resp_o            (tcdm_slave_east_resp[g]                          ),
      .tcdm_slave_east_resp_valid_o      (tcdm_slave_east_resp_valid[g]                    ),
      .tcdm_slave_east_resp_ready_i      (tcdm_slave_east_resp_ready[g]                    ),
      .tcdm_slave_northeast_req_i        (tcdm_slave_northeast_req[g]                      ),
      .tcdm_slave_northeast_req_valid_i  (tcdm_slave_northeast_req_valid[g]                ),
      .tcdm_slave_northeast_req_ready_o  (tcdm_slave_northeast_req_ready[g]                ),
      .tcdm_slave_northeast_resp_o       (tcdm_slave_northeast_resp[g]                     ),
      .tcdm_slave_northeast_resp_valid_o (tcdm_slave_northeast_resp_valid[g]               ),
      .tcdm_slave_northeast_resp_ready_i (tcdm_slave_northeast_resp_ready[g]               ),
      .tcdm_slave_bypass_req_i           (tcdm_slave_bypass_req[g]                         ),
      .tcdm_slave_bypass_req_valid_i     (tcdm_slave_bypass_req_valid[g]                   ),
      .tcdm_slave_bypass_req_ready_o     (tcdm_slave_bypass_req_ready[g]                   ),
      .tcdm_slave_bypass_resp_o          (tcdm_slave_bypass_resp[g]                        ),
      .tcdm_slave_bypass_resp_valid_o    (tcdm_slave_bypass_resp_valid[g]                  ),
      .tcdm_slave_bypass_resp_ready_i    (tcdm_slave_bypass_resp_ready[g]                  ),
      .wake_up_i                         (wake_up_i[g*NumCoresPerGroup +: NumCoresPerGroup]),
      // AXI interface
      .axi_mst_req_o                     (axi_mst_req_o[g]                                 ),
      .axi_mst_resp_i                    (axi_mst_resp_i[g]                                )
   );
  end : gen_groups

  /*******************
   *  Interconnects  *
   *******************/

  for (genvar ini = 0; ini < NumGroups; ini++) begin: gen_interconnections
    // East
    assign tcdm_slave_east_req[ini ^ 2'b01]       = tcdm_master_east_req[ini];
    assign tcdm_slave_east_req_valid[ini ^ 2'b01] = tcdm_master_east_req_valid[ini];
    assign tcdm_master_east_req_ready[ini]        = tcdm_slave_east_req_ready[ini ^ 2'b01];

    assign tcdm_master_east_resp[ini ^ 2'b01]       = tcdm_slave_east_resp[ini];
    assign tcdm_master_east_resp_valid[ini ^ 2'b01] = tcdm_slave_east_resp_valid[ini];
    assign tcdm_slave_east_resp_ready[ini]          = tcdm_master_east_resp_ready[ini ^ 2'b01];

    // North
    assign tcdm_slave_north_req[ini ^ 2'b10]       = tcdm_master_north_req[ini];
    assign tcdm_slave_north_req_valid[ini ^ 2'b10] = tcdm_master_north_req_valid[ini];
    assign tcdm_master_north_req_ready[ini]        = tcdm_slave_north_req_ready[ini ^ 2'b10];

    assign tcdm_master_north_resp[ini ^ 2'b10]       = tcdm_slave_north_resp[ini];
    assign tcdm_master_north_resp_valid[ini ^ 2'b10] = tcdm_slave_north_resp_valid[ini];
    assign tcdm_slave_north_resp_ready[ini]          = tcdm_master_north_resp_ready[ini ^ 2'b10];

    // Northeast

    // First north, then east
    assign tcdm_slave_bypass_req[ini ^ 2'b10]           = tcdm_master_northeast_req[ini];
    assign tcdm_slave_northeast_req[ini ^ 2'b11]        = tcdm_master_bypass_req[ini ^ 2'b10];
    assign tcdm_slave_bypass_req_valid[ini ^ 2'b10]     = tcdm_master_northeast_req_valid[ini];
    assign tcdm_slave_northeast_req_valid[ini ^ 2'b11]  = tcdm_master_bypass_req_valid[ini ^ 2'b10];
    assign tcdm_master_bypass_req_ready[ini ^ 2'b10]    = tcdm_slave_northeast_req_ready[ini ^ 2'b11];
    assign tcdm_master_northeast_req_ready[ini]         = tcdm_slave_bypass_req_ready[ini ^ 2'b10];

    // First east, then north
    assign tcdm_master_northeast_resp[ini]              = tcdm_slave_bypass_resp[ini ^ 2'b10];
    assign tcdm_master_bypass_resp[ini ^ 2'b10]         = tcdm_slave_northeast_resp[ini ^ 2'b11];
    assign tcdm_master_northeast_resp_valid[ini]        = tcdm_slave_bypass_resp_valid[ini ^ 2'b10];
    assign tcdm_master_bypass_resp_valid[ini ^ 2'b10]   = tcdm_slave_northeast_resp_valid[ini ^ 2'b11];
    assign tcdm_slave_bypass_resp_ready[ini ^ 2'b10]    = tcdm_master_northeast_resp_ready[ini];
    assign tcdm_slave_northeast_resp_ready[ini ^ 2'b11] = tcdm_master_bypass_resp_ready[ini ^ 2'b10];
  end: gen_interconnections

  /****************
   *  Assertions  *
   ****************/

  if (NumCores > 1024)
    $fatal(1, "[mempool] MemPool is currently limited to 1024 cores.");

  if (NumTiles < NumGroups)
    $fatal(1, "[mempool] MemPool requires more tiles than groups.");

  if (NumCores != NumTiles * NumCoresPerTile)
    $fatal(1, "[mempool] The number of cores is not divisible by the number of cores per tile.");

  if (BankingFactor < 1)
    $fatal(1, "[mempool] The banking factor must be a positive integer.");

  if (BankingFactor != 2**$clog2(BankingFactor))
    $fatal(1, "[mempool] The banking factor must be a power of two.");

  if (NumGroups != 4)
    $fatal(1, "[mempool] This version of the MemPool cluster only works with four groups.");

endmodule : mempool_cluster