优先级排序与中断响应机制
RISC-V定义了三种中断源,每个特权级各有一组:
| 中断 | mip位 | mie位 | cause | 来源 |
|---|---|---|---|---|
| Machine Software Int | MSIP(3) | MSIE(3) | 2147483651 | 软件中断(核间通信) |
| Machine Timer Int | MTIP(7) | MTIE(7) | 2147483655 | CLINT定时器 |
| Machine External Int | MEIP(11) | MEIE(11) | 2147483659 | PLIC外部设备 |
| Supervisor Software Int | SSIP(1) | SSIE(1) | 2147483649 | S-mode软件中断 |
| Supervisor Timer Int | STIP(5) | STIE(5) | 2147483653 | S-mode定时器 |
| Supervisor External Int | SEIP(9) | SEIE(9) | 2147483657 | S-mode外部中断 |
// Lesson 06: Interrupt Handling — Priority-based selection
module interrupt_handler(
input wire clk, rst_n,
input wire [11:0] mie_val, mip_val,
input wire mstatus_mie,
input wire [1:0] current_priv,
output reg [31:0] int_cause,
output reg int_taken,
output reg [3:0] int_id
);
localparam PRV_M = 2'b10;
wire mie_mei = mie_val[11] & mip_val[11];
wire mie_msi = mie_val[3] & mip_val[3];
wire mie_mti = mie_val[7] & mip_val[7];
wire mie_sei = mie_val[9] & mip_val[9];
wire mie_ssi = mie_val[1] & mip_val[1];
wire mie_sti = mie_val[5] & mip_val[5];
reg int_pending; reg [31:0] sel_cause; reg [3:0] sel_id;
always @(*) begin
int_pending = 0; sel_cause = 0; sel_id = 0;
if (mstatus_mie || current_priv < PRV_M) begin
if (mie_mei) begin int_pending=1; sel_cause=32'h8000000B; sel_id=6; end
else if (mie_msi) begin int_pending=1; sel_cause=32'h80000003; sel_id=3; end
else if (mie_mti) begin int_pending=1; sel_cause=32'h80000007; sel_id=7; end
else if (mie_sei) begin int_pending=1; sel_cause=32'h80000009; sel_id=9; end
else if (mie_ssi) begin int_pending=1; sel_cause=32'h80000001; sel_id=1; end
else if (mie_sti) begin int_pending=1; sel_cause=32'h80000005; sel_id=5; end
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin int_cause <= 0; int_taken <= 0; int_id <= 0; end
else begin
int_taken <= int_pending;
if (int_pending) begin int_cause <= sel_cause; int_id <= sel_id; end
end
end
endmodule
实时操作系统(RTOS)对中断延迟有严格要求:
| 指标 | 定义 | 典型值(RISC-V) |
|---|---|---|
| 中断延迟 | 从IRQ到第一条handler指令 | 20-50 cycles |
| 中断抖动 | 延迟的变化范围 | 5-20 cycles |
| 上下文切换 | 保存/恢复所有寄存器 | 50-100 cycles |
| 中断嵌套深度 | 最大可嵌套层数 | 通常4-8层 |
中断嵌套允许高优先级中断抢占低优先级中断的处理。在Linux中,中断处理分为上半部(top half,不可抢占)和下半部(bottom half,可抢占),以平衡实时性和吞吐量。
| 资料 | 内容 | 链接 |
|---|---|---|
| RISC-V特权规范 | CSR、Trap、中断完整定义 | riscv.org/specifications |
| RISC-V手册 | 中文版免费教材 | crva.ict.ac.cn |
| OpenSBI源码 | M-mode固件参考实现 | github.com/riscv/opensbi |
| Linux RISC-V | 内核移植与驱动 | kernel.org |
| BOOM处理器 | UC Berkeley开源OoO核心 | github.com/riscv-boom/riscv-boom |
| 香山处理器 | 中科院开源高性能核心 | github.com/OpenXiangShan |
| 课程范围 | 课程号 | 主题 |
|---|---|---|
| 特权架构 | 01-06 | 特权级→CSR→ecall→mret→trap→中断 |
| 内存系统 | 07-12 | PLIC→CLINT→SV39→TLB→直接映射→组相联 |
| 算术单元 | 13-14 | Booth乘法器→恢复余数除法 |
| 乱序执行 | 15-19 | OoO→ROB→寄存器重命名→记分牌→Tomasulo |
| 分支预测 | 20-21 | 2位预测器→BTB |
| RISC-V扩展 | 22-26 | RVC→RVM→RVA→RVF→RVD |
| 系统集成 | 27-30 | PMP→解码器→SoC→启动流程 |
建议使用以下环境进行实验:
| 代际 | 控制器 | 特点 | 代表 |
|---|---|---|---|
| 第一代 | 简单优先级 | 固定优先级,无嵌套 | RISC-V CLINT |
| 第二代 | 优先级+路由 | 可配置优先级,多目标路由 | RISC-V PLIC |
| 第三代 | 高级PLIC(APLIC) | 支持MSI,更大中断源数 | RISC-V APLIC |
| 第四代 | IMSIC | 每Hart独立中断文件,MSI | RISC-V IMSIC |
RISC-V最新的中断架构使用IMSC(Incoming Message-Signaled Interrupt Controller),支持MSI(Message-Signaled Interrupts)——设备直接写内存触发中断,无需专用的IRQ线。这与PCIe的MSI-X机制对应。
在多核系统中,中断亲和性决定哪个核心处理哪个中断:
中断控制器的设计涉及多个权衡: