SystemVerilog Review
SystemVerilog Review
Integer Representation
- Unsigned integers: Standard binary (base 2) representation
- With $n$ bits, can represent integers $0$ to $2^n - 1$
- Signed integers: Two's Complement representation
- Most significant bit (MSB) has negative weight $(-2^{(n-1)})$
- With $n$ bits, can represent integers $-2^{(n-1)}$ to $2^{(n-1)} - 1$
- MSB functions as sign bit (0 = positive, 1 = negative)
- Negation: Bitwise complement + 1 (e.g.,
~x + 1
)
Constants & Data Types
- Multi-bit constants format:
<n>'<s><b>#...#
<n>
= width (unsized by default)
<s>
= signed designation (omit or 's')
<b>
= radix/base (d=decimal, h=hex, b=binary, o=octal)
- Case-insensitive, underscores allowed for readability
Operators
- Arithmetic:
+
, -
, *
, /
, %
(modulus), **
(exponentiation)
- Shift:
>>
, <<
, >>>
(arithmetic right shift)
- Relational:
>
, <
, >=
, <=
- Equality:
==
, !=
, ===
(case equality)
- Bitwise:
~
, &
, |
, ^
- Logical:
!
, &&
, ||
- Ternary operator:
select ? <then_expr> : <else_expr>
Bit Manipulation
- Concatenation:
{sig, ..., sig}
- Replication:
{n{m}}
(repeats value m, n times)
Parameters
- Named constants with default values
- Format for parameterized modules:
module <name> #(<parameter list>) (<port list>);
- Example:
#(parameter N = 8)
Modules & Instantiation
- Modules are the building blocks of design hierarchy
- Ports define connections between module and environment
- Port direction:
input
, output
, inout
- Module instantiation:
<type> <name> (<port connections>);
- Connection styles:
- Positional:
my_tri(out, in, enable);
- Named/explicit:
my_tri(.out(out), .in(in), .enable(enable));
- Implicit:
my_tri(.out, .in, .enable);
(when port/signal names match)
Procedural Blocks
- Always blocks: Used for behavioral code, run repeatedly based on sensitivity list
- SystemVerilog variants:
always_comb
: For combinational logic (auto sensitivity list)
always_latch
: For latch-based logic (auto sensitivity list)
always_ff
: For sequential/clocked logic (must specify sensitivity)
- Initial blocks: Run once at time zero (for simulation/test benches only)
Latches vs. Flip-Flops
- Both store information, but operate differently:
- Latches are asynchronous (level-sensitive)
- Flip-flops are edge-triggered (synchronous)
- Beware of inadvertent latches from incomplete assignments
Case Statements
- Create combinational logic inside always blocks
- Must include
default
case to avoid incomplete assignments
- Each case has an implied break
Finite State Machines (FSMs)
- A way to conceptualize computation over time using state transition diagrams
- Components:
- State register (sequential logic)
- Next state logic (combinational)
- Output logic (combinational)
- Implementation notes:
- States require binary encoding (use enum for readability)
- Reset can be synchronous or asynchronous
- State logic can be one combined block or two separate blocks
Moore vs. Mealy FSMs
- Moore: Outputs depend only on current state
- Output changes synchronously with state changes
- Mealy: Outputs depend on state and inputs
- Input changes can cause immediate output changes
Test Benches
- Special modules for simulation only
- Create simulated inputs for FPGA testing
- Control timing of signals using:
- Delay:
#<time>
- Edge-sensitive:
@(<pos/neg>edge <signal>)
- Level-sensitive:
wait(<expression>)
- Output test results using
$display
and related system tasks
- Format specifiers for output:
%h
(hex), %d
(decimal), %b
(binary), etc.