diff --git a/src_Core/CPU/CPU_Decode_C.bsv b/src_Core/CPU/CPU_Decode_C.bsv index 5b3b04e..d242c73 100644 --- a/src_Core/CPU/CPU_Decode_C.bsv +++ b/src_Core/CPU/CPU_Decode_C.bsv @@ -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); diff --git a/src_Core/CPU/CsrFile.bsv b/src_Core/CPU/CsrFile.bsv index e6db11b..77ca3a6 100644 --- a/src_Core/CPU/CsrFile.bsv +++ b/src_Core/CPU/CsrFile.bsv @@ -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); diff --git a/src_Core/ISA/ISA_Decls_C.bsv b/src_Core/ISA/ISA_Decls_C.bsv index 3b05822..b3bfbe6 100644 --- a/src_Core/ISA/ISA_Decls_C.bsv +++ b/src_Core/ISA/ISA_Decls_C.bsv @@ -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 diff --git a/src_Core/ISA/ISA_Decls_CHERI.bsv b/src_Core/ISA/ISA_Decls_CHERI.bsv index 0cf2497..3dbd9dd 100755 --- a/src_Core/ISA/ISA_Decls_CHERI.bsv +++ b/src_Core/ISA/ISA_Decls_CHERI.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/coherence/src/CrossBar.bsv b/src_Core/RISCY_OOO/coherence/src/CrossBar.bsv index e43f2e5..4e1bb86 100644 --- a/src_Core/RISCY_OOO/coherence/src/CrossBar.bsv +++ b/src_Core/RISCY_OOO/coherence/src/CrossBar.bsv @@ -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; diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index 5c58751..8f1185c 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv index 1e57e09..e04b216 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv @@ -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); diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv index 85b7646..b625352 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/procs/lib/BrPred.bsv b/src_Core/RISCY_OOO/procs/lib/BrPred.bsv index 5943f36..1ac9456 100644 --- a/src_Core/RISCY_OOO/procs/lib/BrPred.bsv +++ b/src_Core/RISCY_OOO/procs/lib/BrPred.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi index 722ce39..018b513 100644 --- a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi +++ b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi @@ -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") diff --git a/src_Core/RISCY_OOO/procs/lib/DTlb.bsv b/src_Core/RISCY_OOO/procs/lib/DTlb.bsv index adbb6ff..ee99fda 100644 --- a/src_Core/RISCY_OOO/procs/lib/DTlb.bsv +++ b/src_Core/RISCY_OOO/procs/lib/DTlb.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 4ff0195..e2302c1 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -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); diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index e629b29..cfbfa2b 100755 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -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)); diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 32469d2..122e5ef 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -268,7 +268,7 @@ typedef enum { Alu, Ld, St, Lr, Sc, J, Jr, Br, - CCall, CJALR, Cap, + CCall, CJAL, CJALR, Cap, Auipc, Auipcc, Fpu, diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv index 0fde3d8..ffbf123 100755 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -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 { diff --git a/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv b/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv index ece0f03..24fa28c 100644 --- a/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv +++ b/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/procs/lib/TlbTypes.bsv b/src_Core/RISCY_OOO/procs/lib/TlbTypes.bsv index 0ac2f7d..8c8330b 100644 --- a/src_Core/RISCY_OOO/procs/lib/TlbTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/TlbTypes.bsv @@ -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