Reputation:
I have written the following assign
statement:
assign F = (BCD == 4'd1 | BCD == 4'd2 | BCD == 4'd3 | BCD == 4'd4 | BCD == 4'd5) ? 1'b1 : 1'b0;
where if the BCD
input (4-bits) is 1-5, the function returns a 1 and otherwise returns a 0. This works perfectly how I intended, but I'm looking for a more efficient way to write the "OR" parts. Is there a more efficient way to write this?
Upvotes: 0
Views: 3958
Reputation: 354
There are several ways to do this:
a) Boundary check.
assign F = (BCD > 4'd0) & (BCD < 4'd6);
b) OR reduction and a high limit check.
assign F = |BCD & (BCD < 4'd6);
c) This is a behavioural hardware description, it would be optimized by the synthesis tool. It is parameterized, though.
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
Upvotes: 0
Reputation: 42698
There's no need for the ternary operator here. The result of each equality(==
) is 1-bit, and you are doing a bit-wise OR (|
). You probably should be using a logical OR (||
) whose result is also 1-bit.
assign F = (BCD == 4'd1 || BCD == 4'd2 || BCD == 4'd3 || BCD == 4'd4 || BCD == 4'd5);
In SystemVerilog which most tools are supporting, you can use the inside operator
assign F = BCD inside {[1:5]}; // contiguous range
assign F = BCD inside {[1:3],5, [7:10]}; // noncontiguous values
Upvotes: 3
Reputation: 1316
No, one should use each complete expressions separated by |
. However, in this particular situation, you can use (BCD >= 4'd1) & (BCD <= 4'd5)
.
Upvotes: 2
Reputation: 62163
Since your values are in a continuous range, this can be simplified as:
assign F = ((BCD >= 4'd1) && (BCD <= 4'd5));
If your tool set supports SystemVerilog syntax, you could also use the inside
operator. Refer to IEEE Std 1800-2017, section 11.4.13 Set membership operator.
Upvotes: 1