Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Start Here4
  • UVM Foundations14
  • UVM Phases & Simulation Lifecycle26
  • Factory & Configuration15
  • Transaction-Level Modeling (TLM)13
  • UVM Sequences & Stimulus21
  • UVM Agents & Protocol VIP21
  • Environment & Test Classes11
  • Checking & Coverage in UVM21
  • UVM Register Abstraction Layer (RAL)22
  • Advanced UVM in Practice13
  • Debug & Regression10
  • Coding Practice47
  • Verification in Industry Practice10
    • Simulation for Sign-off
    • Safety, Acceleration and Models
      • Functional Safety: Fault Injection and Diagnostic Coverage
      • Emulation and FPGA Prototyping: When the Simulator Is Too Slow
      • Multi-Language Benches: SystemC, C/C++ and Python
      • Mixed-Signal Verification with UVM
    • Beyond Simulation
  • Senior Prep: Architecture, Leadership and Interviews32
Loading lesson

‹Safety, Acceleration and Models
  1. Topics
  2. UVM Verification
  3. Verification in Industry Practice
  4. Safety, Acceleration and Models
  5. Mixed-Signal Verification with UVM

Part 12 · Industry Practice · Intermediate

Mixed-Signal Verification with UVM

Real-number modelling (real, nettype, wreal), UVM-MS, AMS co-simulation versus RNM, and the boundary checks a digital DV engineer owns: monotonicity, settling and thresholds.

