Merge branch 'CHERI' of https://github.com/CTSRD-CHERI/Toooba into CHERI

This commit is contained in:
jon
2021-06-01 15:18:29 +01:00
17 changed files with 422 additions and 311 deletions

View File

@@ -3,6 +3,7 @@
// RVFI_DII + CHERI modifications:
// Copyright (c) 2020 Jessica Clarke
// Copyright (c) 2020 Jonathan Woodruff
// Copyright (c) 2020 Peter Rugg
// All rights reserved.
//
// This software was developed by SRI International and the University of
@@ -38,71 +39,72 @@ export fv_decode_C;
// ================================================================
// Project imports
import ISA_Decls :: *;
import ISA_Decls :: *;
import ISA_Decls_CHERI :: *;
// ================================================================
function Instr fv_decode_C (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Instr fv_decode_C (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
// ----------------
// Try each possible C instruction
match { .valid_C_LWSP, .i_C_LWSP } = fv_decode_C_LWSP (misa, xl, instr_C);
match { .valid_C_SWSP, .i_C_SWSP } = fv_decode_C_SWSP (misa, xl, instr_C);
match { .valid_C_LW, .i_C_LW } = fv_decode_C_LW (misa, xl, instr_C);
match { .valid_C_SW, .i_C_SW } = fv_decode_C_SW (misa, xl, instr_C);
match { .valid_C_LWSP, .i_C_LWSP } = fv_decode_C_LWSP (misa, xl, cap_enc, instr_C);
match { .valid_C_SWSP, .i_C_SWSP } = fv_decode_C_SWSP (misa, xl, cap_enc, instr_C);
match { .valid_C_LW, .i_C_LW } = fv_decode_C_LW (misa, xl, cap_enc, instr_C);
match { .valid_C_SW, .i_C_SW } = fv_decode_C_SW (misa, xl, cap_enc, instr_C);
match { .valid_C_J, .i_C_J } = fv_decode_C_J (misa, xl, instr_C);
match { .valid_C_JAL, .i_C_JAL } = fv_decode_C_JAL (misa, xl, instr_C);
match { .valid_C_JR, .i_C_JR } = fv_decode_C_JR (misa, xl, instr_C);
match { .valid_C_JALR, .i_C_JALR } = fv_decode_C_JALR (misa, xl, instr_C);
match { .valid_C_BEQZ, .i_C_BEQZ } = fv_decode_C_BEQZ (misa, xl, instr_C);
match { .valid_C_BNEZ, .i_C_BNEZ } = fv_decode_C_BNEZ (misa, xl, instr_C);
match { .valid_C_LI, .i_C_LI } = fv_decode_C_LI (misa, xl, instr_C);
match { .valid_C_LUI, .i_C_LUI } = fv_decode_C_LUI (misa, xl, instr_C);
match { .valid_C_ADDI, .i_C_ADDI } = fv_decode_C_ADDI (misa, xl, instr_C);
match { .valid_C_NOP, .i_C_NOP } = fv_decode_C_NOP (misa, xl, instr_C);
match { .valid_C_ADDIW, .i_C_ADDIW } = fv_decode_C_ADDIW (misa, xl, instr_C);
match { .valid_C_ADDI16SP, .i_C_ADDI16SP } = fv_decode_C_ADDI16SP (misa, xl, instr_C);
match { .valid_C_ADDI4SPN, .i_C_ADDI4SPN } = fv_decode_C_ADDI4SPN (misa, xl, instr_C);
match { .valid_C_SLLI, .i_C_SLLI } = fv_decode_C_SLLI (misa, xl, instr_C);
match { .valid_C_SRLI, .i_C_SRLI } = fv_decode_C_SRLI (misa, xl, instr_C);
match { .valid_C_SRAI, .i_C_SRAI } = fv_decode_C_SRAI (misa, xl, instr_C);
match { .valid_C_ANDI, .i_C_ANDI } = fv_decode_C_ANDI (misa, xl, instr_C);
match { .valid_C_MV, .i_C_MV } = fv_decode_C_MV (misa, xl, instr_C);
match { .valid_C_ADD, .i_C_ADD } = fv_decode_C_ADD (misa, xl, instr_C);
match { .valid_C_AND, .i_C_AND } = fv_decode_C_AND (misa, xl, instr_C);
match { .valid_C_OR, .i_C_OR } = fv_decode_C_OR (misa, xl, instr_C);
match { .valid_C_XOR, .i_C_XOR } = fv_decode_C_XOR (misa, xl, instr_C);
match { .valid_C_SUB, .i_C_SUB } = fv_decode_C_SUB (misa, xl, instr_C);
match { .valid_C_ADDW, .i_C_ADDW } = fv_decode_C_ADDW (misa, xl, instr_C);
match { .valid_C_SUBW, .i_C_SUBW } = fv_decode_C_SUBW (misa, xl, instr_C);
match { .valid_C_EBREAK, .i_C_EBREAK } = fv_decode_C_EBREAK (misa, xl, instr_C);
match { .valid_C_J, .i_C_J } = fv_decode_C_J (misa, xl, cap_enc, instr_C);
match { .valid_C_JAL, .i_C_JAL } = fv_decode_C_JAL (misa, xl, cap_enc, instr_C);
match { .valid_C_JR, .i_C_JR } = fv_decode_C_JR (misa, xl, cap_enc, instr_C);
match { .valid_C_JALR, .i_C_JALR } = fv_decode_C_JALR (misa, xl, cap_enc, instr_C);
match { .valid_C_BEQZ, .i_C_BEQZ } = fv_decode_C_BEQZ (misa, xl, cap_enc, instr_C);
match { .valid_C_BNEZ, .i_C_BNEZ } = fv_decode_C_BNEZ (misa, xl, cap_enc, instr_C);
match { .valid_C_LI, .i_C_LI } = fv_decode_C_LI (misa, xl, cap_enc, instr_C);
match { .valid_C_LUI, .i_C_LUI } = fv_decode_C_LUI (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDI, .i_C_ADDI } = fv_decode_C_ADDI (misa, xl, cap_enc, instr_C);
match { .valid_C_NOP, .i_C_NOP } = fv_decode_C_NOP (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDIW, .i_C_ADDIW } = fv_decode_C_ADDIW (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDI16SP, .i_C_ADDI16SP } = fv_decode_C_ADDI16SP (misa, xl, cap_enc, instr_C);
match { .valid_C_CIncOffsetImm16CSP, .i_C_CIncOffsetImm16CSP } = fv_decode_C_CIncOffsetImm16CSP (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDI4SPN, .i_C_ADDI4SPN } = fv_decode_C_ADDI4SPN (misa, xl, cap_enc, instr_C);
match { .valid_C_CIncOffsetImm4CSPN, .i_C_CIncOffsetImm4CSPN } = fv_decode_C_CIncOffsetImm4CSPN (misa, xl, cap_enc, instr_C);
match { .valid_C_SLLI, .i_C_SLLI } = fv_decode_C_SLLI (misa, xl, cap_enc, instr_C);
match { .valid_C_SRLI, .i_C_SRLI } = fv_decode_C_SRLI (misa, xl, cap_enc, instr_C);
match { .valid_C_SRAI, .i_C_SRAI } = fv_decode_C_SRAI (misa, xl, cap_enc, instr_C);
match { .valid_C_ANDI, .i_C_ANDI } = fv_decode_C_ANDI (misa, xl, cap_enc, instr_C);
match { .valid_C_MV, .i_C_MV } = fv_decode_C_MV (misa, xl, cap_enc, instr_C);
match { .valid_C_ADD, .i_C_ADD } = fv_decode_C_ADD (misa, xl, cap_enc, instr_C);
match { .valid_C_AND, .i_C_AND } = fv_decode_C_AND (misa, xl, cap_enc, instr_C);
match { .valid_C_OR, .i_C_OR } = fv_decode_C_OR (misa, xl, cap_enc, instr_C);
match { .valid_C_XOR, .i_C_XOR } = fv_decode_C_XOR (misa, xl, cap_enc, instr_C);
match { .valid_C_SUB, .i_C_SUB } = fv_decode_C_SUB (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDW, .i_C_ADDW } = fv_decode_C_ADDW (misa, xl, cap_enc, instr_C);
match { .valid_C_SUBW, .i_C_SUBW } = fv_decode_C_SUBW (misa, xl, cap_enc, instr_C);
match { .valid_C_EBREAK, .i_C_EBREAK } = fv_decode_C_EBREAK (misa, xl, cap_enc, instr_C);
match { .valid_C_LDSP, .i_C_LDSP } = fv_decode_C_LDSP (misa, xl, cap_enc, instr_C);
match { .valid_C_SDSP, .i_C_SDSP } = fv_decode_C_SDSP (misa, xl, cap_enc, instr_C);
match { .valid_C_LD, .i_C_LD } = fv_decode_C_LD (misa, xl, cap_enc, instr_C);
match { .valid_C_SD, .i_C_SD } = fv_decode_C_SD (misa, xl, cap_enc, instr_C);
`ifdef RV64
match { .valid_C_LDSP, .i_C_LDSP } = fv_decode_C_LDSP (misa, xl, instr_C);
match { .valid_C_SDSP, .i_C_SDSP } = fv_decode_C_SDSP (misa, xl, instr_C);
match { .valid_C_LD, .i_C_LD } = fv_decode_C_LD (misa, xl, instr_C);
match { .valid_C_SD, .i_C_SD } = fv_decode_C_SD (misa, xl, instr_C);
`endif
`ifdef RV128
match { .valid_C_LQSP, .i_C_LQSP } = fv_decode_C_LQSP (misa, xl, instr_C);
match { .valid_C_SQSP, .i_C_SQSP } = fv_decode_C_SQSP (misa, xl, instr_C);
match { .valid_C_LQ, .i_C_LQ } = fv_decode_C_LQ (misa, xl, instr_C);
match { .valid_C_SQ, .i_C_SQ } = fv_decode_C_SQ (misa, xl, instr_C);
match { .valid_C_LQSP, .i_C_LQSP } = fv_decode_C_LQSP (misa, xl, cap_enc, instr_C);
match { .valid_C_SQSP, .i_C_SQSP } = fv_decode_C_SQSP (misa, xl, cap_enc, instr_C);
match { .valid_C_LQ, .i_C_LQ } = fv_decode_C_LQ (misa, xl, cap_enc, instr_C);
match { .valid_C_SQ, .i_C_SQ } = fv_decode_C_SQ (misa, xl, cap_enc, instr_C);
`endif
`ifdef ISA_F
match { .valid_C_FLWSP, .i_C_FLWSP } = fv_decode_C_FLWSP (misa, xl, instr_C);
match { .valid_C_FSWSP, .i_C_FSWSP } = fv_decode_C_FSWSP (misa, xl, instr_C);
match { .valid_C_FLW, .i_C_FLW } = fv_decode_C_FLW (misa, xl, instr_C);
match { .valid_C_FSW, .i_C_FSW } = fv_decode_C_FSW (misa, xl, instr_C);
match { .valid_C_FLWSP, .i_C_FLWSP } = fv_decode_C_FLWSP (misa, xl, cap_enc, instr_C);
match { .valid_C_FSWSP, .i_C_FSWSP } = fv_decode_C_FSWSP (misa, xl, cap_enc, instr_C);
match { .valid_C_FLW, .i_C_FLW } = fv_decode_C_FLW (misa, xl, cap_enc, instr_C);
match { .valid_C_FSW, .i_C_FSW } = fv_decode_C_FSW (misa, xl, cap_enc, instr_C);
`endif
`ifdef ISA_D
match { .valid_C_FLDSP, .i_C_FLDSP } = fv_decode_C_FLDSP (misa, xl, instr_C);
match { .valid_C_FSDSP, .i_C_FSDSP } = fv_decode_C_FSDSP (misa, xl, instr_C);
match { .valid_C_FLD, .i_C_FLD } = fv_decode_C_FLD (misa, xl, instr_C);
match { .valid_C_FSD, .i_C_FSD } = fv_decode_C_FSD (misa, xl, instr_C);
match { .valid_C_FLDSP, .i_C_FLDSP } = fv_decode_C_FLDSP (misa, xl, cap_enc, instr_C);
match { .valid_C_FSDSP, .i_C_FSDSP } = fv_decode_C_FSDSP (misa, xl, cap_enc, instr_C);
match { .valid_C_FLD, .i_C_FLD } = fv_decode_C_FLD (misa, xl, cap_enc, instr_C);
match { .valid_C_FSD, .i_C_FSD } = fv_decode_C_FSD (misa, xl, cap_enc, instr_C);
`endif
// ----------------
@@ -110,64 +112,64 @@ function Instr fv_decode_C (MISA misa, Bit #(2) xl, Instr_C instr_C);
Instr instr = ?;
if (valid_C_LWSP) instr = i_C_LWSP;
else if (valid_C_SWSP) instr = i_C_SWSP;
else if (valid_C_LW) instr = i_C_LW;
else if (valid_C_SW) instr = i_C_SW;
if (valid_C_LWSP) instr = i_C_LWSP;
else if (valid_C_SWSP) instr = i_C_SWSP;
else if (valid_C_LW) instr = i_C_LW;
else if (valid_C_SW) instr = i_C_SW;
else if (valid_C_J) instr = i_C_J;
else if (valid_C_JAL) instr = i_C_JAL;
else if (valid_C_JR) instr = i_C_JR;
else if (valid_C_JALR) instr = i_C_JALR;
else if (valid_C_BEQZ) instr = i_C_BEQZ;
else if (valid_C_BNEZ) instr = i_C_BNEZ;
else if (valid_C_LI) instr = i_C_LI;
else if (valid_C_LUI) instr = i_C_LUI;
else if (valid_C_ADDI) instr = i_C_ADDI;
else if (valid_C_NOP) instr = i_C_NOP;
else if (valid_C_ADDIW) instr = i_C_ADDIW;
else if (valid_C_ADDI16SP) instr = i_C_ADDI16SP;
else if (valid_C_ADDI4SPN) instr = i_C_ADDI4SPN;
else if (valid_C_SLLI) instr = i_C_SLLI;
else if (valid_C_SRLI) instr = i_C_SRLI;
else if (valid_C_SRAI) instr = i_C_SRAI;
else if (valid_C_ANDI) instr = i_C_ANDI;
else if (valid_C_MV) instr = i_C_MV;
else if (valid_C_ADD) instr = i_C_ADD;
else if (valid_C_AND) instr = i_C_AND;
else if (valid_C_OR) instr = i_C_OR;
else if (valid_C_XOR) instr = i_C_XOR;
else if (valid_C_SUB) instr = i_C_SUB;
else if (valid_C_ADDW) instr = i_C_ADDW;
else if (valid_C_SUBW) instr = i_C_SUBW;
else if (valid_C_EBREAK) instr = i_C_EBREAK;
else if (valid_C_J) instr = i_C_J;
else if (valid_C_JAL) instr = i_C_JAL;
else if (valid_C_JR) instr = i_C_JR;
else if (valid_C_JALR) instr = i_C_JALR;
else if (valid_C_BEQZ) instr = i_C_BEQZ;
else if (valid_C_BNEZ) instr = i_C_BNEZ;
else if (valid_C_LI) instr = i_C_LI;
else if (valid_C_LUI) instr = i_C_LUI;
else if (valid_C_ADDI) instr = i_C_ADDI;
else if (valid_C_NOP) instr = i_C_NOP;
else if (valid_C_ADDIW) instr = i_C_ADDIW;
else if (valid_C_ADDI16SP) instr = i_C_ADDI16SP;
else if (valid_C_CIncOffsetImm16CSP) instr = i_C_CIncOffsetImm16CSP;
else if (valid_C_ADDI4SPN) instr = i_C_ADDI4SPN;
else if (valid_C_CIncOffsetImm4CSPN) instr = i_C_CIncOffsetImm4CSPN;
else if (valid_C_SLLI) instr = i_C_SLLI;
else if (valid_C_SRLI) instr = i_C_SRLI;
else if (valid_C_SRAI) instr = i_C_SRAI;
else if (valid_C_ANDI) instr = i_C_ANDI;
else if (valid_C_MV) instr = i_C_MV;
else if (valid_C_ADD) instr = i_C_ADD;
else if (valid_C_AND) instr = i_C_AND;
else if (valid_C_OR) instr = i_C_OR;
else if (valid_C_XOR) instr = i_C_XOR;
else if (valid_C_SUB) instr = i_C_SUB;
else if (valid_C_ADDW) instr = i_C_ADDW;
else if (valid_C_SUBW) instr = i_C_SUBW;
else if (valid_C_EBREAK) instr = i_C_EBREAK;
`ifdef RV64
else if (valid_C_LDSP) instr = i_C_LDSP;
else if (valid_C_SDSP) instr = i_C_SDSP;
else if (valid_C_LD) instr = i_C_LD;
else if (valid_C_SD) instr = i_C_SD;
else if (valid_C_LDSP) instr = i_C_LDSP;
else if (valid_C_SDSP) instr = i_C_SDSP;
else if (valid_C_LD) instr = i_C_LD;
else if (valid_C_SD) instr = i_C_SD;
`endif
`ifdef RV128
else if (valid_C_LQSP) instr = i_C_LQSP;
else if (valid_C_SQSP) instr = i_C_SQSP;
else if (valid_C_LQ) instr = i_C_LQ;
else if (valid_C_SQ) instr = i_C_SQ;
`endif
else if (valid_C_LQSP) instr = i_C_LQSP;
else if (valid_C_SQSP) instr = i_C_SQSP;
else if (valid_C_LQ) instr = i_C_LQ;
else if (valid_C_SQ) instr = i_C_SQ;
`ifdef ISA_F
else if (valid_C_FLWSP) instr = i_C_FLWSP;
else if (valid_C_FSWSP) instr = i_C_FSWSP;
else if (valid_C_FLW) instr = i_C_FLW;
else if (valid_C_FSW) instr = i_C_FSW;
else if (valid_C_FLWSP) instr = i_C_FLWSP;
else if (valid_C_FSWSP) instr = i_C_FSWSP;
else if (valid_C_FLW) instr = i_C_FLW;
else if (valid_C_FSW) instr = i_C_FSW;
`endif
`ifdef ISA_D
else if (valid_C_FLDSP) instr = i_C_FLDSP;
else if (valid_C_FSDSP) instr = i_C_FSDSP;
else if (valid_C_FLD) instr = i_C_FLD;
else if (valid_C_FSD) instr = i_C_FSD;
else if (valid_C_FLDSP) instr = i_C_FLDSP;
else if (valid_C_FSDSP) instr = i_C_FSDSP;
else if (valid_C_FLD) instr = i_C_FLD;
else if (valid_C_FSD) instr = i_C_FSD;
`endif
else
@@ -180,7 +182,7 @@ endfunction
// 'C' Extension Stack-Pointer-Based Loads
// LWSP: expands into LW
function Tuple2 #(Bool, Instr) fv_decode_C_LWSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LWSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -198,9 +200,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LWSP (MISA misa, Bit #(2) xl, Instr
end
endfunction
`ifdef RV64
// LDSP: expands into LD
function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -211,7 +212,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Instr
&& (rd != 0)
&& (funct3 == funct3_C_LDSP)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
|| (cap_enc)));
RegName rs1 = reg_sp;
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LD, rd, op_LOAD);
@@ -219,11 +220,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Instr
return tuple2 (is_legal, instr);
end
endfunction
`endif
`ifdef RV128
`ifdef RV64
// LQSP: expands into LQ
function Tuple2 #(Bool, Instr) fv_decode_C_LQSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LQSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -233,10 +233,11 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LQSP (MISA misa, Bit #(2) xl, Instr
&& (op == opcode_C2)
&& (rd != 0)
&& (funct3 == funct3_C_LQSP)
&& (xl == misa_mxl_128));
&& (xl == misa_mxl_64)
&& (cap_enc));
RegName rs1 = reg_sp;
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_LOAD);
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_MISC_MEM);
return tuple2 (is_legal, instr);
end
@@ -245,7 +246,7 @@ endfunction
`ifdef ISA_F
// FLWSP: expands into FLW
function Tuple2 #(Bool, Instr) fv_decode_C_FLWSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FLWSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -254,7 +255,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLWSP (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C2)
&& (funct3 == funct3_C_FLWSP)
&& (misa.f == 1'b1));
&& (misa.f == 1'b1)
&& (! cap_enc));
RegName rs1 = reg_sp;
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLW, rd, op_LOAD_FP);
@@ -266,7 +268,7 @@ endfunction
`ifdef ISA_D
// FLDSP: expands into FLD
function Tuple2 #(Bool, Instr) fv_decode_C_FLDSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FLDSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -276,8 +278,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLDSP (MISA misa, Bit #(2) xl, Inst
&& (op == opcode_C2)
&& (funct3 == funct3_C_FLDSP)
&& (misa.d == 1'b1)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& ( (xl == misa_mxl_32)
|| (! cap_enc)));
RegName rs1 = reg_sp;
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLD, rd, op_LOAD_FP);
@@ -291,7 +293,7 @@ endfunction
// 'C' Extension Stack-Pointer-Based Stores
// SWSP: expands to SW
function Tuple2 #(Bool, Instr) fv_decode_C_SWSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SWSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -308,9 +310,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SWSP (MISA misa, Bit #(2) xl, Inst
end
endfunction
`ifdef RV64
// SDSP: expands to SD
function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -320,7 +321,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Inst
&& (op == opcode_C2)
&& (funct3 == funct3_C_SDSP)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
|| (cap_enc)));
RegName rs1 = reg_sp;
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SD, op_STORE);
@@ -328,11 +329,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Inst
return tuple2 (is_legal, instr);
end
endfunction
`endif
`ifdef RV128
`ifdef RV64
// SQSP: expands to SQ
function Tuple2 #(Bool, Instr) fv_decode_C_SQSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SQSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -341,7 +341,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SQSP (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C2)
&& (funct3 == funct3_C_SQSP)
&& (xl == misa_mxl_128));
&& (xl == misa_mxl_64)
&& (cap_enc));
RegName rs1 = reg_sp;
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SQ, op_STORE);
@@ -353,7 +354,7 @@ endfunction
`ifdef ISA_F
// FSWSP: expands to FSW
function Tuple2 #(Bool, Instr) fv_decode_C_FSWSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FSWSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -361,7 +362,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSWSP (MISA misa, Bit #(2) xl, Ins
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C2)
&& (funct3 == funct3_C_FSWSP));
&& (funct3 == funct3_C_FSWSP)
&& (xl == misa_mxl_32)
&& (! cap_enc));
RegName rs1 = reg_sp;
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSW, op_STORE_FP);
@@ -373,7 +376,7 @@ endfunction
`ifdef ISA_D
// FSDSP: expands to FSD
function Tuple2 #(Bool, Instr) fv_decode_C_FSDSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FSDSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -382,8 +385,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSDSP (MISA misa, Bit #(2) xl, Ins
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C2)
&& (funct3 == funct3_C_FSDSP)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& ( (xl == misa_mxl_32)
|| (! cap_enc)));
RegName rs1 = reg_sp;
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSD, op_STORE_FP);
@@ -397,7 +400,7 @@ endfunction
// 'C' Extension Register-Based Loads
// C_LW: expands to LW
function Tuple2 #(Bool, Instr) fv_decode_C_LW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -413,9 +416,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LW (MISA misa, Bit #(2) xl, Instr
end
endfunction
`ifdef RV64
// C_LD: expands to LD
function Tuple2 #(Bool, Instr) fv_decode_C_LD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -425,18 +427,17 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LD (MISA misa, Bit #(2) xl, Instr
&& (op == opcode_C0)
&& (funct3 == funct3_C_LD)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
|| (cap_enc)));
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LD, rd, op_LOAD);
return tuple2 (is_legal, instr);
end
endfunction
`endif
`ifdef RV128
`ifdef RV64
// C_LQ: expands to LQ
function Tuple2 #(Bool, Instr) fv_decode_C_LQ (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LQ (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -445,9 +446,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LQ (MISA misa, Bit #(2) xl, Instr
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_LQ)
&& (xl == misa_mxl_128));
&& (xl == misa_mxl_64)
&& (cap_enc));
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_LOAD);
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_MISC_MEM);
return tuple2 (is_legal, instr);
end
@@ -456,7 +458,7 @@ endfunction
`ifdef ISA_F
// C_FLW: expands to FLW
function Tuple2 #(Bool, Instr) fv_decode_C_FLW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FLW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -464,7 +466,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLW (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_FLW));
&& (funct3 == funct3_C_FLW)
&& (xl == misa_mxl_32)
&& (! cap_enc));
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLW, rd, op_LOAD_FP);
@@ -475,7 +479,7 @@ endfunction
`ifdef ISA_D
// C_FLD: expands to FLD
function Tuple2 #(Bool, Instr) fv_decode_C_FLD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FLD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -484,8 +488,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLD (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_FLD)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& ( (xl == misa_mxl_32)
|| (! cap_enc)));
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLD, rd, op_LOAD_FP);
@@ -498,7 +502,7 @@ endfunction
// 'C' Extension Register-Based Stores
// C_SW: expands to SW
function Tuple2 #(Bool, Instr) fv_decode_C_SW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -514,9 +518,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SW (MISA misa, Bit #(2) xl, Instr
end
endfunction
`ifdef RV64
// C_SD: expands to SD
function Tuple2 #(Bool, Instr) fv_decode_C_SD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -524,18 +527,19 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SD (MISA misa, Bit #(2) xl, Instr
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_SD));
&& (funct3 == funct3_C_SD)
&& ( (xl == misa_mxl_64)
|| (cap_enc)));
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SD, op_STORE);
return tuple2 (is_legal, instr);
end
endfunction
`endif
`ifdef RV128
`ifdef RV64
// C_SQ: expands to SQ
function Tuple2 #(Bool, Instr) fv_decode_C_SQ (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SQ (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -543,7 +547,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SQ (MISA misa, Bit #(2) xl, Instr
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_SQ));
&& (funct3 == funct3_C_SQ)
&& (xl == misa_mxl_64)
&& (cap_enc));
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SQ, op_STORE);
@@ -554,7 +560,7 @@ endfunction
`ifdef ISA_F
// C_FSW: expands to FSW
function Tuple2 #(Bool, Instr) fv_decode_C_FSW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FSW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -562,7 +568,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSW (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_FSW));
&& (funct3 == funct3_C_FSW)
&& (xl == misa_mxl_32)
&& (! cap_enc));
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSW, op_STORE_FP);
@@ -573,7 +581,7 @@ endfunction
`ifdef ISA_D
// C_FSD: expands to FSD
function Tuple2 #(Bool, Instr) fv_decode_C_FSD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FSD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -581,7 +589,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSD (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_FSD));
&& (funct3 == funct3_C_FSD)
&& ( (xl == misa_mxl_32)
|| (! cap_enc)));
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSD, op_STORE_FP);
@@ -595,7 +605,7 @@ endfunction
// C.J, C.JAL, C.JR, C.JALR, C.BEQZ, C.BNEZ
// C.J: expands to JAL
function Tuple2 #(Bool, Instr) fv_decode_C_J (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_J (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CJ-type
match { .funct3, .imm_at_12_2, .op } = fv_ifields_CJ_type (instr_C);
@@ -622,7 +632,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_J (MISA misa, Bit #(2) xl, Instr_
endfunction
// C.JAL: expands to JAL
function Tuple2 #(Bool, Instr) fv_decode_C_JAL (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_JAL (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CJ-type
match { .funct3, .imm_at_12_2, .op } = fv_ifields_CJ_type (instr_C);
@@ -650,7 +660,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JAL (MISA misa, Bit #(2) xl, Inst
endfunction
// C.JR: expands to JALR
function Tuple2 #(Bool, Instr) fv_decode_C_JR (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_JR (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CR-type
match { .funct4, .rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
@@ -669,7 +679,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JR (MISA misa, Bit #(2) xl, Instr
endfunction
// C.JALR: expands to JALR
function Tuple2 #(Bool, Instr) fv_decode_C_JALR (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_JALR (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CR-type
match { .funct4, .rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
@@ -689,7 +699,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JALR (MISA misa, Bit #(2) xl, Ins
endfunction
// C.BEQZ: expands to BEQ
function Tuple2 #(Bool, Instr) fv_decode_C_BEQZ (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_BEQZ (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -708,7 +718,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_BEQZ (MISA misa, Bit #(2) xl, Ins
endfunction
// C.BNEZ: expands to BNE
function Tuple2 #(Bool, Instr) fv_decode_C_BNEZ (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_BNEZ (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -730,7 +740,7 @@ endfunction
// 'C' Extension Integer Constant-Generation
// C.LI: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_LI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -750,7 +760,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LI (MISA misa, Bit #(2) xl, Instr
endfunction
// C.LUI: expands to LUI
function Tuple2 #(Bool, Instr) fv_decode_C_LUI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LUI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -774,7 +784,7 @@ endfunction
// 'C' Extension Integer Register-Immediate Operations
// C.ADDI: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -794,7 +804,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI (MISA misa, Bit #(2) xl, Ins
endfunction
// C.NOP: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_NOP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_NOP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -814,7 +824,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_NOP (MISA misa, Bit #(2) xl, Inst
endfunction
// C.ADDIW: expands to ADDIW
function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -824,8 +834,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, In
&& (op == opcode_C1)
&& (funct3 == funct3_C_ADDIW)
&& (rd_rs1 != 0)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& (xl == misa_mxl_64));
Bit #(12) imm12 = signExtend (imm6);
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ADDIW, rd_rs1, op_OP_IMM_32);
@@ -835,7 +844,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, In
endfunction
// C.ADDI16SP: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -845,7 +854,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl,
&& (op == opcode_C1)
&& (funct3 == funct3_C_ADDI16SP)
&& (rd_rs1 == reg_sp)
&& (nzimm10 != 0));
&& (nzimm10 != 0)
&& (! cap_enc));
Bit #(12) imm12 = signExtend (nzimm10);
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ADDI, rd_rs1, op_OP_IMM);
@@ -854,8 +864,29 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl,
end
endfunction
// C.CIncOffsetImm16CSP: expands to CIncOffsetImm
function Tuple2 #(Bool, Instr) fv_decode_C_CIncOffsetImm16CSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
Bit #(10) nzimm10 = { imm_at_12, imm_at_6_2 [2:1], imm_at_6_2 [3], imm_at_6_2 [0], imm_at_6_2 [4], 4'b0 };
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C1)
&& (funct3 == funct3_C_CIncOffsetImm16CSP)
&& (rd_rs1 == reg_sp)
&& (nzimm10 != 0)
&& (cap_enc));
Bit #(12) imm12 = signExtend (nzimm10);
let instr = mkInstr_I_type (imm12, rd_rs1, f3_cap_CIncOffsetImmediate, rd_rs1, op_cap_Manip);
return tuple2 (is_legal, instr);
end
endfunction
// C.ADDI4SPN: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CIW-type
match { .funct3, .imm_at_12_5, .rd, .op } = fv_ifields_CIW_type (instr_C);
@@ -864,7 +895,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl,
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_ADDI4SPN)
&& (nzimm10 != 0));
&& (nzimm10 != 0)
&& (! cap_enc));
RegName rs1 = reg_sp;
Bit #(12) imm12 = zeroExtend (nzimm10);
@@ -874,8 +906,29 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl,
end
endfunction
// C.CIncOffsetImm4CSPN: expands to CIncOffsetImm
function Tuple2 #(Bool, Instr) fv_decode_C_CIncOffsetImm4CSPN (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CIW-type
match { .funct3, .imm_at_12_5, .rd, .op } = fv_ifields_CIW_type (instr_C);
Bit #(10) nzimm10 = { imm_at_12_5 [5:2], imm_at_12_5 [7:6], imm_at_12_5 [0], imm_at_12_5 [1], 2'b0 };
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_CIncOffsetImm4CSPN)
&& (nzimm10 != 0)
&& (cap_enc));
RegName rs1 = reg_sp;
Bit #(12) imm12 = zeroExtend (nzimm10);
let instr = mkInstr_I_type (imm12, rs1, f3_cap_CIncOffsetImmediate, rd, op_cap_Manip);
return tuple2 (is_legal, instr);
end
endfunction
// C.SLLI: expands to SLLI
function Tuple2 #(Bool, Instr) fv_decode_C_SLLI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SLLI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -898,7 +951,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SLLI (MISA misa, Bit #(2) xl, Ins
endfunction
// C.SRLI: expands to SRLI
function Tuple2 #(Bool, Instr) fv_decode_C_SRLI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SRLI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -924,7 +977,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SRLI (MISA misa, Bit #(2) xl, Ins
endfunction
// C.SRAI: expands to SRAI
function Tuple2 #(Bool, Instr) fv_decode_C_SRAI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SRAI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -950,7 +1003,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SRAI (MISA misa, Bit #(2) xl, Ins
endfunction
// C.ANDI: expands to ANDI
function Tuple2 #(Bool, Instr) fv_decode_C_ANDI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ANDI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -974,7 +1027,7 @@ endfunction
// 'C' Extension Integer Register-Register Operations
// C.MV: expands to ADD
function Tuple2 #(Bool, Instr) fv_decode_C_MV (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_MV (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
@@ -992,7 +1045,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_MV (MISA misa, Bit #(2) xl, Instr
endfunction
// C.ADD: expands to ADD
function Tuple2 #(Bool, Instr) fv_decode_C_ADD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
@@ -1009,7 +1062,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADD (MISA misa, Bit #(2) xl, Inst
endfunction
// C.AND: expands to AND
function Tuple2 #(Bool, Instr) fv_decode_C_AND (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_AND (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1026,7 +1079,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_AND (MISA misa, Bit #(2) xl, Inst
endfunction
// C.OR: expands to OR
function Tuple2 #(Bool, Instr) fv_decode_C_OR (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_OR (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1043,7 +1096,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_OR (MISA misa, Bit #(2) xl, Instr
endfunction
// C.XOR: expands to XOR
function Tuple2 #(Bool, Instr) fv_decode_C_XOR (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_XOR (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1060,7 +1113,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_XOR (MISA misa, Bit #(2) xl, Inst
endfunction
// C.SUB: expands to SUB
function Tuple2 #(Bool, Instr) fv_decode_C_SUB (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SUB (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1077,7 +1130,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SUB (MISA misa, Bit #(2) xl, Inst
endfunction
// C.ADDW: expands to ADDW
function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1086,8 +1139,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Ins
&& (op == opcode_C1)
&& (funct6 == funct6_C_ADDW)
&& (funct2 == funct2_C_ADDW)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& (xl == misa_mxl_64));
let instr = mkInstr_R_type (funct7_ADDW, rs2, rd_rs1, funct3_ADDW, rd_rs1, op_OP_32);
@@ -1096,7 +1148,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Ins
endfunction
// C.SUBW: expands to SUBW
function Tuple2 #(Bool, Instr) fv_decode_C_SUBW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SUBW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1105,8 +1157,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SUBW (MISA misa, Bit #(2) xl, Ins
&& (op == opcode_C1)
&& (funct6 == funct6_C_SUBW)
&& (funct2 == funct2_C_SUBW)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& ((xl == misa_mxl_64)));
let instr = mkInstr_R_type (funct7_SUBW, rs2, rd_rs1, funct3_SUBW, rd_rs1, op_OP_32);
@@ -1118,7 +1169,7 @@ endfunction
// 'C' Extension EBREAK
// C.EBREAK: expands to EBREAK
function Tuple2 #(Bool, Instr) fv_decode_C_EBREAK (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_EBREAK (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CR-type
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);

