18 UVM Scoreboard

UVM scoreboard是一个检查DUT功能的组件。它用analysis export从monitor接受transaction事务以进行检查。

uvm_scoreboard class declaration:

virtual class uvm_scoreboard extends uvm_component

User-defined scoreboard class declaration:

 用户定义的scoreboard是从 uvm_scoreboard 扩展而来的,而 uvm_scoreboard 又派生自 uvm_component。

class <scoreboard_name> extends uvm_scoreboard;

1 uvm_scoreboard class hierarchy

3 Scoreboard Usage

  1. 使用analysis export从monitor接收transaction以进行检查。
  2. scoreboard有一个参考模型reference model可以与design行为进行比较。reference model也称为预测器predictor,它实现design行为,以便scoreboard可以将 DUT 结果与相同驱动刺激的参考模型reference model结果进行比较。

3 How to write scoreboard code in UVM?

  1. 创建一个从 uvm_scoreboard 扩展的用户定义的scoreboard类,并将其注册到工厂中。
  2. 声明analysis export以从monitor接收sequence item或transaction。
  3. 编写标准 new() 函数。由于记分板是一个 uvm_component。new() 函数有两个参数:字符串名称name和 uvm_component 父类parent。
  4. 实现 build_phase 并创建 TLM analysis export实例。
  5. 实现一个 write 方法来接收来自monitor的事务。
  6. 实现run_phase 以在整个仿真时间内检查 DUT 功能。

3.1 Scoreboard Example

class scoreboard extends uvm_scoreboard;
  uvm_analysis_imp #(seq_item, scoreboard) item_collect_export;
  seq_item item_q[$];
  `uvm_component_utils(scoreboard)
  
  function new(string name = "scoreboard", uvm_component parent = null);
    super.new(name, parent);
    item_collect_export = new("item_collect_export", this);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
  
  function void write(seq_item req);
    `uvm_info(get_type_name, $sformatf("Received transaction = %s", req), UVM_LOW);
    item_q.push_back(req);
  endfunction
  
  task run_phase (uvm_phase phase);
    seq_item sb_item;
    forever begin
      wait(item_q.size > 0);
      
      if(item_q.size > 0) begin
        sb_item = item_q.pop_front();
        // Checking comparing logic
        ...        
      end
    end
  endtask
endclass

4 UVM Scoreboad types

根据设计功能,记分板可以通过两种方式实现。

  1. in-order scoreboard
  2. out-of-order scoreboard

4.1 In-order scoreboard

有序记分板(in-order scoreboard)对于输出顺序与stimuli激励相同的设计很有用。比较器将以相同的顺序比较预期输出流和实际输出流。他们将独立抵达。因此,评估必须阻塞,直到预期transaction和实际transaction都存在。

要实现此类scoreboard,更简单的方法是实现 TLM analysis FIFO。有关更多详细信息,请访问TLM analysis FIFO部分。在下面的示例中,有两个monitor,其分析端口连接到记分板以提供输入和输出事务。 

class inorder_sb extends uvm_scoreboard;
  `uvm_component_utils(inorder_sb)
  uvm_analysis_export #(txn) in_export, out_export;
  uvm_tlm_analysis_fifo #(txn) in_fifo, out_fifo;

  function new (string name = "inorder_sb" , uvm_component parent = null) ;
    super.new(name, parent);
  endfunction


  function void build_phase (uvm_phase phase);
    in_fifo    = new("in_fifo", this);
    out_fifo   = new("out_fifo", this);
    in_export  = new("in_export", this);
    out_export = new("out_export", this);
  endfunction


  function void connect_phase (uvm_phase phase);
    in_export.connect(in_fifo.analysis_export);
    out_export.connect(out_fifo.analysis_export);
  endfunction


  task run_phase( uvm_phase phase);
    txn in_txn;
    txn exp_txn, act_txn;
    forever begin
      in_fifo.get(in_txn);
      process_data(in_txn, exp_txn); 
      out_fifo.get(act_txn);
      if (!exp_txn.compare(act_txn)) begin
        `uvm_error(get_full_name(), $sformat("%s does not match %s", exp_txn.sprint(), act_txn.sprint()), UVM_LOW);
      end
    end
  endtask
  
  // Reference model 
  task process_data(input txn in_txn, output txn exp_txn);
    // Generate expected txn for driven stimulus
    ...
    ...
  endtask
endclass

4.2 Out-of-order scoreboard

无序记分板out-of-order scoreboard对于输出顺序与驱动输入激励stimuli不同的设计很有用。基于输入激励参考模型将生成 DUT 的预期结果,并且实际输出预计以任何顺序出现。因此,需要存储从输入激励生成的此类不匹配事务,直到从待比较的 DUT 接收到相应的输出为止。为了存储此类事务,关联数组被广泛使用。根据索引值,transactions存储在预期和实际关联数组中。当匹配的数组索引发生比较时,关联数组中的条目将被删除。

