Carry-save-adder circuit generation - #5409
Conversation
|
Please add tests |
| x.length match { | ||
| case 0 => Seq(0.U(0.W)) | ||
| case 1 => x | ||
| case 2 => x |
There was a problem hiding this comment.
I am confused by this 2 entry case, shouldn't we be adding them?
There was a problem hiding this comment.
I understand your confusion and appreciate your suggestion. Yes we could, and I agree that from an API point-of-view, it is cleaner to return the final sum as single UInt.
I intentionally chose to return the sum in redundant form (as two terms), leaving the final addition to the user. This is more flexible circuit-wise because:
- can exploit that the LSB in the second term is constant-zero: if needed, can OR in an additional +1 without significant timing impact.
- in high-frequency designs with many input terms, user can choose to insert a pipeline register stage after reduction, before the final adder.
- in case more terms are to be added to the result later, it is area-efficient to keep the sum in redundant form as long as possible.
I will think of a way to offer both.
There was a problem hiding this comment.
Discussed in Chisel dev. Maybe the public apply method should return a single UInt with a private recursive function (basically what you have here). Then some of these other use cases can be different function names depending on their arguments and return value types. For example if you want to return the two arguments you should return a tuple rather than a Seq (but of course keep the private recursive method using Seqs)
Summary
For efficient many-term addition, a tree starting with a carry-save adder is typically a good implementation choice.
Although modern logic synthesizers may automatically select an adder tree implementation, in our experience is it helpful to start synthesis with a netlist that already has the desired structure. It helps not only for the result quality, but also for the result stability.
This pull request introduces a Csa (Carry Save Adder) function to reduce an arbitrary number of UInt input terms to two UInt output terms. The sum of the two output terms is equal to the sum of the input terms.
Release Notes
Addition of a Carry Save Adder function to reduce many input terms to two.