一、简介
在芯片中,中断是一种机制,用于向处理器发出信号,通知其需要立即处理的事件或请求。中断可以是内部的,例如来自芯片内部某个功能模块的事件,也可以是外部的,例如来自外部设备的信号。当发生中断时,处理器会立即中断当前正在执行的程序,暂停其操作,并处理中断请求。
中断是一种对处理器执行流程的干预机制,它允许处理器在执行任务时响应外部事件,以及在必要时处理紧急情况。通过中断,处理器可以及时地处理重要事件,提高系统的实时性和响应能力。在芯片中,中断能够帮助处理器有效地管理各种不同的事件和任务,并保证系统的正常运行。
在处理器执行过程中,当发生一个中断请求时,处理器会将当前执行的指令位置以及相关寄存器的状态保存起来,然后跳转到中断服务程序去执行。中断服务程序会处理中断请求所对应的事件或任务,然后恢复处理器之前保存的状态,使其可以继续执行被中断的程序。
总的来说,中断是在芯片中一种重要的机制,用于处理各种事件和请求,保证系统的正常运行和任务的及时响应。
二、芯片中断系统中的一些标志位
在中断系统中,"RAW"(原始中断状态寄存器)、"STS"(中断状态寄存器)、"CLR"(中断清除寄存器)、"SET"(中断使能寄存器)和"MASK"(中断屏蔽寄存器)通常是与中断处理相关的一些寄存器或标志位。这些寄存器和标志位在处理器中断时起到不同的作用,帮助处理器管理中断请求、中断状态和中断处理流程。
-
RAW(原始中断状态寄存器):原始中断状态寄存器记录了尚未被处理的中断请求的状态。当某个中断事件发生时,相关的中断请求会被设置为"1",表示中断事件已经发生但还未被处理。RAW寄存器可以帮助处理器识别当前所有待处理的中断请求。
-
STS(中断状态寄存器):中断状态寄存器记录了当前系统中的中断状态,包括已触发但尚未处理的中断请求。中断服务程序可以根据STS寄存器的信息来处理特定的中断,处理完后通常会更新STS寄存器。
-
CLR(中断清除寄存器):中断清除寄存器用于清除特定的中断请求标志位,表示该中断请求已经被处理。当处理完一个中断后,处理器会向CLR寄存器写入相应的值,以清除相应的中断请求标志位。
-
SET(中断使能寄存器):中断使能寄存器用来控制特定的中断是否允许触发中断请求。通过设置SET寄存器,可以使得RAW和STS中断拉高。
-
MASK(中断屏蔽寄存器):中断屏蔽寄存器用于屏蔽(禁止)或取消屏蔽(允许)特定中断请求,使处理器可以灵活地控制哪些中断请求应该被忽略。处理器可以根据需要设置MASK寄存器,以控制中断请求的优先级和处理顺序
-
Global clr:在芯片设计中通常会存在一个global clr的寄存器配置,用来清除所有中断的raw和sts。
三、为什么需要EOT (End of Test)check:中断checker
在验证环境中,往往存在有EOT check,指的是在仿真结束时,进行一些检查,比如检查一些内部收发cnt寄存器是否一致;又或者是轮询一遍中断系统中所有的中断寄存器去检查中断是否是clean的。那么我们为什么要在EOT checker时去查询中断呢,个人理解有如下原因:
(1)通常情况下,我们需要保证所有正常功能验证点的case如果是PASS的状态,那么中断也理应是clean的,即所有的中断的raw值为0。因此中断检查也是衡量case是否PASS的标志。
(2)如果case 发生FAIL,如果没有EOT 中断checker时,那么我们通常情况下debug的逻辑是根据log中所report的error info入手去debug,其实就是看波形去查看输入输出是否符合预期,通常debug手段是从输出一级一级debug,如果在soc层级debug或者是top层级进行debug,pipeline往往是比较长的,那么往往会存在这样一种场景,即debug了很长时间,从输出debug到中间某个模块发现原来是这里出问题了,是因为发生了某个error,举例比如发生了overflow error。 那么如果存在中断的EOT检查,其实一开始在log中就已经report出哪些中断是非0值完成上报。其实可以瞬间完成error的定位,直接去debug为什么这里发生overflow即可,提高debug效率。
四、关于EOT checker: 中断checker的task coding实现(draft code)
以下code只是基于本人目前的项目经验总结的个人写法,如有不足,欢迎交流指正~~
在SOC环境中,通常intr_raw_check task定义在base_test中的shutdown_phase()。以下为intr_raw_check的大体实现。先拿到Intr系统中的regbank中的寄存器,然后对寄存器遍历,在寄存器中,对每个寄存器中的各个field进行遍历,即backdoor把所有的field读一遍,检查是否存在异常上报。那么关于检查值,分为以下三种情况。
(1)通常情况下,理应遍历所有的中断值为0,即只需要predict read每一个field为0即可。
(2)异常情况下,比如有些case可能是随机的异常case,比如随机注错的case,那么这时候,有可能会出现某个error上报中断,但也有可能没随机到而没有出现error而不会去上报中断,因此这个时候应当去关掉对应的中断checker。因此我这边的处理有定义一个close的queue,如果在子类case中有push某些中断到这个queue,就不会去检查这些中断。但是需要注意的是,应该只close对应的无法预测的中断,而不应该把所有的中断检查都关掉。曾经我们环境有因为全部关掉而miss过一个小bug,即因为该case会上报一个确定的预期的中断,但是却把所有中断检查都关闭。导致在该场景下,其实一直会误报一个中断错误,这个中断错误是DUT的bug,不应该上报,但是却由于该case关闭了所有的中断检查,导致一直没有检查到这个bug。
(3)异常情况下,比如有些case可能是构造异常的case,但是中断的上报是确定的,此刻其实中断检查也是case的一个检查项,比如这个case我本意就是构造fifo overflow的case,那么理应去predict该中断为1,如果真的发生了overflow,但是中断没上报,这就是非预期的情况了。因此此刻我们需要对相应的field去进行predict相应的理想值,若读出来并不是理想值,理应报错。我这边有定义2个队列,即一个field_name的队列,还有一个field_predict的队列。会进行查询历史是否有predict,如果有,就会使用predict value作为期待的golden值去进行检查。