class txn extends uvm_sequence_item;
  int id;  
  // other class properties
  //...
endclass

class out_of_order_sb extends uvm_scoreboard;
  `uvm_component_utils(out_of_order_sb)
  uvm_analysis_export #(txn) in_export, out_export;
  uvm_tlm_analysis_fifo #(txn) in_fifo, out_fifo;
  // associative array of class type as txn and indexed by int
  txn expected_out_array[int];
  txn actual_out_array[int];

  // Store idx in separate queues.
  int expected_out_q[$], actaul_out_q[$];

  function new (string name = "out_of_order_sb" , uvm_component parent = null) ;
    super.new(name, parent);
  endfunction


  function void build_phase (uvm_phase phase);
    in_fifo    = new("in_fifo", this);
    out_fifo   = new("out_fifo", this);
    in_export  = new("in_export", this);
    out_export = new("out_export", this);
  endfunction


  function void connect_phase (uvm_phase phase);
    in_export.connect(in_fifo.analysis_export);
    out_export.connect(out_fifo.analysis_export);
  endfunction


  task run_phase( uvm_phase phase);
    txn in_txn, out_txn;
    forever begin
      fork      
        begin 
          in_fifo.get(in_txn);
          process_data(in_txn);
        end
        begin
          out_fifo.get(out_txn);
          actual_out_array[out_txn.id] = out_txn;
          actaul_out_q.push_back(out_txn.id);
        end

      join
      compare_data();
    end
  endtask
  
  // check_phase to check whether any entry is pending in queues.
  function void check_phase(uvm_phase phase);
    super. check_phase(phase);
    if(expected_out_q.size() != 0) `uvm_info (get_full_name(), $sformatf("expected_out_q size = %0d", expected_out_q.size()), UVM_LOW);
    if(actaul_out_q.size() != 0) `uvm_info (get_full_name(), $sformatf("actaul_out_q size = %0d", actaul_out_q.size()), UVM_LOW);
  endfunction

  task process_data(txn in_txn);
    txn exp_out_txn;
    // Using reference models, generate output for input stimulus.
    // store expected output (exp_out_txn) in expected_out_array
    ...
    ...
    expected_out_array[in_txn.id] = exp_out_txn;
    expected_out_q.push_back(in_txn.id);
  endtask
  
  task compare_data();
    int idx;
    txn exp_txn, act_txn;
    if(expected_out_q.size() > && actaul_out_q.size() > 0) begin
      idx = expected_out_q.pop_front();
      
      // Look for idx in actual_out_array to see whether the output has been received for a driven stimulus or not.
      if(actual_out_array.exists(idx)) begin 
        exp_txn = expected_out_array[idx];
        act_txn = actual_out_array[idx];
        
        if(!exp_txn.compare(act_txn)) begin
          `uvm_error(get_full_name(), $sformat("%s does not match %s", exp_txn.sprint(), act_txn.sprint()), UVM_LOW);
        end
        else begin
          expected_out_array.delete(idx);
          actual_out_array.delete(idx);
        end
      end
      else expected_out_q.push_back(idx); // exp_idx is not found in actual_out_array.
    end
  endtask
endclass

 

  • 19
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的UVM评分板(Scoreboard)的示例,用于检查接收到的事务与期望的结果是否匹配: ```verilog class my_scoreboard extends uvm_scoreboard; `uvm_component_utils(my_scoreboard) // Declare analysis port for receiving transactions uvm_analysis_port #(my_transaction) analysis_port; // Override the build_phase to connect the analysis port virtual function void build_phase(uvm_phase phase); super.build_phase(phase); // Connect the analysis port to the scoreboard's analysis_export analysis_port = new("analysis_port", this); endfunction // Override the write method to check received transactions virtual function void write(my_transaction txn); super.write(txn); // Check the received transaction against expected results if (txn.result == txn.expected_result) `uvm_info("SCOREBOARD", $sformatf("Transaction %0d passed", txn.transaction_id), UVM_MEDIUM) else `uvm_error("SCOREBOARD", $sformatf("Transaction %0d failed", txn.transaction_id)) endfunction endclass ``` 在上面的示例中,`my_scoreboard`是一个UVM评分板,它用于检查接收到的`my_transaction`类型的事务与期望的结果是否匹配。在`build_phase`中,评分板创建了一个分析端口(`analysis_port`)并将其连接到评分板的`analysis_export`。 评分板的`write`方法被重写以检查接收到的事务。在该方法中,评分板比较事务的`result`字段与`expected_result`字段,如果它们匹配,则打印一条通过的信息;否则,打印一条失败的信息。 以上是一个简单的UVM评分板示例,它展示了如何在UVM中创建和使用评分板来检查接收到的事务与期望的结果是否匹配。具体实现中,你需要根据你的需求进行适当的修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值