0. Introduction
In the register operation supported by UVM, there are some methods such as get, update, mirror, write, etc. here, we will sort out their usage.
The register value in the register model should be synchronized with the DUT, but because the DUT value is updated in real time, the register model cannot know this update in real time. There is a value in the register model to keep consistent with the value of the register in the DUT as much as possible, which is called mirrored value. Another value in the register model is called the expected value, which stores the value we want to write to the register. For example, if you want to write 'h1 to a register of the DUT, use the set function to set the expected value, and then use the update task (update will compare the image value with the expected value. If it is different, write the expected value to the DUT and update the image value).
1. Function
1.1 set
virtual function void set ( uvm_reg_data_t value, string fname = "",int lineno = 0 )
Setting the expected value of the register in the model will not change the value of this register in the DUT.
1.2 get
virtual function uvm_reg_data_t get( string fname = "", int lineno = 0 )
Returns the expected value of the register in the model, not the register value in the DUT.
1.3 get_mirrored_value
virtual function uvm_reg_data_t get_mirrored_value( string fname = "", int lineno = 0 )
Returns the mirror value of the register in the model.
1.4 get_reset
virtual function uvm_reg_data_t get_reset( string kind = "HARD" )
Returns the reset value of the register.
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 )
Updates the mirror value in the model. The new image value is passed in through the value parameter.
When a counter is implemented in the DUT, the counter in the model is static. If you want to get the technical value of DUT in the model, you need to manually update the image value, and you can't operate the DUT. You can use the predict function.
The third parameter is uvm_predict_e enumeration type, which has the following three elements:
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 |
If you want to update the image value without operating the DUT, use UVM_PREDICT_DIRECT.
write, read, peek and poke will also call this function to update the image value after reading and writing the DUT.
1.6 randomize
Whether it's uvm_reg, or uvm_field,uvm_block supports randomize ().
assert(rm.invert.reg_data.randomize());assert(rm.invert.randomize());assert(rm.randomize()):
When the register is randomised, the expected value will be random, but the mirror value remains unchanged. After that, the update task can be invoked to update the register value in DUT.
However, if a field can be randomized, it needs to:
1. Set the eighth parameter of configure in filed to 1
2. filed is of type rand.
3. The read-write type of filed is writable.
2. Tasks
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 )
Update the expectations in the model to the DUT. Changes in the DUT register. Update checks the expected value and the mirror value in the model. If they are not equal, update the expected value to the DUT and update the mirror value. Update is the opposite of the mirror operation.
If the image value is the same as the expected value, the DUT register will not be written and the bus transaction will not be generated.
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 )
Reading the value of the register in the DUT is the opposite of the update operation. If the second parameter check is UVM_CHECK, then it will check whether the read value is the same as the image value. If not, an error will be reported. After reading the register value of DUT through mirror, the predict function will be called to update the image value.
mirror has two application scenarios: one is that it is constantly called in the simulation, but at this time, it is UVM_NO_CHECK to ensure that the image value is equal to the value in the DUT; Second, it is called at the end of the simulation, which is UVM_CHECK whether the image value in the model is consistent with the register value in the 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 )
Imitating the behavior of the DUT, writing the register value to the DUT through the front door or back door will generate a bus transaction. And call predict to update the image value.
uvm_path_e define the register operation type as follows:
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 |
I'm using it. If I use set_auto_predict(1) -- automatically update the mirroring value, and then call get and get_ after write. mirrored_ Value can get the newly written value.
If you close auto_predict with uvm_reg_predict to update the mirror value. I call get and get_ after I use write. mirrored_ Value gets 0.
If it's a read task, whether it's auto_predict or uvm_reg_predict will automatically update the image value and expected value.
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 )
Imitating the behavior of the DUT, reading the value of the register in the DUT through the front door or back door and updating the image value will generate a bus 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 )
Read the value of the register through the back door access mode, regardless of the behavior of the DUT. Even if the read-write type of the register cannot be read, the value can be read out.
For a field of type read clear, peek read operation will not clear. So sometimes the results of PEEK and read operations are different
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 )
Write the value of the register through the back door access mode, regardless of the behavior of the DUT. Even if the read-write type of the register cannot be written, the value can be written in.
For file D of write clear type, the poke operation will not clear, so sometimes the results of poke and write operations are different.
WeChat official account
A WeChat official account official's "ICer road of Andy" has been established. The official account mainly shares the learning experience of digital IC. The article is mainly issued on the official account. csdn will try to update it as soon as possible, and interested friends can pay attention to it.