UVM——寄存器模型相關的一些函數

0. 引言

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

  寄存器模型中的寄存器值應該與DUT保持同步,但是由於DUT的值是實時更新的,所以寄存器模型並不能實時知道這種更新,在寄存器模型中專門有個值來儘可能與DUT中寄存器的值保持一致,叫鏡像值(mirrorred value)。寄存器模型中還有一個值叫期望值(respected value),這個值保存我們希望寫入寄存器的值。比如希望向DUT某個寄存器寫入'h1,用set函數設置期望值,然後用update任務(update會比較鏡像值和期望值,如果不一樣,將期望值寫入DUT,並更新鏡像值)。

 

1.  函數

1.1 set 

1

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

  設置模型中寄存器的期望值,不會改變DUT中這個寄存器的值。

1.2 get

1

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

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

1.3 get_mirrored_value

1

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

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

1.4 get_reset

1

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

  返回寄存器的復位值。

1.5 predict

1

2

3

4

5

6

7

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_DIRECT Predicted value is as-is
UVM_PREDICT_READ Predict based on the specified value having been read
UVM_PREDICT_WRITE Predict 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

1

2

3

4

5

6

7

8

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

1

2

3

4

5

6

7

8

9

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

1

2

3

4

5

6

7

8

9

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_FRONTDOOR Use the front door
UVM_BACKDOOR Use the back door
UVM_PREDICT Operation derived from observations by a bus monitor via the uvm_reg_predictor class.
UVM_DEFAULT_PATH Operation specified by the context

2.4 read

1

2

3

4

5

6

7

8

9

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

1

2

3

4

5

6

7

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的行爲,即使寄存器的讀寫類型是不能讀,也可以將值讀出來

 

2.6 poke

1

2

3

4

5

6

7

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的行爲,即使寄存器的讀寫類型是不能寫,也可以將值寫進去

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章