Previous - Up - Next

5.3   Interfaces

5.3.1   Using Interfaces

Using an interface in a module implemented in DML, is done by connecting an object to the device model you are developing, specifying which interfaces you are planning to use.

The connect statement actually perform two steps at the same time: it defines an attribute that can take an object as a value, and it tells the DML compiler that a number of interfaces belonging to this object can be used in the current device model.

The following code will create an irq_dev attribute that accepts only objects implementing the simics_interrupt interface as a value.

connect irq_dev {
    parameter documentation = "The device that interrupts are sent to.";
    parameter configuration = "required";

    interface simple_interrupt;
}

Once an object has been connected, using the interfaces that were specified is simple:

    ...
    if ($irq_raised == 0 && irq == 1) {
        log "info", 3: "Raising interrupt.";
        $irq_dev.simple_interrupt.interrupt($irq_dev, $irq_level);
    }
    ...

5.3.2   Implementing an Existing Interface

Implementing an existing interface in DML is done with the implement statement, which contains the implementation of all the functions listed in the interface. The interface is automatically registered by the DML compiler so that other objects can use it on the current device model:

implement ethernet_device {
    // Called when a frame is received from the network.
    method receive_frame(conf_object_t *link, dbuffer_t *frame) {
        inline $receive_packet(frame);
    }

    // Link speed negotiation functions. Unimplemented, we accept any speed.
    method auto_neg_request(phy_speed_t req_speed)->(phy_speed_t speed) {
        log "unimplemented", 2:
            "Link auto negotiation request (0x%llx)", cast(req_speed, uint64);
        speed = req_speed;
    }
    method auto_neg_reply(phy_speed_t speed) {
        log "unimplemented", 2:
            "Auto negotiation reply (0x%llx)", cast(speed, uint64);
    }
}

5.3.3   Implementing an New Interface

Implementing a new interface is pretty much the same as implementing an existing interface, except that you must declare the structure defining the interface first:

struct myifc_interface_t {
    int (*my_function)(conf_object_t *o, int i);
}

implement myifc {
    method my_function(int i) -> (int j) {
        j = i + 1;
    }
}

There are a few things to remember:

Previous - Up - Next