// 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