From d4e3b1cd7b90192005a5ea7a1675851b4eb61cb8 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Thu, 25 Feb 2021 10:17:07 +0100 Subject: [PATCH 01/16] [hardware] Make the cache two-way set associative and increase L0 size --- hardware/src/mempool_pkg.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hardware/src/mempool_pkg.sv b/hardware/src/mempool_pkg.sv index 56bc4c632..ae129abee 100644 --- a/hardware/src/mempool_pkg.sv +++ b/hardware/src/mempool_pkg.sv @@ -120,9 +120,9 @@ package mempool_pkg; * INSTRUCTION CACHE * ***********************/ - localparam int unsigned ICacheSizeByte = 512 * NumCoresPerCache; // Total Size of instruction cache in bytes - localparam int unsigned ICacheSets = NumCoresPerCache; // Number of sets - localparam int unsigned ICacheLineWidth = 32 * NumCoresPerCache; // Size of each cache line in bits, + localparam int unsigned ICacheSizeByte = 512 * NumCoresPerCache; // Total Size of instruction cache in bytes + localparam int unsigned ICacheSets = NumCoresPerCache / 2; // Number of sets + localparam int unsigned ICacheLineWidth = 32 * 2 * NumCoresPerCache; // Size of each cache line in bits, /********************************** * TCDM INTERCONNECT PARAMETERS * From d45f2065fa61d21e513d310b8654ae64396a03dc Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Tue, 13 Oct 2020 14:59:50 +0200 Subject: [PATCH 02/16] [hardware] Add SCM --- Bender.yml | 1 + hardware/src/scm.sv | 200 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 hardware/src/scm.sv diff --git a/Bender.yml b/Bender.yml index ff1028d36..da1b6e205 100644 --- a/Bender.yml +++ b/Bender.yml @@ -26,6 +26,7 @@ sources: - hardware/src/address_scrambler.sv - hardware/src/axi2mem.sv - hardware/src/bootrom.sv + - hardware/src/scm.sv # Level 1 - hardware/src/mempool_tile.sv # Level 2 diff --git a/hardware/src/scm.sv b/hardware/src/scm.sv new file mode 100644 index 000000000..b0889928b --- /dev/null +++ b/hardware/src/scm.sv @@ -0,0 +1,200 @@ +// Copyright (c) 2020 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// Author: Samuel Riedel + +`include "common_cells/registers.svh" + +module scm #( + parameter int unsigned NumWords = 32'd1024, // Number of words in data array + parameter int unsigned DataWidth = 32'd32, // Width of one word in bits + parameter int unsigned LATCH = 0, // Use FF or latches (0=FF, 1=Latches) + // DEPENDENT PARAMETERS, DO NOT OVERWRITE! + parameter int unsigned AddrWidth = (NumWords > 32'd1) ? $clog2(NumWords) : 32'd1, + parameter type addr_t = logic [AddrWidth-1:0], + parameter type data_t = logic [DataWidth-1:0] +) ( + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low + // input ports + input logic req_i, // request + input logic we_i, // write enable + input addr_t addr_i, // request address + input data_t wdata_i, // write data + // output ports + output data_t rdata_o // read data +); + + // Memory array + data_t data, wdata [NumWords-1:0]; + // Hold the read address to keep output constant + addr_t addr_q; + `FFLSRN(addr_q, addr_i, req_i && !we_i, 0, clk_i, rst_ni) + + // Output + assign rdata_o = data[addr_q]; + + // Write + if (LATCH) begin + always_latch begin + if (!rst_ni) begin + for (int unsigned i = 0; i < NumWords; i++) begin + data[i] <= '0; + end + end else if (clk_i && req_i && we_i) begin + data[addr_i] <= wdata_i; + end + end + end else begin + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + for (int unsigned i = 0; i < NumWords; i++) begin + data[i] <= '0; + end + end else if (req_i && we_i) begin + data[addr_i] <= wdata_i; + end + end + end + +endmodule + +module register_file_1r_1w +#( + parameter ADDR_WIDTH = 5, + parameter DATA_WIDTH = 32 +) +( + input logic clk, + + // Read port + input logic ReadEnable, + input logic [ADDR_WIDTH-1:0] ReadAddr, + output logic [DATA_WIDTH-1:0] ReadData, + + + // Write port + input logic WriteEnable, + input logic [ADDR_WIDTH-1:0] WriteAddr, + input logic [DATA_WIDTH-1:0] WriteData +); + + localparam NUM_WORDS = 2**ADDR_WIDTH; + + // Read address register, located at the input of the address decoder + logic [ADDR_WIDTH-1:0] RAddrRegxDP; + logic [NUM_WORDS-1:0] RAddrOneHotxD; + + + logic [DATA_WIDTH-1:0] MemContentxDP[NUM_WORDS]; + + logic [NUM_WORDS-1:0] WAddrOneHotxD; + logic [NUM_WORDS-1:0] ClocksxC; + logic [DATA_WIDTH-1:0] WDataIntxD; + + logic clk_int; + + int unsigned i; + int unsigned j; + int unsigned k; + int unsigned l; + int unsigned m; + + genvar x; + genvar y; + + cluster_clock_gating CG_WE_GLOBAL + ( + .clk_o ( clk_int ), + .en_i ( WriteEnable ), + .test_en_i ( 1'b0 ), + .clk_i ( clk ) + ); + + //----------------------------------------------------------------------------- + //-- READ : Read address register + //----------------------------------------------------------------------------- + always_ff @(posedge clk) + begin : p_RAddrReg + if(ReadEnable) + RAddrRegxDP <= ReadAddr; + end + + + //----------------------------------------------------------------------------- + //-- READ : Read address decoder RAD + //----------------------------------------------------------------------------- + always_comb + begin : p_RAD + RAddrOneHotxD = '0; + RAddrOneHotxD[RAddrRegxDP] = 1'b1; + end + assign ReadData = MemContentxDP[RAddrRegxDP]; + + + //----------------------------------------------------------------------------- + //-- WRITE : Write Address Decoder (WAD), combinatorial process + //----------------------------------------------------------------------------- + always_comb + begin : p_WAD + for(i=0; i Date: Tue, 16 Mar 2021 16:04:14 +0100 Subject: [PATCH 03/16] [hardware] Rename SCM module --- Bender.yml | 2 +- hardware/src/latch_scm.sv | 126 ++++++++++++++++++++++++ hardware/src/scm.sv | 200 -------------------------------------- 3 files changed, 127 insertions(+), 201 deletions(-) create mode 100644 hardware/src/latch_scm.sv delete mode 100644 hardware/src/scm.sv diff --git a/Bender.yml b/Bender.yml index da1b6e205..76a4287c5 100644 --- a/Bender.yml +++ b/Bender.yml @@ -26,7 +26,7 @@ sources: - hardware/src/address_scrambler.sv - hardware/src/axi2mem.sv - hardware/src/bootrom.sv - - hardware/src/scm.sv + - hardware/src/latch_scm.sv # Level 1 - hardware/src/mempool_tile.sv # Level 2 diff --git a/hardware/src/latch_scm.sv b/hardware/src/latch_scm.sv new file mode 100644 index 000000000..61e29f9be --- /dev/null +++ b/hardware/src/latch_scm.sv @@ -0,0 +1,126 @@ +// Copyright (c) 2020 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +module latch_scm #( + parameter ADDR_WIDTH = 5, + parameter DATA_WIDTH = 32 +) ( + input logic clk, + // Read port + input logic ReadEnable, + input logic [ADDR_WIDTH-1:0] ReadAddr, + output logic [DATA_WIDTH-1:0] ReadData, + // Write port + input logic WriteEnable, + input logic [ADDR_WIDTH-1:0] WriteAddr, + input logic [DATA_WIDTH-1:0] WriteData +); + + localparam NUM_WORDS = 2**ADDR_WIDTH; + + // Read address register, located at the input of the address decoder + logic [ADDR_WIDTH-1:0] RAddrRegxDP; + logic [NUM_WORDS-1:0] RAddrOneHotxD; + + logic [DATA_WIDTH-1:0] MemContentxDP[NUM_WORDS]; + + logic [NUM_WORDS-1:0] WAddrOneHotxD; + logic [NUM_WORDS-1:0] ClocksxC; + logic [DATA_WIDTH-1:0] WDataIntxD; + + logic clk_int; + + int unsigned i; + int unsigned j; + int unsigned k; + int unsigned l; + int unsigned m; + + genvar x; + genvar y; + + cluster_clock_gating CG_WE_GLOBAL ( + .clk_o (clk_int ), + .en_i (WriteEnable), + .test_en_i (1'b0 ), + .clk_i (clk ) + ); + + //----------------------------------------------------------------------------- + //-- READ : Read address register + //----------------------------------------------------------------------------- + always_ff @(posedge clk) begin : p_RAddrReg + if(ReadEnable) + RAddrRegxDP <= ReadAddr; + end + + + //----------------------------------------------------------------------------- + //-- READ : Read address decoder RAD + //----------------------------------------------------------------------------- + always_comb begin : p_RAD + RAddrOneHotxD = '0; + RAddrOneHotxD[RAddrRegxDP] = 1'b1; + end + assign ReadData = MemContentxDP[RAddrRegxDP]; + + + //----------------------------------------------------------------------------- + //-- WRITE : Write Address Decoder (WAD), combinatorial process + //----------------------------------------------------------------------------- + always_comb begin : p_WAD + for(i=0; i - -`include "common_cells/registers.svh" - -module scm #( - parameter int unsigned NumWords = 32'd1024, // Number of words in data array - parameter int unsigned DataWidth = 32'd32, // Width of one word in bits - parameter int unsigned LATCH = 0, // Use FF or latches (0=FF, 1=Latches) - // DEPENDENT PARAMETERS, DO NOT OVERWRITE! - parameter int unsigned AddrWidth = (NumWords > 32'd1) ? $clog2(NumWords) : 32'd1, - parameter type addr_t = logic [AddrWidth-1:0], - parameter type data_t = logic [DataWidth-1:0] -) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - // input ports - input logic req_i, // request - input logic we_i, // write enable - input addr_t addr_i, // request address - input data_t wdata_i, // write data - // output ports - output data_t rdata_o // read data -); - - // Memory array - data_t data, wdata [NumWords-1:0]; - // Hold the read address to keep output constant - addr_t addr_q; - `FFLSRN(addr_q, addr_i, req_i && !we_i, 0, clk_i, rst_ni) - - // Output - assign rdata_o = data[addr_q]; - - // Write - if (LATCH) begin - always_latch begin - if (!rst_ni) begin - for (int unsigned i = 0; i < NumWords; i++) begin - data[i] <= '0; - end - end else if (clk_i && req_i && we_i) begin - data[addr_i] <= wdata_i; - end - end - end else begin - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - for (int unsigned i = 0; i < NumWords; i++) begin - data[i] <= '0; - end - end else if (req_i && we_i) begin - data[addr_i] <= wdata_i; - end - end - end - -endmodule - -module register_file_1r_1w -#( - parameter ADDR_WIDTH = 5, - parameter DATA_WIDTH = 32 -) -( - input logic clk, - - // Read port - input logic ReadEnable, - input logic [ADDR_WIDTH-1:0] ReadAddr, - output logic [DATA_WIDTH-1:0] ReadData, - - - // Write port - input logic WriteEnable, - input logic [ADDR_WIDTH-1:0] WriteAddr, - input logic [DATA_WIDTH-1:0] WriteData -); - - localparam NUM_WORDS = 2**ADDR_WIDTH; - - // Read address register, located at the input of the address decoder - logic [ADDR_WIDTH-1:0] RAddrRegxDP; - logic [NUM_WORDS-1:0] RAddrOneHotxD; - - - logic [DATA_WIDTH-1:0] MemContentxDP[NUM_WORDS]; - - logic [NUM_WORDS-1:0] WAddrOneHotxD; - logic [NUM_WORDS-1:0] ClocksxC; - logic [DATA_WIDTH-1:0] WDataIntxD; - - logic clk_int; - - int unsigned i; - int unsigned j; - int unsigned k; - int unsigned l; - int unsigned m; - - genvar x; - genvar y; - - cluster_clock_gating CG_WE_GLOBAL - ( - .clk_o ( clk_int ), - .en_i ( WriteEnable ), - .test_en_i ( 1'b0 ), - .clk_i ( clk ) - ); - - //----------------------------------------------------------------------------- - //-- READ : Read address register - //----------------------------------------------------------------------------- - always_ff @(posedge clk) - begin : p_RAddrReg - if(ReadEnable) - RAddrRegxDP <= ReadAddr; - end - - - //----------------------------------------------------------------------------- - //-- READ : Read address decoder RAD - //----------------------------------------------------------------------------- - always_comb - begin : p_RAD - RAddrOneHotxD = '0; - RAddrOneHotxD[RAddrRegxDP] = 1'b1; - end - assign ReadData = MemContentxDP[RAddrRegxDP]; - - - //----------------------------------------------------------------------------- - //-- WRITE : Write Address Decoder (WAD), combinatorial process - //----------------------------------------------------------------------------- - always_comb - begin : p_WAD - for(i=0; i Date: Tue, 16 Mar 2021 16:06:34 +0100 Subject: [PATCH 04/16] [hardware] Update tech_cells in latch-based SCM --- hardware/src/latch_scm.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware/src/latch_scm.sv b/hardware/src/latch_scm.sv index 61e29f9be..e09388c36 100644 --- a/hardware/src/latch_scm.sv +++ b/hardware/src/latch_scm.sv @@ -46,7 +46,7 @@ module latch_scm #( genvar x; genvar y; - cluster_clock_gating CG_WE_GLOBAL ( + tc_clk_gating CG_WE_GLOBAL ( .clk_o (clk_int ), .en_i (WriteEnable), .test_en_i (1'b0 ), @@ -89,7 +89,7 @@ module latch_scm #( //----------------------------------------------------------------------------- generate for(x=0; x Date: Tue, 16 Mar 2021 16:37:52 +0100 Subject: [PATCH 05/16] [hardware] Ignore warning about latches --- hardware/src/latch_scm.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hardware/src/latch_scm.sv b/hardware/src/latch_scm.sv index e09388c36..020d8fdda 100644 --- a/hardware/src/latch_scm.sv +++ b/hardware/src/latch_scm.sv @@ -116,11 +116,13 @@ module latch_scm #( //-- Use active low, i.e. transparent on low latches as storage elements //-- Data is sampled on rising clock edge + /* verilator lint_off NOLATCH */ always_latch begin : latch_wdata for(k=0; k Date: Mon, 26 Oct 2020 11:11:12 +0100 Subject: [PATCH 06/16] [hardware] Make the L1 tags SCM based --- .../src/snitch_icache/snitch_icache_lookup.sv | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv index 0937b0ffe..597dddafb 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv @@ -127,19 +127,17 @@ module snitch_icache_lookup #( // Instantiate the RAM sets. for (genvar i = 0; i < CFG.SET_COUNT; i++) begin : g_sets - tc_sram #( - .DataWidth ( CFG.TAG_WIDTH+2 ), - .NumWords ( CFG.LINE_COUNT ), - .NumPorts ( 1 ) + latch_scm #( + .ADDR_WIDTH ($clog2(CFG.LINE_COUNT)), + .DATA_WIDTH (CFG.TAG_WIDTH+2 ) ) i_tag ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .req_i ( ram_enable[i] ), - .we_i ( ram_write ), - .addr_i ( ram_addr ), - .wdata_i ( ram_wtag ), - .be_i ( '1 ), - .rdata_o ( ram_rtag[i] ) + .clk (clk_i ), + .ReadEnable (ram_enable[i] && !ram_write), + .ReadAddr (ram_addr ), + .ReadData (ram_rtag[i] ), + .WriteEnable(ram_enable[i] && ram_write ), + .WriteAddr (ram_addr ), + .WriteData (ram_wtag ) ); tc_sram #( From 6f5759d07fc683fee75ba804a4434da9283dca0e Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Mon, 26 Oct 2020 11:22:34 +0100 Subject: [PATCH 07/16] [be] Make L1 data SCM based --- .../src/snitch_icache/snitch_icache_lookup.sv | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv index 597dddafb..e0b4d28d1 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv @@ -140,19 +140,18 @@ module snitch_icache_lookup #( .WriteData (ram_wtag ) ); - tc_sram #( - .DataWidth ( CFG.LINE_WIDTH ), - .NumWords ( CFG.LINE_COUNT ), - .NumPorts ( 1 ) + + latch_scm #( + .ADDR_WIDTH ($clog2(CFG.LINE_COUNT)), + .DATA_WIDTH (CFG.LINE_WIDTH ) ) i_data ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .req_i ( ram_enable[i] ), - .we_i ( ram_write ), - .addr_i ( ram_addr ), - .wdata_i ( ram_wdata ), - .be_i ( '1 ), - .rdata_o ( ram_rdata[i] ) + .clk (clk_i ), + .ReadEnable (ram_enable[i] && !ram_write), + .ReadAddr (ram_addr ), + .ReadData (ram_rdata[i] ), + .WriteEnable(ram_enable[i] && ram_write ), + .WriteAddr (ram_addr ), + .WriteData (ram_wdata ) ); end From e00f1d8dd0639aabfa3a4533ac73ff7c1c77d568 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Thu, 18 Mar 2021 08:38:16 +0100 Subject: [PATCH 08/16] Revert "[be] Make L1 data SCM based" This reverts commit e295a847692701d5457fcce24fc279fe68352444. --- .../src/snitch_icache/snitch_icache_lookup.sv | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv index e0b4d28d1..597dddafb 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv @@ -140,18 +140,19 @@ module snitch_icache_lookup #( .WriteData (ram_wtag ) ); - - latch_scm #( - .ADDR_WIDTH ($clog2(CFG.LINE_COUNT)), - .DATA_WIDTH (CFG.LINE_WIDTH ) + tc_sram #( + .DataWidth ( CFG.LINE_WIDTH ), + .NumWords ( CFG.LINE_COUNT ), + .NumPorts ( 1 ) ) i_data ( - .clk (clk_i ), - .ReadEnable (ram_enable[i] && !ram_write), - .ReadAddr (ram_addr ), - .ReadData (ram_rdata[i] ), - .WriteEnable(ram_enable[i] && ram_write ), - .WriteAddr (ram_addr ), - .WriteData (ram_wdata ) + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( ram_enable[i] ), + .we_i ( ram_write ), + .addr_i ( ram_addr ), + .wdata_i ( ram_wdata ), + .be_i ( '1 ), + .rdata_o ( ram_rdata[i] ) ); end From fcde3242cc83ca03c3b6443519e754da6cd394de Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Wed, 28 Oct 2020 22:56:24 +0100 Subject: [PATCH 09/16] [hardware] Make L0 latch based This worked in the netlist, but the constraints were bad --- .../snitch/src/snitch_icache/snitch_icache_l0.sv | 15 ++++++++++++++- hardware/src/mempool_tile.sv | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv index 442d78a3f..93045e7f6 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv @@ -120,6 +120,12 @@ module snitch_icache_l0 import snitch_icache_pkg::*; #( assign hit_prefetch_any = |hit_prefetch; assign miss = ~hit_any & in_valid_i & ~pending_refill_q; + logic clk_inv; + tc_clk_inverter i_clk_inv ( + .clk_i (clk_i), + .clk_o (clk_inv) + ); + for (genvar i = 0; i < CFG.L0_LINE_COUNT; i++) begin : gen_array // Tag Array always_ff @(posedge clk_i or negedge rst_ni) begin @@ -139,9 +145,16 @@ module snitch_icache_l0 import snitch_icache_pkg::*; #( end end if (CFG.EARLY_LATCH) begin : gen_latch + logic clk_vld; + tc_clk_gating i_clk_gate ( + .clk_i (clk_inv ), + .en_i (validate_strb[i]), + .test_en_i (1'b0 ), + .clk_o (clk_vld ) + ); // Data Array always_latch begin - if (clk_i && validate_strb[i]) begin + if (clk_vld) begin data[i] <= out_rsp_data_i; end end diff --git a/hardware/src/mempool_tile.sv b/hardware/src/mempool_tile.sv index 2b6f006c6..b8664414b 100644 --- a/hardware/src/mempool_tile.sv +++ b/hardware/src/mempool_tile.sv @@ -165,7 +165,7 @@ module mempool_tile /// Make the early cache latch-based. This reduces latency at the cost of /// increased combinatorial path lengths and the hassle of having latches in /// the design. - .EARLY_LATCH (0 ), + .EARLY_LATCH (1 ), .L0_EARLY_TAG_WIDTH (11 ), .ISO_CROSSING (0 ) ) i_snitch_icache ( From cd0cc9b298b494f04b49da18648d837c063b32b3 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Fri, 20 Nov 2020 13:56:48 +0100 Subject: [PATCH 10/16] [snitch] Implement pipeline in cache lookup --- .../src/snitch_icache/snitch_icache_lookup.sv | 123 ++++++++++++------ 1 file changed, 80 insertions(+), 43 deletions(-) diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv index 597dddafb..753af195e 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv @@ -8,6 +8,9 @@ // permission from ETH Zurich. // // Fabian Schuiki +// Samuel Riedel + +`include "common_cells/registers.svh" /// An actual cache lookup. module snitch_icache_lookup #( @@ -41,20 +44,39 @@ module snitch_icache_lookup #( input logic write_valid_i, output logic write_ready_o ); + logic valid_and_hit; + assign valid_and_hit = out_valid_o & out_hit_o; `ifndef SYNTHESIS initial assert(CFG != '0); `endif + localparam int unsigned DataAddrWdith = CFG.SET_ALIGN + CFG.COUNT_ALIGN; + + typedef struct packed { + logic [CFG.FETCH_AW-1:0] addr; + logic [CFG.COUNT_ALIGN-1:0] set; + logic [CFG.LINE_WIDTH-1:0] data; + logic [CFG.ID_WIDTH_REQ-1:0] id; + logic write; + } req_t; + // Multiplex read and write access to the RAMs onto one port, prioritizing // write accesses. logic [CFG.COUNT_ALIGN-1:0] ram_addr ; logic [CFG.SET_COUNT-1:0] ram_enable ; - logic [CFG.LINE_WIDTH-1:0] ram_wdata, ram_rdata [CFG.SET_COUNT] ; + logic [CFG.LINE_WIDTH-1:0] ram_wdata, ram_rdata; logic [CFG.TAG_WIDTH+1:0] ram_wtag, ram_rtag [CFG.SET_COUNT] ; logic ram_write ; logic ram_write_q; logic [CFG.COUNT_ALIGN:0] init_count_q; + logic [CFG.COUNT_ALIGN-1:0] data_addr; + logic [DataAddrWdith-1:0] data_bank_addr; + req_t data_req_d, data_req_q; + logic req_valid, req_ready; + + logic out_hit, out_error; + logic [CFG.SET_ALIGN-1:0] out_set; always_comb begin : p_portmux write_ready_o = 0; @@ -65,6 +87,7 @@ module snitch_icache_lookup #( ram_wtag = {1'b1, write_error_i, write_tag_i}; ram_enable = '0; ram_write = 1'b0; + req_valid = 1'b0; if (init_count_q != $unsigned(CFG.LINE_COUNT)) begin ram_addr = init_count_q; @@ -76,10 +99,25 @@ module snitch_icache_lookup #( ram_addr = write_addr_i; ram_enable = $unsigned(1 << write_set_i); ram_write = 1'b1; - write_ready_o = 1'b1; - end else if (out_ready_i) begin - ram_enable = in_valid_i ? '1 : '0; - in_ready_o = 1'b1; + write_ready_o = 1'b1; // From Fall-through register + // Store request to data bank + req_valid = 1'b1; + data_req_d.addr = write_addr_i; + data_req_d.set = write_set_i; + data_req_d.data = write_data_i; + data_req_d.id = data_req_q.id; // Don't care + data_req_d.write = 1'b1; + end else if (in_valid_i) begin + // Read the tag banks + ram_enable = '1; + in_ready_o = out_ready_i; + // Store request to data bank + req_valid = 1'b1; + data_req_d.addr = in_addr_i; + data_req_d.set = data_req_q.set; // Don't care + data_req_d.data = data_req_q.data; // Don't care + data_req_d.id = in_id_i; + data_req_d.write = 1'b0; end end @@ -104,27 +142,30 @@ module snitch_icache_lookup #( // The address register keeps track of additional metadata alongside the // looked up tag and data. - logic valid_q; + logic valid_q, valid_d; logic [CFG.FETCH_AW-1:0] addr_q; logic [CFG.ID_WIDTH_REQ-1:0] id_q; - always_ff @(posedge clk_i, negedge rst_ni) begin - if (!rst_ni) - valid_q <= 1'b0; - else if ((in_valid_i && in_ready_o) || out_ready_i) - valid_q <= in_valid_i && in_ready_o; - end - always_ff @(posedge clk_i, negedge rst_ni) begin if (!rst_ni) begin addr_q <= '0; id_q <= '0; - end else if (in_valid_i && in_ready_o) begin - addr_q <= in_addr_i; - id_q <= in_id_i; + end else if (valid_d && out_ready_i) begin + addr_q <= data_req_q.addr; + id_q <= data_req_q.id; end end + `FFLARN(out_hit_o, out_hit, valid_d & out_ready_i, 1'b0, clk_i, rst_ni) + `FFLARN(out_error_o, out_error, valid_d & out_ready_i, 1'b0, clk_i, rst_ni) + `FFLARN(out_set_o, out_set, valid_d & out_ready_i, '0, clk_i, rst_ni) + + // Store data while reading the tag + `FFLARN(data_req_q, data_req_d, req_valid & out_ready_i, '0, clk_i, rst_ni) + `FF(valid_d, req_valid, 1'b0) + + `FF(valid_q, valid_d & ~data_req_q.write, 1'b0) + // Instantiate the RAM sets. for (genvar i = 0; i < CFG.SET_COUNT; i++) begin : g_sets latch_scm #( @@ -139,50 +180,46 @@ module snitch_icache_lookup #( .WriteAddr (ram_addr ), .WriteData (ram_wtag ) ); - - tc_sram #( - .DataWidth ( CFG.LINE_WIDTH ), - .NumWords ( CFG.LINE_COUNT ), - .NumPorts ( 1 ) - ) i_data ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .req_i ( ram_enable[i] ), - .we_i ( ram_write ), - .addr_i ( ram_addr ), - .wdata_i ( ram_wdata ), - .be_i ( '1 ), - .rdata_o ( ram_rdata[i] ) - ); end + // Single data bank for all sets + assign data_addr = {data_req_q.write ? data_req_q.addr : data_req_q.addr >> CFG.LINE_ALIGN}; + assign data_bank_addr = {data_req_q.write ? data_req_q.set : out_set, data_addr}; + tc_sram #( + .DataWidth ( CFG.LINE_WIDTH ), + .NumWords ( CFG.LINE_COUNT * CFG.SET_COUNT ), + .NumPorts ( 1 ) + ) i_data ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( valid_d ), + .we_i ( data_req_q.write ), + .addr_i ( data_bank_addr ), + .wdata_i ( data_req_q.data ), + .be_i ( '1 ), + .rdata_o ( ram_rdata ) + ); + // Determine which RAM line hit, and multiplex that data to the output. logic [CFG.TAG_WIDTH-1:0] required_tag; logic [CFG.SET_COUNT-1:0] line_hit; always_comb begin automatic logic [CFG.SET_COUNT-1:0] errors; - required_tag = addr_q >> (CFG.LINE_ALIGN + CFG.COUNT_ALIGN); + required_tag = data_req_q.addr >> (CFG.LINE_ALIGN + CFG.COUNT_ALIGN); for (int i = 0; i < CFG.SET_COUNT; i++) begin line_hit[i] = ram_rtag[i][CFG.TAG_WIDTH+1] && ram_rtag[i][CFG.TAG_WIDTH-1:0] == required_tag; errors[i] = ram_rtag[i][CFG.TAG_WIDTH] && line_hit[i]; end - out_hit_o = |line_hit & ~ram_write_q; // Don't let refills trigger "valid" lookups - out_error_o = |errors; + out_hit = |line_hit & ~ram_write_q; // Don't let refills trigger "valid" lookups + out_error = |errors; end - always_comb begin - for (int i = 0; i < CFG.LINE_WIDTH; i++) begin - automatic logic [CFG.SET_COUNT-1:0] masked; - for (int j = 0; j < CFG.SET_COUNT; j++) - masked[j] = ram_rdata[j][i] & line_hit[j]; - out_data_o[i] = |masked; - end - end + assign out_data_o = out_hit_o ? ram_rdata : '0; lzc #(.WIDTH(CFG.SET_COUNT)) i_lzc ( .in_i ( line_hit ), - .cnt_o ( out_set_o ), + .cnt_o ( out_set ), .empty_o ( ) ); From 752ce48ef0bf68b7d90b8f926a38225be61052a1 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Tue, 16 Mar 2021 16:13:34 +0100 Subject: [PATCH 11/16] [snitch] Fix variable name matching C++ symbol This is encouraged when using Verilator --- .../deps/snitch/src/snitch_icache/snitch_icache_lookup.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv index 753af195e..a5b6d5d3e 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv @@ -55,7 +55,7 @@ module snitch_icache_lookup #( typedef struct packed { logic [CFG.FETCH_AW-1:0] addr; - logic [CFG.COUNT_ALIGN-1:0] set; + logic [CFG.COUNT_ALIGN-1:0] cset; logic [CFG.LINE_WIDTH-1:0] data; logic [CFG.ID_WIDTH_REQ-1:0] id; logic write; @@ -103,7 +103,7 @@ module snitch_icache_lookup #( // Store request to data bank req_valid = 1'b1; data_req_d.addr = write_addr_i; - data_req_d.set = write_set_i; + data_req_d.cset = write_set_i; data_req_d.data = write_data_i; data_req_d.id = data_req_q.id; // Don't care data_req_d.write = 1'b1; @@ -114,7 +114,7 @@ module snitch_icache_lookup #( // Store request to data bank req_valid = 1'b1; data_req_d.addr = in_addr_i; - data_req_d.set = data_req_q.set; // Don't care + data_req_d.cset = data_req_q.cset; // Don't care data_req_d.data = data_req_q.data; // Don't care data_req_d.id = in_id_i; data_req_d.write = 1'b0; @@ -184,7 +184,7 @@ module snitch_icache_lookup #( // Single data bank for all sets assign data_addr = {data_req_q.write ? data_req_q.addr : data_req_q.addr >> CFG.LINE_ALIGN}; - assign data_bank_addr = {data_req_q.write ? data_req_q.set : out_set, data_addr}; + assign data_bank_addr = {data_req_q.write ? data_req_q.cset : out_set, data_addr}; tc_sram #( .DataWidth ( CFG.LINE_WIDTH ), .NumWords ( CFG.LINE_COUNT * CFG.SET_COUNT ), From af699c85b59190c00bed4d3dbae1635c8c5332b9 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Tue, 16 Mar 2021 16:37:27 +0100 Subject: [PATCH 12/16] [snitch] Ignore warning about latches --- hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv index 93045e7f6..8544d3078 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_l0.sv @@ -153,11 +153,13 @@ module snitch_icache_l0 import snitch_icache_pkg::*; #( .clk_o (clk_vld ) ); // Data Array + /* verilator lint_off NOLATCH */ always_latch begin if (clk_vld) begin data[i] <= out_rsp_data_i; end end + /* verilator lint_on NOLATCH */ end else begin : gen_ff `FFLNR(data[i], out_rsp_data_i, validate_strb[i], clk_i) end From 23f5b0180522313a146f3d6f52e2485641d37bbe Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Wed, 17 Mar 2021 10:11:09 +0100 Subject: [PATCH 13/16] [hardware] Update wave scripts --- hardware/scripts/wave.do | 26 -------------------------- hardware/scripts/wave_cache.do | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 26 deletions(-) create mode 100644 hardware/scripts/wave_cache.do diff --git a/hardware/scripts/wave.do b/hardware/scripts/wave.do index d8d1ea286..731b4a5d7 100644 --- a/hardware/scripts/wave.do +++ b/hardware/scripts/wave.do @@ -23,32 +23,6 @@ for {set group 0} {$group < [examine -radix dec /mempool_pkg::NumGroups]} {incr add wave -group group_[$group] -group Interconnect_Local /mempool_tb/dut/i_mempool/gen_groups[$group]/i_group/i_local_interco/* } -add wave -group Wake_up_reg /mempool_tb/dut/i_ctrl_registers/clk_i -add wave -group Wake_up_reg /mempool_tb/dut/i_ctrl_registers/wake_up -add wave -group Wake_up_reg /mempool_tb/dut/i_ctrl_registers/wake_up_o -add wave -group Wake_up_reg /mempool_tb/dut/i_ctrl_registers/wr_active_d -add wave -group Wake_up_reg /mempool_tb/dut/i_ctrl_registers/wr_active_q - -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[0]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[0]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[0]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[1]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[0]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[2]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[0]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[3]/riscv_core/i_snitch/wake_up_sync_i - -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[1]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[0]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[1]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[1]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[1]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[2]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[1]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[3]/riscv_core/i_snitch/wake_up_sync_i - -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[2]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[0]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[2]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[1]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[2]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[2]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[2]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[3]/riscv_core/i_snitch/wake_up_sync_i - -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[3]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[0]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[3]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[1]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[3]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[2]/riscv_core/i_snitch/wake_up_sync_i -add wave -group Core_wake_up_sync_i /mempool_tb/dut/i_mempool/gen_groups[3]/i_group/gen_tiles[0]/i_tile/i_tile/gen_cores[3]/riscv_core/i_snitch/wake_up_sync_i - add wave -Group Control_Registers /mempool_tb/dut/i_ctrl_registers/* # TreeUpdate [SetDefaultTree] diff --git a/hardware/scripts/wave_cache.do b/hardware/scripts/wave_cache.do new file mode 100644 index 000000000..63097b42a --- /dev/null +++ b/hardware/scripts/wave_cache.do @@ -0,0 +1,24 @@ +# Create cache for core $3 from group $1 tile $2 (core_id=NUM_CORES_PER_group*$1+NUM_CORES_PER_TILE*$2+$3) + +add wave -noupdate -group core[$1][$2][$3] -divider Parameters +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/NR_FETCH_PORTS +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/L0_LINE_COUNT +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/LINE_WIDTH +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/LINE_COUNT +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/SET_COUNT +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/FETCH_DW +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/FILL_AW +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/FILL_DW +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/EARLY_LATCH +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/L0_EARLY_TAG_WIDTH +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/ISO_CROSSING +add wave -noupdate -group core[$1][$2][$3] -divider Signals +add wave -noupdate -group cache[$1][$2][$3] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/* + +for {set i 0} {$i < [examine -radix dec /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/NR_FETCH_PORTS]} {incr i} { + add wave -noupdate -group cache[$1][$2][$3] -group refill[$i] /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/gen_prefetcher[$i]/i_snitch_icache_l0/* +} + +add wave -noupdate -group cache[$1][$2][$3] -group lookup /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/i_lookup/* +add wave -noupdate -group cache[$1][$2][$3] -group handler /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/i_handler/* +add wave -noupdate -group cache[$1][$2][$3] -group refill /mempool_tb/dut/i_mempool/gen_groups[$1]/i_group/gen_tiles[$2]/i_tile/i_tile/gen_caches[$3]/i_snitch_icache/i_refill/* From a1ba5ffce849f99885120f595233be09ac9b261b Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Thu, 25 Mar 2021 20:30:26 +0100 Subject: [PATCH 14/16] [CHANGELOG] Update Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4128461bd..32dc00be8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - Update `axi` dependency to 0.27.1 - Change I$ policy to avoid evicting the cache-line currently in use +- Make the L0 cache's data latch-based and double its size +- Make the L1 cache's tag latch-based +- Serialize the L1 lookup ### Fixed - Add a workaround for a Modelsim 2019 bug in the `axi_demux` From 10dd465ff966d68a76a8e2639dfbb3c4870d3da8 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Mon, 29 Mar 2021 11:08:56 +0200 Subject: [PATCH 15/16] [snitch] Make the L1-tag configurable --- .../snitch/src/snitch_icache/snitch_icache.sv | 3 ++ .../src/snitch_icache/snitch_icache_lookup.sv | 41 +++++++++++++------ .../src/snitch_icache/snitch_icache_pkg.sv | 1 + hardware/src/mempool_tile.sv | 1 + 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache.sv index 88ae1ed2b..8b66d80d3 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache.sv @@ -31,6 +31,8 @@ module snitch_icache #( parameter int FILL_AW = -1, /// Fill interface data width. Power of two; >= 8. parameter int FILL_DW = -1, + /// Replace the L1 tag banks with latch-based SCM. + parameter bit L1_TAG_SCM = 0, /// This reduces area impact at the cost of /// increased hassle of having latches in /// the design. @@ -88,6 +90,7 @@ module snitch_icache #( FETCH_DW: FETCH_DW, FILL_AW: FILL_AW, FILL_DW: FILL_DW, + L1_TAG_SCM: L1_TAG_SCM, EARLY_LATCH: EARLY_LATCH, FETCH_ALIGN: $clog2(FETCH_DW/8), diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv index a5b6d5d3e..2ac9e9b41 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_lookup.sv @@ -168,18 +168,35 @@ module snitch_icache_lookup #( // Instantiate the RAM sets. for (genvar i = 0; i < CFG.SET_COUNT; i++) begin : g_sets - latch_scm #( - .ADDR_WIDTH ($clog2(CFG.LINE_COUNT)), - .DATA_WIDTH (CFG.TAG_WIDTH+2 ) - ) i_tag ( - .clk (clk_i ), - .ReadEnable (ram_enable[i] && !ram_write), - .ReadAddr (ram_addr ), - .ReadData (ram_rtag[i] ), - .WriteEnable(ram_enable[i] && ram_write ), - .WriteAddr (ram_addr ), - .WriteData (ram_wtag ) - ); + if (CFG.L1_TAG_SCM) begin : gen_scm + latch_scm #( + .ADDR_WIDTH ($clog2(CFG.LINE_COUNT)), + .DATA_WIDTH (CFG.TAG_WIDTH+2 ) + ) i_tag ( + .clk (clk_i ), + .ReadEnable (ram_enable[i] && !ram_write), + .ReadAddr (ram_addr ), + .ReadData (ram_rtag[i] ), + .WriteEnable(ram_enable[i] && ram_write ), + .WriteAddr (ram_addr ), + .WriteData (ram_wtag ) + ); + end else begin : gen_sram + tc_sram #( + .DataWidth ( CFG.TAG_WIDTH+2 ), + .NumWords ( CFG.LINE_COUNT ), + .NumPorts ( 1 ) + ) i_tag ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( ram_enable[i] ), + .we_i ( ram_write ), + .addr_i ( ram_addr ), + .wdata_i ( ram_wtag ), + .be_i ( '1 ), + .rdata_o ( ram_rtag[i] ) + ); + end end // Single data bank for all sets diff --git a/hardware/deps/snitch/src/snitch_icache/snitch_icache_pkg.sv b/hardware/deps/snitch/src/snitch_icache/snitch_icache_pkg.sv index 3b978f126..ba35002ee 100644 --- a/hardware/deps/snitch/src/snitch_icache/snitch_icache_pkg.sv +++ b/hardware/deps/snitch/src/snitch_icache/snitch_icache_pkg.sv @@ -30,6 +30,7 @@ package snitch_icache_pkg; int FETCH_DW; int FILL_AW; int FILL_DW; + bit L1_TAG_SCM; bit EARLY_LATCH; // Derived values. diff --git a/hardware/src/mempool_tile.sv b/hardware/src/mempool_tile.sv index b8664414b..79e5546a2 100644 --- a/hardware/src/mempool_tile.sv +++ b/hardware/src/mempool_tile.sv @@ -162,6 +162,7 @@ module mempool_tile .FETCH_DW (DataWidth ), .FILL_AW (AddrWidth ), .FILL_DW (AxiDataWidth ), + .L1_TAG_SCM (1 ), /// Make the early cache latch-based. This reduces latency at the cost of /// increased combinatorial path lengths and the hassle of having latches in /// the design. From 73e6c1efbe7e950dbb119943344e0467ad4004d4 Mon Sep 17 00:00:00 2001 From: Samuel Riedel Date: Mon, 29 Mar 2021 17:54:34 +0200 Subject: [PATCH 16/16] [CHANGELOG] Release 0.2.0 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32dc00be8..1095a1e30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased + +## 0.2.0 - 2021-03-29 + ### Added - Assertion checking that Snitch's instruction interface is stable during stalls