Merge branch 'CHERI' into pdr32-tmp

and get it to build!
This commit is contained in:
Jonathan Woodruff
2020-03-26 18:03:58 +00:00
1115 changed files with 1472029 additions and 327565 deletions

View File

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

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

View File

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

View File

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

View File

@@ -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 ("}");