On this page

    A chip comes back from the fab and the ADC never produces a reading. The digital logic is fine and the ADC is fine. The enable pin that the digital side drives is active-low in the analog block and active-high in the RTL, and every simulation used a stub ADC model that ignored its enable. The bug lived on the line between two teams, and no simulation ever looked at it. How does a digital DV engineer verify that line without a SPICE simulator in every regression?

    The idea: model the analog part just well enough to check the boundary

    A transistor-level (SPICE) simulator solves the circuit's equations continuously; it is accurate and orders of magnitude slower than an event-driven digital simulator. Running SPICE on a whole SoC for every test is out of the question. Real-number modelling (RNM) is the compromise: analog blocks are written as event-driven models whose signals carry real values (volts, amps), updated only when something changes or at a chosen time step. The digital simulator runs them at nearly digital speed.

    It is like a flight simulator for pilots versus a wind tunnel for engineers. The flight simulator is not exact about the air, but it is exact enough about what the pilot sees and does, and it runs in real time. An RNM ADC is not exact about transistor noise, but it is exact enough about what the digital side sees: a code, a ready flag, a settling time, a threshold. That is the boundary you verify.

    Approach

    What runs

    Speed

    Used for

    Digital stub

    A model that ignores analog behaviour (assign ready = 1)

    Fastest

    Early bring-up only; it hides boundary bugs like the enable story

    Real-number model

    Event-driven real signals in SystemVerilog (or Verilog-AMS wreal)

    Near-digital

    Regressions of the mixed-signal boundary

    AMS co-simulation

    Digital simulator plus an analog (SPICE or FastSPICE) solver on part of the design

    Much slower

    Selected scenarios, model validation, sign-off of critical paths

    The picture: where digital meets analog

    Flowchart: a UVM bench with an analog driver, a monitor and a tolerance scoreboard; the driver sets a real voltage on an ADC model, whose code and ready flag go to the monitor; a DAC and filter drive a comparator whose trip bit also goes to the monitor.
    The UVM bench drives real values into analog inputs and checks the digital results with tolerances. The models are only as detailed as the boundary needs: codes, flags, thresholds and timing.

    Build it: a real-number model and three checks

    The model below is a 4-bit DAC driving an RC filter, with a comparator on the output. It runs three checks you will meet on real projects: monotonicity (each code step raises the output; the worst step error is the DNL, differential non-linearity, in LSBs), settling (the output reaches the target within half an LSB inside a time spec) and a threshold (when the comparator trips). The second DAC has a mismatched MSB element, the classic cause of a non-monotonic step at mid-scale.

    top.sv
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    // A real-number model of a 4-bit DAC driving an RC filter, and the three checks a
    // digital DV engineer usually owns at an analog boundary: monotonicity, settling, threshold.
    module top;
      localparam real VREF = 1.0;
      localparam real LSB  = VREF / 16.0;
      localparam real TAU  = 20.0;        // filter time constant, ns
      localparam real T_SETTLE_SPEC = 100.0;
    
      // Static transfer function of a binary-weighted DAC. msb_w is the MSB weight as a
      // fraction of VREF: ideal is 0.5; a mismatched MSB element makes it smaller.
      function automatic real dac(input bit [3:0] code, input real msb_w);
        return VREF * (code[0] * 0.0625 + code[1] * 0.125 + code[2] * 0.25 + code[3] * msb_w);
      endfunction
    
      // Monotonicity and worst DNL (step size error in LSB) over all codes.
      function automatic bit monotonic(input real msb_w, output real worst_dnl, output int at_code);
        bit ok = 1;
        worst_dnl = 0.0; at_code = 0;
        for (int c = 1; c < 16; c++) begin
          real step = dac(c[3:0], msb_w) - dac(c[3:0] - 4'd1, msb_w);
          real dnl  = step / LSB - 1.0;
          if (step <= 0.0) ok = 0;
          if ((dnl < 0 ? -dnl : dnl) > (worst_dnl < 0 ? -worst_dnl : worst_dnl)) begin
            worst_dnl = dnl; at_code = c;
          end
        end
        return ok;
      endfunction
    
      real vout = 0.0, target = 0.0;
      bit  cmp_out;
      real vth = 0.5;                     // comparator threshold
    
      // The analog part: a first-order RC step response, integrated every 1 ns.
      always #1 vout = vout + (target - vout) * (1.0 / TAU);
      // A comparator on the filtered output: the digital side only ever sees this bit.
      always @(vout) cmp_out = (vout > vth);
    
      initial begin
        real dnl; int c; time t0, t_settle, t_cross;
        bit ok;
        ok = monotonic(0.5, dnl, c);
        $display("ideal DAC:      monotonic=%0b worst DNL=%0.2f LSB at code %0d", ok, dnl, c);
        ok = monotonic(0.42, dnl, c);
        $display("MSB weight 0.42: monotonic=%0b worst DNL=%0.2f LSB at code %0d", ok, dnl, c);
    
        // Settling: full-scale step, time until |vout - target| < LSB/2.
        #5 t0 = $time; target = dac(4'hF, 0.5); t_cross = 0;
        while ((target - vout) > LSB / 2.0) begin
          #1;
          if (t_cross == 0 && cmp_out) t_cross = $time - t0;
        end
        t_settle = $time - t0;
        $display("step 0 -> 15: settled to %0.4f V (target %0.4f) in %0t ns, spec %0.0f ns: %s",
                 vout, target, t_settle, T_SETTLE_SPEC, t_settle <= T_SETTLE_SPEC ? "PASS" : "FAIL");
        $display("comparator (vth=%0.2f V) switched %0t ns after the step", vth, t_cross);
        $finish;
      end
    endmodule
    Diagram
    ideal DAC:      monotonic=1 worst DNL=0.00 LSB at code 0
    MSB weight 0.42: monotonic=0 worst DNL=-1.28 LSB at code 8
    step 0 -> 15: settled to 0.9073 V (target 0.9375) in 67 ns, spec 100 ns: PASS
    comparator (vth=0.50 V) switched 15 ns after the step
    • Monotonicity. With the MSB weight at 0.42 instead of 0.5, code 8 (0.42 V) is lower than code 7 (0.4375 V): a DNL of −1.28 LSB, which means a step that goes backwards. A control loop driving this DAC could oscillate around mid-scale.

    • Settling. A first-order filter settles to half an LSB from a full-scale step in τ·ln(15/16 ÷ 1/32) = τ·ln 30 ≈ 68 ns; the model, integrating in 1 ns steps, gives 67 ns, inside the 100 ns spec.

    • Threshold. The comparator trips 15 ns after the step, matching τ·ln(0.9375/0.4375) ≈ 15.2 ns. The digital side sees only that bit, so this is the timing its logic must tolerate.

    • Tolerance, never equality. Every check compares reals against a band (half an LSB, a time spec). An == on a real value is almost always a bug in an analog check.

    Nets that carry reals: nettype and wreal

    Plain real variables cannot have several drivers. Real circuits do: two current sources into one node, a pull-up and a driver on one line. SystemVerilog (IEEE 1800-2012 and later) adds user-defined nettypes: a net whose value is any type, with a resolution function that combines all drivers. Verilog-AMS has wreal for the same purpose, and commercial simulators support it in mixed flows. Vendors ship packages of predefined nettypes (for example a voltage-and-impedance struct) so that models from different teams connect.

    top.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // not-run: Verilator 5.048 and Icarus 13 do not support nettype (both reject it); commercial simulators do
    module top;
      // A user-defined net that carries a real value and resolves several drivers by summing them.
      function automatic real rsum(input real d[]);
        rsum = 0.0;
        foreach (d[i]) rsum += d[i];
      endfunction
      nettype real rnet with rsum;
    
      rnet vin;
      real a = 0.0, b = 0.0;
      assign vin = a;
      assign vin = b;
    
      initial begin
        a = 0.6; b = 0.3;
        #1 $display("vin = %0.2f V (two drivers summed)", vin);
        $finish;
      end
    endmodule

    UVM on the analog boundary

    In UVM terms, an analog input is just another interface. An analog driver takes an item ("ramp vin from 0.2 V to 0.8 V over 2 us") and sets a real on the interface in small steps; an analog monitor samples a real value on an event or at a fixed rate, or watches the digital outputs the analog block produces; the scoreboard compares against a model with tolerances. Sequences describe stimulus in physical units, which reads well and makes coverage meaningful ("input in each eighth of the range").

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // snippet: an analog driver that ramps a real-valued input in steps
    task drive_item(vin_item it);
      real v = vif.vin;
      int  steps = it.ramp_ns / it.step_ns;
      for (int i = 1; i <= steps; i++) begin
        #(it.step_ns * 1ns);
        vif.vin = v + (it.volts - v) * i / steps;
      end
      `uvm_info("AMS_DRV", $sformatf("vin at %0.3f V", vif.vin), UVM_HIGH)
    endtask

    Accellera's UVM-MS working group defines a methodology for exactly this: a small library and an analog bridge between UVM proxy classes and the analog nets, so that analog drivers and monitors become reusable VIP like digital agents. Check the current release on Accellera's site before quoting its API; the concept is what interviewers ask about. Many teams build the same pattern themselves with interfaces and real-valued signals, as above.

    Where digital DV engineers meet analog

    Block

    What the digital side drives

    What you check

    ADC

    Enable, start, sample clock, calibration

    Code for a known input within tolerance, conversion time, ready/valid timing, behaviour at range ends

    DAC

    Codes, update strobe

    Monotonicity, settling within spec, glitch-free updates

    PLL

    Divider and band settings, enable

    Lock within the spec time, lock-detect behaviour, the clock switch-over the digital side does after lock

    Regulators, bandgap, POR

    Enables, trim codes

    Power-up order, ready flags, reset release only after supplies are good

    Comparators, sensors

    Thresholds, trims

    Trip points, hysteresis, the interrupt or flag they raise

    Most real escapes on this boundary are not subtle analog effects. They are connectivity and convention: an inverted enable, a swapped bus order, a trim register wired to the wrong block, a ready flag the digital side never waits for. Those are exactly the bugs that a real-number model with the right pin behaviour finds and a stub hides.

    What breaks: the model that drifted from the circuit

    A team's PLL model locked in 20 us, and every regression passed. On silicon the PLL needed longer in one band, and the digital sequencer, which switched the system clock to the PLL after a fixed 25 us, sometimes switched before lock. The RNM had been written from an early spec and never compared with the circuit after a design change. The fixes were two. First, the sequencer was changed to wait for the lock-detect flag instead of a fixed time, which should have been a requirement and a check from the start. Second, the team added model validation: an AMS co-simulation regression that runs the same stimulus on the model and on the transistor-level circuit and compares lock time, codes and thresholds within tolerance whenever either changes. A real-number model is only evidence while it matches the circuit.

    Interview

    "How do you verify a mixed-signal block, such as an ADC, in a digital UVM flow?"

    A weak answer: "The analog team verifies the ADC; we just use a stub that returns a value."

    A strong answer: "The analog team verifies the circuit; I verify the boundary. I use a real-number model with the real pin behaviour (enable polarity, start, ready timing, codes for given inputs) and drive its analog input from a UVM driver in volts. The scoreboard checks codes within an LSB tolerance, conversion time and the digital handshakes, and coverage bins the input range and modes. The model is validated against the transistor-level circuit with AMS co-simulation, and a few critical scenarios also run in co-simulation. Stubs are for early bring-up only, because they hide polarity and connectivity bugs, which are the common escapes."

    Follow-ups: Why not run SPICE in every test? (orders of magnitude slower; RNM gives near-digital speed for the behaviour the digital side sees). What does a nettype add over a real variable? (multiple drivers combined by a resolution function, like a real circuit node).

    Check yourself A scoreboard checks an ADC model with if (code != expected_code) uvm_error(...), where expected_code = $floor(vin / lsb). It fails rarely at random inputs. Is the ADC model wrong?

    Probably not. For inputs very close to a code boundary, tiny floating-point differences decide which side the value falls on, so the model and the expectation can disagree by one code. The check should accept the expected code plus or minus one LSB near boundaries (or the tolerance the spec gives), and coverage should still record which codes were reached.

    Check yourself Your DAC model is monotonic, but the full-chip regression uses a digital stub instead to save time. What bug classes could the stub hide?

    Anything the stub does not model: inverted enables or strobes, a wrong bit order on the code bus, missing update strobes, timing assumptions (the digital side using the output before it settles) and non-monotonic steps that a control loop depends on. A real-number model costs little speed and keeps those visible; stubs belong only in tests that do not touch the block.

    Check yourself Why does the settling check in the model compare target - vout with half an LSB rather than waiting until vout == target?

    A first-order RC response approaches its target exponentially and never reaches it exactly, so an equality wait would never end. The meaningful spec is settling within a band, here half an LSB, because a downstream ADC or comparator cannot tell finer differences apart.

    Next: this topic covered four ways a project stretches the UVM bench. The rest of the Industry Practice section looks at the other verification work that surrounds it.

    Related topics

    • Up: Safety, Acceleration and Models

    • Multi-Language Benches

    • Coverage model design

    Previous

    244 / 280

    Next: Beyond Simulation

    Up next

    Up nextBeyond Simulation

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Functional Safety: Fault Injection and Diagnostic Coverage
    • Emulation and FPGA Prototyping: When the Simulator Is Too Slow