mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 21:57:11 -04:00
VM based RISC-V tests are passing
This commit is contained in:
parent
f2d45c007b
commit
6c66ea19ae
5 changed files with 102 additions and 83 deletions
24
Makefile
24
Makefile
|
@ -54,18 +54,18 @@ riscv-tests := rv64ui-p-add rv64ui-p-addi rv64ui-p-slli rv64ui-p-addiw rv64ui-p-
|
|||
rv64ui-p-lb rv64ui-p-lbu rv64ui-p-ld rv64ui-p-lh rv64ui-p-lhu rv64ui-p-lui rv64ui-p-lw rv64ui-p-lwu \
|
||||
rv64mi-p-csr rv64mi-p-mcsr rv64mi-p-illegal rv64mi-p-ma_addr rv64mi-p-ma_fetch rv64mi-p-sbreak rv64mi-p-scall \
|
||||
rv64si-p-csr rv64si-p-ma_fetch rv64si-p-scall rv64si-p-wfi rv64si-p-sbreak rv64si-p-dirty \
|
||||
rv64uc-p-rvc
|
||||
# rv64ui-v-add rv64ui-v-addi rv64ui-p-slli rv64ui-v-addiw rv64ui-v-addw rv64ui-v-and rv64ui-v-auipc \
|
||||
# rv64ui-v-beq rv64ui-v-bge rv64ui-v-bgeu rv64ui-v-andi rv64ui-v-blt rv64ui-v-bltu rv64ui-v-bne \
|
||||
# rv64ui-v-simple rv64ui-v-jal rv64ui-v-jalr rv64ui-v-or rv64ui-v-ori rv64ui-v-sub rv64ui-v-subw \
|
||||
# rv64ui-v-xor rv64ui-v-xori rv64ui-v-slliw rv64ui-v-sll rv64ui-v-slli rv64ui-v-slliw \
|
||||
# rv64ui-v-slt rv64ui-v-slti rv64ui-v-sltiu rv64ui-v-sltu rv64ui-v-sra rv64ui-v-srai \
|
||||
# rv64ui-v-sraiw rv64ui-v-sraw rv64ui-v-srl rv64ui-v-srli rv64ui-v-srliw rv64ui-v-srlw \
|
||||
# rv64ui-v-lb rv64ui-v-lbu rv64ui-v-ld rv64ui-v-lh rv64ui-v-lhu rv64ui-v-lui \
|
||||
# rv64um-p-mul rv64um-p-mulh rv64um-p-mulhsu rv64um-p-mulhu rv64um-p-div rv64um-p-divu rv64um-p-rem \
|
||||
# rv64um-p-remu rv64um-p-mulw rv64um-p-divw rv64um-p-divuw rv64um-p-remw rv64um-p-remuw \
|
||||
# rv64um-v-mul rv64um-v-mulh rv64um-v-mulhsu rv64um-v-mulhu rv64um-v-div rv64um-v-divu rv64um-v-rem \
|
||||
# rv64um-v-remu rv64um-v-mulw rv64um-v-divw rv64um-v-divuw rv64um-v-remw rv64um-v-remuw
|
||||
rv64uc-p-rvc \
|
||||
rv64ui-v-add rv64ui-v-addi rv64ui-p-slli rv64ui-v-addiw rv64ui-v-addw rv64ui-v-and rv64ui-v-auipc \
|
||||
rv64ui-v-beq rv64ui-v-bge rv64ui-v-bgeu rv64ui-v-andi rv64ui-v-blt rv64ui-v-bltu rv64ui-v-bne \
|
||||
rv64ui-v-simple rv64ui-v-jal rv64ui-v-jalr rv64ui-v-or rv64ui-v-ori rv64ui-v-sub rv64ui-v-subw \
|
||||
rv64ui-v-xor rv64ui-v-xori rv64ui-v-slliw rv64ui-v-sll rv64ui-v-slli rv64ui-v-slliw \
|
||||
rv64ui-v-slt rv64ui-v-slti rv64ui-v-sltiu rv64ui-v-sltu rv64ui-v-sra rv64ui-v-srai \
|
||||
rv64ui-v-sraiw rv64ui-v-sraw rv64ui-v-srl rv64ui-v-srli rv64ui-v-srliw rv64ui-v-srlw \
|
||||
rv64ui-v-lb rv64ui-v-lbu rv64ui-v-ld rv64ui-v-lh rv64ui-v-lhu rv64ui-v-lui \
|
||||
rv64um-p-mul rv64um-p-mulh rv64um-p-mulhsu rv64um-p-mulhu rv64um-p-div rv64um-p-divu rv64um-p-rem \
|
||||
rv64um-p-remu rv64um-p-mulw rv64um-p-divw rv64um-p-divuw rv64um-p-remw rv64um-p-remuw \
|
||||
rv64um-v-mul rv64um-v-mulh rv64um-v-mulhsu rv64um-v-mulhu rv64um-v-div rv64um-v-divu rv64um-v-rem \
|
||||
rv64um-v-remu rv64um-v-mulw rv64um-v-divw rv64um-v-divuw rv64um-v-remw rv64um-v-remuw
|
||||
|
||||
# failed test directory
|
||||
failed-tests := $(wildcard failedtests/*.S)
|
||||
|
|
|
@ -286,8 +286,6 @@ module ariane #(
|
|||
.*
|
||||
);
|
||||
|
||||
assign fetch_req_if_ex = 1'b0;
|
||||
|
||||
// ---------
|
||||
// ID
|
||||
// ---------
|
||||
|
|
|
@ -65,6 +65,8 @@ module frontend #(
|
|||
// Registers
|
||||
logic [31:0] icache_data_d, icache_data_q;
|
||||
logic icache_valid_d, icache_valid_q;
|
||||
exception_t icache_ex_d, icache_ex_q;
|
||||
|
||||
logic instruction_valid;
|
||||
|
||||
logic icache_speculative_d, icache_speculative_q;
|
||||
|
@ -384,6 +386,7 @@ module frontend #(
|
|||
icache_valid_q <= 1'b0;
|
||||
icache_speculative_q <= 1'b0;
|
||||
icache_vaddr_q <= 'b0;
|
||||
icache_ex_q <= '0;
|
||||
unaligned_q <= 1'b0;
|
||||
unaligned_address_q <= '0;
|
||||
unaligned_instr_q <= '0;
|
||||
|
@ -393,6 +396,7 @@ module frontend #(
|
|||
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;
|
||||
unaligned_address_q <= unaligned_address_d;
|
||||
unaligned_instr_q <= unaligned_instr_d;
|
||||
|
@ -434,21 +438,21 @@ module frontend #(
|
|||
.CACHE_LINE_WIDTH ( 128 ),
|
||||
.FETCH_WIDTH ( FETCH_WIDTH )
|
||||
) i_icache (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.flush_i ( flush_icache_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 ),
|
||||
.kill_s2_i ( kill_s2 ),
|
||||
.kill_s1_i ( kill_s1 ),
|
||||
.kill_s2_i ( kill_s2 ),
|
||||
.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 )
|
||||
.miss_o ( l1_icache_miss_o ),
|
||||
.*
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < INSTR_PER_FETCH; i++) begin
|
||||
|
@ -471,13 +475,10 @@ module frontend #(
|
|||
);
|
||||
end
|
||||
|
||||
exception_t ex;
|
||||
assign ex = '0;
|
||||
|
||||
fetch_fifo i_fetch_fifo (
|
||||
.flush_i ( flush_i ),
|
||||
.branch_predict_i ( bp_sbe ),
|
||||
.ex_i ( ex ),
|
||||
.ex_i ( icache_ex_q ),
|
||||
.addr_i ( icache_vaddr_q ),
|
||||
.rdata_i ( icache_data_q ),
|
||||
.valid_i ( fifo_valid ),
|
||||
|
@ -670,8 +671,8 @@ module bht #(
|
|||
logic [1:0] saturation_counter;
|
||||
} bht_d[NR_ENTRIES-1:0], bht_q[NR_ENTRIES-1:0];
|
||||
|
||||
logic [$clog2(NR_ENTRIES)-1:0] index, update_pc;
|
||||
logic [1:0] saturation_counter;
|
||||
logic [$clog2(NR_ENTRIES)-1:0] index, update_pc;
|
||||
logic [1:0] saturation_counter;
|
||||
|
||||
assign index = vpc_i[PREDICTION_BITS - 1:OFFSET];
|
||||
assign update_pc = bht_update_i.pc[PREDICTION_BITS - 1:OFFSET];
|
||||
|
|
134
src/icache.sv
134
src/icache.sv
|
@ -13,36 +13,46 @@
|
|||
// ------------------------------
|
||||
// Instruction Cache
|
||||
// ------------------------------
|
||||
import ariane_pkg::*;
|
||||
|
||||
module icache #(
|
||||
parameter int unsigned SET_ASSOCIATIVITY = 4,
|
||||
parameter int unsigned INDEX_WIDTH = 12, // in bit
|
||||
parameter int unsigned TAG_WIDTH = 44, // in bit
|
||||
parameter int unsigned CACHE_LINE_WIDTH = 64, // in bit
|
||||
parameter int unsigned FETCH_WIDTH = 32 // in bit
|
||||
)(
|
||||
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 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 logic miss_o, // we missed on the cache
|
||||
AXI_BUS.Master axi
|
||||
);
|
||||
parameter int unsigned SET_ASSOCIATIVITY = 4,
|
||||
parameter int unsigned INDEX_WIDTH = 12, // in bit
|
||||
parameter int unsigned TAG_WIDTH = 44, // in bit
|
||||
parameter int unsigned CACHE_LINE_WIDTH = 64, // in bit
|
||||
parameter int unsigned FETCH_WIDTH = 32 // in bit
|
||||
)(
|
||||
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 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
|
||||
output logic miss_o, // we missed on the cache
|
||||
AXI_BUS.Master axi,
|
||||
// Address translation
|
||||
output logic fetch_req_o,
|
||||
output logic [63:0] fetch_vaddr_o,
|
||||
input logic fetch_valid_i,
|
||||
input logic [63:0] fetch_paddr_i,
|
||||
input exception_t fetch_exception_i
|
||||
);
|
||||
|
||||
localparam int unsigned BYTE_OFFSET = $clog2(CACHE_LINE_WIDTH/8); // 3
|
||||
localparam int unsigned ICACHE_NUM_WORD = 2**(INDEX_WIDTH - BYTE_OFFSET);
|
||||
localparam int unsigned NR_AXI_REFILLS = ($clog2(CACHE_LINE_WIDTH/64) == 0) ? 1 : $clog2(CACHE_LINE_WIDTH/64);
|
||||
// registers
|
||||
enum logic [3:0] { FLUSH, IDLE, TAG_CMP, WAIT_AXI_R_RESP, WAIT_KILLED_REFILL, WAIT_KILLED_AXI_R_RESP,
|
||||
REDO_REQ, WAIT_TAG_SAVED, REFILL
|
||||
REDO_REQ, TAG_CMP_SAVED, REFILL,
|
||||
WAIT_ADDRESS_TRANSLATION, WAIT_ADDRESS_TRANSLATION_KILLED
|
||||
} state_d, state_q;
|
||||
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
|
||||
|
@ -187,6 +197,8 @@ module icache #(
|
|||
|
||||
assign data_be = be;
|
||||
assign data_wdata = wdata;
|
||||
|
||||
assign ex_o = fetch_exception_i;
|
||||
// ------------------
|
||||
// Cache Ctrl
|
||||
// ------------------
|
||||
|
@ -211,13 +223,16 @@ module icache #(
|
|||
wdata = '0;
|
||||
tag_wdata = '0;
|
||||
ready_o = 1'b0;
|
||||
tag = vaddr_q[TAG_WIDTH+INDEX_WIDTH-1:INDEX_WIDTH];
|
||||
tag = fetch_paddr_i[TAG_WIDTH+INDEX_WIDTH-1:INDEX_WIDTH];
|
||||
valid_o = 1'b0;
|
||||
update_lfsr = 1'b0;
|
||||
miss_o = 1'b0;
|
||||
|
||||
axi.ar_valid = 1'b0;
|
||||
axi.ar_addr = '0;
|
||||
axi.ar_valid = 1'b0;
|
||||
axi.ar_addr = '0;
|
||||
|
||||
fetch_req_o = 1'b0;
|
||||
fetch_vaddr_o = vaddr_q;
|
||||
|
||||
case (state_q)
|
||||
// ~> we are ready to receive a new request
|
||||
|
@ -227,7 +242,7 @@ module icache #(
|
|||
if (req_i) begin
|
||||
// request the content of all arrays
|
||||
req = '1;
|
||||
// save the index
|
||||
// save the virtual address
|
||||
vaddr_d = vaddr_i;
|
||||
spec_d = is_speculative_i;
|
||||
state_d = TAG_CMP;
|
||||
|
@ -241,11 +256,15 @@ module icache #(
|
|||
state_d = IDLE;
|
||||
end
|
||||
// ~> compare the tag
|
||||
TAG_CMP: begin
|
||||
TAG_CMP, TAG_CMP_SAVED: begin
|
||||
fetch_req_o = 1'b1; // request address translation
|
||||
// use the saved tag
|
||||
if (state_q == TAG_CMP_SAVED)
|
||||
tag = tag_q;
|
||||
// -------
|
||||
// Hit
|
||||
// -------
|
||||
if (|hit) begin
|
||||
if (|hit && fetch_valid_i) begin
|
||||
ready_o = 1'b1;
|
||||
valid_o = 1'b1;
|
||||
// we've got another request
|
||||
|
@ -255,6 +274,7 @@ module icache #(
|
|||
// 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
|
||||
state_d = IDLE;
|
||||
|
@ -269,7 +289,7 @@ module icache #(
|
|||
state_d = REFILL;
|
||||
evict_way_d = '0;
|
||||
// save tag
|
||||
tag_d = vaddr_q[TAG_WIDTH+INDEX_WIDTH-1:INDEX_WIDTH];
|
||||
tag_d = fetch_paddr_i[TAG_WIDTH+INDEX_WIDTH-1:INDEX_WIDTH];
|
||||
miss_o = 1'b1;
|
||||
// get way which to replace
|
||||
if (repl_w_random) begin
|
||||
|
@ -280,6 +300,28 @@ module icache #(
|
|||
evict_way_d[repl_invalid] = 1'b1;
|
||||
end
|
||||
end
|
||||
// if we didn't hit on the TLB we need to wait until the request has been completed
|
||||
if (!fetch_valid_i) begin
|
||||
state_d = WAIT_ADDRESS_TRANSLATION;
|
||||
end
|
||||
end
|
||||
// ~> wait here for a valid address translation, or on a translation even if the request has been killed
|
||||
WAIT_ADDRESS_TRANSLATION, WAIT_ADDRESS_TRANSLATION_KILLED: begin
|
||||
fetch_req_o = 1'b1;
|
||||
// retry the request if no exception occurred
|
||||
if (fetch_valid_i && (state_q == WAIT_ADDRESS_TRANSLATION)) begin
|
||||
if (fetch_exception_i.valid)
|
||||
valid_o = 1'b1;
|
||||
else begin
|
||||
state_d = REDO_REQ;
|
||||
tag_d = fetch_paddr_i[TAG_WIDTH+INDEX_WIDTH-1:INDEX_WIDTH];
|
||||
end
|
||||
end else if (fetch_valid_i) begin
|
||||
state_d = IDLE;
|
||||
end
|
||||
|
||||
if (kill_s2_i)
|
||||
state_d = WAIT_ADDRESS_TRANSLATION_KILLED;
|
||||
end
|
||||
// ~> request a cache-line refill
|
||||
REFILL, WAIT_KILLED_REFILL: begin
|
||||
|
@ -326,33 +368,7 @@ module icache #(
|
|||
req = '1;
|
||||
addr = vaddr_q[INDEX_WIDTH-1:BYTE_OFFSET];
|
||||
tag = tag_q;
|
||||
state_d = WAIT_TAG_SAVED;
|
||||
end
|
||||
// we already saved the tag -> apply it
|
||||
WAIT_TAG_SAVED: begin
|
||||
tag = tag_q;
|
||||
state_d = IDLE;
|
||||
valid_o = 1'b1;
|
||||
// TODO: Check if this is necessary in a real payload environment
|
||||
// we can handle a new request here
|
||||
ready_o = 1'b1;
|
||||
// we are getting a new request
|
||||
if (req_i) begin
|
||||
// request the content of all arrays
|
||||
req = '1;
|
||||
// save the index
|
||||
vaddr_d = vaddr_i;
|
||||
spec_d = is_speculative_i;
|
||||
state_d = TAG_CMP;
|
||||
end
|
||||
|
||||
if (kill_s1_i)
|
||||
state_d = IDLE;
|
||||
// go to flushing state
|
||||
if (flush_i || flushing_q)
|
||||
state_d = FLUSH;
|
||||
|
||||
|
||||
state_d = TAG_CMP_SAVED; // do tag comparison on the saved tag
|
||||
end
|
||||
// we need to wait for some AXI responses to come back
|
||||
// here for the AW valid
|
||||
|
@ -387,7 +403,11 @@ module icache #(
|
|||
|
||||
if (flush_i) begin
|
||||
flushing_d = 1'b1;
|
||||
ready_o = 1'b0; // we are not ready to accept a further request here
|
||||
end
|
||||
// if we are going to flush -> do not accept any new requests
|
||||
if (flushing_q)
|
||||
ready_o = 1'b0;
|
||||
end
|
||||
|
||||
ff1 #(
|
||||
|
|
|
@ -224,7 +224,7 @@ module mmu #(
|
|||
// ---------
|
||||
// watch out for exceptions happening during walking the page table
|
||||
if (ptw_active && walking_instr) begin
|
||||
fetch_valid_o = 1'b1;
|
||||
fetch_valid_o = ptw_error;
|
||||
fetch_exception_o = {INSTR_PAGE_FAULT, {25'b0, update_vaddr}, 1'b1};
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue