UVM的寄存器模型,对一个寄存器bit中有两种数值,mirror值,尽可能的反映DUT中寄存器的值。expected值,尽可能的反映用户期望的值。
几种常用的操作:
read/write:可以前门访问也可以后门访问,如果在env的顶层定义过uvm_auto_predict(1),则UVM会在这两个操作后自动调用do_predict函数
来更新寄存器模型中的mirror值。
peek/poke:只用于后门访问,而且完全不管硬件的行为,如向只读寄存器写数据,仍可以写入。应用很少。
get/set:得到或设置寄存器模型的期望值。
update操作:可以使用前门访问,也可以使用后门访问,检查期望值与镜像值是否一致,如不一致,则向DUT写入期望值。
通过枚举结构uvm_path_e来定义。
mirror操作:用于读取DUT中寄存器的值并将它们更新到寄存器模型中。可以前门访问也可以后门访问。两种的应用场景:1)check选项关闭,
仿真中不断调用。2)check选项打开,用在结束时,检查DUT与寄存器模型的值是否相同。
predict操作:人为的根据DUT来更新寄存器模型中的镜像值。但同时又不对DUT进行任何操作。此时的uvm_path_e是UVM_PREDICT_DIRECT。
可以通过加monitor在寄存器总线上。检测到uvm_reg_item操作,便通过TLM传送到uvm_reg_predict模块来更新mirror值。
函数内部主要有do_predict操作,这是主要的实现函数。还有一个post_predict的回调函数,可以自己扩展根据mirror值更新
期望值。但是pre_predict并不是一个回调函数,仅仅只是一个虚函数原型。可以在do_predict操作之前调用,完成覆盖率采样。
由于前门访问会消耗仿真时间,而后门访问不会消耗仿真时间,所以在build_phase,connect_phase,config_phase只能使用后门访问,所以
uvm_path_e中默认定义有一个UVM_DEFAULT_PATH,这样就可以在这些phase隐式的指明后门访问。而在task phase中在
显式的指明前门访问。(这时DUT已经开始工作,使用前门访问比较接近硬件)
一般在config中使用寄存器模型,先set/randomized再update。后门访问。