Verilog:使用三元运算符的更有效方法

问题描述

我写了以下assign语句:

assign F = (BCD == 4'd1 | BCD == 4'd2 | BCD == 4'd3 | BCD == 4'd4 | BCD == 4'd5) ? 1'b1 : 1'b0;

如果BCD输入(4位)为1-5,则该函数返回1,否则返回0。这完全符合我的预期,但是我在寻找一种更有效的方法编写“ OR”部分。有没有更有效的方式编写此代码

解决方法

这里不需要三元运算符。每个等式(==)的结果为1位,并且您正在执行按位 OR(|)。您可能应该使用逻辑或(||),其结果也是1位。

assign F = (BCD == 4'd1 || BCD == 4'd2 || BCD == 4'd3 || BCD == 4'd4 || BCD == 4'd5);

在大多数工具支持的SystemVerilog中,您可以使用内部运算符

assign F = BCD inside {[1:5]}; //  contiguous range
assign F = BCD inside {[1:3],5,[7:10]}; //  noncontiguous values
,

否,应该使用由|分隔的每个完整表达式。但是,在这种特殊情况下,您可以使用(BCD >= 4'd1) & (BCD <= 4'd5)

,

由于您的值在连续范围内,因此可以简化为:

assign F = ((BCD >= 4'd1) && (BCD <= 4'd5));

如果工具集支持SystemVerilog语法,则也可以使用inside运算符。请参阅IEEE Std 1800-2017第11.4.13节设置成员资格运算符

,

有几种方法可以做到这一点:

a)边界检查。

assign F = (BCD > 4'd0) & (BCD < 4'd6);

b)OR减少和上限检查。

assign F = |BCD & (BCD < 4'd6);

c)这是行为硬件描述,将通过综合工具进行优化。不过,它已被参数化。

localparam LOW = 1;
localparam HIGH = 5;
integer i;
reg F;
always @ (*) begin
  F = 1'b0;
  for(i = LOW; i <= HIGH; i = i + 1) begin: val_check
    if(BCD == i[3:0]) F = 1'b1;
  end
end