如果Verilog中正好有一个高电平,则连接高电平
如果我有一个由9根导线组成的阵列,如果9根导线中正好有一根是高的,有没有一种简单的方法来制作一根高的新导线?我知道我能做到如果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] ...) |
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;i uniqueActive[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