前回はこちら:msyksphinz.hatenablog.com
UVMを使って、2ポートのArbiterを検証することを考えたい。
2ポートのRound Robin Arbiterは、現在のPriorityに応じてAcceptするポートを変えるArbiterだ。
arbiter2_rr.sv
always_comb begin w_curr_ptr_next = r_curr_ptr; case (r_curr_ptr) 'h0 : begin if (i_valid0) begin w_curr_ptr_next = 1; o_data = i_data0; end else begin o_data = i_data1; end end default : begin // 'h1 : begin if (i_valid1) begin w_curr_ptr_next = 0; o_data = i_data1; end else begin o_data = i_data0; end end endcase // case (r_curr_ptr) o_valid = i_valid0 | i_valid1; end // always_comb always_ff @ (posedge i_clk, negedge i_reset_n) begin if (!i_reset_n) begin r_curr_ptr <= 0; end else begin r_curr_ptr <= w_curr_ptr_next; end end
UVMのスコアボードに、これを再現するための検証チェッカーのコードを追加してみる。
arbiter2_rr_scoreboard.sv
virtual function write (arbiter2_rr_seq_item item); `uvm_info (get_type_name(), $sformatf("pointer=%d, Scoreboard found packet %s", curr_pointer, item.convert2str()), UVM_LOW) if ((item.i_valid1 | item.i_valid0) && !item.o_valid) begin `uvm_error (get_type_name(), $sformatf ("valid3-0 activated, but output not activated")); end case (curr_pointer) 'h0 : begin if (item.i_valid0) begin curr_pointer = 1; if (item.o_data != item.i_data0) begin `uvm_error (get_type_name(), $sformatf ("valid0 activated, but data different. o_data=0x%04h data0=0x%h", item.o_data, item.i_data0)); end end else if (item.i_valid1) begin curr_pointer = 0; if (item.o_data != item.i_data1) begin `uvm_error (get_type_name(), $sformatf ("valid1 activated, but data different. o_data=0x%04h data1=0x%h", item.o_data, item.i_data1)); end end end // case: 'h0 'h1 : begin if (item.i_valid1) begin curr_pointer = 0; if (item.o_data != item.i_data1) begin `uvm_error (get_type_name(), $sformatf ("valid1 activated, but data different. o_data=0x%04h data1=0x%h", item.o_data, item.i_data1)); end end else if (item.i_valid0) begin curr_pointer = 1; if (item.o_data != item.i_data0) begin `uvm_error (get_type_name(), $sformatf ("valid0 activated, but data different. o_data=0x%04h data0=0x%h", item.o_data, item.i_data0)); end end end // case: 'h1 endcase // case (curr_pointer) endfunction // write
実行してみると、正しく検証できることが確認できた。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/m/msyksphinz/20241121/20241121014423.png)