View File

@@ -245,7 +245,7 @@ endfunction
interface PerfCountersVec;
interface Vector#(No_Of_Ctrs, Reg#(Data)) counter_vec;
interface Vector#(No_Of_Ctrs, Reg#(Data)) event_vec;
interface Reg#(Data) inhibit;
interface Reg#(Bit#(No_Of_Ctrs)) inhibit;
method Action send_performance_events (Vector #(No_Of_Evts, Bit#(Report_Width)) evts);
endinterface
(* synthesize *)
@@ -283,8 +283,8 @@ module mkPerfCountersToooba (PerfCountersVec);
interface counter_vec = counters;
interface event_vec = events;
interface inhibit = interface Reg;
method Action _write(Data x) = writeCounterInhibitFF.enq(truncate(x));
method Data _read = zeroExtend(perf_counters.read_ctr_inhibit);
method Action _write(Bit#(No_Of_Ctrs) x) = writeCounterInhibitFF.enq(x);
method Bit#(No_Of_Ctrs) _read = (perf_counters.read_ctr_inhibit);
endinterface;
method send_performance_events = perf_counters.send_performance_events;
endmodule
@@ -821,8 +821,19 @@ module mkCsrFile #(Data hartid)(CsrFile);
Reg#(CapReg) mScratchC_reg <- mkCsrReg(nullCap);
Ehr#(2, CapReg) mepcc_reg <- mkConfigEhr(defaultValue);
`ifdef PERFORMANCE_MONITORING
// Performance monitoring
Reg#(Bit#(1)) mcountinhibit_cy_reg <- mkCsrReg(0);
Reg#(Bit#(1)) mcountinhibit_ir_reg <- mkCsrReg(0);
Reg#(Data) mcountinhibit_reg = concatReg5(readOnlyReg(32'h00000000), perf_counters.inhibit, mcountinhibit_ir_reg, readOnlyReg(1'b0), mcountinhibit_cy_reg);
`endif
rule incCycle;
`ifdef PERFORMANCE_MONITORING
if(!unpack(mcountinhibit_cy_reg)) mcycle_ehr[1] <= mcycle_ehr[1] + 1;
`else
mcycle_ehr[1] <= mcycle_ehr[1] + 1;
`endif
endrule
// Function for getting a csr given an index
@@ -880,7 +891,8 @@ module mkCsrFile #(Data hartid)(CsrFile);
csrAddrMHARTID: mhartid_csr;
csrAddrMCCSR: mccsr_csr;
`ifdef PERFORMANCE_MONITORING
csrAddrMCOUNTERINHIBIT: perf_counters.inhibit;
//csrAddrMCOUNTERINHIBIT: perf_counters.inhibit;
csrAddrMCOUNTERINHIBIT: mcountinhibit_reg;
`endif
`ifdef SECURITY
csrAddrMEVBASE: mevbase_csr;
@@ -1361,7 +1373,11 @@ module mkCsrFile #(Data hartid)(CsrFile);
};
method Action incInstret(SupCnt x);
`ifdef PERFORMANCE_MONITORING
if(!unpack(mcountinhibit_ir_reg)) minstret_ehr[1] <= minstret_ehr[1] + zeroExtend(x);
`else
minstret_ehr[1] <= minstret_ehr[1] + zeroExtend(x);
`endif
endmethod
method Action setTime(Data t);

View File

@@ -15,85 +15,87 @@ Bit #(2) opcode_C0 = 2'b00;
Bit #(2) opcode_C1 = 2'b01;
Bit #(2) opcode_C2 = 2'b10;
Bit #(3) funct3_C_LWSP = 3'b_010;
Bit #(3) funct3_C_LDSP = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_LQSP = 3'b_001; // RV128
Bit #(3) funct3_C_FLWSP = 3'b_011; // RV32FC
Bit #(3) funct3_C_FLDSP = 3'b_001; // RV32DC, RV64DC
Bit #(3) funct3_C_LWSP = 3'b_010;
Bit #(3) funct3_C_LDSP = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_LQSP = 3'b_001; // RV128
Bit #(3) funct3_C_FLWSP = 3'b_011; // RV32FC
Bit #(3) funct3_C_FLDSP = 3'b_001; // RV32DC, RV64DC
Bit #(3) funct3_C_SWSP = 3'b_110;
Bit #(3) funct3_C_SWSP = 3'b_110;
Bit #(3) funct3_C_SQSP = 3'b_101; // RV128
Bit #(3) funct3_C_FSDSP = 3'b_101; // RV32DC, RV64DC
Bit #(3) funct3_C_SQSP = 3'b_101; // RV128
Bit #(3) funct3_C_FSDSP = 3'b_101; // RV32DC, RV64DC
Bit #(3) funct3_C_SDSP = 3'b_111; // RV64 and RV128
Bit #(3) funct3_C_FSWSP = 3'b_111; // RV32FC
Bit #(3) funct3_C_SDSP = 3'b_111; // RV64 and RV128
Bit #(3) funct3_C_FSWSP = 3'b_111; // RV32FC
Bit #(3) funct3_C_LQ = 3'b_001; // RV128
Bit #(3) funct3_C_FLD = 3'b_001; // RV32DC, RV64DC
Bit #(3) funct3_C_LQ = 3'b_001; // RV128
Bit #(3) funct3_C_FLD = 3'b_001; // RV32DC, RV64DC
Bit #(3) funct3_C_LW = 3'b_010;
Bit #(3) funct3_C_LW = 3'b_010;
Bit #(3) funct3_C_LD = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_FLW = 3'b_011; // RV32FC
Bit #(3) funct3_C_LD = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_FLW = 3'b_011; // RV32FC
Bit #(3) funct3_C_FSD = 3'b_101; // RV32DC, RV64DC
Bit #(3) funct3_C_SQ = 3'b_101; // RV128
Bit #(3) funct3_C_FSD = 3'b_101; // RV32DC, RV64DC
Bit #(3) funct3_C_SQ = 3'b_101; // RV128
Bit #(3) funct3_C_SW = 3'b_110;
Bit #(3) funct3_C_SW = 3'b_110;
Bit #(3) funct3_C_SD = 3'b_111; // RV64 and RV128
Bit #(3) funct3_C_FSW = 3'b_111; // RV32FC
Bit #(3) funct3_C_SD = 3'b_111; // RV64 and RV128
Bit #(3) funct3_C_FSW = 3'b_111; // RV32FC
Bit #(3) funct3_C_JAL = 3'b_001; // RV32
Bit #(3) funct3_C_J = 3'b_101;
Bit #(3) funct3_C_BEQZ = 3'b_110;
Bit #(3) funct3_C_BNEZ = 3'b_111;
Bit #(3) funct3_C_JAL = 3'b_001; // RV32
Bit #(3) funct3_C_J = 3'b_101;
Bit #(3) funct3_C_BEQZ = 3'b_110;
Bit #(3) funct3_C_BNEZ = 3'b_111;
Bit #(4) funct4_C_JR = 4'b_1000;
Bit #(4) funct4_C_JALR = 4'b_1001;
Bit #(4) funct4_C_JR = 4'b_1000;
Bit #(4) funct4_C_JALR = 4'b_1001;
Bit #(3) funct3_C_LI = 3'b_010;
Bit #(3) funct3_C_LUI = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_LI = 3'b_010;
Bit #(3) funct3_C_LUI = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_NOP = 3'b_000;
Bit #(3) funct3_C_ADDI = 3'b_000;
Bit #(3) funct3_C_ADDIW = 3'b_001;
Bit #(3) funct3_C_ADDI16SP = 3'b_011;
Bit #(3) funct3_C_ADDI4SPN = 3'b_000;
Bit #(3) funct3_C_SLLI = 3'b_000;
Bit #(3) funct3_C_NOP = 3'b_000;
Bit #(3) funct3_C_ADDI = 3'b_000;
Bit #(3) funct3_C_ADDIW = 3'b_001;
Bit #(3) funct3_C_ADDI16SP = 3'b_011;
Bit #(3) funct3_C_CIncOffsetImm16CSP = 3'b_011;
Bit #(3) funct3_C_ADDI4SPN = 3'b_000;
Bit #(3) funct3_C_CIncOffsetImm4CSPN = 3'b_000;
Bit #(3) funct3_C_SLLI = 3'b_000;
Bit #(3) funct3_C_SRLI = 3'b_100;
Bit #(2) funct2_C_SRLI = 2'b_00;
Bit #(3) funct3_C_SRLI = 3'b_100;
Bit #(2) funct2_C_SRLI = 2'b_00;
Bit #(3) funct3_C_SRAI = 3'b_100;
Bit #(2) funct2_C_SRAI = 2'b_01;
Bit #(3) funct3_C_SRAI = 3'b_100;
Bit #(2) funct2_C_SRAI = 2'b_01;
Bit #(3) funct3_C_ANDI = 3'b_100;
Bit #(2) funct2_C_ANDI = 2'b_10;
Bit #(3) funct3_C_ANDI = 3'b_100;
Bit #(2) funct2_C_ANDI = 2'b_10;
Bit #(4) funct4_C_MV = 4'b_1000;
Bit #(4) funct4_C_ADD = 4'b_1001;
Bit #(4) funct4_C_MV = 4'b_1000;
Bit #(4) funct4_C_ADD = 4'b_1001;
Bit #(6) funct6_C_AND = 6'b_100_0_11;
Bit #(2) funct2_C_AND = 2'b_11;
Bit #(6) funct6_C_AND = 6'b_100_0_11;
Bit #(2) funct2_C_AND = 2'b_11;
Bit #(6) funct6_C_OR = 6'b_100_0_11;
Bit #(2) funct2_C_OR = 2'b_10;
Bit #(6) funct6_C_OR = 6'b_100_0_11;
Bit #(2) funct2_C_OR = 2'b_10;
Bit #(6) funct6_C_XOR = 6'b_100_0_11;
Bit #(2) funct2_C_XOR = 2'b_01;
Bit #(6) funct6_C_XOR = 6'b_100_0_11;
Bit #(2) funct2_C_XOR = 2'b_01;
Bit #(6) funct6_C_SUB = 6'b_100_0_11;
Bit #(2) funct2_C_SUB = 2'b_00;
Bit #(6) funct6_C_SUB = 6'b_100_0_11;
Bit #(2) funct2_C_SUB = 2'b_00;
Bit #(6) funct6_C_ADDW = 6'b_100_1_11;
Bit #(2) funct2_C_ADDW = 2'b_01;
Bit #(6) funct6_C_ADDW = 6'b_100_1_11;
Bit #(2) funct2_C_ADDW = 2'b_01;
Bit #(6) funct6_C_SUBW = 6'b_100_1_11;
Bit #(2) funct2_C_SUBW = 2'b_00;
Bit #(6) funct6_C_SUBW = 6'b_100_1_11;
Bit #(2) funct2_C_SUBW = 2'b_00;
Bit #(4) funct4_C_EBREAK = 4'b_1001;
Bit #(4) funct4_C_EBREAK = 4'b_1001;
// ================================================================
// Functions to extract instruction fields from 'C' (compressed) instructions

View File

@@ -177,14 +177,16 @@ 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_JALR_CAP = 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;
Bit #(5) f5rs2_cap_CSealEntry = 5'h11;
Bit #(5) f5rs2_cap_CLoadTags = 5'h12;
// 5'h13-5'h1f unused (5'h1f reserved for 1-reg instructions)
// 5'h13 unused
Bit #(5) f5rs2_cap_JALR_PCC = 5'h14;
// 5'h15-5'h1f unused (5'h1f reserved for 1-reg instructions)
// ================================================================
// f7_cap_{Load, Store} opcode subdivision

View File

@@ -101,16 +101,9 @@ module mkXBar#(
return False;
end
endfunction
Maybe#(srcIdxT) whichSrc = Invalid; // the src to select
if(isFromSrc(srcRR[dst])) begin
// first check the src with priority
whichSrc = Valid (srcRR[dst]);
end
else begin
// otherwise just get one valid src
Vector#(srcNum, srcIdxT) srcIdxVec = genWith(fromInteger);
whichSrc = searchIndex(isFromSrc, srcIdxVec);
end
// find the first valid source starting at srcRR[dst]
Vector#(srcNum, srcIdxT) srcIdxVec = reverse(rotateBy(reverse(genWith(fromInteger)), unpack(srcRR[dst]))); // Double reverse to achieve rotateBy left, since it's not provided by Bluespec
Maybe#(srcIdxT) whichSrc = fmap(select(srcIdxVec), searchIndex(isFromSrc, srcIdxVec)); // the src to select
if(whichSrc matches tagged Valid .src) begin
// can do enq & deq
deqSrcByDst[dst] = whichSrc;

View File

@@ -1184,6 +1184,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
Auipc, Auipcc: auipcCnt = auipcCnt + 1;
Br: brCnt = brCnt + 1;
J : jmpCnt = jmpCnt + 1;
CJAL: jmpCnt = jmpCnt + 1;
Jr: jrCnt = jrCnt + 1;
CJALR: jrCnt = jrCnt + 1;
Ld: begin

View File

@@ -626,7 +626,7 @@ module mkFetchStage(FetchStage);
end
end else if (is_16b_inst(frag.inst_frag)) begin // 16-bit instruction
new_pick = tagged Valid fetch3_2_instC(frag,
fv_decode_C (misa, misa_mxl_64, frag.inst_frag),
fv_decode_C (misa, misa_mxl_64, getFlags(decompressPc(frag.pc))==1, frag.inst_frag),
zeroExtend(frag.inst_frag));
end
end
@@ -717,7 +717,7 @@ module mkFetchStage(FetchStage);
CapMem push_addr = addPc(pc, ((in.inst_kind == Inst_32b) ? 4 : 2));
CapMem pop_addr = ras.ras[i].first;
if (dInst.iType == J && dst_link) begin
if ((dInst.iType == J || dInst.iType == CJAL) && dst_link) begin
// rs1 is invalid, i.e., not link: push
ras.ras[i].popPush(False, Valid (push_addr));
end
@@ -821,7 +821,7 @@ module mkFetchStage(FetchStage);
if(redirectInst matches tagged Valid .iType &&& doStats) begin
case(iType)
Br: decRedirectBrCnt.incr(1);
J : decRedirectJmpCnt.incr(1);
J, CJAL: decRedirectJmpCnt.incr(1);
Jr: decRedirectJrCnt.incr(1);
default: decRedirectOtherCnt.incr(1);
endcase
@@ -930,7 +930,7 @@ module mkFetchStage(FetchStage);
CapMem pc, CapMem next_pc, IType iType, Bool taken,
DirPredTrainInfo dpTrain, Bool mispred, Bool isCompressed
);
//if (iType == J || (iType == Br && next_pc < pc)) begin
//if (iType == J || iType == CJAL || (iType == Br && next_pc < pc)) begin
// // Only train the next address predictor for jumps and backward branches
// // next_pc != pc + 4 is a substitute for taken
// nextAddrPred.update(pc, next_pc, taken);

View File

@@ -114,8 +114,7 @@ typedef struct {
`endif
Bool misaligned;
Bool capStore;
Bool capWidthLoad;
Bool allowCap;
Bool allowCapLoad;
Maybe#(CSR_XCapCause) capException;
Maybe#(BoundsCheck) check;
} MemExeToFinish deriving(Bits, FShow);
@@ -168,7 +167,7 @@ module mkDTlbSynth(DTlbSynth);
default: False;
endcase),
capStore: x.capStore,
capWidthLoad: x.capWidthLoad
potentialCapLoad: x.allowCapLoad
};
endfunction
let m <- mkDTlb(getTlbReq);
@@ -578,8 +577,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
`endif
misaligned: memAddrMisaligned(getAddr(vaddr), origBE),
capStore: isValidCap(data) && origBE == DataMemAccess(unpack(~0)),
capWidthLoad: origBE == DataMemAccess(unpack(~0)),
allowCap: getHardPerms(x.rVal1).permitLoadCap,
allowCapLoad: getHardPerms(x.rVal1).permitLoadCap && origBE == DataMemAccess(unpack(~0)),
capException: capChecksMem(x.rVal1, x.rVal2, x.cap_checks, x.mem_func, origBE),
check: prepareBoundsCheck(x.rVal1, x.rVal2, almightyCap/*ToDo: pcc*/,
ddc, getAddr(vaddr), accessByteCount, x.cap_checks)
@@ -676,7 +674,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
// update LSQ
LSQUpdateAddrResult updRes <- lsq.updateAddr(
x.ldstq_tag, cause, x.allowCap && allowCapPTE, paddr, isMMIO, x.shiftedBE
x.ldstq_tag, cause, x.allowCapLoad && allowCapPTE, paddr, isMMIO, x.shiftedBE
);
// issue non-MMIO Ld which has no exception and is not waiting for
@@ -1316,7 +1314,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
// write reg file & set ROB as Executed & wake up rs
if(lsqDeqSt.dst matches tagged Valid .dst) begin
CapPipe dataUnpacked = fromMem(tuple2(resp.tag, pack(resp.data)));
dataUnpacked = setValidCap(dataUnpacked, False); // TODO no allowCap around. Can a cap be loaded this way (e.g. AMOSWAP?)
dataUnpacked = setValidCap(dataUnpacked, lsqDeqSt.allowCapAmoLd && isValidCap(dataUnpacked));
inIfc.writeRegFile(dst.indx, dataUnpacked);
inIfc.setRegReadyAggr_mem(dst.indx);
`ifdef INCLUDE_TANDEM_VERIF
@@ -1430,7 +1428,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
// write reg file & wakeup rs (this wakeup is late but MMIO is rare) & set ROB as Executed
if(lsqDeqSt.dst matches tagged Valid .dst) begin
CapPipe dataUnpacked = fromMem(tuple2(resp.tag, pack(resp.data)));
dataUnpacked = setValidCap(dataUnpacked, False); // TODO no allowCap around. Can a cap be loaded this way (e.g. AMOSWAP?)
dataUnpacked = setValidCap(dataUnpacked, lsqDeqSt.allowCapAmoLd && isValidCap(dataUnpacked));
inIfc.writeRegFile(dst.indx, dataUnpacked);
inIfc.setRegReadyAggr_mem(dst.indx);
`ifdef INCLUDE_TANDEM_VERIF

View File

@@ -48,7 +48,7 @@ function Maybe#(CapMem) decodeBrPred( CapMem pc, DecodedInst dInst, Bool histTak
Maybe#(CapMem) nextPc = tagged Invalid;
CapPipe pcPipe = cast(pc);
CapMem jTarget = cast(incOffset(pcPipe, imm_val).value);
if( dInst.iType == J ) begin
if( dInst.iType == J || dInst.iType == CJAL ) begin
nextPc = tagged Valid jTarget;
end else if( dInst.iType == Br ) begin
if( histTaken ) begin

View File

@@ -6,6 +6,7 @@
`CAP_CHECK_FIELD(ddc_unsealed,"ddc_unsealed")
`CAP_CHECK_FIELD(src1_unsealed,"src1_unsealed")
`CAP_CHECK_FIELD(src1_unsealed_or_sentry,"src1_unsealed_or_sentry")
`CAP_CHECK_FIELD(src1_unsealed_or_imm_zero,"src1_unsealed_or_imm_zero")
`CAP_CHECK_FIELD(src2_unsealed,"src2_unsealed")
`CAP_CHECK_FIELD(src1_src2_types_match,"src1_src2_types_match")
`CAP_CHECK_FIELD(src1_permit_ccall,"src1_permit_ccall")

