Confused by syntax -- request help

D

Daku

Guest
Could some Verilog guru please clarify the following:
I have:

assign {cy_sum, result_sum} = a + b;

Where
input [width-1:0] a;
input [width-1:0] b;
and
wire cy_sum;

If {x,y} is the concatenation of x, y, and a+b the
result of the addition, what does the above
statement mean ?
Thanks in advance for your help.
 
On Wed, 9 Nov 2011 20:25:09 -0800 (PST), Daku wrote:

Could some Verilog guru please clarify the following:

input [width-1:0] a;
input [width-1:0] b;
wire cy_sum;
assign {cy_sum, result_sum} = a + b;
You forgot to tell us about the declaration of result_sum.
It is almost certainly

wire [width-1:0] result_sum;

Assuming this is true, here's what happens.

1)
It is fine to use {a,b,c} concatenation on the left (target)
side of an assignment. It has the obvious effect: the
various target vectors are concatenated, left-to-right,
effectively forming one wider vector. The assignment
puts its result into that wide vector. Appropriate slices
of that imaginary wide vector then drop into the individual
target vectors in exactly the way you would expect.

2)
The idiom you showed is a common and useful way to capture
both the sum and the carry from an arithmetic operation.
To give an example, let's suppose width=3, a=3'b110,
b=3'b011. If you wrote
assign result_sum = a+b;
then the arithmetic would be done in 3-bit width, and the
carry bit from the addition would be lost, giving a result
of 3'b001. But of course what we really want is to get the
full result 4'b1001, with the most significant bit going
into a separate carry bit. That's what your concatenation
does: it allows the arithmetic to be done in 4-bit width,
then puts the three LSBs of the result into result_sum
and the MSB into carry_sum.

3)
As has been discussed here many times, the rules in Verilog
for deciding how wide an arithmetic operation should be
are quite subtle and not easy to write down in a compact
form. However, they definitely work in your favour in
this situation. Roughly, the Verilog compiler says...
- look at the widest thing in the expression, including
the result (target) vector
- a, b are 3 bits; the target is 4 bits, so "widest" is
4 bits wide
- so now we know that everything will happen at 4-bit
width
- which means that ALL operands in the expression must
first be widened to 4 bits, before doing any arithmetic
- and the expression is unsigned, so we widen by adding
leading zeros
- so a, b get widened to form 4-bit operands 4'b0110,
4'b0011 (you can't actually see these values, of course)
- then the arithmetic is done using 4-bit "hardware", so
any bits beyond [3] are simply thrown away. In our case
that's OK because we know the result cannot be larger
than 4'b1110.
- Finally, the result (4'b1001) is copied to the target.
Given the widening rules, it's possible that the target
might be narrower than 4 bits, in which case the usual
Verilog "throw away unwanted MSBs" behaviour applies.
But in your case the target is full width, so no bits
are lost.

Recent versions of the Verilog and SystemVerilog standards
have good, complete descriptions of the arithmetic width
rules. It's not easy reading, though.
--
Jonathan Bromley
 
Dear Sir,
Thank you very much for the detailed explanation and
example.


On Nov 10, 4:24 am, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
On Wed, 9 Nov 2011 20:25:09 -0800 (PST), Daku wrote:
Could some Verilog guru please clarify the following:

input   [width-1:0]             a;
input   [width-1:0]             b;
wire                            cy_sum;
assign {cy_sum, result_sum} = a + b;

You forgot to tell us about the declaration of result_sum.
It is almost certainly

  wire [width-1:0] result_sum;

Assuming this is true, here's what happens.

1)
It is fine to use {a,b,c} concatenation on the left (target)
side of an assignment.  It has the obvious effect: the
various target vectors are concatenated, left-to-right,
effectively forming one wider vector.  The assignment
puts its result into that wide vector.  Appropriate slices
of that imaginary wide vector then drop into the individual
target vectors in exactly the way you would expect.

2)
The idiom you showed is a common and useful way to capture
both the sum and the carry from an arithmetic operation.
To give an example, let's suppose width=3, a=3'b110,
b=3'b011.  If you wrote
  assign result_sum = a+b;
then the arithmetic would be done in 3-bit width, and the
carry bit from the addition would be lost, giving a result
of 3'b001.  But of course what we really want is to get the
full result 4'b1001, with the most significant bit going
into a separate carry bit.  That's what your concatenation
does: it allows the arithmetic to be done in 4-bit width,
then puts the three LSBs of the result into result_sum
and the MSB into carry_sum.

3)
As has been discussed here many times, the rules in Verilog
for deciding how wide an arithmetic operation should be
are quite subtle and not easy to write down in a compact
form.  However, they definitely work in your favour in
this situation.  Roughly, the Verilog compiler says...
- look at the widest thing in the expression, including
  the result (target) vector
- a, b are 3 bits; the target is 4 bits, so "widest" is
  4 bits wide
- so now we know that everything will happen at 4-bit
  width
- which means that ALL operands in the expression must
  first be widened to 4 bits, before doing any arithmetic
- and the expression is unsigned, so we widen by adding
  leading zeros
- so a, b get widened to form 4-bit operands 4'b0110,
  4'b0011 (you can't actually see these values, of course)
- then the arithmetic is done using 4-bit "hardware", so
  any bits beyond [3] are simply thrown away.  In our case
  that's OK because we know the result cannot be larger
  than 4'b1110.
- Finally, the result (4'b1001) is copied to the target.
  Given the widening rules, it's possible that the target
  might be narrower than 4 bits, in which case the usual
  Verilog "throw away unwanted MSBs" behaviour applies.
  But in your case the target is full width, so no bits
  are lost.

Recent versions of the Verilog and SystemVerilog standards
have good, complete descriptions of the arithmetic width
rules.  It's not easy reading, though.
--
Jonathan Bromley
 

Welcome to EDABoard.com

Sponsor

Back
Top