2.3.6-加入scoreboard

时间:2023-03-10 07:23:57
2.3.6-加入scoreboard

在验证平台中加入了reference model和monitor之后,最后一步是加入scoreboard。my_scoreboard的代码如下:


代码清单 2-50
文件:src/ch2/section2.3/2.3.6/my_scoreboard.sv
  3 class my_scoreboard extends uvm_scoreboard;
  4   my_transaction  expect_queue[$];
  5   uvm_blocking_get_port #(my_transaction)  exp_port; //expected-port
  6   uvm_blocking_get_port #(my_transaction)  act_port;  //actually received-port
  7   `uvm_component_utils(my_scoreboard)
  8
  9    extern function new(string name, uvm_component parent = null);
 10   extern virtual function void build_phase(uvm_phase phase);
 11   extern virtual task main_phase(uvm_phase phase);
 12 endclass
 13
 14 function my_scoreboard::new(string name, uvm_component parent = null);
 15   super.new(name, parent);
 16 endfunction
 17
 18 function void my_scoreboard::build_phase(uvm_phase phase);
 19   super.build_phase(phase);
 20   exp_port = new("exp_port", this);
 21   act_port = new("act_port", this);
 22 endfunction
 23
 24 task my_scoreboard::main_phase(uvm_phase phase);
 25   my_transaction  get_expect,  get_actual, tmp_tran;
 26   bit result;
 27
 28   super.main_phase(phase);
 29   fork
 30     while (1) begin  //进程1
 31       exp_port.get(get_expect);
 32       expect_queue.push_back(get_expect);
 33     end
 34     while (1) begin  //进程2
 35       act_port.get(get_actual);
 36       if(expect_queue.size() > 0) begin
 37         tmp_tran = expect_queue.pop_front();
 38         result = get_actual.my_compare(tmp_tran);
 39         if(result) begin
 40            `uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_LOW);
 41         end
 42         else begin
 43            `uvm_error("my_scoreboard", "Compare FAILED");
 44            $display("the expect pkt is");
 45            tmp_tran.my_print();
 46            $display("the actual pkt is");
 47            get_actual.my_print();
 48         end
 49       end
 50       else begin
 51         `uvm_error("my_scoreboard", "Received from DUT, while Expect Que ue is empty");
 52         $display("the unexpected pkt is");
 53         get_actual.my_print();
 54       end
 55    end
 56  join
 57 endtask


my_scoreboard要比较的数据一是来源于reference model,二是来源于o_agt的monitor。前者通过exp_port获取,而后者通过act_port获取。在main_phase中通过fork建立起了两个进程,一个进程处理exp_port的数据,当收到数据后,把数据放入expect_queue中;另外一个进程处理act_port的数据,这是DUT的输出数据,当收集到这些数据后,从expect_queue中弹出之前从exp_port收到的数据,并调用my_transaction的my_compare函数。采用这种比较处理方式的前提是exp_port要比act_port先收到数据。由于DUT处理数据需要延时,而reference model是基于高级语言的处理,一般不需要延时,因此可以保证exp_port的数据在act_port的数据之前到来。

act_port和o_agt的ap的连接方式及exp_port和reference model的ap的连接方式与2.3.5节讲述的i_agt的ap和reference model的端口的连接方式类似,这里不再赘述。

代码清单2-50中的第38行用到了my_compare函数,这是一个在my_transaction中定义的函数,其原型为:


代码清单 2-51

文件:src/ch2/section2.3/2.3.6/my_scoreboard.sv

 54    function bit my_compare(my_transaction tr);
 55       bit result;
 56
 57       if(tr == null)
 58          `uvm_fatal("my_transaction", "tr is null!!!!")
 59       result = ((dmac == tr.dmac) &&
 60                (smac == tr.smac) &&
 61                (ether_type == tr.ether_type) &&
 62                (crc == tr.crc));
 63       if(pload.size() != tr.pload.size())
 64          result = 0;
 65       else
 66          for(int i = 0; i < pload.size(); i++) begin
 67             if(pload[i] != tr.pload[i])
 68               result = 0;
 69          end
 70       return result;
 71    endfunction

它逐字段比较两个my_transaction,并给出最终的比较结果。

完成my_scoreboard的定义后,也需要在my_env中将其实例化。此时,整棵UVM树变为如图2-8所示的形式。