title: A test bench for a phase counter using uvm
body: <p>I am trying to create a uvm type test bench for a phase accumulator which is to be used in a DDS chain. Having this may be an overkill for a simple phase accumulator, but I am new to uvm/SystemVerilog so want to learn how to use the concepts. I have several questions.</p>
  <p>My DUT:</p>
  <pre><code>module phase_acc #(
      parameter PHASE_ACC_WIDTH = 16,
      parameter TUNNING_WORD_WIDTH = 8
  ) (
      input wire clk,
      input wire reset,
      input wire load,
      input wire [TUNNING_WORD_WIDTH-1 : 0] tuning_word,
      output reg [PHASE_ACC_WIDTH-1 : 0] phase,
      output wire cycle_end,
      output wire [1:0] phase_quadrant
  );
  
    assign phase_quadrant = phase[PHASE_ACC_WIDTH-1:PHASE_ACC_WIDTH-2];
    assign cycle_end = (phase + tuning_word) &gt; {PHASE_ACC_WIDTH{1'b1}};
  
    always @(clk) begin
      if (reset == 1) begin
        phase &lt;= 0;
      end else begin
        phase &lt;= phase + tuning_word;
      end
    end
  
  endmodule
  </code></pre>
  <p>Please note that this is not complete and planning to fill it after writing tests.</p>
  <p>basic functionality is that the phase_acc counts up by tuning_word at a time. Just before it wraps around, it needs to assert cycle_end. Forget about phase_quadrant for now.</p>
  <p>A new tuning_word can be loaded by asserting load.</p>
  <p>I have created two classes to monitor signals. One for input stimulus (tuning_word and load) which gets triggered when ever load is one during a clock transition. The other is for phase_acc outputs which contain phase, cycle_end. Since these change at each clock transition, a new object of this type need to be created at each clock edge. Monitor uses two analysis ports to send stimulus packets and output packets to scoreboard.</p>
  <p>My first question is, does this design make sense? Most uvm examples I saw have a behavior where after a stimulus is created, the DUT gives a single output which is then verified. (Say a RAM for example). In my case however, the DUT is free running.</p>
  <p>If above design is correct, I have my second question.</p>
  <p>My code for the monitor is:</p>
  <pre><code>class monitor extends uvm_monitor;
    `uvm_component_utils(monitor)
    function new(string name = &quot;monitor&quot;, uvm_component parent = null);
      super.new(name, parent);
    endfunction
  
    uvm_analysis_port #(acc_stimulus) mon_stimulus_analysis_port;
    uvm_analysis_port #(acc_output) mon_output_analysis_port;
    virtual reg_if vif;
    semaphore sema4;
  
    virtual function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      if (!uvm_config_db#(virtual acc_if)::get(this, &quot;&quot;, &quot;acc_if&quot;, vif))
        `uvm_fatal(&quot;MON&quot;, &quot;Could not get vif&quot;)
      sema4 = new(1);
      mon_stimulus_analysis_port = new(&quot;mon_stimulus_analysis_port&quot;, this);
      mon_output_analysis_port = new(&quot;mon_output_analysis_port&quot;, this);
    endfunction
  
    virtual task run_phase(uvm_phase phase);
      super.run_phase(phase);
      forever begin
        fork
          begin
            @(vif.clk);
  
            // output
            acc_output out = new;
            out.phase = vif.phase;
            out.cycle_end = vif.cycle_end;
            out.phase_quadrant = cif.phase_quadrant;
            `uvm_info(get_type_name(), $sformatf(&quot;Monitor found ouout %s&quot;, out.convert2str()),
                      UVM_LOW)
            mon_output_analysis_port.write(out);
  
          end
  
          begin
            @(vif.clk);
            // stimulus
            if (vif.ld) begin
              acc_stimulus stimulus = new;
              stimulus.tunning_word = vif.tuning_word;
              stimulus.load = vif.ld;
              `uvm_info(get_type_name(), $sformatf(&quot;Monitor found stimulus  %s&quot;,
                                                   stimulus.convert2str()), UVM_LOW)
              mon_stimulus_analysis_port.write(stimulus);
            end
          end
        join
      end
    endtask
  endclass
  </code></pre>
  <p>But when trying to compile this, I get an error for the line which says:</p>
  <pre><code>acc_output out = new;
  </code></pre>
  <p>I am not sure what I am doing wrong there. If I were to do this inside an <code>if</code> condition, for example:</p>
  <pre><code> begin
            @(vif.clk);
            if(vif.clk) begin
              // output
              acc_output out = new;
  </code></pre>
  <p>Then the error disappears.</p>
  <p>I cannot understand what's wrong with the code.</p>