1

I am trying a simple code to compare an input to some value(threshold) and tried using the if and else condition statements to assign a variable to either 0 or 1 depending of the variable crossing the threshold or not. But, in this case I am always getting same single value for different inputs. I am new to verilog and trying to write an algorithm for a different application, in which this is my first step. Thanks in advance.

module makebig(a,z);
input signed [15:0]  a;
output reg z;
initial
begin
if (a<16'b0000000000000000) begin
 z<=1;
end
else  begin
 z<=0;
end

end
endmodule

Now the test bench of it.

module makebig_tb();

reg  signed [15:0] a;

wire z;

makebig uut(.a(a),.z(z));
initial
begin
a=16'b0100000000000000;
#5 a=16'b000000000000101;
#5 a=-2;
end
initial
begin
$monitor("a=%b,z=%b",a,z);
end
end module

I don't understand why it is not working. The output for this is something like this...

a=0100000000000000,z=0;
a=0000000000000101,z=0;
a=1111111111111110,z=0;
CiaPan
  • 9,381
  • 2
  • 21
  • 35
  • Not my area, but.... Are you sure the constant in `if` is signed? May be the comparison is evaluated in unsigned numbers despite `input signed` declaration.... – CiaPan Jul 14 '21 at 05:46
  • Yes, in the assignment of the variable a, I have mentioned 'signed'. I even tried taking the half of 2^16 as the threshold but, still not the expected results. – Abhinav kumar Jul 14 '21 at 05:58
  • 2
    Your `if` statement only gets executed once at time 0. – dave_59 Jul 14 '21 at 06:20
  • @dave_59 I didn't understand. Could you elaborate ? – Abhinav kumar Jul 14 '21 at 08:38
  • Does this: [**Why is this verilog relational statement returning true?**](https://stackoverflow.com/questions/21340093/) answer your question? – CiaPan Jul 14 '21 at 11:32
  • I've seen you used `signed` to declare `a`, but I did not ask about `a` but rather about _the constant_ you compare `a` to. In other words, are you sure `16'b0000000000000000` is signed? The answers at the question I link in the comment above suggest it should be unsigned, and the whole comparison is done as unsigned. And _none_ unsigned value is less than zero, hence your constant output of `z` equal `0`. – CiaPan Jul 14 '21 at 11:42
  • Does this answer your question? [Why is this verilog relational statement returning true?](https://stackoverflow.com/questions/21340093/why-is-this-verilog-relational-statement-returning-true) – CiaPan Jul 14 '21 at 11:44

1 Answers1

2

There are two errors here, and both of them have been pointed out in the comments:

  1. You are only running the comparison once (initial begin). Replace this with always @(*) begin to run it each time one of the inputs changes

  2. A comparison with an unsigned constant will result in the whole comparison being unsigned. Replace 16'b0000000000000000 with $signed(16'b0000000000000000)

This produces the expected output

a=0100000000000000,z=0;
a=0000000000000101,z=0;
a=1111111111111110,z=1;
sjw
  • 100
  • 5