0
votes

So I just got around to learning verilog and I was implementing a basic binary adder in it. From my limited understanding of verilog, 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. Any help is appreciated!

2
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;Greg
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.Harry
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)Greg
That fixed the problem, thanks Greg!Harry

2 Answers

1
votes

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

1
votes

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