I want to compare two values only for the number of digits of the smaller of the two values.
For example, two variables are “logic [7:0] A = 8’b1110_0001” and “logic[7:0] B = 0000_1000”.
The variable “B” is smaller than the variable “A”. So two variables are compared as [3:0] (A[3:0], B[3:0])
I implement some code but it is not working. An error occurs at the replication operator during an elaboration.
The code is,
class A
function automatic bit compare(
logic [`USER_WIDTH-1:0] A,
logic [`USER_WIDTH-1:0] B);
if (A == B) begin
return 1'b1;
end else if (A > B) begin
const int B_valid_width = B != 0 ? $clog2(B) : 1;
return A&{B_valid_width{1'b1}} == B;
end else begin
const int A_valid_width = A != 0 ? $clog2(A) : 1;
return A == B&{A_valid_width{1'b1}};
end
return 1'b0;
endfunction
function void is_match( ... )
...
compare(A, B);
...
endfunction
endclass
What am I misunderstanding?
In reply to jh_veryveri:
First you should explain what not working means and what kind of error you are getting
I assume your problem is A_valid_width as stated in the LRM is should be a constant expression or a parameter, which is different from a const variable, you could try doing a masking, I think there are plenty of examples in this forum.
11.4.12.1 Replication operator A replication operator (also called a multiple concatenation) is expressed by a concatenation preceded by a non-negative, non-x, and non-z constant expre
HTH,
-R
In reply to rgarcia07:
Hello, R
Thanks for your reply.
The error message is “Illegal operand for const expression” for replication operator, A_valid_width and B_valid_width. I understood the “const” keyword allows a variable to be treated as a constant. So I used “const int”. Isn’t it “constant expression”?
I tried a parameter but the same error is occurred at the part of parameter declaration.
class A
function automatic bit compare(
logic [`USER_WIDTH-1:0] A,
logic [`USER_WIDTH-1:0] B);
localparam width = (A > B) && (B != 0) ? $clog2(B) :
(B > A) && (A != 0) ? $clog2(A) : 1;
return {width(1'b1}} & A == {width{1'b1}} & B;
endfunction
function void is_match( ... )
...
compare(A, B);
...
endfunction
endclass
I want to mask and compare only the number of bits I want.
Any help would be appreciated.
In reply to jh_veryveri:
I’m sure there are ways of doing this more efficiently, from what I understood from your post this might work
// Code your testbench here
// or browse Examples
`define USER_WIDTH 4
class wrapper;
function bit compare(logic [`USER_WIDTH - 1:0] A, logic [`USER_WIDTH-1:0] B);
int B_valid_width = (B != 0) ? $clog2(B) : 1;
int A_valid_width = (A != 0) ? $clog2(A) : 1;
bit [`USER_WIDTH - 1:0] mask = {`USER_WIDTH{1'b1}};
$display("mask before = %b", mask);
$display("A = %b A_valid_width = %0d", A, A_valid_width);
$display("B = %b B_valid_width = %0d", B, B_valid_width);
if (A === B) begin
return 1'b1;
end
else begin
if (A > B) begin
mask >>= B_valid_width;
$display("A > B mask after = %b", mask);
return ((A & mask) == B);
end
else begin
mask >>= A_valid_width;
$display("A < B mask after = %b", mask);
return (A == (B & mask));
end
end
return 1'b0;
endfunction
endclass
module test();
wrapper m_wrapper;
logic [`USER_WIDTH-1:0] X;
logic [`USER_WIDTH-1:0] Y;
bit result;
initial begin
X = 'b0011;
Y = 'b0100;
m_wrapper = new();
result = m_wrapper.compare(X, Y);
$display("X = %b Y = %b result = %0b", X , Y, result);
Y = 'b0111;
result = m_wrapper.compare(X, Y);
$display("X = %b Y = %b result = %0b", X , Y, result);
end
endmodule
This outputs
# KERNEL: mask before = 1111
# KERNEL: A = 0011 A_valid_width = 2
# KERNEL: B = 0100 B_valid_width = 2
# KERNEL: A < B mask after = 0011
# KERNEL: X = 0011 Y = 0100 result = 0
# KERNEL: mask before = 1111
# KERNEL: A = 0011 A_valid_width = 2
# KERNEL: B = 0111 B_valid_width = 3
# KERNEL: A < B mask after = 0011
# KERNEL: X = 0011 Y = 0111 result = 1
HTH,
-R
In reply to rgarcia07:
Hello, R
Thanks for your comment.
I solved the problem by referring to the source you provided.
Thank you!