struct.sv 2.14 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
`default_nettype none

typedef logic [31:0] Word_t;

// "packed" structs are effectively a single bit-vector that has syntactic sugar
// "for access specific parts
typedef struct packed {
    Word_t data;
    logic valid;
} InnerStruct_t;

typedef enum {MODE_A, MODE_B} Mode_t;

typedef struct packed {
  InnerStruct_t inner;
  Mode_t mode;
} OuterStruct_t;

module Example(
    input logic clock, clear,
    output logic success
);

    Word_t data_in, data_out;
    logic valid_in, valid_out;
    Mode_t mode_in, mode_out;
    OuterStruct_t object;

    always_ff @(posedge clock) begin
        if(clear) begin
            data_in <= 32'h0;
            valid_in <= 1'b0;
            mode_in <= MODE_A;
        end else if(mode_in == MODE_A) begin
            valid_in <= 1'b1;
            mode_in <= MODE_B;
            // $bits is a built-in SystemVerilog function that determines how
            // wide a data-type is (like sizeof in C)
            data_in <= data_in + $bits(object);
        end else begin
            mode_in <= MODE_A;
            data_in <= data_in + 32'h1;
            valid_in <= 1'b1;
        end
    end

    StructCompose compose(
        .data(data_in),
        .valid(valid_in),
        .mode(mode_in),
        .object
    );

    StructDecompose decompose(
        .data(data_out),
        .valid(valid_out),
        .mode(mode_out),
        .object
    );

    always_comb begin
        success = 1'b0;
        if(data_in == data_out)
            if(valid_in == valid_out)
                if(mode_in == mode_out)
                    success = 1'b1;
    end

endmodule

module StructCompose(
    input Word_t data,
    input logic valid,
    input Mode_t mode,
    output OuterStruct_t object
);

    always_comb begin
        object = '{
            inner: '{
                data: data,
                valid: valid
            },
            mode: mode
        };
    end

endmodule

module StructDecompose(
    input OuterStruct_t object,
    output Word_t data,
    output logic valid,
    output Mode_t mode
);

    always_comb begin
        data = object.inner.data;
        valid = object.inner.valid;
        mode = object.mode;
    end

endmodule