Combinational
always @(*) begin
// defaults
y = 0;
if (condition)
y = a;
else
y = b;
end
Flip-flop
always @(posedge clk) begin
q <= d;
end
Flip-flop + async reset
always @(posedge clk or posedge rst) begin
if (rst)
q <= 0;
else
q <= d;
end
Counter
always @(posedge clk or posedge rst) begin
if (rst)
count <= 0;
else
count <= count + 1'b1;
end
FSM
always @(posedge clk or posedge rst) begin
if (rst)
state <= IDLE;
else
state <= next_state;
end
always @(*) begin
next_state = state;
case (state)
IDLE: begin
if (start)
next_state = RUN;
end
RUN: begin
if (done)
next_state = IDLE;
end
default:
next_state = IDLE;
endcase
end
Testbench
module tb;
reg clk;
reg rst;
wire y;
dut uut (
.clk(clk),
.rst(rst),
.y(y)
);
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
rst = 1;
#20;
rst = 0;
#100;
$finish;
end
endmodule
One-page mental model
Think of Verilog .v as five major things:
VERILOG
│
┌───────────┼───────────┐
│ │ │
STRUCTURE HARDWARE SIMULATION
│ │ │
module assign initial
ports always #delay
wire reg $display
parameter case @(...)
if $finish
clock
FSM
RAM
And the single most important distinction:
COMBINATIONAL
↓
always @(*)
↓
blocking =
↓
assign every output
SEQUENTIAL
↓
always @(posedge clk ...)
↓
nonblocking <=
↓
usually represents flip-flops
If you're using Icarus Verilog + GTKWave, this cheat sheet is also enough to cover the bulk of the Verilog you'll encounter in typical digital-logic/FPGA coursework.