Skip to content

Instantly share code, notes, and snippets.

@mcandre
Created September 28, 2021 02:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcandre/048436c2630a3ac686529f2363e99d3f to your computer and use it in GitHub Desktop.
Save mcandre/048436c2630a3ac686529f2363e99d3f to your computer and use it in GitHub Desktop.
bad adder
module half_adder(
input clk,
a,
b,
output reg [0:0] sum,
carry
);
always @(posedge clk)
begin
sum <= a ^ b;
carry <= a & b;
end
endmodule
module test_half_adder;
reg clk = 0;
always #1 clk = !clk;
wire a = 0,
b = 1;
wire [0:0] sum = 0,
carry = 0;
half_adder ha(clk, a, b, sum, carry);
initial
$monitor(
"Time: %t, clk: %0d, a: %0d, b: %0d, sum: %0d, carry: %0d",
$time,
clk,
a,
b,
sum,
carry
);
endmodule
@mcandre
Copy link
Author

mcandre commented Sep 28, 2021

vvp shows sum as indeterminate, instead of 1.

Time:                22383, clk: 1, a: 0, b: 1, sum: x, carry: 0
Time:                22384, clk: 0, a: 0, b: 1, sum: x, carry: 0
Time:                22385, clk: 1, a: 0, b: 1, sum: x, carry: 0
...

@mcandre
Copy link
Author

mcandre commented Sep 28, 2021

Ah, as an astute Element user points out, the initialization on the output parameter variables was conflicting with the assignment in the module.

Even though RTL code may appear to use C-style assignment, that's not what happens physically or in silico. We're talking about electrical wires here. The original voltage initialization level is not replaced, but compounded by module assignments. When we remove the = 0 from the sum and carry declarations, then the code works better.

Note: SystemVerilog appears to lack support for mixed initialized / uninitialized variable declarations. These must be separate into distinct statements.

@caryr
Copy link

caryr commented Sep 28, 2021

Specifically wires are not variables and must have drivers. For variables (reg, log, bit, etc.) you can do this, but wires create drives and when the drivers do not match and the strengths are the same you get an undefined value as the result. The declaration assignment create one continuous driver and the port connection for the half adder creates a second. When these two driver do not match you get an undefined value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment