diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv
index 386ca2280..97bda128e 100644
--- a/src/ieu/controller.sv
+++ b/src/ieu/controller.sv
@@ -131,6 +131,9 @@ module controller(
   logic        BALUOpD;                        // Indicates if it is an ALU B instruction in decode stage
   logic        BSubArithD;                     // TRUE for B-type ext, clr, andn, orn, xnor
   logic        BComparatorSignedE;             // Indicates if max, min (signed comarison) instruction in Execute Stage
+  logic        IFunctD, RFunctD, MFunctD;      // Detect I, R, and M-type RV32IM/Rv64IM instructions
+  logic        LFunctD, SFunctD, BFunctD;      // Detect load, store, branch instructions
+  logic        JFunctD;                        // detect jalr instruction
 
   // Extract fields
   assign OpD = InstrD[6:0];
@@ -138,24 +141,65 @@ module controller(
   assign Funct7D = InstrD[31:25];
   assign Rs1D = InstrD[19:15];
 
+  // Funct 7 checking
+  // Be rigorous about detecting illegal instructions if CSRs or bit manipulation is supported
+  // otherwise be cheap
+
+  if (`ZICSR_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED | `ZBS_SUPPORTED) begin:legalcheck // Exact integer decoding
+    logic Funct7ZeroD, Funct7b5D, IShiftD, INoShiftD;
+    logic Funct7ShiftZeroD, Funct7Shiftb5D;
+
+    assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions
+    assign Funct7b5D   = (Funct7D == 7'b0100000); // srai, sub
+    assign Funct7ShiftZeroD = (`XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD;
+    assign Funct7Shiftb5D   = (`XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D;
+    assign IShiftD     = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms
+    assign INoShiftD   = ((Funct3D != 3'b001) & (Funct3D != 3'b101));
+    assign IFunctD     = IShiftD | INoShiftD;
+    assign RFunctD     = ((Funct3D == 3'b000 | Funct3D == 3'b101) & Funct7b5D) | Funct7ZeroD;
+    assign MFunctD     = (Funct7D == 7'b0000001) & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
+    assign LFunctD     = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | Funct3D == 3'b100 | Funct3D == 3'b101 | 
+                         ((`XLEN == 64) & (Funct3D == 3'b011 | Funct3D == 3'b110));
+    assign SFunctD     = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | 
+                         ((`XLEN == 64) & (Funct3D == 3'b011));
+    assign BFunctD     = (Funct3D[2:1] != 2'b01); // legal branches
+    assign JFunctD     = (Funct3D == 3'b000);
+  end else begin:legalcheck2
+    assign IFunctD     = 1; // Don't bother to separate out shift decoding
+    assign RFunctD     = ~Funct7D[0]; // Not a multiply
+    assign MFunctD     = Funct7D[0] & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
+    assign LFunctD     = 1; // don't bother to check Funct3 for loads
+    assign SFunctD     = 1; // don't bother to check Funct3 for stores
+    assign BFunctD     = 1; // don't bother to check Funct3 for branches
+    assign JFunctD     = 1; // don't bother to check Funct3 for jumps    
+  end
+
   // Main Instruction Decoder
-  always_comb
+  /* verilator lint_off CASEINCOMPLETE */
+  always_comb begin
+    ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // default: Illegal instruction
     case(OpD)
+<<<<<<< HEAD
     // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_BaseALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal
       7'b0000000:     ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Illegal instruction
       7'b0000011:     ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw
+=======
+    // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal
+     7'b0000011: if (LFunctD) 
+                      ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // loads
+>>>>>>> origin
       7'b0000111:     ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported
       7'b0001111: if (`ZIFENCEI_SUPPORTED)
                       ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
               	  else
                       ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop
-      7'b0010011:     ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU
+      7'b0010011: if (IFunctD)    
+                      ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU
       7'b0010111:     ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc
-      7'b0011011: if (`XLEN == 64)
+      7'b0011011: if (IFunctD & `XLEN == 64)
                       ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i
-                  else
-                      ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
-      7'b0100011:     ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // sw
+      7'b0100011: if (SFunctD) 
+                      ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // stores
       7'b0100111:     ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_1; // fsw - only legal if FP supported
       7'b0101111: if (`A_SUPPORTED) begin
                     if (InstrD[31:27] == 5'b00010)
@@ -164,33 +208,30 @@ module controller(
                       ControlsD = `CTRLW'b1_101_01_01_100_0_0_0_0_0_0_0_0_0_01_0; // sc
                     else 
                       ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0; // amo
-                  end else
-                      ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
-      7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000)
+                 end
+      7'b0110011: if (RFunctD)
                       ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type 
-                  else if (Funct7D == 7'b0000001 & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])))
+                  else if (MFunctD)
                       ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide
-                  else
-                      ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
       7'b0110111:     ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui
-      7'b0111011: if ((Funct7D == 7'b0000000 | Funct7D == 7'b0100000) & `XLEN == 64)
+      7'b0111011: if (RFunctD & (`XLEN == 64))
                       ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i
-                  else if (Funct7D == 7'b0000001 & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])) & `XLEN == 64)
+                  else if (MFunctD & (`XLEN == 64))
                       ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide
-                  else
-                      ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
-      7'b1100011:     ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches
-      7'b1100111:     ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr
+      7'b1100011: if (BFunctD)   
+                      ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches
+      7'b1100111: if (JFunctD)
+                      ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr
       7'b1101111:     ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal
       7'b1110011: if (`ZICSR_SUPPORTED) begin
                    if (Funct3D == 3'b000)
                       ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules
                    else
                       ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs
-                  end else
-                      ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
-      default:        ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
+                  end
     endcase
+  end
+  /* verilator lint_on CASEINCOMPLETE */
 
   // Unswizzle control bits
   // Squash control signals if coming from an illegal compressed instruction
diff --git a/testbench/common/riscvassertions.sv b/testbench/common/riscvassertions.sv
index f733aac58..b3bc8f96f 100644
--- a/testbench/common/riscvassertions.sv
+++ b/testbench/common/riscvassertions.sv
@@ -23,7 +23,6 @@
 
 module riscvassertions;
   initial begin
-    $display("IDIV_ON_FPU = %b M_SUPPORTED %b comb %b\n", `IDIV_ON_FPU, `M_SUPPORTED, ((`IDIV_ON_FPU) || (!`M_SUPPORTED)));
     assert (`PMP_ENTRIES == 0 || `PMP_ENTRIES==16 || `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
     assert (`S_SUPPORTED || `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support");
     assert (`IDIV_BITSPERCYCLE == 1 || `IDIV_BITSPERCYCLE==2 || `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");