Make icache bypass-able

This commit is contained in:
Florian Zaruba 2018-06-30 19:27:40 +02:00
parent 5fb6f920d3
commit 9d1218529e
No known key found for this signature in database
GPG key ID: E742FFE8EC38A792
6 changed files with 28 additions and 59 deletions

View file

@ -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

View file

@ -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 ),

View file

@ -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;

View file

@ -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

View file

@ -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

2
tb

@ -1 +1 @@
Subproject commit d5605a06ecf7e2fa881c55f25870fdcef5433a48
Subproject commit aaf24e628e73575705afa15ce5456af60ac26d0a