Johannes
Johannes

Reputation: 43

Subtraction in verilog

I am using code like this:

reg [16:0] result;
reg gradient;

result = (gradient) ? (result+1) : (result-1);

My problem is at result = 7 and gradient = 0. Then I get result = 4.

It doesnt appear at result = 8 and gradient = 1 or 0 and any other combination. But at result = 13 and gradient = 1 to result = 18.

Binary notation

7-1 = 0111 - 0001 = 0110 = 6
7-1 = 0111 - 0001 = 0010 = 4

13+1 = 1101 + 0001 =   1110 = 14
13+1 = 1101 + 0001 = 1 0010 = 18

Anybody has an idea why this strange behavior comes up? I tried to eliminate all other code lines dealing with result and gradient for more than needed.

Upvotes: 0

Views: 1489

Answers (1)

mcleod_ideafix
mcleod_ideafix

Reputation: 11428

The strange behaviour comes from a combinational loop you have created in your code. You have a 17 bit two channel multiplexer which outputs the value gradient, which in turn is derived to both an incrementer and a decrementer, whose outputs go to the inputs of the multiplexer. This causes gradient to change its value very fast, with only the delay introduced by the combinational circuit that has been inferred. In a simulation, with no delays, the output of such combinational loops is undetermined.

Either you use another variable to hold the output of the multiplexer...

reg [16:0] result, result2;
reg gradient;

always @* begin
  result2 = (gradient) ? (result+1) : (result-1);
end

Or you use a clocked register to change its value on each clock cycle (which is most probably what you were looking for), I presume:

reg [16:0] result;
reg gradient;

always @(posedge clk) begin
  result <= (gradient) ? (result+1) : (result-1);
end

Upvotes: 1

Related Questions