codegen should generate systemverilog struct
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;
);
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)])
}
See also https://github.com/google/xls/issues/195 and https://github.com/google/xls/issues/394 (may be a dupe of the latter)
It would be useful to have the ability to dump struct members as separate ports when using Verilog as an output format
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.