mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-19 03:44:46 -04:00
Parametrization step 3 part 2 (#1939)
This commit is contained in:
parent
b8ca8588cf
commit
4817575de9
59 changed files with 628 additions and 635 deletions
|
@ -23,9 +23,9 @@ class ex_trace_item #(
|
|||
string cause_s;
|
||||
logic [63:0] cause;
|
||||
logic [63:0] tval;
|
||||
logic [riscv::VLEN-1:0] pc;
|
||||
logic [CVA6Cfg.VLEN-1:0] pc;
|
||||
|
||||
function new (logic [riscv::VLEN-1:0] pc, logic [63:0] cause, logic [63:0] tval);
|
||||
function new (logic [CVA6Cfg.VLEN-1:0] pc, logic [63:0] cause, logic [63:0] tval);
|
||||
|
||||
this.cause = cause;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ class instr_trace_item #(
|
|||
logic result_fpr [$];
|
||||
logic [63:0] imm;
|
||||
logic [63:0] result;
|
||||
logic [riscv::PLEN-1:0] paddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] paddr;
|
||||
string priv_lvl;
|
||||
bp_resolve_t bp;
|
||||
|
||||
|
@ -49,7 +49,7 @@ class instr_trace_item #(
|
|||
|
||||
// constructor creating a new instruction trace item, e.g.: a single instruction with all relevant information
|
||||
function new (time simtime, longint unsigned cycle, scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] gp_reg_file [32],
|
||||
logic [63:0] fp_reg_file [32], logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, bp_resolve_t bp);
|
||||
logic [63:0] fp_reg_file [32], logic [63:0] result, logic [CVA6Cfg.PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, bp_resolve_t bp);
|
||||
this.simtime = simtime;
|
||||
this.cycle = cycle;
|
||||
this.pc = sbe.pc;
|
||||
|
@ -410,7 +410,7 @@ class instr_trace_item #(
|
|||
instr_tracer_pkg::FSW,
|
||||
instr_tracer_pkg::FSD,
|
||||
instr_tracer_pkg::FSQ: begin
|
||||
logic [riscv::VLEN-1:0] vaddress = gp_reg_file[read_regs[1]] + this.imm;
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddress = gp_reg_file[read_regs[1]] + this.imm;
|
||||
s = $sformatf("%s VA: %x PA: %x", s, vaddress, this.paddr);
|
||||
end
|
||||
|
||||
|
@ -432,7 +432,7 @@ class instr_trace_item #(
|
|||
instr_tracer_pkg::FLW,
|
||||
instr_tracer_pkg::FLD,
|
||||
instr_tracer_pkg::FLQ: begin
|
||||
logic [riscv::VLEN-1:0] vaddress = gp_reg_file[read_regs[0]] + this.imm;
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddress = gp_reg_file[read_regs[0]] + this.imm;
|
||||
s = $sformatf("%s VA: %x PA: %x", s, vaddress, this.paddr);
|
||||
end
|
||||
endcase
|
||||
|
|
|
@ -192,7 +192,7 @@ module instr_tracer #(
|
|||
bp = {};
|
||||
endfunction
|
||||
|
||||
function void printInstr(scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, bp_resolve_t bp);
|
||||
function void printInstr(scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [CVA6Cfg.PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, bp_resolve_t bp);
|
||||
automatic instr_trace_item #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
.bp_resolve_t(bp_resolve_t),
|
||||
|
@ -206,7 +206,7 @@ module instr_tracer #(
|
|||
$fwrite(f, {print_instr, "\n"});
|
||||
endfunction
|
||||
|
||||
function void printException(logic [riscv::VLEN-1:0] pc, logic [63:0] cause, logic [63:0] tval);
|
||||
function void printException(logic [CVA6Cfg.VLEN-1:0] pc, logic [63:0] cause, logic [63:0] tval);
|
||||
automatic ex_trace_item #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
.interrupts_t(interrupts_t),
|
||||
|
|
|
@ -45,11 +45,11 @@ interface instr_tracer_if #(
|
|||
// address translation
|
||||
// stores
|
||||
logic st_valid;
|
||||
logic [riscv::PLEN-1:0] st_paddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] st_paddr;
|
||||
// loads
|
||||
logic ld_valid;
|
||||
logic ld_kill;
|
||||
logic [riscv::PLEN-1:0] ld_paddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] ld_paddr;
|
||||
// misprediction
|
||||
bp_resolve_t resolve_branch;
|
||||
// exceptions
|
||||
|
|
|
@ -66,7 +66,7 @@ module acc_dispatcher
|
|||
input priv_lvl_t ld_st_priv_lvl_i,
|
||||
input logic sum_i,
|
||||
input pmpcfg_t [15:0] pmpcfg_i,
|
||||
input logic [15:0][PLEN-3:0] pmpaddr_i,
|
||||
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
input logic [2:0] fcsr_frm_i,
|
||||
output logic dirty_v_state_o,
|
||||
// Interface with the issue stage
|
||||
|
|
18
core/alu.sv
18
core/alu.sv
|
@ -82,7 +82,7 @@ module alu
|
|||
operand_a_bitmanip = fu_data_i.operand_a;
|
||||
|
||||
if (CVA6Cfg.RVB) begin
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
unique case (fu_data_i.operation)
|
||||
SH1ADDUW: operand_a_bitmanip = fu_data_i.operand_a[31:0] << 1;
|
||||
SH2ADDUW: operand_a_bitmanip = fu_data_i.operand_a[31:0] << 2;
|
||||
|
@ -220,7 +220,7 @@ module alu
|
|||
.cnt_o(lz_tz_count),
|
||||
.empty_o(lz_tz_empty)
|
||||
);
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
//32b
|
||||
lzc #(
|
||||
.WIDTH(32),
|
||||
|
@ -246,7 +246,7 @@ module alu
|
|||
{fu_data_i.operand_a[23:16]},
|
||||
{fu_data_i.operand_a[31:24]}
|
||||
};
|
||||
if (riscv::IS_XLEN64) begin : gen_64b
|
||||
if (CVA6Cfg.IS_XLEN64) begin : gen_64b
|
||||
assign orcbw_result = {
|
||||
{8{|fu_data_i.operand_a[63:56]}},
|
||||
{8{|fu_data_i.operand_a[55:48]}},
|
||||
|
@ -272,7 +272,7 @@ module alu
|
|||
// -----------
|
||||
always_comb begin
|
||||
result_o = '0;
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
unique case (fu_data_i.operation)
|
||||
// Add word: Ignore the upper bits and sign extend to 64 bit
|
||||
ADDW, SUBW: result_o = {{riscv::XLEN - 32{adder_result[31]}}, adder_result[31:0]};
|
||||
|
@ -290,7 +290,7 @@ module alu
|
|||
// Adder Operations
|
||||
ADD, SUB, ADDUW, SH1ADD, SH2ADD, SH3ADD: result_o = adder_result;
|
||||
// Shift Operations
|
||||
SLL, SRL, SRA: result_o = (riscv::IS_XLEN64) ? shift_result : shift_result32;
|
||||
SLL, SRL, SRA: result_o = (CVA6Cfg.IS_XLEN64) ? shift_result : shift_result32;
|
||||
// Comparison Operations
|
||||
SLTS, SLTU: result_o = {{riscv::XLEN - 1{1'b0}}, less};
|
||||
default: ; // default case to suppress unique warning
|
||||
|
@ -302,7 +302,7 @@ module alu
|
|||
// rolw, roriw, rorw
|
||||
rolw = ({{riscv::XLEN-32{1'b0}},fu_data_i.operand_a[31:0]} << fu_data_i.operand_b[4:0]) | ({{riscv::XLEN-32{1'b0}},fu_data_i.operand_a[31:0]} >> (riscv::XLEN-32-fu_data_i.operand_b[4:0]));
|
||||
rorw = ({{riscv::XLEN-32{1'b0}},fu_data_i.operand_a[31:0]} >> fu_data_i.operand_b[4:0]) | ({{riscv::XLEN-32{1'b0}},fu_data_i.operand_a[31:0]} << (riscv::XLEN-32-fu_data_i.operand_b[4:0]));
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
unique case (fu_data_i.operation)
|
||||
CLZW, CTZW:
|
||||
result_o = (lz_tz_wempty) ? 32 : {{riscv::XLEN - 5{1'b0}}, lz_tz_wcount}; // change
|
||||
|
@ -339,16 +339,16 @@ module alu
|
|||
|
||||
// Bitwise Rotation
|
||||
ROL:
|
||||
result_o = (riscv::IS_XLEN64) ? ((fu_data_i.operand_a << fu_data_i.operand_b[5:0]) | (fu_data_i.operand_a >> (riscv::XLEN-fu_data_i.operand_b[5:0]))) : ((fu_data_i.operand_a << fu_data_i.operand_b[4:0]) | (fu_data_i.operand_a >> (riscv::XLEN-fu_data_i.operand_b[4:0])));
|
||||
result_o = (CVA6Cfg.IS_XLEN64) ? ((fu_data_i.operand_a << fu_data_i.operand_b[5:0]) | (fu_data_i.operand_a >> (riscv::XLEN-fu_data_i.operand_b[5:0]))) : ((fu_data_i.operand_a << fu_data_i.operand_b[4:0]) | (fu_data_i.operand_a >> (riscv::XLEN-fu_data_i.operand_b[4:0])));
|
||||
|
||||
ROR, RORI:
|
||||
result_o = (riscv::IS_XLEN64) ? ((fu_data_i.operand_a >> fu_data_i.operand_b[5:0]) | (fu_data_i.operand_a << (riscv::XLEN-fu_data_i.operand_b[5:0]))) : ((fu_data_i.operand_a >> fu_data_i.operand_b[4:0]) | (fu_data_i.operand_a << (riscv::XLEN-fu_data_i.operand_b[4:0])));
|
||||
result_o = (CVA6Cfg.IS_XLEN64) ? ((fu_data_i.operand_a >> fu_data_i.operand_b[5:0]) | (fu_data_i.operand_a << (riscv::XLEN-fu_data_i.operand_b[5:0]))) : ((fu_data_i.operand_a >> fu_data_i.operand_b[4:0]) | (fu_data_i.operand_a << (riscv::XLEN-fu_data_i.operand_b[4:0])));
|
||||
|
||||
ORCB: result_o = orcbw_result;
|
||||
REV8: result_o = rev8w_result;
|
||||
|
||||
default:
|
||||
if (fu_data_i.operation == SLLIUW && riscv::IS_XLEN64)
|
||||
if (fu_data_i.operation == SLLIUW && CVA6Cfg.IS_XLEN64)
|
||||
result_o = {{riscv::XLEN-32{1'b0}}, fu_data_i.operand_a[31:0]} << fu_data_i.operand_b[5:0]; // Left Shift 32 bit unsigned
|
||||
endcase
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ module amo_buffer #(
|
|||
input logic valid_i, // AMO is valid
|
||||
output logic ready_o, // AMO unit is ready
|
||||
input ariane_pkg::amo_t amo_op_i, // AMO Operation
|
||||
input logic [riscv::PLEN-1:0] paddr_i, // physical address of store which needs to be placed in the queue
|
||||
input logic [CVA6Cfg.PLEN-1:0] paddr_i, // physical address of store which needs to be placed in the queue
|
||||
input logic [riscv::XLEN-1:0] data_i, // data which is placed in the queue
|
||||
input logic [1:0] data_size_i, // type of request we are making (e.g.: bytes to write)
|
||||
// D$
|
||||
|
@ -38,10 +38,10 @@ module amo_buffer #(
|
|||
logic amo_valid;
|
||||
|
||||
typedef struct packed {
|
||||
ariane_pkg::amo_t op;
|
||||
logic [riscv::PLEN-1:0] paddr;
|
||||
logic [riscv::XLEN-1:0] data;
|
||||
logic [1:0] size;
|
||||
ariane_pkg::amo_t op;
|
||||
logic [CVA6Cfg.PLEN-1:0] paddr;
|
||||
logic [riscv::XLEN-1:0] data;
|
||||
logic [1:0] size;
|
||||
} amo_op_t;
|
||||
|
||||
amo_op_t amo_data_in, amo_data_out;
|
||||
|
@ -50,7 +50,7 @@ module amo_buffer #(
|
|||
assign amo_req_o.req = no_st_pending_i & amo_valid_commit_i & amo_valid;
|
||||
assign amo_req_o.amo_op = amo_data_out.op;
|
||||
assign amo_req_o.size = amo_data_out.size;
|
||||
assign amo_req_o.operand_a = {{64 - riscv::PLEN{1'b0}}, amo_data_out.paddr};
|
||||
assign amo_req_o.operand_a = {{64 - CVA6Cfg.PLEN{1'b0}}, amo_data_out.paddr};
|
||||
assign amo_req_o.operand_b = {{64 - riscv::XLEN{1'b0}}, amo_data_out.data};
|
||||
|
||||
assign amo_data_in.op = amo_op_i;
|
||||
|
|
|
@ -269,7 +269,7 @@ module axi_shim #(
|
|||
// return path
|
||||
assign axi_req_o.r_ready = rd_rdy_i;
|
||||
assign rd_data_o = axi_resp_i.r.data;
|
||||
if (ariane_pkg::AXI_USER_EN) begin
|
||||
if (CVA6Cfg.AXI_USER_EN) begin
|
||||
assign rd_user_o = axi_resp_i.r.user;
|
||||
end else begin
|
||||
assign rd_user_o = '0;
|
||||
|
|
|
@ -28,7 +28,7 @@ module branch_unit #(
|
|||
// FU data needed to execute instruction - ISSUE_STAGE
|
||||
input fu_data_t fu_data_i,
|
||||
// Instruction PC - ISSUE_STAGE
|
||||
input logic [riscv::VLEN-1:0] pc_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] pc_i,
|
||||
// Instruction is compressed - ISSUE_STAGE
|
||||
input logic is_compressed_instr_i,
|
||||
// any functional unit is valid, check that there is no accidental mis-predict - TO_BE_COMPLETED
|
||||
|
@ -38,7 +38,7 @@ module branch_unit #(
|
|||
// ALU branch compare result - ALU
|
||||
input logic branch_comp_res_i,
|
||||
// Brach unit result - ISSUE_STAGE
|
||||
output logic [riscv::VLEN-1:0] branch_result_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] branch_result_o,
|
||||
// Information of branch prediction - ISSUE_STAGE
|
||||
input branchpredict_sbe_t branch_predict_i,
|
||||
// Signaling that we resolved the branch - ISSUE_STAGE
|
||||
|
@ -48,28 +48,28 @@ module branch_unit #(
|
|||
// Branch exception out - TO_BE_COMPLETED
|
||||
output exception_t branch_exception_o
|
||||
);
|
||||
logic [riscv::VLEN-1:0] target_address;
|
||||
logic [riscv::VLEN-1:0] next_pc;
|
||||
logic [CVA6Cfg.VLEN-1:0] target_address;
|
||||
logic [CVA6Cfg.VLEN-1:0] next_pc;
|
||||
|
||||
// here we handle the various possibilities of mis-predicts
|
||||
always_comb begin : mispredict_handler
|
||||
// set the jump base, for JALR we need to look at the register, for all other control flow instructions we can take the current PC
|
||||
automatic logic [riscv::VLEN-1:0] jump_base;
|
||||
automatic logic [CVA6Cfg.VLEN-1:0] jump_base;
|
||||
// TODO(zarubaf): The ALU can be used to calculate the branch target
|
||||
jump_base = (fu_data_i.operation == ariane_pkg::JALR) ? fu_data_i.operand_a[riscv::VLEN-1:0] : pc_i;
|
||||
jump_base = (fu_data_i.operation == ariane_pkg::JALR) ? fu_data_i.operand_a[CVA6Cfg.VLEN-1:0] : pc_i;
|
||||
|
||||
target_address = {riscv::VLEN{1'b0}};
|
||||
target_address = {CVA6Cfg.VLEN{1'b0}};
|
||||
resolve_branch_o = 1'b0;
|
||||
resolved_branch_o.target_address = {riscv::VLEN{1'b0}};
|
||||
resolved_branch_o.target_address = {CVA6Cfg.VLEN{1'b0}};
|
||||
resolved_branch_o.is_taken = 1'b0;
|
||||
resolved_branch_o.valid = branch_valid_i;
|
||||
resolved_branch_o.is_mispredict = 1'b0;
|
||||
resolved_branch_o.cf_type = branch_predict_i.cf;
|
||||
// calculate next PC, depending on whether the instruction is compressed or not this may be different
|
||||
// TODO(zarubaf): We already calculate this a couple of times, maybe re-use?
|
||||
next_pc = pc_i + ((is_compressed_instr_i) ? {{riscv::VLEN-2{1'b0}}, 2'h2} : {{riscv::VLEN-3{1'b0}}, 3'h4});
|
||||
next_pc = pc_i + ((is_compressed_instr_i) ? {{CVA6Cfg.VLEN-2{1'b0}}, 2'h2} : {{CVA6Cfg.VLEN-3{1'b0}}, 3'h4});
|
||||
// calculate target address simple 64 bit addition
|
||||
target_address = $unsigned($signed(jump_base) + $signed(fu_data_i.imm[riscv::VLEN-1:0]));
|
||||
target_address = $unsigned($signed(jump_base) + $signed(fu_data_i.imm[CVA6Cfg.VLEN-1:0]));
|
||||
// on a JALR we are supposed to reset the LSB to 0 (according to the specification)
|
||||
if (fu_data_i.operation == ariane_pkg::JALR) target_address[0] = 1'b0;
|
||||
// we need to put the branch target address into rd, this is the result of this unit
|
||||
|
@ -113,7 +113,7 @@ module branch_unit #(
|
|||
branch_exception_o.cause = riscv::INSTR_ADDR_MISALIGNED;
|
||||
branch_exception_o.valid = 1'b0;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
branch_exception_o.tval = {{riscv::XLEN - riscv::VLEN{pc_i[riscv::VLEN-1]}}, pc_i};
|
||||
branch_exception_o.tval = {{riscv::XLEN - CVA6Cfg.VLEN{pc_i[CVA6Cfg.VLEN-1]}}, pc_i};
|
||||
else branch_exception_o.tval = '0;
|
||||
// Only throw instruction address misaligned exception if this is indeed a `taken` conditional branch or
|
||||
// an unconditional jump
|
||||
|
|
|
@ -257,7 +257,7 @@ module cache_ctrl
|
|||
// Check for cache-ability
|
||||
// -------------------------
|
||||
if (!config_pkg::is_inside_cacheable_regions(
|
||||
CVA6Cfg, {{{64 - riscv::PLEN} {1'b0}}, tag_o, {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}}}
|
||||
CVA6Cfg, {{{64 - CVA6Cfg.PLEN} {1'b0}}, tag_o, {CVA6Cfg.DCACHE_INDEX_WIDTH{1'b0}}}
|
||||
)) begin
|
||||
mem_req_d.bypass = 1'b1;
|
||||
state_d = WAIT_REFILL_GNT;
|
||||
|
|
|
@ -181,7 +181,7 @@ module cva6_hpdcache_subsystem
|
|||
// NumPorts + 1: Hardware Memory Prefetcher (hwpf)
|
||||
localparam int HPDCACHE_NREQUESTERS = NumPorts + 2;
|
||||
|
||||
typedef logic [riscv::PLEN-1:0] hpdcache_mem_addr_t;
|
||||
typedef logic [CVA6Cfg.PLEN-1:0] hpdcache_mem_addr_t;
|
||||
typedef logic [CVA6Cfg.MEM_TID_WIDTH-1:0] hpdcache_mem_id_t;
|
||||
typedef logic [CVA6Cfg.AxiDataWidth-1:0] hpdcache_mem_data_t;
|
||||
typedef logic [CVA6Cfg.AxiDataWidth/8-1:0] hpdcache_mem_be_t;
|
||||
|
@ -425,7 +425,7 @@ module cva6_hpdcache_subsystem
|
|||
|
||||
hpdcache #(
|
||||
.NREQUESTERS (HPDCACHE_NREQUESTERS),
|
||||
.HPDcacheMemAddrWidth(riscv::PLEN),
|
||||
.HPDcacheMemAddrWidth(CVA6Cfg.PLEN),
|
||||
.HPDcacheMemIdWidth (CVA6Cfg.MEM_TID_WIDTH),
|
||||
.HPDcacheMemDataWidth(CVA6Cfg.AxiDataWidth)
|
||||
) i_hpdcache (
|
||||
|
|
|
@ -77,7 +77,7 @@ module cva6_icache
|
|||
|
||||
// signals
|
||||
logic cache_en_d, cache_en_q; // cache is enabled
|
||||
logic [riscv::VLEN-1:0] vaddr_d, vaddr_q;
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddr_d, vaddr_q;
|
||||
logic paddr_is_nc; // asserted if physical address is non-cacheable
|
||||
logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] cl_hit; // hit from tag compare
|
||||
logic cache_rden; // triggers cache lookup
|
||||
|
@ -138,7 +138,7 @@ module cva6_icache
|
|||
|
||||
// noncacheable if request goes to I/O space, or if cache is disabled
|
||||
assign paddr_is_nc = (~cache_en_q) | (~config_pkg::is_inside_cacheable_regions(
|
||||
CVA6Cfg, {{64 - riscv::PLEN{1'b0}}, cl_tag_d, {CVA6Cfg.ICACHE_INDEX_WIDTH{1'b0}}}
|
||||
CVA6Cfg, {{64 - CVA6Cfg.PLEN{1'b0}}, cl_tag_d, {CVA6Cfg.ICACHE_INDEX_WIDTH{1'b0}}}
|
||||
));
|
||||
|
||||
// pass exception through
|
||||
|
@ -147,7 +147,7 @@ module cva6_icache
|
|||
// latch this in case we have to stall later on
|
||||
// make sure this is 32bit aligned
|
||||
assign vaddr_d = (dreq_o.ready & dreq_i.req) ? dreq_i.vaddr : vaddr_q;
|
||||
assign areq_o.fetch_vaddr = {vaddr_q[riscv::VLEN-1:2], 2'b0};
|
||||
assign areq_o.fetch_vaddr = {vaddr_q[CVA6Cfg.VLEN-1:2], 2'b0};
|
||||
|
||||
// split virtual address into index and offset to address cache arrays
|
||||
assign cl_index = vaddr_d[CVA6Cfg.ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH];
|
||||
|
@ -187,7 +187,7 @@ module cva6_icache
|
|||
///////////////////////////////////////////////////////
|
||||
logic addr_ni;
|
||||
assign addr_ni = config_pkg::is_inside_nonidempotent_regions(
|
||||
CVA6Cfg, {{64 - riscv::PLEN{1'b0}}, areq_i.fetch_paddr}
|
||||
CVA6Cfg, {{64 - CVA6Cfg.PLEN{1'b0}}, areq_i.fetch_paddr}
|
||||
);
|
||||
always_comb begin : p_fsm
|
||||
// default assignment
|
||||
|
|
|
@ -141,7 +141,7 @@ module wt_axi_adapter
|
|||
axi_wr_data[0] = {(CVA6Cfg.AxiDataWidth/riscv::XLEN){dcache_data.data}};
|
||||
axi_wr_user[0] = dcache_data.user;
|
||||
// Cast to AXI address width
|
||||
axi_wr_addr = {{CVA6Cfg.AxiAddrWidth-riscv::PLEN{1'b0}}, dcache_data.paddr};
|
||||
axi_wr_addr = {{CVA6Cfg.AxiAddrWidth-CVA6Cfg.PLEN{1'b0}}, dcache_data.paddr};
|
||||
axi_wr_size = dcache_data.size;
|
||||
axi_wr_req = 1'b0;
|
||||
axi_wr_blen = '0;// single word writes
|
||||
|
@ -166,7 +166,7 @@ module wt_axi_adapter
|
|||
// arbiter mux
|
||||
if (arb_idx) begin
|
||||
// Cast to AXI address width
|
||||
axi_rd_addr = {{CVA6Cfg.AxiAddrWidth - riscv::PLEN{1'b0}}, dcache_data.paddr};
|
||||
axi_rd_addr = {{CVA6Cfg.AxiAddrWidth - CVA6Cfg.PLEN{1'b0}}, dcache_data.paddr};
|
||||
// If dcache_data.size MSB is set, we want to read as much as possible
|
||||
axi_rd_size = dcache_data.size[2] ? MaxNumWords[2:0] : dcache_data.size;
|
||||
if (dcache_data.size[2]) begin
|
||||
|
@ -174,7 +174,7 @@ module wt_axi_adapter
|
|||
end
|
||||
end else begin
|
||||
// Cast to AXI address width
|
||||
axi_rd_addr = {{CVA6Cfg.AxiAddrWidth - riscv::PLEN{1'b0}}, icache_data.paddr};
|
||||
axi_rd_addr = {{CVA6Cfg.AxiAddrWidth - CVA6Cfg.PLEN{1'b0}}, icache_data.paddr};
|
||||
axi_rd_size = MaxNumWords[2:0]; // always request max number of words in case of ifill
|
||||
if (!icache_data.nc) begin
|
||||
axi_rd_blen = AxiRdBlenIcache[$clog2(AxiNumWords)-1:0];
|
||||
|
@ -210,7 +210,7 @@ module wt_axi_adapter
|
|||
2'b10:
|
||||
axi_wr_be[0][dcache_data.paddr[$clog2(CVA6Cfg.AxiDataWidth/8)-1:0]+:4] = '1; // word
|
||||
default:
|
||||
if (riscv::IS_XLEN64)
|
||||
if (CVA6Cfg.IS_XLEN64)
|
||||
axi_wr_be[0][dcache_data.paddr[$clog2(
|
||||
CVA6Cfg.AxiDataWidth/8
|
||||
)-1:0]+:8] = '1; // dword
|
||||
|
|
|
@ -87,7 +87,7 @@ module wt_cache_subsystem
|
|||
wt_cache_pkg::dcache_out_t rtype; // see definitions above
|
||||
logic [2:0] size; // transaction size: 000=Byte 001=2Byte; 010=4Byte; 011=8Byte; 111=Cache line (16/32Byte)
|
||||
logic [CVA6Cfg.DCACHE_SET_ASSOC_WIDTH-1:0] way; // way to replace
|
||||
logic [riscv::PLEN-1:0] paddr; // physical address
|
||||
logic [CVA6Cfg.PLEN-1:0] paddr; // physical address
|
||||
logic [riscv::XLEN-1:0] data; // word width of processor (no block stores at the moment)
|
||||
logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] user; // user width of processor (no block stores at the moment)
|
||||
logic nc; // noncacheable
|
||||
|
|
|
@ -97,7 +97,7 @@ module wt_dcache
|
|||
logic [ NumPorts-1:0] miss_we;
|
||||
logic [ NumPorts-1:0][ riscv::XLEN-1:0] miss_wdata;
|
||||
logic [ NumPorts-1:0][ CVA6Cfg.DCACHE_USER_WIDTH-1:0] miss_wuser;
|
||||
logic [ NumPorts-1:0][ riscv::PLEN-1:0] miss_paddr;
|
||||
logic [ NumPorts-1:0][ CVA6Cfg.PLEN-1:0] miss_paddr;
|
||||
logic [ NumPorts-1:0][ 2:0] miss_size;
|
||||
logic [ NumPorts-1:0][ CVA6Cfg.MEM_TID_WIDTH-1:0] miss_id;
|
||||
logic [ NumPorts-1:0] miss_replay;
|
||||
|
@ -118,7 +118,7 @@ module wt_dcache
|
|||
logic [ CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_hit_oh;
|
||||
|
||||
// miss unit <-> wbuffer
|
||||
logic [ CVA6Cfg.DCACHE_MAX_TX-1:0][ riscv::PLEN-1:0] tx_paddr;
|
||||
logic [ CVA6Cfg.DCACHE_MAX_TX-1:0][ CVA6Cfg.PLEN-1:0] tx_paddr;
|
||||
logic [ CVA6Cfg.DCACHE_MAX_TX-1:0] tx_vld;
|
||||
|
||||
// wbuffer <-> memory
|
||||
|
@ -241,7 +241,7 @@ module wt_dcache
|
|||
assign miss_wdata[k] = {{riscv::XLEN} {1'b0}};
|
||||
assign miss_wuser[k] = {{CVA6Cfg.DCACHE_USER_WIDTH} {1'b0}};
|
||||
assign miss_vld_bits_o[k] = {{CVA6Cfg.DCACHE_SET_ASSOC} {1'b0}};
|
||||
assign miss_paddr[k] = {{riscv::PLEN} {1'b0}};
|
||||
assign miss_paddr[k] = {{CVA6Cfg.PLEN} {1'b0}};
|
||||
assign miss_nc[k] = 1'b0;
|
||||
assign miss_size[k] = 3'b0;
|
||||
assign miss_id[k] = {{CVA6Cfg.MEM_TID_WIDTH} {1'b0}};
|
||||
|
|
|
@ -36,7 +36,7 @@ module wt_dcache_ctrl
|
|||
output logic [riscv::XLEN-1:0] miss_wdata_o, // unused (set to 0)
|
||||
output logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] miss_wuser_o, // unused (set to 0)
|
||||
output logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // valid bits at the missed index
|
||||
output logic [riscv::PLEN-1:0] miss_paddr_o,
|
||||
output logic [CVA6Cfg.PLEN-1:0] miss_paddr_o,
|
||||
output logic miss_nc_o, // request to I/O space
|
||||
output logic [2:0] miss_size_o, // 00: 1byte, 01: 2byte, 10: 4byte, 11: 8byte, 111: cacheline
|
||||
output logic [CVA6Cfg.MEM_TID_WIDTH-1:0] miss_id_o, // set to constant ID
|
||||
|
|
|
@ -123,7 +123,7 @@ module wt_dcache_mem
|
|||
logic [ (riscv::XLEN/8)-1:0] wbuffer_be;
|
||||
logic [riscv::XLEN-1:0] wbuffer_rdata, rdata;
|
||||
logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] wbuffer_ruser, ruser;
|
||||
logic [riscv::PLEN-1:0] wbuffer_cmp_addr;
|
||||
logic [CVA6Cfg.PLEN-1:0] wbuffer_cmp_addr;
|
||||
|
||||
logic cmp_en_d, cmp_en_q;
|
||||
logic rd_acked;
|
||||
|
|
|
@ -45,7 +45,7 @@ module wt_dcache_missunit
|
|||
input logic [NumPorts-1:0] miss_we_i,
|
||||
input logic [NumPorts-1:0][riscv::XLEN-1:0] miss_wdata_i,
|
||||
input logic [NumPorts-1:0][CVA6Cfg.DCACHE_USER_WIDTH-1:0] miss_wuser_i,
|
||||
input logic [NumPorts-1:0][riscv::PLEN-1:0] miss_paddr_i,
|
||||
input logic [NumPorts-1:0][CVA6Cfg.PLEN-1:0] miss_paddr_i,
|
||||
input logic [NumPorts-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits_i,
|
||||
input logic [NumPorts-1:0][2:0] miss_size_i,
|
||||
input logic [NumPorts-1:0][CVA6Cfg.MEM_TID_WIDTH-1:0] miss_id_i, // used as transaction ID
|
||||
|
@ -55,7 +55,7 @@ module wt_dcache_missunit
|
|||
output logic [NumPorts-1:0] miss_rtrn_vld_o,
|
||||
output logic [CVA6Cfg.MEM_TID_WIDTH-1:0] miss_rtrn_id_o, // only used for writes, set to zero fro reads
|
||||
// from writebuffer
|
||||
input logic [CVA6Cfg.DCACHE_MAX_TX-1:0][riscv::PLEN-1:0] tx_paddr_i, // used to check for address collisions with read operations
|
||||
input logic [CVA6Cfg.DCACHE_MAX_TX-1:0][CVA6Cfg.PLEN-1:0] tx_paddr_i, // used to check for address collisions with read operations
|
||||
input logic [CVA6Cfg.DCACHE_MAX_TX-1:0] tx_vld_i, // used to check for address collisions with read operations
|
||||
// write interface to cache memory
|
||||
output logic wr_cl_vld_o, // writes a full cacheline
|
||||
|
@ -91,9 +91,9 @@ module wt_dcache_missunit
|
|||
// 010: word
|
||||
// 011: dword
|
||||
// 111: DCACHE line
|
||||
function automatic logic [riscv::PLEN-1:0] paddrSizeAlign(input logic [riscv::PLEN-1:0] paddr,
|
||||
input logic [2:0] size);
|
||||
logic [riscv::PLEN-1:0] out;
|
||||
function automatic logic [CVA6Cfg.PLEN-1:0] paddrSizeAlign(input logic [CVA6Cfg.PLEN-1:0] paddr,
|
||||
input logic [2:0] size);
|
||||
logic [CVA6Cfg.PLEN-1:0] out;
|
||||
out = paddr;
|
||||
unique case (size)
|
||||
3'b001: out[0:0] = '0;
|
||||
|
@ -119,7 +119,7 @@ module wt_dcache_missunit
|
|||
|
||||
// MSHR for reads
|
||||
typedef struct packed {
|
||||
logic [riscv::PLEN-1:0] paddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] paddr;
|
||||
logic [2:0] size;
|
||||
logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] vld_bits;
|
||||
logic [CVA6Cfg.MEM_TID_WIDTH-1:0] id;
|
||||
|
@ -143,7 +143,7 @@ module wt_dcache_missunit
|
|||
logic [63:0] amo_rtrn_mux;
|
||||
logic [riscv::XLEN-1:0] amo_data, amo_data_a, amo_data_b;
|
||||
logic [riscv::XLEN-1:0] amo_user; //DCACHE USER ? CVA6Cfg.DCACHE_USER_WIDTH
|
||||
logic [riscv::PLEN-1:0] tmp_paddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] tmp_paddr;
|
||||
logic [$clog2(NumPorts)-1:0] miss_port_idx;
|
||||
logic [DCACHE_CL_IDX_WIDTH-1:0] cnt_d, cnt_q;
|
||||
logic [NumPorts-1:0] miss_req_masked_d, miss_req_masked_q;
|
||||
|
@ -224,19 +224,19 @@ module wt_dcache_missunit
|
|||
|
||||
|
||||
for (genvar k = 0; k < NumPorts; k++) begin : gen_rdrd_collision
|
||||
assign mshr_rdrd_collision[k] = (mshr_q.paddr[riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == miss_paddr_i[k][riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && (mshr_vld_q | mshr_vld_q1);
|
||||
assign mshr_rdrd_collision[k] = (mshr_q.paddr[CVA6Cfg.PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == miss_paddr_i[k][CVA6Cfg.PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && (mshr_vld_q | mshr_vld_q1);
|
||||
assign mshr_rdrd_collision_d[k] = (!miss_req_i[k]) ? 1'b0 : mshr_rdrd_collision_q[k] | mshr_rdrd_collision[k];
|
||||
end
|
||||
|
||||
// read/write collision, stalls the corresponding request
|
||||
// write port[NumPorts-1] collides with MSHR_Q
|
||||
assign mshr_rdwr_collision = (mshr_q.paddr[riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == miss_paddr_i[NumPorts-1][riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && mshr_vld_q;
|
||||
assign mshr_rdwr_collision = (mshr_q.paddr[CVA6Cfg.PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == miss_paddr_i[NumPorts-1][CVA6Cfg.PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && mshr_vld_q;
|
||||
|
||||
// read collides with inflight TX
|
||||
always_comb begin : p_tx_coll
|
||||
tx_rdwr_collision = 1'b0;
|
||||
for (int k = 0; k < CVA6Cfg.DCACHE_MAX_TX; k++) begin
|
||||
tx_rdwr_collision |= (miss_paddr_i[miss_port_idx][riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == tx_paddr_i[k][riscv::PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && tx_vld_i[k];
|
||||
tx_rdwr_collision |= (miss_paddr_i[miss_port_idx][CVA6Cfg.PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH] == tx_paddr_i[k][CVA6Cfg.PLEN-1:CVA6Cfg.DCACHE_OFFSET_WIDTH]) && tx_vld_i[k];
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -247,7 +247,7 @@ module wt_dcache_missunit
|
|||
// if size = 32bit word, select appropriate offset, replicate for openpiton...
|
||||
|
||||
if (CVA6Cfg.RVA) begin
|
||||
if (riscv::IS_XLEN64) begin : gen_amo_64b_data
|
||||
if (CVA6Cfg.IS_XLEN64) begin : gen_amo_64b_data
|
||||
assign amo_data_a = {amo_req_i.operand_b[0+:32], amo_req_i.operand_b[0+:32]};
|
||||
assign amo_data_b = amo_req_i.operand_b;
|
||||
end else begin : gen_amo_32b_data
|
||||
|
@ -257,7 +257,7 @@ module wt_dcache_missunit
|
|||
|
||||
always_comb begin
|
||||
if (CVA6Cfg.RVA) begin
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
if (amo_req_i.size == 2'b10) begin
|
||||
amo_data = amo_data_a;
|
||||
end else begin
|
||||
|
@ -303,7 +303,7 @@ module wt_dcache_missunit
|
|||
assign mem_data_o.size = (CVA6Cfg.RVA && amo_sel) ? {1'b0, amo_req_i.size} : miss_size_i [miss_port_idx];
|
||||
assign mem_data_o.amo_op = (CVA6Cfg.RVA && amo_sel) ? amo_req_i.amo_op : AMO_NONE;
|
||||
|
||||
assign tmp_paddr = (CVA6Cfg.RVA && amo_sel) ? amo_req_i.operand_a[riscv::PLEN-1:0] : miss_paddr_i[miss_port_idx];
|
||||
assign tmp_paddr = (CVA6Cfg.RVA && amo_sel) ? amo_req_i.operand_a[CVA6Cfg.PLEN-1:0] : miss_paddr_i[miss_port_idx];
|
||||
assign mem_data_o.paddr = paddrSizeAlign(tmp_paddr, mem_data_o.size);
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
|
|
@ -70,7 +70,7 @@ module wt_dcache_wbuffer
|
|||
output dcache_req_o_t req_port_o,
|
||||
// interface to miss handler
|
||||
input logic miss_ack_i,
|
||||
output logic [riscv::PLEN-1:0] miss_paddr_o,
|
||||
output logic [CVA6Cfg.PLEN-1:0] miss_paddr_o,
|
||||
output logic miss_req_o,
|
||||
output logic miss_we_o, // always 1 here
|
||||
output logic [riscv::XLEN-1:0] miss_wdata_o,
|
||||
|
@ -105,7 +105,7 @@ module wt_dcache_wbuffer
|
|||
output logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] wr_user_o,
|
||||
// to forwarding logic and miss unit
|
||||
output wbuffer_t [DCACHE_WBUF_DEPTH-1:0] wbuffer_data_o,
|
||||
output logic [CVA6Cfg.DCACHE_MAX_TX-1:0][riscv::PLEN-1:0] tx_paddr_o, // used to check for address collisions with read operations
|
||||
output logic [CVA6Cfg.DCACHE_MAX_TX-1:0][CVA6Cfg.PLEN-1:0] tx_paddr_o, // used to check for address collisions with read operations
|
||||
output logic [CVA6Cfg.DCACHE_MAX_TX-1:0] tx_vld_o
|
||||
);
|
||||
|
||||
|
@ -181,7 +181,7 @@ module wt_dcache_wbuffer
|
|||
|
||||
logic [CVA6Cfg.XLEN_ALIGN_BYTES-1:0] bdirty_off;
|
||||
logic [(riscv::XLEN/8)-1:0] tx_be;
|
||||
logic [riscv::PLEN-1:0] wr_paddr, rd_paddr, extract_tag;
|
||||
logic [CVA6Cfg.PLEN-1:0] wr_paddr, rd_paddr, extract_tag;
|
||||
logic [CVA6Cfg.DCACHE_TAG_WIDTH-1:0] rd_tag_d, rd_tag_q;
|
||||
logic [CVA6Cfg.DCACHE_SET_ASSOC-1:0] rd_hit_oh_d, rd_hit_oh_q;
|
||||
logic check_en_d, check_en_q, check_en_q1;
|
||||
|
@ -194,7 +194,7 @@ module wt_dcache_wbuffer
|
|||
logic wr_cl_vld_q, wr_cl_vld_d;
|
||||
logic [DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_q, wr_cl_idx_d;
|
||||
|
||||
logic [riscv::PLEN-1:0] debug_paddr[DCACHE_WBUF_DEPTH-1:0];
|
||||
logic [CVA6Cfg.PLEN-1:0] debug_paddr[DCACHE_WBUF_DEPTH-1:0];
|
||||
|
||||
wbuffer_t wbuffer_check_mux, wbuffer_dirty_mux;
|
||||
|
||||
|
@ -266,20 +266,20 @@ module wt_dcache_wbuffer
|
|||
// note: openpiton can only handle aligned offsets + size, and hence
|
||||
// we have to split unaligned data into multiple transfers (see toSize64)
|
||||
// e.g. if we have the following valid bytes: 0011_1001 -> TX0: 0000_0001, TX1: 0000_1000, TX2: 0011_0000
|
||||
if (riscv::IS_XLEN64) begin : gen_size_64b
|
||||
if (CVA6Cfg.IS_XLEN64) begin : gen_size_64b
|
||||
assign miss_size_o = {1'b0, toSize64(bdirty[dirty_ptr])};
|
||||
end else begin : gen_size_32b
|
||||
assign miss_size_o = {1'b0, toSize32(bdirty[dirty_ptr])};
|
||||
end
|
||||
|
||||
// replicate transfers shorter than a dword
|
||||
assign miss_wdata_o = riscv::IS_XLEN64 ? repData64(
|
||||
assign miss_wdata_o = CVA6Cfg.IS_XLEN64 ? repData64(
|
||||
wbuffer_dirty_mux.data, bdirty_off, miss_size_o[1:0]
|
||||
) : repData32(
|
||||
wbuffer_dirty_mux.data, bdirty_off, miss_size_o[1:0]
|
||||
);
|
||||
if (CVA6Cfg.DATA_USER_EN) begin
|
||||
assign miss_wuser_o = riscv::IS_XLEN64 ? repData64(
|
||||
assign miss_wuser_o = CVA6Cfg.IS_XLEN64 ? repData64(
|
||||
wbuffer_dirty_mux.user, bdirty_off, miss_size_o[1:0]
|
||||
) : repData32(
|
||||
wbuffer_dirty_mux.user, bdirty_off, miss_size_o[1:0]
|
||||
|
@ -288,7 +288,7 @@ module wt_dcache_wbuffer
|
|||
assign miss_wuser_o = '0;
|
||||
end
|
||||
|
||||
assign tx_be = riscv::IS_XLEN64 ? to_byte_enable8(
|
||||
assign tx_be = CVA6Cfg.IS_XLEN64 ? to_byte_enable8(
|
||||
bdirty_off, miss_size_o[1:0]
|
||||
) : to_byte_enable4(
|
||||
bdirty_off, miss_size_o[1:0]
|
||||
|
|
|
@ -51,7 +51,7 @@ module commit_stage
|
|||
// Result of AMO operation - CACHE
|
||||
input amo_resp_t amo_resp_i,
|
||||
// TO_BE_COMPLETED - FRONTEND_CSR_REGFILE
|
||||
output logic [riscv::VLEN-1:0] pc_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] pc_o,
|
||||
// Decoded CSR operation - CSR_REGFILE
|
||||
output fu_op csr_op_o,
|
||||
// Data to write to CSR - CSR_REGFILE
|
||||
|
|
|
@ -111,7 +111,7 @@ module compressed_decoder #(
|
|||
// c.ld -> ld rd', imm(rs1')
|
||||
// RV32
|
||||
// c.flw -> flw fprd', imm(rs1')
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
// CLD: | funct3 | imm[5:3] | rs1' | imm[7:6] | rd' | C0 |
|
||||
instr_o = {
|
||||
4'b0,
|
||||
|
@ -282,7 +282,7 @@ module compressed_decoder #(
|
|||
// c.sd -> sd rs2', imm(rs1')
|
||||
// RV32
|
||||
// c.fsw -> fsw fprs2', imm(rs1')
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
instr_o = {
|
||||
4'b0,
|
||||
instr_i[6:5],
|
||||
|
@ -343,7 +343,7 @@ module compressed_decoder #(
|
|||
|
||||
|
||||
riscv::OpcodeC1Addiw: begin // or riscv::OpcodeC1Jal for RV32IC
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
// c.addiw -> addiw rd, rd, nzimm for RV64IC
|
||||
if (instr_i[11:7] != 5'h0) begin // only valid if the destination is not r0
|
||||
instr_o = {
|
||||
|
@ -516,7 +516,7 @@ module compressed_decoder #(
|
|||
end
|
||||
|
||||
3'b100: begin
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
// c.subw -> subw rd', rd', rs2'
|
||||
instr_o = {
|
||||
2'b01,
|
||||
|
@ -536,7 +536,7 @@ module compressed_decoder #(
|
|||
end
|
||||
|
||||
3'b101: begin
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
// c.addw -> addw rd', rd', rs2'
|
||||
instr_o = {
|
||||
2'b00,
|
||||
|
@ -613,7 +613,7 @@ module compressed_decoder #(
|
|||
3'b010: begin
|
||||
if (CVA6Cfg.RVB) begin
|
||||
// c.zext.h -> zext.h rd', rd'
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
instr_o = {
|
||||
7'h4,
|
||||
5'h0,
|
||||
|
@ -658,7 +658,7 @@ module compressed_decoder #(
|
|||
3'b100: begin
|
||||
if (CVA6Cfg.RVB) begin
|
||||
// c.zext.w -> add.uw
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
instr_o = {
|
||||
7'h4,
|
||||
5'h0,
|
||||
|
@ -795,7 +795,7 @@ module compressed_decoder #(
|
|||
// c.ldsp -> ld rd, imm(x2)
|
||||
// RV32
|
||||
// c.flwsp -> flw fprd, imm(x2)
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
instr_o = {
|
||||
3'b0,
|
||||
instr_i[4:2],
|
||||
|
@ -900,7 +900,7 @@ module compressed_decoder #(
|
|||
// c.sdsp -> sd rs2, imm(x2)
|
||||
// RV32
|
||||
// c.fswsp -> fsw fprs2, imm(x2)
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
instr_o = {
|
||||
3'b0,
|
||||
instr_i[9:7],
|
||||
|
|
|
@ -39,7 +39,7 @@ module csr_regfile
|
|||
// Commit acknowledged a instruction -> increase instret CSR - COMMIT_STAGE
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i,
|
||||
// Address from which to start booting, mtvec is set to the same address - SUBSYSTEM
|
||||
input logic [riscv::VLEN-1:0] boot_addr_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] boot_addr_i,
|
||||
// Hart id in a multicore environment (reflected in a CSR) - SUBSYSTEM
|
||||
input logic [riscv::XLEN-1:0] hart_id_i,
|
||||
// we are taking an exception
|
||||
|
@ -60,15 +60,15 @@ module csr_regfile
|
|||
// Mark the V state as dirty - ACC_DISPATCHER
|
||||
input logic dirty_v_state_i,
|
||||
// PC of instruction accessing the CSR - COMMIT_STAGE
|
||||
input logic [riscv::VLEN-1:0] pc_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] pc_i,
|
||||
// attempts to access a CSR without appropriate privilege - COMMIT_STAGE
|
||||
output exception_t csr_exception_o,
|
||||
// Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly - FRONTEND
|
||||
output logic [riscv::VLEN-1:0] epc_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] epc_o,
|
||||
// Return from exception, set the PC of epc_o - FRONTEND
|
||||
output logic eret_o,
|
||||
// Output base of exception vector, correct CSR is output (mtvec, stvec) - FRONTEND
|
||||
output logic [riscv::VLEN-1:0] trap_vector_base_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] trap_vector_base_o,
|
||||
// Current privilege level the CPU is in - EX_STAGE
|
||||
output riscv::priv_lvl_t priv_lvl_o,
|
||||
// Imprecise FP exception from the accelerator (fcsr.fflags format) - ACC_DISPATCHER
|
||||
|
@ -137,7 +137,7 @@ module csr_regfile
|
|||
// PMP configuration containing pmpcfg for max 16 PMPs - ACC_DISPATCHER
|
||||
output riscv::pmpcfg_t [15:0] pmpcfg_o,
|
||||
// PMP addresses - ACC_DISPATCHER
|
||||
output logic [15:0][riscv::PLEN-3:0] pmpaddr_o,
|
||||
output logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_o,
|
||||
// TO_BE_COMPLETED - PERF_COUNTERS
|
||||
output logic [31:0] mcountinhibit_o,
|
||||
// RVFI
|
||||
|
@ -207,7 +207,7 @@ module csr_regfile
|
|||
logic [63:0] instret_q, instret_d;
|
||||
|
||||
riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d, pmpcfg_next;
|
||||
logic [15:0][riscv::PLEN-3:0] pmpaddr_q, pmpaddr_d, pmpaddr_next;
|
||||
logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_q, pmpaddr_d, pmpaddr_next;
|
||||
logic [MHPMCounterNum+3-1:0] mcountinhibit_d, mcountinhibit_q;
|
||||
logic [3:0] index;
|
||||
|
||||
|
@ -238,7 +238,7 @@ module csr_regfile
|
|||
// ----------------
|
||||
// CSR Read logic
|
||||
// ----------------
|
||||
assign mstatus_extended = riscv::IS_XLEN64 ? mstatus_q[riscv::XLEN-1:0] :
|
||||
assign mstatus_extended = CVA6Cfg.IS_XLEN64 ? mstatus_q[riscv::XLEN-1:0] :
|
||||
{mstatus_q.sd, mstatus_q.wpri3[7:0], mstatus_q[22:0]};
|
||||
|
||||
|
||||
|
@ -595,8 +595,8 @@ module csr_regfile
|
|||
// -> last bit of pmpaddr must be set 0/1 based on the mode:
|
||||
// NA4, NAPOT: 1
|
||||
// TOR, OFF: 0
|
||||
if (pmpcfg_q[index].addr_mode[1] == 1'b1) csr_rdata = pmpaddr_q[index][riscv::PLEN-3:0];
|
||||
else csr_rdata = {pmpaddr_q[index][riscv::PLEN-3:1], 1'b0};
|
||||
if (pmpcfg_q[index].addr_mode[1] == 1'b1) csr_rdata = pmpaddr_q[index][CVA6Cfg.PLEN-3:0];
|
||||
else csr_rdata = {pmpaddr_q[index][CVA6Cfg.PLEN-3:1], 1'b0};
|
||||
end
|
||||
default: read_access_exception = 1'b1;
|
||||
endcase
|
||||
|
@ -659,7 +659,7 @@ module csr_regfile
|
|||
// boot_addr_i will be assigned a constant
|
||||
// on the top-level.
|
||||
if (mtvec_rst_load_q) begin
|
||||
mtvec_d = {{riscv::XLEN - riscv::VLEN{1'b0}}, boot_addr_i} + 'h40;
|
||||
mtvec_d = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, boot_addr_i} + 'h40;
|
||||
end else begin
|
||||
mtvec_d = mtvec_q;
|
||||
end
|
||||
|
@ -1089,7 +1089,7 @@ module csr_regfile
|
|||
automatic logic [3:0] index = csr_addr.csr_decode.address[3:0];
|
||||
// check if the entry or the entry above is locked
|
||||
if (!pmpcfg_q[index].locked && !(pmpcfg_q[index+1].locked && pmpcfg_q[index].addr_mode == riscv::TOR)) begin
|
||||
pmpaddr_d[index] = csr_wdata[riscv::PLEN-3:0];
|
||||
pmpaddr_d[index] = csr_wdata[CVA6Cfg.PLEN-3:0];
|
||||
end
|
||||
end
|
||||
default: update_access_exception = 1'b1;
|
||||
|
@ -1176,7 +1176,7 @@ module csr_regfile
|
|||
// set cause
|
||||
scause_d = ex_i.cause;
|
||||
// set epc
|
||||
sepc_d = {{riscv::XLEN - riscv::VLEN{pc_i[riscv::VLEN-1]}}, pc_i};
|
||||
sepc_d = {{riscv::XLEN - CVA6Cfg.VLEN{pc_i[CVA6Cfg.VLEN-1]}}, pc_i};
|
||||
// set mtval or stval
|
||||
stval_d = (ariane_pkg::ZERO_TVAL
|
||||
&& (ex_i.cause inside {
|
||||
|
@ -1195,7 +1195,7 @@ module csr_regfile
|
|||
mstatus_d.mpp = priv_lvl_q;
|
||||
mcause_d = ex_i.cause;
|
||||
// set epc
|
||||
mepc_d = {{riscv::XLEN - riscv::VLEN{pc_i[riscv::VLEN-1]}}, pc_i};
|
||||
mepc_d = {{riscv::XLEN - CVA6Cfg.VLEN{pc_i[CVA6Cfg.VLEN-1]}}, pc_i};
|
||||
// set mtval or stval
|
||||
if (CVA6Cfg.TvalEn) begin
|
||||
mtval_d = (ariane_pkg::ZERO_TVAL
|
||||
|
@ -1252,7 +1252,7 @@ module csr_regfile
|
|||
default: ;
|
||||
endcase
|
||||
// save PC of next this instruction e.g.: the next one to be executed
|
||||
dpc_d = {{riscv::XLEN - riscv::VLEN{pc_i[riscv::VLEN-1]}}, pc_i};
|
||||
dpc_d = {{riscv::XLEN - CVA6Cfg.VLEN{pc_i[CVA6Cfg.VLEN-1]}}, pc_i};
|
||||
dcsr_d.cause = ariane_pkg::CauseBreakpoint;
|
||||
end
|
||||
|
||||
|
@ -1260,7 +1260,7 @@ module csr_regfile
|
|||
if (CVA6Cfg.DebugEn && ex_i.valid && ex_i.cause == riscv::DEBUG_REQUEST) begin
|
||||
dcsr_d.prv = priv_lvl_o;
|
||||
// save the PC
|
||||
dpc_d = {{riscv::XLEN - riscv::VLEN{pc_i[riscv::VLEN-1]}}, pc_i};
|
||||
dpc_d = {{riscv::XLEN - CVA6Cfg.VLEN{pc_i[CVA6Cfg.VLEN-1]}}, pc_i};
|
||||
// enter debug mode
|
||||
debug_mode_d = 1'b1;
|
||||
// jump to the base address
|
||||
|
@ -1276,19 +1276,19 @@ module csr_regfile
|
|||
if (commit_instr_i[0].fu == CTRL_FLOW) begin
|
||||
// we saved the correct target address during execute
|
||||
dpc_d = {
|
||||
{riscv::XLEN - riscv::VLEN{commit_instr_i[0].bp.predict_address[riscv::VLEN-1]}},
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{commit_instr_i[0].bp.predict_address[CVA6Cfg.VLEN-1]}},
|
||||
commit_instr_i[0].bp.predict_address
|
||||
};
|
||||
// exception valid
|
||||
end else if (ex_i.valid) begin
|
||||
dpc_d = {{riscv::XLEN - riscv::VLEN{1'b0}}, trap_vector_base_o};
|
||||
dpc_d = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, trap_vector_base_o};
|
||||
// return from environment
|
||||
end else if (eret_o) begin
|
||||
dpc_d = {{riscv::XLEN - riscv::VLEN{1'b0}}, epc_o};
|
||||
dpc_d = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, epc_o};
|
||||
// consecutive PC
|
||||
end else begin
|
||||
dpc_d = {
|
||||
{riscv::XLEN - riscv::VLEN{commit_instr_i[0].pc[riscv::VLEN-1]}},
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{commit_instr_i[0].pc[CVA6Cfg.VLEN-1]}},
|
||||
commit_instr_i[0].pc + (commit_instr_i[0].is_compressed ? 'h2 : 'h4)
|
||||
};
|
||||
end
|
||||
|
@ -1487,15 +1487,15 @@ module csr_regfile
|
|||
|
||||
// output assignments dependent on privilege mode
|
||||
always_comb begin : priv_output
|
||||
trap_vector_base_o = {mtvec_q[riscv::VLEN-1:2], 2'b0};
|
||||
trap_vector_base_o = {mtvec_q[CVA6Cfg.VLEN-1:2], 2'b0};
|
||||
// output user mode stvec
|
||||
if (CVA6Cfg.RVS && trap_to_priv_lvl == riscv::PRIV_LVL_S) begin
|
||||
trap_vector_base_o = {stvec_q[riscv::VLEN-1:2], 2'b0};
|
||||
trap_vector_base_o = {stvec_q[CVA6Cfg.VLEN-1:2], 2'b0};
|
||||
end
|
||||
|
||||
// if we are in debug mode jump to a specific address
|
||||
if (CVA6Cfg.DebugEn && debug_mode_q) begin
|
||||
trap_vector_base_o = CVA6Cfg.DmBaseAddress[riscv::VLEN-1:0] + CVA6Cfg.ExceptionAddress[riscv::VLEN-1:0];
|
||||
trap_vector_base_o = CVA6Cfg.DmBaseAddress[CVA6Cfg.VLEN-1:0] + CVA6Cfg.ExceptionAddress[CVA6Cfg.VLEN-1:0];
|
||||
end
|
||||
|
||||
// check if we are in vectored mode, if yes then do BASE + 4 * cause we
|
||||
|
@ -1509,14 +1509,14 @@ module csr_regfile
|
|||
trap_vector_base_o[7:2] = ex_i.cause[5:0];
|
||||
end
|
||||
|
||||
epc_o = mepc_q[riscv::VLEN-1:0];
|
||||
epc_o = mepc_q[CVA6Cfg.VLEN-1:0];
|
||||
// we are returning from supervisor mode, so take the sepc register
|
||||
if (CVA6Cfg.RVS && sret) begin
|
||||
epc_o = sepc_q[riscv::VLEN-1:0];
|
||||
epc_o = sepc_q[CVA6Cfg.VLEN-1:0];
|
||||
end
|
||||
// we are returning from debug mode, to take the dpc register
|
||||
if (CVA6Cfg.DebugEn && dret) begin
|
||||
epc_o = dpc_q[riscv::VLEN-1:0];
|
||||
epc_o = dpc_q[CVA6Cfg.VLEN-1:0];
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1633,7 +1633,7 @@ module csr_regfile
|
|||
for (int i = 0; i < 16; i++) begin
|
||||
if (i < CVA6Cfg.NrPMPEntries) begin
|
||||
pmpcfg_q[i] <= riscv::pmpcfg_t'(CVA6Cfg.PMPCfgRstVal[i]);
|
||||
pmpaddr_q[i] <= CVA6Cfg.PMPAddrRstVal[i][riscv::PLEN-3:0];
|
||||
pmpaddr_q[i] <= CVA6Cfg.PMPAddrRstVal[i][CVA6Cfg.PLEN-3:0];
|
||||
end else begin
|
||||
pmpcfg_q[i] <= '0;
|
||||
pmpaddr_q[i] <= '0;
|
||||
|
|
170
core/cva6.sv
170
core/cva6.sv
|
@ -34,8 +34,8 @@ module cva6
|
|||
// this is the struct which we will inject into the pipeline to guide the various
|
||||
// units towards the correct branch decision and resolve
|
||||
localparam type branchpredict_sbe_t = struct packed {
|
||||
cf_t cf; // type of control flow prediction
|
||||
logic [riscv::VLEN-1:0] predict_address; // target address at which to jump, or not
|
||||
cf_t cf; // type of control flow prediction
|
||||
logic [CVA6Cfg.VLEN-1:0] predict_address; // target address at which to jump, or not
|
||||
},
|
||||
|
||||
localparam type exception_t = struct packed {
|
||||
|
@ -48,36 +48,36 @@ module cva6
|
|||
// cache request ports
|
||||
// I$ address translation requests
|
||||
localparam type icache_areq_t = struct packed {
|
||||
logic fetch_valid; // address translation valid
|
||||
logic [riscv::PLEN-1:0] fetch_paddr; // physical address in
|
||||
exception_t fetch_exception; // exception occurred during fetch
|
||||
logic fetch_valid; // address translation valid
|
||||
logic [CVA6Cfg.PLEN-1:0] fetch_paddr; // physical address in
|
||||
exception_t fetch_exception; // exception occurred during fetch
|
||||
},
|
||||
localparam type icache_arsp_t = struct packed {
|
||||
logic fetch_req; // address translation request
|
||||
logic [riscv::VLEN-1:0] fetch_vaddr; // virtual address out
|
||||
logic fetch_req; // address translation request
|
||||
logic [CVA6Cfg.VLEN-1:0] fetch_vaddr; // virtual address out
|
||||
},
|
||||
|
||||
// I$ data requests
|
||||
localparam type icache_dreq_t = struct packed {
|
||||
logic req; // we request a new word
|
||||
logic kill_s1; // kill the current request
|
||||
logic kill_s2; // kill the last request
|
||||
logic spec; // request is speculative
|
||||
logic [riscv::VLEN-1:0] vaddr; // 1st cycle: 12 bit index is taken for lookup
|
||||
logic req; // we request a new word
|
||||
logic kill_s1; // kill the current request
|
||||
logic kill_s2; // kill the last request
|
||||
logic spec; // request is speculative
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddr; // 1st cycle: 12 bit index is taken for lookup
|
||||
},
|
||||
localparam type icache_drsp_t = struct packed {
|
||||
logic ready; // icache is ready
|
||||
logic valid; // signals a valid read
|
||||
logic [CVA6Cfg.FETCH_WIDTH-1:0] data; // 2+ cycle out: tag
|
||||
logic [CVA6Cfg.FETCH_USER_WIDTH-1:0] user; // User bits
|
||||
logic [riscv::VLEN-1:0] vaddr; // virtual address out
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddr; // virtual address out
|
||||
exception_t ex; // we've encountered an exception
|
||||
},
|
||||
|
||||
// IF/ID Stage
|
||||
// store the decompressed instruction
|
||||
localparam type fetch_entry_t = struct packed {
|
||||
logic [riscv::VLEN-1:0] address; // the address of the instructions from below
|
||||
logic [CVA6Cfg.VLEN-1:0] address; // the address of the instructions from below
|
||||
logic [31:0] instruction; // instruction word
|
||||
branchpredict_sbe_t branch_predict; // this field contains branch prediction information regarding the forward branch path
|
||||
exception_t ex; // this field contains exceptions which might have happened earlier, e.g.: fetch exceptions
|
||||
|
@ -85,7 +85,7 @@ module cva6
|
|||
|
||||
// ID/EX/WB Stage
|
||||
localparam type scoreboard_entry_t = struct packed {
|
||||
logic [riscv::VLEN-1:0] pc; // PC of instruction
|
||||
logic [CVA6Cfg.VLEN-1:0] pc; // PC of instruction
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; // this can potentially be simplified, we could index the scoreboard entry
|
||||
// with the transaction id in any case make the width more generic
|
||||
fu_t fu; // functional unit to use
|
||||
|
@ -116,12 +116,12 @@ module cva6
|
|||
// all the necessary data structures
|
||||
// bp_resolve_t
|
||||
localparam type bp_resolve_t = struct packed {
|
||||
logic valid; // prediction with all its values is valid
|
||||
logic [riscv::VLEN-1:0] pc; // PC of predict or mis-predict
|
||||
logic [riscv::VLEN-1:0] target_address; // target address at which to jump, or not
|
||||
logic is_mispredict; // set if this was a mis-predict
|
||||
logic is_taken; // branch is taken
|
||||
cf_t cf_type; // Type of control flow change
|
||||
logic valid; // prediction with all its values is valid
|
||||
logic [CVA6Cfg.VLEN-1:0] pc; // PC of predict or mis-predict
|
||||
logic [CVA6Cfg.VLEN-1:0] target_address; // target address at which to jump, or not
|
||||
logic is_mispredict; // set if this was a mis-predict
|
||||
logic is_taken; // branch is taken
|
||||
cf_t cf_type; // Type of control flow change
|
||||
},
|
||||
|
||||
// All information needed to determine whether we need to associate an interrupt
|
||||
|
@ -136,7 +136,7 @@ module cva6
|
|||
|
||||
localparam type lsu_ctrl_t = struct packed {
|
||||
logic valid;
|
||||
logic [riscv::VLEN-1:0] vaddr;
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddr;
|
||||
logic overflow;
|
||||
logic [riscv::XLEN-1:0] data;
|
||||
logic [(riscv::XLEN/8)-1:0] be;
|
||||
|
@ -156,7 +156,7 @@ module cva6
|
|||
|
||||
localparam type icache_req_t = struct packed {
|
||||
logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] way; // way to replace
|
||||
logic [riscv::PLEN-1:0] paddr; // physical address
|
||||
logic [CVA6Cfg.PLEN-1:0] paddr; // physical address
|
||||
logic nc; // noncacheable
|
||||
logic [CVA6Cfg.MEM_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
||||
},
|
||||
|
@ -272,7 +272,7 @@ module cva6
|
|||
// Asynchronous reset active low - SUBSYSTEM
|
||||
input logic rst_ni,
|
||||
// Reset boot address - SUBSYSTEM
|
||||
input logic [riscv::VLEN-1:0] boot_addr_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] boot_addr_i,
|
||||
// Hard ID reflected as CSR - SUBSYSTEM
|
||||
input logic [riscv::XLEN-1:0] hart_id_i,
|
||||
// Level sensitive (async) interrupts - SUBSYSTEM
|
||||
|
@ -320,7 +320,7 @@ module cva6
|
|||
riscv::priv_lvl_t priv_lvl;
|
||||
exception_t ex_commit; // exception from commit stage
|
||||
bp_resolve_t resolved_branch;
|
||||
logic [ riscv::VLEN-1:0] pc_commit;
|
||||
logic [ CVA6Cfg.VLEN-1:0] pc_commit;
|
||||
logic eret;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack;
|
||||
|
@ -332,8 +332,8 @@ module cva6
|
|||
// --------------
|
||||
// PCGEN <-> CSR
|
||||
// --------------
|
||||
logic [riscv::VLEN-1:0] trap_vector_base_commit_pcgen;
|
||||
logic [riscv::VLEN-1:0] epc_commit_pcgen;
|
||||
logic [CVA6Cfg.VLEN-1:0] trap_vector_base_commit_pcgen;
|
||||
logic [CVA6Cfg.VLEN-1:0] epc_commit_pcgen;
|
||||
// --------------
|
||||
// IF <-> ID
|
||||
// --------------
|
||||
|
@ -353,11 +353,11 @@ module cva6
|
|||
// --------------
|
||||
// ISSUE <-> EX
|
||||
// --------------
|
||||
logic [riscv::VLEN-1:0] rs1_forwarding_id_ex; // unregistered version of fu_data_o.operanda
|
||||
logic [riscv::VLEN-1:0] rs2_forwarding_id_ex; // unregistered version of fu_data_o.operandb
|
||||
logic [CVA6Cfg.VLEN-1:0] rs1_forwarding_id_ex; // unregistered version of fu_data_o.operanda
|
||||
logic [CVA6Cfg.VLEN-1:0] rs2_forwarding_id_ex; // unregistered version of fu_data_o.operandb
|
||||
|
||||
fu_data_t fu_data_id_ex;
|
||||
logic [riscv::VLEN-1:0] pc_id_ex;
|
||||
logic [CVA6Cfg.VLEN-1:0] pc_id_ex;
|
||||
logic is_compressed_instr_id_ex;
|
||||
// fixed latency units
|
||||
logic flu_ready_ex_id;
|
||||
|
@ -466,7 +466,7 @@ module cva6
|
|||
logic sum_csr_ex;
|
||||
logic mxr_csr_ex;
|
||||
logic [CVA6Cfg.PPNW-1:0] satp_ppn_csr_ex;
|
||||
logic [ASID_WIDTH-1:0] asid_csr_ex;
|
||||
logic [CVA6Cfg.ASID_WIDTH-1:0] asid_csr_ex;
|
||||
logic [11:0] csr_addr_ex_csr;
|
||||
fu_op csr_op_commit_csr;
|
||||
logic [riscv::XLEN-1:0] csr_wdata_commit_csr;
|
||||
|
@ -483,73 +483,73 @@ module cva6
|
|||
logic debug_mode;
|
||||
logic single_step_csr_commit;
|
||||
riscv::pmpcfg_t [15:0] pmpcfg;
|
||||
logic [15:0][riscv::PLEN-3:0] pmpaddr;
|
||||
logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr;
|
||||
logic [31:0] mcountinhibit_csr_perf;
|
||||
// ----------------------------
|
||||
// Performance Counters <-> *
|
||||
// ----------------------------
|
||||
logic [11:0] addr_csr_perf;
|
||||
logic [riscv::XLEN-1:0] data_csr_perf, data_perf_csr;
|
||||
logic we_csr_perf;
|
||||
logic we_csr_perf;
|
||||
|
||||
logic icache_flush_ctrl_cache;
|
||||
logic itlb_miss_ex_perf;
|
||||
logic dtlb_miss_ex_perf;
|
||||
logic dcache_miss_cache_perf;
|
||||
logic icache_miss_cache_perf;
|
||||
logic [ NumPorts-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits;
|
||||
logic stall_issue;
|
||||
logic icache_flush_ctrl_cache;
|
||||
logic itlb_miss_ex_perf;
|
||||
logic dtlb_miss_ex_perf;
|
||||
logic dcache_miss_cache_perf;
|
||||
logic icache_miss_cache_perf;
|
||||
logic [ NumPorts-1:0][CVA6Cfg.DCACHE_SET_ASSOC-1:0] miss_vld_bits;
|
||||
logic stall_issue;
|
||||
// --------------
|
||||
// CTRL <-> *
|
||||
// --------------
|
||||
logic set_pc_ctrl_pcgen;
|
||||
logic flush_csr_ctrl;
|
||||
logic flush_unissued_instr_ctrl_id;
|
||||
logic flush_ctrl_if;
|
||||
logic flush_ctrl_id;
|
||||
logic flush_ctrl_ex;
|
||||
logic flush_ctrl_bp;
|
||||
logic flush_tlb_ctrl_ex;
|
||||
logic fence_i_commit_controller;
|
||||
logic fence_commit_controller;
|
||||
logic sfence_vma_commit_controller;
|
||||
logic halt_ctrl;
|
||||
logic halt_csr_ctrl;
|
||||
logic dcache_flush_ctrl_cache;
|
||||
logic dcache_flush_ack_cache_ctrl;
|
||||
logic set_debug_pc;
|
||||
logic flush_commit;
|
||||
logic flush_acc;
|
||||
logic set_pc_ctrl_pcgen;
|
||||
logic flush_csr_ctrl;
|
||||
logic flush_unissued_instr_ctrl_id;
|
||||
logic flush_ctrl_if;
|
||||
logic flush_ctrl_id;
|
||||
logic flush_ctrl_ex;
|
||||
logic flush_ctrl_bp;
|
||||
logic flush_tlb_ctrl_ex;
|
||||
logic fence_i_commit_controller;
|
||||
logic fence_commit_controller;
|
||||
logic sfence_vma_commit_controller;
|
||||
logic halt_ctrl;
|
||||
logic halt_csr_ctrl;
|
||||
logic dcache_flush_ctrl_cache;
|
||||
logic dcache_flush_ack_cache_ctrl;
|
||||
logic set_debug_pc;
|
||||
logic flush_commit;
|
||||
logic flush_acc;
|
||||
|
||||
icache_areq_t icache_areq_ex_cache;
|
||||
icache_arsp_t icache_areq_cache_ex;
|
||||
icache_dreq_t icache_dreq_if_cache;
|
||||
icache_drsp_t icache_dreq_cache_if;
|
||||
icache_areq_t icache_areq_ex_cache;
|
||||
icache_arsp_t icache_areq_cache_ex;
|
||||
icache_dreq_t icache_dreq_if_cache;
|
||||
icache_drsp_t icache_dreq_cache_if;
|
||||
|
||||
amo_req_t amo_req;
|
||||
amo_resp_t amo_resp;
|
||||
logic sb_full;
|
||||
amo_req_t amo_req;
|
||||
amo_resp_t amo_resp;
|
||||
logic sb_full;
|
||||
|
||||
// ----------------
|
||||
// DCache <-> *
|
||||
// ----------------
|
||||
dcache_req_i_t [ 2:0] dcache_req_ports_ex_cache;
|
||||
dcache_req_o_t [ 2:0] dcache_req_ports_cache_ex;
|
||||
dcache_req_i_t [ 1:0] dcache_req_ports_acc_cache;
|
||||
dcache_req_o_t [ 1:0] dcache_req_ports_cache_acc;
|
||||
logic dcache_commit_wbuffer_empty;
|
||||
logic dcache_commit_wbuffer_not_ni;
|
||||
dcache_req_i_t [ 2:0] dcache_req_ports_ex_cache;
|
||||
dcache_req_o_t [ 2:0] dcache_req_ports_cache_ex;
|
||||
dcache_req_i_t [ 1:0] dcache_req_ports_acc_cache;
|
||||
dcache_req_o_t [ 1:0] dcache_req_ports_cache_acc;
|
||||
logic dcache_commit_wbuffer_empty;
|
||||
logic dcache_commit_wbuffer_not_ni;
|
||||
|
||||
//RVFI
|
||||
lsu_ctrl_t rvfi_lsu_ctrl;
|
||||
logic [riscv::PLEN-1:0] rvfi_mem_paddr;
|
||||
logic rvfi_is_compressed;
|
||||
rvfi_probes_csr_t rvfi_csr;
|
||||
lsu_ctrl_t rvfi_lsu_ctrl;
|
||||
logic [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr;
|
||||
logic rvfi_is_compressed;
|
||||
rvfi_probes_csr_t rvfi_csr;
|
||||
|
||||
// Accelerator port
|
||||
logic [ 63:0] inval_addr;
|
||||
logic inval_valid;
|
||||
logic inval_ready;
|
||||
logic [ 63:0] inval_addr;
|
||||
logic inval_valid;
|
||||
logic inval_ready;
|
||||
|
||||
// --------------
|
||||
// Frontend
|
||||
|
@ -565,7 +565,7 @@ module cva6
|
|||
.flush_bp_i (1'b0),
|
||||
.halt_i (halt_ctrl),
|
||||
.debug_mode_i (debug_mode),
|
||||
.boot_addr_i (boot_addr_i[riscv::VLEN-1:0]),
|
||||
.boot_addr_i (boot_addr_i[CVA6Cfg.VLEN-1:0]),
|
||||
.icache_dreq_i (icache_dreq_cache_if),
|
||||
.icache_dreq_o (icache_dreq_if_cache),
|
||||
.resolved_branch_i (resolved_branch),
|
||||
|
@ -781,8 +781,7 @@ module cva6
|
|||
.icache_arsp_t(icache_arsp_t),
|
||||
.icache_dreq_t(icache_dreq_t),
|
||||
.icache_drsp_t(icache_drsp_t),
|
||||
.lsu_ctrl_t(lsu_ctrl_t),
|
||||
.ASID_WIDTH(ASID_WIDTH)
|
||||
.lsu_ctrl_t(lsu_ctrl_t)
|
||||
) ex_stage_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -942,14 +941,13 @@ module cva6
|
|||
.irq_ctrl_t (irq_ctrl_t),
|
||||
.scoreboard_entry_t(scoreboard_entry_t),
|
||||
.rvfi_probes_csr_t (rvfi_probes_csr_t),
|
||||
.AsidWidth (ASID_WIDTH),
|
||||
.MHPMCounterNum (MHPMCounterNum)
|
||||
) csr_regfile_i (
|
||||
.flush_o (flush_csr_ctrl),
|
||||
.halt_csr_o (halt_csr_ctrl),
|
||||
.commit_instr_i (commit_instr_id_commit),
|
||||
.commit_ack_i (commit_macro_ack),
|
||||
.boot_addr_i (boot_addr_i[riscv::VLEN-1:0]),
|
||||
.boot_addr_i (boot_addr_i[CVA6Cfg.VLEN-1:0]),
|
||||
.hart_id_i (hart_id_i[riscv::XLEN-1:0]),
|
||||
.ex_i (ex_commit),
|
||||
.csr_op_i (csr_op_commit_csr),
|
||||
|
@ -1385,9 +1383,9 @@ module cva6
|
|||
`ifdef PITON_ARIANE
|
||||
localparam PC_QUEUE_DEPTH = 16;
|
||||
|
||||
logic piton_pc_vld;
|
||||
logic [ riscv::VLEN-1:0] piton_pc;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][riscv::VLEN-1:0] pc_data;
|
||||
logic piton_pc_vld;
|
||||
logic [ CVA6Cfg.VLEN-1:0] piton_pc;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.VLEN-1:0] pc_data;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0] pc_pop, pc_empty;
|
||||
|
||||
for (genvar i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin : gen_pc_fifo
|
||||
|
|
|
@ -35,8 +35,8 @@ module cva6_rvfi
|
|||
// CVA6 configuration
|
||||
// ------------------------------------------
|
||||
// Extended config
|
||||
localparam bit RVF = (riscv::IS_XLEN64 | riscv::IS_XLEN32) & CVA6Cfg.FpuEn;
|
||||
localparam bit RVD = (riscv::IS_XLEN64 ? 1 : 0) & CVA6Cfg.FpuEn;
|
||||
localparam bit RVF = (CVA6Cfg.IS_XLEN64 | CVA6Cfg.IS_XLEN32) & CVA6Cfg.FpuEn;
|
||||
localparam bit RVD = (CVA6Cfg.IS_XLEN64 ? 1 : 0) & CVA6Cfg.FpuEn;
|
||||
localparam bit FpPresent = RVF | RVD | CVA6Cfg.XF16 | CVA6Cfg.XF16ALT | CVA6Cfg.XF8;
|
||||
|
||||
localparam logic [riscv::XLEN-1:0] IsaCode = (riscv::XLEN'(CVA6Cfg.RVA) << 0) // A - Atomic Instructions extension
|
||||
|
@ -73,31 +73,31 @@ module cva6_rvfi
|
|||
logic [riscv::XLEN-1:0] rs1_forwarding;
|
||||
logic [riscv::XLEN-1:0] rs2_forwarding;
|
||||
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][riscv::VLEN-1:0] commit_instr_pc;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.VLEN-1:0] commit_instr_pc;
|
||||
fu_op [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] commit_instr_op;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rs1;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rs2;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rd;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] commit_instr_result;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][riscv::VLEN-1:0] commit_instr_valid;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.VLEN-1:0] commit_instr_valid;
|
||||
|
||||
logic [riscv::XLEN-1:0] ex_commit_cause;
|
||||
logic ex_commit_valid;
|
||||
|
||||
riscv::priv_lvl_t priv_lvl;
|
||||
|
||||
logic [riscv::VLEN-1:0] lsu_ctrl_vaddr;
|
||||
logic [CVA6Cfg.VLEN-1:0] lsu_ctrl_vaddr;
|
||||
fu_t lsu_ctrl_fu;
|
||||
logic [(riscv::XLEN/8)-1:0] lsu_ctrl_be;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] lsu_ctrl_trans_id;
|
||||
|
||||
logic [((CVA6Cfg.CvxifEn || CVA6Cfg.RVV) ? 5 : 4)-1:0][riscv::XLEN-1:0] wbdata;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack;
|
||||
logic [riscv::PLEN-1:0] mem_paddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] mem_paddr;
|
||||
logic debug_mode;
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata;
|
||||
|
||||
logic [riscv::VLEN-1:0] lsu_addr;
|
||||
logic [CVA6Cfg.VLEN-1:0] lsu_addr;
|
||||
logic [(riscv::XLEN/8)-1:0] lsu_rmask;
|
||||
logic [(riscv::XLEN/8)-1:0] lsu_wmask;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] lsu_addr_trans_id;
|
||||
|
@ -198,7 +198,7 @@ module cva6_rvfi
|
|||
typedef struct packed {
|
||||
logic [riscv::XLEN-1:0] rs1_rdata;
|
||||
logic [riscv::XLEN-1:0] rs2_rdata;
|
||||
logic [riscv::VLEN-1:0] lsu_addr;
|
||||
logic [CVA6Cfg.VLEN-1:0] lsu_addr;
|
||||
logic [(riscv::XLEN/8)-1:0] lsu_rmask;
|
||||
logic [(riscv::XLEN/8)-1:0] lsu_wmask;
|
||||
logic [riscv::XLEN-1:0] lsu_wdata;
|
||||
|
@ -464,22 +464,22 @@ module cva6_rvfi
|
|||
rdata:
|
||||
csr.pmpcfg_q[i].addr_mode[1]
|
||||
== 1'b1 ?
|
||||
{'0, csr.pmpaddr_q[i][riscv::PLEN-3:0]}
|
||||
{'0, csr.pmpaddr_q[i][CVA6Cfg.PLEN-3:0]}
|
||||
: {
|
||||
'0
|
||||
,
|
||||
csr.pmpaddr_q[i][riscv::PLEN-3:1]
|
||||
csr.pmpaddr_q[i][CVA6Cfg.PLEN-3:1]
|
||||
,
|
||||
1'b0
|
||||
},
|
||||
wdata:
|
||||
csr.pmpcfg_q[i].addr_mode[1]
|
||||
== 1'b1 ?
|
||||
{'0, csr.pmpaddr_q[i][riscv::PLEN-3:0]}
|
||||
{'0, csr.pmpaddr_q[i][CVA6Cfg.PLEN-3:0]}
|
||||
: {
|
||||
'0
|
||||
,
|
||||
csr.pmpaddr_q[i][riscv::PLEN-3:1]
|
||||
csr.pmpaddr_q[i][CVA6Cfg.PLEN-3:1]
|
||||
,
|
||||
1'b0
|
||||
},
|
||||
|
|
|
@ -45,7 +45,7 @@ module cva6_rvfi_probes
|
|||
input lsu_ctrl_t lsu_ctrl_i,
|
||||
input logic [ CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_i,
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i,
|
||||
input logic [ riscv::PLEN-1:0] mem_paddr_i,
|
||||
input logic [ CVA6Cfg.PLEN-1:0] mem_paddr_i,
|
||||
input logic debug_mode_i,
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata_i,
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ module decoder
|
|||
// Debug (async) request - SUBSYSTEM
|
||||
input logic debug_req_i,
|
||||
// PC from fetch stage - FRONTEND
|
||||
input logic [riscv::VLEN-1:0] pc_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] pc_i,
|
||||
// Is a compressed instruction - compressed_decoder
|
||||
input logic is_compressed_i,
|
||||
// Compressed form of instruction - FRONTEND
|
||||
|
@ -683,7 +683,7 @@ module decoder
|
|||
instruction_o.rs1[4:0] = instr.rtype.rs1;
|
||||
instruction_o.rs2[4:0] = instr.rtype.rs2;
|
||||
instruction_o.rd[4:0] = instr.rtype.rd;
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
unique case ({
|
||||
instr.rtype.funct7, instr.rtype.funct3
|
||||
})
|
||||
|
@ -769,7 +769,7 @@ module decoder
|
|||
end
|
||||
3'b101: begin
|
||||
if (instr.instr[31:20] == 12'b001010000111) instruction_o.op = ariane_pkg::ORCB;
|
||||
else if (riscv::IS_XLEN64 && instr.instr[31:20] == 12'b011010111000)
|
||||
else if (CVA6Cfg.IS_XLEN64 && instr.instr[31:20] == 12'b011010111000)
|
||||
instruction_o.op = ariane_pkg::REV8;
|
||||
else if (instr.instr[31:20] == 12'b011010011000)
|
||||
instruction_o.op = ariane_pkg::REV8;
|
||||
|
@ -793,7 +793,7 @@ module decoder
|
|||
imm_select = IIMM;
|
||||
instruction_o.rs1[4:0] = instr.itype.rs1;
|
||||
instruction_o.rd[4:0] = instr.itype.rd;
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
unique case (instr.itype.funct3)
|
||||
3'b000: instruction_o.op = ariane_pkg::ADDW; // Add Immediate
|
||||
3'b001: begin
|
||||
|
@ -1165,7 +1165,7 @@ module decoder
|
|||
default: illegal_instr = 1'b1;
|
||||
endcase
|
||||
// double words
|
||||
end else if (riscv::IS_XLEN64 && CVA6Cfg.RVA && instr.stype.funct3 == 3'h3) begin
|
||||
end else if (CVA6Cfg.IS_XLEN64 && CVA6Cfg.RVA && instr.stype.funct3 == 3'h3) begin
|
||||
unique case (instr.instr[31:27])
|
||||
5'h0: instruction_o.op = ariane_pkg::AMO_ADDD;
|
||||
5'h1: instruction_o.op = ariane_pkg::AMO_SWAPD;
|
||||
|
|
|
@ -28,8 +28,7 @@ module ex_stage
|
|||
parameter type icache_arsp_t = logic,
|
||||
parameter type icache_dreq_t = logic,
|
||||
parameter type icache_drsp_t = logic,
|
||||
parameter type lsu_ctrl_t = logic,
|
||||
parameter int unsigned ASID_WIDTH = 1
|
||||
parameter type lsu_ctrl_t = logic
|
||||
) (
|
||||
// Subsystem Clock - SUBSYSTEM
|
||||
input logic clk_i,
|
||||
|
@ -40,13 +39,13 @@ module ex_stage
|
|||
// Debug mode is enabled - CSR_REGFILE
|
||||
input logic debug_mode_i,
|
||||
// rs1 forwarding - ISSUE_STAGE
|
||||
input logic [riscv::VLEN-1:0] rs1_forwarding_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] rs1_forwarding_i,
|
||||
// rs2 forwarding - ISSUE_STAGE
|
||||
input logic [riscv::VLEN-1:0] rs2_forwarding_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] rs2_forwarding_i,
|
||||
// FU data useful to execute instruction - ISSUE_STAGE
|
||||
input fu_data_t fu_data_i,
|
||||
// PC of the current instruction - ISSUE_STAGE
|
||||
input logic [riscv::VLEN-1:0] pc_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] pc_i,
|
||||
// Report whether isntruction is compressed - ISSUE_STAGE
|
||||
input logic is_compressed_instr_i,
|
||||
// Fixed Latency Unit result - ISSUE_STAGE
|
||||
|
@ -168,7 +167,7 @@ module ex_stage
|
|||
// TO_BE_COMPLETED - CSR_REGFILE
|
||||
input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i,
|
||||
// TO_BE_COMPLETED - CSR_REGFILE
|
||||
input logic [ASID_WIDTH-1:0] asid_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_i,
|
||||
// icache translation response - CACHE
|
||||
input icache_arsp_t icache_areq_i,
|
||||
// icache translation request - CACHE
|
||||
|
@ -192,11 +191,11 @@ module ex_stage
|
|||
// Report the PMP configuration - CSR_REGFILE
|
||||
input riscv::pmpcfg_t [15:0] pmpcfg_i,
|
||||
// Report the PMP addresses - CSR_REGFILE
|
||||
input logic [15:0][riscv::PLEN-3:0] pmpaddr_i,
|
||||
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
// Information dedicated to RVFI - RVFI
|
||||
output lsu_ctrl_t rvfi_lsu_ctrl_o,
|
||||
// Information dedicated to RVFI - RVFI
|
||||
output [riscv::PLEN-1:0] rvfi_mem_paddr_o
|
||||
output [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr_o
|
||||
);
|
||||
|
||||
// -------------------------
|
||||
|
@ -223,13 +222,13 @@ module ex_stage
|
|||
logic current_instruction_is_sfence_vma;
|
||||
// These two register store the rs1 and rs2 parameters in case of `SFENCE_VMA`
|
||||
// instruction to be used for TLB flush in the next clock cycle.
|
||||
logic [ASID_WIDTH-1:0] asid_to_be_flushed;
|
||||
logic [riscv::VLEN-1:0] vaddr_to_be_flushed;
|
||||
logic [CVA6Cfg.ASID_WIDTH-1:0] asid_to_be_flushed;
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddr_to_be_flushed;
|
||||
|
||||
// from ALU to branch unit
|
||||
logic alu_branch_res; // branch comparison result
|
||||
logic [riscv::XLEN-1:0] alu_result, csr_result, mult_result;
|
||||
logic [riscv::VLEN-1:0] branch_result;
|
||||
logic [CVA6Cfg.VLEN-1:0] branch_result;
|
||||
logic csr_ready, mult_ready;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] mult_trans_id;
|
||||
logic mult_valid;
|
||||
|
@ -298,7 +297,7 @@ module ex_stage
|
|||
// result MUX
|
||||
always_comb begin
|
||||
// Branch result as default case
|
||||
flu_result_o = {{riscv::XLEN - riscv::VLEN{1'b0}}, branch_result};
|
||||
flu_result_o = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, branch_result};
|
||||
flu_trans_id_o = fu_data_i.trans_id;
|
||||
// ALU result
|
||||
if (alu_valid_i) begin
|
||||
|
@ -391,8 +390,7 @@ module ex_stage
|
|||
.icache_arsp_t(icache_arsp_t),
|
||||
.icache_dreq_t(icache_dreq_t),
|
||||
.icache_drsp_t(icache_drsp_t),
|
||||
.lsu_ctrl_t(lsu_ctrl_t),
|
||||
.ASID_WIDTH(ASID_WIDTH)
|
||||
.lsu_ctrl_t(lsu_ctrl_t)
|
||||
) lsu_i (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
|
@ -493,7 +491,7 @@ module ex_stage
|
|||
// if the current instruction in EX_STAGE is a sfence.vma, in the next cycle no writes will happen
|
||||
end else if ((~current_instruction_is_sfence_vma) && (~((fu_data_i.operation == SFENCE_VMA) && csr_valid_i))) begin
|
||||
vaddr_to_be_flushed <= rs1_forwarding_i;
|
||||
asid_to_be_flushed <= rs2_forwarding_i[ASID_WIDTH-1:0];
|
||||
asid_to_be_flushed <= rs2_forwarding_i[CVA6Cfg.ASID_WIDTH-1:0];
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
|
|
|
@ -32,7 +32,7 @@ module bht #(
|
|||
// Debug mode state - CSR
|
||||
input logic debug_mode_i,
|
||||
// Virtual PC - CACHE
|
||||
input logic [riscv::VLEN-1:0] vpc_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] vpc_i,
|
||||
// Update bht with resolved address - EXECUTE
|
||||
input bht_update_t bht_update_i,
|
||||
// Prediction from bht - FRONTEND
|
||||
|
|
|
@ -40,7 +40,7 @@ module btb #(
|
|||
// Debug mode state - CSR
|
||||
input logic debug_mode_i,
|
||||
// Virtual PC - CACHE
|
||||
input logic [riscv::VLEN-1:0] vpc_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] vpc_i,
|
||||
// Update BTB with resolved address - EXECUTE
|
||||
input btb_update_t btb_update_i,
|
||||
// BTB Prediction - FRONTEND
|
||||
|
|
|
@ -29,7 +29,7 @@ module frontend
|
|||
// Asynchronous reset active low - SUBSYSTEM
|
||||
input logic rst_ni,
|
||||
// Next PC when reset - SUBSYSTEM
|
||||
input logic [riscv::VLEN-1:0] boot_addr_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] boot_addr_i,
|
||||
// Flush branch prediction - zero
|
||||
input logic flush_bp_i,
|
||||
// Flush requested by FENCE, mis-predict and exception - CONTROLLER
|
||||
|
@ -39,7 +39,7 @@ module frontend
|
|||
// Set COMMIT PC as next PC requested by FENCE, CSR side-effect and Accelerate port - CONTROLLER
|
||||
input logic set_pc_commit_i,
|
||||
// COMMIT PC - COMMIT
|
||||
input logic [riscv::VLEN-1:0] pc_commit_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] pc_commit_i,
|
||||
// Exception event - COMMIT
|
||||
input logic ex_valid_i,
|
||||
// Mispredict event and next PC - EXECUTE
|
||||
|
@ -47,9 +47,9 @@ module frontend
|
|||
// Return from exception event - CSR
|
||||
input logic eret_i,
|
||||
// Next PC when returning from exception - CSR
|
||||
input logic [riscv::VLEN-1:0] epc_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] epc_i,
|
||||
// Next PC when jumping into exception - CSR
|
||||
input logic [riscv::VLEN-1:0] trap_vector_base_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] trap_vector_base_i,
|
||||
// Debug event - CSR
|
||||
input logic set_debug_pc_i,
|
||||
// Debug mode state - CSR
|
||||
|
@ -67,32 +67,32 @@ module frontend
|
|||
);
|
||||
|
||||
localparam type bht_update_t = struct packed {
|
||||
logic valid;
|
||||
logic [riscv::VLEN-1:0] pc; // update at PC
|
||||
logic taken;
|
||||
logic valid;
|
||||
logic [CVA6Cfg.VLEN-1:0] pc; // update at PC
|
||||
logic taken;
|
||||
};
|
||||
|
||||
localparam type btb_prediction_t = struct packed {
|
||||
logic valid;
|
||||
logic [riscv::VLEN-1:0] target_address;
|
||||
logic valid;
|
||||
logic [CVA6Cfg.VLEN-1:0] target_address;
|
||||
};
|
||||
|
||||
localparam type btb_update_t = struct packed {
|
||||
logic valid;
|
||||
logic [riscv::VLEN-1:0] pc; // update at PC
|
||||
logic [riscv::VLEN-1:0] target_address;
|
||||
logic valid;
|
||||
logic [CVA6Cfg.VLEN-1:0] pc; // update at PC
|
||||
logic [CVA6Cfg.VLEN-1:0] target_address;
|
||||
};
|
||||
|
||||
localparam type ras_t = struct packed {
|
||||
logic valid;
|
||||
logic [riscv::VLEN-1:0] ra;
|
||||
logic valid;
|
||||
logic [CVA6Cfg.VLEN-1:0] ra;
|
||||
};
|
||||
|
||||
// Instruction Cache Registers, from I$
|
||||
logic [ CVA6Cfg.FETCH_WIDTH-1:0] icache_data_q;
|
||||
logic icache_valid_q;
|
||||
ariane_pkg::frontend_exception_t icache_ex_valid_q;
|
||||
logic [ riscv::VLEN-1:0] icache_vaddr_q;
|
||||
logic [ CVA6Cfg.VLEN-1:0] icache_vaddr_q;
|
||||
logic instr_queue_ready;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0] instr_queue_consumed;
|
||||
// upper-most branch-prediction from last cycle
|
||||
|
@ -100,13 +100,13 @@ module frontend
|
|||
bht_prediction_t bht_q;
|
||||
// instruction fetch is ready
|
||||
logic if_ready;
|
||||
logic [riscv::VLEN-1:0] npc_d, npc_q; // next PC
|
||||
logic [CVA6Cfg.VLEN-1:0] npc_d, npc_q; // next PC
|
||||
|
||||
// indicates whether we come out of reset (then we need to load boot_addr_i)
|
||||
logic npc_rst_load_q;
|
||||
|
||||
logic replay;
|
||||
logic [ riscv::VLEN-1:0] replay_addr;
|
||||
logic [ CVA6Cfg.VLEN-1:0] replay_addr;
|
||||
|
||||
// shift amount
|
||||
logic [$clog2(CVA6Cfg.INSTR_PER_FETCH)-1:0] shamt;
|
||||
|
@ -122,29 +122,29 @@ module frontend
|
|||
// -----------------------
|
||||
// RVI ctrl flow prediction
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0] rvi_return, rvi_call, rvi_branch, rvi_jalr, rvi_jump;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] rvi_imm;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] rvi_imm;
|
||||
// RVC branching
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0] rvc_branch, rvc_jump, rvc_jr, rvc_return, rvc_jalr, rvc_call;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] rvc_imm;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] rvc_imm;
|
||||
// re-aligned instruction and address (coming from cache - combinationally)
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][ 31:0] instr;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0] instruction_valid;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][ 31:0] instr;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] addr;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0] instruction_valid;
|
||||
// BHT, BTB and RAS prediction
|
||||
bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction;
|
||||
btb_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] btb_prediction;
|
||||
bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction_shifted;
|
||||
btb_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] btb_prediction_shifted;
|
||||
ras_t ras_predict;
|
||||
logic [ riscv::VLEN-1:0] vpc_btb;
|
||||
bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction;
|
||||
btb_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] btb_prediction;
|
||||
bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction_shifted;
|
||||
btb_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] btb_prediction_shifted;
|
||||
ras_t ras_predict;
|
||||
logic [ CVA6Cfg.VLEN-1:0] vpc_btb;
|
||||
|
||||
// branch-predict update
|
||||
logic is_mispredict;
|
||||
logic is_mispredict;
|
||||
logic ras_push, ras_pop;
|
||||
logic [ riscv::VLEN-1:0] ras_update;
|
||||
logic [ CVA6Cfg.VLEN-1:0] ras_update;
|
||||
|
||||
// Instruction FIFO
|
||||
logic [ riscv::VLEN-1:0] predict_address;
|
||||
logic [ CVA6Cfg.VLEN-1:0] predict_address;
|
||||
cf_t [CVA6Cfg.INSTR_PER_FETCH-1:0] cf_type;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0] taken_rvi_cf;
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0] taken_rvc_cf;
|
||||
|
@ -269,8 +269,8 @@ module frontend
|
|||
// otherwise default to static prediction
|
||||
end else begin
|
||||
// set if immediate is negative - static prediction
|
||||
taken_rvi_cf[i] = rvi_branch[i] & rvi_imm[i][riscv::VLEN-1];
|
||||
taken_rvc_cf[i] = rvc_branch[i] & rvc_imm[i][riscv::VLEN-1];
|
||||
taken_rvi_cf[i] = rvi_branch[i] & rvi_imm[i][CVA6Cfg.VLEN-1];
|
||||
taken_rvc_cf[i] = rvc_branch[i] & rvc_imm[i][CVA6Cfg.VLEN-1];
|
||||
end
|
||||
if (taken_rvi_cf[i] || taken_rvc_cf[i]) begin
|
||||
cf_type[i] = ariane_pkg::Branch;
|
||||
|
@ -347,7 +347,7 @@ module frontend
|
|||
// Mis-predict handling is a little bit different
|
||||
// select PC a.k.a PC Gen
|
||||
always_comb begin : npc_select
|
||||
automatic logic [riscv::VLEN-1:0] fetch_address;
|
||||
automatic logic [CVA6Cfg.VLEN-1:0] fetch_address;
|
||||
// check whether we come out of reset
|
||||
// this is a workaround. some tools have issues
|
||||
// having boot_addr_i in the asynchronous
|
||||
|
@ -369,7 +369,7 @@ module frontend
|
|||
end
|
||||
// 1. Default assignment
|
||||
if (if_ready) begin
|
||||
npc_d = {fetch_address[riscv::VLEN-1:2], 2'b0} + 'h4;
|
||||
npc_d = {fetch_address[CVA6Cfg.VLEN-1:2], 2'b0} + 'h4;
|
||||
end
|
||||
// 2. Replay instruction fetch
|
||||
if (replay) begin
|
||||
|
@ -397,12 +397,12 @@ module frontend
|
|||
// instruction in the commit stage
|
||||
// TODO(zarubaf) This adder can at least be merged with the one in the csr_regfile stage
|
||||
if (set_pc_commit_i) begin
|
||||
npc_d = pc_commit_i + (halt_i ? '0 : {{riscv::VLEN - 3{1'b0}}, 3'b100});
|
||||
npc_d = pc_commit_i + (halt_i ? '0 : {{CVA6Cfg.VLEN - 3{1'b0}}, 3'b100});
|
||||
end
|
||||
// 7. Debug
|
||||
// enter debug on a hard-coded base-address
|
||||
if (CVA6Cfg.DebugEn && set_debug_pc_i)
|
||||
npc_d = CVA6Cfg.DmBaseAddress[riscv::VLEN-1:0] + CVA6Cfg.HaltAddress[riscv::VLEN-1:0];
|
||||
npc_d = CVA6Cfg.DmBaseAddress[CVA6Cfg.VLEN-1:0] + CVA6Cfg.HaltAddress[CVA6Cfg.VLEN-1:0];
|
||||
icache_dreq_o.vaddr = fetch_address;
|
||||
end
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ module instr_queue
|
|||
// Instruction - instr_realign
|
||||
input logic [CVA6Cfg.INSTR_PER_FETCH-1:0][31:0] instr_i,
|
||||
// Instruction address - instr_realign
|
||||
input logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_i,
|
||||
input logic [CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] addr_i,
|
||||
// Instruction is valid - instr_realign
|
||||
input logic [CVA6Cfg.INSTR_PER_FETCH-1:0] valid_i,
|
||||
// Handshake’s ready with CACHE - CACHE
|
||||
|
@ -68,15 +68,15 @@ module instr_queue
|
|||
// Exception (which is page-table fault) - CACHE
|
||||
input ariane_pkg::frontend_exception_t exception_i,
|
||||
// Exception address - CACHE
|
||||
input logic [riscv::VLEN-1:0] exception_addr_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] exception_addr_i,
|
||||
// Branch predict - FRONTEND
|
||||
input logic [riscv::VLEN-1:0] predict_address_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] predict_address_i,
|
||||
// Instruction predict address - FRONTEND
|
||||
input ariane_pkg::cf_t [CVA6Cfg.INSTR_PER_FETCH-1:0] cf_type_i,
|
||||
// Replay instruction because one of the FIFO was full - FRONTEND
|
||||
output logic replay_o,
|
||||
// Address at which to replay the fetch - FRONTEND
|
||||
output logic [riscv::VLEN-1:0] replay_addr_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] replay_addr_o,
|
||||
// Handshake’s data with ID_STAGE - ID_STAGE
|
||||
output fetch_entry_t fetch_entry_o,
|
||||
// Handshake’s valid with ID_STAGE - ID_STAGE
|
||||
|
@ -89,7 +89,7 @@ module instr_queue
|
|||
logic [31:0] instr; // instruction word
|
||||
ariane_pkg::cf_t cf; // branch was taken
|
||||
ariane_pkg::frontend_exception_t ex; // exception happened
|
||||
logic [riscv::VLEN-1:0] ex_vaddr; // lower VLEN bits of tval for exception
|
||||
logic [CVA6Cfg.VLEN-1:0] ex_vaddr; // lower CVA6Cfg.VLEN bits of tval for exception
|
||||
} instr_data_t;
|
||||
|
||||
logic [CVA6Cfg.LOG2_INSTR_PER_FETCH-1:0] branch_index;
|
||||
|
@ -105,7 +105,7 @@ ariane_pkg::FETCH_FIFO_DEPTH
|
|||
logic instr_overflow;
|
||||
// address queue
|
||||
logic [$clog2(ariane_pkg::FETCH_FIFO_DEPTH)-1:0] address_queue_usage;
|
||||
logic [ riscv::VLEN-1:0] address_out;
|
||||
logic [ CVA6Cfg.VLEN-1:0] address_out;
|
||||
logic pop_address;
|
||||
logic push_address;
|
||||
logic full_address;
|
||||
|
@ -116,7 +116,7 @@ ariane_pkg::FETCH_FIFO_DEPTH
|
|||
// Registers
|
||||
// output FIFO select, one-hot
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0] idx_ds_d, idx_ds_q;
|
||||
logic [riscv::VLEN-1:0] pc_d, pc_q; // current PC
|
||||
logic [CVA6Cfg.VLEN-1:0] pc_d, pc_q; // current PC
|
||||
logic reset_address_d, reset_address_q; // we need to re-set the address because of a flush
|
||||
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH*2-2:0] branch_mask_extended;
|
||||
|
@ -298,7 +298,7 @@ ariane_pkg::FETCH_FIFO_DEPTH
|
|||
fetch_entry_o.ex.valid = instr_data_out[i].ex != ariane_pkg::FE_NONE;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
fetch_entry_o.ex.tval = {
|
||||
{(riscv::XLEN - riscv::VLEN) {1'b0}}, instr_data_out[i].ex_vaddr
|
||||
{(riscv::XLEN - CVA6Cfg.VLEN) {1'b0}}, instr_data_out[i].ex_vaddr
|
||||
};
|
||||
fetch_entry_o.branch_predict.cf = instr_data_out[i].cf;
|
||||
pop_instr[i] = fetch_entry_valid_o & fetch_entry_ready_i;
|
||||
|
@ -323,7 +323,7 @@ ariane_pkg::FETCH_FIFO_DEPTH
|
|||
fetch_entry_o.ex.cause = riscv::INSTR_PAGE_FAULT;
|
||||
end
|
||||
if (CVA6Cfg.TvalEn)
|
||||
fetch_entry_o.ex.tval = {{64 - riscv::VLEN{1'b0}}, instr_data_out[0].ex_vaddr};
|
||||
fetch_entry_o.ex.tval = {{64 - CVA6Cfg.VLEN{1'b0}}, instr_data_out[0].ex_vaddr};
|
||||
else fetch_entry_o.ex.tval = '0;
|
||||
fetch_entry_o.branch_predict.predict_address = address_out;
|
||||
fetch_entry_o.branch_predict.cf = instr_data_out[0].cf;
|
||||
|
@ -397,7 +397,7 @@ ariane_pkg::FETCH_FIFO_DEPTH
|
|||
|
||||
fifo_v3 #(
|
||||
.DEPTH (ariane_pkg::FETCH_FIFO_DEPTH), // TODO(zarubaf): Fork out to separate param
|
||||
.DATA_WIDTH(riscv::VLEN),
|
||||
.DATA_WIDTH(CVA6Cfg.VLEN),
|
||||
.FPGA_EN (CVA6Cfg.FPGA_EN)
|
||||
) i_fifo_address (
|
||||
.clk_i (clk_i),
|
||||
|
|
|
@ -31,7 +31,7 @@ module instr_scan #(
|
|||
// Unconditional jump instruction - FRONTEND
|
||||
output logic rvi_jump_o,
|
||||
// Instruction immediat - FRONTEND
|
||||
output logic [riscv::VLEN-1:0] rvi_imm_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] rvi_imm_o,
|
||||
// Branch compressed instruction - FRONTEND
|
||||
output logic rvc_branch_o,
|
||||
// Unconditional jump compressed instruction - FRONTEND
|
||||
|
@ -45,12 +45,12 @@ module instr_scan #(
|
|||
// JAL compressed instruction - FRONTEND
|
||||
output logic rvc_call_o,
|
||||
// Instruction compressed immediat - FRONTEND
|
||||
output logic [riscv::VLEN-1:0] rvc_imm_o
|
||||
output logic [CVA6Cfg.VLEN-1:0] rvc_imm_o
|
||||
);
|
||||
|
||||
function automatic logic [riscv::VLEN-1:0] uj_imm(logic [31:0] instruction_i);
|
||||
function automatic logic [CVA6Cfg.VLEN-1:0] uj_imm(logic [31:0] instruction_i);
|
||||
return {
|
||||
{44 + riscv::VLEN - 64{instruction_i[31]}},
|
||||
{44 + CVA6Cfg.VLEN - 64{instruction_i[31]}},
|
||||
instruction_i[19:12],
|
||||
instruction_i[20],
|
||||
instruction_i[30:21],
|
||||
|
@ -58,9 +58,9 @@ module instr_scan #(
|
|||
};
|
||||
endfunction
|
||||
|
||||
function automatic logic [riscv::VLEN-1:0] sb_imm(logic [31:0] instruction_i);
|
||||
function automatic logic [CVA6Cfg.VLEN-1:0] sb_imm(logic [31:0] instruction_i);
|
||||
return {
|
||||
{51 + riscv::VLEN - 64{instruction_i[31]}},
|
||||
{51 + CVA6Cfg.VLEN - 64{instruction_i[31]}},
|
||||
instruction_i[31],
|
||||
instruction_i[7],
|
||||
instruction_i[30:25],
|
||||
|
@ -110,6 +110,6 @@ module instr_scan #(
|
|||
assign rvc_return_o = ((instr_i[11:7] == 5'd1) | (instr_i[11:7] == 5'd5)) & rvc_jr_o;
|
||||
|
||||
// differentiates between JAL and BRANCH opcode, JALR comes from BHT
|
||||
assign rvc_imm_o = (instr_i[14]) ? {{56+riscv::VLEN-64{instr_i[12]}}, instr_i[6:5], instr_i[2], instr_i[11:10], instr_i[4:3], 1'b0}
|
||||
: {{53+riscv::VLEN-64{instr_i[12]}}, instr_i[8], instr_i[10:9], instr_i[6], instr_i[7], instr_i[2], instr_i[11], instr_i[5:3], 1'b0};
|
||||
assign rvc_imm_o = (instr_i[14]) ? {{56+CVA6Cfg.VLEN-64{instr_i[12]}}, instr_i[6:5], instr_i[2], instr_i[11:10], instr_i[4:3], 1'b0}
|
||||
: {{53+CVA6Cfg.VLEN-64{instr_i[12]}}, instr_i[8], instr_i[10:9], instr_i[6], instr_i[7], instr_i[2], instr_i[11], instr_i[5:3], 1'b0};
|
||||
endmodule
|
||||
|
|
|
@ -30,7 +30,7 @@ module ras #(
|
|||
// Pop address from RAS - FRONTEND
|
||||
input logic pop_i,
|
||||
// Data to be pushed - FRONTEND
|
||||
input logic [riscv::VLEN-1:0] data_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] data_i,
|
||||
// Popped data - FRONTEND
|
||||
output ras_t data_o
|
||||
);
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
package ariane_pkg;
|
||||
|
||||
// TODO: Slowly move those parameters to the new system.
|
||||
localparam ASID_WIDTH = (riscv::XLEN == 64) ? 16 : 1;
|
||||
localparam BITS_SATURATION_COUNTER = 2;
|
||||
|
||||
localparam ISSUE_WIDTH = 1;
|
||||
|
@ -127,7 +126,7 @@ package ariane_pkg;
|
|||
| riscv::SSTATUS_UPIE
|
||||
| riscv::SSTATUS_SPIE
|
||||
| riscv::SSTATUS_UXL
|
||||
| riscv::sstatus_sd(riscv::IS_XLEN64);
|
||||
| riscv::sstatus_sd(Cfg.IS_XLEN64);
|
||||
endfunction
|
||||
|
||||
localparam logic [63:0] SMODE_STATUS_WRITE_MASK = riscv::SSTATUS_SIE
|
||||
|
@ -140,9 +139,6 @@ package ariane_pkg;
|
|||
// AXI
|
||||
// ---------------
|
||||
|
||||
localparam AXI_USER_EN = cva6_config_pkg::CVA6ConfigDataUserEn | cva6_config_pkg::CVA6ConfigFetchUserEn;
|
||||
localparam AXI_USER_WIDTH = cva6_config_pkg::CVA6ConfigDataUserWidth;
|
||||
|
||||
typedef enum logic {
|
||||
SINGLE_REQ,
|
||||
CACHE_LINE_REQ
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package build_config_pkg;
|
||||
|
||||
function automatic config_pkg::cva6_cfg_t build_config(config_pkg::cva6_user_cfg_t CVA6Cfg);
|
||||
bit RVF = (riscv::IS_XLEN64 | riscv::IS_XLEN32) & CVA6Cfg.FpuEn;
|
||||
bit RVD = (riscv::IS_XLEN64 ? 1 : 0) & CVA6Cfg.FpuEn;
|
||||
bit IS_XLEN32 = (riscv::XLEN == 32) ? 1'b1 : 1'b0;
|
||||
bit IS_XLEN64 = (riscv::XLEN == 32) ? 1'b0 : 1'b1;
|
||||
bit RVF = (IS_XLEN64 | IS_XLEN32) & CVA6Cfg.FpuEn;
|
||||
bit RVD = (IS_XLEN64 ? 1 : 0) & CVA6Cfg.FpuEn;
|
||||
bit FpPresent = RVF | RVD | CVA6Cfg.XF16 | CVA6Cfg.XF16ALT | CVA6Cfg.XF8;
|
||||
bit NSX = CVA6Cfg.XF16 | CVA6Cfg.XF16ALT | CVA6Cfg.XF8 | CVA6Cfg.XFVec; // Are non-standard extensions present?
|
||||
int unsigned FLen = RVD ? 64 : // D ext.
|
||||
|
@ -27,7 +29,12 @@ package build_config_pkg;
|
|||
|
||||
config_pkg::cva6_cfg_t cfg;
|
||||
|
||||
cfg.VLEN = (riscv::XLEN == 32) ? 32 : 64;
|
||||
cfg.PLEN = (riscv::XLEN == 32) ? 34 : 56;
|
||||
cfg.IS_XLEN32 = IS_XLEN32;
|
||||
cfg.IS_XLEN64 = IS_XLEN64;
|
||||
cfg.XLEN_ALIGN_BYTES = $clog2(riscv::XLEN / 8);
|
||||
cfg.ASID_WIDTH = (riscv::XLEN == 64) ? 16 : 1;
|
||||
|
||||
cfg.FPGA_EN = CVA6Cfg.FPGA_EN;
|
||||
cfg.NrCommitPorts = CVA6Cfg.NrCommitPorts;
|
||||
|
@ -97,13 +104,13 @@ package build_config_pkg;
|
|||
cfg.ICACHE_SET_ASSOC = CVA6Cfg.IcacheSetAssoc;
|
||||
cfg.ICACHE_SET_ASSOC_WIDTH = $clog2(CVA6Cfg.IcacheSetAssoc);
|
||||
cfg.ICACHE_INDEX_WIDTH = ICACHE_INDEX_WIDTH;
|
||||
cfg.ICACHE_TAG_WIDTH = riscv::PLEN - ICACHE_INDEX_WIDTH;
|
||||
cfg.ICACHE_TAG_WIDTH = cfg.PLEN - ICACHE_INDEX_WIDTH;
|
||||
cfg.ICACHE_LINE_WIDTH = CVA6Cfg.IcacheLineWidth;
|
||||
cfg.ICACHE_USER_LINE_WIDTH = (CVA6Cfg.AxiUserWidth == 1) ? 4 : CVA6Cfg.IcacheLineWidth;
|
||||
cfg.DCACHE_SET_ASSOC = CVA6Cfg.DcacheSetAssoc;
|
||||
cfg.DCACHE_SET_ASSOC_WIDTH = $clog2(CVA6Cfg.DcacheSetAssoc);
|
||||
cfg.DCACHE_INDEX_WIDTH = DCACHE_INDEX_WIDTH;
|
||||
cfg.DCACHE_TAG_WIDTH = riscv::PLEN - DCACHE_INDEX_WIDTH;
|
||||
cfg.DCACHE_TAG_WIDTH = cfg.PLEN - DCACHE_INDEX_WIDTH;
|
||||
cfg.DCACHE_LINE_WIDTH = CVA6Cfg.DcacheLineWidth;
|
||||
cfg.DCACHE_USER_LINE_WIDTH = (CVA6Cfg.AxiUserWidth == 1) ? 4 : CVA6Cfg.DcacheLineWidth;
|
||||
cfg.DCACHE_USER_WIDTH = CVA6Cfg.AxiUserWidth;
|
||||
|
@ -115,6 +122,7 @@ package build_config_pkg;
|
|||
cfg.DATA_USER_EN = CVA6Cfg.DataUserEn;
|
||||
cfg.FETCH_USER_WIDTH = CVA6Cfg.FetchUserWidth;
|
||||
cfg.FETCH_USER_EN = CVA6Cfg.FetchUserEn;
|
||||
cfg.AXI_USER_EN = CVA6Cfg.DataUserEn | CVA6Cfg.FetchUserEn;
|
||||
|
||||
cfg.FETCH_WIDTH = 32;
|
||||
cfg.INSTR_PER_FETCH = CVA6Cfg.RVC == 1'b1 ? (cfg.FETCH_WIDTH / 16) : 1;
|
||||
|
|
|
@ -163,7 +163,12 @@ package config_pkg;
|
|||
} cva6_user_cfg_t;
|
||||
|
||||
typedef struct packed {
|
||||
int unsigned VLEN;
|
||||
int unsigned PLEN;
|
||||
bit IS_XLEN32;
|
||||
bit IS_XLEN64;
|
||||
int unsigned XLEN_ALIGN_BYTES;
|
||||
int unsigned ASID_WIDTH;
|
||||
|
||||
bit FPGA_EN;
|
||||
/// Number of commit ports, i.e., maximum number of instructions that the
|
||||
|
@ -257,6 +262,7 @@ package config_pkg;
|
|||
int unsigned DATA_USER_EN;
|
||||
int unsigned FETCH_USER_WIDTH;
|
||||
int unsigned FETCH_USER_EN;
|
||||
int unsigned AXI_USER_EN;
|
||||
|
||||
int unsigned FETCH_WIDTH;
|
||||
int unsigned INSTR_PER_FETCH;
|
||||
|
|
|
@ -20,15 +20,11 @@ package riscv;
|
|||
// ----------------------
|
||||
// Import cva6 config from cva6_config_pkg
|
||||
// ----------------------
|
||||
// FIXME stop using them from CoreV-Verif and HPDCache
|
||||
// Then remove them from this package
|
||||
localparam XLEN = cva6_config_pkg::CVA6ConfigXlen;
|
||||
|
||||
// Warning: When using STD_CACHE, configuration must be PLEN=56 and VLEN=64
|
||||
// Warning: VLEN must be superior or equal to PLEN
|
||||
localparam VLEN = (XLEN == 32) ? 32 : 64; // virtual address length
|
||||
localparam PLEN = (XLEN == 32) ? 34 : 56; // physical address length
|
||||
|
||||
localparam IS_XLEN32 = (XLEN == 32) ? 1'b1 : 1'b0;
|
||||
localparam IS_XLEN64 = (XLEN == 32) ? 1'b0 : 1'b1;
|
||||
localparam VLEN = (XLEN == 32) ? 32 : 64;
|
||||
localparam PLEN = (XLEN == 32) ? 34 : 56;
|
||||
|
||||
// --------------------
|
||||
// Privilege Spec
|
||||
|
@ -605,9 +601,15 @@ package riscv;
|
|||
localparam logic [63:0] MSTATUS_TVM = 'h00100000;
|
||||
localparam logic [63:0] MSTATUS_TW = 'h00200000;
|
||||
localparam logic [63:0] MSTATUS_TSR = 'h00400000;
|
||||
localparam logic [63:0] MSTATUS_UXL = {30'h0000000, IS_XLEN64, IS_XLEN64, 32'h00000000};
|
||||
localparam logic [63:0] MSTATUS_SXL = {28'h0000000, IS_XLEN64, IS_XLEN64, 34'h00000000};
|
||||
localparam logic [63:0] MSTATUS_SD = {IS_XLEN64, 31'h00000000, ~IS_XLEN64, 31'h00000000};
|
||||
function automatic logic [63:0] mstatus_uxl(logic IS_XLEN64);
|
||||
return {30'h0000000, IS_XLEN64, IS_XLEN64, 32'h00000000};
|
||||
endfunction
|
||||
function automatic logic [63:0] mstatus_sxl(logic IS_XLEN64);
|
||||
return {28'h0000000, IS_XLEN64, IS_XLEN64, 34'h00000000};
|
||||
endfunction
|
||||
function automatic logic [63:0] mstatus_sd(logic IS_XLEN64);
|
||||
return {IS_XLEN64, 31'h00000000, ~IS_XLEN64, 31'h00000000};
|
||||
endfunction
|
||||
|
||||
typedef enum logic [2:0] {
|
||||
CSRRW = 3'h1,
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
logic [config_pkg::NRET*riscv::XLEN-1:0] rd_wdata; \
|
||||
logic [config_pkg::NRET*riscv::XLEN-1:0] pc_rdata; \
|
||||
logic [config_pkg::NRET*riscv::XLEN-1:0] pc_wdata; \
|
||||
logic [config_pkg::NRET*riscv::VLEN-1:0] mem_addr; \
|
||||
logic [config_pkg::NRET*riscv::PLEN-1:0] mem_paddr; \
|
||||
logic [config_pkg::NRET*Cfg.VLEN-1:0] mem_addr; \
|
||||
logic [config_pkg::NRET*Cfg.PLEN-1:0] mem_paddr; \
|
||||
logic [config_pkg::NRET*(riscv::XLEN/8)-1:0] mem_rmask; \
|
||||
logic [config_pkg::NRET*(riscv::XLEN/8)-1:0] mem_wmask; \
|
||||
logic [config_pkg::NRET*riscv::XLEN-1:0] mem_rdata; \
|
||||
|
@ -105,23 +105,23 @@
|
|||
logic is_compressed; \
|
||||
logic [riscv::XLEN-1:0] rs1_forwarding; \
|
||||
logic [riscv::XLEN-1:0] rs2_forwarding; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][riscv::VLEN-1:0] commit_instr_pc; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][Cfg.VLEN-1:0] commit_instr_pc; \
|
||||
ariane_pkg::fu_op [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][Cfg.TRANS_ID_BITS-1:0] commit_instr_op; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] commit_instr_rs1; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] commit_instr_rs2; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] commit_instr_rd; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][riscv::XLEN-1:0] commit_instr_result; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][riscv::VLEN-1:0] commit_instr_valid; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][Cfg.VLEN-1:0] commit_instr_valid; \
|
||||
logic [riscv::XLEN-1:0] ex_commit_cause; \
|
||||
logic ex_commit_valid; \
|
||||
riscv::priv_lvl_t priv_lvl; \
|
||||
logic [riscv::VLEN-1:0] lsu_ctrl_vaddr; \
|
||||
logic [Cfg.VLEN-1:0] lsu_ctrl_vaddr; \
|
||||
ariane_pkg::fu_t lsu_ctrl_fu; \
|
||||
logic [(riscv::XLEN/8)-1:0] lsu_ctrl_be; \
|
||||
logic [Cfg.TRANS_ID_BITS-1:0] lsu_ctrl_trans_id; \
|
||||
logic [((cva6_config_pkg::CVA6ConfigCvxifEn || cva6_config_pkg::CVA6ConfigVExtEn) ? 5 : 4)-1:0][riscv::XLEN-1:0] wbdata; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0] commit_ack; \
|
||||
logic [riscv::PLEN-1:0] mem_paddr; \
|
||||
logic [Cfg.PLEN-1:0] mem_paddr; \
|
||||
logic debug_mode; \
|
||||
logic [cva6_config_pkg::CVA6ConfigNrCommitPorts-1:0][riscv::XLEN-1:0] wdata; \
|
||||
}
|
||||
|
@ -158,7 +158,7 @@
|
|||
logic [riscv::XLEN-1:0] icache_q; \
|
||||
logic [riscv::XLEN-1:0] acc_cons_q; \
|
||||
riscv::pmpcfg_t [15:0] pmpcfg_q; \
|
||||
logic [15:0][riscv::PLEN-3:0] pmpaddr_q; \
|
||||
logic [15:0][Cfg.PLEN-3:0] pmpaddr_q; \
|
||||
}
|
||||
|
||||
`endif // RVFI_TYPES_SVH
|
||||
|
|
|
@ -36,13 +36,13 @@ module instr_realign
|
|||
// Instruction is unaligned - FRONTEND
|
||||
output logic serving_unaligned_o,
|
||||
// 32-bit block address - CACHE
|
||||
input logic [riscv::VLEN-1:0] address_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] address_i,
|
||||
// 32-bit block - CACHE
|
||||
input logic [CVA6Cfg.FETCH_WIDTH-1:0] data_i,
|
||||
// instruction is valid - FRONTEND
|
||||
output logic [CVA6Cfg.INSTR_PER_FETCH-1:0] valid_o,
|
||||
// Instruction address - FRONTEND
|
||||
output logic [CVA6Cfg.INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_o,
|
||||
output logic [CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] addr_o,
|
||||
// Instruction - instr_scan&instr_queue
|
||||
output logic [CVA6Cfg.INSTR_PER_FETCH-1:0][31:0] instr_o
|
||||
);
|
||||
|
@ -59,7 +59,7 @@ module instr_realign
|
|||
// the last instruction was unaligned
|
||||
logic unaligned_d, unaligned_q;
|
||||
// register to save the unaligned address
|
||||
logic [riscv::VLEN-1:0] unaligned_address_d, unaligned_address_q;
|
||||
logic [CVA6Cfg.VLEN-1:0] unaligned_address_d, unaligned_address_q;
|
||||
// we have an unaligned instruction
|
||||
assign serving_unaligned_o = unaligned_q;
|
||||
|
||||
|
@ -67,7 +67,7 @@ module instr_realign
|
|||
if (CVA6Cfg.FETCH_WIDTH == 32) begin : realign_bp_32
|
||||
always_comb begin : re_align
|
||||
unaligned_d = unaligned_q;
|
||||
unaligned_address_d = {address_i[riscv::VLEN-1:2], 2'b10};
|
||||
unaligned_address_d = {address_i[CVA6Cfg.VLEN-1:2], 2'b10};
|
||||
unaligned_instr_d = data_i[31:16];
|
||||
|
||||
valid_o[0] = valid_i;
|
||||
|
@ -76,7 +76,7 @@ module instr_realign
|
|||
|
||||
valid_o[1] = 1'b0;
|
||||
instr_o[1] = '0;
|
||||
addr_o[1] = {address_i[riscv::VLEN-1:2], 2'b10};
|
||||
addr_o[1] = {address_i[CVA6Cfg.VLEN-1:2], 2'b10};
|
||||
|
||||
// this instruction is compressed or the last instruction was unaligned
|
||||
if (instr_is_compressed[0] || unaligned_q) begin
|
||||
|
@ -94,7 +94,7 @@ module instr_realign
|
|||
// save the upper bits for next cycle
|
||||
unaligned_d = 1'b1;
|
||||
unaligned_instr_d = data_i[31:16];
|
||||
unaligned_address_d = {address_i[riscv::VLEN-1:2], 2'b10};
|
||||
unaligned_address_d = {address_i[CVA6Cfg.VLEN-1:2], 2'b10};
|
||||
end
|
||||
end // else -> normal fetch
|
||||
|
||||
|
@ -105,7 +105,7 @@ module instr_realign
|
|||
if (!instr_is_compressed[0]) begin
|
||||
valid_o = '0;
|
||||
unaligned_d = 1'b1;
|
||||
unaligned_address_d = {address_i[riscv::VLEN-1:2], 2'b10};
|
||||
unaligned_address_d = {address_i[CVA6Cfg.VLEN-1:2], 2'b10};
|
||||
unaligned_instr_d = data_i[15:0];
|
||||
// the instruction isn't compressed but only the lower is ready
|
||||
end else begin
|
||||
|
@ -130,13 +130,13 @@ module instr_realign
|
|||
addr_o[0] = address_i;
|
||||
|
||||
instr_o[1] = '0;
|
||||
addr_o[1] = {address_i[riscv::VLEN-1:3], 3'b010};
|
||||
addr_o[1] = {address_i[CVA6Cfg.VLEN-1:3], 3'b010};
|
||||
|
||||
instr_o[2] = {16'b0, data_i[47:32]};
|
||||
addr_o[2] = {address_i[riscv::VLEN-1:3], 3'b100};
|
||||
addr_o[2] = {address_i[CVA6Cfg.VLEN-1:3], 3'b100};
|
||||
|
||||
instr_o[3] = {16'b0, data_i[63:48]};
|
||||
addr_o[3] = {address_i[riscv::VLEN-1:3], 3'b110};
|
||||
addr_o[3] = {address_i[CVA6Cfg.VLEN-1:3], 3'b110};
|
||||
|
||||
// last instruction was unaligned
|
||||
if (unaligned_q) begin
|
||||
|
@ -172,7 +172,7 @@ module instr_realign
|
|||
end else begin
|
||||
instr_o[1] = data_i[47:16];
|
||||
valid_o[1] = valid_i;
|
||||
addr_o[2] = {address_i[riscv::VLEN-1:3], 3'b110};
|
||||
addr_o[2] = {address_i[CVA6Cfg.VLEN-1:3], 3'b110};
|
||||
if (instr_is_compressed[2]) begin
|
||||
unaligned_d = 1'b0;
|
||||
instr_o[2] = {16'b0, data_i[63:48]};
|
||||
|
@ -211,7 +211,7 @@ module instr_realign
|
|||
end else begin
|
||||
instr_o[1] = data_i[47:16];
|
||||
valid_o[1] = valid_i;
|
||||
addr_o[2] = {address_i[riscv::VLEN-1:3], 3'b110};
|
||||
addr_o[2] = {address_i[CVA6Cfg.VLEN-1:3], 3'b110};
|
||||
if (instr_is_compressed[3]) begin
|
||||
instr_o[2] = data_i[63:48];
|
||||
valid_o[2] = valid_i;
|
||||
|
@ -229,12 +229,12 @@ module instr_realign
|
|||
// | * | C | C | I |
|
||||
// | * | I | I |
|
||||
end else begin
|
||||
addr_o[1] = {address_i[riscv::VLEN-1:3], 3'b100};
|
||||
addr_o[1] = {address_i[CVA6Cfg.VLEN-1:3], 3'b100};
|
||||
|
||||
if (instr_is_compressed[2]) begin
|
||||
instr_o[1] = {16'b0, data_i[47:32]};
|
||||
valid_o[1] = valid_i;
|
||||
addr_o[2] = {address_i[riscv::VLEN-1:3], 3'b110};
|
||||
addr_o[2] = {address_i[CVA6Cfg.VLEN-1:3], 3'b110};
|
||||
if (instr_is_compressed[3]) begin
|
||||
// | * | C | C | I |
|
||||
valid_o[2] = valid_i;
|
||||
|
@ -267,7 +267,7 @@ module instr_realign
|
|||
// | * | I | C | x -> aligned
|
||||
// | I | C | C | x -> again unaligned
|
||||
// | * | C | C | C | x -> aligned
|
||||
addr_o[0] = {address_i[riscv::VLEN-1:3], 3'b010};
|
||||
addr_o[0] = {address_i[CVA6Cfg.VLEN-1:3], 3'b010};
|
||||
|
||||
if (instr_is_compressed[1]) begin
|
||||
instr_o[0] = {16'b0, data_i[31:16]};
|
||||
|
@ -276,10 +276,10 @@ module instr_realign
|
|||
if (instr_is_compressed[2]) begin
|
||||
valid_o[1] = valid_i;
|
||||
instr_o[1] = {16'b0, data_i[47:32]};
|
||||
addr_o[1] = {address_i[riscv::VLEN-1:3], 3'b100};
|
||||
addr_o[1] = {address_i[CVA6Cfg.VLEN-1:3], 3'b100};
|
||||
if (instr_is_compressed[3]) begin
|
||||
instr_o[2] = {16'b0, data_i[63:48]};
|
||||
addr_o[2] = {address_i[riscv::VLEN-1:3], 3'b110};
|
||||
addr_o[2] = {address_i[CVA6Cfg.VLEN-1:3], 3'b110};
|
||||
valid_o[2] = valid_i;
|
||||
end else begin
|
||||
// this instruction is unaligned
|
||||
|
@ -289,14 +289,14 @@ module instr_realign
|
|||
end
|
||||
end else begin
|
||||
instr_o[1] = data_i[63:32];
|
||||
addr_o[1] = {address_i[riscv::VLEN-1:3], 3'b100};
|
||||
addr_o[1] = {address_i[CVA6Cfg.VLEN-1:3], 3'b100};
|
||||
valid_o[1] = valid_i;
|
||||
end
|
||||
// instruction 1 is not compressed -> check slot 3
|
||||
end else begin
|
||||
instr_o[0] = data_i[47:16];
|
||||
valid_o[0] = valid_i;
|
||||
addr_o[1] = {address_i[riscv::VLEN-1:3], 3'b110};
|
||||
addr_o[1] = {address_i[CVA6Cfg.VLEN-1:3], 3'b110};
|
||||
if (instr_is_compressed[3]) begin
|
||||
instr_o[1] = data_i[63:48];
|
||||
valid_o[1] = valid_i;
|
||||
|
@ -324,7 +324,7 @@ module instr_realign
|
|||
// regular instruction -> unaligned
|
||||
end else begin
|
||||
unaligned_d = 1'b1;
|
||||
unaligned_address_d = {address_i[riscv::VLEN-1:3], 3'b110};
|
||||
unaligned_address_d = {address_i[CVA6Cfg.VLEN-1:3], 3'b110};
|
||||
unaligned_instr_d = data_i[63:48];
|
||||
end
|
||||
// instruction is a regular instruction
|
||||
|
@ -340,7 +340,7 @@ module instr_realign
|
|||
valid_o = '0;
|
||||
if (!instr_is_compressed[3]) begin
|
||||
unaligned_d = 1'b1;
|
||||
unaligned_address_d = {address_i[riscv::VLEN-1:3], 3'b110};
|
||||
unaligned_address_d = {address_i[CVA6Cfg.VLEN-1:3], 3'b110};
|
||||
unaligned_instr_d = data_i[63:48];
|
||||
end else begin
|
||||
valid_o[3] = valid_i;
|
||||
|
|
|
@ -69,7 +69,7 @@ module issue_read_operands
|
|||
// Unregistered version of fu_data_o.operandb - TO_BE_COMPLETED
|
||||
output logic [riscv::XLEN-1:0] rs2_forwarding_o,
|
||||
// Instruction pc - TO_BE_COMPLETED
|
||||
output logic [riscv::VLEN-1:0] pc_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] pc_o,
|
||||
// Is compressed instruction - TO_BE_COMPLETED
|
||||
output logic is_compressed_instr_o,
|
||||
// Fixed Latency Unit ready to accept new request - TO_BE_COMPLETED
|
||||
|
@ -145,30 +145,30 @@ module issue_read_operands
|
|||
|
||||
// original instruction
|
||||
riscv::instruction_t orig_instr;
|
||||
assign orig_instr = riscv::instruction_t'(orig_instr_i);
|
||||
assign orig_instr = riscv::instruction_t'(orig_instr_i);
|
||||
|
||||
// ID <-> EX registers
|
||||
|
||||
assign rs1_forwarding_o = operand_a_n[riscv::VLEN-1:0]; //forwarding or unregistered rs1 value
|
||||
assign rs2_forwarding_o = operand_b_n[riscv::VLEN-1:0]; //forwarding or unregistered rs2 value
|
||||
assign rs1_forwarding_o = operand_a_n[CVA6Cfg.VLEN-1:0]; //forwarding or unregistered rs1 value
|
||||
assign rs2_forwarding_o = operand_b_n[CVA6Cfg.VLEN-1:0]; //forwarding or unregistered rs2 value
|
||||
|
||||
assign fu_data_o.operand_a = operand_a_q;
|
||||
assign fu_data_o.operand_b = operand_b_q;
|
||||
assign fu_data_o.fu = fu_q;
|
||||
assign fu_data_o.fu = fu_q;
|
||||
assign fu_data_o.operation = operator_q;
|
||||
assign fu_data_o.trans_id = trans_id_q;
|
||||
assign fu_data_o.imm = imm_q;
|
||||
assign alu_valid_o = alu_valid_q;
|
||||
assign branch_valid_o = branch_valid_q;
|
||||
assign lsu_valid_o = lsu_valid_q;
|
||||
assign csr_valid_o = csr_valid_q;
|
||||
assign mult_valid_o = mult_valid_q;
|
||||
assign fpu_valid_o = fpu_valid_q;
|
||||
assign fpu_fmt_o = fpu_fmt_q;
|
||||
assign fpu_rm_o = fpu_rm_q;
|
||||
assign cvxif_valid_o = CVA6Cfg.CvxifEn ? cvxif_valid_q : '0;
|
||||
assign cvxif_off_instr_o = CVA6Cfg.CvxifEn ? cvxif_off_instr_q : '0;
|
||||
assign stall_issue_o = stall;
|
||||
assign fu_data_o.trans_id = trans_id_q;
|
||||
assign fu_data_o.imm = imm_q;
|
||||
assign alu_valid_o = alu_valid_q;
|
||||
assign branch_valid_o = branch_valid_q;
|
||||
assign lsu_valid_o = lsu_valid_q;
|
||||
assign csr_valid_o = csr_valid_q;
|
||||
assign mult_valid_o = mult_valid_q;
|
||||
assign fpu_valid_o = fpu_valid_q;
|
||||
assign fpu_fmt_o = fpu_fmt_q;
|
||||
assign fpu_rm_o = fpu_rm_q;
|
||||
assign cvxif_valid_o = CVA6Cfg.CvxifEn ? cvxif_valid_q : '0;
|
||||
assign cvxif_off_instr_o = CVA6Cfg.CvxifEn ? cvxif_off_instr_q : '0;
|
||||
assign stall_issue_o = stall;
|
||||
// ---------------
|
||||
// Issue Stage
|
||||
// ---------------
|
||||
|
@ -299,7 +299,7 @@ module issue_read_operands
|
|||
// use the PC as operand a
|
||||
if (issue_instr_i.use_pc) begin
|
||||
operand_a_n = {
|
||||
{riscv::XLEN - riscv::VLEN{issue_instr_i.pc[riscv::VLEN-1]}}, issue_instr_i.pc
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{issue_instr_i.pc[CVA6Cfg.VLEN-1]}}, issue_instr_i.pc
|
||||
};
|
||||
end
|
||||
|
||||
|
@ -599,7 +599,7 @@ module issue_read_operands
|
|||
trans_id_q <= '0;
|
||||
pc_o <= '0;
|
||||
is_compressed_instr_o <= 1'b0;
|
||||
branch_predict_o <= {cf_t'(0), {riscv::VLEN{1'b0}}};
|
||||
branch_predict_o <= {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}};
|
||||
end else begin
|
||||
operand_a_q <= operand_a_n;
|
||||
operand_b_q <= operand_b_n;
|
||||
|
|
|
@ -47,13 +47,13 @@ module issue_stage
|
|||
// Handshake's acknowlege with decode stage - ID_STAGE
|
||||
output logic decoded_instr_ack_o,
|
||||
// rs1 forwarding - EX_STAGE
|
||||
output [riscv::VLEN-1:0] rs1_forwarding_o,
|
||||
output [CVA6Cfg.VLEN-1:0] rs1_forwarding_o,
|
||||
// rs2 forwarding - EX_STAGE
|
||||
output [riscv::VLEN-1:0] rs2_forwarding_o,
|
||||
output [CVA6Cfg.VLEN-1:0] rs2_forwarding_o,
|
||||
// FU data useful to execute instruction - EX_STAGE
|
||||
output fu_data_t fu_data_o,
|
||||
// Program Counter - EX_STAGE
|
||||
output logic [riscv::VLEN-1:0] pc_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] pc_o,
|
||||
// Is compressed instruction - EX_STAGE
|
||||
output logic is_compressed_instr_o,
|
||||
// Fixed Latency Unit is ready - EX_STAGE
|
||||
|
@ -151,8 +151,8 @@ module issue_stage
|
|||
logic [ riscv::XLEN-1:0] rs1_forwarding_xlen;
|
||||
logic [ riscv::XLEN-1:0] rs2_forwarding_xlen;
|
||||
|
||||
assign rs1_forwarding_o = rs1_forwarding_xlen[riscv::VLEN-1:0];
|
||||
assign rs2_forwarding_o = rs2_forwarding_xlen[riscv::VLEN-1:0];
|
||||
assign rs1_forwarding_o = rs1_forwarding_xlen[CVA6Cfg.VLEN-1:0];
|
||||
assign rs2_forwarding_o = rs2_forwarding_xlen[CVA6Cfg.VLEN-1:0];
|
||||
|
||||
assign issue_instr_o = issue_instr_sb_iro;
|
||||
assign issue_instr_hs_o = issue_instr_valid_sb_iro & issue_ack_iro_sb;
|
||||
|
|
|
@ -25,8 +25,7 @@ module load_store_unit
|
|||
parameter type icache_arsp_t = logic,
|
||||
parameter type icache_dreq_t = logic,
|
||||
parameter type icache_drsp_t = logic,
|
||||
parameter type lsu_ctrl_t = logic,
|
||||
parameter int unsigned ASID_WIDTH = 1
|
||||
parameter type lsu_ctrl_t = logic
|
||||
) (
|
||||
// Subsystem Clock - SUBSYSTEM
|
||||
input logic clk_i,
|
||||
|
@ -83,49 +82,49 @@ module load_store_unit
|
|||
output icache_areq_t icache_areq_o,
|
||||
|
||||
// Current privilege mode - CSR_REGFILE
|
||||
input riscv::priv_lvl_t priv_lvl_i,
|
||||
input riscv::priv_lvl_t priv_lvl_i,
|
||||
// Privilege level at which load and stores should happen - CSR_REGFILE
|
||||
input riscv::priv_lvl_t ld_st_priv_lvl_i,
|
||||
input riscv::priv_lvl_t ld_st_priv_lvl_i,
|
||||
// Supervisor User Memory - CSR_REGFILE
|
||||
input logic sum_i,
|
||||
input logic sum_i,
|
||||
// Make Executable Readable - CSR_REGFILE
|
||||
input logic mxr_i,
|
||||
input logic mxr_i,
|
||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||
input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i,
|
||||
input logic [ CVA6Cfg.PPNW-1:0] satp_ppn_i,
|
||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||
input logic [ ASID_WIDTH-1:0] asid_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_i,
|
||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||
input logic [ ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||
input logic [ riscv::VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
input logic [ CVA6Cfg.VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
// TLB flush - CONTROLLER
|
||||
input logic flush_tlb_i,
|
||||
input logic flush_tlb_i,
|
||||
// Instruction TLB miss - PERF_COUNTERS
|
||||
output logic itlb_miss_o,
|
||||
output logic itlb_miss_o,
|
||||
// Data TLB miss - PERF_COUNTERS
|
||||
output logic dtlb_miss_o,
|
||||
output logic dtlb_miss_o,
|
||||
|
||||
// Data cache request output - CACHES
|
||||
input dcache_req_o_t [ 2:0] dcache_req_ports_i,
|
||||
input dcache_req_o_t [ 2:0] dcache_req_ports_i,
|
||||
// Data cache request input - CACHES
|
||||
output dcache_req_i_t [ 2:0] dcache_req_ports_o,
|
||||
output dcache_req_i_t [ 2:0] dcache_req_ports_o,
|
||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||
input logic dcache_wbuffer_empty_i,
|
||||
input logic dcache_wbuffer_empty_i,
|
||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||
input logic dcache_wbuffer_not_ni_i,
|
||||
input logic dcache_wbuffer_not_ni_i,
|
||||
// AMO request - CACHE
|
||||
output amo_req_t amo_req_o,
|
||||
output amo_req_t amo_req_o,
|
||||
// AMO response - CACHE
|
||||
input amo_resp_t amo_resp_i,
|
||||
input amo_resp_t amo_resp_i,
|
||||
// PMP configuration - CSR_REGFILE
|
||||
input riscv::pmpcfg_t [15:0] pmpcfg_i,
|
||||
input riscv::pmpcfg_t [15:0] pmpcfg_i,
|
||||
// PMP address - CSR_REGFILE
|
||||
input logic [15:0][riscv::PLEN-3:0] pmpaddr_i,
|
||||
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
|
||||
// RVFI inforamtion - RVFI
|
||||
output lsu_ctrl_t rvfi_lsu_ctrl_o,
|
||||
output lsu_ctrl_t rvfi_lsu_ctrl_o,
|
||||
// RVFI information - RVFI
|
||||
output [riscv::PLEN-1:0] rvfi_mem_paddr_o
|
||||
output [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr_o
|
||||
);
|
||||
|
||||
// data is misaligned
|
||||
|
@ -144,26 +143,26 @@ module load_store_unit
|
|||
// Address Generation Unit (AGU)
|
||||
// ------------------------------
|
||||
// virtual address as calculated by the AGU in the first cycle
|
||||
logic [ riscv::VLEN-1:0] vaddr_i;
|
||||
logic [ CVA6Cfg.VLEN-1:0] vaddr_i;
|
||||
logic [ riscv::XLEN-1:0] vaddr_xlen;
|
||||
logic overflow;
|
||||
logic [(riscv::XLEN/8)-1:0] be_i;
|
||||
|
||||
assign vaddr_xlen = $unsigned($signed(fu_data_i.imm) + $signed(fu_data_i.operand_a));
|
||||
assign vaddr_i = vaddr_xlen[riscv::VLEN-1:0];
|
||||
assign vaddr_i = vaddr_xlen[CVA6Cfg.VLEN-1:0];
|
||||
// we work with SV39 or SV32, so if VM is enabled, check that all bits [XLEN-1:38] or [XLEN-1:31] are equal
|
||||
assign overflow = (riscv::IS_XLEN64 && (!((&vaddr_xlen[riscv::XLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|vaddr_xlen[riscv::XLEN-1:CVA6Cfg.SV-1]) == 1'b0)));
|
||||
assign overflow = (CVA6Cfg.IS_XLEN64 && (!((&vaddr_xlen[riscv::XLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|vaddr_xlen[riscv::XLEN-1:CVA6Cfg.SV-1]) == 1'b0)));
|
||||
|
||||
logic st_valid_i;
|
||||
logic ld_valid_i;
|
||||
logic ld_translation_req;
|
||||
logic st_translation_req;
|
||||
logic [riscv::VLEN-1:0] ld_vaddr;
|
||||
logic [riscv::VLEN-1:0] st_vaddr;
|
||||
logic translation_req;
|
||||
logic translation_valid;
|
||||
logic [riscv::VLEN-1:0] mmu_vaddr;
|
||||
logic [riscv::PLEN-1:0] mmu_paddr, mmu_vaddr_plen, fetch_vaddr_plen;
|
||||
logic st_valid_i;
|
||||
logic ld_valid_i;
|
||||
logic ld_translation_req;
|
||||
logic st_translation_req;
|
||||
logic [CVA6Cfg.VLEN-1:0] ld_vaddr;
|
||||
logic [CVA6Cfg.VLEN-1:0] st_vaddr;
|
||||
logic translation_req;
|
||||
logic translation_valid;
|
||||
logic [CVA6Cfg.VLEN-1:0] mmu_vaddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] mmu_paddr, mmu_vaddr_plen, fetch_vaddr_plen;
|
||||
exception_t mmu_exception;
|
||||
logic dtlb_hit;
|
||||
logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn;
|
||||
|
@ -196,8 +195,7 @@ module load_store_unit
|
|||
.dcache_req_i_t (dcache_req_i_t),
|
||||
.dcache_req_o_t (dcache_req_o_t),
|
||||
.INSTR_TLB_ENTRIES(ariane_pkg::INSTR_TLB_ENTRIES),
|
||||
.DATA_TLB_ENTRIES (ariane_pkg::DATA_TLB_ENTRIES),
|
||||
.ASID_WIDTH (ASID_WIDTH)
|
||||
.DATA_TLB_ENTRIES (ariane_pkg::DATA_TLB_ENTRIES)
|
||||
) i_cva6_mmu (
|
||||
// misaligned bypass
|
||||
.misaligned_ex_i(misaligned_exception),
|
||||
|
@ -232,8 +230,7 @@ module load_store_unit
|
|||
.dcache_req_i_t (dcache_req_i_t),
|
||||
.dcache_req_o_t (dcache_req_o_t),
|
||||
.INSTR_TLB_ENTRIES(ariane_pkg::INSTR_TLB_ENTRIES),
|
||||
.DATA_TLB_ENTRIES (ariane_pkg::DATA_TLB_ENTRIES),
|
||||
.ASID_WIDTH (ASID_WIDTH)
|
||||
.DATA_TLB_ENTRIES (ariane_pkg::DATA_TLB_ENTRIES)
|
||||
) i_cva6_mmu (
|
||||
// misaligned bypass
|
||||
.misaligned_ex_i(misaligned_exception),
|
||||
|
@ -259,12 +256,12 @@ module load_store_unit
|
|||
);
|
||||
end else begin : gen_no_mmu
|
||||
|
||||
if (riscv::VLEN > riscv::PLEN) begin
|
||||
assign mmu_vaddr_plen = mmu_vaddr[riscv::PLEN-1:0];
|
||||
assign fetch_vaddr_plen = icache_areq_i.fetch_vaddr[riscv::PLEN-1:0];
|
||||
if (CVA6Cfg.VLEN > CVA6Cfg.PLEN) begin
|
||||
assign mmu_vaddr_plen = mmu_vaddr[CVA6Cfg.PLEN-1:0];
|
||||
assign fetch_vaddr_plen = icache_areq_i.fetch_vaddr[CVA6Cfg.PLEN-1:0];
|
||||
end else begin
|
||||
assign mmu_vaddr_plen = {{{riscv::PLEN - riscv::VLEN} {1'b0}}, mmu_vaddr};
|
||||
assign fetch_vaddr_plen = {{{riscv::PLEN - riscv::VLEN} {1'b0}}, icache_areq_i.fetch_vaddr};
|
||||
assign mmu_vaddr_plen = {{{CVA6Cfg.PLEN - CVA6Cfg.VLEN} {1'b0}}, mmu_vaddr};
|
||||
assign fetch_vaddr_plen = {{{CVA6Cfg.PLEN - CVA6Cfg.VLEN} {1'b0}}, icache_areq_i.fetch_vaddr};
|
||||
end
|
||||
|
||||
assign icache_areq_o.fetch_valid = icache_areq_i.fetch_req;
|
||||
|
@ -283,7 +280,7 @@ module load_store_unit
|
|||
|
||||
assign itlb_miss_o = 1'b0;
|
||||
assign dtlb_miss_o = 1'b0;
|
||||
assign dtlb_ppn = mmu_vaddr_plen[riscv::PLEN-1:12];
|
||||
assign dtlb_ppn = mmu_vaddr_plen[CVA6Cfg.PLEN-1:12];
|
||||
assign dtlb_hit = 1'b1;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
|
@ -418,7 +415,7 @@ module load_store_unit
|
|||
st_valid_i = 1'b0;
|
||||
|
||||
translation_req = 1'b0;
|
||||
mmu_vaddr = {riscv::VLEN{1'b0}};
|
||||
mmu_vaddr = {CVA6Cfg.VLEN{1'b0}};
|
||||
|
||||
// check the operation to activate the right functional unit accordingly
|
||||
unique case (lsu_ctrl.fu)
|
||||
|
@ -447,7 +444,7 @@ module load_store_unit
|
|||
// 12 bit are the same anyway
|
||||
// and we can always generate the byte enable from the address at hand
|
||||
|
||||
if (riscv::IS_XLEN64) begin : gen_8b_be
|
||||
if (CVA6Cfg.IS_XLEN64) begin : gen_8b_be
|
||||
assign be_i = be_gen(vaddr_i[2:0], extract_transfer_size(fu_data_i.operation));
|
||||
end else begin : gen_4b_be
|
||||
assign be_i = be_gen_32(vaddr_i[1:0], extract_transfer_size(fu_data_i.operation));
|
||||
|
@ -473,7 +470,7 @@ module load_store_unit
|
|||
AMO_SWAPD, AMO_ADDD, AMO_ANDD, AMO_ORD,
|
||||
AMO_XORD, AMO_MAXD, AMO_MAXDU, AMO_MIND,
|
||||
AMO_MINDU: begin
|
||||
if (riscv::IS_XLEN64 && lsu_ctrl.vaddr[2:0] != 3'b000) begin
|
||||
if (CVA6Cfg.IS_XLEN64 && lsu_ctrl.vaddr[2:0] != 3'b000) begin
|
||||
data_misaligned = 1'b1;
|
||||
end
|
||||
end
|
||||
|
@ -504,13 +501,13 @@ module load_store_unit
|
|||
misaligned_exception.cause = riscv::LD_ADDR_MISALIGNED;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
misaligned_exception.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
|
||||
end else if (lsu_ctrl.fu == STORE) begin
|
||||
misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
misaligned_exception.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -520,13 +517,13 @@ module load_store_unit
|
|||
misaligned_exception.cause = riscv::LD_ACCESS_FAULT;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
misaligned_exception.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
|
||||
end else if (lsu_ctrl.fu == STORE) begin
|
||||
misaligned_exception.cause = riscv::ST_ACCESS_FAULT;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
misaligned_exception.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -50,9 +50,9 @@ module load_unit
|
|||
// Request address translation - TO_BE_COMPLETED
|
||||
output logic translation_req_o,
|
||||
// Virtual address - TO_BE_COMPLETED
|
||||
output logic [riscv::VLEN-1:0] vaddr_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] vaddr_o,
|
||||
// Physical address - TO_BE_COMPLETED
|
||||
input logic [riscv::PLEN-1:0] paddr_i,
|
||||
input logic [CVA6Cfg.PLEN-1:0] paddr_i,
|
||||
// Excepted which appears before load - TO_BE_COMPLETED
|
||||
input exception_t ex_i,
|
||||
// Data TLB hit - lsu
|
||||
|
@ -481,7 +481,7 @@ module load_unit
|
|||
// prepare these signals for faster selection in the next cycle
|
||||
assign rdata_is_signed = ldbuf_rdata.operation inside {ariane_pkg::LW, ariane_pkg::LH, ariane_pkg::LB};
|
||||
assign rdata_is_fp_signed = ldbuf_rdata.operation inside {ariane_pkg::FLW, ariane_pkg::FLH, ariane_pkg::FLB};
|
||||
assign rdata_offset = ((ldbuf_rdata.operation inside {ariane_pkg::LW, ariane_pkg::FLW}) & riscv::IS_XLEN64) ? ldbuf_rdata.address_offset + 3 :
|
||||
assign rdata_offset = ((ldbuf_rdata.operation inside {ariane_pkg::LW, ariane_pkg::FLW}) & CVA6Cfg.IS_XLEN64) ? ldbuf_rdata.address_offset + 3 :
|
||||
( ldbuf_rdata.operation inside {ariane_pkg::LH, ariane_pkg::FLH}) ? ldbuf_rdata.address_offset + 1 :
|
||||
ldbuf_rdata.address_offset;
|
||||
|
||||
|
|
|
@ -38,8 +38,7 @@ module cva6_mmu_sv32
|
|||
parameter type dcache_req_i_t = logic,
|
||||
parameter type dcache_req_o_t = logic,
|
||||
parameter int unsigned INSTR_TLB_ENTRIES = 2,
|
||||
parameter int unsigned DATA_TLB_ENTRIES = 2,
|
||||
parameter int unsigned ASID_WIDTH = 1
|
||||
parameter int unsigned DATA_TLB_ENTRIES = 2
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -54,7 +53,7 @@ module cva6_mmu_sv32
|
|||
// in the LSU as we distinguish load and stores, what we do here is simple address translation
|
||||
input exception_t misaligned_ex_i,
|
||||
input logic lsu_req_i, // request address translation
|
||||
input logic [riscv::VLEN-1:0] lsu_vaddr_i, // virtual address in
|
||||
input logic [CVA6Cfg.VLEN-1:0] lsu_vaddr_i, // virtual address in
|
||||
input logic lsu_is_store_i, // the translation is requested by a store
|
||||
// if we need to walk the page table we can't grant in the same cycle
|
||||
// Cycle 0
|
||||
|
@ -62,7 +61,7 @@ module cva6_mmu_sv32
|
|||
output logic [CVA6Cfg.PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit)
|
||||
// Cycle 1
|
||||
output logic lsu_valid_o, // translation is valid
|
||||
output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address
|
||||
output logic [CVA6Cfg.PLEN-1:0] lsu_paddr_o, // translated address
|
||||
output exception_t lsu_exception_o, // address translation threw an exception
|
||||
// General control signals
|
||||
input riscv::priv_lvl_t priv_lvl_i,
|
||||
|
@ -71,9 +70,9 @@ module cva6_mmu_sv32
|
|||
input logic mxr_i,
|
||||
// input logic flag_mprv_i,
|
||||
input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i,
|
||||
input logic [ASID_WIDTH-1:0] asid_i,
|
||||
input logic [ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
input logic flush_tlb_i,
|
||||
// Performance counters
|
||||
output logic itlb_miss_o,
|
||||
|
@ -83,35 +82,35 @@ module cva6_mmu_sv32
|
|||
output dcache_req_i_t req_port_o,
|
||||
// PMP
|
||||
input riscv::pmpcfg_t [15:0] pmpcfg_i,
|
||||
input logic [15:0][riscv::PLEN-3:0] pmpaddr_i
|
||||
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i
|
||||
);
|
||||
|
||||
logic iaccess_err; // insufficient privilege to access this instruction page
|
||||
logic daccess_err; // insufficient privilege to access this data page
|
||||
logic ptw_active; // PTW is currently walking a page table
|
||||
logic walking_instr; // PTW is walking because of an ITLB miss
|
||||
logic ptw_error; // PTW threw an exception
|
||||
logic ptw_access_exception; // PTW threw an access exception (PMPs)
|
||||
logic [riscv::PLEN-1:0] ptw_bad_paddr; // PTW PMP exception bad physical addr
|
||||
logic iaccess_err; // insufficient privilege to access this instruction page
|
||||
logic daccess_err; // insufficient privilege to access this data page
|
||||
logic ptw_active; // PTW is currently walking a page table
|
||||
logic walking_instr; // PTW is walking because of an ITLB miss
|
||||
logic ptw_error; // PTW threw an exception
|
||||
logic ptw_access_exception; // PTW threw an access exception (PMPs)
|
||||
logic [CVA6Cfg.PLEN-1:0] ptw_bad_paddr; // PTW PMP exception bad physical addr
|
||||
|
||||
logic [riscv::VLEN-1:0] update_vaddr;
|
||||
logic [CVA6Cfg.VLEN-1:0] update_vaddr;
|
||||
tlb_update_sv32_t update_itlb, update_dtlb, update_shared_tlb;
|
||||
|
||||
logic itlb_lu_access;
|
||||
riscv::pte_sv32_t itlb_content;
|
||||
logic itlb_is_4M;
|
||||
logic itlb_lu_hit;
|
||||
logic itlb_lu_access;
|
||||
riscv::pte_sv32_t itlb_content;
|
||||
logic itlb_is_4M;
|
||||
logic itlb_lu_hit;
|
||||
|
||||
logic dtlb_lu_access;
|
||||
riscv::pte_sv32_t dtlb_content;
|
||||
logic dtlb_is_4M;
|
||||
logic dtlb_lu_hit;
|
||||
logic dtlb_lu_access;
|
||||
riscv::pte_sv32_t dtlb_content;
|
||||
logic dtlb_is_4M;
|
||||
logic dtlb_lu_hit;
|
||||
|
||||
logic shared_tlb_access;
|
||||
logic [riscv::VLEN-1:0] shared_tlb_vaddr;
|
||||
logic shared_tlb_hit;
|
||||
logic shared_tlb_access;
|
||||
logic [CVA6Cfg.VLEN-1:0] shared_tlb_vaddr;
|
||||
logic shared_tlb_hit;
|
||||
|
||||
logic itlb_req;
|
||||
logic itlb_req;
|
||||
|
||||
|
||||
// Assignments
|
||||
|
@ -121,8 +120,7 @@ module cva6_mmu_sv32
|
|||
|
||||
cva6_tlb_sv32 #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.TLB_ENTRIES(INSTR_TLB_ENTRIES),
|
||||
.ASID_WIDTH (ASID_WIDTH)
|
||||
.TLB_ENTRIES(INSTR_TLB_ENTRIES)
|
||||
) i_itlb (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -143,8 +141,7 @@ module cva6_mmu_sv32
|
|||
|
||||
cva6_tlb_sv32 #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.TLB_ENTRIES(DATA_TLB_ENTRIES),
|
||||
.ASID_WIDTH (ASID_WIDTH)
|
||||
.TLB_ENTRIES(DATA_TLB_ENTRIES)
|
||||
) i_dtlb (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -166,8 +163,7 @@ module cva6_mmu_sv32
|
|||
cva6_shared_tlb_sv32 #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.SHARED_TLB_DEPTH(64),
|
||||
.SHARED_TLB_WAYS (2),
|
||||
.ASID_WIDTH (ASID_WIDTH)
|
||||
.SHARED_TLB_WAYS (2)
|
||||
) i_shared_tlb (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -207,8 +203,7 @@ module cva6_mmu_sv32
|
|||
cva6_ptw_sv32 #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.dcache_req_i_t(dcache_req_i_t),
|
||||
.dcache_req_o_t(dcache_req_o_t),
|
||||
.ASID_WIDTH(ASID_WIDTH)
|
||||
.dcache_req_o_t(dcache_req_o_t)
|
||||
) i_ptw (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -282,13 +277,13 @@ module cva6_mmu_sv32
|
|||
always_comb begin : instr_interface
|
||||
// MMU disabled: just pass through
|
||||
icache_areq_o.fetch_valid = icache_areq_i.fetch_req;
|
||||
if (riscv::PLEN > riscv::VLEN)
|
||||
if (CVA6Cfg.PLEN > CVA6Cfg.VLEN)
|
||||
icache_areq_o.fetch_paddr = {
|
||||
{riscv::PLEN - riscv::VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
{CVA6Cfg.PLEN - CVA6Cfg.VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
}; // play through in case we disabled address translation
|
||||
else
|
||||
icache_areq_o.fetch_paddr = {
|
||||
2'b00, icache_areq_i.fetch_vaddr[riscv::VLEN-1:0]
|
||||
2'b00, icache_areq_i.fetch_vaddr[CVA6Cfg.VLEN-1:0]
|
||||
}; // play through in case we disabled address translation
|
||||
// two potential exception sources:
|
||||
// 1. HPTW threw an exception -> signal with a page fault exception
|
||||
|
@ -303,13 +298,13 @@ module cva6_mmu_sv32
|
|||
// AXI decode error), or when PTW performs walk due to ITLB miss and raises
|
||||
// an error.
|
||||
if (enable_translation_i) begin
|
||||
// we work with SV32, so if VM is enabled, check that all bits [riscv::VLEN-1:CVA6Cfg.SV-1] are equal
|
||||
if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[riscv::VLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[riscv::VLEN-1:CVA6Cfg.SV-1]) == 1'b0)) begin
|
||||
// we work with SV32, so if VM is enabled, check that all bits [CVA6Cfg.VLEN-1:CVA6Cfg.SV-1] are equal
|
||||
if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[CVA6Cfg.VLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[CVA6Cfg.VLEN-1:CVA6Cfg.SV-1]) == 1'b0)) begin
|
||||
icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT;
|
||||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
};
|
||||
end
|
||||
|
||||
|
@ -336,7 +331,7 @@ module cva6_mmu_sv32
|
|||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
};
|
||||
//to check on wave --> not connected
|
||||
end else if (!pmp_instr_allow) begin
|
||||
|
@ -356,13 +351,13 @@ module cva6_mmu_sv32
|
|||
icache_areq_o.fetch_exception.cause = riscv::INSTR_PAGE_FAULT;
|
||||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, update_vaddr};
|
||||
icache_areq_o.fetch_exception.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, update_vaddr};
|
||||
end //to check on wave
|
||||
// TODO(moschn,zarubaf): What should the value of tval be in this case?
|
||||
else begin
|
||||
icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT;
|
||||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn) icache_areq_o.fetch_exception.tval = ptw_bad_paddr[riscv::PLEN-1:2];
|
||||
if (CVA6Cfg.TvalEn) icache_areq_o.fetch_exception.tval = ptw_bad_paddr[CVA6Cfg.PLEN-1:2];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -372,20 +367,20 @@ module cva6_mmu_sv32
|
|||
icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT;
|
||||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = icache_areq_o.fetch_paddr[riscv::PLEN-1:2];
|
||||
icache_areq_o.fetch_exception.tval = icache_areq_o.fetch_paddr[CVA6Cfg.PLEN-1:2];
|
||||
//to check on wave --> not connected
|
||||
end
|
||||
end
|
||||
|
||||
// check for execute flag on memory
|
||||
assign match_any_execute_region = config_pkg::is_inside_execute_regions(
|
||||
CVA6Cfg, {{64 - riscv::PLEN{1'b0}}, icache_areq_o.fetch_paddr}
|
||||
CVA6Cfg, {{64 - CVA6Cfg.PLEN{1'b0}}, icache_areq_o.fetch_paddr}
|
||||
);
|
||||
|
||||
// Instruction fetch
|
||||
pmp #(
|
||||
.PLEN (riscv::PLEN),
|
||||
.PMP_LEN (riscv::PLEN - 2),
|
||||
.PLEN (CVA6Cfg.PLEN),
|
||||
.PMP_LEN (CVA6Cfg.PLEN - 2),
|
||||
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
|
||||
) i_pmp_if (
|
||||
.addr_i (icache_areq_o.fetch_paddr),
|
||||
|
@ -401,7 +396,7 @@ module cva6_mmu_sv32
|
|||
//-----------------------
|
||||
// Data Interface
|
||||
//-----------------------
|
||||
logic [riscv::VLEN-1:0] lsu_vaddr_n, lsu_vaddr_q;
|
||||
logic [CVA6Cfg.VLEN-1:0] lsu_vaddr_n, lsu_vaddr_q;
|
||||
riscv::pte_sv32_t dtlb_pte_n, dtlb_pte_q;
|
||||
exception_t misaligned_ex_n, misaligned_ex_q;
|
||||
logic lsu_req_n, lsu_req_q;
|
||||
|
@ -427,11 +422,11 @@ module cva6_mmu_sv32
|
|||
lsu_is_store_n = lsu_is_store_i;
|
||||
dtlb_is_4M_n = dtlb_is_4M;
|
||||
|
||||
if (riscv::PLEN > riscv::VLEN) begin
|
||||
lsu_paddr_o = {{riscv::PLEN - riscv::VLEN{1'b0}}, lsu_vaddr_q};
|
||||
lsu_dtlb_ppn_o = {{riscv::PLEN - riscv::VLEN{1'b0}}, lsu_vaddr_n[riscv::VLEN-1:12]};
|
||||
if (CVA6Cfg.PLEN > CVA6Cfg.VLEN) begin
|
||||
lsu_paddr_o = {{CVA6Cfg.PLEN - CVA6Cfg.VLEN{1'b0}}, lsu_vaddr_q};
|
||||
lsu_dtlb_ppn_o = {{CVA6Cfg.PLEN - CVA6Cfg.VLEN{1'b0}}, lsu_vaddr_n[CVA6Cfg.VLEN-1:12]};
|
||||
end else begin
|
||||
lsu_paddr_o = {2'b00, lsu_vaddr_q[riscv::VLEN-1:0]};
|
||||
lsu_paddr_o = {2'b00, lsu_vaddr_q[CVA6Cfg.VLEN-1:0]};
|
||||
lsu_dtlb_ppn_o = lsu_vaddr_n[CVA6Cfg.PPNW-1:0];
|
||||
end
|
||||
lsu_valid_o = lsu_req_q;
|
||||
|
@ -475,14 +470,14 @@ module cva6_mmu_sv32
|
|||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, lsu_vaddr_q
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q
|
||||
};
|
||||
// to check on wave
|
||||
// Check if any PMPs are violated
|
||||
end else if (!pmp_data_allow) begin
|
||||
lsu_exception_o.cause = riscv::ST_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = lsu_paddr_o[riscv::PLEN-1:2];
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = lsu_paddr_o[CVA6Cfg.PLEN-1:2];
|
||||
//only 32 bits on 34b of lsu_paddr_o are returned.
|
||||
end
|
||||
|
||||
|
@ -494,13 +489,13 @@ module cva6_mmu_sv32
|
|||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, lsu_vaddr_q
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q
|
||||
};
|
||||
// Check if any PMPs are violated
|
||||
end else if (!pmp_data_allow) begin
|
||||
lsu_exception_o.cause = riscv::LD_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = lsu_paddr_o[riscv::PLEN-1:2];
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = lsu_paddr_o[CVA6Cfg.PLEN-1:2];
|
||||
end
|
||||
end
|
||||
end else
|
||||
|
@ -520,14 +515,14 @@ module cva6_mmu_sv32
|
|||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, update_vaddr
|
||||
};
|
||||
end else begin
|
||||
lsu_exception_o.cause = riscv::LOAD_PAGE_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, update_vaddr
|
||||
};
|
||||
end
|
||||
end
|
||||
|
@ -538,7 +533,7 @@ module cva6_mmu_sv32
|
|||
// the page table walker can only throw page faults
|
||||
lsu_exception_o.cause = riscv::LD_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = ptw_bad_paddr[riscv::PLEN-1:2];
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = ptw_bad_paddr[CVA6Cfg.PLEN-1:2];
|
||||
end
|
||||
end
|
||||
end // If translation is not enabled, check the paddr immediately against PMPs
|
||||
|
@ -546,19 +541,19 @@ module cva6_mmu_sv32
|
|||
if (lsu_is_store_q) begin
|
||||
lsu_exception_o.cause = riscv::ST_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = lsu_paddr_o[riscv::PLEN-1:2];
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = lsu_paddr_o[CVA6Cfg.PLEN-1:2];
|
||||
end else begin
|
||||
lsu_exception_o.cause = riscv::LD_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = lsu_paddr_o[riscv::PLEN-1:2];
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = lsu_paddr_o[CVA6Cfg.PLEN-1:2];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Load/store PMP check
|
||||
pmp #(
|
||||
.PLEN (riscv::PLEN),
|
||||
.PMP_LEN (riscv::PLEN - 2),
|
||||
.PLEN (CVA6Cfg.PLEN),
|
||||
.PMP_LEN (CVA6Cfg.PLEN - 2),
|
||||
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
|
||||
) i_pmp_data (
|
||||
.addr_i (lsu_paddr_o),
|
||||
|
|
|
@ -31,8 +31,7 @@ module cva6_ptw_sv32
|
|||
#(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter type dcache_req_i_t = logic,
|
||||
parameter type dcache_req_o_t = logic,
|
||||
parameter int ASID_WIDTH = 1
|
||||
parameter type dcache_req_o_t = logic
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -52,14 +51,14 @@ module cva6_ptw_sv32
|
|||
// to Shared TLB, update logic
|
||||
output tlb_update_sv32_t shared_tlb_update_o,
|
||||
|
||||
output logic [riscv::VLEN-1:0] update_vaddr_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] update_vaddr_o,
|
||||
|
||||
input logic [ASID_WIDTH-1:0] asid_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_i,
|
||||
|
||||
// from shared TLB
|
||||
input logic shared_tlb_access_i,
|
||||
input logic shared_tlb_hit_i,
|
||||
input logic [riscv::VLEN-1:0] shared_tlb_vaddr_i,
|
||||
input logic shared_tlb_access_i,
|
||||
input logic shared_tlb_hit_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] shared_tlb_vaddr_i,
|
||||
|
||||
input logic itlb_req_i,
|
||||
|
||||
|
@ -72,8 +71,8 @@ module cva6_ptw_sv32
|
|||
|
||||
// PMP
|
||||
input riscv::pmpcfg_t [15:0] pmpcfg_i,
|
||||
input logic [15:0][riscv::PLEN-3:0] pmpaddr_i,
|
||||
output logic [riscv::PLEN-1:0] bad_paddr_o
|
||||
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
output logic [CVA6Cfg.PLEN-1:0] bad_paddr_o
|
||||
|
||||
);
|
||||
|
||||
|
@ -109,11 +108,11 @@ module cva6_ptw_sv32
|
|||
// latched tag signal
|
||||
logic tag_valid_n, tag_valid_q;
|
||||
// register the ASID
|
||||
logic [ASID_WIDTH-1:0] tlb_update_asid_q, tlb_update_asid_n;
|
||||
logic [CVA6Cfg.ASID_WIDTH-1:0] tlb_update_asid_q, tlb_update_asid_n;
|
||||
// register the VPN we need to walk, SV32 defines a 32 bit virtual address
|
||||
logic [riscv::VLEN-1:0] vaddr_q, vaddr_n;
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddr_q, vaddr_n;
|
||||
// 4 byte aligned physical pointer
|
||||
logic [riscv::PLEN-1:0] ptw_pptr_q, ptw_pptr_n;
|
||||
logic [CVA6Cfg.PLEN-1:0] ptw_pptr_q, ptw_pptr_n;
|
||||
|
||||
// Assignments
|
||||
assign update_vaddr_o = vaddr_q;
|
||||
|
@ -151,8 +150,8 @@ module cva6_ptw_sv32
|
|||
|
||||
pmp #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.PLEN (riscv::PLEN),
|
||||
.PMP_LEN (riscv::PLEN - 2),
|
||||
.PLEN (CVA6Cfg.PLEN),
|
||||
.PMP_LEN (CVA6Cfg.PLEN - 2),
|
||||
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
|
||||
) i_pmp_ptw (
|
||||
.addr_i (ptw_pptr_q),
|
||||
|
|
|
@ -22,8 +22,7 @@ module cva6_shared_tlb_sv32
|
|||
#(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter int SHARED_TLB_DEPTH = 64,
|
||||
parameter int SHARED_TLB_WAYS = 2,
|
||||
parameter int ASID_WIDTH = 1
|
||||
parameter int SHARED_TLB_WAYS = 2
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -32,17 +31,17 @@ module cva6_shared_tlb_sv32
|
|||
input logic enable_translation_i, // CSRs indicate to enable SV32
|
||||
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
|
||||
|
||||
input logic [ASID_WIDTH-1:0] asid_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_i,
|
||||
|
||||
// from TLBs
|
||||
// did we miss?
|
||||
input logic itlb_access_i,
|
||||
input logic itlb_hit_i,
|
||||
input logic [riscv::VLEN-1:0] itlb_vaddr_i,
|
||||
input logic itlb_access_i,
|
||||
input logic itlb_hit_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] itlb_vaddr_i,
|
||||
|
||||
input logic dtlb_access_i,
|
||||
input logic dtlb_hit_i,
|
||||
input logic [riscv::VLEN-1:0] dtlb_vaddr_i,
|
||||
input logic dtlb_access_i,
|
||||
input logic dtlb_hit_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] dtlb_vaddr_i,
|
||||
|
||||
// to TLBs, update logic
|
||||
output tlb_update_sv32_t itlb_update_o,
|
||||
|
@ -52,9 +51,9 @@ module cva6_shared_tlb_sv32
|
|||
output logic itlb_miss_o,
|
||||
output logic dtlb_miss_o,
|
||||
|
||||
output logic shared_tlb_access_o,
|
||||
output logic shared_tlb_hit_o,
|
||||
output logic [riscv::VLEN-1:0] shared_tlb_vaddr_o,
|
||||
output logic shared_tlb_access_o,
|
||||
output logic shared_tlb_hit_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] shared_tlb_vaddr_o,
|
||||
|
||||
output logic itlb_req_o,
|
||||
|
||||
|
@ -113,14 +112,14 @@ module cva6_shared_tlb_sv32
|
|||
|
||||
riscv::pte_sv32_t [SHARED_TLB_WAYS-1:0] pte;
|
||||
|
||||
logic [riscv::VLEN-1-12:0] itlb_vpn_q;
|
||||
logic [riscv::VLEN-1-12:0] dtlb_vpn_q;
|
||||
logic [CVA6Cfg.VLEN-1-12:0] itlb_vpn_q;
|
||||
logic [CVA6Cfg.VLEN-1-12:0] dtlb_vpn_q;
|
||||
|
||||
logic [ASID_WIDTH-1:0] tlb_update_asid_q, tlb_update_asid_d;
|
||||
logic [CVA6Cfg.ASID_WIDTH-1:0] tlb_update_asid_q, tlb_update_asid_d;
|
||||
|
||||
logic shared_tlb_access_q, shared_tlb_access_d;
|
||||
logic shared_tlb_hit_d;
|
||||
logic [riscv::VLEN-1:0] shared_tlb_vaddr_q, shared_tlb_vaddr_d;
|
||||
logic [CVA6Cfg.VLEN-1:0] shared_tlb_vaddr_q, shared_tlb_vaddr_d;
|
||||
|
||||
logic itlb_req_d, itlb_req_q;
|
||||
logic dtlb_req_d, dtlb_req_q;
|
||||
|
|
|
@ -28,8 +28,7 @@ module cva6_tlb_sv32
|
|||
import ariane_pkg::*;
|
||||
#(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter int unsigned TLB_ENTRIES = 4,
|
||||
parameter int unsigned ASID_WIDTH = 1
|
||||
parameter int unsigned TLB_ENTRIES = 4
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -38,11 +37,11 @@ module cva6_tlb_sv32
|
|||
input tlb_update_sv32_t update_i,
|
||||
// Lookup signals
|
||||
input logic lu_access_i,
|
||||
input logic [ASID_WIDTH-1:0] lu_asid_i,
|
||||
input logic [riscv::VLEN-1:0] lu_vaddr_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] lu_asid_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] lu_vaddr_i,
|
||||
output riscv::pte_sv32_t lu_content_o,
|
||||
input logic [ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
output logic lu_is_4M_o,
|
||||
output logic lu_hit_o
|
||||
);
|
||||
|
@ -78,7 +77,7 @@ module cva6_tlb_sv32
|
|||
for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin
|
||||
// first level match, this may be a mega page, check the ASID flags as well
|
||||
// if the entry is associated to a global address, don't match the ASID (ASID is don't care)
|
||||
if (tags_q[i].valid && ((lu_asid_i == tags_q[i].asid[ASID_WIDTH-1:0]) || content_q[i].g) && vpn1 == tags_q[i].vpn1) begin
|
||||
if (tags_q[i].valid && ((lu_asid_i == tags_q[i].asid[CVA6Cfg.ASID_WIDTH-1:0]) || content_q[i].g) && vpn1 == tags_q[i].vpn1) begin
|
||||
if (tags_q[i].is_4M || vpn0 == tags_q[i].vpn0) begin
|
||||
lu_is_4M_o = tags_q[i].is_4M;
|
||||
lu_content_o = content_q[i];
|
||||
|
@ -118,10 +117,10 @@ module cva6_tlb_sv32
|
|||
else if (asid_to_be_flushed_is0 && ( (vaddr_vpn0_match[i] && vaddr_vpn1_match[i]) || (vaddr_vpn1_match[i] && tags_q[i].is_4M) ) && (~vaddr_to_be_flushed_is0))
|
||||
tags_n[i].valid = 1'b0;
|
||||
// the entry is flushed if it's not global and asid and vaddr both matches with the entry to be flushed ("SFENCE.VMA vaddr asid" case)
|
||||
else if ((!content_q[i].g) && ((vaddr_vpn0_match[i] && vaddr_vpn1_match[i]) || (vaddr_vpn1_match[i] && tags_q[i].is_4M)) && (asid_to_be_flushed_i == tags_q[i].asid[ASID_WIDTH-1:0]) && (!vaddr_to_be_flushed_is0) && (!asid_to_be_flushed_is0))
|
||||
else if ((!content_q[i].g) && ((vaddr_vpn0_match[i] && vaddr_vpn1_match[i]) || (vaddr_vpn1_match[i] && tags_q[i].is_4M)) && (asid_to_be_flushed_i == tags_q[i].asid[CVA6Cfg.ASID_WIDTH-1:0]) && (!vaddr_to_be_flushed_is0) && (!asid_to_be_flushed_is0))
|
||||
tags_n[i].valid = 1'b0;
|
||||
// the entry is flushed if it's not global, and the asid matches and vaddr is 0. ("SFENCE.VMA 0 asid" case)
|
||||
else if ((!content_q[i].g) && (vaddr_to_be_flushed_is0) && (asid_to_be_flushed_i == tags_q[i].asid[ASID_WIDTH-1:0]) && (!asid_to_be_flushed_is0))
|
||||
else if ((!content_q[i].g) && (vaddr_to_be_flushed_is0) && (asid_to_be_flushed_i == tags_q[i].asid[CVA6Cfg.ASID_WIDTH-1:0]) && (!asid_to_be_flushed_is0))
|
||||
tags_n[i].valid = 1'b0;
|
||||
// normal replacement
|
||||
end else if (update_i.valid & replace_en[i]) begin
|
||||
|
@ -248,7 +247,7 @@ module cva6_tlb_sv32
|
|||
$error("TLB size must be a multiple of 2 and greater than 1");
|
||||
$stop();
|
||||
end
|
||||
assert (ASID_WIDTH >= 1)
|
||||
assert (CVA6Cfg.ASID_WIDTH >= 1)
|
||||
else begin
|
||||
$error("ASID width must be at least 1");
|
||||
$stop();
|
||||
|
|
|
@ -27,8 +27,7 @@ module mmu
|
|||
parameter type dcache_req_o_t = logic,
|
||||
parameter type exception_t = logic,
|
||||
parameter int unsigned INSTR_TLB_ENTRIES = 4,
|
||||
parameter int unsigned DATA_TLB_ENTRIES = 4,
|
||||
parameter int unsigned ASID_WIDTH = 1
|
||||
parameter int unsigned DATA_TLB_ENTRIES = 4
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -43,7 +42,7 @@ module mmu
|
|||
// in the LSU as we distinguish load and stores, what we do here is simple address translation
|
||||
input exception_t misaligned_ex_i,
|
||||
input logic lsu_req_i, // request address translation
|
||||
input logic [riscv::VLEN-1:0] lsu_vaddr_i, // virtual address in
|
||||
input logic [CVA6Cfg.VLEN-1:0] lsu_vaddr_i, // virtual address in
|
||||
input logic lsu_is_store_i, // the translation is requested by a store
|
||||
// if we need to walk the page table we can't grant in the same cycle
|
||||
// Cycle 0
|
||||
|
@ -51,7 +50,7 @@ module mmu
|
|||
output logic [CVA6Cfg.PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit)
|
||||
// Cycle 1
|
||||
output logic lsu_valid_o, // translation is valid
|
||||
output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address
|
||||
output logic [CVA6Cfg.PLEN-1:0] lsu_paddr_o, // translated address
|
||||
output exception_t lsu_exception_o, // address translation threw an exception
|
||||
// General control signals
|
||||
input riscv::priv_lvl_t priv_lvl_i,
|
||||
|
@ -60,9 +59,9 @@ module mmu
|
|||
input logic mxr_i,
|
||||
// input logic flag_mprv_i,
|
||||
input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i,
|
||||
input logic [ASID_WIDTH-1:0] asid_i,
|
||||
input logic [ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
input logic flush_tlb_i,
|
||||
// Performance counters
|
||||
output logic itlb_miss_o,
|
||||
|
@ -72,27 +71,27 @@ module mmu
|
|||
output dcache_req_i_t req_port_o,
|
||||
// PMP
|
||||
input riscv::pmpcfg_t [15:0] pmpcfg_i,
|
||||
input logic [15:0][riscv::PLEN-3:0] pmpaddr_i
|
||||
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i
|
||||
);
|
||||
|
||||
localparam type tlb_update_t = struct packed {
|
||||
logic valid; // valid flag
|
||||
logic is_2M; //
|
||||
logic is_1G; //
|
||||
logic [27-1:0] vpn; // VPN (39bits) = 27bits + 12bits offset
|
||||
logic [ASID_WIDTH-1:0] asid;
|
||||
riscv::pte_t content;
|
||||
logic valid; // valid flag
|
||||
logic is_2M; //
|
||||
logic is_1G; //
|
||||
logic [27-1:0] vpn; // VPN (39bits) = 27bits + 12bits offset
|
||||
logic [CVA6Cfg.ASID_WIDTH-1:0] asid;
|
||||
riscv::pte_t content;
|
||||
};
|
||||
|
||||
logic iaccess_err; // insufficient privilege to access this instruction page
|
||||
logic daccess_err; // insufficient privilege to access this data page
|
||||
logic ptw_active; // PTW is currently walking a page table
|
||||
logic walking_instr; // PTW is walking because of an ITLB miss
|
||||
logic ptw_error; // PTW threw an exception
|
||||
logic ptw_access_exception; // PTW threw an access exception (PMPs)
|
||||
logic [riscv::PLEN-1:0] ptw_bad_paddr; // PTW PMP exception bad physical addr
|
||||
logic iaccess_err; // insufficient privilege to access this instruction page
|
||||
logic daccess_err; // insufficient privilege to access this data page
|
||||
logic ptw_active; // PTW is currently walking a page table
|
||||
logic walking_instr; // PTW is walking because of an ITLB miss
|
||||
logic ptw_error; // PTW threw an exception
|
||||
logic ptw_access_exception; // PTW threw an access exception (PMPs)
|
||||
logic [CVA6Cfg.PLEN-1:0] ptw_bad_paddr; // PTW PMP exception bad physical addr
|
||||
|
||||
logic [riscv::VLEN-1:0] update_vaddr;
|
||||
logic [CVA6Cfg.VLEN-1:0] update_vaddr;
|
||||
tlb_update_t update_ptw_itlb, update_ptw_dtlb;
|
||||
|
||||
logic itlb_lu_access;
|
||||
|
@ -116,8 +115,7 @@ module mmu
|
|||
tlb #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.tlb_update_t(tlb_update_t),
|
||||
.TLB_ENTRIES (INSTR_TLB_ENTRIES),
|
||||
.ASID_WIDTH (ASID_WIDTH)
|
||||
.TLB_ENTRIES (INSTR_TLB_ENTRIES)
|
||||
) i_itlb (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -140,8 +138,7 @@ module mmu
|
|||
tlb #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.tlb_update_t(tlb_update_t),
|
||||
.TLB_ENTRIES (DATA_TLB_ENTRIES),
|
||||
.ASID_WIDTH (ASID_WIDTH)
|
||||
.TLB_ENTRIES (DATA_TLB_ENTRIES)
|
||||
) i_dtlb (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -166,8 +163,7 @@ module mmu
|
|||
.CVA6Cfg (CVA6Cfg),
|
||||
.dcache_req_i_t(dcache_req_i_t),
|
||||
.dcache_req_o_t(dcache_req_o_t),
|
||||
.tlb_update_t(tlb_update_t),
|
||||
.ASID_WIDTH(ASID_WIDTH)
|
||||
.tlb_update_t(tlb_update_t)
|
||||
) i_ptw (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -226,7 +222,7 @@ module mmu
|
|||
always_comb begin : instr_interface
|
||||
// MMU disabled: just pass through
|
||||
icache_areq_o.fetch_valid = icache_areq_i.fetch_req;
|
||||
icache_areq_o.fetch_paddr = icache_areq_i.fetch_vaddr[riscv::PLEN-1:0]; // play through in case we disabled address translation
|
||||
icache_areq_o.fetch_paddr = icache_areq_i.fetch_vaddr[CVA6Cfg.PLEN-1:0]; // play through in case we disabled address translation
|
||||
// two potential exception sources:
|
||||
// 1. HPTW threw an exception -> signal with a page fault exception
|
||||
// 2. We got an access error because of insufficient permissions -> throw an access exception
|
||||
|
@ -241,13 +237,13 @@ module mmu
|
|||
// AXI decode error), or when PTW performs walk due to ITLB miss and raises
|
||||
// an error.
|
||||
if (enable_translation_i) begin
|
||||
// we work with SV39 or SV32, so if VM is enabled, check that all bits [riscv::VLEN-1:CVA6Cfg.SV-1] are equal
|
||||
if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[riscv::VLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[riscv::VLEN-1:CVA6Cfg.SV-1]) == 1'b0)) begin
|
||||
// we work with SV39 or SV32, so if VM is enabled, check that all bits [CVA6Cfg.VLEN-1:CVA6Cfg.SV-1] are equal
|
||||
if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[CVA6Cfg.VLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[CVA6Cfg.VLEN-1:CVA6Cfg.SV-1]) == 1'b0)) begin
|
||||
icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT;
|
||||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
};
|
||||
end
|
||||
|
||||
|
@ -277,14 +273,14 @@ module mmu
|
|||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
};
|
||||
end else if (!pmp_instr_allow) begin
|
||||
icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT;
|
||||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, icache_areq_i.fetch_vaddr
|
||||
};
|
||||
end
|
||||
end else
|
||||
|
@ -298,12 +294,12 @@ module mmu
|
|||
icache_areq_o.fetch_exception.cause = riscv::INSTR_PAGE_FAULT;
|
||||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, update_vaddr};
|
||||
icache_areq_o.fetch_exception.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, update_vaddr};
|
||||
end else begin
|
||||
icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT;
|
||||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, update_vaddr};
|
||||
icache_areq_o.fetch_exception.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, update_vaddr};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -314,21 +310,21 @@ module mmu
|
|||
icache_areq_o.fetch_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
icache_areq_o.fetch_exception.tval = {
|
||||
{riscv::XLEN - riscv::PLEN{1'b0}}, icache_areq_o.fetch_paddr
|
||||
{riscv::XLEN - CVA6Cfg.PLEN{1'b0}}, icache_areq_o.fetch_paddr
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
// check for execute flag on memory
|
||||
assign match_any_execute_region = config_pkg::is_inside_execute_regions(
|
||||
CVA6Cfg, {{64 - riscv::PLEN{1'b0}}, icache_areq_o.fetch_paddr}
|
||||
CVA6Cfg, {{64 - CVA6Cfg.PLEN{1'b0}}, icache_areq_o.fetch_paddr}
|
||||
);
|
||||
|
||||
// Instruction fetch
|
||||
pmp #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.PLEN (riscv::PLEN),
|
||||
.PMP_LEN (riscv::PLEN - 2),
|
||||
.PLEN (CVA6Cfg.PLEN),
|
||||
.PMP_LEN (CVA6Cfg.PLEN - 2),
|
||||
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
|
||||
) i_pmp_if (
|
||||
.addr_i (icache_areq_o.fetch_paddr),
|
||||
|
@ -344,7 +340,7 @@ module mmu
|
|||
//-----------------------
|
||||
// Data Interface
|
||||
//-----------------------
|
||||
logic [riscv::VLEN-1:0] lsu_vaddr_n, lsu_vaddr_q;
|
||||
logic [CVA6Cfg.VLEN-1:0] lsu_vaddr_n, lsu_vaddr_q;
|
||||
riscv::pte_t dtlb_pte_n, dtlb_pte_q;
|
||||
exception_t misaligned_ex_n, misaligned_ex_q;
|
||||
logic lsu_req_n, lsu_req_q;
|
||||
|
@ -372,8 +368,8 @@ module mmu
|
|||
dtlb_is_2M_n = dtlb_is_2M;
|
||||
dtlb_is_1G_n = dtlb_is_1G;
|
||||
|
||||
lsu_paddr_o = lsu_vaddr_q[riscv::PLEN-1:0];
|
||||
lsu_dtlb_ppn_o = lsu_vaddr_n[riscv::PLEN-1:12];
|
||||
lsu_paddr_o = lsu_vaddr_q[CVA6Cfg.PLEN-1:0];
|
||||
lsu_dtlb_ppn_o = lsu_vaddr_n[CVA6Cfg.PLEN-1:12];
|
||||
lsu_valid_o = lsu_req_q;
|
||||
lsu_exception_o = misaligned_ex_q;
|
||||
pmp_access_type = lsu_is_store_q ? riscv::ACCESS_WRITE : riscv::ACCESS_READ;
|
||||
|
@ -420,7 +416,7 @@ module mmu
|
|||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, lsu_vaddr_q
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q
|
||||
};
|
||||
// Check if any PMPs are violated
|
||||
end else if (!pmp_data_allow) begin
|
||||
|
@ -428,7 +424,7 @@ module mmu
|
|||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, lsu_vaddr_q
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q
|
||||
};
|
||||
end
|
||||
|
||||
|
@ -440,7 +436,7 @@ module mmu
|
|||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, lsu_vaddr_q
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q
|
||||
};
|
||||
// Check if any PMPs are violated
|
||||
end else if (!pmp_data_allow) begin
|
||||
|
@ -448,7 +444,7 @@ module mmu
|
|||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, lsu_vaddr_q
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, lsu_vaddr_q
|
||||
};
|
||||
end
|
||||
end
|
||||
|
@ -469,14 +465,14 @@ module mmu
|
|||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, update_vaddr
|
||||
};
|
||||
end else begin
|
||||
lsu_exception_o.cause = riscv::LOAD_PAGE_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {
|
||||
{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr
|
||||
{riscv::XLEN - CVA6Cfg.VLEN{lsu_vaddr_q[CVA6Cfg.VLEN-1]}}, update_vaddr
|
||||
};
|
||||
end
|
||||
end
|
||||
|
@ -489,12 +485,12 @@ module mmu
|
|||
lsu_exception_o.cause = riscv::ST_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_vaddr_n};
|
||||
lsu_exception_o.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_vaddr_n};
|
||||
end else begin
|
||||
lsu_exception_o.cause = riscv::LD_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_vaddr_n};
|
||||
lsu_exception_o.tval = {{riscv::XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_vaddr_n};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -503,11 +499,13 @@ module mmu
|
|||
if (lsu_is_store_q) begin
|
||||
lsu_exception_o.cause = riscv::ST_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = {{riscv::XLEN - riscv::PLEN{1'b0}}, lsu_paddr_o};
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {{riscv::XLEN - CVA6Cfg.PLEN{1'b0}}, lsu_paddr_o};
|
||||
end else begin
|
||||
lsu_exception_o.cause = riscv::LD_ACCESS_FAULT;
|
||||
lsu_exception_o.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn) lsu_exception_o.tval = {{riscv::XLEN - riscv::PLEN{1'b0}}, lsu_paddr_o};
|
||||
if (CVA6Cfg.TvalEn)
|
||||
lsu_exception_o.tval = {{riscv::XLEN - CVA6Cfg.PLEN{1'b0}}, lsu_paddr_o};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -515,8 +513,8 @@ module mmu
|
|||
// Load/store PMP check
|
||||
pmp #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.PLEN (riscv::PLEN),
|
||||
.PMP_LEN (riscv::PLEN - 2),
|
||||
.PLEN (CVA6Cfg.PLEN),
|
||||
.PMP_LEN (CVA6Cfg.PLEN - 2),
|
||||
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
|
||||
) i_pmp_data (
|
||||
.addr_i (lsu_paddr_o),
|
||||
|
|
|
@ -21,8 +21,7 @@ module ptw
|
|||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter type dcache_req_i_t = logic,
|
||||
parameter type dcache_req_o_t = logic,
|
||||
parameter type tlb_update_t = logic,
|
||||
parameter int ASID_WIDTH = 1
|
||||
parameter type tlb_update_t = logic
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -46,18 +45,18 @@ module ptw
|
|||
output tlb_update_t itlb_update_o,
|
||||
output tlb_update_t dtlb_update_o,
|
||||
|
||||
output logic [riscv::VLEN-1:0] update_vaddr_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] update_vaddr_o,
|
||||
|
||||
input logic [ ASID_WIDTH-1:0] asid_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_i,
|
||||
// from TLBs
|
||||
// did we miss?
|
||||
input logic itlb_access_i,
|
||||
input logic itlb_hit_i,
|
||||
input logic [riscv::VLEN-1:0] itlb_vaddr_i,
|
||||
input logic itlb_access_i,
|
||||
input logic itlb_hit_i,
|
||||
input logic [ CVA6Cfg.VLEN-1:0] itlb_vaddr_i,
|
||||
|
||||
input logic dtlb_access_i,
|
||||
input logic dtlb_hit_i,
|
||||
input logic [ riscv::VLEN-1:0] dtlb_vaddr_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] dtlb_vaddr_i,
|
||||
// from CSR file
|
||||
input logic [CVA6Cfg.PPNW-1:0] satp_ppn_i, // ppn from satp
|
||||
input logic mxr_i,
|
||||
|
@ -67,8 +66,8 @@ module ptw
|
|||
// PMP
|
||||
|
||||
input riscv::pmpcfg_t [15:0] pmpcfg_i,
|
||||
input logic [15:0][riscv::PLEN-3:0] pmpaddr_i,
|
||||
output logic [riscv::PLEN-1:0] bad_paddr_o
|
||||
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
output logic [CVA6Cfg.PLEN-1:0] bad_paddr_o
|
||||
|
||||
);
|
||||
|
||||
|
@ -103,11 +102,11 @@ module ptw
|
|||
// latched tag signal
|
||||
logic tag_valid_n, tag_valid_q;
|
||||
// register the ASID
|
||||
logic [ASID_WIDTH-1:0] tlb_update_asid_q, tlb_update_asid_n;
|
||||
logic [CVA6Cfg.ASID_WIDTH-1:0] tlb_update_asid_q, tlb_update_asid_n;
|
||||
// register the VPN we need to walk, SV39 defines a 39 bit virtual address
|
||||
logic [riscv::VLEN-1:0] vaddr_q, vaddr_n;
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddr_q, vaddr_n;
|
||||
// 4 byte aligned physical pointer
|
||||
logic [riscv::PLEN-1:0] ptw_pptr_q, ptw_pptr_n;
|
||||
logic [CVA6Cfg.PLEN-1:0] ptw_pptr_q, ptw_pptr_n;
|
||||
|
||||
// Assignments
|
||||
assign update_vaddr_o = vaddr_q;
|
||||
|
@ -148,8 +147,8 @@ module ptw
|
|||
|
||||
pmp #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.PLEN (riscv::PLEN),
|
||||
.PMP_LEN (riscv::PLEN - 2),
|
||||
.PLEN (CVA6Cfg.PLEN),
|
||||
.PMP_LEN (CVA6Cfg.PLEN - 2),
|
||||
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
|
||||
) i_pmp_ptw (
|
||||
.addr_i (ptw_pptr_q),
|
||||
|
|
|
@ -20,37 +20,36 @@ module tlb
|
|||
#(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter type tlb_update_t = logic,
|
||||
parameter int unsigned TLB_ENTRIES = 4,
|
||||
parameter int unsigned ASID_WIDTH = 1
|
||||
parameter int unsigned TLB_ENTRIES = 4
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic flush_i, // Flush signal
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic flush_i, // Flush signal
|
||||
// Update TLB
|
||||
input tlb_update_t update_i,
|
||||
input tlb_update_t update_i,
|
||||
// Lookup signals
|
||||
input logic lu_access_i,
|
||||
input logic [ ASID_WIDTH-1:0] lu_asid_i,
|
||||
input logic [riscv::VLEN-1:0] lu_vaddr_i,
|
||||
output riscv::pte_t lu_content_o,
|
||||
input logic [ ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
output logic lu_is_2M_o,
|
||||
output logic lu_is_1G_o,
|
||||
output logic lu_hit_o
|
||||
input logic lu_access_i,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] lu_asid_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] lu_vaddr_i,
|
||||
output riscv::pte_t lu_content_o,
|
||||
input logic [CVA6Cfg.ASID_WIDTH-1:0] asid_to_be_flushed_i,
|
||||
input logic [CVA6Cfg.VLEN-1:0] vaddr_to_be_flushed_i,
|
||||
output logic lu_is_2M_o,
|
||||
output logic lu_is_1G_o,
|
||||
output logic lu_hit_o
|
||||
);
|
||||
|
||||
localparam VPN2 = (riscv::VLEN - 31 < 8) ? riscv::VLEN - 31 : 8;
|
||||
localparam VPN2 = (CVA6Cfg.VLEN - 31 < 8) ? CVA6Cfg.VLEN - 31 : 8;
|
||||
|
||||
// SV39 defines three levels of page tables
|
||||
struct packed {
|
||||
logic [ASID_WIDTH-1:0] asid;
|
||||
logic [VPN2:0] vpn2;
|
||||
logic [8:0] vpn1;
|
||||
logic [8:0] vpn0;
|
||||
logic is_2M;
|
||||
logic is_1G;
|
||||
logic valid;
|
||||
logic [CVA6Cfg.ASID_WIDTH-1:0] asid;
|
||||
logic [VPN2:0] vpn2;
|
||||
logic [8:0] vpn1;
|
||||
logic [8:0] vpn0;
|
||||
logic is_2M;
|
||||
logic is_1G;
|
||||
logic valid;
|
||||
} [TLB_ENTRIES-1:0]
|
||||
tags_q, tags_n;
|
||||
|
||||
|
@ -260,7 +259,7 @@ module tlb
|
|||
$error("TLB size must be a multiple of 2 and greater than 1");
|
||||
$stop();
|
||||
end
|
||||
assert (ASID_WIDTH >= 1)
|
||||
assert (CVA6Cfg.ASID_WIDTH >= 1)
|
||||
else begin
|
||||
$error("ASID width must be at least 1");
|
||||
$stop();
|
||||
|
|
|
@ -99,7 +99,7 @@ module mult
|
|||
// we've go a new division operation
|
||||
if (mult_valid_i && fu_data_i.operation inside {DIV, DIVU, DIVW, DIVUW, REM, REMU, REMW, REMUW}) begin
|
||||
// is this a word operation?
|
||||
if (riscv::IS_XLEN64 && (fu_data_i.operation == DIVW || fu_data_i.operation == DIVUW || fu_data_i.operation == REMW || fu_data_i.operation == REMUW)) begin
|
||||
if (CVA6Cfg.IS_XLEN64 && (fu_data_i.operation == DIVW || fu_data_i.operation == DIVUW || fu_data_i.operation == REMW || fu_data_i.operation == REMUW)) begin
|
||||
// yes so check if we should sign extend this is only done for a signed operation
|
||||
if (div_signed) begin
|
||||
operand_a = sext32(CVA6Cfg, fu_data_i.operand_a[31:0]);
|
||||
|
@ -144,7 +144,7 @@ module mult
|
|||
|
||||
// Result multiplexer
|
||||
// if it was a signed word operation the bit will be set and the result will be sign extended accordingly
|
||||
assign div_result = (riscv::IS_XLEN64 && word_op_q) ? sext32(CVA6Cfg, result) : result;
|
||||
assign div_result = (CVA6Cfg.IS_XLEN64 && word_op_q) ? sext32(CVA6Cfg, result) : result;
|
||||
|
||||
// ---------------------
|
||||
// Registers
|
||||
|
|
|
@ -132,7 +132,8 @@ module multiplier
|
|||
CLMULR: result_o = clmulr_q;
|
||||
// MUL performs an XLEN-bit×XLEN-bit multiplication and places the lower XLEN bits in the destination register
|
||||
default: begin
|
||||
if (operator_q == MULW && riscv::IS_XLEN64) result_o = sext32(CVA6Cfg, mult_result_q[31:0]);
|
||||
if (operator_q == MULW && CVA6Cfg.IS_XLEN64)
|
||||
result_o = sext32(CVA6Cfg, mult_result_q[31:0]);
|
||||
else result_o = mult_result_q[riscv::XLEN-1:0]; // including MUL
|
||||
end
|
||||
endcase
|
||||
|
|
|
@ -40,8 +40,8 @@ module store_buffer
|
|||
input logic valid_i, // this is a valid store
|
||||
input logic valid_without_flush_i, // just tell if the address is valid which we are current putting and do not take any further action
|
||||
|
||||
input logic [riscv::PLEN-1:0] paddr_i, // physical address of store which needs to be placed in the queue
|
||||
output [riscv::PLEN-1:0] rvfi_mem_paddr_o,
|
||||
input logic [CVA6Cfg.PLEN-1:0] paddr_i, // physical address of store which needs to be placed in the queue
|
||||
output [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr_o,
|
||||
input logic [riscv::XLEN-1:0] data_i, // data which is placed in the queue
|
||||
input logic [(riscv::XLEN/8)-1:0] be_i, // byte enable in
|
||||
input logic [1:0] data_size_i, // type of request we are making (e.g.: bytes to write)
|
||||
|
@ -55,7 +55,7 @@ module store_buffer
|
|||
// 1. Speculative queue
|
||||
// 2. Commit queue which is non-speculative, e.g.: the store will definitely happen.
|
||||
struct packed {
|
||||
logic [riscv::PLEN-1:0] address;
|
||||
logic [CVA6Cfg.PLEN-1:0] address;
|
||||
logic [riscv::XLEN-1:0] data;
|
||||
logic [(riscv::XLEN/8)-1:0] be;
|
||||
logic [1:0] data_size;
|
||||
|
|
|
@ -57,11 +57,11 @@ module store_unit
|
|||
// Address translation request - TO_BE_COMPLETED
|
||||
output logic translation_req_o,
|
||||
// Virtual address - TO_BE_COMPLETED
|
||||
output logic [riscv::VLEN-1:0] vaddr_o,
|
||||
output logic [CVA6Cfg.VLEN-1:0] vaddr_o,
|
||||
// RVFI information - RVFI
|
||||
output [riscv::PLEN-1:0] rvfi_mem_paddr_o,
|
||||
output [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr_o,
|
||||
// Physical address - TO_BE_COMPLETED
|
||||
input logic [riscv::PLEN-1:0] paddr_i,
|
||||
input logic [CVA6Cfg.PLEN-1:0] paddr_i,
|
||||
// Exception raised before store - TO_BE_COMPLETED
|
||||
input exception_t ex_i,
|
||||
// Data TLB hit - lsu
|
||||
|
@ -83,7 +83,7 @@ module store_unit
|
|||
// align data to address e.g.: shift data to be naturally 64
|
||||
function automatic [riscv::XLEN-1:0] data_align(logic [2:0] addr, logic [63:0] data);
|
||||
// Set addr[2] to 1'b0 when 32bits
|
||||
logic [ 2:0] addr_tmp = {(addr[2] && riscv::IS_XLEN64), addr[1:0]};
|
||||
logic [ 2:0] addr_tmp = {(addr[2] && CVA6Cfg.IS_XLEN64), addr[1:0]};
|
||||
logic [63:0] data_tmp = {64{1'b0}};
|
||||
case (addr_tmp)
|
||||
3'b000: data_tmp[riscv::XLEN-1:0] = {data[riscv::XLEN-1:0]};
|
||||
|
|
|
@ -181,7 +181,7 @@ localparam AxiAddrWidth = 64;
|
|||
localparam AxiDataWidth = 64;
|
||||
localparam AxiIdWidthMaster = 4;
|
||||
localparam AxiIdWidthSlaves = AxiIdWidthMaster + $clog2(NBSlave); // 5
|
||||
localparam AxiUserWidth = ariane_pkg::AXI_USER_WIDTH;
|
||||
localparam AxiUserWidth = CVA6Cfg.AxiUserWidth;
|
||||
|
||||
`AXI_TYPEDEF_ALL(axi_slave,
|
||||
logic [ AxiAddrWidth-1:0],
|
||||
|
|
|
@ -33,7 +33,7 @@ module ariane import ariane_pkg::*; #(
|
|||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
// Core ID, Cluster ID and boot address are considered more or less static
|
||||
input logic [riscv::VLEN-1:0] boot_addr_i, // reset boot address
|
||||
input logic [CVA6Cfg.VLEN-1:0] boot_addr_i, // reset boot address
|
||||
input logic [riscv::XLEN-1:0] hart_id_i, // hart id in a multicore environment (reflected in a CSR)
|
||||
|
||||
// Interrupt inputs
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
module ariane_testharness #(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = build_config_pkg::build_config(cva6_config_pkg::cva6_cfg),
|
||||
//
|
||||
parameter int unsigned AXI_USER_WIDTH = ariane_pkg::AXI_USER_WIDTH,
|
||||
parameter int unsigned AXI_USER_EN = ariane_pkg::AXI_USER_EN,
|
||||
parameter int unsigned AXI_USER_WIDTH = CVA6Cfg.AxiUserWidth,
|
||||
parameter int unsigned AXI_USER_EN = CVA6Cfg.AXI_USER_EN,
|
||||
parameter int unsigned AXI_ADDRESS_WIDTH = 64,
|
||||
parameter int unsigned AXI_DATA_WIDTH = 64,
|
||||
parameter bit InclSimDTM = 1'b1,
|
||||
|
|
|
@ -23,7 +23,7 @@ module rvfi_tracer #(
|
|||
output logic[31:0] end_of_test_o
|
||||
);
|
||||
|
||||
logic[riscv::PLEN-1:0] TOHOST_ADDR;
|
||||
logic[CVA6Cfg.PLEN-1:0] TOHOST_ADDR;
|
||||
int f;
|
||||
int unsigned SIM_FINISH;
|
||||
initial begin
|
||||
|
@ -49,7 +49,7 @@ module rvfi_tracer #(
|
|||
always_ff @(posedge clk_i) begin
|
||||
end_of_test_q = (rst_ni && (end_of_test_d[0] == 1'b1)) ? end_of_test_d : 0;
|
||||
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
||||
pc64 = {{riscv::XLEN-riscv::VLEN{rvfi_i[i].pc_rdata[riscv::VLEN-1]}}, rvfi_i[i].pc_rdata};
|
||||
pc64 = {{riscv::XLEN-CVA6Cfg.VLEN{rvfi_i[i].pc_rdata[CVA6Cfg.VLEN-1]}}, rvfi_i[i].pc_rdata};
|
||||
// print the instruction information if the instruction is valid or a trap is taken
|
||||
if (rvfi_i[i].valid) begin
|
||||
// Instruction information
|
||||
|
|
|
@ -49,7 +49,6 @@ module uvmt_cva6_tb;
|
|||
rvfi_probes_instr_t instr;
|
||||
};
|
||||
|
||||
localparam AXI_USER_EN = ariane_pkg::AXI_USER_EN;
|
||||
localparam NUM_WORDS = 2**24;
|
||||
|
||||
// ENV (testbench) parameters
|
||||
|
@ -113,7 +112,7 @@ module uvmt_cva6_tb;
|
|||
.rvfi_probes_csr_t ( rvfi_probes_csr_t ),
|
||||
.rvfi_probes_t ( rvfi_probes_t ),
|
||||
//
|
||||
.AXI_USER_EN (AXI_USER_EN),
|
||||
.AXI_USER_EN (CVA6Cfg.AXI_USER_EN),
|
||||
.NUM_WORDS (NUM_WORDS)
|
||||
) cva6_dut_wrap (
|
||||
.clknrst_if(clknrst_if),
|
||||
|
|
Loading…
Add table
Reference in a new issue