Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wire high if exactly one high in Verilog

Tags:

verilog

If I've got an array of 9 wires, is there an easy way to make a new wire that is high if exactly one of the 9 is high? I know I could 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, yuck, right? Especially since the nine wires will probably be 25 at some point. Any better way to do this, maybe using generate? It has to be synthesizable too.

like image 268
Dax Fohl Avatar asked Dec 16 '22 22:12

Dax Fohl


2 Answers

assign zeroOrOnehot     = ~|(data & (data-1));
assign atLeastOneBitSet = |data;
assign exactlyOneActive = zeroOrOnehot & atLeastOneBitSet;  

Regards - Cliff Cummings - Verilog & SystemVerilog Guru

like image 110
Cliff Cummings Avatar answered Dec 18 '22 10:12

Cliff Cummings


This should be a pretty efficient 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);
like image 39
Morgan Avatar answered Dec 18 '22 10:12

Morgan