如果我有一个9线的阵列,如果9中的一个很高,是否有一种简单的方法可以制造一条高的新线?我知道我能做到
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
但是,哎,对吧?特别是因为九根导线在某些时候可能是25根。有没有更好的方法,可能使用generate
?它也必须是可合成的。
答案 0 :(得分:6)
assign zeroOrOnehot = ~|(data & (data-1));
assign atLeastOneBitSet = |data;
assign exactlyOneActive = zeroOrOnehot & atLeastOneBitSet;
问候 - Cliff Cummings - Verilog& SystemVerilog Guru
答案 1 :(得分:4)
这应该是一种非常有效的设计。
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);
答案 2 :(得分:2)
我认为这样的事情应该有效。 For循环将是可合成的,只要它有一个常量循环计数器,如下所示:
#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);
答案 3 :(得分:1)
所有其他解决方案都需要O(N ^ 2)个门。请注意以下模式
(a#b#c#d#e#f#g#h) & (a&b # c&d # e&f # g&h) & (a&b&c&d # e&f&g&h)
在那里测试聚合xor,每对的xor,每组4的xor,每组8的xor(未显示)等,给出正确答案O(N log(N ))大门。 (您可以在truth table generator上验证逻辑)。不知道如何在Verilog中以简洁的方式编写这个。
答案 4 :(得分:1)
这是一个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
答案 5 :(得分:-1)
从逻辑的角度思考:你想要什么? 假设你有两条线:你想要知道的是一个高或不...它不是一个,它不是一个或......等等,它是一个xor(独占或......一个或另一个但不是两个)
所以你想要的是: 指定exactOneActive = data [0] ^ data [1] ^ data [2] ^ ...
也许以下是合法的:数据^ 1b'0(xor所有位都有一个零位)