Chapter 8 – Scoreboard

The scoreboard is a crucial element in a self-checking environment, it verifies the proper operation of a design at a functional level. This component is the most difficult one to write, it varies from project to project and from designer to designer.

In our case, we decided to make the prediction of the DUT functionality in the monitors and let the scoreboard compare the prediction with the DUT’s response. But there are designers who prefer to leave the prediction to the scoreboard. So the functionality of the scoreboard is very subjective.

In the agent, we created two monitors, as a result, we will have to create two analysis exports in the scoreboard that are going to be used to retrieve transactions from both monitors. After that, a method compare() is going to be executed in the run phase and compare both transactions. If they match, it means that the testbench and the DUT both agree in the functionality and it will return an “OK” message.

But we have a problem: we have two transaction streams coming from two monitors and we need to make sure they are synchronized. This could be done manually by writing appropriated write() functions but there is an easier and cleaner way of doing this: by using UVM FIFO.

These FIFO will work as it’s represented in Figure 8.1.

Usage of FIFO in the scoreboard

Figure 8.1 – Usage of FIFO in the scoreboard

The FIFO are instantiated similarly to ports/exports, with uvm_tlm_analysis_fifo #(generic_transaction) generic_fifo and they already implement the respective write() functions that are called from the monitors. To access their data we just execute the get() method from each FIFO.

The code from the scoreboard follows in Code 8.1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class simpleadder_scoreboard extends uvm_scoreboard;
     `uvm_component_utils(simpleadder_scoreboard)
 
     uvm_analysis_export #(simpleadder_transaction) sb_export_before;
     uvm_analysis_export #(simpleadder_transaction) sb_export_after;
 
     uvm_tlm_analysis_fifo #(simpleadder_transaction) before_fifo;
     uvm_tlm_analysis_fifo #(simpleadder_transaction) after_fifo;
 
     simpleadder_transaction transaction_before;
     simpleadder_transaction transaction_after;
 
     function new(string name, uvm_component parent);
          super.new(name, parent);
          transaction_before    = new("transaction_before");
          transaction_after    = new("transaction_after");
     endfunction: new
 
     function void build_phase(uvm_phase phase);
          super.build_phase(phase);
          sb_export_before    = new("sb_export_before", this);
          sb_export_after        = new("sb_export_after", this);
 
          before_fifo        = new("before_fifo", this);
          after_fifo        = new("after_fifo", this);
     endfunction: build_phase
 
     function void connect_phase(uvm_phase phase);
          sb_export_before.connect(before_fifo.analysis_export);
          sb_export_after.connect(after_fifo.analysis_export);
     endfunction: connect_phase
 
     task run();
          forever begin
               before_fifo.get(transaction_before);
               after_fifo.get(transaction_after);
               compare();
          end
     endtask: run
 
     virtual function void compare();
          if(transaction_before.out == transaction_after.out) begin
               `uvm_info("compare", {"Test: OK!"}, UVM_LOW);
          end else begin
               `uvm_info("compare", {"Test: Fail!"}, UVM_LOW);
          end
     endfunction: compare
endclass: simpleadder_scoreboard

Code 8.1 – Code for the scoreboard

In Figure 8.2, it’s represented the current state of our testbench.

State of the testbench after the scoreboardFigure 8.2 – State of the testbench after the scoreboard

For more information about scoreboards you can consult:

The code for the scoreboard can be consulted here:

7 thoughts to “Chapter 8 – Scoreboard”

  1. You’ll want to change the `uvm_info macro for “Test: Fail” to `uvm_error macro, otherwise the reporting will not report the scoreboard errors.

  2. Hi,
    Can you please explain why did you use

    uvm_analysis_export #(simpleadder_transaction) sb_export_before;

    instead of

    uvm_blocking_put_imp #(simpleadder_transaction) sb_export_before;

    Cause in the previous chapter you explained that this is how the export is declared.

  3. Hello Pedro, I am not sure you’ll see this message since the last answers are 2 years old.. I hope so, if so may you please contact me by e-mail ? I need your help and some advices for my internship and UVM would be a big part of it, ’till now your work has helped me a lot …

  4. Hello, I also hope that I can still get an answer. At the moment it drives me crazy that I don’t understand the use of before and after. Why are the inputs to the DUT labeled “after” and the outputs “before”. Shouldn’t it be the other way around?

  5. Hi Pedro,
    Can you show the connection between the monitor and scoreboard in the env.
    How does the packet reach scoreboard in absence of write() function.

    Thanks..

Leave a Reply

Your email address will not be published. Required fields are marked *