anchor.diff:                  interrupt: isInterrupt,
                   cause: trapCause } );
   
  -        // This split attribute is required to produce multiple rules so the
  -        // ifetch.response.get method doesn't cause this rule to conflict
  -        // with the execute rule.
  -        (* split *)
           if (maybeNextPc matches tagged Valid .replayPc) begin
               // This instruction is not writing to the register file
               // it is either an instruction that requires flushing the pipeline
               // or it caused an exception
               fetchStateEhr[0] <= tagged Valid FetchState{ pc: replayPc };
               // kill other instructions
  -            if (executeStateEhr[0] matches tagged Valid .*) begin
  -                let ignore <- ifetch.response.get;
  -            end
  -            executeStateEhr[0] <= tagged Invalid;
  +            if (executeStateEhr[0] matches tagged Valid .validExecuteState) begin
  +                executeStateEhr[0] <= tagged Valid ExecuteState{ poisoned: True, pc: validExecuteState.pc };
  +            end
           end else begin
               // This instruction retired
               // write to the register file
  
positive.code:     Ehr#(4, Maybe#(FetchState)) fetchStateEhr <- mkEhr(tagged Invalid);
      Ehr#(4, Maybe#(ExecuteState)) executeStateEhr <- mkEhr(tagged Invalid);
      Ehr#(4, Maybe#(WriteBackState)) writeBackStateEhr <- mkEhr(tagged Invalid);
  
      FIFO#(VerificationPacket) verificationPackets <- mkFIFO;
  
  
negative.code:         ifetch.request.put(pc);
  
          // pass to execute state
          executeStateEhr[2] <= tagged Valid ExecuteState{ poisoned: False, pc: pc };
      endrule
  
      rule doExecute(executeStateEhr[1] matches tagged Valid .executeState
                      &&& writeBackStateEhr[1] == tagged Invalid);
          // get and clear the execute state
          let poisoned = executeState.poisoned;
          let pc = executeState.pc;
          executeStateEhr[1] <= tagged Invalid;
  
          // get the instruction
          let inst <- ifetch.response.get;
  
          if (!poisoned) begin
              // check for interrupts
              Maybe#(TrapCause) trap = tagged Invalid;
              if (csrf.readyInterrupt matches tagged Valid .validInterrupt) begin
                  trap = tagged Valid (tagged Interrupt validInterrupt);
              end
  
              // decode the instruction
              let maybeDInst = decodeInst(inst);
              if (maybeDInst == tagged Invalid && trap == tagged Invalid) begin
                  trap = tagged Valid (tagged Exception IllegalInst);
              end
              let dInst = fromMaybe(?, maybeDInst);
  
              // $display("[Execute] pc: 0x%0x, inst: 0x%0x, dInst: ", pc, inst, fshow(dInst));
  
              // read registers
              let rVal1 = rf.rd1(toFullRegIndex(dInst.rs1, getInstFields(inst).rs1));
              let rVal2 = rf.rd2(toFullRegIndex(dInst.rs2, getInstFields(inst).rs2));
  
              // execute instruction
              let execResult = basicExec(dInst, rVal1, rVal2, pc);
              let data = execResult.data;
              let addr = execResult.addr;
              let nextPc = execResult.nextPc;
  
              // check for next address alignment
              if (nextPc[1:0] != 0 && trap == tagged Invalid) begin
                  trap = tagged Valid (tagged Exception InstAddrMisaligned);
              end
  
  `ifdef CONFIG_M
              if (dInst.execFunc matches tagged MulDiv .mulDivInst &&& trap == tagged Invalid) begin
                  mulDiv.exec(mulDivInst, rVal1, rVal2);
              end
  `endif
  
              if (dInst.execFunc matches tagged Mem .memInst &&& trap == tagged Invalid) begin
                  // check allignment
                  Bool aligned = (case (memInst.size)
                                      B: True;
                                      H: (execResult.addr[0] == 0);
                                      W: (execResult.addr[1:0] == 0);
                                      D: (execResult.addr[2:0] == 0);
                                  endcase);
                  if (aligned) begin
                      // send the request to the memory
                      dmem.request.put( RVDMemReq {
                          op: dInst.execFunc.Mem.op,
                          size: dInst.execFunc.Mem.size,
                          isUnsigned: dInst.execFunc.Mem.isUnsigned,
                          addr: zeroExtend(addr),
                          data: data } );
                  end else begin
                      // misaligned address exception
                      if ((memInst.op == tagged Mem Ld) || (memInst.op == tagged Mem Lr)) begin
                          trap = tagged Valid (tagged Exception LoadAddrMisaligned);
                      end else begin
                          trap = tagged Valid (tagged Exception StoreAddrMisaligned);
                      end
                  end
              end
  
              // update next pc for fetch stage if no trap
              if (trap == tagged Invalid) begin
                  fetchStateEhr[1] <= tagged Valid FetchState{ pc: nextPc };
              end
              // store things for next stage
              writeBackStateEhr[1] <= tagged Valid WriteBackState{
                                                          pc: pc,
                                                          trap: trap,
                                                          dInst: dInst,
                                                          addr: addr,
                                                          data: data
                                                      };
          end
      endrule
  
      rule doWriteBack(writeBackStateEhr[0] matches tagged Valid .writeBackState
  