提到寄存器,不知道大家首先脑海中闪现的词语是什么?
是大学时期学过的《微机原理》课程中的汇编语言编程提到的8086CPU14个寄存器:即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES ?通过汇编指令操作这些寄存器,便可以写出基本的汇编语言程序,实现预期的功能。
是研究生时期做的51单片机、STM32单片机、DSP处理器芯片中提到的各种各样的配置寄存器?我们根据单片机手册,按找要求配置相应的寄存器,便可以启动相应的功能模块。
是第一次动手使用FPGA 编程,写下 reg clk,rst 代码,然后被Qurtus 综合器综合成触发器?我们想到组合逻辑电路,时序电路。
亦或者是,电脑内存,SSDRAM , 机械硬盘,固态硬盘?
其实,一路走来,我们多多少少不同阶段,都会和寄存器打交道。如今,我们涉足于IC领域,IC 领域的寄存器,自然有IC 领域的一套规则和方法。
当今IC 设计发展,可谓是越来越复杂,大规模的集成电路设计在强大的EDA 软件的支撑下,可以说是越来越成为一种时尚。记得很久之前看过一篇文章,在真正完成RTL 代码的综合之后,有统计过组合电路和时序电路的占比统计。其实,越来越多的寄存器设计,被应用。大概有以下理由:
(1)反馈控制
因为不能使用组合逻辑做loop,所以当设计中有反馈的时候,不可避免的要使用reg,将reg的输出loop回去。
(2)采样存储以备后用
举例:BUS A上面载有模块配置信息,一直在变,有一个使能信号B(脉冲)指示A数据是否有效。为了采集有效的配置信息,有必要在B脉冲到来时刻将A进行采样存起来,以备模块后续使用。
(3)wire难以构造的逻辑
举例:信号A上升沿,计算开始。信号B上升沿,计算结束。如果要用一根信号c表示正在计算,最好的办法就是:
assign c_nxt = A ? 1'b1 : B? 1'b0 : c_reg;
c_reg <= c_nxt;
该逻辑使用wire难以构造,使用reg则很简单。
(4)均衡延时
举例:z=a + b*c,a,b,c是同时输入的,要计算z。如果乘法器需要 3个周期才能做完,那么就必须将a延时3T,这样才能与b*c相加。
(5)timing不满足
我们在进行时序分析的时候,STA工具报出timing violation,建立时间不满足,必须插入寄存器将组合逻辑切断。
(6)设计后手
在实际数字电路设计中,Design 会适度加入一些 寄存器设计。其主要目的就是为可能的设计bug 留后手。这也合情理,在真正tape-out 之后,进行硅后测试会发现有很多片子,会出现莫名其妙的问题。那么,我们可以适度的通过配置寄存器,disable 某些功能,然后降价出售。
从这五个应用也可以看出,寄存器并非只为存储而生。
那么,从验证的角度来看,应用寄存器模型,有什么好处呢?
- 复用性更好,将总线访问寄存器抽象成寄存器模型访问的方式,使得后期地址修改(比如基地址更改,因为偏移地址都是固定的)或者域的添加都不会对已有的激励构成影响,从而提高复用性。
- 使得配置寄存器序列(reg的sequence)时更加可读(主要是从地址映射成了一个reg名字)。(如果你通过一个总线形式去访问硬件寄存器,那么是按地址来进行访问的,可读性较差(你可以选择用一些verilog定义的全局变量起到像枚举类型的作用),用寄存器模型能直接看出对哪个寄存器、对寄存器中哪个域在做操作(比如在随机化一个32位但是有多个域的reg,直接分段随机化的可读性在不了解设计的情况下很差,而随机化reg_field则很容易读懂))
- register model不仅可以发送激励(所以rgm也是个uvm_object),还可以用来做测试(有内建的序列可以测试register model),比如检查每个field如复位值和硬件是否一直
- 新增寄存器覆盖率的检查(可以在reg内部或者外部利用继承于uvm_subscriber自定义一个covergroup)。
- 用来检查硬件寄存器,以及配合scoreboadr来实时检查DUT功能。(refmodel被集成到scoreboard里,而在模拟的时候可以通过regmodel对设计的配置来模拟打包)
- 更方便对寄存器进行操作,前门访问和后门访问。在用前门访问验证了寄存器访问的物理通路工作正常的情况下,可以在后续测试中用后门访问节省时间。
- 有mirror value 和desired value 去跟踪寄存器的值,还能起到一个相当于影子存储的作用。