UVM — 寄存器模型相关的一些函数

0. 引言

       在UVM支持的寄存器操作中,有get、update、mirror、write等等一些方法,在这里整理一下他们的用法。

  寄存器模型中的寄存器值应该与DUT保持同步,但是由于DUT的值是实时更新的,所以寄存器模型并不能实时知道这种更新,在寄存器模型中专门有个值来尽可能与DUT中寄存器的值保持一致,叫镜像值(mirrorred value)寄存器模型中还有一个值叫期望值(desired value),这个值保存我们希望写入寄存器的值。

1.  函数

1.1 set 

如希望向DUT某个寄存器写入'h1,用set函数设置期望值,然后用update任务(update会比较镜像值期望值,如果不一样,将期望值写入DUT,并更新镜像值。

virtual function void set ( uvm_reg_data_t value, string fname = "",int lineno = 0 )

  设置模型中寄存器的期望值,不会改变DUT中这个寄存器的值。

1.2 get

virtual function uvm_reg_data_t get( string fname  =  "", int lineno = 0 )

     返回模型中寄存器的期望值,而不是DUT中的寄存器值

1.3 get_mirrored_value 

virtual function uvm_reg_data_t get_mirrored_value( string fname = "", int lineno = 0 )

      返回模型中寄存器的镜像值。 

1.4 get_reset 

virtual function uvm_reg_data_t get_reset( string kind = "HARD" )

    返回寄存器的复位值

 1.5 predict

virtual function bit predict (  uvm_reg_data_t  value,      
  uvm_reg_byte_en_t be     =  -1,
  uvm_predict_e     kind   =  UVM_PREDICT_DIRECT,
  uvm_path_e        path   =  UVM_FRONTDOOR,
  uvm_reg_map       map    =  null,
  string            fname  =  "",
  int               lineno =  0   )

       更新模型中的镜像值。新的镜像值通过value参数传入。

  当在DUT中实现一个计数器的时候,模型中的计数器是静止的。如果想在模型中得到DUT的技术值,这就需要手动更新镜像值,又不能对DUT进行操作,这可以通过predict函数。

第三个参数是uvm_predict_e枚举类型,他有如下三个元素:

UVM_PREDICT_DIRECTPredicted value is as-is
UVM_PREDICT_READPredict based on the specified value having been read
UVM_PREDICT_WRITEPredict based on the specified value having been written

如果想要更新镜像值又不对DUT进行操作,要用UVM_PREDICT_DIRECT。

  write、read、peek和poke在完成对DUT的读写之后也会调用这个函数,更新镜像值。

1.6 randomize

  无论是uvm_reg,还是uvm_field、uvm_block,都是支持randomize()。

1

2

3

assert(rm.invert.reg_data.randomize());

assert(rm.invert.randomize());

assert(rm.randomize()):

  当寄存器随机化后,期望值会被随机,但是镜像值不变,之后调用update任务,可以更新DUT中的寄存器值。

  但是一个field能够被随机化,需要:

    1. 在filed的configure第八个参数设为1.

    2. filed为rand类型。

    3. filed的读写类型为可写的。

 2. 任务

2.1  update

virtual task update(    output  uvm_status_e    status,     
  input     uvm_path_e        path     =  UVM_DEFAULT_PATH,
  input     uvm_reg_map       map      =  null,
  input     uvm_sequence_base parent   =  null,
  input     int               prior    =  -1,
  input     uvm_object    extension    =  null,
  input     string            fname    =  "",
  input     int               lineno   =  0   )

 将模型中的期望值更新到DUT中。改变DUT中的寄存器。update会检查模型中的期望值和镜像值,如果两者不相等,那么将期望值更新到DUT中,并且更新镜像值。update与mirror操作相反。

  如果镜像值和期望值相同,那么不会写DUT寄存器,也就不会产生总线transaction。

 2.2 mirror

virtual task mirror(    output  uvm_status_e    status,     
  input     uvm_check_e        check    =  UVM_NO_CHECK,
  input     uvm_path_e         path     =  UVM_DEFAULT_PATH,
  input     uvm_reg_map        map      =  null,
  input     uvm_sequence_base  parent   =  null,
  input     int                prior    =  -1,
  input     uvm_object        extension =  null,
  input     string             fname    =  "",
  input     int                lineno   =  0   )

