xls icon indicating copy to clipboard operation
xls copied to clipboard

codegen should generate systemverilog struct

Open proppy opened this issue 2 years ago • 4 comments

Currently we flatten all struct into a single bus, ex:

struct Operand {
  a: u8,
  b: u8,
  c: u8,
}

fn muladd(op: Operand) -> u8 {}

will generate:

module user_module(
  input wire [23:0] op,
  output wire [7:0] out
);

It would be nice if instead we generated the corresponding SystemVerilog struct construct as defined in section 7.2.1 of the 1800-2017 standard and preserve the fields names for improved readibility:

7.2.1 Packed structures A packed structure is a mechanism for subdividing a vector into subfields, which can be conveniently accessed as members. Consequently, a packed structure consists of bit fields, which are packed together in memory without gaps. An unpacked structure has an implementation-dependent packing, normally matching the C compiler. A packed structure differs from an unpacked structure in that, when a packed structure appears as a primary, it shall be treated as a single vector.

typedef struct packed {
  wire [7:0] a;
  wire [7:0] b;
  wire [7:0] c;
} Operand;

module user_module(
  input Operand [23:0] op;
  output wire [7:0] out;
);

proppy avatar Dec 26 '23 05:12 proppy

Note this might require additional tagging in the IR as it looks like struct are currently flattend as tuple:

top fn __user_module__muladd(op: (bits[8], bits[8], bits[8])) -> bits[8] {
  op_a: bits[8] = tuple_index(op, index=0, id=2, pos=[(0,9,6)])
  op_b: bits[8] = tuple_index(op, index=1, id=3, pos=[(0,9,13)])
  op_c: bits[8] = tuple_index(op, index=2, id=5, pos=[(0,9,20)])
}

proppy avatar Dec 26 '23 05:12 proppy

See also https://github.com/google/xls/issues/195 and https://github.com/google/xls/issues/394 (may be a dupe of the latter)

cdleary avatar Jan 04 '24 23:01 cdleary

It would be useful to have the ability to dump struct members as separate ports when using Verilog as an output format

rw1nkler avatar Sep 02 '24 15:09 rw1nkler

It would be nice if instead we generated the corresponding SystemVerilog struct construct as defined in section 7.2.1 of the 1800-2017 standard and preserve the fields names for improved readibility:

...

typedef struct packed {
  wire [7:0] a;
  wire [7:0] b;
  wire [7:0] c;
} Operand;

module user_module(
  input Operand [23:0] op;
  output wire [7:0] out;
);

I think for this to be more generally useful, it would be important to emit the struct (and union, enum, etc.) in a separate SV package. This allows the interface types to be shared and imported by other libraries for integrating the IP in a larger design.

mikex-oss avatar Sep 13 '24 20:09 mikex-oss