Verilog Rules
UW–Madison ECE 552: Introduction to Computer Architecture · Spring 2026
This document outlines the specific Verilog subset permitted for course projects. The primary goal is to ensure all code is synthesizable and reflects actual hardware components rather than abstract simulation models. Additionally, SystemVerilog and advanced constructs are intentionally excluded to encourage you think about the underlying hardware, and improve compatibility with some tools.
This year, we're introducing a Verilog code checker that will make sure your submission follows these rules. There could be false positives - if you think your code is correct but the checker is complaining, please post on Piazza or send us an email.
Note: These rules only apply to the synthesizable processor. You can use any features you want for your testbench and verification, but do not upload this code to Gradescope.
Operator Restrictions
The following operators are allowed (and encouraged when appropriate):
| Operator | Example | Operator | Example |
|---|---|---|---|
| Bitwise AND | x & y |
AND Reduction | &x |
| Bitwise OR | x | y |
OR Reduction | |x |
| Bitwise XOR | x ^ y |
XOR Reduction | ^x |
| Bitwise XNOR | x ~^ y |
XNOR Reduction | ~^x |
| Bitwise Invert | ~x |
NAND Reduction | ~&x |
| Ternary | sel ? x : y |
NOR Reduction | ^|x |
| Equality | x == y |
Constant Shift Left | x << const |
| Inequality | x != y |
Constant Shift Right | x >> const |
| Concatenation | {x, y} |
Replication | {const{x}} |
| Binary Addition | x + y |
Binary Subtraction | x - y |
| Unary Negation | -x |
Greater Than | x > y |
| Less Than | x < y |
Greater Than or Equal | x >= y |
| Less Than or Equal | x <= y |
The following operators are not allowed as they synthesize poorly or do not map to any hardware.
| Operator | Example | Operator | Example |
|---|---|---|---|
| Logical AND | x && y |
Logical OR | x || y |
| Strict Equality | x === y |
Strict Inequality | x !== y |
| Multiplication | x * y |
Division | x / y |
| Modulo | x % y |
Power | x ** y |
| Shift Left (Variable) | x << y |
Wildcard Equality | x ==? y |
| Shift Right (Variable) | x >> y |
Wildcard Inequality | x !=? y |
| Arithmetic Shift Right | x >>> y |
In addition, do not use signed logic (including the $signed() function) as
it leads to weird behavior and is a common source of bugs.
Hint: If you need an "unsupported" operation like multiplication or a variable shift, you must build that component structurally using the allowed bitwise and boolean operators.
Constant Operations
Some operations are only allowed when operated on constant expressions. For example, shifts are allowed by constant amounts:
wire [7:0] x = 8'hAA;
wire [7:0] y = x << 2;
But not by variable amounts:
input wire [2:0] amount;
// ...
wire [7:0] x = 8'hAA;
wire [7:0] y = x << amount;
Builtin Tasks and Functions
In general, builtin functions like $display() and $assert() are not
synthesizable and disallowed. An exception is the $clog2() function when a
constant expression is passed as input - this can be used to calculate the
number of bits needed.
Behavioral Logic & Control Flow
Many control flow constructs synthesize poorly or are not allowed: for,
while, do...while, repeat, forever, join, wait, disable.
Case statements are allowed as an alternative to nested ternary expressions. However, they must be fully specified and have a default case to avoid inferring a latch.
Conditional statements (if/else) are only allowed within clocked blocks to
infer registers:
reg [7:0] x;
always (posedge i_clk) begin
if (i_rst)
x <= 8'h00;
else
x <= x + 1;
end
They are not allowed in combinational logic (use a case statement or ternary instead):
reg [7:0] x;
always @(*) begin
if (i_sel)
x = 8'hAA;
else
x = 8'hBB;
end
Timing & Event Control
Explicit timing controls are not allowed in synthesizable hardware, as timing is governed by the system clock.
Simulation Timing
Statements involving delays (#), cycle delays (##), or repeated events are not allowed.
Signal Events
Sensitivity lists may only use posedge or implicit @(*) signals.
The negedge trigger and iff conditions on events are not allowed.
Literals & Types
The following types and expressions are not allowed: real numbers, string literals, time literals, and null.
Class-based expressions (e.g., new, copy) are strictly for simulation and cannot be used.