Skip to main content

SystemVerilog let Construct – Reusable Named Expressions for RTL and Assertions

· loading · loading · ·
Verification RTL Design SystemVerilog Let Assertions Reusable Expressions Testbench RTL
Verification RTL Design
Axolot Logic
Author
Axolot Logic
Digital Design Engineer
Table of Contents
SystemVerilog Design Series - This article is part of a series.
Part 19: This Article

🧠 What is let in SystemVerilog?
#

The let construct in SystemVerilog allows you to define named expressions, similar to an inline macro or a parameterized function, but for expression reuse. It’s useful in both RTL and testbenches where a condition or formula is repeated multiple times.


🔧 Syntax
#

let <name> = <expression>;

Or with arguments:

let <name>(arg1, arg2, ...) = <expression using args>;

✅ Basic Example
#

let is_even(x) = (x % 2 == 0);

always_comb begin
  if (is_even(count)) begin
    // Do something when count is even
  end
end

🎯 Instead of repeating (x % 2 == 0) everywhere, you can reuse is_even().


🧪 Use Case in Assertions
#

let is very useful in assert or cover statements:

let valid_condition(a, b) = (a > 0) && (b < 100);

assert property (@(posedge clk) valid_condition(a, b) |-> ready);

📌 let improves readability and prevents duplication of complex expressions in assertions.


📦 let in Packages
#

You can define let expressions inside packages to reuse them across modules and testbenches:

package math_expr_pkg;
  let abs_diff(x, y) = (x > y) ? (x - y) : (y - x);
endpackage

And use it like this:

import math_expr_pkg::*;

logic [7:0] d = abs_diff(a, b);

🧬 Comparison: let vs function
#

Featureletfunction
SyntaxExpression onlyProcedural logic allowed
Use in asserts✅ Yes❌ Not allowed in assert property
Return typeInferred from expressionMust be declared
UsageInline, concise conditionsComplex operations, multi-line logic

🔥 Real-World Examples
#

1. Simplify Repeated Conditions
#

let handshake = (valid && ready);

always_comb begin
  if (handshake)
    do_transfer();
end

2. Parametric Formulas
#

let overflow_check(a, b, sum) = (sum < a) || (sum < b);

⚠️ Notes & Limitations
#

  • let is not synthesizable by all tools — check your synthesis tool’s support.
  • Use only for pure expressions — no side effects or procedural constructs.
  • Cannot contain begin-end, loops, or if statements — it’s not a function.

✅ Summary
#

BenefitExplanation
Improves readabilityGives names to complex expressions
Reusable expressionsUse across modules, assertions, testbenches
Assertion-friendlyUsable inside assert property, unlike function
LightweightNo overhead compared to function calls

The let construct brings elegance and reuse to your SystemVerilog code. Use it to define meaningful, compact, and reusable logic conditions — especially in assertions and testbenches where clarity matters most.


// === File: math_pkg.sv ===
package math_pkg;
  let abs_diff(x, y) = (x > y) ? (x - y) : (y - x);
  let is_even(n) = (n % 2 == 0);
endpackage
// === File: dut.sv ===
import math_pkg::*;

module dut(input logic [3:0] a, b,
           output logic [3:0] diff,
           output logic even);

  assign diff = abs_diff(a, b);
  assign even = is_even(a);

endmodule
// === File: tb_let_demo.sv ===
import math_pkg::*;

module tb_let_demo;

  logic [3:0] a = 4'd9, b = 4'd3;
  logic [3:0] diff;
  logic even;

  dut u_dut (.a(a), .b(b), .diff(diff), .even(even));

  initial begin
    #1;
    $display("abs_diff(%0d, %0d) = %0d", a, b, diff);
    $display("is_even(%0d) = %b", a, even);
    #5 $finish;
  end

endmodule

SystemVerilog Design Series - This article is part of a series.
Part 19: This Article

Related

SystemVerilog Clocking Block – Timing Control for Testbenches
· loading · loading
Verification Hardware Design SystemVerilog Clocking Block RTL Design Testbench UVM Timing
Verification Hardware Design
SystemVerilog Package – Reusable Types, Constants, and Functions
· loading · loading
Hardware Design Verification SystemVerilog Package Namespace Modular Design RTL UVM
Hardware Design Verification
SystemVerilog Interface – Modular Signal Grouping with modport and Clocking Blocks
· loading · loading
Hardware Design Verification SystemVerilog Interface Modport Testbench RTL Design Connectivity
Hardware Design Verification
SystemVerilog Randomization – $urandom, randcase, and randsequence
· loading · loading
Verification Testbench Design SystemVerilog Randomization Testbench $Urandom Randcase Randsequence Functional Verification
Verification Testbench Design
SystemVerilog Enum Data Type
· loading · loading
Hardware Design Verification SystemVerilog Enum FSM RTL Design Testbench Debugging
Hardware Design Verification
SystemVerilog Logic Data Type
· loading · loading
Hardware Design Verification SystemVerilog Logic RTL Design Verilog Synthesis Net vs Variable
Hardware Design Verification