From 9d1218529eee9079fd5f495c658c908a7392629f Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Sat, 30 Jun 2018 19:27:40 +0200 Subject: [PATCH] Make icache bypass-able --- Makefile | 2 +- src/ariane.sv | 20 ++++++-------------- src/ariane_wrapped.sv | 15 +-------------- src/frontend.sv | 27 +++++++++++---------------- src/icache.sv | 21 ++++++++------------- tb | 2 +- 6 files changed, 28 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index 0bec374f5..24a20fa09 100755 --- a/Makefile +++ b/Makefile @@ -176,7 +176,7 @@ $(tests): build verilate: $(verilator) $(ariane_pkg) $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) $(wildcard src/axi_slice/*.sv) \ src/util/cluster_clock_gating.sv src/util/behav_sram.sv src/axi_mem_if/src/axi2mem.sv tb/agents/axi_if/axi_if.sv \ - --unroll-count 256 -Wno-fatal -LDFLAGS "-lfesvr" -CFLAGS "-std=c++11" -Wall --cc --trace \ + --unroll-count 256 -Wno-fatal -Werror-PINMISSING -LDFLAGS "-lfesvr" -CFLAGS "-std=c++11" -Wall --cc --trace \ $(list_incdir) --top-module ariane_wrapped --exe tb/ariane_tb.cpp tb/simmem.cpp cd obj_dir && make -j8 -f Variane_wrapped.mk diff --git a/src/ariane.sv b/src/ariane.sv index 33ce453a2..8b62c2958 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -68,9 +68,6 @@ module ariane #( logic if_ready_if_pcgen; logic fetch_valid_pcgen_if; // -------------- - // PCGEN <-> COMMIT - // -------------- - // -------------- // PCGEN <-> CSR // -------------- logic [63:0] trap_vector_base_commit_pcgen; @@ -186,6 +183,8 @@ module ariane #( logic tw_csr_id; logic tsr_csr_id; logic dcache_en_csr_nbdcache; + logic icache_en_csr_frontend; + // ---------------------------- // Performance Counters <-> * // ---------------------------- @@ -214,22 +213,15 @@ module ariane #( logic halt_csr_ctrl; logic flush_dcache_ctrl_ex; logic flush_dcache_ack_ex_ctrl; - // ---------------- - // ICache <-> * - // ---------------- - logic flush_icache_ctrl_icache; - logic bypass_icache_csr_icache; + logic flush_icache_ctrl_icache; assign sec_lvl_o = priv_lvl; assign flush_dcache_ack_o = flush_dcache_ack_ex_ctrl; // -------------- // Frontend // -------------- - frontend #( - .BTB_ENTRIES ( BTB_ENTRIES ), - .BHT_ENTRIES ( BHT_ENTRIES ), - .RAS_DEPTH ( RAS_DEPTH ) - ) i_frontend ( + frontend i_frontend ( + .en_cache_i ( icache_en_csr_frontend ), .flush_i ( flush_ctrl_if ), // not entirely correct .flush_bp_i ( 1'b0 ), .flush_icache_i ( flush_icache_ctrl_icache ), @@ -478,7 +470,7 @@ module ariane #( .tw_o ( tw_csr_id ), .tsr_o ( tsr_csr_id ), .dcache_en_o ( dcache_en_csr_nbdcache ), - .icache_en_o ( bypass_icache_csr_icache ), + .icache_en_o ( icache_en_csr_frontend ), .perf_addr_o ( addr_csr_perf ), .perf_data_o ( data_csr_perf ), .perf_data_i ( data_perf_csr ), diff --git a/src/ariane_wrapped.sv b/src/ariane_wrapped.sv index fede5cebb..f3b9601be 100644 --- a/src/ariane_wrapped.sv +++ b/src/ariane_wrapped.sv @@ -29,8 +29,6 @@ module ariane_wrapped #( input logic clk_i, input logic rst_ni, input logic test_en_i, // enable all clock gates for testing - // CPU Control Signals - input logic fetch_enable_i, // Core ID, Cluster ID and boot address are considered more or less static input logic [63:0] boot_addr_i, input logic [ 3:0] core_id_i, @@ -43,18 +41,7 @@ module ariane_wrapped #( output logic sec_lvl_o, // current privilege level oot // Timer facilities input logic [63:0] time_i, // global time (most probably coming from an RTC) - input logic time_irq_i, // timer interrupt in - // Debug Interface - input logic debug_req_i, - output logic debug_gnt_o, - output logic debug_rvalid_o, - input logic [15:0] debug_addr_i, - input logic debug_we_i, - input logic [63:0] debug_wdata_i, - output logic [63:0] debug_rdata_o, - output logic debug_halted_o, - input logic debug_halt_i, - input logic debug_resume_i + input logic time_irq_i // timer interrupt in ); localparam int unsigned AXI_NUMBYTES = AXI_DATA_WIDTH/8; diff --git a/src/frontend.sv b/src/frontend.sv index 5863d2446..b255a906c 100644 --- a/src/frontend.sv +++ b/src/frontend.sv @@ -15,9 +15,6 @@ import ariane_pkg::*; module frontend #( - parameter int unsigned BTB_ENTRIES = 8, - parameter int unsigned BHT_ENTRIES = 1024, - parameter int unsigned RAS_DEPTH = 4, parameter int unsigned SET_ASSOCIATIVITY = 4, parameter int unsigned CACHE_LINE_WIDTH = 64, // in bit parameter int unsigned FETCH_WIDTH = 32 @@ -25,6 +22,7 @@ module frontend #( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low input logic flush_i, // flush request for PCGEN + input logic en_cache_i, // enable icache input logic flush_bp_i, // flush branch prediction input logic flush_icache_i, // instruction fence in // global input @@ -65,7 +63,6 @@ module frontend #( logic instruction_valid; - logic icache_speculative_d, icache_speculative_q; logic [63:0] icache_vaddr_d, icache_vaddr_q; // BHT, BTB and RAS prediction @@ -104,7 +101,6 @@ module frontend #( logic [63:0] bp_vaddr; logic bp_valid; // we have a valid branch-prediction - logic fetch_is_speculative; // is it a speculative fetch or a fetch which need to do for sure // branch-prediction which we inject into the pipeline branchpredict_sbe_t bp_sbe; logic fifo_valid, fifo_ready; // fetch FIFO @@ -316,8 +312,6 @@ module frontend #( always_comb begin : npc_select automatic logic [63:0] fetch_address; - fetch_is_speculative = 1'b0; - fetch_address = npc_q; // keep stable by default npc_d = npc_q; @@ -325,7 +319,6 @@ module frontend #( // 1. Branch Prediction // ------------------------------- if (bp_valid) begin - fetch_is_speculative = 1'b1; fetch_address = bp_vaddr; npc_d = bp_vaddr; end @@ -334,7 +327,6 @@ module frontend #( // ------------------------------- if (if_ready) begin npc_d = {fetch_address[63:2], 2'b0} + 64'h4; - fetch_is_speculative = 1'b1; end // ------------------------------- // 2. Control flow change request @@ -374,7 +366,6 @@ module frontend #( npc_q <= boot_addr_i; icache_data_q <= '0; icache_valid_q <= 1'b0; - icache_speculative_q <= 1'b0; icache_vaddr_q <= 'b0; icache_ex_q <= '0; unaligned_q <= 1'b0; @@ -384,7 +375,6 @@ module frontend #( npc_q <= npc_d; icache_data_q <= icache_data_d; icache_valid_q <= icache_valid_d; - icache_speculative_q <= icache_speculative_d; icache_vaddr_q <= icache_vaddr_d; icache_ex_q <= icache_ex_d; unaligned_q <= unaligned_d; @@ -428,9 +418,11 @@ module frontend #( .CACHE_LINE_WIDTH ( 128 ), .FETCH_WIDTH ( FETCH_WIDTH ) ) i_icache ( + .clk_i, + .rst_ni, .flush_i ( flush_icache_i ), + .en_cache_i, .vaddr_i ( fetch_vaddr ), // 1st cycle - .is_speculative_i ( fetch_is_speculative ), // 1st cycle .data_o ( icache_data_d ), .req_i ( icache_req ), .kill_s1_i ( kill_s1 ), @@ -438,11 +430,14 @@ module frontend #( .ready_o ( icache_ready ), .valid_o ( icache_valid_d ), .ex_o ( icache_ex_d ), - .is_speculative_o ( icache_speculative_d ), .vaddr_o ( icache_vaddr_d ), - .axi ( axi ), - .miss_o ( l1_icache_miss_o ), - .* + .axi, + .fetch_req_o, + .fetch_vaddr_o, + .fetch_valid_i, + .fetch_paddr_i, + .fetch_exception_i, + .miss_o ( l1_icache_miss_o ) ); for (genvar i = 0; i < INSTR_PER_FETCH; i++) begin diff --git a/src/icache.sv b/src/icache.sv index 5786b64d4..b1679ec00 100644 --- a/src/icache.sv +++ b/src/icache.sv @@ -25,14 +25,13 @@ module icache #( input logic clk_i, input logic rst_ni, input logic flush_i, // flush the icache, flush and kill have to be asserted together + input logic en_cache_i, // cache accesses input logic req_i, // we request a new word - input logic is_speculative_i, // is this request speculative or not input logic kill_s1_i, // kill the current request input logic kill_s2_i, // kill the last request output logic ready_o, // icache is ready input logic [63:0] vaddr_i, // 1st cycle: 12 bit index is taken for lookup output logic [FETCH_WIDTH-1:0] data_o, // 2+ cycle out: tag - output logic is_speculative_o, // the fetch was speculative output logic [63:0] vaddr_o, // virtual address out output logic valid_o, // signals a valid read output exception_t ex_o, // we've encountered an exception @@ -57,7 +56,6 @@ module icache #( logic [$clog2(ICACHE_NUM_WORD)-1:0] cnt_d, cnt_q; logic [NR_AXI_REFILLS-1:0] burst_cnt_d, burst_cnt_q; // counter for AXI transfers logic [63:0] vaddr_d, vaddr_q; - logic spec_d, spec_q; // request is speculative logic [TAG_WIDTH-1:0] tag_d, tag_q; logic [SET_ASSOCIATIVITY-1:0] evict_way_d, evict_way_q; logic flushing_d, flushing_q; @@ -202,19 +200,19 @@ module icache #( // ------------------ // Cache Ctrl // ------------------ + // for bypassing we use the existing infrastructure of the cache + // but on every access we are re-fetching the cache-line always_comb begin : cache_ctrl // default assignments state_d = state_q; cnt_d = cnt_q; vaddr_d = vaddr_q; - spec_d = spec_q; tag_d = tag_q; evict_way_d = evict_way_q; flushing_d = flushing_q; burst_cnt_d = burst_cnt_q; - is_speculative_o = spec_q; - vaddr_o = vaddr_q; + vaddr_o = vaddr_q; req = '0; addr = vaddr_i[INDEX_WIDTH-1:BYTE_OFFSET]; @@ -244,7 +242,6 @@ module icache #( req = '1; // save the virtual address vaddr_d = vaddr_i; - spec_d = is_speculative_i; state_d = TAG_CMP; end @@ -264,7 +261,7 @@ module icache #( // ------- // Hit // ------- - if (|hit && fetch_valid_i) begin + if (|hit && fetch_valid_i && (en_cache_i || (state_q != TAG_CMP))) begin ready_o = 1'b1; valid_o = 1'b1; // we've got another request @@ -273,7 +270,6 @@ module icache #( req = '1; // save the index and stay in compare mode vaddr_d = vaddr_i; - spec_d = is_speculative_i; state_d = TAG_CMP; // no new request -> go back to idle end else begin @@ -287,7 +283,8 @@ module icache #( // ------- end else begin state_d = REFILL; - evict_way_d = '0; + // hit gonna be zero in most cases except for when the cache is disabled + evict_way_d = hit; // save tag tag_d = fetch_paddr_i[TAG_WIDTH+INDEX_WIDTH-1:INDEX_WIDTH]; miss_o = 1'b1; @@ -296,7 +293,7 @@ module icache #( evict_way_d = random_way; // shift the lfsr update_lfsr = 1'b1; - end else begin + end else if (!|hit) begin evict_way_d[repl_invalid] = 1'b1; end end @@ -438,7 +435,6 @@ module icache #( tag_q <= '0; evict_way_q <= '0; flushing_q <= 1'b0; - spec_q <= 1'b0; burst_cnt_q <= '0;; end else begin state_q <= state_d; @@ -447,7 +443,6 @@ module icache #( tag_q <= tag_d; evict_way_q <= evict_way_d; flushing_q <= flushing_d; - spec_q <= spec_d; burst_cnt_q <= burst_cnt_d; end end diff --git a/tb b/tb index d5605a06e..aaf24e628 160000 --- a/tb +++ b/tb @@ -1 +1 @@ -Subproject commit d5605a06ecf7e2fa881c55f25870fdcef5433a48 +Subproject commit aaf24e628e73575705afa15ce5456af60ac26d0a