*2-3-7-加入field_automation机制
在2.3.3節(jié)中引入my_mointor時(shí),在my_transaction中加入了my_print函數(shù);
在2.3.5節(jié)中引入reference model時(shí),加入了my_copy函數(shù);
在2.3.6節(jié)引入scoreboard時(shí),加入了my_compare函數(shù)。
上述三個(gè)函數(shù)雖然各自不同,但是對(duì)于不同的transaction來(lái)說(shuō),都是類(lèi)似的:它們都需要逐字段地對(duì)transaction進(jìn)行某些操作。
那么有沒(méi)有某種簡(jiǎn)單的方法,可以通過(guò)定義某些規(guī)則自動(dòng)實(shí)現(xiàn)這三個(gè)函數(shù)呢?答案是肯定的。這就是UVM中的field_automation機(jī)制,使用uvm_field系列宏實(shí)現(xiàn):
代碼清單 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來(lái)實(shí)現(xiàn)my_transaction的factory注冊(cè),在這兩個(gè)宏中間,使用uvm_field宏注冊(cè)所有字段。uvm_field系列宏隨著transaction成員變量的不同而不同,如上面的定義中出現(xiàn)了針對(duì)bit類(lèi)型的uvm_field_int及針對(duì)byte類(lèi)型動(dòng)態(tài)數(shù)組的uvm_field_array_int。
3.3.1節(jié)列出了所有的uvm_field系列宏。
當(dāng)使用上述宏注冊(cè)之后,可以直接調(diào)用copy、compare、print等函數(shù),而無(wú)需自己定義。這極大地簡(jiǎn)化了驗(yàn)證平臺(tái)的搭建,提高了效率:
代碼清單 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機(jī)制的另外一大好處是簡(jiǎn)化了driver和monitor。在2.3.1節(jié)及2.3.3節(jié)中,my_driver的drv_one_pkt任務(wù)和my_monitor的collect_one_pkt任務(wù)代碼很長(zhǎng),但是幾乎都是一些重復(fù)性的代碼。使用field_automation機(jī)制后,drv_one_pkt任務(wù)可以簡(jiǎn)化為:
代碼清單 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行調(diào)用pack_bytes將tr中所有的字段變成byte流放入data_q中,在2.3.1節(jié)中是手工地將所有字段放入data_q中的。
pack_bytes極大地減少了代碼量。在把所有的字段變成byte流放入data_q中時(shí),字段按照uvm_field系列宏書(shū)寫(xiě)的順序排列。在上述代碼中是先放入dmac,再依次放入smac、ether_type、pload、crc。假如my_transaction定義時(shí)各個(gè)字段的順序如下:
代碼清單 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
那么將會(huì)先放入smac,再依次放入dmac、ether_type、pload、crc。
my_monitor的collect_one_pkt可以簡(jiǎn)化成:
代碼清單 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函數(shù)將data_q中的byte流轉(zhuǎn)換成tr中的各個(gè)字段。unpack_bytes函數(shù)的輸入?yún)?shù)必須是一個(gè)動(dòng)態(tài)數(shù)組,所以需要先把收集到的、放在data_q中的數(shù)據(jù)復(fù)制到一個(gè)動(dòng)態(tài)數(shù)組中。由于tr中的pload是一個(gè)動(dòng)態(tài)數(shù)組,所以需要在調(diào)用unpack_bytes之前指定其大小,這樣unpack_bytes函數(shù)才能正常工作。
轉(zhuǎn)載于:https://www.cnblogs.com/YINBin/p/6915664.html
總結(jié)
以上是生活随笔為你收集整理的*2-3-7-加入field_automation机制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 用python阐释工作量证明(proof
- 下一篇: 团队作业8——第二次项目冲刺(Beta阶