异常和中断

1. 异常:硬件、系统和应用的组合拳

异常是一个硬件和软件组合到一起的 处理过程。异常的前半生,也就是异常的发生和捕捉,是在硬件层面完成的。但异常的后半生,其实是由软件来完成的。

计算机会为每一种可能发生的异常分配一个异常代码(Exception Number)。也称为中断向量(Interrupt Vector)。异常发生的时候,CPU 检测到一个特殊的信号。这些信号一般叫做发生了一个事件(Event)。CPU 在检测到事件的时候,其实也就拿到了对应的异常代码。

这些异常代码里,I / O 发出的信号的异常代码,是由操作系统来分配的,也就是由软件来设定的。而像加法溢出这样的异常代码,则是由 CPU 预先分配好的,也就是有硬件来分配的。

拿到异常代码以后,CPU 就会触发异常处理的流程。计算机在内存里会保留一个异常表(Exception Table)。也称为中断向量表(Interrupt Vector Table)。这个异常表里面存放的是不同的异常代码对应的异常处理程序(Exception Handler)所在的地址。

CPU 在拿到了异常码之后,会把当前的程序执行的现场,保存到程序栈里面,然后会根据异常码查询,找到对应的异常处理程序,最后把后续指令执行的指挥权,交给这个异常处理程序。

在这里插入图片描述

2. 异常的分类

异常可分为 中断、陷阱、故障 和 中止

  1. 中断(Interrupt)。程序在执行到了一半的时候,被打断了。这个打断执行的信号,来自于 CPU 的外部 I / O 设备。
  2. 陷阱(Trap)。程序员“故意”主动触发的异常。比如应用程序调用系统调用。
  3. 故障(Fault)。陷阱是我们开发程序的时候刻意触发的异常,而故障不是。比如进行加法计算的时候发生了溢出,就是故障类型的异常。
  4. 中止(Abort)。当 CPU 遇到了故障,但是恢复不过来的时候,程序就不得不中止了。

在这里插入图片描述

3. 异常处理

异常处理流程:保存现场、异常代码查询、异常处理程序调用。

而中止类型的异常,其实是在故障类型异常的一种特殊情况。当故障发生,但是我们发现没有异常处理程序能够处理这种异常的情况下,程序就不得不进入中止状态,也就是最终会退出当前的程序执行。

  1. 异常情况往往发生在程序正常执行的预期之外,比如中断、故障发生的时候。除了本来程序压栈要做的事情之外,我们还需要把 CPU 内当前运行程序用到的所有寄存器,都放到栈里面。最典型的就是条件码寄存器里面的内容。
  2. 像陷阱这样的异常,涉及程序指令在用户态和内核态之间的切换。对应压栈的时候,对应的数据是压到内核栈里,而不是程序栈里。
  3. 像故障这样的异常,在异常处理程序执行完成之后。从栈里返回出来,继续执行的不是顺序的下一条指令,而是故障发生的当前指令。因为当前指令因为故障没有正常执行成功,必须重新去执行一次。

此文章为2月Day2学习笔记,内容来源于极客时间《深入浅出计算机组成原理》

### 单周期CPU设计中异常中断处理的实现方案 单周期CPU设计中,异常中断处理是确保系统健壮性可靠性的重要机制。在支持异常中断的单周期CPU设计中,关键在于如何正确地捕获、响应恢复这些事件[^2]。以下是关于单周期CPU设计中异常中断处理的具体实现方法: #### 1. 异常处理机制的设计 异常处理通常需要以下几个步骤: - **异常检测**:通过硬件逻辑检测到特定条件(如算术溢出或非法指令),触发异常。 - **保存上下文**:将当前程序计数器(PC)值存储到`epc`寄存器中,以便后续返回时能够继续执行。 - **更新状态寄存器**:设置`status`寄存器中的相应位,标识当前处于异常处理模式。 - **跳转到异常处理程序**:通过修改PC值,使CPU跳转到预定义的异常处理程序地址。 例如,在MIPS架构中,可以通过以下方式实现异常检测跳转: ```verilog always @(posedge clk or negedge reset_n) begin if (!reset_n) begin pc <= 0; end else if (exception_detected) begin epc <= pc; // 保存当前PC到epc status <= status | EXCEPTION_MODE; // 更新状态寄存器 pc <= EXCEPTION_HANDLER_ADDRESS; // 跳转到异常处理程序 end else begin pc <= next_pc; end end ``` #### 2. 中断处理机制的设计 中断处理与异常类似,但通常由外部事件触发。在单周期CPU中,中断处理的关键点包括: - **中断优先级管理**:通过`status`寄存器中的位字段,控制哪些中断可以被响应。 - **中断屏蔽**:在进入中断处理程序之前,禁用其他中断以避免嵌套。 - **恢复现场**:在中断处理完成后,恢复原来的PC值状态。 以下是一个简单的中断处理逻辑示例: ```verilog always @(posedge clk or negedge reset_n) begin if (!reset_n) begin pc <= 0; end else if (interrupt_request && !status.interrupt_mask) begin epc <= pc; // 保存当前PC到epc cause <= INTERRUPT_CAUSE_CODE; // 设置中断原因 status <= status | INTERRUPT_MODE; // 更新状态寄存器 pc <= INTERRUPT_HANDLER_ADDRESS; // 跳转到中断处理程序 end else begin pc <= next_pc; end end ``` #### 3. 特殊寄存器的支持 为了支持异常中断处理,单周期CPU需要引入一些特殊寄存器: - `cause`:记录异常中断的原因。 - `epc`:保存发生异常中断时的PC值,用于后续恢复。 - `status`:管理CPU的状态,包括是否处于异常中断模式,以及中断屏蔽标志。 这些寄存器可以通过专用的指令(如`mtc0``mfc0`)进行访问修改[^2]。 #### 4. 指令集扩展 为了支持异常中断处理,需要扩展CPU的指令集,加入专门的指令: - `mtc0`:将普通寄存器的内容写入控制寄存器。 - `mfc0`:从控制寄存器读取内容到普通寄存器。 - `eret`:用于从异常中断处理程序返回。 #### 5. 延迟槽的处理 在单周期CPU设计中,由于没有流水线结构,延迟槽的影响相对较小。然而,对于某些分支或跳转指令,仍然需要考虑延迟槽的存在[^3]。可以通过在硬件中直接忽略延迟槽中的指令来简化设计。 --- ### 示例代码片段 以下是一个简单的Verilog代码片段,展示如何在单周期CPU中实现基本的异常中断处理逻辑: ```verilog // 异常中断处理模块 module exception_handler ( input wire clk, input wire reset_n, input wire exception_detected, input wire interrupt_request, output reg [31:0] pc, output reg [31:0] epc, output reg [31:0] cause, output reg [31:0] status ); parameter EXCEPTION_HANDLER_ADDRESS = 32'h80000000; parameter INTERRUPT_HANDLER_ADDRESS = 32'h80000080; always @(posedge clk or negedge reset_n) begin if (!reset_n) begin pc <= 0; epc <= 0; cause <= 0; status <= 0; end else if (exception_detected) begin epc <= pc; cause <= EXCEPTION_CAUSE_CODE; status <= status | EXCEPTION_MODE; pc <= EXCEPTION_HANDLER_ADDRESS; end else if (interrupt_request && !status.interrupt_mask) begin epc <= pc; cause <= INTERRUPT_CAUSE_CODE; status <= status | INTERRUPT_MODE; pc <= INTERRUPT_HANDLER_ADDRESS; end else begin pc <= next_pc; end end endmodule ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Balaaam

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值