I have a simple example to show as a use case. Practically, we have a 1-D vector of operands which we want to sum inside a sequential block. The code I have written is the following:
reg signed [31:0] operands_s [4] = {32'd 30, 32'd 40, -32'd 50, -32'd 20};
reg signed [31:0] operand_s_a;
reg signed [31:0] operand_s_b;
int i = 0;
logic signed [31:0] sum;
assign sum = $signed(operand_s_a) + $signed(operand_s_b);
always_ff @(posedge clock) begin
if (reset == 0) begin
operand_s_a = operands_s[i];
operand_s_b = operands_s[i+1];
i=i+2;
$display("A = %0d, B = %0d, S = %0d", operand_s_a, operand_s_b, sum);
end
end
Now the output after the execution as I would like it to be is:
A = 30, B = 40, S = 70
A = -50, B = -20, S = -70
Instead, the assign statement is off-by-1 and the result is this
A = 30, B = 40, S = x
A = -50, B = -20, S = 70
A = x, B = x, S = -70
In my understanding (which seems to be wrong), on the positive edge of the clock cycle the sequential block (in this case, the operands A and B) should be available to any other block downstream (in this case the adder). Since the assign is of combinational nature, on the same clock cycle that A and B are loaded I expected that the sum will be also the correct one and not the previous value (X) which is due to the reset being asserted.
Inside the IEEE Standard for SystemVerilog in the 10.3.2 section the following is stated:
Assignments on nets or variables shall be continuous and automatic. In other words, whenever an operand in
the right-hand expression changes value, the whole right-hand side shall be evaluated. If the new value is
different from the previous value, then the new value shall be assigned to the left-hand side.
In this case, the RHS as the output shows changes values, but the LHS does not change. What am I missing here? Is it maybe updated, but my $display statement is in the wrong position to reflect that change?
Thank you in advance!