Skip to content

Commit 29a88ad

Browse files
authored
Add cc_onehot module (#121)
* Add `cc_onehot` module A fast implementation of $onehot() * Make linter happy
1 parent 015917f commit 29a88ad

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

Bender.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ sources:
2323
# Level 0
2424
- src/binary_to_gray.sv
2525
- src/cb_filter_pkg.sv
26+
- src/cc_onehot.sv
2627
- src/cdc_2phase.sv
2728
- src/cf_math_pkg.sv
2829
- src/clk_div.sv

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
66

77
## Unreleased
88

9+
### Added
10+
- Add `cc_onehot`
11+
912
## 1.22.1 - 2021-06-14
1013
### Fixed
1114
- Remove breaking change of `spill_register`

src/cc_onehot.sv

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2021 ETH Zurich.
2+
// Copyright and related rights are licensed under the Solderpad Hardware
3+
// License, Version 0.51 (the "License"); you may not use this file except in
4+
// compliance with the License. You may obtain a copy of the License at
5+
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
6+
// or agreed to in writing, software, hardware and materials distributed under
7+
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
8+
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
// specific language governing permissions and limitations under the License.
10+
11+
/// Hardware implementation of SystemVerilog's `$onehot()` function.
12+
/// It uses a tree of half adders and a separate
13+
/// or reduction tree for the carry.
14+
15+
// Author: Florian Zaruba <[email protected]>
16+
// Author: Fabian Schuiki <[email protected]>
17+
// Author: Stefan Mach <[email protected]>
18+
module cc_onehot #(
19+
parameter int unsigned Width = 4
20+
) (
21+
input logic [Width-1:0] d_i,
22+
output logic is_onehot_o
23+
);
24+
// trivial base case
25+
if (Width == 1) begin : gen_degenerated_onehot
26+
assign is_onehot_o = d_i;
27+
end else begin : gen_onehot
28+
localparam int LVLS = $clog2(Width) + 1;
29+
30+
logic [LVLS-1:0][2**(LVLS-1)-1:0] sum, carry;
31+
logic [LVLS-2:0] carry_array;
32+
33+
// Extend to a power of two.
34+
assign sum[0] = $unsigned(d_i);
35+
36+
// generate half adders for each lvl
37+
// lvl 0 is the input level
38+
for (genvar i = 1; i < LVLS; i++) begin : gen_lvl
39+
localparam int unsigned LVLWidth = 2**LVLS / 2**i;
40+
for (genvar j = 0; j < LVLWidth; j+=2) begin : gen_width
41+
assign sum[i][j/2] = sum[i-1][j] ^ sum[i-1][j+1];
42+
assign carry[i][j/2] = sum[i-1][j] & sum[i-1][j+1];
43+
end
44+
// generate carry tree
45+
assign carry_array[i-1] = |carry[i][LVLWidth/2-1:0];
46+
end
47+
assign is_onehot_o = sum[LVLS-1][0] & ~|carry_array;
48+
end
49+
50+
endmodule

0 commit comments

Comments
 (0)