diff --git a/Bender.yml b/Bender.yml index 2ff83d4633..69cf4a9705 100644 --- a/Bender.yml +++ b/Bender.yml @@ -13,6 +13,8 @@ dependencies: fpnew: { git: "https://github.com/pulp-platform/cvfpu.git", rev: pulp-v0.1.1 } tech_cells_generic: { git: "https://github.com/pulp-platform/tech_cells_generic.git", version: 0.2.13 } + redundancy_cells: + { git: "https://github.com/pulp-platform/redundancy_cells.git", rev: c37bdb47339bf70e8323de8df14ea8bbeafb6583 } # branch: astral_rebase frozen: true @@ -251,6 +253,10 @@ sources: - include_dirs: - common/local/util files: + - common/local/util/secded_13_8.sv + - common/local/util/secded_39_32.sv + - common/local/util/secded_72_64.sv + - common/local/util/ecc_wrap.sv - common/local/util/sram_pulp.sv - target: not(all(fpga, xilinx)) diff --git a/common/local/util/ecc_wrap.sv b/common/local/util/ecc_wrap.sv new file mode 100644 index 0000000000..25737cd056 --- /dev/null +++ b/common/local/util/ecc_wrap.sv @@ -0,0 +1,47 @@ +// Copyright 2018 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: Yvan Tortorella , University of Bologna +// Description: parametric ECC wrapper for SEC-DED in CVA6 SRAMs + +module ecc_wrap #( + parameter int unsigned DataWidth = 32, + parameter int unsigned ParityWidth = 7 , + localparam int unsigned EccDataWidth = DataWidth + ParityWidth +)( + input logic [DataWidth-1:0] wdata_i, + output logic [EccDataWidth-1:0] wdata_o, + input logic [EccDataWidth-1:0] rdata_i, + output logic [DataWidth-1:0] rdata_o, + output logic [ParityWidth-1:0] syndrome_o, + output logic [1:0] error_o +); + +hsiao_ecc_enc #( + .DataWidth ( DataWidth ), + .ProtWidth ( ParityWidth ), + .TotalWidth ( EccDataWidth ) +) i_ecc_encoder ( + .in ( wdata_i ), + .out ( wdata_o ) +); + +hsiao_ecc_dec #( + .DataWidth ( DataWidth ), + .ProtWidth ( ParityWidth ), + .TotalWidth ( EccDataWidth ) +) i_ecc_decoder ( + .in ( rdata_i ), + .d_o ( rdata_o ), + .syndrome_o ( syndrome_o ), + .err_o ( error_o ) +); + +endmodule: ecc_wrap diff --git a/common/local/util/secded_13_8.sv b/common/local/util/secded_13_8.sv new file mode 100644 index 0000000000..9416c9b34a --- /dev/null +++ b/common/local/util/secded_13_8.sv @@ -0,0 +1,54 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// HSIAO SECDED Encoder/Decoder for 8-bit words + +module secded_13_8_enc ( + input [7:0] in, + output logic [12:0] out +); + + always_comb begin : p_encode + out[7:0] = in; + out[8] = ^(in & 8'h6B); + out[9] = ^(in & 8'hF8); + out[10] = ^(in & 8'hD5); + out[11] = ^(in & 8'hA7); + out[12] = ^(in & 8'h1E); + end + +endmodule : secded_13_8_enc + +module secded_13_8_dec ( + input [12:0] in, + output logic [7:0] d_o, + output logic [4:0] syndrome_o, + output logic [1:0] err_o +); + + logic single_error; + + // Syndrome calculation + assign syndrome_o[0] = ^(in & 13'h016B); + assign syndrome_o[1] = ^(in & 13'h02F8); + assign syndrome_o[2] = ^(in & 13'h04D5); + assign syndrome_o[3] = ^(in & 13'h08A7); + assign syndrome_o[4] = ^(in & 13'h101E); + + // Corrected output calculation + assign d_o[0] = (syndrome_o == 5'hd) ^ in[0]; + assign d_o[1] = (syndrome_o == 5'h19) ^ in[1]; + assign d_o[2] = (syndrome_o == 5'h1c) ^ in[2]; + assign d_o[3] = (syndrome_o == 5'h13) ^ in[3]; + assign d_o[4] = (syndrome_o == 5'h16) ^ in[4]; + assign d_o[5] = (syndrome_o == 5'hb) ^ in[5]; + assign d_o[6] = (syndrome_o == 5'h7) ^ in[6]; + assign d_o[7] = (syndrome_o == 5'he) ^ in[7]; + + // err_o calc. bit0: single error, bit1: double error + assign single_error = ^syndrome_o; + assign err_o[0] = single_error; + assign err_o[1] = ~single_error & (|syndrome_o); + +endmodule : secded_13_8_dec diff --git a/common/local/util/secded_39_32.sv b/common/local/util/secded_39_32.sv new file mode 100644 index 0000000000..132a079abc --- /dev/null +++ b/common/local/util/secded_39_32.sv @@ -0,0 +1,82 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// HSIAO SECDED Encoder/Decoder for 32-bit words + +module secded_39_32_enc ( + input [31:0] in, + output logic [38:0] out +); + + always_comb begin : p_encode + out[31:0] = in; + out[32] = ^(in & 32'h3800CDBC); + out[33] = ^(in & 32'hC439C325); + out[34] = ^(in & 32'h52D82C63); + out[35] = ^(in & 32'hA4363856); + out[36] = ^(in & 32'h9B833109); + out[37] = ^(in & 32'h2DCF42C0); + out[38] = ^(in & 32'h4364969A); + end + +endmodule : secded_39_32_enc + +module secded_39_32_dec ( + input [38:0] in, + output logic [31:0] d_o, + output logic [6:0] syndrome_o, + output logic [1:0] err_o +); + + logic single_error; + + // Syndrome calculation + assign syndrome_o[0] = ^(in & 39'h013800CDBC); + assign syndrome_o[1] = ^(in & 39'h02C439C325); + assign syndrome_o[2] = ^(in & 39'h0452D82C63); + assign syndrome_o[3] = ^(in & 39'h08A4363856); + assign syndrome_o[4] = ^(in & 39'h109B833109); + assign syndrome_o[5] = ^(in & 39'h202DCF42C0); + assign syndrome_o[6] = ^(in & 39'h404364969A); + + // Corrected output calculation + assign d_o[0] = (syndrome_o == 7'h16) ^ in[0]; + assign d_o[1] = (syndrome_o == 7'h4c) ^ in[1]; + assign d_o[2] = (syndrome_o == 7'hb) ^ in[2]; + assign d_o[3] = (syndrome_o == 7'h51) ^ in[3]; + assign d_o[4] = (syndrome_o == 7'h49) ^ in[4]; + assign d_o[5] = (syndrome_o == 7'h7) ^ in[5]; + assign d_o[6] = (syndrome_o == 7'h2c) ^ in[6]; + assign d_o[7] = (syndrome_o == 7'h61) ^ in[7]; + assign d_o[8] = (syndrome_o == 7'h13) ^ in[8]; + assign d_o[9] = (syndrome_o == 7'h62) ^ in[9]; + assign d_o[10] = (syndrome_o == 7'h45) ^ in[10]; + assign d_o[11] = (syndrome_o == 7'hd) ^ in[11]; + assign d_o[12] = (syndrome_o == 7'h58) ^ in[12]; + assign d_o[13] = (syndrome_o == 7'h1c) ^ in[13]; + assign d_o[14] = (syndrome_o == 7'h23) ^ in[14]; + assign d_o[15] = (syndrome_o == 7'h43) ^ in[15]; + assign d_o[16] = (syndrome_o == 7'h32) ^ in[16]; + assign d_o[17] = (syndrome_o == 7'h38) ^ in[17]; + assign d_o[18] = (syndrome_o == 7'h68) ^ in[18]; + assign d_o[19] = (syndrome_o == 7'h26) ^ in[19]; + assign d_o[20] = (syndrome_o == 7'he) ^ in[20]; + assign d_o[21] = (syndrome_o == 7'h4a) ^ in[21]; + assign d_o[22] = (syndrome_o == 7'h64) ^ in[22]; + assign d_o[23] = (syndrome_o == 7'h34) ^ in[23]; + assign d_o[24] = (syndrome_o == 7'h70) ^ in[24]; + assign d_o[25] = (syndrome_o == 7'h54) ^ in[25]; + assign d_o[26] = (syndrome_o == 7'h2a) ^ in[26]; + assign d_o[27] = (syndrome_o == 7'h31) ^ in[27]; + assign d_o[28] = (syndrome_o == 7'h15) ^ in[28]; + assign d_o[29] = (syndrome_o == 7'h29) ^ in[29]; + assign d_o[30] = (syndrome_o == 7'h46) ^ in[30]; + assign d_o[31] = (syndrome_o == 7'h1a) ^ in[31]; + + // err_o calc. bit0: single error, bit1: double error + assign single_error = ^syndrome_o; + assign err_o[0] = single_error; + assign err_o[1] = ~single_error & (|syndrome_o); + +endmodule : secded_39_32_dec diff --git a/common/local/util/secded_72_64.sv b/common/local/util/secded_72_64.sv new file mode 100644 index 0000000000..47f380dcaf --- /dev/null +++ b/common/local/util/secded_72_64.sv @@ -0,0 +1,116 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// HSIAO SECDED Encoder/Decoder for 64-bit words + +module secded_72_64_enc ( + input [63:0] in, + output logic [71:0] out +); + + always_comb begin : p_encode + out[63:0] = in; + out[64] = ^(in & 64'hF8000000001FFFFF); + out[65] = ^(in & 64'h9D00000FFFE0003F); + out[66] = ^(in & 64'h8F003FF003E007C1); + out[67] = ^(in & 64'hF10FC0F03C207842); + out[68] = ^(in & 64'h6E71C711C4438884); + out[69] = ^(in & 64'h3EB65926488C9108); + out[70] = ^(in & 64'hD3DAAA4A91152210); + out[71] = ^(in & 64'h67ED348D221A4420); + end + +endmodule : secded_72_64_enc + +module secded_72_64_dec ( + input [71:0] in, + output logic [63:0] d_o, + output logic [7:0] syndrome_o, + output logic [1:0] err_o +); + + logic single_error; + + // Syndrome calculation + assign syndrome_o[0] = ^(in & 72'h01F8000000001FFFFF); + assign syndrome_o[1] = ^(in & 72'h029D00000FFFE0003F); + assign syndrome_o[2] = ^(in & 72'h048F003FF003E007C1); + assign syndrome_o[3] = ^(in & 72'h08F10FC0F03C207842); + assign syndrome_o[4] = ^(in & 72'h106E71C711C4438884); + assign syndrome_o[5] = ^(in & 72'h203EB65926488C9108); + assign syndrome_o[6] = ^(in & 72'h40D3DAAA4A91152210); + assign syndrome_o[7] = ^(in & 72'h8067ED348D221A4420); + + // Corrected output calculation + assign d_o[0] = (syndrome_o == 8'h7) ^ in[0]; + assign d_o[1] = (syndrome_o == 8'hb) ^ in[1]; + assign d_o[2] = (syndrome_o == 8'h13) ^ in[2]; + assign d_o[3] = (syndrome_o == 8'h23) ^ in[3]; + assign d_o[4] = (syndrome_o == 8'h43) ^ in[4]; + assign d_o[5] = (syndrome_o == 8'h83) ^ in[5]; + assign d_o[6] = (syndrome_o == 8'hd) ^ in[6]; + assign d_o[7] = (syndrome_o == 8'h15) ^ in[7]; + assign d_o[8] = (syndrome_o == 8'h25) ^ in[8]; + assign d_o[9] = (syndrome_o == 8'h45) ^ in[9]; + assign d_o[10] = (syndrome_o == 8'h85) ^ in[10]; + assign d_o[11] = (syndrome_o == 8'h19) ^ in[11]; + assign d_o[12] = (syndrome_o == 8'h29) ^ in[12]; + assign d_o[13] = (syndrome_o == 8'h49) ^ in[13]; + assign d_o[14] = (syndrome_o == 8'h89) ^ in[14]; + assign d_o[15] = (syndrome_o == 8'h31) ^ in[15]; + assign d_o[16] = (syndrome_o == 8'h51) ^ in[16]; + assign d_o[17] = (syndrome_o == 8'h91) ^ in[17]; + assign d_o[18] = (syndrome_o == 8'h61) ^ in[18]; + assign d_o[19] = (syndrome_o == 8'ha1) ^ in[19]; + assign d_o[20] = (syndrome_o == 8'hc1) ^ in[20]; + assign d_o[21] = (syndrome_o == 8'he) ^ in[21]; + assign d_o[22] = (syndrome_o == 8'h16) ^ in[22]; + assign d_o[23] = (syndrome_o == 8'h26) ^ in[23]; + assign d_o[24] = (syndrome_o == 8'h46) ^ in[24]; + assign d_o[25] = (syndrome_o == 8'h86) ^ in[25]; + assign d_o[26] = (syndrome_o == 8'h1a) ^ in[26]; + assign d_o[27] = (syndrome_o == 8'h2a) ^ in[27]; + assign d_o[28] = (syndrome_o == 8'h4a) ^ in[28]; + assign d_o[29] = (syndrome_o == 8'h8a) ^ in[29]; + assign d_o[30] = (syndrome_o == 8'h32) ^ in[30]; + assign d_o[31] = (syndrome_o == 8'h52) ^ in[31]; + assign d_o[32] = (syndrome_o == 8'h92) ^ in[32]; + assign d_o[33] = (syndrome_o == 8'h62) ^ in[33]; + assign d_o[34] = (syndrome_o == 8'ha2) ^ in[34]; + assign d_o[35] = (syndrome_o == 8'hc2) ^ in[35]; + assign d_o[36] = (syndrome_o == 8'h1c) ^ in[36]; + assign d_o[37] = (syndrome_o == 8'h2c) ^ in[37]; + assign d_o[38] = (syndrome_o == 8'h4c) ^ in[38]; + assign d_o[39] = (syndrome_o == 8'h8c) ^ in[39]; + assign d_o[40] = (syndrome_o == 8'h34) ^ in[40]; + assign d_o[41] = (syndrome_o == 8'h54) ^ in[41]; + assign d_o[42] = (syndrome_o == 8'h94) ^ in[42]; + assign d_o[43] = (syndrome_o == 8'h64) ^ in[43]; + assign d_o[44] = (syndrome_o == 8'ha4) ^ in[44]; + assign d_o[45] = (syndrome_o == 8'hc4) ^ in[45]; + assign d_o[46] = (syndrome_o == 8'h38) ^ in[46]; + assign d_o[47] = (syndrome_o == 8'h58) ^ in[47]; + assign d_o[48] = (syndrome_o == 8'h98) ^ in[48]; + assign d_o[49] = (syndrome_o == 8'h68) ^ in[49]; + assign d_o[50] = (syndrome_o == 8'ha8) ^ in[50]; + assign d_o[51] = (syndrome_o == 8'hc8) ^ in[51]; + assign d_o[52] = (syndrome_o == 8'h70) ^ in[52]; + assign d_o[53] = (syndrome_o == 8'hb0) ^ in[53]; + assign d_o[54] = (syndrome_o == 8'hd0) ^ in[54]; + assign d_o[55] = (syndrome_o == 8'he0) ^ in[55]; + assign d_o[56] = (syndrome_o == 8'hce) ^ in[56]; + assign d_o[57] = (syndrome_o == 8'hf4) ^ in[57]; + assign d_o[58] = (syndrome_o == 8'hb6) ^ in[58]; + assign d_o[59] = (syndrome_o == 8'h37) ^ in[59]; + assign d_o[60] = (syndrome_o == 8'h6b) ^ in[60]; + assign d_o[61] = (syndrome_o == 8'hb9) ^ in[61]; + assign d_o[62] = (syndrome_o == 8'hd9) ^ in[62]; + assign d_o[63] = (syndrome_o == 8'h4f) ^ in[63]; + + // err_o calc. bit0: single error, bit1: double error + assign single_error = ^syndrome_o; + assign err_o[0] = single_error; + assign err_o[1] = ~single_error & (|syndrome_o); + +endmodule : secded_72_64_dec diff --git a/common/local/util/sram_pulp.sv b/common/local/util/sram_pulp.sv index 360b8c77eb..fa4a7e5d84 100644 --- a/common/local/util/sram_pulp.sv +++ b/common/local/util/sram_pulp.sv @@ -20,13 +20,15 @@ // `FPGA_TARGET_ALTERA in your build environment (default is ALTERA) module sram #( - parameter DATA_WIDTH = 64, - parameter BYTE_WIDTH = 8, - parameter USER_WIDTH = 1, - parameter USER_EN = 0, - parameter NUM_WORDS = 1024, - parameter SIM_INIT = "zeros", - parameter OUT_REGS = 0 // enables output registers in FPGA macro (read lat = 2) + parameter DATA_WIDTH = 64, + parameter BYTE_WIDTH = 8, + parameter USER_WIDTH = 1, + parameter USER_EN = 0, + parameter NUM_WORDS = 1024, + parameter ENABLE_ECC = 0, // Enable or disable SRAM with error correcting codes + parameter ECC_GRANULARITY = 0, + parameter SIM_INIT = "zeros", + parameter OUT_REGS = 0 // enables output registers in FPGA macro (read lat = 2) )( input logic clk_i, input logic rst_ni, @@ -37,9 +39,122 @@ module sram #( input logic [DATA_WIDTH-1:0] wdata_i, input logic [(DATA_WIDTH+BYTE_WIDTH-1)/BYTE_WIDTH-1:0] be_i, output logic [USER_WIDTH-1:0] ruser_o, - output logic [DATA_WIDTH-1:0] rdata_o + output logic [DATA_WIDTH-1:0] rdata_o, + output logic [1:0] error_o, + output logic [1:0] user_error_o ); +if (ENABLE_ECC) begin: gen_ecc_sram + + localparam int unsigned G = (ECC_GRANULARITY == 0) ? DATA_WIDTH : ECC_GRANULARITY; + localparam int unsigned NumBanks = DATA_WIDTH/G; + + localparam int unsigned K = $clog2(G) + 2; + + localparam int unsigned EccDataWidth = G + K; + localparam int unsigned BeWidth = (G+BYTE_WIDTH-1)/BYTE_WIDTH; + localparam int unsigned EccBeWidth = (EccDataWidth+BYTE_WIDTH-1)/BYTE_WIDTH; + localparam int unsigned BeWidthDiff = EccBeWidth - BeWidth; + + logic [NumBanks-1:0][G-1:0] wdata, rdata, wuser, ruser; + logic [NumBanks-1:0][EccDataWidth-1:0] ecc_wdata, ecc_rdata, ecc_wuser, ecc_ruser; + logic [NumBanks-1:0][K-1:0] syndrome, user_syndrome; + logic [NumBanks-1:0][1:0] ecc_error, user_ecc_error; + logic [NumBanks-1:0] correctable_error, uncorrectable_error, + user_correctable_error, user_uncorrectable_error; + logic [NumBanks-1:0][EccBeWidth-1:0] ecc_be; + + assign error_o[0] = |correctable_error; + assign error_o[1] = |uncorrectable_error; + assign user_error_o[0] = |user_correctable_error; + assign user_error_o[1] = |user_uncorrectable_error; + for (genvar i = 0; i < NumBanks; i++) begin: gen_data_split + assign wdata[i] = wdata_i[G*i+:G]; + assign rdata_o[G*i+:G] = rdata[i]; + assign ecc_be[i] = {{BeWidthDiff{|be_i[i*BeWidth+:BeWidth]}}, be_i[i*BeWidth+:BeWidth]}; + assign correctable_error[i] = ecc_error[i][0]; + assign uncorrectable_error[i] = ecc_error[i][1]; + + ecc_wrap #( + .DataWidth ( G ), + .ParityWidth ( K ) + ) i_ecc_wrap ( + .wdata_i ( wdata[i] ), + .wdata_o ( ecc_wdata[i] ), + .rdata_i ( ecc_rdata[i] ), + .rdata_o ( rdata[i] ), + .syndrome_o ( syndrome[i] ), + .error_o ( ecc_error[i] ) + ); + + tc_sram #( + .NumWords ( NUM_WORDS ), + .DataWidth ( EccDataWidth ), + .ByteWidth ( BYTE_WIDTH ), + .NumPorts ( 32'd1 ), + .Latency ( 32'd1 ), + .SimInit ( SIM_INIT ), + .PrintSimCfg ( 1'b0 ) + ) i_ecc_sram ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( req_i ), + .we_i ( we_i ), + .be_i ( ecc_be[i] ), + .wdata_i ( ecc_wdata[i] ), + .addr_i ( addr_i ), + .rdata_o ( ecc_rdata[i] ) + ); + + if (USER_EN > 1) begin: gen_ecc_mem_user + assign wuser[i] = wuser_i[G*i+:G]; + assign ruser_o[G*i+:G] = ruser[i]; + assign user_correctable_error[i] = user_ecc_error[i][0]; + assign user_uncorrectable_error[i] = user_ecc_error[i][1]; + + ecc_wrap #( + .DataWidth ( G ), + .ParityWidth ( K ) + ) i_ecc_wrap ( + .wdata_i ( wuser[i] ), + .wdata_o ( ecc_wuser[i] ), + .rdata_i ( ecc_ruser[i] ), + .rdata_o ( ruser[i] ), + .syndrome_o ( user_syndrome[i] ), + .error_o ( user_ecc_error[i] ) + ); + + tc_sram #( + .NumWords ( NUM_WORDS ), + .DataWidth ( EccDataWidth ), + .ByteWidth ( BYTE_WIDTH ), + .NumPorts ( 32'd1 ), + .Latency ( 32'd1 ), + .SimInit ( SIM_INIT ), + .PrintSimCfg ( 1'b0 ) + ) i_ecc_sram ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( req_i ), + .we_i ( we_i ), + .be_i ( ecc_be[i] ), + .wdata_i ( ecc_wuser[i] ), + .addr_i ( addr_i ), + .rdata_o ( ecc_ruser[i] ) + ); + + if (USER_WIDTH != DATA_WIDTH) + $fatal(1, "sram_pulp: USER_WIDTH needs to be equal to DATA_WIDTH (if USER_EN is set)."); + end else begin + assign user_correctable_error[i] = '0; + assign user_uncorrectable_error[i] = '0; + end + end + +end else begin: gen_standard_sram + assign error_o = '0; + assign user_error_o = '0; + tc_sram #( .NumWords ( NUM_WORDS ), .DataWidth ( DATA_WIDTH ), @@ -86,5 +201,6 @@ module sram #( end else begin assign ruser_o = '0; end +end endmodule : sram diff --git a/core/cache_subsystem/cva6_icache.sv b/core/cache_subsystem/cva6_icache.sv index 978c2720bf..2ce32433f7 100644 --- a/core/cache_subsystem/cva6_icache.sv +++ b/core/cache_subsystem/cva6_icache.sv @@ -30,6 +30,7 @@ module cva6_icache import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter bit EnableEcc = 0, /// ID to be used for read transactions parameter logic [MEM_TID_WIDTH-1:0] RdTxId = 0 ) ( @@ -455,7 +456,8 @@ module cva6_icache sram #( // tag + valid bit .DATA_WIDTH(ICACHE_TAG_WIDTH + 1), - .NUM_WORDS (ICACHE_NUM_WORDS) + .NUM_WORDS (ICACHE_NUM_WORDS), + .ENABLE_ECC (EnableEcc) ) tag_sram ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -468,7 +470,9 @@ module cva6_icache .wdata_i({vld_wdata[i], cl_tag_q}), .be_i ('1), .ruser_o(), - .rdata_o(cl_tag_valid_rdata[i]) + .rdata_o(cl_tag_valid_rdata[i]), + .error_o (/* TODO: Connect */), + .user_error_o (/* TODO: Connect */) ); assign cl_tag_rdata[i] = cl_tag_valid_rdata[i][ICACHE_TAG_WIDTH-1:0]; @@ -479,7 +483,9 @@ module cva6_icache .USER_WIDTH(ICACHE_USER_LINE_WIDTH), .DATA_WIDTH(ICACHE_LINE_WIDTH), .USER_EN (ariane_pkg::FETCH_USER_EN), - .NUM_WORDS (ICACHE_NUM_WORDS) + .NUM_WORDS (ICACHE_NUM_WORDS), + .ENABLE_ECC(EnableEcc), + .ECC_GRANULARITY(32) ) data_sram ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -490,7 +496,9 @@ module cva6_icache .wdata_i(mem_rtrn_i.data), .be_i ('1), .ruser_o(cl_ruser[i]), - .rdata_o(cl_rdata[i]) + .rdata_o(cl_rdata[i]), + .error_o(/* TODO: Connect */), + .user_error_o(/* TODO: Connect */) ); end diff --git a/core/cache_subsystem/cva6_icache_axi_wrapper.sv b/core/cache_subsystem/cva6_icache_axi_wrapper.sv index 4561fc551f..5ae2930958 100644 --- a/core/cache_subsystem/cva6_icache_axi_wrapper.sv +++ b/core/cache_subsystem/cva6_icache_axi_wrapper.sv @@ -18,6 +18,7 @@ module cva6_icache_axi_wrapper import wt_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter bit EnableEcc = 0, parameter type axi_req_t = logic, parameter type axi_rsp_t = logic ) ( @@ -105,6 +106,7 @@ module cva6_icache_axi_wrapper cva6_icache #( // use ID 0 for icache reads .CVA6Cfg(CVA6Cfg), + .EnableEcc(EnableEcc), .RdTxId (0) ) i_cva6_icache ( .clk_i (clk_i), diff --git a/core/cache_subsystem/std_cache_subsystem.sv b/core/cache_subsystem/std_cache_subsystem.sv index 3695e50c23..efd6967399 100644 --- a/core/cache_subsystem/std_cache_subsystem.sv +++ b/core/cache_subsystem/std_cache_subsystem.sv @@ -20,6 +20,7 @@ module std_cache_subsystem import std_cache_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter bit EnableEcc = 0, parameter int unsigned NumPorts = 4, parameter type axi_ar_chan_t = logic, parameter type axi_aw_chan_t = logic, @@ -77,6 +78,7 @@ module std_cache_subsystem cva6_icache_axi_wrapper #( .CVA6Cfg (CVA6Cfg), + .EnableEcc(EnableEcc), .axi_req_t(axi_req_t), .axi_rsp_t(axi_rsp_t) ) i_cva6_icache_axi_wrapper ( @@ -105,6 +107,7 @@ module std_cache_subsystem std_nbdcache #( .CVA6Cfg (CVA6Cfg), .NumPorts (NumPorts), + .EnableEcc(EnableEcc), .axi_req_t(axi_req_t), .axi_rsp_t(axi_rsp_t) ) i_nbdcache ( diff --git a/core/cache_subsystem/std_nbdcache.sv b/core/cache_subsystem/std_nbdcache.sv index 5d904cf998..6e0d38ba1c 100644 --- a/core/cache_subsystem/std_nbdcache.sv +++ b/core/cache_subsystem/std_nbdcache.sv @@ -19,6 +19,7 @@ module std_nbdcache #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter int unsigned NumPorts = 4, + parameter bit EnableEcc = 0, parameter type axi_req_t = logic, parameter type axi_rsp_t = logic ) ( @@ -186,7 +187,9 @@ module std_nbdcache for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin : sram_block sram #( .DATA_WIDTH(DCACHE_LINE_WIDTH), - .NUM_WORDS (DCACHE_NUM_WORDS) + .NUM_WORDS (DCACHE_NUM_WORDS), + .ENABLE_ECC(EnableEcc), + .ECC_GRANULARITY(32) ) data_sram ( .req_i (req_ram[i]), .rst_ni (rst_ni), @@ -197,12 +200,15 @@ module std_nbdcache .be_i (be_ram.data), .ruser_o(), .rdata_o(rdata_ram[i].data), + .error_o(/* TODO: Connect */), + .user_error_o(/* TODO: Connect */), .* ); sram #( .DATA_WIDTH(DCACHE_TAG_WIDTH), - .NUM_WORDS (DCACHE_NUM_WORDS) + .NUM_WORDS (DCACHE_NUM_WORDS), + .ENABLE_ECC(EnableEcc) ) tag_sram ( .req_i (req_ram[i]), .rst_ni (rst_ni), @@ -213,6 +219,8 @@ module std_nbdcache .be_i (be_ram.tag), .ruser_o(), .rdata_o(rdata_ram[i].tag), + .error_o(/* TODO: Connect */), + .user_error_o(/* TODO: Connect */), .* ); @@ -236,7 +244,9 @@ module std_nbdcache .USER_WIDTH(1), .DATA_WIDTH(DCACHE_SET_ASSOC * $bits(vldrty_t)), .BYTE_WIDTH(1), - .NUM_WORDS (DCACHE_NUM_WORDS) + .NUM_WORDS (DCACHE_NUM_WORDS), + .ENABLE_ECC(EnableEcc), + .ECC_GRANULARITY(8) // TODO: fix to use 32 ) valid_dirty_sram ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -247,7 +257,9 @@ module std_nbdcache .wdata_i(dirty_wdata), .be_i (be_valid_dirty_ram), .ruser_o(), - .rdata_o(dirty_rdata) + .rdata_o(dirty_rdata), + .error_o(/* TODO: Connect */), + .user_error_o(/* TODO: Connect */) ); // ------------------------------------------------ diff --git a/core/cache_subsystem/wt_dcache_mem.sv b/core/cache_subsystem/wt_dcache_mem.sv index b2b41c3c73..5dd8d1a70a 100644 --- a/core/cache_subsystem/wt_dcache_mem.sv +++ b/core/cache_subsystem/wt_dcache_mem.sv @@ -312,7 +312,9 @@ module wt_dcache_mem .wdata_i(bank_wdata[k]), .be_i (bank_be[k]), .ruser_o(bank_ruser[k]), - .rdata_o(bank_rdata[k]) + .rdata_o(bank_rdata[k]), + .error_o(), + .user_error_o() ); end @@ -336,7 +338,9 @@ module wt_dcache_mem .wdata_i({vld_wdata[i], wr_cl_tag_i}), .be_i ('1), .ruser_o(), - .rdata_o(vld_tag_rdata[i]) + .rdata_o(vld_tag_rdata[i]), + .error_o(), + .user_error_o() ); end diff --git a/core/cva6.sv b/core/cva6.sv index 88ac521991..a330870b1a 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -12,12 +12,12 @@ // Date: 19.03.2017 // Description: CVA6 Top-level module - module cva6 import ariane_pkg::*; #( // CVA6 config parameter config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg, + parameter bit EnableEcc = 0, parameter bit IsRVFI = bit'(cva6_config_pkg::CVA6ConfigRvfiTrace), // RVFI parameter type rvfi_probes_t = struct packed { @@ -1232,6 +1232,7 @@ module cva6 // not as important since this cache subsystem is about to be // deprecated .CVA6Cfg (CVA6ExtendCfg), + .EnableEcc (EnableEcc), .NumPorts (NumPorts), .axi_ar_chan_t(axi_ar_chan_t), .axi_aw_chan_t(axi_aw_chan_t), diff --git a/core/mmu_sv32/cva6_shared_tlb_sv32.sv b/core/mmu_sv32/cva6_shared_tlb_sv32.sv index 98e2a044a9..fa9b6f2eee 100644 --- a/core/mmu_sv32/cva6_shared_tlb_sv32.sv +++ b/core/mmu_sv32/cva6_shared_tlb_sv32.sv @@ -339,7 +339,9 @@ module cva6_shared_tlb_sv32 .wdata_i(tag_wr_data), .be_i ('1), .ruser_o(), - .rdata_o(tag_rd_data[i]) + .rdata_o(tag_rd_data[i]), + .error_o(/* TODO: Connect */), + .user_error_o(/* TODO: Connect */) ); assign shared_tag_rd[i] = shared_tag_t'(tag_rd_data[i]); @@ -358,7 +360,9 @@ module cva6_shared_tlb_sv32 .wdata_i(pte_wr_data), .be_i ('1), .ruser_o(), - .rdata_o(pte_rd_data[i]) + .rdata_o(pte_rd_data[i]), + .error_o(/* TODO: Connect */), + .user_error_o(/* TODO: Connect */) ); assign pte[i] = riscv::pte_sv32_t'(pte_rd_data[i]); end diff --git a/corev_apu/tb/ariane_tb.cpp b/corev_apu/tb/ariane_tb.cpp index 5c03f1b7e2..60c7439780 100644 --- a/corev_apu/tb/ariane_tb.cpp +++ b/corev_apu/tb/ariane_tb.cpp @@ -333,10 +333,10 @@ int main(int argc, char **argv) { // Preload memory. #if (VERILATOR_VERSION_INTEGER >= 5000000) // Verilator v5: Use rootp pointer and .data() accessor. -#define MEM top->rootp->ariane_testharness__DOT__i_sram__DOT__i_tc_sram__DOT__sram.m_storage +#define MEM top->rootp->ariane_testharness__DOT__i_sram__DOT__gen_standard_sram__DOT__i_tc_sram__DOT__sram.m_storage #else // Verilator v4 -#define MEM top->ariane_testharness__DOT__i_sram__DOT__i_tc_sram__DOT__sram +#define MEM top->ariane_testharness__DOT__i_sram__DOT__gen_standard_sram__DOT__i_tc_sram__DOT__sram #endif long long addr; long long len; diff --git a/corev_apu/tb/ariane_testharness.sv b/corev_apu/tb/ariane_testharness.sv index 63a4877c6b..45ddb97b3e 100644 --- a/corev_apu/tb/ariane_testharness.sv +++ b/corev_apu/tb/ariane_testharness.sv @@ -507,16 +507,18 @@ module ariane_testharness #( `endif .NUM_WORDS ( NUM_WORDS ) ) i_sram ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .req_i ( req ), - .we_i ( we ), - .addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ), - .wuser_i ( wuser ), - .wdata_i ( wdata ), - .be_i ( be ), - .ruser_o ( ruser ), - .rdata_o ( rdata ) + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( req ), + .we_i ( we ), + .addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ), + .wuser_i ( wuser ), + .wdata_i ( wdata ), + .be_i ( be ), + .ruser_o ( ruser ), + .rdata_o ( rdata ), + .error_o ( ), + .user_error_o ( ) ); // ---------------