diff --git a/Makefile b/Makefile index 588f335a7b9cee25b4b163778ada0e8f67d5ea5e..af8868aa8dbb68f9dfdc05174fa19b83efb03672 100644 --- a/Makefile +++ b/Makefile @@ -68,8 +68,8 @@ ariane_pkg := $(addprefix $(root-dir), $(ariane_pkg)) # utility modules util := $(wildcard src/util/*.svh) \ - src/util/instruction_tracer_pkg.sv \ src/util/instruction_tracer_if.sv \ + src/util/instruction_tracer.sv \ src/tech_cells_generic/src/cluster_clock_gating.sv \ tb/common/mock_uart.sv \ src/util/sram.sv @@ -456,12 +456,13 @@ check-torture: diff -s $(riscv-torture-dir)/$(test-location).spike.sig $(riscv-torture-dir)/$(test-location).rtlsim.sig fpga_filter := $(addprefix $(root-dir), bootrom/bootrom.sv) +fpga_filter += $(addprefix $(root-dir), src/util/instruction_tracer.sv) -fpga: $(ariane_pkg) $(util) $(src) $(fpga_src) $(util) $(uart_src) +fpga: $(ariane_pkg) $(util) $(src) $(fpga_src) $(uart_src) @echo "[FPGA] Generate sources" @echo read_vhdl {$(uart_src)} > fpga/scripts/add_sources.tcl @echo read_verilog -sv {$(ariane_pkg)} >> fpga/scripts/add_sources.tcl - @echo read_verilog -sv {$(util)} >> fpga/scripts/add_sources.tcl + @echo read_verilog -sv {$(filter-out $(fpga_filter), $(util))} >> fpga/scripts/add_sources.tcl @echo read_verilog -sv {$(filter-out $(fpga_filter), $(src))} >> fpga/scripts/add_sources.tcl @echo read_verilog -sv {$(fpga_src)} >> fpga/scripts/add_sources.tcl @echo "[FPGA] Generate Bitstream" diff --git a/fpga/src/ariane_xilinx.sv b/fpga/src/ariane_xilinx.sv index 1a3e674549d8e8eeb67ddd2be739c586b0487c37..d03212354a8dfffff5ffe0c98f1b6ccb7cd6ea6e 100644 --- a/fpga/src/ariane_xilinx.sv +++ b/fpga/src/ariane_xilinx.sv @@ -86,7 +86,6 @@ module ariane_xilinx ( // 24 MByte in 8 byte words localparam NumWords = (24 * 1024 * 1024) / 8; localparam NBSlave = 2; // debug, ariane -localparam logic [63:0] CacheStartAddr = 64'h8000_0000; localparam AxiAddrWidth = 64; localparam AxiDataWidth = 64; localparam AxiIdWidthMaster = 4; @@ -347,7 +346,7 @@ ariane_axi::req_t axi_ariane_req; ariane_axi::resp_t axi_ariane_resp; ariane #( - .CachedAddrBeg ( CacheStartAddr ) + .ArianeCfg ( ariane_soc::ArianeSocCfg ) ) i_ariane ( .clk_i ( clk ), .rst_ni ( ndmreset_n ), diff --git a/include/ariane_pkg.sv b/include/ariane_pkg.sv index 8a02aa916db3c35b0c7f8792d2478462addb3df7..58a6aa43069bd8124b6bebcb0296bc6ff9935e6e 100644 --- a/include/ariane_pkg.sv +++ b/include/ariane_pkg.sv @@ -31,46 +31,101 @@ package ariane_pkg; // This is the new user config interface system. If you need to parameterize something // within Ariane add a field here and assign a default value to the config. Please make // sure to add a propper parameter check to the `check_cfg` function. + localparam NrMaxRules = 16; + typedef struct packed { - int NrNonIdempotentRules; // Number of non idempotent rules - logic [15:0][63:0] NonIdempotentAddrBase; // base which needs to match - logic [15:0][63:0] NonIdempotentLength; // bit mask which bits to consider when matching the rule - int NrExecuteRegionRules; // Number of regions which have execute property - logic [15:0][63:0] ExecuteRegionAddrBase; // base which needs to match - logic [15:0][63:0] ExecuteRegionLength; // bit mask which bits to consider when matching the rule + // PMAs + int NrNonIdempotentRules; // Number of non idempotent rules + logic [NrMaxRules-1:0][63:0] NonIdempotentAddrBase; // base which needs to match + logic [NrMaxRules-1:0][63:0] NonIdempotentLength; // bit mask which bits to consider when matching the rule + int NrExecuteRegionRules; // Number of regions which have execute property + logic [NrMaxRules-1:0][63:0] ExecuteRegionAddrBase; // base which needs to match + logic [NrMaxRules-1:0][63:0] ExecuteRegionLength; // bit mask which bits to consider when matching the rule + int NrCachedRegionRules; // Number of regions which have cached property + logic [NrMaxRules-1:0][63:0] CachedRegionAddrBase; // base which needs to match + logic [NrMaxRules-1:0][63:0] CachedRegionLength; // bit mask which bits to consider when matching the rule + // cache config + bit Axi64BitCompliant; // set to 1 when using in conjunction with 64bit AXI bus adapter + bit SwapEndianess; // set to 1 to swap endianess inside L1.5 openpiton adapter + // + logic [63:0] DmBaseAddress; // offset of the debug module } ariane_cfg_t; localparam ariane_cfg_t ArianeDefaultConfig = '{ + // idempotent region NrNonIdempotentRules: 2, NonIdempotentAddrBase: {64'b0, 64'b0}, NonIdempotentLength: {64'b0, 64'b0}, NrExecuteRegionRules: 3, // DRAM, Boot ROM, Debug Module ExecuteRegionAddrBase: {64'h8000_0000, 64'h1_0000, 64'h0}, - ExecuteRegionLength: {64'h40000000, 64'h10000, 64'h1000} + ExecuteRegionLength: {64'h40000000, 64'h10000, 64'h1000}, + // cached region + NrCachedRegionRules: 1, + CachedRegionAddrBase: {64'h8000_0000}, + CachedRegionLength: {64'h40000000}, + // cache config + Axi64BitCompliant: 1'b1, + SwapEndianess: 1'b0, + // debug + DmBaseAddress: 64'h0 }; // Function being called to check parameters function automatic void check_cfg (ariane_cfg_t Cfg); // pragma translate_off `ifndef VERILATOR - assert(Cfg.NrNonIdempotentRules <= 16); - assert(Cfg.NrExecuteRegionRules <= 16); + assert(Cfg.NrNonIdempotentRules <= NrMaxRules); + assert(Cfg.NrExecuteRegionRules <= NrMaxRules); + assert(Cfg.NrCachedRegionRules <= NrMaxRules); `endif // pragma translate_on endfunction // Generate a mask for a given power of two length function logic [63:0] gen_mask (input logic [63:0] len); - // pragma translate_off - `ifndef VERILATOR - // check that the region we want is actually power of two aligned - assert (2**$clog2(len) == len) else $error("Length must be a power of two"); - `endif - // pragma translate_on return {64{1'b1}} << $clog2(len); endfunction + function automatic logic range_check(logic[63:0] base, logic[63:0] len, logic[63:0] address); + // if len is a power of two, and base is properly aligned, this chack can be simplified + automatic logic[63:0] mask; + // mask = gen_mask(len); + // if ((64'b1<<$clog2(len) == len) && (mask & base == base)) begin + // return (address & mask) == (base & mask); + // end else begin + return (address >= base) && (address < (base+len)); + // end + endfunction : range_check + + function automatic logic is_inside_nonidempotent_regions (ariane_cfg_t Cfg, logic[63:0] address); + logic[NrMaxRules-1:0] pass; + pass = '0; + for (int unsigned k=0; k<Cfg.NrNonIdempotentRules; k++) begin + pass[k] = range_check(Cfg.NonIdempotentAddrBase[k], Cfg.NonIdempotentLength[k], address); + end + return |pass; + endfunction : is_inside_nonidempotent_regions + + function automatic logic is_inside_execute_regions (ariane_cfg_t Cfg, logic[63:0] address); + // if we don't specify any region we assume everything is accessible + logic[NrMaxRules-1:0] pass; + pass = '0; + for (int unsigned k=0; k<Cfg.NrExecuteRegionRules; k++) begin + pass[k] = range_check(Cfg.ExecuteRegionAddrBase[k], Cfg.ExecuteRegionLength[k], address); + end + return |pass; + endfunction : is_inside_execute_regions + + function automatic logic is_inside_cacheable_regions (ariane_cfg_t Cfg, logic[63:0] address); + automatic logic[NrMaxRules-1:0] pass; + pass = '0; + for (int unsigned k=0; k<Cfg.NrCachedRegionRules; k++) begin + pass[k] = range_check(Cfg.CachedRegionAddrBase[k], Cfg.CachedRegionLength[k], address); + end + return |pass; + endfunction : is_inside_cacheable_regions + // TODO: Slowly move those parameters to the new system. localparam NR_SB_ENTRIES = 8; // number of scoreboard entries localparam TRANS_ID_BITS = $clog2(NR_SB_ENTRIES); // depending on the number of scoreboard entries we need that many bits diff --git a/openpiton/ariane_verilog_wrap.sv b/openpiton/ariane_verilog_wrap.sv index 2ef30be09404acbbf30c21de8d3af995361a2dc4..ceb0d5a4592f47553f0c29e164aabf4a7eef1854 100644 --- a/openpiton/ariane_verilog_wrap.sv +++ b/openpiton/ariane_verilog_wrap.sv @@ -14,10 +14,23 @@ module ariane_verilog_wrap #( - parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address - parameter bit SwapEndianess = 1, // swap endianess in l15 adapter - parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region - parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000 // begin of cached region + // debug module base address + parameter logic [63:0] DmBaseAddress = 64'h0, + // swap endianess in l15 adapter + parameter bit SwapEndianess = 1, + // PMA configuration + // idempotent region + parameter int NrNonIdempotentRules = 0, + parameter logic [NrMaxRules*64-1:0] NonIdempotentAddrBase = '0, + parameter logic [NrMaxRules*64-1:0] NonIdempotentLength = '0, + // executable regions + parameter int NrExecuteRegionRules = 0, + parameter logic [NrMaxRules*64-1:0] ExecuteRegionAddrBase = '0, + parameter logic [NrMaxRules*64-1:0] ExecuteRegionLength = '0, + // cacheable regions + parameter int NrCachedRegionRules = 0, + parameter logic [NrMaxRules*64-1:0] CachedRegionAddrBase = '0, + parameter logic [NrMaxRules*64-1:0] CachedRegionLength = '0 ) ( input clk_i, input reset_l, // this is an openpiton-specific name, do not change (hier. paths in TB use this) @@ -150,11 +163,27 @@ module ariane_verilog_wrap #( // ariane instance ///////////////////////////// + localparam ariane_pkg::ariane_cfg_t ArianeOpenPitonCfg = '{ + // idempotent region + NrNonIdempotentRules: NrNonIdempotentRules, + NonIdempotentAddrBase: NonIdempotentAddrBase, + NonIdempotentLength: NonIdempotentLength, + NrExecuteRegionRules: NrExecuteRegionRules, + ExecuteRegionAddrBase: ExecuteRegionAddrBase, + ExecuteRegionLength: ExecuteRegionLength, + // cached region + NrCachedRegionRules: NrCachedRegionRules, + CachedRegionAddrBase: CachedRegionAddrBase, + CachedRegionLength: CachedRegionLength, + // cache config + Axi64BitCompliant: 1'b0, + SwapEndianess: SwapEndianess, + // debug + DmBaseAddress: DmBaseAddress + }; + ariane #( - .DmBaseAddress ( DmBaseAddress ), - .SwapEndianess ( SwapEndianess ), - .CachedAddrEnd ( CachedAddrEnd ), - .CachedAddrBeg ( CachedAddrBeg ) + .ArianeCfg ( ArianeOpenPitonCfg ) ) ariane ( .clk_i ( clk_i ), .rst_ni ( spc_grst_l ), diff --git a/src/ariane.sv b/src/ariane.sv index 05851595fdf24e3366e091d2638e325102894f58..23a90d2ff065ee86a8e49bc37d786b49bcdb4f29 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -13,20 +13,11 @@ // Description: Ariane Top-level module import ariane_pkg::*; -// pragma translate_off -`ifndef VERILATOR -import instruction_tracer_pkg::*; -`endif -// pragma translate_on - module ariane #( - parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address - parameter int unsigned AxiIdWidth = 4, - parameter bit SwapEndianess = 0, // swap endianess in l15 adapter - parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region - parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region - parameter ariane_pkg::ariane_cfg_t Cfg = ariane_pkg::ArianeDefaultConfig + parameter int unsigned AxiIdWidth = 4, + parameter bit SwapEndianess = 0, // swap endianess in l15 adapter + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig ) ( input logic clk_i, input logic rst_ni, @@ -231,7 +222,7 @@ module ariane #( // Frontend // -------------- frontend #( - .DmBaseAddress ( DmBaseAddress ) + .DmBaseAddress ( ArianeCfg.DmBaseAddress ) ) i_frontend ( .flush_i ( flush_ctrl_if ), // not entirely correct .flush_bp_i ( 1'b0 ), @@ -341,7 +332,7 @@ module ariane #( // EX // --------- ex_stage #( - .Cfg ( Cfg ) + .ArianeCfg ( ArianeCfg ) ) ex_stage_i ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -465,7 +456,7 @@ module ariane #( // --------- csr_regfile #( .AsidWidth ( ASID_WIDTH ), - .DmBaseAddress ( DmBaseAddress ) + .DmBaseAddress ( ArianeCfg.DmBaseAddress ) ) csr_regfile_i ( .flush_o ( flush_csr_ctrl ), .halt_csr_o ( halt_csr_ctrl ), @@ -580,9 +571,7 @@ module ariane #( // this is a cache subsystem that is compatible with OpenPiton wt_cache_subsystem #( .AxiIdWidth ( AxiIdWidth ), - .CachedAddrBeg ( CachedAddrBeg ), - .CachedAddrEnd ( CachedAddrEnd ), - .SwapEndianess ( SwapEndianess ) + .ArianeCfg ( ArianeCfg ) ) i_cache_subsystem ( // to D$ .clk_i ( clk_i ), @@ -620,7 +609,10 @@ module ariane #( `else std_cache_subsystem #( - .CACHE_START_ADDR ( CachedAddrBeg ) + // note: this only works with one cacheable region + // not as important since this cache subsystem is about to be + // deprecated + .CACHE_START_ADDR ( ArianeCfg.CachedRegionAddrBase ) ) i_cache_subsystem ( // to D$ .clk_i ( clk_i ), @@ -658,7 +650,7 @@ module ariane #( // ------------------- // pragma translate_off `ifndef VERILATOR - initial ariane_pkg::check_cfg(Cfg); + initial ariane_pkg::check_cfg(ArianeCfg); `endif // pragma translate_on @@ -748,25 +740,11 @@ module ariane #( // assign current privilege level assign tracer_if.priv_lvl = priv_lvl; assign tracer_if.debug_mode = debug_mode; - instr_tracer instr_tracer_i (tracer_if, hart_id_i); - - program instr_tracer ( - instruction_tracer_if tracer_if, - input logic [63:0] hart_id_i - ); - instruction_tracer it = new (tracer_if, 1'b0); - - initial begin - #15ns; - it.create_file(hart_id_i); - it.trace(); - end - - final begin - it.close(); - end - endprogram + instruction_tracer instr_tracer_i ( + .tracer_if(tracer_if), + .hart_id_i + ); // mock tracer for Verilator, to be used with spike-dasm `else diff --git a/src/cache_subsystem/wt_cache_subsystem.sv b/src/cache_subsystem/wt_cache_subsystem.sv index 32093206b993e9ad315a953a6701c3401bac982c..d38335c8fe9ab3cd995f1b42f8b1ce485f446965 100644 --- a/src/cache_subsystem/wt_cache_subsystem.sv +++ b/src/cache_subsystem/wt_cache_subsystem.sv @@ -22,10 +22,8 @@ import ariane_pkg::*; import wt_cache_pkg::*; module wt_cache_subsystem #( - parameter int unsigned AxiIdWidth = 10, - parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region - parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region - parameter bit SwapEndianess = 0 // swap endianess in l15 adapter + parameter int unsigned AxiIdWidth = 10, + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions ) ( input logic clk_i, input logic rst_ni, @@ -75,15 +73,9 @@ module wt_cache_subsystem #( wt_cache_pkg::dcache_rtrn_t adapter_dcache; wt_icache #( -`ifdef PITON_ARIANE - .Axi64BitCompliant ( 1'b0 ), -`else - .Axi64BitCompliant ( 1'b1 ), -`endif // use ID 0 for icache reads .RdTxId ( 0 ), - .CachedAddrBeg ( CachedAddrBeg ), - .CachedAddrEnd ( CachedAddrEnd ) + .ArianeCfg ( ArianeCfg ) ) i_wt_icache ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -107,16 +99,10 @@ module wt_cache_subsystem #( // they have equal prio and are RR arbited // Port 2 is write only and goes into the merging write buffer wt_dcache #( -`ifdef PITON_ARIANE - .Axi64BitCompliant ( 1'b0 ), -`else - .Axi64BitCompliant ( 1'b1 ), -`endif // use ID 1 for dcache reads and amos. note that the writebuffer // uses all IDs up to DCACHE_MAX_TX-1 for write transactions. .RdAmoTxId ( 1 ), - .CachedAddrBeg ( CachedAddrBeg ), - .CachedAddrEnd ( CachedAddrEnd ) + .ArianeCfg ( ArianeCfg ) ) i_wt_dcache ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -144,7 +130,7 @@ module wt_cache_subsystem #( `ifdef PITON_ARIANE wt_l15_adapter #( - .SwapEndianess ( SwapEndianess ) + .SwapEndianess ( ArianeCfg.SwapEndianess ) ) i_adapter ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/src/cache_subsystem/wt_dcache.sv b/src/cache_subsystem/wt_dcache.sv index bb0709fa8fe25ac8e59fc438b07344910b86e0ec..34a400641f1cc944e8c51f08dfca4d9e899bb947 100644 --- a/src/cache_subsystem/wt_dcache.sv +++ b/src/cache_subsystem/wt_dcache.sv @@ -16,12 +16,11 @@ import ariane_pkg::*; import wt_cache_pkg::*; module wt_dcache #( - parameter bit Axi64BitCompliant = 1'b0, // set this to 1 when using in conjunction with 64bit AXI bus adapter // ID to be used for read and AMO transactions. // note that the write buffer uses all IDs up to DCACHE_MAX_TX-1 for write transactions parameter logic [CACHE_ID_WIDTH-1:0] RdAmoTxId = 1, - parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region - parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000 // end of cached region + // contains cacheable regions + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -110,9 +109,9 @@ module wt_dcache #( /////////////////////////////////////////////////////// wt_dcache_missunit #( - .Axi64BitCompliant ( Axi64BitCompliant ), - .AmoTxId ( RdAmoTxId ), - .NumPorts ( NumPorts ) + .Axi64BitCompliant ( ArianeCfg.Axi64BitCompliant ), + .AmoTxId ( RdAmoTxId ), + .NumPorts ( NumPorts ) ) i_wt_dcache_missunit ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -170,8 +169,7 @@ module wt_dcache #( wt_dcache_ctrl #( .RdTxId ( RdAmoTxId ), - .CachedAddrBeg ( CachedAddrBeg ), - .CachedAddrEnd ( CachedAddrEnd ) + .ArianeCfg ( ArianeCfg ) ) i_wt_dcache_ctrl ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -213,8 +211,7 @@ module wt_dcache #( assign rd_prio[2] = 1'b0; wt_dcache_wbuffer #( - .CachedAddrBeg ( CachedAddrBeg ), - .CachedAddrEnd ( CachedAddrEnd ) + .ArianeCfg ( ArianeCfg ) ) i_wt_dcache_wbuffer ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -268,8 +265,8 @@ module wt_dcache #( /////////////////////////////////////////////////////// wt_dcache_mem #( - .Axi64BitCompliant ( Axi64BitCompliant ), - .NumPorts ( NumPorts ) + .Axi64BitCompliant ( ArianeCfg.Axi64BitCompliant ), + .NumPorts ( NumPorts ) ) i_wt_dcache_mem ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/src/cache_subsystem/wt_dcache_ctrl.sv b/src/cache_subsystem/wt_dcache_ctrl.sv index 2eea9aa839e8892b2c22c728e4bdb6ada037590b..b99c61f3ee4d240836f74667e73bacf3757fdbe4 100644 --- a/src/cache_subsystem/wt_dcache_ctrl.sv +++ b/src/cache_subsystem/wt_dcache_ctrl.sv @@ -16,9 +16,8 @@ import ariane_pkg::*; import wt_cache_pkg::*; module wt_dcache_ctrl #( - parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 1, // ID to use for read transactions - parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region - parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000 // end of cached region + parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 1, // ID to use for read transactions + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -84,9 +83,9 @@ module wt_dcache_ctrl #( assign miss_paddr_o = {address_tag_q, address_idx_q, address_off_q}; assign miss_size_o = (miss_nc_o) ? data_size_q : 3'b111; - assign miss_nc_o = (address_tag_q < (CachedAddrBeg>>DCACHE_INDEX_WIDTH)) || - (address_tag_q >= (CachedAddrEnd>>DCACHE_INDEX_WIDTH)) || - (!cache_en_i); + // noncacheable if request goes to I/O space, or if cache is disabled + assign miss_nc_o = (~cache_en_i) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {address_tag_q, {DCACHE_INDEX_WIDTH{1'b0}}})); + assign miss_we_o = '0; assign miss_wdata_o = '0; diff --git a/src/cache_subsystem/wt_dcache_wbuffer.sv b/src/cache_subsystem/wt_dcache_wbuffer.sv index dbc370dc8c5ddbb519ea07f4cc13ee5da771b15e..865411bf46b92c1a02af5b8ba99595a311bb4df2 100644 --- a/src/cache_subsystem/wt_dcache_wbuffer.sv +++ b/src/cache_subsystem/wt_dcache_wbuffer.sv @@ -52,8 +52,7 @@ import ariane_pkg::*; import wt_cache_pkg::*; module wt_dcache_wbuffer #( - parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region - parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000 // end of cached region + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -136,9 +135,8 @@ module wt_dcache_wbuffer #( assign miss_nc_o = nc_pending_q; - assign addr_is_nc = (req_port_i.address_tag < (CachedAddrBeg>>DCACHE_INDEX_WIDTH)) || - (req_port_i.address_tag >= (CachedAddrEnd>>DCACHE_INDEX_WIDTH)) || - (!cache_en_i); + // noncacheable if request goes to I/O space, or if cache is disabled + assign addr_is_nc = (~cache_en_i) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}})); assign miss_we_o = 1'b1; assign miss_vld_bits_o = '0; diff --git a/src/cache_subsystem/wt_icache.sv b/src/cache_subsystem/wt_icache.sv index 9d5f3840b56a91c7f555c0ed5593f6d2443a92a9..effafa49a5a9f70e5de9d98db5ca55f53c40cbbf 100644 --- a/src/cache_subsystem/wt_icache.sv +++ b/src/cache_subsystem/wt_icache.sv @@ -28,10 +28,8 @@ import ariane_pkg::*; import wt_cache_pkg::*; module wt_icache #( - parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 0, // ID to be used for read transactions - parameter bit Axi64BitCompliant = 1'b0, // set this to 1 when using in conjunction with 64bit AXI bus adapter - parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region - parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000 // end of cached region + parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 0, // ID to be used for read transactions + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions ) ( input logic clk_i, input logic rst_ni, @@ -103,9 +101,7 @@ module wt_icache #( assign cl_tag_d = (areq_i.fetch_valid) ? areq_i.fetch_paddr[ICACHE_TAG_WIDTH+ICACHE_INDEX_WIDTH-1:ICACHE_INDEX_WIDTH] : cl_tag_q; // noncacheable if request goes to I/O space, or if cache is disabled - assign paddr_is_nc = (cl_tag_d < (CachedAddrBeg>>ICACHE_INDEX_WIDTH)) || - (cl_tag_d >= (CachedAddrEnd>>ICACHE_INDEX_WIDTH)) || - (!cache_en_q); + assign paddr_is_nc = (~cache_en_q) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {cl_tag_d, {ICACHE_INDEX_WIDTH{1'b0}}})); // pass exception through assign dreq_o.ex = areq_i.fetch_exception; @@ -119,7 +115,7 @@ module wt_icache #( assign cl_index = vaddr_d[ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH]; - if (Axi64BitCompliant) begin : gen_axi_offset + if (ArianeCfg.Axi64BitCompliant) begin : gen_axi_offset // if we generate a noncacheable access, the word will be at offset 0 or 4 in the cl coming from memory assign cl_offset_d = ( dreq_o.ready & dreq_i.req) ? {dreq_i.vaddr>>2, 2'b0} : ( paddr_is_nc & mem_data_req_o ) ? cl_offset_q[2]<<2 : // needed since we transfer 32bit over a 64bit AXI bus in this case diff --git a/src/ex_stage.sv b/src/ex_stage.sv index 273e65d38cadf11196157da1dc01295f0232077d..f1f813340ebe1aab8328227fd1dc040efa8614a0 100644 --- a/src/ex_stage.sv +++ b/src/ex_stage.sv @@ -16,7 +16,7 @@ import ariane_pkg::*; module ex_stage #( - parameter ariane_pkg::ariane_cfg_t Cfg = ariane_pkg::ArianeDefaultConfig + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -252,7 +252,7 @@ module ex_stage #( assign lsu_data = lsu_valid_i ? fu_data_i : '0; load_store_unit #( - .Cfg ( Cfg ) + .ArianeCfg ( ArianeCfg ) ) lsu_i ( .clk_i, .rst_ni, diff --git a/src/load_store_unit.sv b/src/load_store_unit.sv index 90819d376a7a5577ce20ee8984477a47204b12c7..481eaab4e2d71f3f2a84b49eb47057c1e677669c 100644 --- a/src/load_store_unit.sv +++ b/src/load_store_unit.sv @@ -16,7 +16,7 @@ import ariane_pkg::*; module load_store_unit #( parameter int unsigned ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t Cfg = ariane_pkg::ArianeDefaultConfig + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig )( input logic clk_i, input logic rst_ni, @@ -121,7 +121,7 @@ module load_store_unit #( .INSTR_TLB_ENTRIES ( 16 ), .DATA_TLB_ENTRIES ( 16 ), .ASID_WIDTH ( ASID_WIDTH ), - .Cfg ( Cfg ) + .ArianeCfg ( ArianeCfg ) ) i_mmu ( // misaligned bypass .misaligned_ex_i ( misaligned_exception ), diff --git a/src/mmu.sv b/src/mmu.sv index eb88cdf5d732a67c885a31e9cb9327275f575d00..00ef8e278fcad2f05e9464d67ef00c609ab21004 100644 --- a/src/mmu.sv +++ b/src/mmu.sv @@ -17,10 +17,10 @@ import ariane_pkg::*; module mmu #( - parameter int unsigned INSTR_TLB_ENTRIES = 4, - parameter int unsigned DATA_TLB_ENTRIES = 4, - parameter int unsigned ASID_WIDTH = 1, - parameter ariane_pkg::ariane_cfg_t Cfg = ariane_pkg::ArianeDefaultConfig + parameter int unsigned INSTR_TLB_ENTRIES = 4, + parameter int unsigned DATA_TLB_ENTRIES = 4, + parameter int unsigned ASID_WIDTH = 1, + parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig ) ( input logic clk_i, input logic rst_ni, @@ -243,15 +243,9 @@ module mmu #( end end - always_comb begin : execute_addr_check - // if we don't specify any region we assume everything is accessible - match_any_execute_region = (Cfg.NrExecuteRegionRules == 0); - // check for execute flag on memory - for (int i = 0; i < Cfg.NrExecuteRegionRules; i++) begin - match_any_execute_region |= (Cfg.ExecuteRegionAddrBase[i] & ariane_pkg::gen_mask(Cfg.ExecuteRegionLength[i])) - == (icache_areq_o.fetch_paddr & ariane_pkg::gen_mask(Cfg.ExecuteRegionLength[i])); - end - end + // check for execute flag on memory + assign match_any_execute_region = ariane_pkg::is_inside_execute_regions(ArianeCfg, icache_areq_o.fetch_paddr); + //----------------------- // Data Interface //----------------------- diff --git a/src/util/instruction_tracer.svh b/src/util/instruction_tracer.svh deleted file mode 100644 index a056e237b24d4d6b28c04de915883b27003fb976..0000000000000000000000000000000000000000 --- a/src/util/instruction_tracer.svh +++ /dev/null @@ -1,212 +0,0 @@ -// 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: Florian Zaruba, ETH Zurich -// Date: 16.05.2017 -// Description: Instruction Tracer Main Class - - -class instruction_tracer; - // interface to the core - virtual instruction_tracer_if tracer_if; - // keep the decoded instructions in a queue - logic [31:0] decode_queue [$]; - // keep the issued instructions in a queue - logic [31:0] issue_queue [$]; - // issue scoreboard entries - scoreboard_entry_t issue_sbe_queue [$]; - scoreboard_entry_t issue_sbe; - // store resolved branches, get (mis-)predictions - branchpredict_t bp [$]; - // shadow copy of the register files - logic [63:0] gp_reg_file [32]; - logic [63:0] fp_reg_file [32]; - // 64 bit clock tick count - longint unsigned clk_ticks; - int f, commit_log; - // address mapping - // contains mappings of the form vaddr <-> paddr - // should it print the instructions to the console - logic display_instructions; - logic [63:0] store_mapping[$], load_mapping[$], address_mapping; - - // static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst(); - - - function new(virtual instruction_tracer_if tracer_if, logic display_instructions); - - this.tracer_if = tracer_if; - this.display_instructions = display_instructions; - - endfunction : new - - function void create_file(logic [63:0] hart_id); - string fn, fn_commit_log; - $sformat(fn, "trace_hart_%04.0f.log", hart_id); - $sformat(fn_commit_log, "trace_hart_%04.0f_commit.log", hart_id); - $display("[TRACER] Output filename is: %s", fn); - - this.f = $fopen(fn,"w"); - if (ENABLE_SPIKE_COMMIT_LOG) this.commit_log = $fopen(fn_commit_log, "w"); - endfunction : create_file - - task trace(); - logic [31:0] decode_instruction, issue_instruction, issue_commit_instruction; - scoreboard_entry_t commit_instruction; - // initialize register 0 - gp_reg_file = '{default:0}; - fp_reg_file = '{default:0}; - - forever begin - automatic branchpredict_t bp_instruction = '0; - // new cycle, we are only interested if reset is de-asserted - @(tracer_if.pck iff tracer_if.pck.rstn); - // increment clock tick - clk_ticks++; - - // ------------------- - // Instruction Decode - // ------------------- - // we are decoding an instruction - if (tracer_if.pck.fetch_valid && tracer_if.pck.fetch_ack) begin - decode_instruction = tracer_if.pck.instruction; - decode_queue.push_back(decode_instruction); - end - // ------------------- - // Instruction Issue - // ------------------- - // we got a new issue ack, so put the element from the decode queue to - // the issue queue - if (tracer_if.pck.issue_ack && !tracer_if.pck.flush_unissued) begin - issue_instruction = decode_queue.pop_front(); - issue_queue.push_back(issue_instruction); - // also save the scoreboard entry to a separate issue queue - issue_sbe_queue.push_back(scoreboard_entry_t'(tracer_if.pck.issue_sbe)); - end - - // -------------------- - // Address Translation - // -------------------- - if (tracer_if.pck.st_valid) begin - store_mapping.push_back(tracer_if.pck.st_paddr); - end - - if (tracer_if.pck.ld_valid && !tracer_if.pck.ld_kill) begin - load_mapping.push_back(tracer_if.pck.ld_paddr); - end - // ---------------------- - // Store predictions - // ---------------------- - if (tracer_if.pck.resolve_branch.valid) begin - bp.push_back(tracer_if.pck.resolve_branch); - end - // -------------- - // Commit - // -------------- - // we are committing an instruction - for (int i = 0; i < 2; i++) begin - if (tracer_if.pck.commit_ack[i]) begin - commit_instruction = scoreboard_entry_t'(tracer_if.pck.commit_instr[i]); - issue_commit_instruction = issue_queue.pop_front(); - issue_sbe = issue_sbe_queue.pop_front(); - // check if the instruction retiring is a load or store, get the physical address accordingly - if (tracer_if.pck.commit_instr[i].fu == LOAD) - address_mapping = load_mapping.pop_front(); - else if (tracer_if.pck.commit_instr[i].fu == STORE) - address_mapping = store_mapping.pop_front(); - - if (tracer_if.pck.commit_instr[i].fu == CTRL_FLOW) - bp_instruction = bp.pop_front(); - // the scoreboards issue entry still contains the immediate value as a result - // check if the write back is valid, if not we need to source the result from the register file - // as the most recent version of this register will be there. - if (tracer_if.pck.we_gpr[i] || tracer_if.pck.we_fpr[i]) begin - printInstr(issue_sbe, issue_commit_instruction, tracer_if.pck.wdata[i], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction); - end else if (is_rd_fpr(commit_instruction.op)) begin - printInstr(issue_sbe, issue_commit_instruction, fp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction); - end else begin - printInstr(issue_sbe, issue_commit_instruction, gp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction); - end - end - end - // -------------- - // Exceptions - // -------------- - if (tracer_if.pck.exception.valid && !(tracer_if.pck.debug_mode && tracer_if.pck.exception.cause == riscv::BREAKPOINT)) begin - // print exception - printException(tracer_if.pck.commit_instr[0].pc, tracer_if.pck.exception.cause, tracer_if.pck.exception.tval); - end - // ---------------------- - // Commit Registers - // ---------------------- - // update shadow reg files here - for (int i = 0; i < 2; i++) begin - if (tracer_if.pck.we_gpr[i] && tracer_if.pck.waddr[i] != 5'b0) begin - gp_reg_file[tracer_if.pck.waddr[i]] = tracer_if.pck.wdata[i]; - end else if (tracer_if.pck.we_fpr[i]) begin - fp_reg_file[tracer_if.pck.waddr[i]] = tracer_if.pck.wdata[i]; - end - end - // -------------- - // Flush Signals - // -------------- - // flush un-issued instructions - if (tracer_if.pck.flush_unissued) begin - this.flushDecode(); - end - // flush whole pipeline - if (tracer_if.pck.flush) begin - this.flush(); - end - end - - endtask - - // flush all decoded instructions - function void flushDecode (); - decode_queue = {}; - endfunction - - // flush everything, we took an exception/interrupt - function void flush (); - this.flushDecode(); - // clear all elements in the queue - issue_queue = {}; - issue_sbe_queue = {}; - // also clear mappings - store_mapping = {}; - load_mapping = {}; - bp = {}; - endfunction - - function void printInstr(scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [63:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, branchpredict_t bp); - instruction_trace_item iti = new ($time, clk_ticks, sbe, instr, this.gp_reg_file, this.fp_reg_file, result, paddr, priv_lvl, debug_mode, bp); - // print instruction to console - string print_instr = iti.printInstr(); - if (ENABLE_SPIKE_COMMIT_LOG && !debug_mode) begin - $fwrite(this.commit_log, riscv::spikeCommitLog(sbe.pc, priv_lvl, instr, sbe.rd, result, is_rd_fpr(sbe.op))); - end - uvm_report_info( "Tracer", print_instr, UVM_HIGH); - $fwrite(this.f, {print_instr, "\n"}); - endfunction - - function void printException(logic [63:0] pc, logic [63:0] cause, logic [63:0] tval); - exception_trace_item eti = new (pc, cause, tval); - string print_ex = eti.printException(); - uvm_report_info( "Tracer", print_ex, UVM_HIGH); - $fwrite(this.f, {print_ex, "\n"}); - endfunction - - function void close(); - if (f) $fclose(this.f); - if (ENABLE_SPIKE_COMMIT_LOG && this.commit_log) $fclose(this.commit_log); - endfunction - -endclass : instruction_tracer diff --git a/src/util/instruction_tracer_pkg.sv b/src/util/instruction_tracer_pkg.sv deleted file mode 100644 index f17d6c88cdbc50b6f38dc6c8ebd145bd8c860f72..0000000000000000000000000000000000000000 --- a/src/util/instruction_tracer_pkg.sv +++ /dev/null @@ -1,27 +0,0 @@ -// 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: Florian Zaruba, ETH Zurich -// Date: 16.05.2017 -// Description: Instruction Tracer Package - -package instruction_tracer_pkg; - - import ariane_pkg::*; - //pragma translate_off - import uvm_pkg::*; - `include "uvm_macros.svh" - `include "instruction_tracer_defines.svh" - `include "instruction_trace_item.svh" - `include "exception_trace_item.svh" - `include "instruction_tracer.svh" - //pragma translate_on - -endpackage diff --git a/tb/ariane_soc_pkg.sv b/tb/ariane_soc_pkg.sv index 316b9866de0eb150e111f73413bf580dc2fd5dff..bfe408f21962eb322a3b4ef8d9801ab4ac7ce72b 100644 --- a/tb/ariane_soc_pkg.sv +++ b/tb/ariane_soc_pkg.sv @@ -11,58 +11,78 @@ // Author: Florian Zaruba, ETH Zurich // Description: Contains SoC information as constants package ariane_soc; - // M-Mode Hart, S-Mode Hart - localparam int unsigned NumTargets = 2; - // Uart, SPI, Ethernet, reserved - localparam int unsigned NumSources = 30; - localparam int unsigned MaxPriority = 7; + // M-Mode Hart, S-Mode Hart + localparam int unsigned NumTargets = 2; + // Uart, SPI, Ethernet, reserved + localparam int unsigned NumSources = 30; + localparam int unsigned MaxPriority = 7; - localparam NrSlaves = 2; // actually masters, but slaves on the crossbar + localparam NrSlaves = 2; // actually masters, but slaves on the crossbar - // 4 is recommended by AXI standard, so lets stick to it, do not change - localparam IdWidth = 4; - localparam IdWidthSlave = IdWidth + $clog2(NrSlaves); + // 4 is recommended by AXI standard, so lets stick to it, do not change + localparam IdWidth = 4; + localparam IdWidthSlave = IdWidth + $clog2(NrSlaves); - typedef enum int unsigned { - DRAM = 0, - GPIO = 1, - Ethernet = 2, - SPI = 3, - UART = 4, - PLIC = 5, - CLINT = 6, - ROM = 7, - Debug = 8 - } axi_slaves_t; + typedef enum int unsigned { + DRAM = 0, + GPIO = 1, + Ethernet = 2, + SPI = 3, + UART = 4, + PLIC = 5, + CLINT = 6, + ROM = 7, + Debug = 8 + } axi_slaves_t; - localparam NB_PERIPHERALS = Debug + 1; + localparam NB_PERIPHERALS = Debug + 1; - localparam logic[63:0] DebugLength = 64'h1000; - localparam logic[63:0] ROMLength = 64'h10000; - localparam logic[63:0] CLINTLength = 64'hC0000; - localparam logic[63:0] PLICLength = 64'h3FF_FFFF; - localparam logic[63:0] UARTLength = 64'h1000; - localparam logic[63:0] SPILength = 64'h800000; - localparam logic[63:0] EthernetLength = 64'h10000; - localparam logic[63:0] GPIOLength = 64'h1000; - localparam logic[63:0] DRAMLength = 64'h40000000; // 1GByte of DDR (split between two chips on Genesys2) - localparam logic[63:0] SRAMLength = 64'h1800000; // 24 MByte of SRAM - // Instantiate AXI protocol checkers - localparam bit GenProtocolChecker = 1'b0; - typedef enum logic [63:0] { - DebugBase = 64'h0000_0000, - ROMBase = 64'h0001_0000, - CLINTBase = 64'h0200_0000, - PLICBase = 64'h0C00_0000, - UARTBase = 64'h1000_0000, - SPIBase = 64'h2000_0000, - EthernetBase = 64'h3000_0000, - GPIOBase = 64'h4000_0000, - DRAMBase = 64'h8000_0000 - } soc_bus_start_t; + localparam logic[63:0] DebugLength = 64'h1000; + localparam logic[63:0] ROMLength = 64'h10000; + localparam logic[63:0] CLINTLength = 64'hC0000; + localparam logic[63:0] PLICLength = 64'h3FF_FFFF; + localparam logic[63:0] UARTLength = 64'h1000; + localparam logic[63:0] SPILength = 64'h800000; + localparam logic[63:0] EthernetLength = 64'h10000; + localparam logic[63:0] GPIOLength = 64'h1000; + localparam logic[63:0] DRAMLength = 64'h40000000; // 1GByte of DDR (split between two chips on Genesys2) + localparam logic[63:0] SRAMLength = 64'h1800000; // 24 MByte of SRAM + // Instantiate AXI protocol checkers + localparam bit GenProtocolChecker = 1'b0; - localparam NrRegion = 1; - localparam logic [NrRegion-1:0][NB_PERIPHERALS-1:0] ValidRule = {{NrRegion * NB_PERIPHERALS}{1'b1}}; + typedef enum logic [63:0] { + DebugBase = 64'h0000_0000, + ROMBase = 64'h0001_0000, + CLINTBase = 64'h0200_0000, + PLICBase = 64'h0C00_0000, + UARTBase = 64'h1000_0000, + SPIBase = 64'h2000_0000, + EthernetBase = 64'h3000_0000, + GPIOBase = 64'h4000_0000, + DRAMBase = 64'h8000_0000 + } soc_bus_start_t; + + localparam NrRegion = 1; + localparam logic [NrRegion-1:0][NB_PERIPHERALS-1:0] ValidRule = {{NrRegion * NB_PERIPHERALS}{1'b1}}; + + localparam ariane_pkg::ariane_cfg_t ArianeSocCfg = '{ + // idempotent region + NrNonIdempotentRules: 0, + NonIdempotentAddrBase: {64'b0}, + NonIdempotentLength: {64'b0}, + NrExecuteRegionRules: 3, + ExecuteRegionAddrBase: {DRAMBase, ROMBase, DebugBase}, + ExecuteRegionLength: {DRAMLength, ROMLength, DebugLength}, + // cached region + NrCachedRegionRules: 1, + CachedRegionAddrBase: {DRAMBase}, + CachedRegionLength: {DRAMLength}, + // cache config + Axi64BitCompliant: 1'b1, + SwapEndianess: 1'b0, + // debug + DmBaseAddress: DebugBase + }; endpackage diff --git a/tb/ariane_testharness.sv b/tb/ariane_testharness.sv index 67cbb0dffbe17f7ab4107ed3c4edd8be30754224..be0fc9dd029f76d80953d134f89756928e8f3fc3 100644 --- a/tb/ariane_testharness.sv +++ b/tb/ariane_testharness.sv @@ -659,11 +659,8 @@ module ariane_testharness #( ariane_axi::resp_t axi_ariane_resp; ariane #( - .AxiIdWidth ( ariane_soc::IdWidth ), - .SwapEndianess ( 0 ), - .CachedAddrBeg ( ariane_soc::DRAMBase ), - .CachedAddrEnd ( (ariane_soc::DRAMBase + ariane_soc::DRAMLength) ), - .DmBaseAddress ( ariane_soc::DebugBase ) + .AxiIdWidth ( ariane_soc::IdWidth ), + .ArianeCfg ( ariane_soc::ArianeSocCfg ) ) i_ariane ( .clk_i ( clk_i ), .rst_ni ( ndmreset_n ), diff --git a/tb/tb_wt_dcache/hdl/tb.sv b/tb/tb_wt_dcache/hdl/tb.sv index 310814476ffe6fb981b385eae1a52f2021e16543..3b817bf9976f40d5a2afe9cdb888a108224784cd 100644 --- a/tb/tb_wt_dcache/hdl/tb.sv +++ b/tb/tb_wt_dcache/hdl/tb.sv @@ -40,6 +40,26 @@ module tb; parameter logic [63:0] CachedAddrBeg = MemBytes>>3;//1/8th of the memory is NC parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF; + localparam ariane_cfg_t ArianeDefaultConfig = '{ + // idempotent region + NrNonIdempotentRules: 0, + NonIdempotentAddrBase: {64'b0}, + NonIdempotentLength: {64'b0}, + // executable region + NrExecuteRegionRules: 0, + ExecuteRegionAddrBase: {64'h0}, + ExecuteRegionLength: {64'h0}, + // cached region + NrCachedRegionRules: 1, + CachedRegionAddrBase: {CachedAddrBeg},//1/8th of the memory is NC + CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1}, + // cache config + Axi64BitCompliant: 1'b1, + SwapEndianess: 1'b0, + // debug + DmBaseAddress: 64'h0 + }; + // contention and invalidation rates (in %) parameter MemRandHitRate = 75; parameter MemRandInvRate = 10; @@ -204,9 +224,7 @@ module tb; /////////////////////////////////////////////////////////////////////////////// wt_dcache #( - .CachedAddrBeg ( CachedAddrBeg ), - .CachedAddrEnd ( CachedAddrEnd ), - .Axi64BitCompliant ( 1'b1 ) + .ArianeCfg ( ArianeDefaultConfig ) ) i_dut ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/tb/tb_wt_icache/hdl/tb.sv b/tb/tb_wt_icache/hdl/tb.sv index 7f7c4485b907379701c84782bd01cb5106ce490a..0a6b62ec77091f9a9c4a73741d464aac88f04f0a 100644 --- a/tb/tb_wt_icache/hdl/tb.sv +++ b/tb/tb_wt_icache/hdl/tb.sv @@ -39,6 +39,26 @@ module tb; parameter logic [63:0] CachedAddrBeg = MemBytes/4; parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF; + localparam ariane_cfg_t Cfg = '{ + // idempotent region + NrNonIdempotentRules: 0, + NonIdempotentAddrBase: {64'b0}, + NonIdempotentLength: {64'b0}, + // executable region + NrExecuteRegionRules: 0, + ExecuteRegionAddrBase: {64'h0}, + ExecuteRegionLength: {64'h0}, + // cached region + NrCachedRegionRules: 1, + CachedRegionAddrBase: {CachedAddrBeg}, + CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1}, + // cache config + Axi64BitCompliant: 1'b0, + SwapEndianess: 1'b0, + // debug + DmBaseAddress: 64'h0 + }; + // rates are in percent parameter TlbRandHitRate = 50; parameter MemRandHitRate = 50; @@ -240,8 +260,7 @@ module tb; /////////////////////////////////////////////////////////////////////////////// wt_icache #( - .CachedAddrBeg(CachedAddrBeg), - .CachedAddrEnd(CachedAddrEnd) + .ArianeCfg(Cfg) ) dut ( .clk_i ( clk_i ), .rst_ni ( rst_ni ),