如果Verilog中正好有一个高电平,则连接高电平

如果Verilog中正好有一个高电平,则连接高电平,verilog,Verilog,如果我有一个由9根导线组成的阵列,如果9根导线中正好有一根是高的,有没有一种简单的方法来制作一根高的新导线?我知道我能做到 wire[8:0] data; wire exactlyOneActive; assign exactlyOneActive = (data[0] & !data[1] & !data[2] ...) | (!data[0] & data[1] & !data[2] ...) |

如果我有一个由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
?它也必须是可合成的。

我认为类似的东西应该可以工作。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);
#定义N 8
导线[N:0]数据;
reg[N:0]唯一激活;
始终@(数据)开始
对于(i=0;iuniqueActive[i]=(data==1这应该是一个非常有效的设计

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);

问候-克里夫·卡明斯-Verilog&SystemVerilog大师

从逻辑的角度思考:你想要什么? 假设你有两条线:你想知道是一条高还是不是…它不是一条,也不是一条或…等等,它是一条异或(异或…,一条或另一条,但不是两条)

所以你想要的是: 分配exactlyOneActive=data[0]^data[1]^data[2]^


也许以下是合法的:数据^1b'0(用一个零位异或所有位)

所有其他解决方案都需要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)
在测试聚合异或、每对的异或、每组4的异或、每组8的异或(未显示)等时,可以在O(N log(N))门中给出正确答案。(您可以在上验证逻辑)。但不确定如何在Verilog中以简洁的方式编写它。

这是一个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
导线[8:0]导线;
电线绝缘;
电线[8:-1]不止一根;
电线[8:-1]至少一根;
genvar i;
生成

对于(i=0;iis,变量i是整数还是寄存器?
i
在本例中将是整数。这仍然是可合成的,因为循环将在编译时展开。但是1^1^1=0^1=1。我想这告诉我的是,我有奇数个高位。哦,你说得对。你想要的是一位加法器(因此,您可以判断是否有进位(即两位都是0或1)。
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