Merge branch 'CHERI' of https://github.com/CTSRD-CHERI/Toooba into CHERI
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -268,7 +268,7 @@ typedef enum {
|
||||
Alu,
|
||||
Ld, St, Lr, Sc,
|
||||
J, Jr, Br,
|
||||
CCall, CJALR, Cap,
|
||||
CCall, CJAL, CJALR, Cap,
|
||||
Auipc,
|
||||
Auipcc,
|
||||
Fpu,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user