Replication in assignment pattern not working on queue of structure

I’m initializing a queue of structure while declaring it as shown below. I tried both unpacked array concatenation and assignment pattern but getting syntax error "token is: ‘=’ ". I don’t fully understand the difference between the two except for the limitation in replication for former and need for element by element compatibility in latter.


typedef struct {
 A a;
 B b;
 C c;
 D d;
} lp_s;    //A,B,C,D : integer enums

lp_s var[$] = '{    //No difference in result even with unpacked array concatenation
 '{a:A_ENUM, b: B_ENUM, default:0}
};

Please help. Thanks!

In reply to rishikpillai90:

‘var’ is a keyword in SystemVerilog used for a variable declaration. If the type is not specified, then var defaults to logic type. Just rename your variable queue and it should solve the problem.

The following should work fine.

module top();
  typedef enum {H_ENUM,A_ENUM} A;
  typedef enum {I_ENUM,B_ENUM} B;
  typedef enum {J_ENUM,C_ENUM} C;
  typedef enum {K_ENUM,D_ENUM} D;
  
  typedef struct {
 A a;
 B b;
 C c;
 D d;
} lp_s;    //A,B,C,D : integer enums
 
lp_s vari[$] = '{    //No difference in result even with unpacked array concatenation
 '{a:A_ENUM, b: B_ENUM, default:0}
};
  initial begin
    #1;
    $display(vari);
  end
endmodule

For more information, var is explained in IEEE 1800-2012 Section 6.8.

In reply to sharvil111:

Hi sharvil111,

Thanks for the input. But my actual variable name is different from what I have posted here. It is quite big with underscores and all that and is not a SV keyword. I am putting this code in a header file outside any initial block, tasks or functions and included in a package. Would that create the problem?

Rishi

In reply to rishikpillai90:

Can you show your code somewhat more accurately? The above one works fine for me. I guess there might be some package import/scope resolution issue. The below code works fine for me with the use of package.

package mypkg;
  typedef enum {H_ENUM,A_ENUM} A;
  typedef enum {I_ENUM,B_ENUM} B;
  typedef enum {J_ENUM,C_ENUM} C;
  typedef enum {K_ENUM,D_ENUM} D;
 
  typedef struct {
 A a;
 B b;
 C c;
 D d;
} lp_s;    //A,B,C,D : integer enums
 
lp_s vari[$] = '{    //No difference in result even with unpacked array concatenation
 '{a:A_ENUM, b: B_ENUM, default:0}
};
endpackage

module top();
  import mypkg::*;
  initial begin
    #1;
    $display("%0p",mypkg::vari);
  end
endmodule

In reply to sharvil111:

It was indeed a scope resolution problem. My struct datatype was declared in another package which was not imported fully. I’m not seeing the error now after the necessary changes. Thank you for the help.

In reply to rishikpillai90:

Also, how can we do replication of struct assignment in this case?

I tried below but getting syntax error:

Assignment pattern is illegal due to: Replication field exceeds the size of
the target


lp_s vari[$] = '{    
      '{a: A_VAL0, b: B_VAL0, default:0},
 '{15{'{a: A_VAL1, b: B_VAL1, default:0}}},
      '{a: A_VAL2, b: B_VAL2, default:0}
};

In reply to rishikpillai90:

There are certain restrictions in using replication operators. I would advise to make an API and set the values from that. The closest one can get is replicating same values:

typedef struct packed{
 A a;
 B b;
 C c;
 D d;
} lp_s;    //A,B,C,D : integer enums
 
lp_s vari[$] = '{    
  //'{a: A_ENUM, b: B_ENUM, default:0},
  15{a: A_ENUM, b: B_ENUM, default:0}
  //{a: A_ENUM, b: B_ENUM, default:0}
};

Refer to this similar thread for more information.

Section 10.1 of IEEE 1800-2017 discusses about the legal and illegal combinations.

In reply to sharvil111:

From LRM, I could only see that the one pertinent restriction to replication in my scenario is that it can’t be used for unpacked array concatenation. Can you point out any other which applies here?

Did your above code work? It didn’t for me because the source type of RHS is not self-determined.

Also, making code from my previous post work might be a stretch because the replication used there (and many other trial and error options I tried) is not assignment compatible with elements of the queue. But then what change would make it so is unknown. Guess I have to remove the replication and move ahead.

In reply to rishikpillai90:

You can add an explicit type to an assignment pattern so it can be used in a self-determined context.

 typedef lp_s lp_sq[$];
   
   lp_s vari[$] = { // unpacked array concatenation of struct assignment patterns
  lp_s'{a: A_ENUM, b: B_ENUM, C: J_ENUM, D: D_ENUM},
  lp_sq'{12{lp_s'{a: A_ENUM, b: B_ENUM, C: J_ENUM, D: D_ENUM}}},
  lp_s'{a: A_ENUM, b: B_ENUM, C: J_ENUM, D: D_ENUM }
};

Note, you can’t use default:0 here because 0 is not a valid type to assign to an enum.

In reply to rishikpillai90:

The given code worked for me. Note that I had used packed structure. As pointed by Dave, one should use explicit type casting since we need to make sure that the replication fits into self-determined context.

In reply to dave_59:

Thanks Dave. This worked for me. Even though LRM says that unpacked array concatenation forbids replication (Section 10.10.1), we could circumvent the limitation every time using this method (right?).

In reply to rishikpillai90:

The LRM say you cannot use replication as part of the unpacked array concatenation operator, unlike the way you can use it in a packed array concatenation. Once you are inside the self-determined context of each operand, that rule no longer applies.