What am I doing wrong about the replication operator?

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!