From c85539c4e5926f3c82ca84f3654969afcb05b1c5 Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Tue, 31 Oct 2023 11:37:41 +0100 Subject: [PATCH 1/3] Add stream modules for gearing --- Bender.yml | 2 ++ src/geared_stream_collect.sv | 67 ++++++++++++++++++++++++++++++++++++ src/geared_stream_split.sv | 61 ++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 src/geared_stream_collect.sv create mode 100644 src/geared_stream_split.sv diff --git a/Bender.yml b/Bender.yml index c65d197..3b147d5 100644 --- a/Bender.yml +++ b/Bender.yml @@ -16,6 +16,8 @@ dependencies: sources: # Level 0 + - src/geared_stream_collect.sv + - src/geared_stream_split.sv - src/mem_req_multicut.sv - src/mem_rsp_multicut.sv - src/stream_mem_to_banks_det.sv diff --git a/src/geared_stream_collect.sv b/src/geared_stream_collect.sv new file mode 100644 index 0000000..76cf904 --- /dev/null +++ b/src/geared_stream_collect.sv @@ -0,0 +1,67 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +// Michael Rogenmoser + +`include "common_cells/registers.svh" + +module geared_stream_collect #( + parameter int unsigned GearRatio = 1, + parameter type T = logic // Vivado requires a default value for type parameters. +) ( + input logic clk_i, // Clock + input logic geared_clk_i, // Geared Clock + input logic rst_ni, // Asynchronous active-low reset + input logic clr_i, // Synchronous clear + // Input port + input logic [GearRatio-1:0] valid_i, + output logic [GearRatio-1:0] ready_o, + input T [GearRatio-1:0] data_i, + // Output port + output logic valid_o, + input logic ready_i, + output T data_o, + input logic [GearRatio-1:0] selected_reg_i +); + + if (GearRatio < 1) begin + $fatal(1, "Gear Ratio < 1 not supported!"); + end else if (GearRatio == 1) begin + assign valid_o = valid_i; + assign ready_o = ready_i; + assign data_o = data_i; + end else begin + logic last_cycle_in_gear; + + logic [GearRatio-1:0] valid_in_d, valid_in_q; + logic [GearRatio-1:0] ready_out_d, ready_out_q, ready_out_tmp; + + T [GearRatio-1:0] data_out; + logic [$clog2(GearRatio)-1:0] sel_reg; + + assign valid_o = |(valid_in_q & selected_reg_i); + + onehot_to_bin #( + .ONEHOT_WIDTH(GearRatio) + ) i_selected_reg ( + .onehot ( selected_reg_i ), + .bin ( sel_reg ) + ); + assign data_o = data_out[sel_reg]; + + assign ready_o = ready_out_q | ready_out_tmp; + + for (genvar i = 0; i < GearRatio; i++) begin + + assign valid_in_d[i] = last_cycle_in_gear ? valid_i[i] : 1'b0; + assign ready_out_d[i] = last_cycle_in_gear ? 1'b0 : (ready_out_tmp | ready_out_q); + assign ready_out_tmp[i] = selected_reg_i == i ? ready_i : 1'b0; + + `FFLARNC(ready_out_q[i], ready_out_d[i], 1'b1, clr_i, 1'b0, clk_i, rst_ni) + `FFLARNC(valid_in_q[i], valid_in_d[i], last_cycle_in_gear || (selected_reg_i[i] && ready_i), clr_i, 1'b0, clk_i, rst_ni) + `FFLARNC(data_out[i], data_i[i], last_cycle_in_gear & valid_i[i] & ready_o[i], clr_i, '0, clk_i, rst_ni) + end + end + +endmodule diff --git a/src/geared_stream_split.sv b/src/geared_stream_split.sv new file mode 100644 index 0000000..beca189 --- /dev/null +++ b/src/geared_stream_split.sv @@ -0,0 +1,61 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +// Michael Rogenmoser + +`include "common_cells/registers.svh" + +module geared_stream_split #( + parameter int unsigned GearRatio = 1, + parameter type T = logic // Vivado requires a default value for type parameters. +) ( + input logic clk_i, // Clock + input logic geared_clk_i, // Geared Clock + input logic rst_ni, // Asynchronous active-low reset + input logic clr_i, // Synchronous clear + // Input port + input logic valid_i, + output logic ready_o, + input T data_i, + output logic [GearRatio-1:0] selected_reg_o, + // Output port + output logic [GearRatio-1:0] valid_o, + input logic [GearRatio-1:0] ready_i, + output T [GearRatio-1:0] data_o +); + + if (GearRatio < 1) begin + $fatal(1, "Gear Ratio < 1 not supported!"); + end else if (GearRatio == 1) begin + assign valid_o = valid_i; + assign ready_o = ready_i; + assign data_o = data_i; + assign selected_reg_o = 1'b1; + end else begin + logic [GearRatio-1:0] reg_active_d, reg_active; + logic [GearRatio-1:0] ready_out; + logic [GearRatio-1:0] reg_ena; + + // reg_active is high for one cycle for each position during a full geared_clk cycle + assign reg_active_d[GearRatio-1:1] = reg_active[GearRatio-2:0]; + assign reg_active_d[0] = reg_active[GearRatio-1]; + + `FF(reg_active, reg_active_d, {{(GearRatio-1){1'b0}}, 1'b1}, clk_i, rst_ni) + + assign selected_reg_o = reg_active; + + assign ready_o = |ready_out; + + for (genvar i = 0; i < GearRatio; i++) begin + + assign ready_out[i] = (ready_i[i] | ~valid_o[i]) & reg_active[i]; + assign reg_ena[i] = valid_i & ready_out[i]; + + // only active once during each geared_clk cycle + `FFLARNC(valid_o[i], valid_i, ready_out[i], clr_i, 1'b0, clk_i, rst_ni) + `FFLARNC(data_o[i], data_i, reg_ena[i], clr_i, '0, clk_i, rst_ni) + end + end + +endmodule From 024aba67af4675a30ac50f4f3d6bf63ba83637d1 Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Tue, 23 Jul 2024 18:41:49 +0200 Subject: [PATCH 2/3] WIP: geared island --- src/geared_memory_island.sv | 273 ++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 src/geared_memory_island.sv diff --git a/src/geared_memory_island.sv b/src/geared_memory_island.sv new file mode 100644 index 0000000..43c6da5 --- /dev/null +++ b/src/geared_memory_island.sv @@ -0,0 +1,273 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +// Michael Rogenmoser + +module geared_memory_island #( + /// Address Width + parameter int unsigned AddrWidth = 0, + /// Data Width for the Narrow Ports + parameter int unsigned NarrowDataWidth = 0, + /// Data Width for the Wide Ports + parameter int unsigned WideDataWidth = 0, + + /// Number of Narrow Ports + parameter int unsigned NumNarrowReq = 0, + /// Number of Wide Ports + parameter int unsigned NumWideReq = 0, + + /// Banking Factor for the Wide Ports (power of 2) + parameter int unsigned NumWideBanks = (1<<$clog2(NumWideReq))*2, + /// Extra multiplier for the Narrow banking factor (baseline is WideWidth/NarrowWidth) (power of 2) + parameter int unsigned NarrowExtraBF = 1, + /// Words per memory bank. (Total number of banks is (WideWidth/NarrowWidth)*NumWideBanks) + parameter int unsigned WordsPerBank = 1024, + + parameter int unsigned GearRatio = 1, + + /// Spill Narrow + parameter int unsigned SpillNarrowReqEntry = 0, + parameter int unsigned SpillNarrowRspEntry = 0, + parameter int unsigned SpillNarrowReqRouted = 0, + parameter int unsigned SpillNarrowRspRouted = 0, + /// Spill Wide + parameter int unsigned SpillWideReqEntry = 0, + parameter int unsigned SpillWideRspEntry = 0, + parameter int unsigned SpillWideReqRouted = 0, + parameter int unsigned SpillWideRspRouted = 0, + parameter int unsigned SpillWideReqSplit = 0, + parameter int unsigned SpillWideRspSplit = 0, + /// Spill at Bank + parameter int unsigned SpillReqBank = 0, + parameter int unsigned SpillRspBank = 0, + + parameter MemorySimInit = "none", + + // Derived, DO NOT OVERRIDE + parameter int unsigned NarrowStrbWidth = NarrowDataWidth/8, + parameter int unsigned WideStrbWidth = WideDataWidth/8, + parameter int unsigned NWDivisor = WideDataWidth/NarrowDataWidth +) ( + input logic clk_i, + input logic rst_ni, + + // Narrow inputs + input logic [NumNarrowReq-1:0] narrow_req_i, + output logic [NumNarrowReq-1:0] narrow_gnt_o, + input logic [NumNarrowReq-1:0][ AddrWidth-1:0] narrow_addr_i, + input logic [NumNarrowReq-1:0] narrow_we_i, + input logic [NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_wdata_i, + input logic [NumNarrowReq-1:0][NarrowStrbWidth-1:0] narrow_strb_i, + output logic [NumNarrowReq-1:0] narrow_rvalid_o, + output logic [NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_rdata_o, + + // Wide inputs + input logic [ NumWideReq-1:0] wide_req_i, + output logic [ NumWideReq-1:0] wide_gnt_o, + input logic [ NumWideReq-1:0][ AddrWidth-1:0] wide_addr_i, + input logic [ NumWideReq-1:0] wide_we_i, + input logic [ NumWideReq-1:0][ WideDataWidth-1:0] wide_wdata_i, + input logic [ NumWideReq-1:0][ WideStrbWidth-1:0] wide_strb_i, + output logic [ NumWideReq-1:0] wide_rvalid_o, + output logic [ NumWideReq-1:0][ WideDataWidth-1:0] wide_rdata_o +); + + typedef struct packed { + logic [ AddrWidth-1:0] addr; + logic we; + logic [NarrowDataWidth-1:0] wdata; + logic [NarrowStrbWidth-1:0] strb; + } narrow_mem_req_t; + + typedef struct packed { + logic [ AddrWidth-1:0] addr; + logic we; + logic [WideDataWidth-1:0] wdata; + logic [WideStrbWidth-1:0] strb; + } wide_mem_req_t; + + logic geared_clk; + + narrow_mem_req_t [NumNarrowReq-1:0] narrow_mem_req; + narrow_mem_req_t [NumNarrowReq-1:0][GearRatio-1:0] narrow_mem_req_geared; + logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_req_geared; + logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_gnt_geared; + logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_rvalid_geared; + logic [NumNarrowReq-1:0][GearRatio-1:0][NarrowDataWidth-1:0] narrow_rdata_geared; + + logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_selected; + logic [NumNarrowReq-1:0][cf_math_pkg::idx_width(GearRatio)-1:0] narrow_selected_bin; + logic [NumNarrowReq-1:0][cf_math_pkg::idx_width(GearRatio)-1:0] narrow_selected_out; + + logic [GearRatio*NumNarrowReq-1:0] narrow_req_entry_geared; + logic [GearRatio*NumNarrowReq-1:0] narrow_gnt_entry_geared; + logic [GearRatio*NumNarrowReq-1:0][ AddrWidth-1:0] narrow_addr_entry_geared; + logic [GearRatio*NumNarrowReq-1:0] narrow_we_entry_geared; + logic [GearRatio*NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_wdata_entry_geared; + logic [GearRatio*NumNarrowReq-1:0][NarrowStrbWidth-1:0] narrow_strb_entry_geared; + logic [GearRatio*NumNarrowReq-1:0] narrow_rvalid_entry_geared; + logic [GearRatio*NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_rdata_entry_geared; + + wide_mem_req_t [NumWideReq-1:0] wide_mem_req; + wide_mem_req_t [NumWideReq-1:0][GearRatio-1:0] wide_mem_req_geared; + + logic [GearRatio* NumWideReq-1:0] wide_req_entry_geared; + logic [GearRatio* NumWideReq-1:0] wide_gnt_entry_geared; + logic [GearRatio* NumWideReq-1:0][ AddrWidth-1:0] wide_addr_entry_geared; + logic [GearRatio* NumWideReq-1:0] wide_we_entry_geared; + logic [GearRatio* NumWideReq-1:0][ WideDataWidth-1:0] wide_wdata_entry_geared; + logic [GearRatio* NumWideReq-1:0][ WideStrbWidth-1:0] wide_strb_entry_geared; + logic [GearRatio* NumWideReq-1:0] wide_rvalid_entry_geared; + logic [GearRatio* NumWideReq-1:0][ WideDataWidth-1:0] wide_rdata_entry_geared; + + clk_int_div #( + .DIV_VALUE_WIDTH ( $clog2(GearRatio) ), + .DEFAULT_DIV_VALUE ( GearRatio ), + .ENABLE_CLOCK_IN_RESET ( 1'b1 ) + ) i_gear_clk_div ( + .clk_i, + .rst_ni, + .en_i ( 1'b1 ), + .test_mode_en_i ( 1'b0 ), + .div_i ( GearRatio ), + .div_valid_i ( 1'b0 ), + .div_ready_o (), + .clk_o ( geared_clk ), + .cycl_count_o () + ); + + for (genvar i = 0; i < NumNarrowReq; i++) begin : gen_narrow_gearing + assign narrow_mem_req[i] = '{ + addr: narrow_addr_i [i], + we: narrow_we_i [i], + wdata: narrow_wdata_i [i], + strb: narrow_strb_i [i] + }; + + geared_stream_split #( + .GearRatio ( GearRatio ), + .T ( narrow_mem_req_t ) + ) i_gear_split ( + .clk_i, + .geared_clk_i ( geared_clk ), + .rst_ni, + .clr_i ( '0 ), + + .valid_i ( narrow_req_i [i] ), + .ready_o ( narrow_gnt_o [i] ), + .data_i ( narrow_mem_req [i] ), + .selected_reg_o ( narrow_selected [i] ), + + .valid_o ( narrow_req_geared [i] ), + .ready_i ( narrow_gnt_geared [i] ), + .data_o ( narrow_mem_req_geared[i] ) + ); + + for (genvar j = 0; j < GearRatio; j++) begin + localparam id = i*GearRatio + j; + assign narrow_req_entry_geared [id] = narrow_req_geared [i][j]; + assign narrow_gnt_geared [i][j] = narrow_gnt_entry_geared [id]; + assign narrow_addr_entry_geared [id] = narrow_mem_req_geared [i][j].addr; + assign narrow_we_entry_geared [id] = narrow_mem_req_geared [i][j].we; + assign narrow_wdata_entry_geared[id] = narrow_mem_req_geared [i][j].wdata; + assign narrow_strb_entry_geared [id] = narrow_mem_req_geared [i][j].strb; + assign narrow_rvalid_geared [i][j] = narrow_rvalid_entry_geared[id]; + assign narrow_rdata_geared [i][j] = narrow_rdata_entry_geared [id]; + end + + onehot_to_bin #( + .ONEHOT_WIDTH ( GearRatio ) + ) i_gear_to_bin ( + .onehot ( narrow_selected [i] ), + .bin ( narrow_selected_bin[i] ) + ); + + fifo_v3 #( + .FALL_THROUGH(1'b0), + .DATA_WIDTH ($clog2(GearRatio)), + .DEPTH () // TODO: NumOutstanding * GearRatio + ) i_selection_fifo ( + .clk_i, + .rst_ni, + .flush_i ('0), + .testmode_i(), + .full_o (), + .empty_o (), + .usage_o (), + .data_i ( narrow_selected_bin[i] ), + .push_i ( |narrow_selected [i] ), + .data_o ( narrow_selected_out[i] ), + .pop_i ( narrow_rvalid_o [i] ) + ); + + geared_stream_collect #( + .GearRatio ( GearRatio ), + .T ( logic [NarrowDataWidth-1:0] ) + ) i_gear_collect ( + .clk_i, + .geared_clk_i ( geared_clk ), + .rst_ni, + .clr_i ('0), + + .valid_i ( narrow_rvalid_geared [i] ), + .ready_o (), // This is a problem... -> fix it + .data_i ( narrow_rdata_geared [i] ), + + .valid_o ( narrow_rvalid_o [i] ), + .ready_i ( 1'b1 ), + .data_o ( narrow_rdata_o [i] ), + .selected_reg_i( 1< Date: Wed, 7 Aug 2024 16:54:47 +0200 Subject: [PATCH 3/3] WIP: add rready wrap --- src/geared_memory_island.sv | 123 ++++++++++++-- src/memory_island_core_rready_wrap.sv | 224 ++++++++++++++++++++++++++ 2 files changed, 335 insertions(+), 12 deletions(-) create mode 100644 src/memory_island_core_rready_wrap.sv diff --git a/src/geared_memory_island.sv b/src/geared_memory_island.sv index 43c6da5..d2771c2 100644 --- a/src/geared_memory_island.sv +++ b/src/geared_memory_island.sv @@ -42,6 +42,8 @@ module geared_memory_island #( parameter int unsigned SpillReqBank = 0, parameter int unsigned SpillRspBank = 0, + parameter bit InternalCombRspReq = 1'b1, + parameter MemorySimInit = "none", // Derived, DO NOT OVERRIDE @@ -94,6 +96,7 @@ module geared_memory_island #( logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_req_geared; logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_gnt_geared; logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_rvalid_geared; + logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_rready_geared; logic [NumNarrowReq-1:0][GearRatio-1:0][NarrowDataWidth-1:0] narrow_rdata_geared; logic [NumNarrowReq-1:0][GearRatio-1:0] narrow_selected; @@ -107,10 +110,16 @@ module geared_memory_island #( logic [GearRatio*NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_wdata_entry_geared; logic [GearRatio*NumNarrowReq-1:0][NarrowStrbWidth-1:0] narrow_strb_entry_geared; logic [GearRatio*NumNarrowReq-1:0] narrow_rvalid_entry_geared; + logic [GearRatio*NumNarrowReq-1:0] narrow_rready_entry_geared; logic [GearRatio*NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_rdata_entry_geared; wide_mem_req_t [NumWideReq-1:0] wide_mem_req; wide_mem_req_t [NumWideReq-1:0][GearRatio-1:0] wide_mem_req_geared; + logic [NumWideReq-1:0][GearRatio-1:0] wide_req_geared; + logic [NumWideReq-1:0][GearRatio-1:0] wide_gnt_geared; + logic [NumWideReq-1:0][GearRatio-1:0] wide_rvalid_geared; + logic [NumWideReq-1:0][GearRatio-1:0] wide_rready_geared; + logic [NumWideReq-1:0][GearRatio-1:0][WideDataWidth-1:0] wide_rdata_geared; logic [GearRatio* NumWideReq-1:0] wide_req_entry_geared; logic [GearRatio* NumWideReq-1:0] wide_gnt_entry_geared; @@ -119,6 +128,7 @@ module geared_memory_island #( logic [GearRatio* NumWideReq-1:0][ WideDataWidth-1:0] wide_wdata_entry_geared; logic [GearRatio* NumWideReq-1:0][ WideStrbWidth-1:0] wide_strb_entry_geared; logic [GearRatio* NumWideReq-1:0] wide_rvalid_entry_geared; + logic [GearRatio* NumWideReq-1:0] wide_rready_entry_geared; logic [GearRatio* NumWideReq-1:0][ WideDataWidth-1:0] wide_rdata_entry_geared; clk_int_div #( @@ -166,14 +176,15 @@ module geared_memory_island #( for (genvar j = 0; j < GearRatio; j++) begin localparam id = i*GearRatio + j; - assign narrow_req_entry_geared [id] = narrow_req_geared [i][j]; - assign narrow_gnt_geared [i][j] = narrow_gnt_entry_geared [id]; - assign narrow_addr_entry_geared [id] = narrow_mem_req_geared [i][j].addr; - assign narrow_we_entry_geared [id] = narrow_mem_req_geared [i][j].we; - assign narrow_wdata_entry_geared[id] = narrow_mem_req_geared [i][j].wdata; - assign narrow_strb_entry_geared [id] = narrow_mem_req_geared [i][j].strb; - assign narrow_rvalid_geared [i][j] = narrow_rvalid_entry_geared[id]; - assign narrow_rdata_geared [i][j] = narrow_rdata_entry_geared [id]; + assign narrow_req_entry_geared [id] = narrow_req_geared [i][j]; + assign narrow_gnt_geared [i][j] = narrow_gnt_entry_geared [id]; + assign narrow_addr_entry_geared [id] = narrow_mem_req_geared [i][j].addr; + assign narrow_we_entry_geared [id] = narrow_mem_req_geared [i][j].we; + assign narrow_wdata_entry_geared [id] = narrow_mem_req_geared [i][j].wdata; + assign narrow_strb_entry_geared [id] = narrow_mem_req_geared [i][j].strb; + assign narrow_rvalid_geared [i][j] = narrow_rvalid_entry_geared[id]; + assign narrow_rready_entry_geared[id] = narrow_rready_geared [i][j]; + assign narrow_rdata_geared [i][j] = narrow_rdata_entry_geared [id]; end onehot_to_bin #( @@ -191,7 +202,7 @@ module geared_memory_island #( .clk_i, .rst_ni, .flush_i ('0), - .testmode_i(), + .testmode_i('0), .full_o (), .empty_o (), .usage_o (), @@ -211,19 +222,103 @@ module geared_memory_island #( .clr_i ('0), .valid_i ( narrow_rvalid_geared [i] ), - .ready_o (), // This is a problem... -> fix it + .ready_o ( narrow_rready_geared [i] ), .data_i ( narrow_rdata_geared [i] ), .valid_o ( narrow_rvalid_o [i] ), .ready_i ( 1'b1 ), .data_o ( narrow_rdata_o [i] ), - .selected_reg_i( 1< + +module memory_island_core_rready_wrap #( + /// Address Width + parameter int unsigned AddrWidth = 0, + /// Data Width for the Narrow Ports + parameter int unsigned NarrowDataWidth = 0, + /// Data Width for the Wide Ports + parameter int unsigned WideDataWidth = 0, + + /// Number of Narrow Ports + parameter int unsigned NumNarrowReq = 0, + /// Number of Wide Ports + parameter int unsigned NumWideReq = 0, + + /// Banking Factor for the Wide Ports (power of 2) + parameter int unsigned NumWideBanks = (1<<$clog2(NumWideReq))*2, + /// Extra multiplier for the Narrow banking factor (baseline is WideWidth/NarrowWidth) (power of 2) + parameter int unsigned NarrowExtraBF = 1, + /// Words per memory bank. (Total number of banks is (WideWidth/NarrowWidth)*NumWideBanks) + parameter int unsigned WordsPerBank = 1024, + + /// Spill Narrow + parameter int unsigned SpillNarrowReqEntry = 0, + parameter int unsigned SpillNarrowRspEntry = 0, + parameter int unsigned SpillNarrowReqRouted = 0, + parameter int unsigned SpillNarrowRspRouted = 0, + /// Spill Wide + parameter int unsigned SpillWideReqEntry = 0, + parameter int unsigned SpillWideRspEntry = 0, + parameter int unsigned SpillWideReqRouted = 0, + parameter int unsigned SpillWideRspRouted = 0, + parameter int unsigned SpillWideReqSplit = 0, + parameter int unsigned SpillWideRspSplit = 0, + /// Spill at Bank + parameter int unsigned SpillReqBank = 0, + parameter int unsigned SpillRspBank = 0, + + parameter bit CombRspReq = 1'b1, + + parameter MemorySimInit = "none", + + /// Relinquish narrow priority after x cycles, 0 for never. Requires SpillNarrowReqRouted==0. + parameter int unsigned WidePriorityWait = 1, + + // Derived, DO NOT OVERRIDE + parameter int unsigned NarrowStrbWidth = NarrowDataWidth/8, + parameter int unsigned WideStrbWidth = WideDataWidth/8, + parameter int unsigned NWDivisor = WideDataWidth/NarrowDataWidth +) ( + input logic clk_i, + input logic rst_ni, + + // Narrow inputs + input logic [NumNarrowReq-1:0] narrow_req_i, + output logic [NumNarrowReq-1:0] narrow_gnt_o, + input logic [NumNarrowReq-1:0][ AddrWidth-1:0] narrow_addr_i, + input logic [NumNarrowReq-1:0] narrow_we_i, + input logic [NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_wdata_i, + input logic [NumNarrowReq-1:0][NarrowStrbWidth-1:0] narrow_strb_i, + output logic [NumNarrowReq-1:0] narrow_rvalid_o, + input logic [NumNarrowReq-1:0] narrow_rready_i, + output logic [NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_rdata_o, + + // Wide inputs + input logic [ NumWideReq-1:0] wide_req_i, + output logic [ NumWideReq-1:0] wide_gnt_o, + input logic [ NumWideReq-1:0][ AddrWidth-1:0] wide_addr_i, + input logic [ NumWideReq-1:0] wide_we_i, + input logic [ NumWideReq-1:0][ WideDataWidth-1:0] wide_wdata_i, + input logic [ NumWideReq-1:0][ WideStrbWidth-1:0] wide_strb_i, + output logic [ NumWideReq-1:0] wide_rvalid_o, + input logic [ NumWideReq-1:0] wide_rready_i, + output logic [ NumWideReq-1:0][ WideDataWidth-1:0] wide_rdata_o +); + + localparam NarrowDepth = ; + localparam WideDepth = ; + + logic [NumNarrowReq-1:0] narrow_req; + logic [NumNarrowReq-1:0] narrow_gnt; + logic [NumNarrowReq-1:0] narrow_rvalid; + logic [NumNarrowReq-1:0][NarrowDataWidth-1:0] narrow_rdata; + logic [NumNarrowReq-1:0] narrow_fifo_ready; + logic [NumNarrowReq-1:0] narrow_credit_left; + + + logic [ NumWideReq-1:0] wide_req; + logic [ NumWideReq-1:0] wide_gnt; + logic [ NumWideReq-1:0] wide_rvalid; + logic [ NumWideReq-1:0][ WideDataWidth-1:0] wide_rdata; + logic [ NumWideReq-1:0] wide_fifo_ready; + logic [ NumWideReq-1:0] wide_credit_left; + + for (genvar i = 0; i < NumNarrowReq; i++) begin : gen_narrow_r_fifo + stream_fifo #( + .FALL_THROUGH ( 1'b1 ), + .DATA_WIDTH ( NarrowDataWidth ), + .DEPTH () + ) i_rdata_fifo ( + .clk_i, + .rst_ni, + .flush_i ('0), + .testmode_i('0), + .usage_o (), + .data_i ( narrow_rdata [i] ), + .valid_i ( narrow_rvalid [i] ), + .ready_o ( narrow_fifo_ready[i] ), + .data_o ( narrow_rdata_o [i] ), + .valid_o ( narrow_rvalid_o [i] ), + .ready_i ( narrow_rready_i [i] ), + ); + + credit_counter #( + .NumCredits ( ), + .InitCreditEmpty( 1'b0 ) + ) i_rdata_credit ( + .clk_i, + .rst_ni, + .credit_o (), + .credit_give_i( narrow_rvalid_o[i] & narrow_rready_i[i] ), + .credit_take_i( narrow_req [i] & narrow_gnt [i] ), + .credit_init_i( '0 ), + .credit_left_o( narrow_credit_left [i] ), + .credit_crit_o(), + .credit_full_o() + ); + + // Only transmit request if we have credits or a space frees up + assign narrow_req [i] = narrow_req_i[i] & (narrow_credit_left[i] | (CombRspReq & narrow_rready_i[i] & narrow_rvalid_o[i])); + // Only grant request if we have credits or a space frees up + assign narrow_gnt_o[i] = narrow_gnt [i] & (narrow_credit_left[i] | (CombRspReq & narrow_rready_i[i] & narrow_rvalid_o[i])); + end + + for (genvar i = 0; i < NumWideReq; i++) begin : gen_wide_r_fifo + stream_fifo #( + .FALL_THROUGH ( 1'b1 ), + .DATA_WIDTH ( WideDataWidth ), + .DEPTH () + ) i_rdata_fifo ( + .clk_i, + .rst_ni, + .flush_i ('0), + .testmode_i('0), + .usage_o (), + .data_i ( wide_rdata [i] ), + .valid_i ( wide_rvalid [i] ), + .ready_o ( wide_fifo_ready[i] ), + .data_o ( wide_rdata_o [i] ), + .valid_o ( wide_rvalid_o [i] ), + .ready_i ( wide_rready_i [i] ), + ); + + credit_counter #( + .NumCredits ( ), + .InitCreditEmpty( 1'b0 ) + ) i_rdata_credit ( + .clk_i, + .rst_ni, + .credit_o (), + .credit_give_i( wide_rvalid_o[i] & wide_rready_i[i] ), + .credit_take_i( wide_req [i] & wide_gnt [i] ), + .credit_init_i( '0 ), + .credit_left_o( wide_credit_left [i] ), + .credit_crit_o(), + .credit_full_o() + ); + + // Only transmit request if we have credits or a space frees up + assign wide_req [i] = wide_req_i[i] & (wide_credit_left[i] | (CombRspReq & wide_rready_i[i] & wide_rvalid_o[i])); + // Only grant request if we have credits or a space frees up + assign wide_gnt_o[i] = wide_gnt [i] & (wide_credit_left[i] | (CombRspReq & wide_rready_i[i] & wide_rvalid_o[i])); + end + + memory_island_core #( + .AddrWidth ( AddrWidth ), + .NarrowDataWidth ( NarrowDataWidth ), + .WideDataWidth ( WideDataWidth ), + .NumNarrowReq ( NumNarrowReq ), + .NumWideReq ( NumWideReq ), + .NumWideBanks ( NumWideBanks ), + .NarrowExtraBF ( NarrowExtraBF ), + .WordsPerBank ( WordsPerBank ), + .SpillNarrowReqEntry ( SpillNarrowReqEntry ), + .SpillNarrowRspEntry ( SpillNarrowRspEntry ), + .SpillNarrowReqRouted ( SpillNarrowReqRouted ), + .SpillNarrowRspRouted ( SpillNarrowRspRouted ), + .SpillWideReqEntry ( SpillWideReqEntry ), + .SpillWideRspEntry ( SpillWideRspEntry ), + .SpillWideReqRouted ( SpillWideReqRouted ), + .SpillWideRspRouted ( SpillWideRspRouted ), + .SpillWideReqSplit ( SpillWideReqSplit ), + .SpillWideRspSplit ( SpillWideRspSplit ), + .SpillReqBank ( SpillReqBank ), + .SpillRspBank ( SpillRspBank ), + .WidePriorityWait ( WidePriorityWait ), + .MemorySimInit ( MemorySimInit ) + ) i_memory_island ( + .clk_i, + .rst_ni, + + .narrow_req_i ( narrow_req ), + .narrow_gnt_o ( narrow_gnt ), + .narrow_addr_i, + .narrow_we_i, + .narrow_wdata_i, + .narrow_strb_i, + .narrow_rvalid_o ( narrow_rvalid ), + .narrow_rdata_o ( narrow_rdata ), + .wide_req_i ( wide_req ), + .wide_gnt_o ( wide_gnt ), + .wide_addr_i, + .wide_we_i, + .wide_wdata_i, + .wide_strb_i, + .wide_rvalid_o ( wide_rvalid ), + .wide_rdata_o ( wide_rdata ) + ); + +endmodule