Merge branch 'CHERI' into pdr32-tmp
and get it to build!
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013-2019 Bluespec, Inc. All Rights Reserved
|
||||
// Copyright (c) 2013-2020 Bluespec, Inc. All Rights Reserved
|
||||
|
||||
// ================================================================
|
||||
// ISA defs for UC Berkeley RISC V
|
||||
@@ -234,28 +234,28 @@ deriving (FShow, Bits);
|
||||
function Decoded_Instr fv_decode (Instr instr);
|
||||
return Decoded_Instr {opcode: instr_opcode (instr),
|
||||
|
||||
rd: instr_rd (instr),
|
||||
rs1: instr_rs1 (instr),
|
||||
rs2: instr_rs2 (instr),
|
||||
rs3: instr_rs3 (instr),
|
||||
csr: instr_csr (instr),
|
||||
rd: instr_rd (instr),
|
||||
rs1: instr_rs1 (instr),
|
||||
rs2: instr_rs2 (instr),
|
||||
rs3: instr_rs3 (instr),
|
||||
csr: instr_csr (instr),
|
||||
|
||||
funct3: instr_funct3 (instr),
|
||||
funct5: instr_funct5 (instr),
|
||||
funct7: instr_funct7 (instr),
|
||||
funct10: instr_funct10 (instr),
|
||||
funct3: instr_funct3 (instr),
|
||||
funct5: instr_funct5 (instr),
|
||||
funct7: instr_funct7 (instr),
|
||||
funct10: instr_funct10 (instr),
|
||||
|
||||
imm12_I: instr_I_imm12 (instr),
|
||||
imm12_S: instr_S_imm12 (instr),
|
||||
imm13_SB: instr_SB_imm13 (instr),
|
||||
imm20_U: instr_U_imm20 (instr),
|
||||
imm21_UJ: instr_UJ_imm21 (instr),
|
||||
imm12_I: instr_I_imm12 (instr),
|
||||
imm12_S: instr_S_imm12 (instr),
|
||||
imm13_SB: instr_SB_imm13 (instr),
|
||||
imm20_U: instr_U_imm20 (instr),
|
||||
imm21_UJ: instr_UJ_imm21 (instr),
|
||||
|
||||
pred: instr_pred (instr),
|
||||
succ: instr_succ (instr),
|
||||
pred: instr_pred (instr),
|
||||
succ: instr_succ (instr),
|
||||
|
||||
aqrl: instr_aqrl (instr)
|
||||
};
|
||||
aqrl: instr_aqrl (instr)
|
||||
};
|
||||
endfunction
|
||||
|
||||
// Decodes if we need to read the GPR register file. This step becomes necessary
|
||||
@@ -269,7 +269,7 @@ endfunction
|
||||
// if (di.opcode != op_FP) begin
|
||||
// return (tuple2 (False, True)); // Regular op with GPR read
|
||||
// end
|
||||
//
|
||||
//
|
||||
// // This is an FP operation. The following f5 values would work for F and
|
||||
// // D subsets
|
||||
// else begin
|
||||
@@ -361,13 +361,27 @@ RegName reg_s10 = 26; RegName reg_s11 = 27;
|
||||
|
||||
RegName reg_t3 = 28; RegName reg_t4 = 29; RegName reg_t5 = 30; RegName reg_t6 = 31;
|
||||
|
||||
// ----------------
|
||||
// Is 'r' a standard register for PC save/restore on call/return?
|
||||
// This function is used in branch-predictors for managing the return-address stack.
|
||||
|
||||
function Bool fn_reg_is_link (RegName r);
|
||||
return ((r == x1) || (r == x5));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
// Kinds of memory access (excluding AMOs)
|
||||
|
||||
typedef enum { Access_RWX_R, Access_RWX_W, Access_RWX_X } Access_RWX
|
||||
deriving (Eq, Bits, FShow);
|
||||
|
||||
// ================================================================
|
||||
// Data sizes for LOAD/STORE
|
||||
|
||||
typedef enum {BITS8,
|
||||
BITS16,
|
||||
BITS32,
|
||||
BITS64 // Even in RV32, to allow for Double (floating point)
|
||||
BITS16,
|
||||
BITS32,
|
||||
BITS64 // Even in RV32, to allow for Double (floating point)
|
||||
} Mem_Data_Size
|
||||
deriving (Eq, Bits, FShow);
|
||||
|
||||
@@ -429,23 +443,23 @@ deriving (FShow);
|
||||
instance Bits #(Fence_Ordering, 8);
|
||||
function Bit #(8) pack (Fence_Ordering fo);
|
||||
return {pack (fo.pi),
|
||||
pack (fo.po),
|
||||
pack (fo.pr),
|
||||
pack (fo.pw),
|
||||
pack (fo.si),
|
||||
pack (fo.so),
|
||||
pack (fo.sr),
|
||||
pack (fo.sw) };
|
||||
pack (fo.po),
|
||||
pack (fo.pr),
|
||||
pack (fo.pw),
|
||||
pack (fo.si),
|
||||
pack (fo.so),
|
||||
pack (fo.sr),
|
||||
pack (fo.sw) };
|
||||
endfunction
|
||||
function Fence_Ordering unpack (Bit #(8) b8);
|
||||
return Fence_Ordering {pi: unpack (b8 [7]),
|
||||
po: unpack (b8 [6]),
|
||||
pr: unpack (b8 [5]),
|
||||
pw: unpack (b8 [4]),
|
||||
si: unpack (b8 [3]),
|
||||
so: unpack (b8 [2]),
|
||||
sr: unpack (b8 [1]),
|
||||
sw: unpack (b8 [0]) };
|
||||
po: unpack (b8 [6]),
|
||||
pr: unpack (b8 [5]),
|
||||
pw: unpack (b8 [4]),
|
||||
si: unpack (b8 [3]),
|
||||
so: unpack (b8 [2]),
|
||||
sr: unpack (b8 [1]),
|
||||
sw: unpack (b8 [0]) };
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
@@ -599,10 +613,10 @@ Bit #(10) f10_REMUW = 10'b000_0001_111;
|
||||
|
||||
function Bool is_OP_32_MUL_DIV_REM (Bit #(10) f10);
|
||||
return ( (f10 == f10_MULW)
|
||||
|| (f10 == f10_DIVW)
|
||||
|| (f10 == f10_DIVUW)
|
||||
|| (f10 == f10_REMW)
|
||||
|| (f10 == f10_REMUW));
|
||||
|| (f10 == f10_DIVW)
|
||||
|| (f10 == f10_DIVUW)
|
||||
|| (f10 == f10_REMW)
|
||||
|| (f10 == f10_REMUW));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -788,15 +802,15 @@ endfunction
|
||||
|
||||
// Check if a rounding mode value in the FCSR.FRM is valid
|
||||
function Bool fv_fcsr_frm_valid (Bit #(3) frm);
|
||||
return ( (frm != 3'b101)
|
||||
return ( (frm != 3'b101)
|
||||
&& (frm != 3'b110)
|
||||
&& (frm != 3'b111)
|
||||
);
|
||||
endfunction
|
||||
endfunction
|
||||
|
||||
// Check if a rounding mode value in the instr is valid
|
||||
function Bool fv_inst_frm_valid (Bit #(3) frm);
|
||||
return ( (frm != 3'b101)
|
||||
return ( (frm != 3'b101)
|
||||
&& (frm != 3'b110)
|
||||
);
|
||||
endfunction
|
||||
@@ -827,12 +841,12 @@ function Bool fv_is_fp_instr_legal (
|
||||
return (f2 == f2_S); // Only SP is legal
|
||||
`endif
|
||||
else
|
||||
if ( (f7 == f7_FADD_S)
|
||||
|| (f7 == f7_FSUB_S)
|
||||
|| (f7 == f7_FMUL_S)
|
||||
if ( (f7 == f7_FADD_S)
|
||||
|| (f7 == f7_FSUB_S)
|
||||
|| (f7 == f7_FMUL_S)
|
||||
`ifdef ISA_FD_DIV
|
||||
|| (f7 == f7_FDIV_S)
|
||||
|| (f7 == f7_FSQRT_S)
|
||||
|| (f7 == f7_FDIV_S)
|
||||
|| (f7 == f7_FSQRT_S)
|
||||
`endif
|
||||
|| ((f7 == f7_FSGNJ_S) && ( rm == 0))
|
||||
|| ((f7 == f7_FSGNJ_S) && ( rm == 1))
|
||||
@@ -842,10 +856,10 @@ function Bool fv_is_fp_instr_legal (
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_L_S) && (rs2 == 2))
|
||||
|| ((f7 == f7_FCVT_LU_S)&& (rs2 == 3))
|
||||
`endif
|
||||
`endif
|
||||
|| ((f7 == f7_FCVT_S_W) && (rs2 == 0))
|
||||
|| ((f7 == f7_FCVT_S_WU)&& (rs2 == 1))
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_S_WU)&& (rs2 == 1))
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_S_L) && (rs2 == 2))
|
||||
|| ((f7 == f7_FCVT_S_LU)&& (rs2 == 3))
|
||||
`endif
|
||||
@@ -858,12 +872,12 @@ function Bool fv_is_fp_instr_legal (
|
||||
|| ((f7 == f7_FMV_W_X) && ( rm == 0))
|
||||
|| ((f7 == f7_FCLASS_S) && ( rm == 1))
|
||||
`ifdef ISA_D
|
||||
|| (f7 == f7_FADD_D)
|
||||
|| (f7 == f7_FSUB_D)
|
||||
|| (f7 == f7_FMUL_D)
|
||||
|| (f7 == f7_FADD_D)
|
||||
|| (f7 == f7_FSUB_D)
|
||||
|| (f7 == f7_FMUL_D)
|
||||
`ifdef ISA_FD_DIV
|
||||
|| (f7 == f7_FDIV_D)
|
||||
|| (f7 == f7_FSQRT_D)
|
||||
|| (f7 == f7_FDIV_D)
|
||||
|| (f7 == f7_FSQRT_D)
|
||||
`endif
|
||||
|| ((f7 == f7_FSGNJ_D) && ( rm == 0))
|
||||
|| ((f7 == f7_FSGNJ_D) && ( rm == 1))
|
||||
@@ -873,10 +887,10 @@ function Bool fv_is_fp_instr_legal (
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_L_D) && (rs2 == 2))
|
||||
|| ((f7 == f7_FCVT_LU_D)&& (rs2 == 3))
|
||||
`endif
|
||||
`endif
|
||||
|| ((f7 == f7_FCVT_D_W) && (rs2 == 0))
|
||||
|| ((f7 == f7_FCVT_D_WU)&& (rs2 == 1))
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_D_WU)&& (rs2 == 1))
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_D_L) && (rs2 == 2))
|
||||
|| ((f7 == f7_FCVT_D_LU)&& (rs2 == 3))
|
||||
`endif
|
||||
@@ -970,7 +984,7 @@ endfunction
|
||||
|
||||
function Bool f3_is_CSRR_S_or_C (Bit #(3) f3);
|
||||
return ((f3 == f3_CSRRS) || (f3 == f3_CSRRSI) ||
|
||||
(f3 == f3_CSRRC) || (f3 == f3_CSRRCI));
|
||||
(f3 == f3_CSRRC) || (f3 == f3_CSRRCI));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -987,11 +1001,11 @@ Priv_Mode m_Priv_Mode = 2'b11;
|
||||
|
||||
function Fmt fshow_Priv_Mode (Priv_Mode pm);
|
||||
return case (pm)
|
||||
u_Priv_Mode: $format ("U");
|
||||
s_Priv_Mode: $format ("S");
|
||||
m_Priv_Mode: $format ("M");
|
||||
default: $format ("RESERVED");
|
||||
endcase;
|
||||
u_Priv_Mode: $format ("U");
|
||||
s_Priv_Mode: $format ("S");
|
||||
m_Priv_Mode: $format ("M");
|
||||
default: $format ("RESERVED");
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -1092,7 +1106,7 @@ CSR_Addr csr_addr_hpmcounter29h = 12'hC9D; // Upper 32 bits of performance
|
||||
CSR_Addr csr_addr_hpmcounter30h = 12'hC9E; // Upper 32 bits of performance-monitoring counter
|
||||
CSR_Addr csr_addr_hpmcounter31h = 12'hC9F; // Upper 32 bits of performance-monitoring counter
|
||||
|
||||
// Information from the CSR on a new trap.
|
||||
// Information from the CSR on a new trap.
|
||||
typedef struct {
|
||||
Addr pc;
|
||||
WordXL mstatus;
|
||||
|
||||
208
src_Core/ISA/ISA_Decls_CHERI.bsv
Normal file
208
src_Core/ISA/ISA_Decls_CHERI.bsv
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Peter Rugg
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by SRI International and the University of
|
||||
* Cambridge Computer Laboratory (Department of Computer Science and
|
||||
* Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
|
||||
* DARPA SSITH research programme.
|
||||
*
|
||||
* @BERI_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with this work for
|
||||
* additional information regarding copyright ownership. BERI licenses this
|
||||
* file to you under the BERI Hardware-Software License, Version 1.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.beri-open-systems.org/legal/license-1-0.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, Work distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* @BERI_LICENSE_HEADER_END@
|
||||
*/
|
||||
import ISA_Decls::*;
|
||||
import CHERICap::*;
|
||||
import CHERICC_Fat::*;
|
||||
|
||||
typedef TMul#(XLEN, 2) CLEN;
|
||||
|
||||
// Exception codes
|
||||
|
||||
typedef enum {
|
||||
None = 5'd0,
|
||||
LengthViolation = 5'd1,
|
||||
TagViolation = 5'd2,
|
||||
SealViolation = 5'd3,
|
||||
TypeViolation = 5'd4,
|
||||
CallTrap = 5'd5,
|
||||
ReturnTrap = 5'd6,
|
||||
StackUnderflow = 5'd7,
|
||||
MMUStoreCapProhibit = 5'd8,
|
||||
RepresentViolation = 5'd9,
|
||||
UnalignedBase = 5'd10,
|
||||
// 5'd11 - 5'd15 reserved
|
||||
GlobalViolation = 5'd16,
|
||||
PermitXViolation = 5'd17,
|
||||
PermitRViolation = 5'd18,
|
||||
PermitWViolation = 5'd19,
|
||||
PermitRCapViolation = 5'd20,
|
||||
PermitWCapViolation = 5'd21,
|
||||
PermitWLocalCapViolation = 5'd22,
|
||||
PermitSealViolation = 5'd23,
|
||||
PermitASRViolation = 5'd24,
|
||||
PermitCCallViolation = 5'd25,
|
||||
PermitUnsealViolation = 5'd26,
|
||||
PermitSetCIDViolation = 5'd27
|
||||
// 5'd28 - 5'd31 reserved
|
||||
} CHERIException deriving(Bits, Eq, FShow);
|
||||
|
||||
// SCR map
|
||||
|
||||
typedef enum {
|
||||
SCR_PCC = 5'd00,
|
||||
SCR_DDC = 5'd01,
|
||||
|
||||
SCR_UTCC = 5'd04,
|
||||
SCR_UTDC = 5'd05,
|
||||
SCR_UScratchC = 5'd06,
|
||||
SCR_UEPCC = 5'd07,
|
||||
|
||||
SCR_STCC = 5'd12,
|
||||
SCR_STDC = 5'd13,
|
||||
SCR_SScratchC = 5'd14,
|
||||
SCR_SEPCC = 5'd15,
|
||||
|
||||
SCR_MTCC = 5'd28,
|
||||
SCR_MTDC = 5'd29,
|
||||
SCR_MScratchC = 5'd30,
|
||||
SCR_MEPCC = 5'd31
|
||||
} SCR deriving(Bits, Eq, FShow);
|
||||
|
||||
function CapPipe update_scr_via_csr (CapPipe old_scr, WordXL new_csr);
|
||||
let new_scr = setOffset(old_scr, new_csr);
|
||||
let ret = new_scr.value;
|
||||
if (!new_scr.exact || isSealed(old_scr)) begin
|
||||
ret = setValidCap(ret, False);
|
||||
end
|
||||
return ret;
|
||||
endfunction
|
||||
|
||||
RegName cCallRD = 31;
|
||||
|
||||
// Instruction field encodings
|
||||
|
||||
// Top-level opcodes
|
||||
Opcode op_cap_Manip = 7'h5b;
|
||||
//Opcode op_cap_Mem = 7'h0b; // Not yet implemented
|
||||
|
||||
// ================================================================
|
||||
// op_cap_Manip opcode subdivision
|
||||
|
||||
// f3 selects between immediate and 3-reg instructions
|
||||
Bit #(3) f3_cap_ThreeOp = 3'h0;
|
||||
Bit #(3) f3_cap_CIncOffsetImmediate = 3'h1;
|
||||
Bit #(3) f3_cap_CSetBoundsImmediate = 3'h2;
|
||||
// 3'h3-3'h7 unused
|
||||
|
||||
// ================================================================
|
||||
// op_cap_ThreeOp opcode subdivision
|
||||
|
||||
// f7 selects between 3-reg operations
|
||||
|
||||
// 7'h00 unused
|
||||
Bit #(7) f7_cap_CSpecialRW = 7'h01;
|
||||
// 7'h02-7'h07 unused
|
||||
Bit #(7) f7_cap_CSetBounds = 7'h08;
|
||||
Bit #(7) f7_cap_CSetBoundsExact = 7'h09;
|
||||
// 7'h0a unused
|
||||
Bit #(7) f7_cap_CSeal = 7'h0b;
|
||||
Bit #(7) f7_cap_CUnseal = 7'h0c;
|
||||
Bit #(7) f7_cap_CAndPerm = 7'h0d;
|
||||
Bit #(7) f7_cap_CSetFlags = 7'h0e;
|
||||
Bit #(7) f7_cap_CSetOffset = 7'h0f;
|
||||
Bit #(7) f7_cap_CSetAddr = 7'h10;
|
||||
Bit #(7) f7_cap_CIncOffset = 7'h11;
|
||||
Bit #(7) f7_cap_CToPtr = 7'h12;
|
||||
Bit #(7) f7_cap_CFromPtr = 7'h13;
|
||||
Bit #(7) f7_cap_CSub = 7'h14;
|
||||
// 7'h15-7'h1c unused
|
||||
Bit #(7) f7_cap_CBuildCap = 7'h1d;
|
||||
Bit #(7) f7_cap_CCopyType = 7'h1e;
|
||||
Bit #(7) f7_cap_CCSeal = 7'h1f;
|
||||
Bit #(7) f7_cap_CTestSubset = 7'h20;
|
||||
// 7'h21-7'hfb unused
|
||||
Bit #(7) f7_cap_Stores = 7'h7c;
|
||||
Bit #(7) f7_cap_Loads = 7'h7d;
|
||||
Bit #(7) f7_cap_TwoSrc = 7'h7e;
|
||||
Bit #(7) f7_cap_TwoOp = 7'h7f;
|
||||
|
||||
// ================================================================
|
||||
// f7_cap_TwoSrc opcode subdivision
|
||||
|
||||
// rd selects between 2-reg operations
|
||||
|
||||
// 5'h00 unused
|
||||
Bit #(5) rd_cap_CCall = 5'h01;
|
||||
// 5'h02-5'h1f unused
|
||||
|
||||
// ================================================================
|
||||
// f7_cap_TwoOp opcode subdivision
|
||||
|
||||
// f5rs2 selects between 2-reg operations (f5rs2 instead of f5 because f5
|
||||
// is already used in RISC-V and is in a different position
|
||||
|
||||
Bit #(5) f5rs2_cap_CGetPerm = 5'h00;
|
||||
Bit #(5) f5rs2_cap_CGetType = 5'h01;
|
||||
Bit #(5) f5rs2_cap_CGetBase = 5'h02;
|
||||
Bit #(5) f5rs2_cap_CGetLen = 5'h03;
|
||||
Bit #(5) f5rs2_cap_CGetTag = 5'h04;
|
||||
Bit #(5) f5rs2_cap_CGetSealed = 5'h05;
|
||||
Bit #(5) f5rs2_cap_CGetOffset = 5'h06;
|
||||
Bit #(5) f5rs2_cap_CGetFlags = 5'h07;
|
||||
Bit #(5) f5rs2_cap_CRRL = 5'h08;
|
||||
Bit #(5) f5rs2_cap_CRAM = 5'h09;
|
||||
Bit #(5) f5rs2_cap_CMove = 5'h0a;
|
||||
Bit #(5) f5rs2_cap_CClearTag = 5'h0b;
|
||||
Bit #(5) f5rs2_cap_CJALR = 5'h0c;
|
||||
Bit #(5) f5rs2_cap_CClearReg = 5'h0d;
|
||||
// 5'h0e unused
|
||||
Bit #(5) f5rs2_cap_CGetAddr = 5'h0f;
|
||||
Bit #(5) f5rs2_cap_CClearFPReg = 5'h10;
|
||||
// 5'h11-5'h1f unused (5'h1f reserved for 1-reg instructions
|
||||
|
||||
// ================================================================
|
||||
// f7_cap_{Load, Store} opcode subdivision
|
||||
|
||||
MemReqSize cap_mem_SIZE_B = 'h0;
|
||||
MemReqSize cap_mem_SIZE_H = 'h1;
|
||||
MemReqSize cap_mem_SIZE_W = 'h2;
|
||||
MemReqSize cap_mem_SIZE_D = 'h3;
|
||||
//MemReqSize f5rs2_cap_mem_SIZE_Q = 'h4; //TODO
|
||||
|
||||
Bit #(1) cap_mem_ddc = 1'h0;
|
||||
Bit #(1) cap_mem_cap = 1'h1;
|
||||
|
||||
Bit #(1) cap_mem_unsigned = 1'h1;
|
||||
Bit #(1) cap_mem_signed = 1'h0;
|
||||
|
||||
// ================================================================
|
||||
// Other:
|
||||
|
||||
// Region in MISC_MEM for LQ
|
||||
Bit #(3) f3_LQ = 3'h2;
|
||||
Bit #(3) f3_SQ = 3'b100;
|
||||
|
||||
`ifdef RV64
|
||||
Bit #(3) w_SIZE_CAP = f3_SQ;
|
||||
Bit #(3) w_SIZE_MAX = f3_SQ;
|
||||
`else //RV32
|
||||
Bit #(3) w_SIZE_CAP = f3_SD;
|
||||
Bit #(3) w_SIZE_MAX = f3_SD;
|
||||
`endif
|
||||
|
||||
Bit #(3) f3_AMO_CAP = w_SIZE_CAP;
|
||||
@@ -201,56 +201,56 @@ Bit #(2) misa_mxl_128 = 3;
|
||||
|
||||
function WordXL misa_to_word (MISA ms);
|
||||
return {ms.mxl,
|
||||
0, // expands appropriately for RV32 and RV64
|
||||
ms.z, ms.y,
|
||||
ms.x, ms.w, ms.v, ms.u, ms.t, ms.s, ms.r, ms.q,
|
||||
ms.p, ms.o, ms.n, ms.m, ms.l, ms.k, ms.j, ms.i,
|
||||
ms.h, ms.g, ms.f, ms.e, ms.d, ms.c, ms.b, ms.a};
|
||||
0, // expands appropriately for RV32 and RV64
|
||||
ms.z, ms.y,
|
||||
ms.x, ms.w, ms.v, ms.u, ms.t, ms.s, ms.r, ms.q,
|
||||
ms.p, ms.o, ms.n, ms.m, ms.l, ms.k, ms.j, ms.i,
|
||||
ms.h, ms.g, ms.f, ms.e, ms.d, ms.c, ms.b, ms.a};
|
||||
endfunction
|
||||
|
||||
function MISA word_to_misa (WordXL x);
|
||||
return MISA {mxl: x [xlen-1:xlen-2],
|
||||
z: x [25], y: x [24],
|
||||
x: x [23], w: x [22], v: x [21], u: x [20], t: x [19], s: x [18], r: x [17], q: x [16],
|
||||
p: x [15], o: x [14], n: x [13], m: x [12], l: x [11], k: x [10], j: x [9], i: x [8],
|
||||
h: x [7], g: x [6], f: x [5], e: x [4], d: x [3], c: x [2], b: x [1], a: x [0]};
|
||||
z: x [25], y: x [24],
|
||||
x: x [23], w: x [22], v: x [21], u: x [20], t: x [19], s: x [18], r: x [17], q: x [16],
|
||||
p: x [15], o: x [14], n: x [13], m: x [12], l: x [11], k: x [10], j: x [9], i: x [8],
|
||||
h: x [7], g: x [6], f: x [5], e: x [4], d: x [3], c: x [2], b: x [1], a: x [0]};
|
||||
endfunction
|
||||
|
||||
instance FShow #(MISA);
|
||||
function Fmt fshow (MISA misa);
|
||||
let fmt_mxl = case (misa.mxl)
|
||||
1: $format ("mxl 32");
|
||||
2: $format ("mxl 64");
|
||||
3: $format ("mxl 128");
|
||||
default: $format ("mxl unknown %0d", misa.mxl);
|
||||
endcase;
|
||||
1: $format ("mxl 32");
|
||||
2: $format ("mxl 64");
|
||||
3: $format ("mxl 128");
|
||||
default: $format ("mxl unknown %0d", misa.mxl);
|
||||
endcase;
|
||||
return ( fmt_mxl
|
||||
+ $format ((misa.z == 1'b1) ? "Z" : "")
|
||||
+ $format ((misa.y == 1'b1) ? "Y" : "")
|
||||
+ $format ((misa.x == 1'b1) ? "X" : "")
|
||||
+ $format ((misa.w == 1'b1) ? "W" : "")
|
||||
+ $format ((misa.v == 1'b1) ? "V" : "")
|
||||
+ $format ((misa.u == 1'b1) ? "U" : "")
|
||||
+ $format ((misa.t == 1'b1) ? "T" : "")
|
||||
+ $format ((misa.s == 1'b1) ? "S" : "")
|
||||
+ $format ((misa.r == 1'b1) ? "R" : "")
|
||||
+ $format ((misa.q == 1'b1) ? "Q" : "")
|
||||
+ $format ((misa.p == 1'b1) ? "P" : "")
|
||||
+ $format ((misa.o == 1'b1) ? "O" : "")
|
||||
+ $format ((misa.n == 1'b1) ? "N" : "")
|
||||
+ $format ((misa.m == 1'b1) ? "M" : "")
|
||||
+ $format ((misa.l == 1'b1) ? "L" : "")
|
||||
+ $format ((misa.k == 1'b1) ? "K" : "")
|
||||
+ $format ((misa.j == 1'b1) ? "J" : "")
|
||||
+ $format ((misa.i == 1'b1) ? "I" : "")
|
||||
+ $format ((misa.h == 1'b1) ? "H" : "")
|
||||
+ $format ((misa.g == 1'b1) ? "G" : "")
|
||||
+ $format ((misa.f == 1'b1) ? "F" : "")
|
||||
+ $format ((misa.d == 1'b1) ? "E" : "")
|
||||
+ $format ((misa.d == 1'b1) ? "D" : "")
|
||||
+ $format ((misa.c == 1'b1) ? "C" : "")
|
||||
+ $format ((misa.b == 1'b1) ? "B" : "")
|
||||
+ $format ((misa.a == 1'b1) ? "A" : ""));
|
||||
+ $format ((misa.z == 1'b1) ? "Z" : "")
|
||||
+ $format ((misa.y == 1'b1) ? "Y" : "")
|
||||
+ $format ((misa.x == 1'b1) ? "X" : "")
|
||||
+ $format ((misa.w == 1'b1) ? "W" : "")
|
||||
+ $format ((misa.v == 1'b1) ? "V" : "")
|
||||
+ $format ((misa.u == 1'b1) ? "U" : "")
|
||||
+ $format ((misa.t == 1'b1) ? "T" : "")
|
||||
+ $format ((misa.s == 1'b1) ? "S" : "")
|
||||
+ $format ((misa.r == 1'b1) ? "R" : "")
|
||||
+ $format ((misa.q == 1'b1) ? "Q" : "")
|
||||
+ $format ((misa.p == 1'b1) ? "P" : "")
|
||||
+ $format ((misa.o == 1'b1) ? "O" : "")
|
||||
+ $format ((misa.n == 1'b1) ? "N" : "")
|
||||
+ $format ((misa.m == 1'b1) ? "M" : "")
|
||||
+ $format ((misa.l == 1'b1) ? "L" : "")
|
||||
+ $format ((misa.k == 1'b1) ? "K" : "")
|
||||
+ $format ((misa.j == 1'b1) ? "J" : "")
|
||||
+ $format ((misa.i == 1'b1) ? "I" : "")
|
||||
+ $format ((misa.h == 1'b1) ? "H" : "")
|
||||
+ $format ((misa.g == 1'b1) ? "G" : "")
|
||||
+ $format ((misa.f == 1'b1) ? "F" : "")
|
||||
+ $format ((misa.d == 1'b1) ? "E" : "")
|
||||
+ $format ((misa.d == 1'b1) ? "D" : "")
|
||||
+ $format ((misa.c == 1'b1) ? "C" : "")
|
||||
+ $format ((misa.b == 1'b1) ? "B" : "")
|
||||
+ $format ((misa.a == 1'b1) ? "A" : ""));
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
@@ -314,43 +314,43 @@ function Fmt fshow_mstatus (MISA misa, WordXL mstatus);
|
||||
Bit #(2) mpp = fv_get_bits (mstatus, fromInteger (mstatus_mpp_bitpos));
|
||||
|
||||
return ( $format ("MStatus{")
|
||||
+ $format ("sd:%0d", fv_mstatus_sd (mstatus))
|
||||
+ $format ("sd:%0d", fv_mstatus_sd (mstatus))
|
||||
|
||||
+ ((misa.mxl == misa_mxl_64) ? $format (" sxl:%0d uxl:%0d", sxl, uxl) : $format (""))
|
||||
+ ((misa.mxl == misa_mxl_64) ? $format (" sxl:%0d uxl:%0d", sxl, uxl) : $format (""))
|
||||
|
||||
+ $format (" tsr:%0d", mstatus [mstatus_tsr_bitpos])
|
||||
+ $format (" tw:%0d", mstatus [mstatus_tw_bitpos])
|
||||
+ $format (" tvm:%0d", mstatus [mstatus_tvm_bitpos])
|
||||
+ $format (" mxr:%0d", mstatus [mstatus_mxr_bitpos])
|
||||
+ $format (" sum:%0d", mstatus [mstatus_sum_bitpos])
|
||||
+ $format (" mprv:%0d", mstatus [mstatus_mprv_bitpos])
|
||||
+ $format (" tsr:%0d", mstatus [mstatus_tsr_bitpos])
|
||||
+ $format (" tw:%0d", mstatus [mstatus_tw_bitpos])
|
||||
+ $format (" tvm:%0d", mstatus [mstatus_tvm_bitpos])
|
||||
+ $format (" mxr:%0d", mstatus [mstatus_mxr_bitpos])
|
||||
+ $format (" sum:%0d", mstatus [mstatus_sum_bitpos])
|
||||
+ $format (" mprv:%0d", mstatus [mstatus_mprv_bitpos])
|
||||
|
||||
+ $format (" xs:%0d", xs)
|
||||
+ $format (" fs:%0d", fs)
|
||||
+ $format (" xs:%0d", xs)
|
||||
+ $format (" fs:%0d", fs)
|
||||
|
||||
+ $format (" mpp:%0d", mpp)
|
||||
+ $format (" spp:%0d", mstatus [mstatus_spp_bitpos])
|
||||
+ $format (" mpp:%0d", mpp)
|
||||
+ $format (" spp:%0d", mstatus [mstatus_spp_bitpos])
|
||||
|
||||
+ $format (" pies:%0d_%0d%0d",
|
||||
mstatus [mstatus_mpie_bitpos], mstatus [mstatus_spie_bitpos], mstatus [mstatus_upie_bitpos])
|
||||
+ $format (" pies:%0d_%0d%0d",
|
||||
mstatus [mstatus_mpie_bitpos], mstatus [mstatus_spie_bitpos], mstatus [mstatus_upie_bitpos])
|
||||
|
||||
+ $format (" ies:%0d_%0d%0d",
|
||||
mstatus [mstatus_mie_bitpos], mstatus [mstatus_sie_bitpos], mstatus [mstatus_uie_bitpos])
|
||||
+ $format ("}")
|
||||
);
|
||||
+ $format (" ies:%0d_%0d%0d",
|
||||
mstatus [mstatus_mie_bitpos], mstatus [mstatus_sie_bitpos], mstatus [mstatus_uie_bitpos])
|
||||
+ $format ("}")
|
||||
);
|
||||
endfunction
|
||||
|
||||
// ----------------
|
||||
// Help functions to manipulate mstatus on traps and trap-returns
|
||||
|
||||
function Priv_Mode fv_new_priv_on_exception (MISA misa,
|
||||
Priv_Mode from_priv,
|
||||
Bool interrupt,
|
||||
Exc_Code exc_code,
|
||||
Bit #(16) medeleg,
|
||||
Bit #(12) mideleg,
|
||||
Bit #(16) sedeleg,
|
||||
Bit #(12) sideleg);
|
||||
Priv_Mode from_priv,
|
||||
Bool interrupt,
|
||||
Exc_Code exc_code,
|
||||
Bit #(16) medeleg,
|
||||
Bit #(12) mideleg,
|
||||
Bit #(16) sedeleg,
|
||||
Bit #(12) sideleg);
|
||||
Priv_Mode to_priv = m_Priv_Mode;
|
||||
Bit #(1) deleg_bit = 1'b0;
|
||||
|
||||
@@ -358,39 +358,39 @@ function Priv_Mode fv_new_priv_on_exception (MISA misa,
|
||||
if (from_priv < m_Priv_Mode) begin
|
||||
// If S is supported
|
||||
if (misa.s == 1'b1) begin
|
||||
// Look in medeleg/mideleg for the cause bit; if set, delegate.
|
||||
if (interrupt)
|
||||
deleg_bit = mideleg [exc_code];
|
||||
else
|
||||
deleg_bit = medeleg [exc_code];
|
||||
if (deleg_bit == 1'b1) begin
|
||||
// If the current priv mode is S, then delegate to S.
|
||||
to_priv = s_Priv_Mode;
|
||||
// If the current priv mode is U, and user mode traps are supported,
|
||||
// then consult sedeleg/sideleg to determine if delegated to U mode.
|
||||
if ((from_priv == u_Priv_Mode) && (misa.n == 1'b1)) begin
|
||||
if (interrupt)
|
||||
deleg_bit = sideleg [exc_code];
|
||||
else
|
||||
deleg_bit = sedeleg [exc_code];
|
||||
if (deleg_bit == 1'b1)
|
||||
to_priv = u_Priv_Mode;
|
||||
end
|
||||
end
|
||||
// Look in medeleg/mideleg for the cause bit; if set, delegate.
|
||||
if (interrupt)
|
||||
deleg_bit = mideleg [exc_code];
|
||||
else
|
||||
deleg_bit = medeleg [exc_code];
|
||||
if (deleg_bit == 1'b1) begin
|
||||
// If the current priv mode is S, then delegate to S.
|
||||
to_priv = s_Priv_Mode;
|
||||
// If the current priv mode is U, and user mode traps are supported,
|
||||
// then consult sedeleg/sideleg to determine if delegated to U mode.
|
||||
if ((from_priv == u_Priv_Mode) && (misa.n == 1'b1)) begin
|
||||
if (interrupt)
|
||||
deleg_bit = sideleg [exc_code];
|
||||
else
|
||||
deleg_bit = sedeleg [exc_code];
|
||||
if (deleg_bit == 1'b1)
|
||||
to_priv = u_Priv_Mode;
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// S is not supported
|
||||
// If user mode traps are supported,
|
||||
// then consult medele/mideleg to determine if delegated to U mode.
|
||||
if (misa.n == 1'b1) begin
|
||||
// Look in medeleg/mideleg for the cause bit; if set, delegate.
|
||||
if (interrupt)
|
||||
deleg_bit = mideleg [exc_code];
|
||||
else
|
||||
deleg_bit = medeleg [exc_code];
|
||||
if (deleg_bit == 1'b1)
|
||||
to_priv = u_Priv_Mode;
|
||||
end
|
||||
// S is not supported
|
||||
// If user mode traps are supported,
|
||||
// then consult medele/mideleg to determine if delegated to U mode.
|
||||
if (misa.n == 1'b1) begin
|
||||
// Look in medeleg/mideleg for the cause bit; if set, delegate.
|
||||
if (interrupt)
|
||||
deleg_bit = mideleg [exc_code];
|
||||
else
|
||||
deleg_bit = medeleg [exc_code];
|
||||
if (deleg_bit == 1'b1)
|
||||
to_priv = u_Priv_Mode;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -407,14 +407,14 @@ function WordXL fv_new_mstatus_on_exception (WordXL mstatus, Priv_Mode from_y, P
|
||||
|
||||
// xPP = y Assert: (to_x == m_Priv_Mode) || (to_x == s_Priv_Mode)
|
||||
mstatus = ( (to_x == m_Priv_Mode)
|
||||
? fv_assign_bits (mstatus, fromInteger (mstatus_mpp_bitpos), from_y)
|
||||
: fv_assign_bit (mstatus, fromInteger (mstatus_spp_bitpos), from_y [0]));
|
||||
? fv_assign_bits (mstatus, fromInteger (mstatus_mpp_bitpos), from_y)
|
||||
: fv_assign_bit (mstatus, fromInteger (mstatus_spp_bitpos), from_y [0]));
|
||||
return mstatus;
|
||||
endfunction
|
||||
|
||||
function Tuple2 #(WordXL, Priv_Mode) fv_new_mstatus_on_ret (MISA misa,
|
||||
WordXL mstatus,
|
||||
Priv_Mode from_x);
|
||||
WordXL mstatus,
|
||||
Priv_Mode from_x);
|
||||
Bit #(6) ie_from_x = extend (from_x);
|
||||
Bit #(6) pie_from_x = fromInteger (mstatus_upie_bitpos) + extend (from_x);
|
||||
|
||||
@@ -478,20 +478,20 @@ deriving (Bits, FShow);
|
||||
function WordXL mcounteren_to_word (MCounteren mc);
|
||||
return {0,
|
||||
mc.ir,
|
||||
mc.tm,
|
||||
mc.cy};
|
||||
mc.tm,
|
||||
mc.cy};
|
||||
endfunction
|
||||
|
||||
function MCounteren word_to_mcounteren (WordXL x);
|
||||
return MCounteren {ir: x[2],
|
||||
tm: x[1],
|
||||
cy: x[0]};
|
||||
cy: x[0]};
|
||||
endfunction
|
||||
|
||||
function MCounteren mcounteren_reset_value;
|
||||
return MCounteren {ir: 1'b0,
|
||||
tm: 1'b0,
|
||||
cy: 1'b0};
|
||||
cy: 1'b0};
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -521,9 +521,9 @@ deriving (Bits);
|
||||
instance FShow #(MCause);
|
||||
function Fmt fshow (MCause mc);
|
||||
if (mc.interrupt == 1)
|
||||
return fshow_interrupt_Exc_Code (mc.exc_code);
|
||||
return fshow_interrupt_Exc_Code (mc.exc_code);
|
||||
else
|
||||
return fshow_trap_Exc_Code (mc.exc_code);
|
||||
return fshow_trap_Exc_Code (mc.exc_code);
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
@@ -533,7 +533,7 @@ endfunction
|
||||
|
||||
function MCause word_to_mcause (WordXL x);
|
||||
return MCause {interrupt: msb (x),
|
||||
exc_code: truncate (x)};
|
||||
exc_code: truncate (x)};
|
||||
endfunction
|
||||
|
||||
// Exception Codes in mcause
|
||||
@@ -583,47 +583,47 @@ Exc_Code exc_code_STORE_AMO_PAGE_FAULT = 15;
|
||||
|
||||
function Fmt fshow_interrupt_Exc_Code (Exc_Code exc_code);
|
||||
return case (exc_code)
|
||||
exc_code_USER_SW_INTERRUPT: $format ("USER_SW_INTERRUPT");
|
||||
exc_code_SUPERVISOR_SW_INTERRUPT: $format ("SUPERVISOR_SW_INTERRUPT");
|
||||
exc_code_HYPERVISOR_SW_INTERRUPT: $format ("HYPERVISOR_SW_INTERRUPT");
|
||||
exc_code_MACHINE_SW_INTERRUPT: $format ("MACHINE_SW_INTERRUPT");
|
||||
exc_code_USER_SW_INTERRUPT: $format ("USER_SW_INTERRUPT");
|
||||
exc_code_SUPERVISOR_SW_INTERRUPT: $format ("SUPERVISOR_SW_INTERRUPT");
|
||||
exc_code_HYPERVISOR_SW_INTERRUPT: $format ("HYPERVISOR_SW_INTERRUPT");
|
||||
exc_code_MACHINE_SW_INTERRUPT: $format ("MACHINE_SW_INTERRUPT");
|
||||
|
||||
exc_code_USER_TIMER_INTERRUPT: $format ("USER_TIMER_INTERRUPT");
|
||||
exc_code_SUPERVISOR_TIMER_INTERRUPT: $format ("SUPERVISOR_TIMER_INTERRUPT");
|
||||
exc_code_HYPERVISOR_TIMER_INTERRUPT: $format ("HYPERVISOR_TIMER_INTERRUPT");
|
||||
exc_code_MACHINE_TIMER_INTERRUPT: $format ("MACHINE_TIMER_INTERRUPT");
|
||||
exc_code_USER_TIMER_INTERRUPT: $format ("USER_TIMER_INTERRUPT");
|
||||
exc_code_SUPERVISOR_TIMER_INTERRUPT: $format ("SUPERVISOR_TIMER_INTERRUPT");
|
||||
exc_code_HYPERVISOR_TIMER_INTERRUPT: $format ("HYPERVISOR_TIMER_INTERRUPT");
|
||||
exc_code_MACHINE_TIMER_INTERRUPT: $format ("MACHINE_TIMER_INTERRUPT");
|
||||
|
||||
exc_code_USER_EXTERNAL_INTERRUPT: $format ("USER_EXTERNAL_INTERRUPT");
|
||||
exc_code_SUPERVISOR_EXTERNAL_INTERRUPT: $format ("SUPERVISOR_EXTERNAL_INTERRUPT");
|
||||
exc_code_HYPERVISOR_EXTERNAL_INTERRUPT: $format ("HYPERVISOR_EXTERNAL_INTERRUPT");
|
||||
exc_code_MACHINE_EXTERNAL_INTERRUPT: $format ("MACHINE_EXTERNAL_INTERRUPT");
|
||||
default: $format ("unknown interrupt Exc_Code %d", exc_code);
|
||||
endcase;
|
||||
exc_code_USER_EXTERNAL_INTERRUPT: $format ("USER_EXTERNAL_INTERRUPT");
|
||||
exc_code_SUPERVISOR_EXTERNAL_INTERRUPT: $format ("SUPERVISOR_EXTERNAL_INTERRUPT");
|
||||
exc_code_HYPERVISOR_EXTERNAL_INTERRUPT: $format ("HYPERVISOR_EXTERNAL_INTERRUPT");
|
||||
exc_code_MACHINE_EXTERNAL_INTERRUPT: $format ("MACHINE_EXTERNAL_INTERRUPT");
|
||||
default: $format ("unknown interrupt Exc_Code %d", exc_code);
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
function Fmt fshow_trap_Exc_Code (Exc_Code exc_code);
|
||||
return case (exc_code)
|
||||
exc_code_INSTR_ADDR_MISALIGNED: $format ("INSTRUCTION_ADDR_MISALIGNED");
|
||||
exc_code_INSTR_ACCESS_FAULT: $format ("INSTRUCTION_ACCESS_FAULT");
|
||||
exc_code_ILLEGAL_INSTRUCTION: $format ("ILLEGAL_INSTRUCTION");
|
||||
exc_code_BREAKPOINT: $format ("BREAKPOINT");
|
||||
exc_code_INSTR_ADDR_MISALIGNED: $format ("INSTRUCTION_ADDR_MISALIGNED");
|
||||
exc_code_INSTR_ACCESS_FAULT: $format ("INSTRUCTION_ACCESS_FAULT");
|
||||
exc_code_ILLEGAL_INSTRUCTION: $format ("ILLEGAL_INSTRUCTION");
|
||||
exc_code_BREAKPOINT: $format ("BREAKPOINT");
|
||||
|
||||
exc_code_LOAD_ADDR_MISALIGNED: $format ("LOAD_ADDR_MISALIGNED");
|
||||
exc_code_LOAD_ACCESS_FAULT: $format ("LOAD_ACCESS_FAULT");
|
||||
exc_code_LOAD_ADDR_MISALIGNED: $format ("LOAD_ADDR_MISALIGNED");
|
||||
exc_code_LOAD_ACCESS_FAULT: $format ("LOAD_ACCESS_FAULT");
|
||||
|
||||
exc_code_STORE_AMO_ADDR_MISALIGNED: $format ("STORE_AMO_ADDR_MISALIGNED");
|
||||
exc_code_STORE_AMO_ACCESS_FAULT: $format ("STORE_AMO_ACCESS_FAULT");
|
||||
exc_code_STORE_AMO_ADDR_MISALIGNED: $format ("STORE_AMO_ADDR_MISALIGNED");
|
||||
exc_code_STORE_AMO_ACCESS_FAULT: $format ("STORE_AMO_ACCESS_FAULT");
|
||||
|
||||
exc_code_ECALL_FROM_U: $format ("ECALL_FROM_U");
|
||||
exc_code_ECALL_FROM_S: $format ("ECALL_FROM_S");
|
||||
exc_code_ECALL_FROM_M: $format ("ECALL_FROM_M");
|
||||
exc_code_ECALL_FROM_U: $format ("ECALL_FROM_U");
|
||||
exc_code_ECALL_FROM_S: $format ("ECALL_FROM_S");
|
||||
exc_code_ECALL_FROM_M: $format ("ECALL_FROM_M");
|
||||
|
||||
exc_code_INSTR_PAGE_FAULT: $format ("INSTRUCTION_PAGE_FAULT");
|
||||
exc_code_LOAD_PAGE_FAULT: $format ("LOAD_PAGE_FAULT");
|
||||
exc_code_STORE_AMO_PAGE_FAULT: $format ("STORE_AMO_PAGE_FAULT");
|
||||
exc_code_INSTR_PAGE_FAULT: $format ("INSTRUCTION_PAGE_FAULT");
|
||||
exc_code_LOAD_PAGE_FAULT: $format ("LOAD_PAGE_FAULT");
|
||||
exc_code_STORE_AMO_PAGE_FAULT: $format ("STORE_AMO_PAGE_FAULT");
|
||||
|
||||
default: $format ("unknown trap Exc_Code %d", exc_code);
|
||||
endcase;
|
||||
default: $format ("unknown trap Exc_Code %d", exc_code);
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -632,44 +632,44 @@ endfunction
|
||||
// and if so, corresponding exception code
|
||||
|
||||
function Maybe #(Exc_Code) fv_interrupt_pending (MISA misa,
|
||||
WordXL mstatus,
|
||||
WordXL mip,
|
||||
WordXL mie,
|
||||
Bit #(12) mideleg,
|
||||
Bit #(12) sideleg,
|
||||
Priv_Mode cur_priv);
|
||||
WordXL mstatus,
|
||||
WordXL mip,
|
||||
WordXL mie,
|
||||
Bit #(12) mideleg,
|
||||
Bit #(12) sideleg,
|
||||
Priv_Mode cur_priv);
|
||||
|
||||
function Maybe #(Exc_Code) fv_interrupt_i_pending (Exc_Code i);
|
||||
Bool intr_pending = ((mip [i] == 1) && (mie [i] == 1));
|
||||
Priv_Mode handler_priv;
|
||||
if (mideleg [i] == 1)
|
||||
if (misa.u == 1)
|
||||
if (misa.s == 1)
|
||||
// System with M, S, U
|
||||
if (sideleg [i] == 1)
|
||||
if (misa.n == 1)
|
||||
// M->S->U delegation
|
||||
handler_priv = u_Priv_Mode;
|
||||
else
|
||||
// Error: SIDELEG [i] should not be 1 if MISA.N is 0
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
if (misa.u == 1)
|
||||
if (misa.s == 1)
|
||||
// System with M, S, U
|
||||
if (sideleg [i] == 1)
|
||||
if (misa.n == 1)
|
||||
// M->S->U delegation
|
||||
handler_priv = u_Priv_Mode;
|
||||
else
|
||||
// Error: SIDELEG [i] should not be 1 if MISA.N is 0
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
// M->S delegation
|
||||
handler_priv = s_Priv_Mode;
|
||||
else
|
||||
// System with M, U
|
||||
if (misa.n == 1)
|
||||
// M->U delegation
|
||||
handler_priv = u_Priv_Mode;
|
||||
else
|
||||
// Error: MIDELEG [i] should not be 1 if MISA.N is 0
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
// Error: System with M only; MIDELEG [i] should not be 1
|
||||
handler_priv = m_Priv_Mode;
|
||||
handler_priv = s_Priv_Mode;
|
||||
else
|
||||
// System with M, U
|
||||
if (misa.n == 1)
|
||||
// M->U delegation
|
||||
handler_priv = u_Priv_Mode;
|
||||
else
|
||||
// Error: MIDELEG [i] should not be 1 if MISA.N is 0
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
// Error: System with M only; MIDELEG [i] should not be 1
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
// no delegation
|
||||
handler_priv = m_Priv_Mode;
|
||||
// no delegation
|
||||
handler_priv = m_Priv_Mode;
|
||||
|
||||
Bool xie;
|
||||
if (cur_priv == u_Priv_Mode)
|
||||
@@ -680,10 +680,10 @@ function Maybe #(Exc_Code) fv_interrupt_pending (MISA misa,
|
||||
xie = (mstatus [mstatus_mie_bitpos] == 1);
|
||||
else
|
||||
// Error: unexpected mode
|
||||
xie = False;
|
||||
xie = False;
|
||||
|
||||
Bool glob_enabled = ( (cur_priv < handler_priv)
|
||||
|| ((cur_priv == handler_priv) && xie));
|
||||
|| ((cur_priv == handler_priv) && xie));
|
||||
|
||||
return ((intr_pending && glob_enabled) ? (tagged Valid i) : (tagged Invalid));
|
||||
endfunction
|
||||
|
||||
@@ -342,19 +342,19 @@ endfunction
|
||||
|
||||
function Bool is_invalid_pte (PTE pte);
|
||||
return ( (fn_PTE_to_V (pte) == 0)
|
||||
|| ( (fn_PTE_to_R (pte) == 0)
|
||||
&& (fn_PTE_to_W (pte) == 1)));
|
||||
|| ( (fn_PTE_to_R (pte) == 0)
|
||||
&& (fn_PTE_to_W (pte) == 1)));
|
||||
endfunction
|
||||
|
||||
// ----------------
|
||||
// Check if PTE bits deny a virtual-mem access
|
||||
|
||||
function Bool is_pte_denial (Bool dmem_not_imem, // load-store or fetch?
|
||||
Bool read_not_write,
|
||||
Priv_Mode priv,
|
||||
Bit #(1) sstatus_SUM,
|
||||
Bit #(1) mstatus_MXR,
|
||||
PTE pte);
|
||||
Bool read_not_write,
|
||||
Priv_Mode priv,
|
||||
Bit #(1) sstatus_SUM,
|
||||
Bit #(1) mstatus_MXR,
|
||||
PTE pte);
|
||||
|
||||
let pte_u = fn_PTE_to_U (pte);
|
||||
let pte_x = fn_PTE_to_X (pte);
|
||||
@@ -362,7 +362,7 @@ function Bool is_pte_denial (Bool dmem_not_imem, // load-store or f
|
||||
let pte_r = fn_PTE_to_R (pte);
|
||||
|
||||
Bool priv_deny = ( ((priv == u_Priv_Mode) && (pte_u == 1'b0))
|
||||
|| ((priv == s_Priv_Mode) && (pte_u == 1'b1) && (sstatus_SUM == 1'b0)));
|
||||
|| ((priv == s_Priv_Mode) && (pte_u == 1'b1) && (sstatus_SUM == 1'b0)));
|
||||
|
||||
Bool access_fetch = ((! dmem_not_imem) && read_not_write);
|
||||
Bool access_load = (dmem_not_imem && read_not_write);
|
||||
@@ -371,8 +371,8 @@ function Bool is_pte_denial (Bool dmem_not_imem, // load-store or f
|
||||
let pte_r_mxr = (pte_r | (mstatus_MXR & pte_x));
|
||||
|
||||
Bool access_ok = ( (access_fetch && (pte_x == 1'b1))
|
||||
|| (access_load && (pte_r_mxr == 1'b1))
|
||||
|| (access_store && (pte_w == 1'b1)));
|
||||
|| (access_load && (pte_r_mxr == 1'b1))
|
||||
|| (access_store && (pte_w == 1'b1)));
|
||||
|
||||
|
||||
return (priv_deny || (! access_ok));
|
||||
@@ -383,7 +383,7 @@ endfunction
|
||||
|
||||
function Bool is_pte_A_D_fault (Bool read_not_write, PTE pte);
|
||||
return ( (fn_PTE_to_A (pte) == 0)
|
||||
|| ((! read_not_write) && (fn_PTE_to_D (pte) == 0)));
|
||||
|| ((! read_not_write) && (fn_PTE_to_D (pte) == 0)));
|
||||
endfunction
|
||||
|
||||
// ----------------
|
||||
@@ -391,8 +391,8 @@ endfunction
|
||||
|
||||
function Exc_Code fn_page_fault_exc_code (Bool dmem_not_imem, Bool read_not_write);
|
||||
return ((! dmem_not_imem) ? exc_code_INSTR_PAGE_FAULT
|
||||
:(read_not_write ? exc_code_LOAD_PAGE_FAULT
|
||||
: exc_code_STORE_AMO_PAGE_FAULT));
|
||||
:(read_not_write ? exc_code_LOAD_PAGE_FAULT
|
||||
: exc_code_STORE_AMO_PAGE_FAULT));
|
||||
endfunction
|
||||
|
||||
`else // ifdef ISA_PRIV_S
|
||||
@@ -414,8 +414,8 @@ endfunction
|
||||
|
||||
function Exc_Code fn_access_exc_code (Bool dmem_not_imem, Bool read_not_write);
|
||||
return ((! dmem_not_imem) ? exc_code_INSTR_ACCESS_FAULT
|
||||
:(read_not_write ? exc_code_LOAD_ACCESS_FAULT
|
||||
: exc_code_STORE_AMO_ACCESS_FAULT));
|
||||
:(read_not_write ? exc_code_LOAD_ACCESS_FAULT
|
||||
: exc_code_STORE_AMO_ACCESS_FAULT));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -25,25 +25,25 @@ import ISA_Decls :: *;
|
||||
// ================================================================
|
||||
|
||||
typedef enum {// These are not from instruction flow and do not have a PC or instruction
|
||||
TRACE_RESET,
|
||||
TRACE_GPR_WRITE,
|
||||
TRACE_FPR_WRITE,
|
||||
TRACE_CSR_WRITE,
|
||||
TRACE_MEM_WRITE,
|
||||
TRACE_RESET,
|
||||
TRACE_GPR_WRITE,
|
||||
TRACE_FPR_WRITE,
|
||||
TRACE_CSR_WRITE,
|
||||
TRACE_MEM_WRITE,
|
||||
|
||||
// These are from instruction flow and have a PC and instruction
|
||||
TRACE_OTHER,
|
||||
TRACE_I_RD, TRACE_F_RD,
|
||||
TRACE_I_LOAD, TRACE_F_LOAD,
|
||||
TRACE_STORE,
|
||||
TRACE_AMO,
|
||||
TRACE_TRAP,
|
||||
TRACE_RET,
|
||||
TRACE_CSRRX,
|
||||
// These are from instruction flow and have a PC and instruction
|
||||
TRACE_OTHER,
|
||||
TRACE_I_RD, TRACE_F_GRD, TRACE_F_FRD,
|
||||
TRACE_I_LOAD, TRACE_F_LOAD,
|
||||
TRACE_I_STORE, TRACE_F_STORE,
|
||||
TRACE_AMO,
|
||||
TRACE_TRAP,
|
||||
TRACE_RET,
|
||||
TRACE_CSRRX,
|
||||
|
||||
// These are from an interrupt and has a PC but no instruction
|
||||
TRACE_INTR
|
||||
} Trace_Op
|
||||
// These are from an interrupt and has a PC but no instruction
|
||||
TRACE_INTR
|
||||
} Trace_Op
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
typedef struct {
|
||||
@@ -56,6 +56,9 @@ typedef struct {
|
||||
WordXL word2;
|
||||
Bit #(64) word3; // Wider than WordXL because can contain paddr (in RV32, paddr can be 34 bits)
|
||||
WordXL word4;
|
||||
`ifdef ISA_F
|
||||
WordFL word5;
|
||||
`endif
|
||||
} Trace_Data
|
||||
deriving (Bits);
|
||||
|
||||
@@ -139,19 +142,39 @@ function Trace_Data mkTrace_I_RD (WordXL pc, ISize isize, Bit #(32) instr, RegNa
|
||||
return td;
|
||||
endfunction
|
||||
|
||||
// F_RD
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x x x x rdval
|
||||
function Trace_Data mkTrace_F_RD (WordXL pc, ISize isize, Bit #(32) instr, RegName rd, WordXL rdval);
|
||||
`ifdef ISA_F
|
||||
// F_FRD
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4 word5
|
||||
// x x x x x fflags mstatus rdval
|
||||
function Trace_Data mkTrace_F_FRD (WordXL pc, ISize isize, Bit #(32) instr, RegName rd, WordFL rdval, Bit#(5) fflags, WordXL mstatus);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_F_RD;
|
||||
td.op = TRACE_F_FRD;
|
||||
td.pc = pc;
|
||||
td.instr_sz = isize;
|
||||
td.instr = instr;
|
||||
td.rd = rd;
|
||||
td.word2 = extend (fflags);
|
||||
td.word4 = mstatus;
|
||||
td.word5 = rdval;
|
||||
return td;
|
||||
endfunction
|
||||
|
||||
// F_GRD
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4 word5
|
||||
// x x x x x rdval fflags mstatus
|
||||
function Trace_Data mkTrace_F_GRD (WordXL pc, ISize isize, Bit #(32) instr, RegName rd, WordXL rdval, Bit#(5) fflags, WordXL mstatus);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_F_GRD;
|
||||
td.pc = pc;
|
||||
td.instr_sz = isize;
|
||||
td.instr = instr;
|
||||
td.rd = rd;
|
||||
td.word1 = rdval;
|
||||
td.word2 = extend (fflags);
|
||||
td.word4 = mstatus;
|
||||
return td;
|
||||
endfunction
|
||||
`endif
|
||||
|
||||
// I_LOAD
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
@@ -168,40 +191,70 @@ function Trace_Data mkTrace_I_LOAD (WordXL pc, ISize isize, Bit #(32) instr, Reg
|
||||
return td;
|
||||
endfunction
|
||||
|
||||
// F_LOAD
|
||||
// I_STORE
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x x x x rdval eaddr
|
||||
function Trace_Data mkTrace_F_LOAD (WordXL pc, ISize isize, Bit #(32) instr, RegName rd, WordXL rdval, WordXL eaddr);
|
||||
// x x x x funct3 stval eaddr
|
||||
function Trace_Data mkTrace_I_STORE (WordXL pc, Bit #(3) funct3, ISize isize, Bit #(32) instr, WordXL stval, WordXL eaddr);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_I_STORE;
|
||||
td.pc = pc;
|
||||
td.instr_sz = isize;
|
||||
td.instr = instr;
|
||||
td.word1 = zeroExtend (funct3);
|
||||
td.word2 = stval;
|
||||
td.word3 = zeroExtend (eaddr);
|
||||
return td;
|
||||
endfunction
|
||||
|
||||
`ifdef ISA_F
|
||||
// F_LOAD
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4 word5
|
||||
// x x x x x eaddr mstatus rdval
|
||||
function Trace_Data mkTrace_F_LOAD (WordXL pc, ISize isize, Bit #(32) instr, RegName rd, WordFL rdval, WordXL eaddr, WordXL mstatus);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_F_LOAD;
|
||||
td.pc = pc;
|
||||
td.instr_sz = isize;
|
||||
td.instr = instr;
|
||||
td.rd = rd;
|
||||
td.word1 = rdval;
|
||||
td.word3 = zeroExtend (eaddr);
|
||||
td.word4 = mstatus;
|
||||
td.word5 = rdval;
|
||||
return td;
|
||||
endfunction
|
||||
|
||||
// STORE
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x x x stval eaddr
|
||||
function Trace_Data mkTrace_STORE (WordXL pc, ISize isize, Bit #(32) instr, WordXL stval, WordXL eaddr);
|
||||
// F_STORE
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4 word5
|
||||
// x x x x funct3 eaddr stval
|
||||
function Trace_Data mkTrace_F_STORE (WordXL pc, Bit #(3) funct3, ISize isize, Bit #(32) instr, WordFL stval, WordXL eaddr);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_STORE;
|
||||
td.op = TRACE_F_STORE;
|
||||
td.pc = pc;
|
||||
td.instr_sz = isize;
|
||||
td.instr = instr;
|
||||
td.word2 = stval;
|
||||
td.word3 = zeroExtend (eaddr);
|
||||
td.word5 = stval;
|
||||
return td;
|
||||
endfunction
|
||||
|
||||
function Trace_Data fv_trace_update_mstatus_fs (Trace_Data td, Bit #(2) fs);
|
||||
let ntd = td;
|
||||
ntd.word4 = fv_assign_bits (td.word4, fromInteger (mstatus_fs_bitpos), fs);
|
||||
return (ntd);
|
||||
endfunction
|
||||
|
||||
function Trace_Data fv_trace_update_fcsr_fflags (Trace_Data td, Bit #(5) fflags);
|
||||
let ntd = td;
|
||||
ntd.word2 = (td.word2 | extend (fflags));
|
||||
return (ntd);
|
||||
endfunction
|
||||
`endif
|
||||
|
||||
// AMO
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x x x x rdval stval eaddr
|
||||
function Trace_Data mkTrace_AMO (WordXL pc, ISize isize, Bit #(32) instr,
|
||||
RegName rd, WordXL rdval, WordXL stval, WordXL eaddr);
|
||||
// x x x x x rdval stval eaddr funct3
|
||||
function Trace_Data mkTrace_AMO (WordXL pc, Bit #(3) funct3, ISize isize, Bit #(32) instr,
|
||||
RegName rd, WordXL rdval, WordXL stval, WordXL eaddr);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_AMO;
|
||||
td.pc = pc;
|
||||
@@ -211,6 +264,7 @@ function Trace_Data mkTrace_AMO (WordXL pc, ISize isize, Bit #(32) instr,
|
||||
td.word1 = rdval;
|
||||
td.word2 = stval;
|
||||
td.word3 = zeroExtend (eaddr);
|
||||
td.word4 = zeroExtend (funct3);
|
||||
return td;
|
||||
endfunction
|
||||
|
||||
@@ -218,7 +272,7 @@ endfunction
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x x x priv mstatus mcause mepc mtval
|
||||
function Trace_Data mkTrace_TRAP (WordXL pc, ISize isize, Bit #(32) instr,
|
||||
Priv_Mode priv, WordXL mstatus, WordXL mcause, WordXL mepc, WordXL mtval);
|
||||
Priv_Mode priv, WordXL mstatus, WordXL mcause, WordXL mepc, WordXL mtval);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_TRAP;
|
||||
td.pc = pc;
|
||||
@@ -247,10 +301,14 @@ function Trace_Data mkTrace_RET (WordXL pc, ISize isize, Bit #(32) instr, Priv_M
|
||||
endfunction
|
||||
|
||||
// CSRRX
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x x x x rdval csrvalid csraddr csrval
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4 word5
|
||||
// x x x x x rdval [1] mstatus_valid csraddr csrval mstatus
|
||||
// [0] csrvalid
|
||||
function Trace_Data mkTrace_CSRRX (WordXL pc, ISize isize, Bit #(32) instr,
|
||||
RegName rd, WordXL rdval, Bool csrvalid, CSR_Addr csraddr, WordXL csrval);
|
||||
RegName rd, WordXL rdval,
|
||||
Bool csrvalid, CSR_Addr csraddr, WordXL csrval,
|
||||
Bool mstatus_valid,
|
||||
WordXL mstatus);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_CSRRX;
|
||||
td.pc = pc;
|
||||
@@ -258,9 +316,12 @@ function Trace_Data mkTrace_CSRRX (WordXL pc, ISize isize, Bit #(32) instr,
|
||||
td.instr = instr;
|
||||
td.rd = rd;
|
||||
td.word1 = rdval;
|
||||
td.word2 = (csrvalid ? 1 : 0);
|
||||
td.word2 = ((mstatus_valid ? 2 : 0) | (csrvalid ? 1 : 0));
|
||||
td.word3 = zeroExtend (csraddr);
|
||||
td.word4 = csrval;
|
||||
`ifdef ISA_F
|
||||
td.word5 = mstatus;
|
||||
`endif
|
||||
return td;
|
||||
endfunction
|
||||
|
||||
@@ -268,7 +329,7 @@ endfunction
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x priv mstatus mcause mepc mtval
|
||||
function Trace_Data mkTrace_INTR (WordXL pc,
|
||||
Priv_Mode priv, WordXL mstatus, WordXL mcause, WordXL mepc, WordXL mtval);
|
||||
Priv_Mode priv, WordXL mstatus, WordXL mcause, WordXL mepc, WordXL mtval);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_INTR;
|
||||
td.pc = pc;
|
||||
@@ -291,44 +352,57 @@ instance FShow #(Trace_Data);
|
||||
end
|
||||
|
||||
else if ((td.op == TRACE_GPR_WRITE) || (td.op == TRACE_FPR_WRITE))
|
||||
fmt = fmt + $format (" rd %0d rdval %0h", td.rd, td.word1);
|
||||
fmt = fmt + $format (" rd %0d rdval %0h", td.rd, td.word1);
|
||||
|
||||
else if (td.op == TRACE_CSR_WRITE)
|
||||
fmt = fmt + $format (" csraddr %0h csrval %0h", td.word3, td.word4);
|
||||
fmt = fmt + $format (" csraddr %0h csrval %0h", td.word3, td.word4);
|
||||
|
||||
else if (td.op == TRACE_MEM_WRITE)
|
||||
fmt = fmt + $format (" sz %0d stval %0h paddr %0h", td.word1, td.word2, td.word3);
|
||||
fmt = fmt + $format (" sz %0d stval %0h paddr %0h", td.word1, td.word2, td.word3);
|
||||
|
||||
else begin
|
||||
fmt = fmt + $format (" pc %0h", td.pc);
|
||||
fmt = fmt + $format (" pc %0h", td.pc);
|
||||
|
||||
if (td.op != TRACE_INTR)
|
||||
fmt = fmt + $format (" instr.%0d %0h:", pack (td.instr_sz), td.instr);
|
||||
if (td.op != TRACE_INTR)
|
||||
fmt = fmt + $format (" instr.%0d %0h:", pack (td.instr_sz), td.instr);
|
||||
|
||||
if ((td.op == TRACE_I_RD) || (td.op == TRACE_F_RD))
|
||||
fmt = fmt + $format (" rd %0d rdval %0h", td.rd, td.word1);
|
||||
if (td.op == TRACE_I_RD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h", td.rd, td.word1);
|
||||
`ifdef ISA_F
|
||||
else if (td.op == TRACE_F_FRD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h fflags %05b", td.rd, td.word5, td.word2);
|
||||
|
||||
else if ((td.op == TRACE_I_LOAD) || (td.op == TRACE_F_LOAD))
|
||||
fmt = fmt + $format (" rd %0d rdval %0h eaddr %0h",
|
||||
td.rd, td.word1, td.word3);
|
||||
else if (td.op == TRACE_F_GRD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h fflags %05b", td.rd, td.word1, td.word2);
|
||||
|
||||
else if (td.op == TRACE_STORE)
|
||||
fmt = fmt + $format (" stval %0h eaddr %0h", td.word2, td.word3);
|
||||
else if (td.op == TRACE_F_LOAD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h eaddr %0h",
|
||||
td.rd, td.word5, td.word3);
|
||||
|
||||
else if (td.op == TRACE_AMO)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h stval %0h eaddr %0h",
|
||||
td.rd, td.word1, td.word2, td.word3);
|
||||
else if (td.op == TRACE_F_STORE)
|
||||
fmt = fmt + $format (" stval %0h eaddr %0h", td.word5, td.word3);
|
||||
`endif
|
||||
else if (td.op == TRACE_I_LOAD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h eaddr %0h",
|
||||
td.rd, td.word1, td.word3);
|
||||
|
||||
else if (td.op == TRACE_CSRRX)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h csraddr %0h csrval %0h",
|
||||
td.rd, td.word1, td.word3, td.word4);
|
||||
else if (td.op == TRACE_I_STORE)
|
||||
fmt = fmt + $format (" stval %0h eaddr %0h", td.word2, td.word3);
|
||||
|
||||
else if ((td.op == TRACE_TRAP) || (td.op == TRACE_INTR))
|
||||
fmt = fmt + $format (" priv %0d mstatus %0h mcause %0h mepc %0h mtval %0h",
|
||||
td.rd, td.word1, td.word2, td.word3, td.word4);
|
||||
else if (td.op == TRACE_AMO)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h stval %0h eaddr %0h",
|
||||
td.rd, td.word1, td.word2, td.word3);
|
||||
|
||||
else if (td.op == TRACE_RET)
|
||||
fmt = fmt + $format (" priv %0d mstatus %0h", td.rd, td.word1);
|
||||
else if (td.op == TRACE_CSRRX)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h csraddr %0h csrval %0h",
|
||||
td.rd, td.word1, td.word3, td.word4);
|
||||
|
||||
else if ((td.op == TRACE_TRAP) || (td.op == TRACE_INTR))
|
||||
fmt = fmt + $format (" priv %0d mstatus %0h mcause %0h mepc %0h mtval %0h",
|
||||
td.rd, td.word1, td.word2, td.word3, td.word4);
|
||||
|
||||
else if (td.op == TRACE_RET)
|
||||
fmt = fmt + $format (" priv %0d mstatus %0h", td.rd, td.word1);
|
||||
end
|
||||
|
||||
fmt = fmt + $format ("}");
|
||||
|
||||
Reference in New Issue
Block a user