2026年FPGA大赛用国产高云GW5A做RISC-V软核,中断控制器PLIC接到ICB总线上总是丢中断,是优先级编码写错还是握手时序有问题?

开放4 回答 60 浏览

我们队今年电赛选了国产高云GW5A平台,用RISC-V软核做实时控制系统。PLIC中断控制器接ICB总线后,外部按键中断偶尔丢失,示波器抓波形发现claim/complete握手时序和spec对不上。试过加两级同步寄存器、改优先级阈值都没根治。有没有做过国产FPGA中断控制器的同学,这种丢中断一般是优先级编码逻辑写错,还是ICB转AXI桥接的握手时序没对齐?求定位思路。

分享:

4 个回答

  • FPGA新手

    我去年带过一支用高云GW2A做RISC-V软核的队伍,丢中断这个坑我们踩了差不多三周,最后发现根因跟优先级编码一点关系都没有。先说一个判断原则:优先级编码写错,现象通常是「低优先级永远抢不到」或者「高优先级被低优先级压住」,属于可复现的分配问题;而你们描述的是「偶尔丢」,且示波器上claim/complete和spec对不上,那基本可以锁定在握手时序,而不是编码逻辑。

    顺着这个往下推,PLIC的claim/complete本身是纯寄存器读写,只要软核访问总线的时序对了,它不会自己丢。真正容易出问题的是中间那层ICB到AXI的桥。中断响应窗口很窄:外部按键触发gateway,gateway把pending置起来,软核要在几个周期内读到claim并回complete。如果桥接的valid/ready反压没覆盖这个窗口,比如ICB侧已经拉高valid,AXI侧ready因为写通道拥塞晚了几拍才来,中间那笔claim读就可能被吞掉——pending还在,但软核没收到,看起来就是「丢了」。

    排查顺序我建议这样走:先用ILA把中断pending、gateway输出、ICB侧valid/ready、AXI侧valid/ready、软核claim读地址这几路一起抓,重点是看丢的那一次,pending到claim之间到底断在哪一级。如果pending置起了但claim读没发出,问题在软核侧或桥的请求通道;如果claim读发出了但complete没回,问题在响应通道或者软核中断服务程序里被别的分支跳过了。

    另外优先级阈值寄存器被软核重复写覆盖这个点别忽略。很多软核的启动代码、RTOS初始化、以及中断服务里都会写阈值,如果两处写的值不一致,后写的会把前面覆盖掉,导致某些优先级的中断被静默屏蔽。这个用ILA抓寄存器写使能和写数据就能确认,比改编码逻辑省事得多。

    最后说个取舍:加两级同步寄存器解决的是跨时钟域亚稳态,对握手反压没帮助,你们如果PLIC和软核同频,加同步器反而可能引入额外延迟,让响应窗口更紧。先把时钟域关系确认清楚,再决定要不要保留。你们PLIC和软核是同一个时钟域吗?这个直接决定后面往哪个方向查。

  • 电子爱好者

    先别怀疑优先级编码,八成是ICB到AXI桥的valid/ready反压没盖住claim响应窗口。用ILA抓pending到claim全链路,看丢的那次断在哪级,比盲改阈值快得多。

  • FPGA小学生

    从工程定位的角度讲,这类「偶尔丢」的问题最忌讳一上来就改逻辑。我的主思路是:先建立一条可观测链路,再谈修改。

    具体做法是用ILA同时抓四组信号:gateway的pending、PLIC的claim读使能、ICB侧valid/ready、AXI侧valid/ready。触发条件设在pending上升沿,抓满一次完整的中断响应过程。然后人工比对丢中断那一次和正常那一次的波形差异——差异点就是嫌疑点。

    常见的差异有三种:一是claim读使能根本没拉起来,说明软核没进中断或者被更高优先级屏蔽;二是使能拉起了但ready迟迟不来,说明桥的反压没对齐;三是complete写了但pending没清,说明complete地址或时序错了。这三种对应完全不同的修法,不抓波形根本分不清。

    至于优先级编码,它影响的是仲裁结果,不会造成「偶尔」丢,除非你的编码逻辑里有组合环或者竞争,那种情况一般会稳定复现。所以先把观测做起来,别急着动编码。你们现在ILA的采样深度够抓一次完整中断响应吗?

  • 电路板玩家2023

    先说结论方向:你们描述里最关键的一条信息是「示波器抓波形发现 claim/complete 握手时序和 spec 对不上」。这句话其实已经把优先级编码基本排除了。优先级编码写错,表现出来的是仲裁结果不对——高优先级抢不到、低优先级被压死,属于每次触发都能复现的分配问题;而 claim/complete 时序对不上是协议层的错,是握手本身没走完,跟谁优先没关系。所以别在阈值和编码上继续耗,把精力放到桥接和响应窗口上。

    往深一层想,PLIC 的 claim/complete 本质就是两次带地址的寄存器读写,它自己不会「偶尔丢」。真正会偶尔丢的,是它和软核之间那条路径。GW5A 上 PLIC 挂在 ICB 上,如果中间还有 ICB 转 AXI 的桥,那中断响应窗口就变得很窄:gateway 把 pending 拉起来,软核要在有限周期内完成 claim 读、处理、再 complete 写。桥接的 valid/ready 反压如果没覆盖住整个窗口,pending 就可能被下一次边沿覆盖掉,或者 claim 读被吞掉一拍。

    排查顺序我建议这样走。第一步先确认 claim/complete 是不是严格按 RISC-V PLIC spec 的时序:claim 读是不是单次读、complete 写是不是写回同一个 ID、地址有没有对齐。第二步也是最容易被忽略的,查优先级阈值寄存器——很多软核代码会在初始化里反复写 threshold,如果这个写操作和中断响应撞在一起,threshold 被临时改掉,低优先级中断就会被静默丢弃。这种「软核自己覆盖自己」的丢法,现象就是偶尔丢、还挑时间点。第三步才去查 ICB 到 AXI 桥的 valid/ready 反压,重点看 claim 读使能拉起来之后 ready 有没有及时回,以及 complete 写下去之后 pending 有没有被清干净。

    验证手段就一个:ILA 抓 pending 上升沿做触发,一次性抓满从 pending 到 claim 到 complete 的完整过程,把丢的那次和正常那次并排比对。差异点出现在哪一级,根因就在哪一级。加两级同步寄存器只解决亚稳态,解决不了反压没对齐的问题,所以你加了没用是正常的。

    最后问一句,你们 PLIC 是用的开源 IP 还是自己写的?这两条路的排查重点不太一样。

登录后可在本页底部提交回答

提问者

FPGA学习笔记查看主页
浏览「其他」

描述场景与已尝试方案,更容易获得有效解答

相关问题

同分类

提问建议

  • 标题写清核心疑问,避免「求助」「请问」等空泛用语
  • 正文补充环境、版本、报错信息或截图
  • 先搜索本站是否已有相近问题,减少重复提问
  • 若与课程相关,请标明课时或章节便于讲师定位