Verilog Comparator

Verilog Comparator

I'm newbie to a verilog.

I did a lot of research, and finally wrote this code, but it seems to not work.

Can anyone fix it for me?

module comparator();
    reg[3:0] a, b;
    wire[1:0] equal, lower, greater;    

    if (a<b) begin

        equal = 0;
        lower = 1;
        greater = 0;
    end

    else if (a==b) begin
        equal = 1;
        lower = 0;
        greater = 0;
    end

    else begin
        equal = 0;
        lower = 0;
        greater = 1;
    end;

    initial begin
                $monitor($time, 
                         "a=%b, b=%b, greater=%b, equals=%b, lower=%b",
                          a, b, greater, equal, lower);

                a=9; b=10;
                #100 $display ("\n", $time, "\n");
        end
endmodule 
1

2 Answers

Behavioural procedures must be enclosed within an always block, like this: Also, your module needs inputs and outputs. A more correct version would be like this:

module comparator (
    input wire [3:0] a,
    input wire [3:0] b,
    output reg equal,
    output reg lower,
    output reg greater
    );

    always @* begin
      if (a<b) begin
        equal = 0;
        lower = 1;
        greater = 0;
      end
      else if (a==b) begin
        equal = 1;
        lower = 0;
        greater = 0;
      end
      else begin
        equal = 0;
        lower = 0;
        greater = 1;
      end
    end
endmodule

I suggest reading some tutorial about behavioral modelling with Verilog, because you missed a lot of points:

  • How to correctly define inputs and outputs in a module
  • What things can be wires and what things should be regs
  • The use of always @* to model combinational logic

And most important: how to write a test bench. Test benches are written as module with no inputs and outputs) that instantiates your UUT (unit under test), provides inputs, read outputs and check whether they are valid.

module testcomp;
    reg [3:0] a, b;
    wire eq, lw, gr;

    comparator uut (
       .a(a),
       .b(b),
       .equal(eq),
       .lower(lw),
       .greater(gr)
    );

    initial begin
      a = 0;
      repeat (16) begin
        b = 0;
        repeat (16) begin
          #10;
          $display ("TESTING %d and %d yields eq=%d lw=%d gr=%d", a, b, eq, lw, gr);
          if (a==b && eq!=1'b1 && gr!=1'b0 && lw!=1'b0) begin
            $display ("ERROR!");
            $finish;
          end
          if (a>b && eq!=1'b0 && gr!=1'b1 && lw!=1'b0) begin
            $display ("ERROR!");
            $finish;
          end
          if (a<b && eq!=1'b1 && gr!=1'b0 && lw!=1'b1) begin
            $display ("ERROR!");
            $finish;
          end
          b = b + 1;
        end
        a = a + 1;
      end
      $display ("PASSED!");
      $finish;
    end
endmodule

You can play with this example at EDAPlayGround using this link:

2

Without always block:

module comparator (
  input wire [3:0] a,
  input wire [3:0] b,
  output reg equal,
  output reg lower,
  output reg greater
);
assign equal = (a===b);
assign lower = (a<b)?1'b1:1'b0;
assign greater = (a>b)1'b1:1'b0;
end

Be careful, you need to consider 'X' and 'Z', use "===" instead of "=="

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Marcus Vance
Author

Marcus Vance

Marcus Vance is a cybersecurity auditor and technology writer dedicated to educating the public about online safety, data privacy regulations, enterprise security, and emerging cyber threats.