0

I was implementing a basic binary adder in Verilog. From my limited understanding, the following should add two 16-bit values:

module ADD(X, Y, Z);
input[15:0] X;
input[15:0] Y;

output Z[15:0];
wire C[15:0];

assign C[0] = 0;
integer i;
for(i=1; i<16; i=i+1) begin 
   assign C[i]=(X[i-1]&Y[i-1])|(X[i-1]&C[i-1])|(Y[i-1]&C[i-1]);
end
for(i=0; i<16; i=i+1) begin
   assign Z[i]=X[i]^Y[i]^C[i];
end
endmodule

However, I get an error when I try to synthesize the above.

Error (10170): Verilog HDL syntax error at add.v(10) near text "for"; expecting "endmodule"

I'm not sure what is wrong with the code.

3
  • You could skip the for loop with: output [15:0] Z; wire [15:0] C = { (X&Y)|(X&C)|(Y&C) , 1'b0}; assign Z=X^Y^C;. If you don't need to demonstrate the full adder operations, then just say assign Z=X+Y; Commented May 16, 2014 at 22:52
  • I tried doing C = { (X&Y)|(X&C)|(Y&C) } and I got an error saying that I have to assign individually to array elements. Commented May 19, 2014 at 0:41
  • I guessing C is still declared as wire C [15:0], should be wire [15:0] C. They have different meanings. Working example [here]( edaplayground.com/x/U8) (ModelSim10.1d/Icarus0.10) Commented May 19, 2014 at 16:36

2 Answers 2

3

The for-loop is used outside of an always block, so i needs to be a genvar instead of an integer. Also, you probably want Z and C to declared an packed arrays instead of unpacked, mo the [15:0] to the other side.

output [15:0] Z; // make as packed bits
wire [15:0] C;

assign C[0] = 0;
genvar i; // not integer
generate // Required for IEEE 1364-2001, optional for *-2005 and SystemVerilog
for(i=1; i<16; i=i+1) begin 
  assign C[i]=(X[i-1]&Y[i-1])|(X[i-1]&C[i-1])|(Y[i-1]&C[i-1]);
end
for(i=0; i<16; i=i+1) begin
  assign Z[i]=X[i]^Y[i]^C[i];
end
endgenerate // must be matched with a generate

Alternative solution 1: use an always block

output reg[15:0] Z; // make as reg
reg [15:0] C;

integer i; // integer OK
always @* begin
  for(i=1; i<16; i=i+1) begin
    if (i==0)  C[i] = 1'b0;
    else       C[i]=(X[i-1]&Y[i-1])|(X[i-1]&C[i-1])|(Y[i-1]&C[i-1]);
    Z[i]=X[i]^Y[i]^C[i];
  end
end

Alternative solution 2: bit-wise assignment

output [15:0] Z;

wire [15:0] C = { (X&Y)|(X&C)|(Y&C) , 1'b0 };
assign Z = X^Y^C;

Alternative solution 3: behavioral assignment

output [15:0] Z;
assign Z = X+Y;

Working examples here

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

2 Comments

All the alternative solutions work, but the first solution still gives me the same error. I am using Quartus II 13.1
@Harry, I did a little digging; Veilog-2001 requires a generate/endgeneate wrapper. It is optional for Verilog-2005 and SystemVerilog. Quartus support Verilog-2001, not Verilog-2005. Quartus does support SystemVerilog when the file ends in .sv instead of .v. For the first solution to work, either add generate/endgeneate (see updated answer) or enable SystemVerilog by renaming the file .
1

Change the definition of i from integer to genvar.

Notice that for loops can be used either in an always block or in a generate block. The latter is implicitly the context that you are using it in your code. In generate blocks, the loop variable should be of type genvar.

More info in IEEE Std 1800-2012

2 Comments

I replaced the integer in the above code with genvar and still get the same error.
@Harry, what simulator are you using?

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.