Write, Run & Share Verilog code online using OneCompiler's Verilog online editor for free. It's one of the robust, feature-rich online editors for Verilog. Getting started with the OneCompiler's Verilog online editor is really simple and pretty fast. The editor shows sample boilerplate code when you choose language as 'Verilog' and start writing code to learn and test online without worrying about tedious process of installation.
Verilog is a hardware description language (HDL) used to model and design digital circuits and systems. It allows designers to describe hardware at various levels of abstraction, from gate-level to behavioral. Verilog is widely used for FPGA and ASIC design, simulation, and verification in the semiconductor industry.
Modules are the fundamental building blocks in Verilog, defining inputs, outputs, and the logic between them. Every Verilog design starts with a module definition. Modules can be instantiated inside other modules to create hierarchical designs.
// Basic module
module hello;
initial begin
$display("Hello, World!");
$finish;
end
endmodule
// Module with ports
module adder(
input [3:0] a, b, // 4-bit inputs
output [4:0] sum // 5-bit output
);
assign sum = a + b;
endmodule
// Module instantiation
module top;
reg [3:0] x, y;
wire [4:0] result;
adder add1(.a(x), .b(y), .sum(result)); // Named connection
endmodule
Verilog has two main data types: wire for continuous connections and reg for storing values. Vectors define multi-bit signals with [MSB:LSB] notation. Number literals use the format <size>'<base><value>.
// Wires and regs
wire [7:0] data; // 8-bit wire
reg [7:0] counter; // 8-bit register
reg [15:0] memory [0:255]; // Array of 256 16-bit values
// Parameters
parameter WIDTH = 8;
localparam SIZE = 256; // Local, can't be overridden
// Number formats: b(binary), o(octal), d(decimal), h(hex)
4'b1010 // 4-bit binary: 10
8'd255 // 8-bit decimal
16'hFF00 // 16-bit hex
8'bxxxx_zzzz // x=unknown, z=high-impedance
Verilog supports arithmetic, logical, bitwise, relational, shift, and reduction operators. The conditional operator ?: provides inline if-else. Concatenation {} and replication {n{}} combine signals.
// Arithmetic: +, -, *, /, %
// Bitwise: &(and), |(or), ^(xor), ~(not)
// Logical: &&, ||, !
// Relational: ==, !=, <, >, <=, >=
// Case equality: === (handles x/z), !==
// Shift: <<, >>, <<<, >>>
assign y = a & b; // Bitwise AND
assign y = sel ? a : b; // Conditional (mux)
// Reduction (operate on all bits of vector)
assign all_ones = &a; // AND all bits
assign parity = ^a; // XOR all bits
// Concatenation and replication
assign y = {a, b}; // Concatenate
assign y = {4{a}}; // Replicate 4 times
Continuous assignments model combinational logic where outputs update immediately when inputs change. The assign statement creates permanent connections that execute concurrently.
module combinational(input a, b, c, sel, output y, z);
assign y = a & b; // AND gate
assign z = sel ? a : b; // 2:1 mux
assign bus = enable ? data : 8'bz; // Tri-state
// Priority encoder
assign out = (sel == 2'b00) ? 4'b0001 :
(sel == 2'b01) ? 4'b0010 :
(sel == 2'b10) ? 4'b0100 : 4'b1000;
endmodule
Procedural blocks (always, initial) contain sequential statements. Use always @(*) for combinational logic and always @(posedge clk) for sequential. Use non-blocking <= for sequential logic and blocking = for combinational.
// Combinational (always @*)
always @(*) begin
if (sel) y = a;
else y = b;
end
// Sequential (posedge clk)
always @(posedge clk or posedge reset) begin
if (reset)
counter <= 8'b0;
else
counter <= counter + 1;
end
// Initial block (simulation only)
initial begin
clk = 0;
forever #5 clk = ~clk; // Clock generation
end
// Blocking (=) vs non-blocking (<=)
always @(posedge clk) begin
a <= b; // Non-blocking: all execute "simultaneously"
c <= a; // Gets OLD value of a
end
Verilog provides if-else, case, and loop statements for control flow. Case statements are commonly used for state machines and decoders. Loops are primarily used in testbenches and generate blocks.
// If-else
if (sel == 2'b00) y = a;
else if (sel == 2'b01) y = b;
else y = c;
// Case
case (sel)
2'b00: y = a;
2'b01: y = b;
default: y = 0;
endcase
// casez (z as don't care)
casez (opcode)
4'b1???: y = op_high; // Matches 1xxx
default: y = op_low;
endcase
// Loops (mainly testbench/generate)
for (i = 0; i < 10; i = i + 1) begin
$display("i = %d", i);
end
repeat (5) @(posedge clk); // Wait 5 clock cycles
Flip-flops and registers are modeled using always @(posedge clk) with non-blocking assignments. Resets can be synchronous (inside clock block) or asynchronous (in sensitivity list).
// D Flip-Flop with async reset
module dff(input clk, reset, d, output reg q);
always @(posedge clk or posedge reset) begin
if (reset) q <= 1'b0;
else q <= d;
end
endmodule
// N-bit Register with enable
module register #(parameter WIDTH = 8)(
input clk, reset, load,
input [WIDTH-1:0] d,
output reg [WIDTH-1:0] q
);
always @(posedge clk) begin
if (reset) q <= 0;
else if (load) q <= d;
end
endmodule
// Shift Register
always @(posedge clk) begin
q <= {q[6:0], shift_in}; // Shift left, insert at LSB
end
State machines use case statements within clocked always blocks. A common pattern separates next-state logic (combinational) from state register (sequential).
module fsm(input clk, reset, start, done, output reg busy);
localparam IDLE = 2'b00, RUN = 2'b01, STOP = 2'b10;
reg [1:0] state, next_state;
// State register
always @(posedge clk or posedge reset) begin
if (reset) state <= IDLE;
else state <= next_state;
end
// Next state logic
always @(*) begin
next_state = state;
case (state)
IDLE: if (start) next_state = RUN;
RUN: if (done) next_state = STOP;
STOP: next_state = IDLE;
endcase
end
// Output logic
always @(*) begin
busy = (state == RUN);
end
endmodule
Testbenches verify design functionality using initial blocks, delays, and system tasks. They instantiate the design under test (DUT) and apply stimulus.
module testbench;
reg clk, reset;
reg [7:0] data_in;
wire [7:0] data_out;
// Instantiate DUT
my_design dut(.clk(clk), .reset(reset), .data_in(data_in), .data_out(data_out));
// Clock generation
initial begin
clk = 0;
forever #5 clk = ~clk;
end
// Stimulus
initial begin
reset = 1; data_in = 0;
#20 reset = 0;
#10 data_in = 8'hAA;
#10 data_in = 8'h55;
#50 $finish;
end
// Waveform dump
initial begin
$dumpfile("wave.vcd");
$dumpvars(0, testbench);
end
// Monitor
initial $monitor("Time=%0t data_out=%h", $time, data_out);
endmodule
System tasks provide simulation control, I/O, and debugging. Format specifiers: %d(decimal), %h(hex), %b(binary), %t(time).
// Display
$display("Value: %d, Hex: %h", val, val);
$monitor("a=%b b=%b", a, b); // Print on any change
// Simulation control
$finish; // End simulation
$stop; // Pause simulation
$time; // Current simulation time
// File I/O
integer file;
file = $fopen("output.txt", "w");
$fwrite(file, "Data: %d\n", data);
$fclose(file);
// Memory initialization
$readmemh("data.hex", memory);
$readmemb("data.bin", memory);
// Random
$random % 100; // Random 0-99
$urandom_range(10, 0); // Random in range