Supported SystemVerilog subset

Quick reference for the educational simulator — one synthesizable module per design.

1Module structure

module name ( /* ANSI ports */ );
  // net / variable declarations
  // assign, always_comb, always_ff
endmodule

Only the first module in the file is parsed.

2ANSI port list

module add (
  input  logic [7:0] a, b,
  input  logic signed [3:0] d,
  output wire  [8:0] s
);
  • Directions: input, output
  • Optional type logic / wire / int, optional signed, optional [msb:lsb]

3Net declarations

logic [3:0] cnt, nxt;
wire  carry;
logic signed [7:0] acc;

A declaration gives a name and an optional width.

4Continuous assignments

assign a = b | c;
assign x[3:0] = y[7:4];
assign {cout, sum} = a + b;

Concatenation targets are also allowed with = and <= in procedural blocks. assign targets need constant indexes.

4Concatenation & replication

{a, b[3:0], 2'b01}
{4{bit}}      {W{1'b0}}
  • Operands are self-determined; result is unsigned
  • Unsized constants (e.g. 5) inside {} are errors
  • Replication count N: positive constant expression

5Combinational blocks

always_comb begin
  y = '0;
  if (en) y = a;
  else    y = b;
end
  • Blocking assignments =, if/else, case, for
  • Shorthands: x++ x-- ++x --x, += -= *= &= |= ^= <<= >>=
  • Not sensitive to signals it writes itself, so sum = sum + a[i] works

6Sequential blocks

always_ff @(posedge clk or negedge rst_n)
  if (!rst_n) q <= '0;
  else        q <= d;
  • Non-blocking <= only; if/else, case, for, begin/end
  • Event list with or or ,: the first event is the clock (posedge); further events are asynchronous
  • Cycle t: clock edge (t > 0) → inputs change → logic settles → values sampled

10Case statements

unique case (sel)
  2'd0, 2'd1: y = a;
  2'd2:       begin y = b; z = 1; end
  default:    y = '0;
endcase

casez (req)  4'b1???: g = 3; ... endcase
  • case, casez (?/z = don't care), casex (also x); in always_comb and always_ff
  • Item statement: assignment, if, case, begin…end or ;
  • First matching item wins; compared at the widest width, signed only if all are signed
  • unique / priority accepted but not checked

8Enumerations

typedef enum logic [1:0]
  {IDLE, RUN, DONE = 2'd3} state_t;
state_t state, next;
enum logic {OFF, ON} mode;  // anonymous
  • Base type: logic/bit [msb:lsb] or int (default, 32 bits)
  • Members count up from 0 or from the previous value; usable as constants in expressions
  • Waveform shows enum signals by member name

9Signed values

logic signed [7:0] a;   int i;
8'sd5  4'sb1111  $signed(x)  $unsigned(x)
  • Plain decimal literals are signed; int is signed 32-bit
  • An expression is signed only if all operands are signed; signed expressions sign-extend
  • Part-selects and comparison results are unsigned; < <= > >= compare signed if both sides are
  • Waveform shows signed decimals; stimulus accepts negative values

11Packed arrays

logic [3:0][7:0] w;   // 4 bytes = 32-bit vector
w[2]  w[2][3:0]  w[2][7]  w[2:1]
w[i] <= d;
  • Leftmost dimension is outermost; also for ports, signed, int
  • One select per dimension, part-select last; part-select bounds constant
  • Variable indexes allowed (also on procedural targets); out of range: read 0, write ignored. Constant out of range is an error
  • Non-blocking targets resolve their index when executed
  • Elements of a signed packed array are unsigned (IEEE 1800 §7.4.1)

13Unpacked arrays (memories)

logic [7:0] mem [0:255];
logic [7:0] regs [8];       // = [0:7]
logic [7:0] rom [0:3] =
  '{8'h11, 8'h22, 8'h33, 8'h44};
y = mem[addr][7:4];  regs[i] <= d;
  • Any element type, one unpacked dimension; initializer with one constant per element
  • Constant or variable index, then element selects; out of range: read 0, write ignored
  • No array ports, mem[a:b] slices, 2nd unpacked dimension or whole-array use
  • Waveform: ≤16 elements show every row; larger arrays show chosen elements (default first 4), set in the Arrays panel, e.g. 0-3, 10, 200-203 or all (max 256)

12int and for loops

always_comb begin
  ones = 0;
  for (int i = 0; i < 8; i++)
    ones += a[i];
end
  • int / integer: signed 32-bit (variables, ports, loop variables)
  • Init: int|integer|logic [..] i = e (local) or i = e (existing variable)
  • Step: i++ i-- ++i --i i += e i -= e i = e; max 65 536 iterations
  • Loop variables are internal: no waveform row, do not re-trigger logic

14Parameters

module m #(parameter W = 8, N = 4,
           localparam M = W * 2) (...);
localparam [7:0] K = 8'hA5;
localparam int N2 = 4, M2 = N2 * 2;
  • Keyword carries over in the list; values are constant expressions of earlier parameters
  • Types: int, logic/bit [signed] [range], signed [range], [range]; untyped takes its value's type (P = 5 → signed 32-bit)
  • Usable in ranges, array sizes, selects, replication, enum values, case items, loops
  • No overrides (single module): defaults are always used
  • Fill literals '0, '1 (no 'x, 'z)

7Comments & stimulus

// line comment
/* block comment (not nested) */
/* stimulus 16 ... */

A /* stimulus <cycles> … */ block defines input waveforms for the wave viewer.

15Testbench export

The Testbench button in the wave viewer generates tb_<module>.sv:

  • Ports, header parameters #(.W(..)), clock rising at 10t
  • Input waveform applied at 10t+1; every output checked at 10t+9
  • x/z bits not compared; PASS/FAIL summary; $dumpvars for a VCD
  • Without self-check: stimulus only, $finish after the last cycle
  • Verified with Icarus Verilog for all examples

Operator precedence (highest → lowest)

GroupOperators
1Primaryidentifiers, constants, (e), a[i], a[msb:lsb], {a, b}, {N{a}}
2Unary~ ! -, reduction & ~& | ~| ^ ~^ ^~, $signed(), $unsigned()
3Multiplicative* (/ % ** not supported)
4Additive+ -
5Shift<< >> <<< >>>
6Relational< <= > >=
7Equality== !=
8Bitwise AND&
9Bitwise XOR^ ~^ ^~
10Bitwise OR|
11Logical AND&&
12Logical OR||
13Conditionalc ? a : b (right-associative)

Not supported

Structural

  • Module instantiation, multiple modules
  • generate blocks
  • assign with delays
  • reg, tri and other net kinds

Behavioral

  • Plain always, initial
  • while, repeat, forever
  • / % ** operators

Types & ports

  • inout, var, array ports
  • bit, byte, shortint… as variable types
  • 'x, 'z fill literals; parameter overrides