cv32e40p系列<19>


      XRET_JUMP:
      begin
        is_decoding_o = 1'b0;
        ctrl_fsm_ns   = DECODE;
        unique case(1'b1)
          mret_dec_i: begin
              //mret
              pc_mux_o              = debug_mode_q ? PC_EXCEPTION : PC_MRET;
              pc_set_o              = 1'b1;
              exc_pc_mux_o          = EXC_PC_DBE; // only used if in debug_mode
          end
          uret_dec_i: begin
              //uret
              pc_mux_o              = debug_mode_q ? PC_EXCEPTION : PC_URET;
              pc_set_o              = 1'b1;
              exc_pc_mux_o          = EXC_PC_DBE; // only used if in debug_mode
          end
          dret_dec_i: begin
              //dret
              // this case is only reachable while in debug_mode
              pc_mux_o              = PC_DRET;
              pc_set_o              = 1'b1;
              debug_mode_n          = 1'b0;
          end
          default:;
        endcase

        if (debug_single_step_i && ~debug_mode_q) begin
          ctrl_fsm_ns = DBG_TAKEN_IF;
        end
      end

      // a branch was in ID when trying to go to debug rom. Wait until we can
      // determine branch target address (for saving into dpc) before proceeding
      DBG_WAIT_BRANCH:
      begin
        is_decoding_o = 1'b0;
        halt_if_o = 1'b1;

        if (branch_taken_ex_i) begin
          // there is a branch in the EX stage that is taken
          pc_mux_o = PC_BRANCH;
          pc_set_o = 1'b1;
        end

        ctrl_fsm_ns = DBG_FLUSH;
      end

      // We enter this state when we encounter
      // 1. ebreak during debug mode
      // 2. trigger match
      // 3. ebreak with forced entry into debug mode (ebreakm or ebreaku set).
      // 4. halt request during decode
      // Regular ebreak's go through FLUSH_EX and FLUSH_WB.
      // For 1. we don't update dcsr and dpc while for 2., 3., & 4. we do
      // dpc is set to the address of ebreak and trigger match
      // not to the next instruction's (which is why we save the pc in id).
      DBG_TAKEN_ID:
      begin
        is_decoding_o     = 1'b0;
        pc_set_o          = 1'b1;
        pc_mux_o          = PC_EXCEPTION;
        exc_pc_mux_o      = EXC_PC_DBD;
        // If not in debug mode then save cause and dpc csrs
        // else it was an ebreak in debug mode, so don't update csrs
        if (~debug_mode_q) begin
            csr_save_cause_o = 1'b1;
            csr_save_id_o    = 1'b1;
            debug_csr_save_o = 1'b1;
            if (trigger_match_i)
                debug_cause_o = DBG_CAUSE_TRIGGER; // pri 4 (highest)
            else if (ebrk_force_debug_mode & ebrk_insn_i)
                debug_cause_o = DBG_CAUSE_EBREAK; // pri 3
            else if (debug_req_entry_q)
                debug_cause_o = DBG_CAUSE_HALTREQ;// pri 2 and 1

        end
        debug_req_entry_n  = 1'b0;
        ctrl_fsm_ns        = DECODE;
        debug_mode_n       = 1'b1;
      end

XRET_JUMPDBG_WAIT_BRANCHDBG_TAKEN_ID这三个状态中,处理器控制器采取了不同的行为来处理特定的指令和调试事件。

XRET_JUMP

XRET_JUMP状态中,处理器响应mreturetdret指令,这些指令用于从异常或调试模式返回到正常执行流程。

  • mret_dec_i:处理mret指令,用于从机器模式异常返回。
  • uret_dec_i:处理uret指令,用于从用户模式异常返回。
  • dret_dec_i:处理dret指令,用于从调试模式返回。在执行dret指令后,将关闭调试模式。

如果启用了单步调试模式(debug_single_step_i),则在完成返回操作后,处理器将进入调试状态(DBG_TAKEN_IF)。

DBG_WAIT_BRANCH

DBG_WAIT_BRANCH状态中,处理器正在等待分支指令的目标地址确定,这是为了正确更新调试寄存器(如dpc)。如果EX阶段有分支指令被采纳(branch_taken_ex_i),则设置程序计数器(PC)跳转到分支目标地址。完成后,处理器进入DBG_FLUSH状态,以处理调试事件。

DBG_TAKEN_ID

DBG_TAKEN_ID状态中,处理器响应以下事件进入调试模式:

  1. 在调试模式下遇到ebreak指令。
  2. 触发器匹配。
  3. 强制进入调试模式(由ebreakmebreaku设置)。
  4. 在解码阶段收到停止请求。

在此状态中,处理器设置程序计数器跳转到异常处理程序,但特别是在调试模式下遇到ebreak时,不更新调试相关的CSR。对于其他情况,则更新相应的调试寄存器。完成后,处理器返回到DECODE状态继续执行指令,并将调试模式标志设置为激活(debug_mode_n = 1'b1)。

这些状态允许处理器在面对特定系统指令、异常和调试事件时灵活处理,确保了正确的程序流程和调试功能的实现。


      // We enter this state for single stepping
      // DPC is set the next instruction to be executed/fetched
      DBG_TAKEN_IF:
      begin
        is_decoding_o     = 1'b0;
        pc_set_o          = 1'b1;
        pc_mux_o          = PC_EXCEPTION;
        exc_pc_mux_o      = EXC_PC_DBD;
        csr_save_cause_o  = 1'b1;
        debug_csr_save_o  = 1'b1;
        if (debug_force_wakeup_q) 
            debug_cause_o = DBG_CAUSE_HALTREQ;
        else if (debug_single_step_i)
            debug_cause_o = DBG_CAUSE_STEP; // pri 0
        csr_save_if_o   = 1'b1;
        ctrl_fsm_ns     = DECODE;
        debug_mode_n    = 1'b1;
        debug_force_wakeup_n = 1'b0;
      end


      DBG_FLUSH:
      begin
        is_decoding_o = 1'b0;

        halt_if_o   = 1'b1;
        halt_id_o   = 1'b1;

        perf_pipeline_stall_o = data_load_event_i;

        if (data_err_i)
        begin //data error
            // the current LW or SW have been blocked by the PMP
            csr_save_ex_o     = 1'b1;
            csr_save_cause_o  = 1'b1;
            data_err_ack_o    = 1'b1;
            //no jump in this stage as we have to wait one cycle to go to Machine Mode
            csr_cause_o       = {
   1'b0, data_we_ex_i ? EXC_CAUSE_STORE_FAULT : EXC_CAUSE_LOAD_FAULT};
            ctrl_fsm_ns       = FLUSH_WB;
        end  //data error
        else begin
          if(debug_mode_q                          |
             trigger_match_i                       |
             (ebrk_force_debug_mode & ebrk_insn_i) |
             data_load_event_i                     |
             debug_req_entry_q                     )
            begin
              ctrl_fsm_ns = DBG_TAKEN_ID;
            end else
            begin
              /
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值