Every listing in this course is built from a few small forms. This page names them once, runs them in one short program, and sends you back to the lesson you came from. You do not need to memorize it; keep it open beside the first listings and look things up.
A bit is a wire that carries 0 or 1. In simulation it can also be x (unknown) or z (not driven).
logic clk; declares one bit. logic [3:0] count; declares a bus of four bits. The numbers in brackets name the top and bottom positions, so [3:0] means bit 3 down to bit 0.
count[3] is the top bit and count[0] the bottom one. A 4-bit bus holds the values 0 to 15; one more than 15 wraps back to 0, because the fifth bit does not exist.
A literal such as 4'd14 has three parts: the width in bits (4), a base letter after the apostrophe, and the value. Writing the width keeps a number from silently becoming the wrong size.
Written | Reads as | Value |
|---|---|---|
| 4 bits, decimal 0 | 0 |
| 4 bits, decimal 14 | 14 |
| 4 bits, binary 1010 | 10 |
| 4 bits, hexadecimal A | 10 |
| 1 bit, binary 1 | 1 |
Operator | Meaning | Note |
|---|---|---|
| add | result wraps at the width of the bus |
| equal, not equal | an |
| equal, not equal, comparing | testbenches use |
| not, and, or |
|
| less than or equal in an expression; non-blocking assignment as a statement | see the next section |
= is a blocking assignment: it takes effect at once, and the next statement sees the new value. Testbenches use it for stimulus and setup.
<= as a statement is a non-blocking assignment: every right-hand side is read first, and the new values appear together at the end of the time step. Clocked design blocks use it, which is how a register samples its input on the edge and updates after the edge.
The usual split: inside a clocked always_ff block you write <=; in a testbench initial block you write =.
always_ff @(posedge clk) begin ... end runs once on every rising edge of clk. Whatever it assigns with <= becomes the new register value. That is a flip-flop.
always #5 clk = ~clk; flips the clock every 5 time units, so the period is 10. ~ flips every bit of a value.
initial begin ... end runs once from time zero. It is simulation-only and is how a testbench drives inputs. @(posedge clk) inside it waits for the next rising edge; #1 waits one time unit; $display(...) prints.
Inside an if / else if chain, order is priority: the first condition that is true wins and the rest are skipped. That is why the course lists reset first, then clear, then count. Order of separate non-blocking assignments, by contrast, does not matter: they all update together.
Read the listing top to bottom, then check each printed line against what you expect. It declares a 4-bit bus, writes the number 10 three ways, reads single bits, and clocks a counter past 15.
module primer;
logic [3:0] count; // four bits: count[3] is the top bit, count[0] the bottom bit
logic clk = 0;
logic [3:0] a, b;
always #5 clk = ~clk; // flip the clock every 5 time units
// a clocked block: runs on every rising edge of clk
always_ff @(posedge clk) begin
count <= count + 4'd1; // non-blocking: the new value appears after the edge
end
initial begin
count = 4'd14; // blocking: takes effect at once
a = 4'b1010; // the same number three ways:
b = 4'hA;
$display("4'b1010 = %0d, 4'hA = %0d, equal: %0d", a, b, a == b);
$display("count[3] = %0d, count[0] = %0d", count[3], count[0]);
@(posedge clk); #1 $display("after edge 1: count = %0d", count);
@(posedge clk); #1 $display("after edge 2: count = %0d (4 bits wrap 15 -> 0)", count);
$finish;
end
endmoduleThis was compiled and run with Icarus Verilog 13.0 on macOS:
# captured terminal output
$ iverilog -g2012 -Wall -o primer.vvp primer.sv
$ vvp primer.vvp
4'b1010 = 10, 4'hA = 10, equal: 1
count[3] = 1, count[0] = 0
after edge 1: count = 15
after edge 2: count = 0 (4 bits wrap 15 -> 0)The first line shows 4'b1010 and 4'hA are the same number: 10, so the comparison prints 1.
The second line shows count starting at 14 is 1110: bit 3 is 1 and bit 0 is 0.
The last two lines show the clocked block adding 1 on each edge, and 15 plus 1 wrapping to 0 because four bits cannot hold 16.