0

I am having a strange problem with Verilog HDL. I found in my code that if I multiply a variable by two, but then assign that value to the same variable, it gets all messed up. Sometimes, the simv program even crashes. I originally needed to do this, because I had a for loop for shifting or rotating a certain amount. But, then I found that not only shifting the same variable did not work, but also, addition, subtraction, multiplication, or division does not work either.

So in my code example, if you set a to 16'b0001_0000_1010_0101, and b to 3, then you get an output of 16'b0000_0000_0000_0000. Just note that I am ignoring b for now... I should get 16'b0010_0001_0100_1010... but something is going wrong.

So, this is my code file test.v:

// ALU module.
module test(in1, in2, out1);

input [15:0] in1;
input [15:0] in2;

output reg [15:0] out1;

// Variables for shifting right and for rotating left or right.
reg [15:0] shiftedValue;

always@(in1, in2)
begin

assign shiftedValue = in1;

assign shiftedValue = shiftedValue * 2;

assign out1 = shiftedValue;

// This display value is correct!
// but it's still wrong in the test bench.
$display("out1 == %b", out1);

end

endmodule

module testStim;

reg [15:0] a;
reg [15:0] b;
wire [15:0] c;

// create ALU instance.
test myTest(a, b, c);

initial
begin

a = 16'b0001_0000_1010_0101;
b = 3;

#10
$display("op1In == %b, op1Out == %b", a, c);

$finish;

end

endmodule

This is the output after running simv (I stripped out the erroneous garbage...):

out1 == 0010000101001010
op1In == 0001000010100101, op1Out == 0000000000000000

Thanks, Erik W.

1 Answer 1

3

You have done what is called as procedural continuous assignment.

The difference between regular continuous assignments and procedural continuous assignments is this:

  • Continuous assignment can only drive wire/net data type. Procedural assignment can drive only reg data type and not nets.
  • Continuous assignment should appear outside procedural blocks(always, initial etc), while latter must be inside procedural blocks.
  • Continuous assignment executes each time the right hand side expression changes. Procedural assignment depends on sensitivity list of always block.

As soon as the always block ends, the effect of assign statement is removed. You must add deassign statement to retain the values (which I think is not the real intent) or Just remove assign statement from the code. As shown below:

shiftedValue = in1;
shiftedValue = shiftedValue * 2;
out1 = shiftedValue;

More information about assign, deassign is available at this, this and this links.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that makes more sense.
@Erik343 Kindly accept the answer to close this question.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.