Wire high if exactly one maximum in Verilog

If I have an array of 9 wires, is there an easy way to make a new wire tall if exactly one of the 9 wires is tall? I know what I can do

wire[8:0] data; wire exactlyOneActive; assign exactlyOneActive = (data[0] & !data[1] & !data[2] ...) | (!data[0] & data[1] & !data[2] ...) | (!data[0] & !data[1] & data[2] ...) | ...etc 

but yes yes? Especially since the nine wires are likely to be 25 at some point. Is there any better way to do this, perhaps using generate ? It must also be synthesized.

+4
source share
6 answers
 assign zeroOrOnehot = ~|(data & (data-1)); assign atLeastOneBitSet = |data; assign exactlyOneActive = zeroOrOnehot & atLeastOneBitSet; 

Regards - Cliff Cummings - Verilog and SystemVerilog Guru

+6
source

This should be a pretty effective design.

 wire[8:0] data; wire exactly_one_active; //Total is log2_ceiling of data bits wide // Remove binary weighting wire [3:0] total = data[8] + data[7] ... + data[0]; assign exactly_one_active = (total == 4'b1); 
+4
source

I think something like this should work. For a cycle it will be synthesized if it has a counter of constant cycles, as it does:

 #define N 8 wire [N:0] data; reg [N:0] uniqueActive; always @(data) begin for (i=0 ; i < N; i = i+1 ) begin uniqueActive[i] = (data == 1<<i); end end assign exactlyOneActive = (uniqueActive != 0); 
+2
source

All other solutions require O (N ^ 2). Pay attention to the following pattern.

 (a#b#c#d#e#f#g#h) & (a&b # c&d # e&f # g&h) & (a&b&c&d # e&f&g&h) 

where you check the set of xor, xor of each pair, xor of each group of 4, xor of each group of 8 (not shown), etc., gives you the correct answer in the O (N log (N)) gate. (You can check the logic on the truth table generator ). Not sure how to write this in concise form in Verilog though.

+1
source

Here is the shutter solution O (N)

 wire[8:0] wires; wire isOneHot; wire[8:-1] moreThanOne; wire[8:-1] atLeastOne; genvar i; generate for (i=0; i<9; i=i+1) begin :b1 assign atLeastOne[i] = atLeastOne[i-1] | wires[i]; assign moreThanOne[i] = moreThanOne[i-1] | atLeastOne[i-1] & wires[i]; end assign isOneHot = atLeastOne[8] & !moreThanOne[8]; endgenerate 
+1
source

Think logically: what do you need? Let's say you had two wires: and you wanted to know whether it is one tall or not ... it's not a, and it's not ... or wait, it's xor (exclusive or ... one or the other, but not both) .

so what you want: assign exactly OneActive = data [0] ^ data [1] ^ data [2] ^ ...

possibly legal: data ^ 1b'0 (xor all bits with one zero bit)

-1
source

All Articles