mtveezy
mtveezy

Reputation: 711

verilog set bus equal to array of struct bits

I'm trying to set a bus equal to a bit of a struct, for an array of structs (s.t. the array size == bus size). My struct looks like

typedef struct {
  //other stuff
  logic            valid;
} BFRAME_OUTPUT;

And I've declared the array of structs and bus like

  BFRAME_OUTPUT             bframe_outs[`BSTACK_SIZE-1:0];
  logic [`BSTACK_SIZE-1:0]  valid;

I want to do something like either of these to simply make the valid bus equal to the valid bits for the array of structs.

assign valid[`BSTACK_SIZE-1:0] = bframe_outs[`BSTACK_SIZE-1:0].valid;
//
// or
//
for(int i = 0; i < `BSTACK_SIZE; ++i) begin
    assign[i] = bframe_outs[i].valid;
end

However I get errors when trying to simulate with vcs:

Error-[XMRE] Cross-module reference resolution error
/modules/branch_stack.sv, 87
  Error found while trying to resolve cross-module reference.
  token 'bframe_outs'.  Originating module 'branch_stack'.
  Source info: assign valid[(16 - 1):0] = bframe_outs[(16 - 1):0].valid;

Upvotes: 0

Views: 2116

Answers (1)

sharvil111
sharvil111

Reputation: 4381

More importantly, there is another error which you have not shown:

Error-[PSNA] Part Select Not Allowed testbench.sv, 14 Part selects are not allowed on arrays of classes. Source info: assign valid[(5 - 1):0] = bframe_outs[(5 - 1):0].valid; Convert the part select to refer to each element individually.

As the error points out, you need to convert the assignment to part selection. Here, you can use one of the two ways. Either use logic as reg and use it in always block, or use logic as wire and do some other stuff.

While using it as reg, you need to extract the value in some procedural block. So, just remove the assign statement and use alway_comb. Since you have used logic here, no need to change its datatype.

always_comb 
    begin
      for(int i = 0; i < `BSTACK_SIZE; ++i) 
        valid[i] = bframe_outs[i].valid;
    end

Alternatively, there is a generate block to perform certain things multiple times. Note that by using generate block, you are providing continuous assignments and using logic as wire. Here, you need to provide each bit signal to the wire individually. Here, use generate as follows:

  genvar i;
  generate
    for(i = 0; i < `BSTACK_SIZE; ++i) begin
      assign valid[i] = bframe_outs[i].valid;
    end
  endgenerate

Refer to SystemVerilog IEEE 1800-2012 section 7.2 for structures and this link for generate blocks. I have created a working example at EDAPlayground link.

Upvotes: 2

Related Questions