Day 13 · SystemVerilog Transition

The logic Type

Video 2 of 4 · ~8 minutes

Dr. Mike Borowczak · Electrical & Computer Engineering · CECS · UCF

Why SVlogic typealways_*enum/struct/package

🌍 Where This Lives

In Industry

Open-source: every SV project on GitHub uses logic. PicoRV32, Ibex, CORE-V, BlackParrot, RocketChip — not a reg declaration in sight. Commercial: Intel's, AMD's, and Apple's design style guides mandate logic for all new code. The wire/reg distinction is strictly maintenance-mode in modern flows.

In This Course

From Day 13 on, all new code uses logic. Your Week 1-3 library is optionally modernized (simple find/replace: wirelogic, reglogic, except in module ports where the distinction is irrelevant). Your Day 14 assertions assume SV style.

⚠️reg Means Register”

❌ Wrong Model

reg declarations become flip-flops. wire declarations become combinational logic. The type tells me the hardware.”

✓ Right Model

The reg keyword has nothing to do with registers. It's a procedural assignment target — a variable you can assign inside always, initial, or task blocks. Whether it becomes a flip-flop, a latch, or combinational logic depends entirely on the always block that drives it. reg is a confusing name for “assignable variable.”

The receipt: reg inside always @(*) → combinational. reg inside always @(posedge clk) → flip-flop. The keyword does not decide. The block decides. logic drops the misleading name and acknowledges: “any 4-state signal, the synthesis tool figures out the hardware.”

👁️ I Do — Verilog-2001 vs SystemVerilog

VERILOG-2001

module counter (
    input  wire       clk, rst,
    output reg  [7:0] count    // reg in port
);
    // internal:
    wire [7:0] next_count;
    reg        load_done;

    always @(posedge clk)
        if (rst) count <= 0;
        else     count <= next_count;

    assign next_count = count + 1'b1;
endmodule

SYSTEMVERILOG

module counter (
    input  logic       clk, rst,
    output logic [7:0] count
);
    logic [7:0] next_count;
    logic       load_done;

    always_ff @(posedge clk)
        if (rst) count <= 0;
        else     count <= next_count;

    assign next_count = count + 1'b1;
endmodule
My thinking: Exactly the same hardware. The SV version is shorter and uniform. Every signal is logic, regardless of whether it's driven by an always block or a continuous assignment. The synthesis tool figures out the rest.

🤝 We Do — The Conversion Rules

Verilog-2001SystemVerilogWhen
wirelogicAlways, except for specific bidirectional/tri-state uses
reglogicAlways
wire [7:0]logic [7:0]Always
wire signedlogic signedAlways
wire [31:0] arr [0:15]logic [31:0] arr [0:15]Always — same semantics
The only exception: logic supports only single-driver semantics. If a signal has multiple drivers (tri-state bus, bidirectional I/O, or parallel combinational drivers), use wire or the 4-state bus types (tri, wand, wor). For 99% of RTL you'll write, single-driver is what you want — and logic actually catches accidental multiple drivers as a warning.

🧪 You Do — Modernize This Snippet

module uart_tx_ctrl (
    input  wire        clk, rst, start,
    input  wire  [7:0] data,
    output reg         tx_busy,
    output wire        tx_line
);
    reg  [3:0] state;
    reg  [9:0] shifter;
    wire       bit_tick;
    reg  [7:0] count;
    // ...
endmodule

Rewrite the declarations in SV style.

module uart_tx_ctrl (
    input  logic       clk, rst, start,
    input  logic [7:0] data,
    output logic       tx_busy, tx_line
);
    logic [3:0] state;
    logic [9:0] shifter;
    logic       bit_tick;
    logic [7:0] count;
    // ...
endmodule
Every type becomes logic. No decision fatigue. The synthesis tool infers flops, combinational logic, or wires based on how each signal is driven — not on how it's declared.
▶ LIVE DEMO

Modernize Your Debouncer

~4 minutes — Week 2 module, SV-ified

▸ COMMANDS

cd labs/week4_day13/ex2_sv_migrate/
cp ../../week2_day05/ex4_debounce/*.v .
sed -i 's/\\bwire\\b/logic/g; s/\\breg\\b/logic/g' debounce.v
mv debounce.v debounce.sv
iverilog -g2012 -o sim tb_debounce.v debounce.sv
./sim

▸ EXPECTED STDOUT

PASS: stable 1 passes through
PASS: stable 0 passes through
PASS: 1-cycle glitch filtered
PASS: bouncing settles after window
=== 8 passed, 0 failed ===

# same hardware, same cell count

▸ KEY OBSERVATION

A 3-character sed modernizes the whole file. Your Week 1-3 library can be SV-ified in minutes. The testbench still passes because behavior is identical.

🔧 The 4-State Value System (Unchanged)

logic keeps Verilog's 4-state value system: 0, 1, X, Z. You can still track uninitialized state (X) and high-impedance (Z) — nothing semantic changes.

ValueMeaningCommon in
0Logic lowEverything
1Logic highEverything
XUnknown / uninitializedSimulation of uninitialized FFs, X-propagation bugs
ZHigh-impedance (floating)Tri-state buses, inout ports
Note: If you need strictly 2-state (no X or Z) for a testbench counter or loop index, use bit, byte, int, shortint, longint. These are SV additions that skip the 4-state overhead in simulation (faster sim). For RTL, stick with logic.

🤖 Check the Machine

Ask AI: “I converted my Verilog to SystemVerilog by replacing wire and reg with logic. My testbench now fails with 'X' values on signals that used to work. What's wrong?”

TASK

AI diagnoses a post-migration X-value bug.

BEFORE

Predict: multiple drivers on a logic signal (allowed for wire, warned for logic).

AFTER

Strong AI mentions single-driver rule. Weak AI flails.

TAKEAWAY

The X-on-logic symptom is a classic multi-driver catch. AI that knows the single-driver rule diagnoses fast.

Key Takeaways

logic replaces both wire and reg. Use it for all RTL signals.

reg never meant “register.” The name was always misleading.

logic is single-driver — this catches multi-driver bugs at elaboration.

 Keeps Verilog's 4-state (0, 1, X, Z) semantics. 2-state types (bit, int) are for TB only.

One keyword, zero ambiguity. If it's a signal, it's logic.

🔗 Transfer

Intent-Based always_*

Video 3 of 4 · ~10 minutes

▸ WHY THIS MATTERS NEXT

You've used always @(*) and always @(posedge clk) all semester. Video 3 replaces them with always_comb, always_ff, and always_latch: variants that forbid the wrong thing at compile time. Same hardware, fewer bugs, better error messages.