I'm attempting to capture the carry out of the addition of two N bit numbers with a carry in. My code is:
module alu(a, b, f, cOut, z);
parameter size = 8; // how many bits is each input
parameter n = size - 1;
input a; // operand a
input b; // operand b
input f;
wire [n:0] a;
wire [n:0] b;
wire [2:0] f;
wire [n:0] sum;
assign {cOut,sum} = {(n+1){a + b + {n{f[2]}}}};
In my inner replicator, I'm trying to zero-extend the bit at f[2] to be the size of the operands (f[2] is the carry in). With the outer replicator, I'm trying to zero-extend the addition to fit in n+1 bits. Then cOut will be set to the MSB, which will represent the carry out.
Here's the error that Verilator reports:
% verilator -cc alu.v
%Warning-WIDTH: alu.v:22: Operator ASSIGNW expects 9 bits on the Assign RHS, but Assign RHS's REPLICATE generates 64 bits.
%Warning-WIDTH: Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.
%Error: Exiting due to 1 warning(s)
%Error: Command Failed /usr/bin/verilator_bin -cc alu.
Does anyone know why Verilator thinks that the RHS will be 64 bits? And is there a better way to write this without nested replicators in Verilog?
Best Answer
Replicators do not zero extend, they replicate.
{7{f[2]}}
means{f[2],f[2],f[2],f[2],f[2],f[2],f[2]}
You miss read the message. The RHS is 9 bits but is being assigned 64 bits (the LHS width).
a
andb
are 8 bit values, are are used as the initial width to be replicated. the Replicator value(n+8)
is 8. 8*8 is 64, which is now the LHS width value.To extend leading zeros use
{ {n{1'b0}}, f[2] }
, which in this case will evaluate to{7'b0000000,f[2]}
Most synthesizers will generate the proper logic with
assign {cOut,sum} = a + b + f[2];
, and this is assuming you want unsigned logic.