读DUT中寄存器的值,与update操作相反。如果第二个参数check为UVM_CHECK,那么会检查读取的值与镜像值是否一样,如果不一样报错。通过mirror读取DUT的寄存器值之后,会调用predict函数,更新镜像值。

  mirror有两种应用场景:一是在仿真中不断调用,但此时是UVM_NO_CHECK,保证镜像值与DUT中的值相等;二是在仿真结束的时候调用,这时是UVM_CHECK检查模型中的镜像值与DUT中的寄存器值是否一致。

2.3 write

virtual task write( output  uvm_status_e    status,     
  input     uvm_reg_data_t     value,      
  input     uvm_path_e         path     =  UVM_DEFAULT_PATH,
  input     uvm_reg_map        map  =  null,
  input     uvm_sequence_base  parent   =  null,
  input     int                prior    =  -1,
  input     uvm_object         extension    =  null,
  input     string             fname    =  "",
  input     int                lineno   =  0   )

 

模仿DUT的行为,通过前门或者后门方式向DUT中写入寄存器值,会产生总线transaction。并且调用predict更新镜像值。

  uvm_path_e定义寄存器操作类型,如下:

UVM_FRONTDOORUse the front door
UVM_BACKDOORUse the back door
UVM_PREDICTOperation derived from observations by a bus monitor via the uvm_reg_predictor class.
UVM_DEFAULT_PATHOperation specified by the context

  我在使用中,如果用set_auto_predict(1)——采取自动更行镜像值的方式,write之后,调用get和get_mirrored_value都能得到新写入的值。  

  如果关闭auto_predict,用uvm_reg_predict来更新镜像值,我在在使用中write之后,调用get和get_mirrored_value得到0

  如果是read任务,那么无论是auto_predict还是uvm_reg_predict都会自动更新镜像值和期望值。

  链接:https://github.com/east1203/uvm_codes/tree/master/tb1_wd/a.uvm_reg_predict

2.4 read

virtual task read(  output  uvm_status_e    status,     
  output    uvm_reg_data_t    value,      
  input     uvm_path_e        path     =  UVM_DEFAULT_PATH,
  input     uvm_reg_map       map      =  null,
  input     uvm_sequence_base parent   =  null,
  input     int               prior    =  -1,
  input     uvm_object    extension    =  null,
  input     string            fname    =  "",
  input     int               lineno   =  0   )

模仿DUT的行为,通过前门或者后门方式读取DUT中寄存器的值,并更新镜像值,会产生总线transaction

2.5 peek

virtual task poke(  output  uvm_status_e    status,     
  input     uvm_reg_data_t      value,      
  input     string              kind     =  "",
  input     uvm_sequence_base   parent   =  null,
  input     uvm_object      extension    =  null,
  input     string              fname    =  "",
  input     int                 lineno   =  0   )

 通过后门访问方式读取寄存器的值,不关心DUT的行为,即使寄存器的读写类型是不能读,也可以将值读出来

   对于read clear类型的field,peek读操作不会clear。所以有的时候peek和read操作结果不一样

2.6 poke

virtual task peek(  output  uvm_status_e    status,     
  output    uvm_reg_data_t      value,      
  input     string              kind     =  "",
  input     uvm_sequence_base   parent   =  null,
  input     uvm_object       extension   =  null,
  input     string              fname    =  "",
  input     int                 lineno   =  0   )

 通过后门访问方式写入寄存器的值,不关心DUT的行为,即使寄存器的读写类型是不能写,也可以将值写进去

   对于write clear类型的filed,poke操作不会clear,所以有的时候poke和write操作结果不一样

 3. 补充

3.1 get_root_map

3.2 get_root_blocks 

这是一个静态函数,获得最顶层的reg_block。以往在seq中调用寄存器模型都是通过p_sequencer中的reg_model句柄,有了get_root_blocks则可以在seq中直接获得,然后cast转化使用。

function void uvm_reg_block::get_root_blocks (ref uvm_reg_block blks[$]);
    foreach (m_roots[blk]) begin
        blks.push_back(blk);
    end
endfunction

 m_roots 是 uvm_reg_block中的一个静态的联合数组

virtual class uvm_reg_block extends uvm_object;

......

    local static bit m_roots[uvm_reg_block];


 

3.3 get_address

3.4 get_reg_by_offset

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值