1`timescale 1ns/1ps
2
3// Design Code
4module ADDER(
5    input clk,
6    input [7:0]	a,
7    input [7:0]	b,
8    input bIsPos,
9    output reg [8:0] result
10);
11
12    always @ (posedge clk) begin
13        if (bIsPos) begin	
14            result <= a + b;
15        end else begin
16            result <= a - b;
17        end
18    end
19
20endmodule: ADDER
21
22interface adder_if(
23    input bit clk,
24    input [7:0] a,
25    input [7:0] b,
26    input bIsPos,
27    input [8:0] result
28);
29
30    clocking cb @(posedge clk);
31        output a;
32        output b;
33        output bIsPos;
34        input result;
35    endclocking : cb
36
37endinterface: adder_if
38
39
40bind ADDER adder_if my_adder_if(
41    .clk(clk),
42    .a(a),
43    .b(b),
44    .bIsPos(bIsPos),
45    .result(result)
46);
47
48
49// Testbench Code
50import uvm_pkg::*;
51`include "uvm_macros.svh"
52
53class testbench_env extends uvm_env;
54
55    virtual adder_if m_if;
56
57    function new(string name, uvm_component parent = null);
58        super.new(name, parent);
59    endfunction
60    
61    function void connect_phase(uvm_phase phase);
62        assert(uvm_resource_db#(virtual adder_if)::read_by_name(get_full_name(), "adder_if", m_if));
63    endfunction: connect_phase
64
65    task run_phase(uvm_phase phase);
66        phase.raise_objection(this);
67        `uvm_info(get_name(), "Starting test!", UVM_HIGH);
68        begin
69            int a = 8'h4, b = 8'h5;
70            @(m_if.cb);
71            m_if.cb.a <= a;
72            m_if.cb.b <= b;
73            m_if.cb.bIsPos <= 1'b1;
74            repeat(2) @(m_if.cb);
75            `uvm_info(get_name(), $sformatf("%0d + %0d = %0d", a, b, m_if.cb.result), UVM_LOW);
76        end
77        `uvm_info(get_name(), "Ending test!", UVM_HIGH);
78        phase.drop_objection(this);
79    endtask: run_phase
80endclass
81
82
83module top;
84
85    bit clk;
86    env environment;
87    ADDER dut(.clk (clk));
88
89    initial begin
90        environment = new("testbench_env");
91        uvm_resource_db#(virtual adder_if)::set("env", "adder_if", dut.my_adder_if);
92        clk = 0;
93        run_test();
94    end
95
96    // Clock generation	
97    initial begin
98        forever begin
99            #(1) clk = ~clk;
100        end
101    end
102    
103endmodule
104