View File

@@ -297,7 +297,7 @@ module mkDTlb#(
en.level,
r.write ? DataStore : DataLoad,
r.capStore,
r.capWidthLoad);
r.potentialCapLoad);
if (permCheck.allowed) begin
// fill TLB, and record resp
tlb.addEntry(en);
@@ -487,7 +487,7 @@ module mkDTlb#(
entry.level,
r.write ? DataStore : DataLoad,
r.capStore,
r.capWidthLoad);
r.potentialCapLoad);
$display("Permission check output 2: ", fshow(permCheck));
if (permCheck.allowed) begin
// update TLB replacement info

View File

@@ -92,6 +92,13 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode);
illegalInst = True;
end
Bool capWidth = ((mem_func == St || mem_func == Amo) && funct3 == f3_SQ)
|| (opcode == opcMiscMem && funct3 == f3_LQ);
if (capWidth && amo_func != None && amo_func != Swap) begin
illegalInst = True; // Don't support atomic cap arithmetic
end
// unsignedLd
// it doesn't matter if this is set to True for stores
Bool unsignedLd = False;
@@ -109,9 +116,6 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode);
unsignedLd = True;
end
Bool capWidth = (mem_func == St && funct3 == 3'b100)
|| (opcode == opcMiscMem && funct3 == 3'b010);
// byteEn
// TODO: Some combinations of operations and byteEn's are illegal.
// They should be detected here.
@@ -487,7 +491,13 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
opcJal: begin
dInst.iType = J;
if (cap_mode) begin
dInst.iType = CJAL;
end
else begin
dInst.iType = J;
end
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Invalid;
regs.src2 = Invalid;
@@ -502,18 +512,32 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
opcJalr: begin
dInst.iType = Jr;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
regs.src2 = Invalid;
dInst.imm = Valid(immI);
dInst.csr = tagged Invalid;
dInst.execFunc = tagged Br AT;
dInst.capChecks.check_enable = True;
dInst.capChecks.check_authority_src = Pcc;
dInst.capChecks.check_low_src = Src1Addr;
dInst.capChecks.check_high_src = Src1AddrPlus2;
dInst.capChecks.check_inclusive = True;
if (cap_mode) begin
dInst.iType = CJALR;
dInst.capChecks.src1_tag = True;
dInst.capChecks.src1_permit_x = True;
dInst.capChecks.src1_unsealed_or_sentry = True;
dInst.capChecks.src1_unsealed_or_imm_zero = True;
dInst.capChecks.check_authority_src = Src1;
end
else begin
dInst.iType = Jr;
dInst.capChecks.check_authority_src = Pcc;
end
end
opcBranch: begin
@@ -1341,7 +1365,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
regs.src1 = Valid(tagged Gpr rs1);
dInst.capFunc = CapInspect (GetPerm);
end
f5rs2_cap_CJALR: begin
f5rs2_cap_JALR_CAP: begin
dInst.capChecks.src1_tag = True;
dInst.capChecks.src1_permit_x = True;
dInst.capChecks.src1_unsealed_or_sentry = True;
@@ -1356,7 +1380,19 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.execFunc = tagged Br AT;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
end
end
f5rs2_cap_JALR_PCC: begin
dInst.capChecks.check_enable = True;
dInst.capChecks.check_authority_src = Pcc;
dInst.capChecks.check_low_src = Src1Addr;
dInst.capChecks.check_high_src = Src1AddrPlus2;
dInst.capChecks.check_inclusive = True;
dInst.iType = Jr;
dInst.execFunc = tagged Br AT;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
end
f5rs2_cap_CGetType: begin
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);

View File

@@ -46,54 +46,56 @@ import ISA_Decls_CHERI::*;
import CacheUtils::*; // For CLoadTags alignment
(* noinline *)
function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact);
function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact, ImmData imm);
function Maybe#(CSR_XCapCause) e1(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e});
function Maybe#(CSR_XCapCause) e2(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e});
function Maybe#(CSR_XCapCause) eDDC(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1, pack(scrAddrDDC)}, cheri_exc_code: e});
Maybe#(CSR_XCapCause) result = Invalid;
if (toCheck.ddc_tag && !isValidCap(ddc))
if (toCheck.ddc_tag && !isValidCap(ddc))
result = eDDC(cheriExcTagViolation);
else if (toCheck.src1_tag && !isValidCap(a))
else if (toCheck.src1_tag && !isValidCap(a))
result = e1(cheriExcTagViolation);
else if (toCheck.src2_tag && !isValidCap(b))
else if (toCheck.src2_tag && !isValidCap(b))
result = e2(cheriExcTagViolation);
else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED))
else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED))
result = eDDC(cheriExcSealViolation);
else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED))
else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED))
result = e1(cheriExcSealViolation);
else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY))
else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY))
result = e1(cheriExcSealViolation);
else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED))
else if (toCheck.src1_unsealed_or_imm_zero && isValidCap(a) && (getKind(a) != UNSEALED) && (imm != 0))
result = e1(cheriExcSealViolation);
else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED))
result = e2(cheriExcSealViolation);
else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True))
else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True))
result = e1(cheriExcSealViolation);
else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True))
else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True))
result = e2(cheriExcSealViolation);
else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getKind(a).SEALED_WITH_TYPE)))
else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getKind(a).SEALED_WITH_TYPE)))
result = e1(cheriExcTypeViolation);
else if (toCheck.src1_src2_types_match && getKind(a).SEALED_WITH_TYPE != getKind(b).SEALED_WITH_TYPE)
else if (toCheck.src1_src2_types_match && getKind(a).SEALED_WITH_TYPE != getKind(b).SEALED_WITH_TYPE)
result = e1(cheriExcTypeViolation);
else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall)
else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall)
result = e1(cheriExcPermitCCallViolation);
else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall)
else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall)
result = e2(cheriExcPermitCCallViolation);
else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute)
else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute)
result = e1(cheriExcPermitXViolation);
else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute)
else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute)
result = e2(cheriExcPermitXViolation);
else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal)
else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal)
result = e2(cheriExcPermitUnsealViolation);
else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal)
else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal)
result = e2(cheriExcPermitSealViolation);
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE))
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE))
result = e2(cheriExcTypeViolation);
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
result = e2(cheriExcLengthViolation);
else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a))
else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a))
result = e2(cheriExcSoftwarePermViolation);
else if (toCheck.src1_derivable && !isDerivable(a))
else if (toCheck.src1_derivable && !isDerivable(a))
result = e1(cheriExcLengthViolation);
else if (toCheck.cap_exact && !cap_exact)
else if (toCheck.cap_exact && !cap_exact)
result = e1(cheriExcRepresentViolation);
return result;
endfunction
@@ -358,7 +360,7 @@ function CapPipe brAddrCalc(CapPipe pc, CapPipe val, IType iType, Data imm, Bool
jumpTarget = setAddrUnsafe(jumpTarget, {truncateLSB(getAddr(jumpTarget)), 1'b0});
jumpTarget = setKind(jumpTarget, UNSEALED); // It is checked elsewhere that we have an unsealed cap already, or sentry if permitted
CapPipe targetAddr = (case (iType)
J : branchTarget;
J, CJAL : branchTarget;
Jr,CCall,CJALR : jumpTarget;
Br : (taken? branchTarget : pcPlusN);
default : pcPlusN;
@@ -407,7 +409,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
cf.taken = aluBr(getAddr(rVal1), getAddr(rVal2), br_f);
cf.nextPc = brAddrCalc(pcc, rVal1, dInst.iType, fromMaybe(0,getDInstImm(dInst)), cf.taken, orig_inst, newPcc);
Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact);
Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact, dInst.imm.Valid);
if (dInst.execFunc matches tagged Br .unused) begin
rVal1 = cf.nextPc;
if (!cf.taken) dInst.capChecks.check_enable = False;
@@ -431,6 +433,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
Sc : rVal2;
Amo : rVal2;
J : nullWithAddr(getOffset(link_pcc));
CJAL : setKind(link_pcc, SENTRY);
CCall : cap_alu_result;
CJALR : setKind(link_pcc, SENTRY);
Jr : nullWithAddr(getOffset(link_pcc));

View File

@@ -268,7 +268,7 @@ typedef enum {
Alu,
Ld, St, Lr, Sc,
J, Jr, Br,
CCall, CJALR, Cap,
CCall, CJAL, CJALR, Cap,
Auipc,
Auipcc,
Fpu,

View File

@@ -57,7 +57,7 @@ import Cur_Cycle :: *;
// some parts of full_result are for verification
// but some are truly used for execution
// ppc is only used by iType = BR/J/JR
// ppc is only used by iType = BR/J/CJAL/JR
// csrData is only used by iType = Csr
// vaddr is only used by mem inst in page fault
typedef union tagged {

View File

@@ -338,7 +338,7 @@ typedef struct {
Bool isMMIO;
MemDataByteEn shiftedBE;
MemTaggedData stData;
Bool allowCap;
Bool allowCapAmoLd;
Maybe#(Trap) fault;
} StQDeqEntry deriving (Bits, Eq, FShow);
@@ -857,6 +857,7 @@ module mkSplitLSQ(SplitLSQ);
Vector#(StQSize, Ehr#(2, MemDataByteEn)) st_shiftedBE <- replicateM(mkEhr(?));
Vector#(StQSize, Ehr#(1, MemTaggedData)) st_stData <- replicateM(mkEhr(?));
Vector#(StQSize, Ehr#(2, Maybe#(Trap))) st_fault <- replicateM(mkEhr(?));
Vector#(StQSize, Ehr#(2, Bool)) st_allowCapAmoLd <- replicateM(mkEhr(?));
Vector#(StQSize, Ehr#(2, Bool)) st_computed <- replicateM(mkEhr(?));
Vector#(StQSize, Ehr#(2, Bool)) st_verified <- replicateM(mkEhr(?));
Vector#(StQSize, Ehr#(2, SpecBits)) st_specBits <- replicateM(mkEhr(?));
@@ -896,6 +897,10 @@ module mkSplitLSQ(SplitLSQ);
let st_fault_deqSt = getVEhrPort(st_fault, 1);
let st_fault_enq = getVEhrPort(st_fault, 1); // write
let st_allowCapAmoLd_updAddr = getVEhrPort(st_allowCapAmoLd, 0); // write
let st_allowCapAmoLd_deqSt = getVEhrPort(st_allowCapAmoLd, 1);
let st_allowCapAmoLd_enq = getVEhrPort(st_allowCapAmoLd, 1); // write
let st_computed_verify = getVEhrPort(st_computed, 0);
let st_computed_updAddr = getVEhrPort(st_computed, 0); // write
let st_computed_issue = getVEhrPort(st_computed, 1);
@@ -1544,6 +1549,7 @@ module mkSplitLSQ(SplitLSQ);
st_rel[st_enqP] <= mem_inst.rl;
st_dst[st_enqP] <= dst;
st_fault_enq[st_enqP] <= Invalid;
st_allowCapAmoLd_enq[st_enqP] <= False;
st_computed_enq[st_enqP] <= False;
st_verified_enq[st_enqP] <= False;
st_specBits_enq[st_enqP] <= spec_bits;
@@ -1635,6 +1641,7 @@ module mkSplitLSQ(SplitLSQ);
// write fault, computed paddr, shift be. NOTE computed is
// true only when no fault.
st_fault_updAddr[tag] <= fault;
st_allowCapAmoLd_updAddr[tag] <= allowCap;
st_computed_updAddr[tag] <= !isValid(fault);
st_paddr_updAddr[tag] <= pa;
st_isMMIO_updAddr[tag] <= mmio;
@@ -2174,6 +2181,7 @@ module mkSplitLSQ(SplitLSQ);
isMMIO: st_isMMIO_deqSt[deqP],
shiftedBE: st_shiftedBE_deqSt[deqP],
stData: st_stData_deqSt[deqP],
allowCapAmoLd: st_allowCapAmoLd_deqSt[deqP],
fault: st_fault_deqSt[deqP]
};
endmethod

View File

@@ -32,7 +32,7 @@ typedef struct{
Addr addr;
Bool write;
Bool capStore;
Bool capWidthLoad;
Bool potentialCapLoad;
} TlbReq deriving(Eq, Bits, FShow);
typedef Tuple3#(Addr, Maybe#(Exception), Bool) TlbResp;
@@ -192,7 +192,7 @@ function TlbPermissionCheck hasVMPermission(
PTEType pte_type, PTEUpperType pte_upper_type,
Ppn ppn, PageWalkLevel level,
TlbAccessType access,
Bool capStore, Bool capWidthLoad
Bool capStore, Bool potentialCapLoad
);
// try to find any page fault
Bool fault = False;
@@ -249,7 +249,7 @@ function TlbPermissionCheck hasVMPermission(
!(pte_type.executable && vm_info.exeReadable)) begin
fault = True;
end
if (capWidthLoad) begin
if (potentialCapLoad) begin
if (!fault) excCode = excLoadCapPageFault;
// load traps if page not cap readable and using cap_read_mod set
if (!pte_upper_type.cap_readable && pte_upper_type.cap_read_mod) begin