1
\$\begingroup\$
module And(a,b);
 input [31:0]a;
 output reg b;
 integer i;
 initial assign b=a[0];
 initial begin
 for(i=1;i<=31;i=i+1) begin
 assign b=b&a[i];
 end
 end
endmodule
module tb;
 wire b;
 reg [31:0]a;
 And gate(.a(a),.b(b));
 initial begin
 $monitor(" a=%b b=%b",a,b);
 a=32'd757038;#10 a=32'b11111111111111111111111111111111;
 end
endmodule

The error was as shown:

[2023年07月31日 13:25:14 UTC] iverilog '-Wall' design.sv testbench.sv && unbuffer vvp a.out 
 a=00000000000010111000110100101110 b=x 
 a=11111111111111111111111111111111 b=x 
Done
toolic
10.8k11 gold badges31 silver badges35 bronze badges
asked Jul 31, 2023 at 13:31
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

The issue is that you are trying to assign multiple signals to the same variable.

You have an assign b = a[0], which performs continuous assignment (basically connects the two signals together. Fine. However you then have a loop which then assigns b to a[1], also to a[2], also to ... and so on. As a result b is being driven by multiple sources and so you get x indicating contention - there is no way of knowing what value b should take.

From what I can gather, you are trying to perform the "Unary Reduction AND" function - basically AND all of the bits in the input signal together to get the output signal. In which case there is an operator for that:

module And(a,b);
input [31:0] a;
output b;
assign b = &a;
endmodule

The unary & operator performs the AND operation across all bits in the input resulting in a single output bit which is high only when all inputs are high.


If you are set on using a loop to do this, you should not be using initial or assign. Instead you should use the blocking assignment operator = in an always block.

always @ * begin
 b = a[0];
 for (i = 1; i < 32; i = i + 1) begin
 b = b & a[i];
 end
end

This doesn't drive b with multiple signals. Instead it will assign to an internal version of b, which then be reassigned during each pass of the loop using the temperary b value it calculated on the pass before. Eventually once the loop is over the resulting value will be assigned back to the real b. This loop will resolve to simply a large chain of AND gates performing unary reduction.

answered Jul 31, 2023 at 13:53
\$\endgroup\$
2
  • \$\begingroup\$ I should perhaps ask this as a separate question. My apologies for taking a short-cut here. Do you know, off-hand, if existing synthesis and logic equivalence tools, seeing these two different approaches to the same goal, and given the same target FPGA architecture and overall context would then yield identical implementations? My experience is decades old and, back then, I could not count on anything much at all. Very likely I'd get two completely different results. I found myself having to code towards results I desired and forced to manual floorplanning, to boot. Been out of it too long. +1 \$\endgroup\$ Commented Aug 1, 2023 at 7:05
  • 1
    \$\begingroup\$ @periblepsis In all likelihood both implementations (loop vs unary op) will result in exactly the same hardware on an FPGA. Both are combination circuits taking a 32 bit input and giving a 1 bit output, as such they will both end up being nothing more than a single 32-input LUT. This LUT will be made using a tree of smaller 4/5/6-in LUT primitves from the FPGA (whichever size is supported). \$\endgroup\$ Commented Aug 1, 2023 at 15:56

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.