实现8源中断控制器,支持优先级编码、掩码使能和优先级阈值。
中断控制器架构:
IRQ0 ──→ ┌──────────────────────────┐
IRQ7 ──→ │ 边沿检测 → Pending寄存器 │
│ 掩码(MASK) → 使能过滤 │
│ 优先级编码器 → IRQ_ID │
│ 阈值比较 → IRQ_OUT │
│ ACK → 清除Pending │
└──────────────────────────┘
│ │
irq_out irq_id[2:0]// Interrupt Controller — 中断控制器, 8 sources
module interrupt_controller #(parameter NUM_IRQ=8)(
input wire clk, rst,
input wire [NUM_IRQ-1:0] irq_src,
input wire [NUM_IRQ-1:0] irq_mask,
input wire [2:0] irq_ack, input wire ack_valid,
output wire [2:0] irq_id, output wire irq_out,
input wire [2:0] priority_threshold
);
reg [NUM_IRQ-1:0] irq_pending, irq_prev;
always @(posedge clk or posedge rst) begin
if (rst) begin irq_pending<=0;irq_prev<=0; end
else begin
irq_prev<=irq_src;
irq_pending<=irq_pending | (irq_src & ~irq_prev);
if (ack_valid) irq_pending[irq_ack]<=0;
end
end
wire [NUM_IRQ-1:0] masked_pending = irq_pending & irq_mask;
reg [2:0] pri_id; reg pri_valid;
always @(*) begin
pri_id=0;pri_valid=0;
if (masked_pending[0]) begin pri_id=0;pri_valid=1; end
else if (masked_pending[1]) begin pri_id=1;pri_valid=1; end
else if (masked_pending[2]) begin pri_id=2;pri_valid=1; end
else if (masked_pending[3]) begin pri_id=3;pri_valid=1; end
else if (masked_pending[4]) begin pri_id=4;pri_valid=1; end
else if (masked_pending[5]) begin pri_id=5;pri_valid=1; end
else if (masked_pending[6]) begin pri_id=6;pri_valid=1; end
else if (masked_pending[7]) begin pri_id=7;pri_valid=1; end
end
assign irq_out=pri_valid && (pri_id<=priority_threshold);
assign irq_id=pri_id;
endmodule
测试:IRQ[2]和IRQ[5]同时触发,验证irq_id=2(优先级更高)。掩码IRQ[2]后验证irq_id=5。设置阈值=3,IRQ[5]不产生中断。ACK IRQ[5]后验证pending清除。
本实验所有Verilog代码已通过Verilator编译验证,功能行为正确。测试用例覆盖核心功能路径,确保设计满足规格要求。
ARM Cortex-M的NVIC支持240个中断、8级可编程优先级、中断嵌套和尾链。RISC-V的CLINT/PLIC支持中断路由和优先级。x86的APIC支持多核中断分发。
尝试修改代码中的关键参数,观察仿真结果变化:
💡 Verilator会在位宽不匹配时给出Warning,这是学习的好机会
在现有基础上增加新功能:
🔧 增量开发:每次只改一个地方,验证通过后再改下一个
| 语法 | 说明 | 示例 |
|---|---|---|
reg [7:0] | 8位寄存器 | reg [7:0] data; |
wire | 组合逻辑连线 | wire valid = cnt > 5; |
always @(posedge clk) | 时序逻辑 | 上升沿触发 |
always @(*) | 组合逻辑 | 敏感列表自动推导 |
localparam | 局部常量 | localparam DIV = 50000000; |
case | 多分支选择 | 注意default分支 |
$clog2 | 计算位宽 | $clog2(16)=4 |
本设计在典型FPGA上的资源占用估算:LUT约20-150个,FF约30-120个,无BRAM/DSP依赖(特殊模块除外)。时钟频率可达50-100MHz+。Verilator仿真速度约5-10M周期/秒。