anchor.diff:          ifetch.request.put(pc);
   
           // pass to execute state
  -        executeStateEhr[2] <= tagged Valid ExecuteState{ pc: pc };
  +        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;
   
  -        // check for interrupts
  -        Maybe#(TrapCause) trap = tagged Invalid;
  -        if (csrf.readyInterrupt matches tagged Valid .validInterrupt) begin
  -            trap = tagged Valid (tagged Interrupt validInterrupt);
  -        end
  -
           // get the instruction
           let inst <- ifetch.response.get;
   
  -        // decode the instruction
  -        let maybeDInst = decodeInst(inst);
  -        if (maybeDInst == tagged Invalid && trap == tagged Invalid) begin
  -            trap = tagged Valid (tagged Exception IllegalInst);
  +        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
  -        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
  -                                                };
       endrule
   
       rule doWriteBack(writeBackStateEhr[0] matches tagged Valid .writeBackState
  
positive.code:                 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;
          end else begin
              // This instruction retired
              // write to the register file
  
negative.code: } FetchState deriving (Bits, Eq, FShow);
  
  typedef struct {
      Bool poisoned;
      Addr pc;
  } ExecuteState deriving (Bits, Eq, FShow);
  
  