Verilog Code for Comparator: Syntax and Example
A comparator in Verilog compares two inputs and outputs signals indicating if one is greater, less, or equal to the other. Use
always block with if-else statements or continuous assignments to implement it.Syntax
A basic comparator compares two inputs and sets output flags for greater than, less than, or equal conditions. The always block triggers on input changes. Use if-else to check conditions and assign outputs.
Parts explained:
input [n-1:0] a, b;: Inputs to compare.output reg gt, lt, eq;: Outputs for greater than, less than, equal.always @(*): Runs whenever inputs change.if (a > b): Checks ifais greater.
verilog
module comparator(
input [3:0] a,
input [3:0] b,
output reg gt,
output reg lt,
output reg eq
);
always @(*) begin
if (a > b) begin
gt = 1;
lt = 0;
eq = 0;
end else if (a < b) begin
gt = 0;
lt = 1;
eq = 0;
end else begin
gt = 0;
lt = 0;
eq = 1;
end
end
endmoduleExample
This example compares two 4-bit inputs a and b. It sets gt high if a is greater, lt high if a is less, and eq high if they are equal.
It shows how to write a simple comparator module that can be tested in simulation.
verilog
module comparator(
input [3:0] a,
input [3:0] b,
output reg gt,
output reg lt,
output reg eq
);
always @(*) begin
if (a > b) begin
gt = 1;
lt = 0;
eq = 0;
end else if (a < b) begin
gt = 0;
lt = 1;
eq = 0;
end else begin
gt = 0;
lt = 0;
eq = 1;
end
end
endmodule
// Testbench
module testbench;
reg [3:0] a, b;
wire gt, lt, eq;
comparator comp(.a(a), .b(b), .gt(gt), .lt(lt), .eq(eq));
initial begin
a = 4'd5; b = 4'd3;
#10;
$display("a=%d b=%d gt=%b lt=%b eq=%b", a, b, gt, lt, eq);
a = 4'd2; b = 4'd7;
#10;
$display("a=%d b=%d gt=%b lt=%b eq=%b", a, b, gt, lt, eq);
a = 4'd4; b = 4'd4;
#10;
$display("a=%d b=%d gt=%b lt=%b eq=%b", a, b, gt, lt, eq);
$finish;
end
endmoduleOutput
a=5 b=3 gt=1 lt=0 eq=0
a=2 b=7 gt=0 lt=1 eq=0
a=4 b=4 gt=0 lt=0 eq=1
Common Pitfalls
Common mistakes when writing comparators include:
- Not using
regtype for outputs assigned insidealwaysblocks. - Forgetting to cover all conditions, which can cause latches.
- Using blocking assignments (
=) incorrectly in sequential logic. - Not using
always @(*)for combinational logic, causing simulation mismatches.
Always ensure all outputs are assigned in every branch to avoid unintended memory elements.
verilog
module wrong_comparator(
input [3:0] a,
input [3:0] b,
output gt,
output lt,
output eq
);
// Outputs are wires by default and assigned in always block - wrong
always @(*) begin
if (a > b) begin
gt = 1; // Error: gt is wire, cannot assign here
lt = 0;
eq = 0;
end
end
endmodule
// Correct way
module correct_comparator(
input [3:0] a,
input [3:0] b,
output reg gt,
output reg lt,
output reg eq
);
always @(*) begin
if (a > b) begin
gt = 1;
lt = 0;
eq = 0;
end else if (a < b) begin
gt = 0;
lt = 1;
eq = 0;
end else begin
gt = 0;
lt = 0;
eq = 1;
end
end
endmoduleQuick Reference
Tips for writing Verilog comparators:
- Use
always @(*)for combinational logic. - Declare outputs as
regif assigned insidealwaysblocks. - Cover all conditions to avoid latches.
- Use
if-elseor ternary operators for clarity. - Test with a simple testbench to verify behavior.
Key Takeaways
Use an always @(*) block with if-else statements to compare inputs in Verilog.
Declare outputs as reg when assigning inside always blocks to avoid errors.
Cover all comparison cases to prevent unintended latches in hardware.
Test your comparator with different input values using a testbench.
Avoid assigning to wire outputs inside always blocks; use reg instead.