From 4d36072f094a2839b8d605a56eeb4db0cb03c5f1 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 17 Jul 2024 06:04:21 -0700 Subject: [PATCH 1/6] Converted regression-wally to use argparse --- bin/regression-wally | 47 ++++++++++++++++++++++---------------------- bin/wsim | 2 +- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/bin/regression-wally b/bin/regression-wally index a059bf648..8d67e387b 100755 --- a/bin/regression-wally +++ b/bin/regression-wally @@ -11,6 +11,7 @@ # ################################## import sys,os,shutil +import argparse import multiprocessing from collections import namedtuple from multiprocessing import Pool, TimeoutError @@ -320,13 +321,16 @@ coveragesim = "questa" # Questa is required for code/functional coverage #defaultsim = "questa" # Default simulator for all other tests; change to Verilator when flow is ready defaultsim = "verilator" # Default simulator for all other tests -ccov = '--ccov' in sys.argv -fp = '--fp' in sys.argv -nightly = '--nightly' in sys.argv -testfloat = '--testfloat' in sys.argv -buildroot = '--buildroot' in sys.argv +parser = argparse.ArgumentParser() +parser.add_argument("--ccov", help="Code Coverage", action="store_true") +parser.add_argument("--fcov", help="Functional Coverage", action="store_true") +parser.add_argument("--nightly", help="Run large nightly regression", action="store_true") +parser.add_argument("--buildroot", help="Include Buildroot Linux boot test (takes many hours, done along with --nightly)", action="store_true") +parser.add_argument("--testfloat", help="Include Testfloat floating-point unit tests", action="store_true") +parser.add_argument("--fp", help="Include floating-point tests in coverage (slower runtime)", action="store_true") +args = parser.parse_args() -if (nightly): +if (args.nightly): nightMode = "--nightly"; # sims = [defaultsim] # uncomment to use only the default simulator sims = ["questa", "verilator", "vcs"] # uncomment to exercise all simulators @@ -334,7 +338,7 @@ else: nightMode = "" sims = [defaultsim] -if (ccov): # only run RV64GC tests in coverage mode +if (args.ccov): # only run RV64GC tests in coverage mode coverStr = '--ccov' else: coverStr = '' @@ -353,24 +357,24 @@ configs = [ # run full buildroot boot simulation (slow) if buildroot flag is set. Start it early to overlap with other tests -if (buildroot): +if (args.buildroot): # addTests(tests_buildrootboot, defaultsim) # non-lockstep with Verilator runs in about 2 hours addTests(tests_buildrootbootlockstep, "questa") # lockstep with Questa and ImperasDV runs overnight -if (ccov): # only run RV64GC tests on Questa in code coverage mode +if (args.ccov): # only run RV64GC tests on Questa in code coverage mode addTests(tests64gc_nofp, "questa") - if (fp): + if (args.fp): addTests(tests64gc_fp, "questa") else: for sim in sims: - if (not (buildroot and sim == defaultsim)): # skip shot buildroot sim if running long one + if (not (args.buildroot and sim == defaultsim)): # skip short buildroot sim if running long one addTests(tests_buildrootshort, sim) addTests(tests, sim) addTests(tests64gc_nofp, sim) addTests(tests64gc_fp, sim) # run derivative configurations and lockstep tests in nightly regression -if (nightly): +if (args.nightly): addTests(derivconfigtests, defaultsim) sim_log = WALLY + "/sim/questa/logs/lockstep_coverage.log" tc = TestCase( @@ -391,9 +395,9 @@ if (nightly): configs.append(tc) # testfloat tests -if (testfloat): # for testfloat alone, just run testfloat tests +if (args.testfloat): # for testfloat alone, just run testfloat tests configs = [] -if (testfloat or nightly): # for nightly, run testfloat along with others +if (args.testfloat or args.nightly): # for nightly, run testfloat along with others testfloatsim = "questa" # change to Verilator when Issue #707 about testfloat not running Verilator is resolved testfloatconfigs = ["fdqh_ieee_rv64gc", "fdq_ieee_rv64gc", "fdh_ieee_rv64gc", "fd_ieee_rv64gc", "fh_ieee_rv64gc", "f_ieee_rv64gc", "fdqh_ieee_rv32gc", "f_ieee_rv32gc"] for config in testfloatconfigs: @@ -458,7 +462,7 @@ if (testfloat or nightly): # for nightly, run testfloat along with others def main(): """Run the tests and count the failures""" - global configs, ccov + global configs, args os.chdir(regressionDir) dirs = ["questa/logs", "questa/wkdir", "verilator/logs", "verilator/wkdir", "vcs/logs", "vcs/wkdir"] for d in dirs: @@ -467,17 +471,12 @@ def main(): os.mkdir(d) except: pass - - if '--makeTests' in sys.argv: - os.chdir(regressionDir) - os.system('./make-tests.sh | tee ./logs/make-tests.log') - - elif '--ccov' in sys.argv: + if args.ccov: TIMEOUT_DUR = 20*60 # seconds os.system('rm -f questa/cov/*.ucdb') - elif '--nightly' in sys.argv: + elif args.nightly in sys.argv: TIMEOUT_DUR = 60*1440 # 1 day - elif '--testfloat' in sys.argv: + elif args.testfloat in sys.argv: TIMEOUT_DUR = 30*60 # seconds else: TIMEOUT_DUR = 10*60 # seconds @@ -497,7 +496,7 @@ def main(): print(f"{bcolors.FAIL}%s_%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (config.variant, config.name, TIMEOUT_DUR)) # Coverage report - if ccov: + if args.ccov: os.system('make QuestaCodeCoverage') # Count the number of failures if num_fail: diff --git a/bin/wsim b/bin/wsim index 34e725707..b70d0e26f 100755 --- a/bin/wsim +++ b/bin/wsim @@ -27,7 +27,7 @@ parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "verilat parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testbench_fp"], default="testbench") parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true") parser.add_argument("--ccov", "-c", help="Code Coverage", action="store_true") -parser.add_argument("--fcov", "-f", help="Functional Coverage", action="store_true") +parser.add_argument("--fcov", "-f", help="Functional Coverage, implies lockstep", action="store_true") parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="") parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true") parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true") From df063acf611f0bb2a335fe93ce39a331bab55dee Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 18 Jul 2024 08:26:58 -0700 Subject: [PATCH 2/6] Refactored decompression to use simpler default illegal instruction --- src/ifu/decompress.sv | 190 ++++++++++++++++-------------------------- 1 file changed, 70 insertions(+), 120 deletions(-) diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index 512dacfd5..d8a1afb8b 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -32,7 +32,8 @@ module decompress import cvw::*; #(parameter cvw_t P) ( output logic [31:0] InstrD, // Decompressed instruction output logic IllegalCompInstrD // Invalid decompressed instruction ); - + + logic [32:0] LInstrD; // decompressed instruction with illegal flag in [32] logic [15:0] instr16; logic [4:0] rds1, rs2, rs1p, rs2p, rds1p, rdp; logic [11:0] immCILSP, immCILSPD, immCSS, immCSSD, immCL, immCLD, immCI, immCS, immCSD, immCB, immCIASP, immCIW; @@ -75,173 +76,122 @@ module decompress import cvw::*; #(parameter cvw_t P) ( always_comb if (op == 2'b11) begin // noncompressed instruction - InstrD = InstrRawD; - IllegalCompInstrD = '0; + LInstrD = {1'b0, InstrRawD}; end else begin // convert compressed instruction into uncompressed - IllegalCompInstrD = '0; + LInstrD = {1'b1, 16'b0, instr16}; // if a legal instruction is not decoded, default to illegal and preserve 16-bit value for mtval case ({op, instr16[15:13]}) - 5'b00000: if (immCIW != 0) InstrD = {immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn - else begin // illegal instruction - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end + 5'b00000: if (immCIW != 0) LInstrD = {1'b0, immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn 5'b00001: if (P.ZCD_SUPPORTED) - InstrD = {immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld - else begin // unsupported instruction - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - 5'b00010: InstrD = {immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw - 5'b00011: if (P.XLEN==32) + LInstrD = {1'b0, immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld + 5'b00010: LInstrD = {1'b0, immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw + 5'b00011: if (P.XLEN==32) begin if (P.ZCF_SUPPORTED) - InstrD = {immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw - else begin - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - else - InstrD = {immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld; + LInstrD = {1'b0, immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw + end else + LInstrD = {1'b0, immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld 5'b00100: if (P.ZCB_SUPPORTED) if (instr16[12:10] == 3'b000) - InstrD = {10'b0, instr16[5], instr16[6], rs1p, 3'b100, rdp, 7'b0000011}; // c.lbu + LInstrD = {1'b0, 10'b0, instr16[5], instr16[6], rs1p, 3'b100, rdp, 7'b0000011}; // c.lbu else if (instr16[12:10] == 3'b001) begin if (instr16[6]) - InstrD = {10'b0, instr16[5], 1'b0, rs1p, 3'b001, rdp, 7'b0000011}; // c.lh + LInstrD = {1'b0, 10'b0, instr16[5], 1'b0, rs1p, 3'b001, rdp, 7'b0000011}; // c.lh else - InstrD = {10'b0, instr16[5], 1'b0, rs1p, 3'b101, rdp, 7'b0000011}; // c.lhu + LInstrD = {1'b0, 10'b0, instr16[5], 1'b0, rs1p, 3'b101, rdp, 7'b0000011}; // c.lhu end else if (instr16[12:10] == 3'b010) - InstrD = {7'b0, rs2p, rs1p, 3'b000, 3'b000, instr16[5], instr16[6], 7'b0100011}; // c.sb + LInstrD = {1'b0, 7'b0, rs2p, rs1p, 3'b000, 3'b000, instr16[5], instr16[6], 7'b0100011}; // c.sb else if (instr16[12:10] == 3'b011 & instr16[6] == 1'b0) - InstrD = {7'b0, rs2p, rs1p, 3'b001, 3'b000, instr16[5], 1'b0, 7'b0100011}; // c.sh - else begin - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - else begin - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end + LInstrD = {1'b0, 7'b0, rs2p, rs1p, 3'b001, 3'b000, instr16[5], 1'b0, 7'b0100011}; // c.sh 5'b00101: if (P.ZCD_SUPPORTED) - InstrD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd - else begin // unsupported instruction - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - 5'b00110: InstrD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw - 5'b00111: if (P.XLEN==32) + LInstrD = {1'b0, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd + 5'b00110: LInstrD = {1'b0, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw + 5'b00111: if (P.XLEN==32) begin if (P.ZCF_SUPPORTED) - InstrD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw - else begin - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - else - InstrD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd - 5'b01000: InstrD = {immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi + LInstrD = {1'b0, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw + end else + LInstrD = {1'b0, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd + 5'b01000: LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi 5'b01001: if (P.XLEN==32) - InstrD = {immCJ, 5'b00001, 7'b1101111}; // c.jal + LInstrD = {1'b0, immCJ, 5'b00001, 7'b1101111}; // c.jal else - InstrD = {immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw - 5'b01010: InstrD = {immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li + LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw + 5'b01010: LInstrD = {1'b0, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li 5'b01011: if (rds1 != 5'b00010) - InstrD = {immCILUI, rds1, 7'b0110111}; // c.lui + LInstrD = {1'b0, immCILUI, rds1, 7'b0110111}; // c.lui else - InstrD = {immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp + LInstrD = {1'b0, immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp 5'b01100: if (instr16[11:10] == 2'b00) - InstrD = {6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli + LInstrD = {1'b0, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli else if (instr16[11:10] == 2'b01) - InstrD = {6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai + LInstrD = {1'b0, 6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai else if (instr16[11:10] == 2'b10) - InstrD = {immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi + LInstrD = {1'b0, immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi else if (instr16[12:10] == 3'b011) if (instr16[6:5] == 2'b00) - InstrD = {7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub + LInstrD = {1'b0, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub else if (instr16[6:5] == 2'b01) - InstrD = {7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor + LInstrD = {1'b0, 7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor else if (instr16[6:5] == 2'b10) - InstrD = {7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or + LInstrD = {1'b0, 7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or else // if (instr16[6:5] == 2'b11) - InstrD = {7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and + LInstrD = {1'b0, 7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and else begin // (instr16[12:10] == 3'b111) if (instr16[6:5] == 2'b00 & P.XLEN > 32) - InstrD = {7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw + LInstrD = {1'b0, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw else if (instr16[6:5] == 2'b01 & P.XLEN > 32) - InstrD = {7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw + LInstrD = {1'b0, 7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw else if (instr16[6:2] == 5'b11000 & P.ZCB_SUPPORTED) - InstrD = {12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255 + LInstrD = {1'b0, 12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255 else if (instr16[6:2] == 5'b11001 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) - InstrD = {12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b + LInstrD = {1'b0, 12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b else if (instr16[6:2] == 5'b11010 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) - InstrD = {7'b0000100, 5'b00000, rds1p, 3'b100, rds1p, 3'b011, P.XLEN > 32, 3'b011}; // c.zext.h + LInstrD = {1'b0, 7'b0000100, 5'b00000, rds1p, 3'b100, rds1p, 3'b011, P.XLEN > 32, 3'b011}; // c.zext.h else if (instr16[6:2] == 5'b11011 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) - InstrD = {12'b011000000101, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.h + LInstrD = {1'b0, 12'b011000000101, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.h else if (instr16[6:2] == 5'b11101 & P.ZCB_SUPPORTED) - InstrD = {12'b111111111111, rds1p, 3'b100, rds1p, 7'b0010011}; // c.not = xori + LInstrD = {1'b0, 12'b111111111111, rds1p, 3'b100, rds1p, 7'b0010011}; // c.not = xori else if (instr16[6:2] == 5'b11100 & P.ZCB_SUPPORTED & P.ZBA_SUPPORTED & P.XLEN > 32) - InstrD = {7'b0000100, 5'b00000, rds1p, 3'b000, rds1p, 7'b0111011}; // c.zext.w = add.uw rd, rs1, 0 + LInstrD = {1'b0, 7'b0000100, 5'b00000, rds1p, 3'b000, rds1p, 7'b0111011}; // c.zext.w = add.uw rd, rs1, 0 else if (instr16[6:5] == 2'b10 & P.ZCB_SUPPORTED & P.ZMMUL_SUPPORTED) - InstrD = {7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul - else begin // reserved - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - /** end else begin // illegal instruction - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap **/ + LInstrD = {1'b0, 7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul end - 5'b01101: InstrD = {immCJ, 5'b00000, 7'b1101111}; // c.j - 5'b01110: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz - 5'b01111: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez - 5'b10000: InstrD = {6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli + 5'b01101: LInstrD = {1'b0, immCJ, 5'b00000, 7'b1101111}; // c.j + 5'b01110: LInstrD = {1'b0, immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz + 5'b01111: LInstrD = {1'b0, immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez + 5'b10000: LInstrD = {1'b0, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli 5'b10001: if (P.ZCD_SUPPORTED) - InstrD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp - else begin // unsupported instruction - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - 5'b10010: InstrD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp - 5'b10011: if (P.XLEN == 32) + LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp + 5'b10010: LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp + 5'b10011: if (P.XLEN == 32) begin if (P.ZCF_SUPPORTED) - InstrD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp - else begin - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - else - InstrD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp + LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp + end else + LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp 5'b10100: if (instr16[12] == 0) if (instr16[6:2] == 5'b00000) - InstrD = {7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr + LInstrD = {1'b0, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr else - InstrD = {7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv + LInstrD = {1'b0, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv else if (rs2 == 5'b00000) if (rds1 == 5'b00000) - InstrD = {12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak + LInstrD = {1'b0, 12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak else - InstrD = {12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr + LInstrD = {1'b0, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr else - InstrD = {7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add + LInstrD = {1'b0, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add 5'b10101: if (P.ZCD_SUPPORTED) - InstrD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp - else begin // unsupported instruction - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - 5'b10110: InstrD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp - 5'b10111: if (P.XLEN==32) + LInstrD = {1'b0, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp + 5'b10110: LInstrD = {1'b0, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp + 5'b10111: if (P.XLEN==32) begin if (P.ZCF_SUPPORTED) - InstrD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp - else begin - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end - else - InstrD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp - default: begin // illegal instruction - IllegalCompInstrD = 1'b1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap - end + LInstrD = {1'b0, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp + end else + LInstrD = {1'b0, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp + default: ; // illegal instruction endcase end + + // extract instruction and illegal from LInstrD + assign {IllegalCompInstrD, InstrD} = LInstrD; + endmodule From 3b4726ea9906cbc943d32b83be98bf0729966f84 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 18 Jul 2024 09:30:16 -0700 Subject: [PATCH 3/6] Check legal compressed nonzero destination registers, add c.nop decoding --- src/ifu/decompress.sv | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index d8a1afb8b..340c5055a 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -109,16 +109,17 @@ module decompress import cvw::*; #(parameter cvw_t P) ( LInstrD = {1'b0, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw end else LInstrD = {1'b0, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd - 5'b01000: LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi + 5'b01000: if (rds1 != 5'b0) LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi + else if (immCI[5:0] == 6'b0) LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.nop 5'b01001: if (P.XLEN==32) LInstrD = {1'b0, immCJ, 5'b00001, 7'b1101111}; // c.jal else LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw - 5'b01010: LInstrD = {1'b0, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li - 5'b01011: if (rds1 != 5'b00010) - LInstrD = {1'b0, immCILUI, rds1, 7'b0110111}; // c.lui - else + 5'b01010: if (rds1 != 5'b0) LInstrD = {1'b0, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li + 5'b01011: if (rds1 == 5'b00010) LInstrD = {1'b0, immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp + else if (rds1 != 5'b0) + LInstrD = {1'b0, immCILUI, rds1, 7'b0110111}; // c.lui 5'b01100: if (instr16[11:10] == 2'b00) LInstrD = {1'b0, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli else if (instr16[11:10] == 2'b01) @@ -159,25 +160,25 @@ module decompress import cvw::*; #(parameter cvw_t P) ( 5'b01111: LInstrD = {1'b0, immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez 5'b10000: LInstrD = {1'b0, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli 5'b10001: if (P.ZCD_SUPPORTED) - LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp - 5'b10010: LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp + if (rds1 != 5'b0) LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp + 5'b10010: if (rds1 != 5'b0) LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp 5'b10011: if (P.XLEN == 32) begin if (P.ZCF_SUPPORTED) LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp end else LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp 5'b10100: if (instr16[12] == 0) - if (instr16[6:2] == 5'b00000) - LInstrD = {1'b0, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr - else + if (instr16[6:2] == 5'b00000) begin + if (rds1 != 5'b0) LInstrD = {1'b0, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr + end else LInstrD = {1'b0, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv else - if (rs2 == 5'b00000) + if (rs2 == 5'b00000) begin if (rds1 == 5'b00000) LInstrD = {1'b0, 12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak else - LInstrD = {1'b0, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr - else + if (rds1 != 5'b0) LInstrD = {1'b0, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr + end else LInstrD = {1'b0, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add 5'b10101: if (P.ZCD_SUPPORTED) LInstrD = {1'b0, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp From ebea314a6edd238cfff2563f647eeafbd57383e7 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 18 Jul 2024 21:38:17 -0700 Subject: [PATCH 4/6] Modified decompressor to look for illegal x0 values and hints --- src/ifu/decompress.sv | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index 340c5055a..10d59f7f2 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -109,22 +109,27 @@ module decompress import cvw::*; #(parameter cvw_t P) ( LInstrD = {1'b0, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw end else LInstrD = {1'b0, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd - 5'b01000: if (rds1 != 5'b0) LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi + 5'b01000: if (rds1 != 5'b0) + if (immCI[5:0] != 0) LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi + else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.addi with imm = 0 is a HINT, treated as nop else if (immCI[5:0] == 6'b0) LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.nop + else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.nop with imm != 0 is a HINT, treated as nop 5'b01001: if (P.XLEN==32) LInstrD = {1'b0, immCJ, 5'b00001, 7'b1101111}; // c.jal - else + else if (rds1 != 5'b0) LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw 5'b01010: if (rds1 != 5'b0) LInstrD = {1'b0, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li + else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.li with rd = 0 is a HINT, treated as nop 5'b01011: if (rds1 == 5'b00010) LInstrD = {1'b0, immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp else if (rds1 != 5'b0) LInstrD = {1'b0, immCILUI, rds1, 7'b0110111}; // c.lui - 5'b01100: if (instr16[11:10] == 2'b00) - LInstrD = {1'b0, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli - else if (instr16[11:10] == 2'b01) - LInstrD = {1'b0, 6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai - else if (instr16[11:10] == 2'b10) + else if (immCILUI[5:0] != 0) LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.lui with rd = 0, imm!=0 is a HINT, treated as nop + 5'b01100: if (instr16[11:10] == 2'b00) begin + if (P.XLEN == 64 | ~immSH[5]) LInstrD = {1'b0, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli; shamt[5] must be 0 in RV32C + end else if (instr16[11:10] == 2'b01) begin + if (P.XLEN == 64 | ~immSH[5]) LInstrD = {1'b0, 6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai; shamt[5] must be 0 in RV32C + end else if (instr16[11:10] == 2'b10) LInstrD = {1'b0, immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi else if (instr16[12:10] == 3'b011) if (instr16[6:5] == 2'b00) @@ -158,20 +163,23 @@ module decompress import cvw::*; #(parameter cvw_t P) ( 5'b01101: LInstrD = {1'b0, immCJ, 5'b00000, 7'b1101111}; // c.j 5'b01110: LInstrD = {1'b0, immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz 5'b01111: LInstrD = {1'b0, immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez - 5'b10000: LInstrD = {1'b0, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli + 5'b10000: if (rds1 != 5'b0) begin + if (P.XLEN == 64 | ~immSH[5]) LInstrD = {1'b0, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli; shamt[5] must be 0 in RV32C + end else if (immSH != 0) LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.slli with rd = 0, immm != 0 is a HINT, treated as nop 5'b10001: if (P.ZCD_SUPPORTED) if (rds1 != 5'b0) LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp 5'b10010: if (rds1 != 5'b0) LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp 5'b10011: if (P.XLEN == 32) begin if (P.ZCF_SUPPORTED) LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp - end else + end else if (rds1 != 5'b0) LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp 5'b10100: if (instr16[12] == 0) - if (instr16[6:2] == 5'b00000) begin + if (rs2 == 5'b00000) begin if (rds1 != 5'b0) LInstrD = {1'b0, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr end else - LInstrD = {1'b0, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv + if (rds1 != 5'b0) LInstrD = {1'b0, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv + else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.mv with rd = 0 is a HINT, treated as nop else if (rs2 == 5'b00000) begin if (rds1 == 5'b00000) @@ -179,7 +187,8 @@ module decompress import cvw::*; #(parameter cvw_t P) ( else if (rds1 != 5'b0) LInstrD = {1'b0, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr end else - LInstrD = {1'b0, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add + if (rds1 != 0) LInstrD = {1'b0, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add + else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.add with rd = 0 is a HINT, treated as nop, even if it is a C.NTL 5'b10101: if (P.ZCD_SUPPORTED) LInstrD = {1'b0, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp 5'b10110: LInstrD = {1'b0, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp From 945722cd5b15a23d2da79a68a9887d26a1681a93 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 18 Jul 2024 22:01:43 -0700 Subject: [PATCH 5/6] Neatly formatted decompress.sv --- src/ifu/decompress.sv | 159 ++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 91 deletions(-) diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index 10d59f7f2..2b0caf269 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -40,6 +40,7 @@ module decompress import cvw::*; #(parameter cvw_t P) ( logic [19:0] immCJ, immCILUI; logic [5:0] immSH; logic [1:0] op; + logic LegalCompInstrD; // Extract op and register source/destination fields assign instr16 = InstrRawD[15:0]; // instruction is already aligned @@ -76,132 +77,108 @@ module decompress import cvw::*; #(parameter cvw_t P) ( always_comb if (op == 2'b11) begin // noncompressed instruction - LInstrD = {1'b0, InstrRawD}; + LInstrD = {1'b1, InstrRawD}; end else begin // convert compressed instruction into uncompressed - LInstrD = {1'b1, 16'b0, instr16}; // if a legal instruction is not decoded, default to illegal and preserve 16-bit value for mtval + LInstrD = {1'b0, 16'b0, instr16}; // if a legal instruction is not decoded, default to illegal and preserve 16-bit value for mtval case ({op, instr16[15:13]}) - 5'b00000: if (immCIW != 0) LInstrD = {1'b0, immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn - 5'b00001: if (P.ZCD_SUPPORTED) - LInstrD = {1'b0, immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld - 5'b00010: LInstrD = {1'b0, immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw + 5'b00000: if (immCIW != 0) LInstrD = {1'b1, immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn + 5'b00001: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld + 5'b00010: LInstrD = {1'b1, immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw 5'b00011: if (P.XLEN==32) begin - if (P.ZCF_SUPPORTED) - LInstrD = {1'b0, immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw - end else - LInstrD = {1'b0, immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld + if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw + end else LInstrD = {1'b1, immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld 5'b00100: if (P.ZCB_SUPPORTED) - if (instr16[12:10] == 3'b000) - LInstrD = {1'b0, 10'b0, instr16[5], instr16[6], rs1p, 3'b100, rdp, 7'b0000011}; // c.lbu + if (instr16[12:10] == 3'b000) LInstrD = {1'b1, 10'b0, instr16[5], instr16[6], rs1p, 3'b100, rdp, 7'b0000011}; // c.lbu else if (instr16[12:10] == 3'b001) begin - if (instr16[6]) - LInstrD = {1'b0, 10'b0, instr16[5], 1'b0, rs1p, 3'b001, rdp, 7'b0000011}; // c.lh - else - LInstrD = {1'b0, 10'b0, instr16[5], 1'b0, rs1p, 3'b101, rdp, 7'b0000011}; // c.lhu + if (instr16[6]) LInstrD = {1'b1, 10'b0, instr16[5], 1'b0, rs1p, 3'b001, rdp, 7'b0000011}; // c.lh + else LInstrD = {1'b1, 10'b0, instr16[5], 1'b0, rs1p, 3'b101, rdp, 7'b0000011}; // c.lhu end else if (instr16[12:10] == 3'b010) - LInstrD = {1'b0, 7'b0, rs2p, rs1p, 3'b000, 3'b000, instr16[5], instr16[6], 7'b0100011}; // c.sb + LInstrD = {1'b1, 7'b0, rs2p, rs1p, 3'b000, 3'b000, instr16[5], instr16[6], 7'b0100011}; // c.sb else if (instr16[12:10] == 3'b011 & instr16[6] == 1'b0) - LInstrD = {1'b0, 7'b0, rs2p, rs1p, 3'b001, 3'b000, instr16[5], 1'b0, 7'b0100011}; // c.sh - 5'b00101: if (P.ZCD_SUPPORTED) - LInstrD = {1'b0, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd - 5'b00110: LInstrD = {1'b0, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw + LInstrD = {1'b1, 7'b0, rs2p, rs1p, 3'b001, 3'b000, instr16[5], 1'b0, 7'b0100011}; // c.sh + 5'b00101: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd + 5'b00110: LInstrD = {1'b1, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw 5'b00111: if (P.XLEN==32) begin - if (P.ZCF_SUPPORTED) - LInstrD = {1'b0, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw - end else - LInstrD = {1'b0, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd + if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw + end else LInstrD = {1'b1, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd 5'b01000: if (rds1 != 5'b0) - if (immCI[5:0] != 0) LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi - else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.addi with imm = 0 is a HINT, treated as nop - else if (immCI[5:0] == 6'b0) LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.nop - else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.nop with imm != 0 is a HINT, treated as nop - 5'b01001: if (P.XLEN==32) - LInstrD = {1'b0, immCJ, 5'b00001, 7'b1101111}; // c.jal - else if (rds1 != 5'b0) - LInstrD = {1'b0, immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw - 5'b01010: if (rds1 != 5'b0) LInstrD = {1'b0, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li - else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.li with rd = 0 is a HINT, treated as nop - 5'b01011: if (rds1 == 5'b00010) - LInstrD = {1'b0, immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp - else if (rds1 != 5'b0) - LInstrD = {1'b0, immCILUI, rds1, 7'b0110111}; // c.lui - else if (immCILUI[5:0] != 0) LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.lui with rd = 0, imm!=0 is a HINT, treated as nop + if (immCI[5:0] != 0) LInstrD = {1'b1, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.addi with imm = 0 is a HINT, treated as nop + else if (immCI[5:0] == 6'b0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.nop + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.nop with imm != 0 is a HINT, treated as nop + 5'b01001: if (P.XLEN==32) LInstrD = {1'b1, immCJ, 5'b00001, 7'b1101111}; // c.jal + else if (rds1 != 5'b0) LInstrD = {1'b1, immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw + 5'b01010: if (rds1 != 5'b0) LInstrD = {1'b1, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.li with rd = 0 is a HINT, treated as nop + 5'b01011: if (rds1 == 5'b00010) LInstrD = {1'b1, immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp + else if (rds1 != 5'b0) LInstrD = {1'b1, immCILUI, rds1, 7'b0110111}; // c.lui + else if (immCILUI[5:0] != 0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.lui with rd = 0, imm!=0 is a HINT, treated as nop 5'b01100: if (instr16[11:10] == 2'b00) begin - if (P.XLEN == 64 | ~immSH[5]) LInstrD = {1'b0, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli; shamt[5] must be 0 in RV32C + if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli; shamt[5] must be 0 in RV32C end else if (instr16[11:10] == 2'b01) begin - if (P.XLEN == 64 | ~immSH[5]) LInstrD = {1'b0, 6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai; shamt[5] must be 0 in RV32C - end else if (instr16[11:10] == 2'b10) - LInstrD = {1'b0, immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi - else if (instr16[12:10] == 3'b011) - if (instr16[6:5] == 2'b00) - LInstrD = {1'b0, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub - else if (instr16[6:5] == 2'b01) - LInstrD = {1'b0, 7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor - else if (instr16[6:5] == 2'b10) - LInstrD = {1'b0, 7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or - else // if (instr16[6:5] == 2'b11) - LInstrD = {1'b0, 7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and - else begin // (instr16[12:10] == 3'b111) + if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai; shamt[5] must be 0 in RV32C + end else if (instr16[11:10] == 2'b10) LInstrD = {1'b1, immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi + else if (instr16[12:10] == 3'b011) begin + if (instr16[6:5] == 2'b00) LInstrD = {1'b1, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub + else if (instr16[6:5] == 2'b01) LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor + else if (instr16[6:5] == 2'b10) LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or + else LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and + end else begin // (instr16[12:10] == 3'b111) if (instr16[6:5] == 2'b00 & P.XLEN > 32) - LInstrD = {1'b0, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw + LInstrD = {1'b1, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw else if (instr16[6:5] == 2'b01 & P.XLEN > 32) - LInstrD = {1'b0, 7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw + LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw else if (instr16[6:2] == 5'b11000 & P.ZCB_SUPPORTED) - LInstrD = {1'b0, 12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255 + LInstrD = {1'b1, 12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255 else if (instr16[6:2] == 5'b11001 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) - LInstrD = {1'b0, 12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b + LInstrD = {1'b1, 12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b else if (instr16[6:2] == 5'b11010 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) - LInstrD = {1'b0, 7'b0000100, 5'b00000, rds1p, 3'b100, rds1p, 3'b011, P.XLEN > 32, 3'b011}; // c.zext.h + LInstrD = {1'b1, 7'b0000100, 5'b00000, rds1p, 3'b100, rds1p, 3'b011, P.XLEN > 32, 3'b011}; // c.zext.h else if (instr16[6:2] == 5'b11011 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) - LInstrD = {1'b0, 12'b011000000101, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.h + LInstrD = {1'b1, 12'b011000000101, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.h else if (instr16[6:2] == 5'b11101 & P.ZCB_SUPPORTED) - LInstrD = {1'b0, 12'b111111111111, rds1p, 3'b100, rds1p, 7'b0010011}; // c.not = xori + LInstrD = {1'b1, 12'b111111111111, rds1p, 3'b100, rds1p, 7'b0010011}; // c.not = xori else if (instr16[6:2] == 5'b11100 & P.ZCB_SUPPORTED & P.ZBA_SUPPORTED & P.XLEN > 32) - LInstrD = {1'b0, 7'b0000100, 5'b00000, rds1p, 3'b000, rds1p, 7'b0111011}; // c.zext.w = add.uw rd, rs1, 0 + LInstrD = {1'b1, 7'b0000100, 5'b00000, rds1p, 3'b000, rds1p, 7'b0111011}; // c.zext.w = add.uw rd, rs1, 0 else if (instr16[6:5] == 2'b10 & P.ZCB_SUPPORTED & P.ZMMUL_SUPPORTED) - LInstrD = {1'b0, 7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul + LInstrD = {1'b1, 7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul end - 5'b01101: LInstrD = {1'b0, immCJ, 5'b00000, 7'b1101111}; // c.j - 5'b01110: LInstrD = {1'b0, immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz - 5'b01111: LInstrD = {1'b0, immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez + 5'b01101: LInstrD = {1'b1, immCJ, 5'b00000, 7'b1101111}; // c.j + 5'b01110: LInstrD = {1'b1, immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz + 5'b01111: LInstrD = {1'b1, immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez 5'b10000: if (rds1 != 5'b0) begin - if (P.XLEN == 64 | ~immSH[5]) LInstrD = {1'b0, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli; shamt[5] must be 0 in RV32C - end else if (immSH != 0) LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.slli with rd = 0, immm != 0 is a HINT, treated as nop + if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli; shamt[5] must be 0 in RV32C + end else if (immSH != 0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.slli with rd = 0, immm != 0 is a HINT, treated as nop 5'b10001: if (P.ZCD_SUPPORTED) - if (rds1 != 5'b0) LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp - 5'b10010: if (rds1 != 5'b0) LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp + if (rds1 != 5'b0) LInstrD = {1'b1, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp + 5'b10010: if (rds1 != 5'b0) LInstrD = {1'b1, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp 5'b10011: if (P.XLEN == 32) begin - if (P.ZCF_SUPPORTED) - LInstrD = {1'b0, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp - end else if (rds1 != 5'b0) - LInstrD = {1'b0, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp + if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp + end else if (rds1 != 5'b0) LInstrD = {1'b1, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp 5'b10100: if (instr16[12] == 0) if (rs2 == 5'b00000) begin - if (rds1 != 5'b0) LInstrD = {1'b0, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr + if (rds1 != 5'b0) LInstrD = {1'b1, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr end else - if (rds1 != 5'b0) LInstrD = {1'b0, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv - else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.mv with rd = 0 is a HINT, treated as nop + if (rds1 != 5'b0) LInstrD = {1'b1, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.mv with rd = 0 is a HINT, treated as nop else if (rs2 == 5'b00000) begin - if (rds1 == 5'b00000) - LInstrD = {1'b0, 12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak - else - if (rds1 != 5'b0) LInstrD = {1'b0, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr + if (rds1 == 5'b00000) LInstrD = {1'b1, 12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak + else if (rds1 != 5'b0) LInstrD = {1'b1, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr end else - if (rds1 != 0) LInstrD = {1'b0, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add - else LInstrD = {1'b0, 25'b0, 7'b0010011}; // c.add with rd = 0 is a HINT, treated as nop, even if it is a C.NTL - 5'b10101: if (P.ZCD_SUPPORTED) - LInstrD = {1'b0, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp - 5'b10110: LInstrD = {1'b0, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp + if (rds1 != 0) LInstrD = {1'b1, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.add with rd = 0 is a HINT, treated as nop, even if it is a C.NTL + 5'b10101: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp + 5'b10110: LInstrD = {1'b1, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp 5'b10111: if (P.XLEN==32) begin - if (P.ZCF_SUPPORTED) - LInstrD = {1'b0, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp - end else - LInstrD = {1'b0, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp + if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp + end else LInstrD = {1'b1, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp default: ; // illegal instruction endcase end // extract instruction and illegal from LInstrD - assign {IllegalCompInstrD, InstrD} = LInstrD; + assign {LegalCompInstrD, InstrD} = LInstrD; + assign IllegalCompInstrD = ~LegalCompInstrD; endmodule From c64c12dc6c469c0349a7e20fc4f11e7f73eeb6db Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 18 Jul 2024 22:48:32 -0700 Subject: [PATCH 6/6] Detect illegal compressed immediates, hints --- src/ifu/decompress.sv | 118 +++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index 2b0caf269..798993d78 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -64,10 +64,10 @@ module decompress import cvw::*; #(parameter cvw_t P) ( assign immCJ = {instr16[12], instr16[8], instr16[10:9], instr16[6], instr16[7], instr16[2], instr16[11], instr16[5:3], {9{instr16[12]}}}; assign immCB = {{4{instr16[12]}}, instr16[6:5], instr16[2], instr16[11:10], instr16[4:3], instr16[12]}; assign immCI = {{7{instr16[12]}}, instr16[6:2]}; - assign immCILUI = {{15{instr16[12]}}, instr16[6:2]}; - assign immCIASP = {{3{instr16[12]}}, instr16[4:3], instr16[5], instr16[2], instr16[6], 4'b0000}; + assign immCILUI = {{15{instr16[12]}}, instr16[6:2]}; // c.lui + assign immCIASP = {{3{instr16[12]}}, instr16[4:3], instr16[5], instr16[2], instr16[6], 4'b0000}; // c.addi16sp assign immCIW = {2'b00, instr16[10:7], instr16[12:11], instr16[5], instr16[6], 2'b00}; - assign immSH = {instr16[12], instr16[6:2]}; + assign immSH = {instr16[12], instr16[6:2]}; // c. shift instructions: c.srli, c.srai, c.slli // only for RV128 // assign immCILSPQ = {2{instr16[5]}, instr16[5:2], instr16[12], instr16[6], 4'b0000}; @@ -81,97 +81,99 @@ module decompress import cvw::*; #(parameter cvw_t P) ( end else begin // convert compressed instruction into uncompressed LInstrD = {1'b0, 16'b0, instr16}; // if a legal instruction is not decoded, default to illegal and preserve 16-bit value for mtval case ({op, instr16[15:13]}) - 5'b00000: if (immCIW != 0) LInstrD = {1'b1, immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn - 5'b00001: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld - 5'b00010: LInstrD = {1'b1, immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw + 5'b00000: if (immCIW != 0) LInstrD = {1'b1, immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn + 5'b00001: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld + 5'b00010: LInstrD = {1'b1, immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw 5'b00011: if (P.XLEN==32) begin - if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw - end else LInstrD = {1'b1, immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld + if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw + end else LInstrD = {1'b1, immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld 5'b00100: if (P.ZCB_SUPPORTED) - if (instr16[12:10] == 3'b000) LInstrD = {1'b1, 10'b0, instr16[5], instr16[6], rs1p, 3'b100, rdp, 7'b0000011}; // c.lbu + if (instr16[12:10] == 3'b000) LInstrD = {1'b1, 10'b0, instr16[5], instr16[6], rs1p, 3'b100, rdp, 7'b0000011}; // c.lbu else if (instr16[12:10] == 3'b001) begin - if (instr16[6]) LInstrD = {1'b1, 10'b0, instr16[5], 1'b0, rs1p, 3'b001, rdp, 7'b0000011}; // c.lh - else LInstrD = {1'b1, 10'b0, instr16[5], 1'b0, rs1p, 3'b101, rdp, 7'b0000011}; // c.lhu + if (instr16[6]) LInstrD = {1'b1, 10'b0, instr16[5], 1'b0, rs1p, 3'b001, rdp, 7'b0000011}; // c.lh + else LInstrD = {1'b1, 10'b0, instr16[5], 1'b0, rs1p, 3'b101, rdp, 7'b0000011}; // c.lhu end else if (instr16[12:10] == 3'b010) LInstrD = {1'b1, 7'b0, rs2p, rs1p, 3'b000, 3'b000, instr16[5], instr16[6], 7'b0100011}; // c.sb else if (instr16[12:10] == 3'b011 & instr16[6] == 1'b0) LInstrD = {1'b1, 7'b0, rs2p, rs1p, 3'b001, 3'b000, instr16[5], 1'b0, 7'b0100011}; // c.sh - 5'b00101: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd - 5'b00110: LInstrD = {1'b1, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw + 5'b00101: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd + 5'b00110: LInstrD = {1'b1, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw 5'b00111: if (P.XLEN==32) begin - if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw - end else LInstrD = {1'b1, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd + if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw + end else LInstrD = {1'b1, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; // c.sd 5'b01000: if (rds1 != 5'b0) - if (immCI[5:0] != 0) LInstrD = {1'b1, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi - else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.addi with imm = 0 is a HINT, treated as nop - else if (immCI[5:0] == 6'b0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.nop - else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.nop with imm != 0 is a HINT, treated as nop - 5'b01001: if (P.XLEN==32) LInstrD = {1'b1, immCJ, 5'b00001, 7'b1101111}; // c.jal - else if (rds1 != 5'b0) LInstrD = {1'b1, immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw - 5'b01010: if (rds1 != 5'b0) LInstrD = {1'b1, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li - else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.li with rd = 0 is a HINT, treated as nop - 5'b01011: if (rds1 == 5'b00010) LInstrD = {1'b1, immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp - else if (rds1 != 5'b0) LInstrD = {1'b1, immCILUI, rds1, 7'b0110111}; // c.lui - else if (immCILUI[5:0] != 0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.lui with rd = 0, imm!=0 is a HINT, treated as nop + if (immCI[5:0] != 0) LInstrD = {1'b1, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.addi with imm = 0 is a HINT, treated as nop + else if (immCI[5:0] == 6'b0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.nop = addi x0, x0, 0 + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.nop with imm != 0 is a HINT, treated as nop + 5'b01001: if (P.XLEN==32) LInstrD = {1'b1, immCJ, 5'b00001, 7'b1101111}; // c.jal + else if (rds1 != 5'b0) LInstrD = {1'b1, immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw + 5'b01010: if (rds1 != 5'b0) LInstrD = {1'b1, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.li with rd = 0 is a HINT, treated as nop + 5'b01011: if (rds1 == 5'b00010) begin + if (immCIASP[9:4] != 6'b0) LInstrD = {1'b1, immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp + end else if (immCILUI[5:0] != 0) + if (rds1 != 5'b0) LInstrD = {1'b1, immCILUI, rds1, 7'b0110111}; // c.lui + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.lui with rd = 0, imm!=0 is a HINT, treated as nop 5'b01100: if (instr16[11:10] == 2'b00) begin - if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli; shamt[5] must be 0 in RV32C + if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli; shamt[5] must be 0 in RV32C end else if (instr16[11:10] == 2'b01) begin - if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai; shamt[5] must be 0 in RV32C - end else if (instr16[11:10] == 2'b10) LInstrD = {1'b1, immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi + if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai; shamt[5] must be 0 in RV32C + end else if (instr16[11:10] == 2'b10) LInstrD = {1'b1, immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi else if (instr16[12:10] == 3'b011) begin - if (instr16[6:5] == 2'b00) LInstrD = {1'b1, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub - else if (instr16[6:5] == 2'b01) LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor - else if (instr16[6:5] == 2'b10) LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or - else LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and + if (instr16[6:5] == 2'b00) LInstrD = {1'b1, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub + else if (instr16[6:5] == 2'b01) LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor + else if (instr16[6:5] == 2'b10) LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or + else LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and end else begin // (instr16[12:10] == 3'b111) if (instr16[6:5] == 2'b00 & P.XLEN > 32) - LInstrD = {1'b1, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw + LInstrD = {1'b1, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw else if (instr16[6:5] == 2'b01 & P.XLEN > 32) - LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw + LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw else if (instr16[6:2] == 5'b11000 & P.ZCB_SUPPORTED) - LInstrD = {1'b1, 12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255 + LInstrD = {1'b1, 12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255 else if (instr16[6:2] == 5'b11001 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) - LInstrD = {1'b1, 12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b + LInstrD = {1'b1, 12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b else if (instr16[6:2] == 5'b11010 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) LInstrD = {1'b1, 7'b0000100, 5'b00000, rds1p, 3'b100, rds1p, 3'b011, P.XLEN > 32, 3'b011}; // c.zext.h else if (instr16[6:2] == 5'b11011 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED) - LInstrD = {1'b1, 12'b011000000101, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.h + LInstrD = {1'b1, 12'b011000000101, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.h else if (instr16[6:2] == 5'b11101 & P.ZCB_SUPPORTED) - LInstrD = {1'b1, 12'b111111111111, rds1p, 3'b100, rds1p, 7'b0010011}; // c.not = xori + LInstrD = {1'b1, 12'b111111111111, rds1p, 3'b100, rds1p, 7'b0010011}; // c.not = xori else if (instr16[6:2] == 5'b11100 & P.ZCB_SUPPORTED & P.ZBA_SUPPORTED & P.XLEN > 32) - LInstrD = {1'b1, 7'b0000100, 5'b00000, rds1p, 3'b000, rds1p, 7'b0111011}; // c.zext.w = add.uw rd, rs1, 0 + LInstrD = {1'b1, 7'b0000100, 5'b00000, rds1p, 3'b000, rds1p, 7'b0111011}; // c.zext.w = add.uw rd, rs1, 0 else if (instr16[6:5] == 2'b10 & P.ZCB_SUPPORTED & P.ZMMUL_SUPPORTED) - LInstrD = {1'b1, 7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul + LInstrD = {1'b1, 7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul end 5'b01101: LInstrD = {1'b1, immCJ, 5'b00000, 7'b1101111}; // c.j - 5'b01110: LInstrD = {1'b1, immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz - 5'b01111: LInstrD = {1'b1, immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez + 5'b01110: LInstrD = {1'b1, immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz + 5'b01111: LInstrD = {1'b1, immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez 5'b10000: if (rds1 != 5'b0) begin - if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli; shamt[5] must be 0 in RV32C - end else if (immSH != 0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.slli with rd = 0, immm != 0 is a HINT, treated as nop + if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli; shamt[5] must be 0 in RV32C + end else if (immSH != 0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.slli with rd = 0, immm != 0 is a HINT, treated as nop 5'b10001: if (P.ZCD_SUPPORTED) - if (rds1 != 5'b0) LInstrD = {1'b1, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp - 5'b10010: if (rds1 != 5'b0) LInstrD = {1'b1, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp + if (rds1 != 5'b0) LInstrD = {1'b1, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp + 5'b10010: if (rds1 != 5'b0) LInstrD = {1'b1, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp 5'b10011: if (P.XLEN == 32) begin - if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp - end else if (rds1 != 5'b0) LInstrD = {1'b1, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp + if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp + end else if (rds1 != 5'b0) LInstrD = {1'b1, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp 5'b10100: if (instr16[12] == 0) if (rs2 == 5'b00000) begin - if (rds1 != 5'b0) LInstrD = {1'b1, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr + if (rds1 != 5'b0) LInstrD = {1'b1, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr end else - if (rds1 != 5'b0) LInstrD = {1'b1, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv - else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.mv with rd = 0 is a HINT, treated as nop + if (rds1 != 5'b0) LInstrD = {1'b1, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.mv with rd = 0 is a HINT, treated as nop else if (rs2 == 5'b00000) begin - if (rds1 == 5'b00000) LInstrD = {1'b1, 12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak - else if (rds1 != 5'b0) LInstrD = {1'b1, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr + if (rds1 == 5'b00000) LInstrD = {1'b1, 12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak + else if (rds1 != 5'b0) LInstrD = {1'b1, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr end else - if (rds1 != 0) LInstrD = {1'b1, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add - else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.add with rd = 0 is a HINT, treated as nop, even if it is a C.NTL + if (rds1 != 0) LInstrD = {1'b1, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add + else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.add with rd = 0 is a HINT, treated as nop, even if it is a C.NTL 5'b10101: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp - 5'b10110: LInstrD = {1'b1, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp + 5'b10110: LInstrD = {1'b1, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp 5'b10111: if (P.XLEN==32) begin - if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp + if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp end else LInstrD = {1'b1, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp default: ; // illegal instruction endcase