Search code examples
dml-lang

Register array with a field in only one of the registers in DML 1.4


I want to make a register array, where one of the registers should include a field in bit 0 with a value of 1.

I have tried using a conditional without any success.

register feature_bits[i < N_FEATURE_SELECT_REGS] size 4 is unmapped {
    #if (i == 1) {
        field virtio_f_version_1 @ [0] "VIRTIO_F_VERSION_1" {
            param init_val = 1;
        }
    }
}

I have also tried indexing the register element and set the field accordingly

register feature_bits[i < N_FEATURE_SELECT_REGS] size 4 is unmapped;
register feature_bits[1] {
    field VIRTIO_F_VERSION_1 @ [0] {
        param init_val = 1;
    }
}

None of these approaches worked.


Solution

  • If we take a step back and look at what you're trying to accomplish here, it's possible that a third option can be usable. If it's only the init-value of some fields that differs, you can create a template type and iterate over it like this:

    template feature_bit {
        param lsb : uint64;
    }
    
    bank regs is (init, hard_reset) {
        register features[i < 4] size 4 @ unmapped;
    
        method init() {
            foreach f in (each feature_bit in (this)) {
                features[f.lsb / 32].val[f.lsb % 32] = 1;
            }
        }
    
        method hard_reset() {
            init();
        }
    
        group featA is feature_bit { param lsb = 42; }
        group featB is feature_bit { param lsb = 3; }
    }
    

    The init-template is depth-first recursive, so the feature registers will be initialized first, and then the init() method of the bank will run and set the value of the feature-registers by iterating over all instances of the feature_bit template. We also call init from hard_reset, which is also depth-first recursive, otherwise the register will be 0 after reset.