*2-3-7-加入field_automation机制
在2.3.3節中引入my_mointor時,在my_transaction中加入了my_print函數;
在2.3.5節中引入reference model時,加入了my_copy函數;
在2.3.6節引入scoreboard時,加入了my_compare函數。
上述三個函數雖然各自不同,但是對于不同的transaction來說,都是類似的:它們都需要逐字段地對transaction進行某些操作。
那么有沒有某種簡單的方法,可以通過定義某些規則自動實現這三個函數呢?答案是肯定的。這就是UVM中的field_automation機制,使用uvm_field系列宏實現:
代碼清單 2-52
文件:src/ch2/section2.3/2.3.7/my_transaction.sv
? 4 class my_transaction extends uvm_sequence_item;
? 5
? 6?? rand bit[47:0] dmac;
? 7?? rand bit[47:0] smac;
? 8?? rand bit[15:0] ether_type;
? 9?? rand byte????? pload[];
?10?? rand bit[31:0] crc;
?…
?25?? `uvm_object_utils_begin(my_transaction)
?26???? `uvm_field_int(dmac, UVM_ALL_ON)
?27???? `uvm_field_int(smac, UVM_ALL_ON)
?28???? `uvm_field_int(ether_type, UVM_ALL_ON)
?29???? `uvm_field_array_int(pload, UVM_ALL_ON)
?30???? `uvm_field_int(crc, UVM_ALL_ON)
?31?? `uvm_object_utils_end
?…
?37 endclass
這里使用uvm_object_utils_begin和uvm_object_utils_end來實現my_transaction的factory注冊,在這兩個宏中間,使用uvm_field宏注冊所有字段。uvm_field系列宏隨著transaction成員變量的不同而不同,如上面的定義中出現了針對bit類型的uvm_field_int及針對byte類型動態數組的uvm_field_array_int。
3.3.1節列出了所有的uvm_field系列宏。
當使用上述宏注冊之后,可以直接調用copy、compare、print等函數,而無需自己定義。這極大地簡化了驗證平臺的搭建,提高了效率:
代碼清單 2-53
文件:src/ch2/section2.3/2.3.7/my_model.sv
?26 task my_model::main_phase(uvm_phase phase);
?27?? my_transaction tr;
?28?? my_transaction new_tr;
?29?? super.main_phase(phase);
?30?? while(1) begin
?31???? port.get(tr);
?32???? new_tr = new("new_tr");
?33???? new_tr.copy(tr);
?34???? `uvm_info("my_model", "get one transaction, copy and print it:", UVM_LOW)
?35???? new_tr.print();
?36???? ap.write(new_tr);
?37?? end
?38 endtask
代碼清單 2-54
文件:src/ch2/section2.3/2.3.7/my_scoreboard.sv
…
?34????? while (1) begin
?35??????? act_port.get(get_actual);
?36??????? if(expect_queue.size() > 0) begin
?37????????? tmp_tran = expect_queue.pop_front();
?38????????? result = get_actual.compare(tmp_tran);
?39????????? if(result) begin
?40??????????? `uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_LOW);
?41????????? end
…
引入field_automation機制的另外一大好處是簡化了driver和monitor。在2.3.1節及2.3.3節中,my_driver的drv_one_pkt任務和my_monitor的collect_one_pkt任務代碼很長,但是幾乎都是一些重復性的代碼。使用field_automation機制后,drv_one_pkt任務可以簡化為:
代碼清單 2-55
文件:src/ch2/section2.3/2.3.7/my_driver.sv
?38 task my_driver::drive_one_pkt(my_transaction tr);
?39?? byte unsigned data_q[];
?40?? int? data_size;
?41
?42?? data_size = tr.pack_bytes(data_q) / 8;
?43?? `uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
?44?? repeat(3) @(posedge vif.clk);
?45?? for ( int i = 0; i < data_size; i++ ) begin
?46????? @(posedge vif.clk);
?47????? vif.valid <= 1'b1;
?48????? vif.data <= data_q[i];
?49?? end
?50
?51?? @(posedge vif.clk);
?52?? vif.valid <= 1'b0;
?53?? `uvm_info("my_driver", "end drive one pkt", UVM_LOW);
?54 endtask
第42行調用pack_bytes將tr中所有的字段變成byte流放入data_q中,在2.3.1節中是手工地將所有字段放入data_q中的。
pack_bytes極大地減少了代碼量。在把所有的字段變成byte流放入data_q中時,字段按照uvm_field系列宏書寫的順序排列。在上述代碼中是先放入dmac,再依次放入smac、ether_type、pload、crc。假如my_transaction定義時各個字段的順序如下:
代碼清單 2-56
`uvm_object_utils_begin(my_transaction)
?? `uvm_field_int(smac, UVM_ALL_ON)
?? `uvm_field_int(dmac, UVM_ALL_ON)
?? `uvm_field_int(ether_type, UVM_ALL_ON)
?? `uvm_field_array_int(pload, UVM_ALL_ON)
?? `uvm_field_int(crc, UVM_ALL_ON)
`uvm_object_utils_end
那么將會先放入smac,再依次放入dmac、ether_type、pload、crc。
my_monitor的collect_one_pkt可以簡化成:
代碼清單 2-57
文件:src/ch2/section2.3/2.3.7/my_monitor.sv
?34 task my_monitor::collect_one_pkt(my_transaction tr);
?35?? byte unsigned data_q[$];
?36?? byte unsigned data_array[];
?37?? logic [7:0] data;
?38?? logic valid = 0;
?39?? int data_size;
?…
?46?? `uvm_info("my_monitor", "begin to collect one pkt", UVM_LOW);
?47?? while(vif.valid) begin
?48????? data_q.push_back(vif.data);
?49????? @(posedge vif.clk);
?50?? end
?51?? data_size? = data_q.size();
?52?? data_array = new[data_size];
?53?? for ( int i = 0; i < data_size; i++ ) begin
?54????? data_array[i] = data_q[i];
?55?? end
?56?? tr.pload = new[data_size - 18]; //da sa, e_type, crc
?57?? data_size = tr.unpack_bytes(data_array) / 8;
?58?? `uvm_info("my_monitor", "end collect one pkt", UVM_LOW);
?59 endtask
這里使用unpack_bytes函數將data_q中的byte流轉換成tr中的各個字段。unpack_bytes函數的輸入參數必須是一個動態數組,所以需要先把收集到的、放在data_q中的數據復制到一個動態數組中。由于tr中的pload是一個動態數組,所以需要在調用unpack_bytes之前指定其大小,這樣unpack_bytes函數才能正常工作。
轉載于:https://www.cnblogs.com/YINBin/p/6915664.html
總結
以上是生活随笔為你收集整理的*2-3-7-加入field_automation机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用python阐释工作量证明(proof
- 下一篇: 团队作业8——第二次项目冲刺(Beta阶