2.7.3. Addressable port arrays

Port arrays can also be addressable. The declaration for addressable port arrays is the same as for port arrays except for the addition of the addressable keyword. The following declaration is for an array of five addressable master ports, named pa, that implement the MyProtocol protocol:

addressable master port<MyProtocol> pa[5];

Note

The addressable keyword can also be used with slave port arrays, but it has no effect.

Connection of addressable port arrays

Connecting individual elements of addressable port arrays requires an indexing scheme and specification of an address range. Because port index and port address ranges both appear in square brackets, it is necessary to observe a proper sequence between the two specifiers:

  • The port index must be located after the array identifier.

    m[2] specifies the third port in port array m.

  • Address ranges must be located after the port index.

    m[0][0x0..0xF] specifies address range 0x0-0xF of the first port.

If you specify a connection in which a port array participates, you must supply an address range after the name of the port array. Example 2.29 shows how addressable port arrays are connected:

Example 2.29. Connection of addressable port arrays

protocol MyProtocol { /* protocol behaviors */ }

component Foo
{
addressable master port<MyProtocol> addr_mPortArray[4];
}

component Bar
{
slave port<MyProtocol> sPort;
slave port<MyProtocol> sPortArray[4];
}

component MyComponent
{
    composition
    {
        foo : Foo;
        bar : Bar;
    }

    connection
    {
        // single to single
        foo.addr_mPortArray[2][0x0..0xF] => bar.sPortArray[0x10..0x1F];
        foo.addr_mPortArray[2][0x0..0xF] => bar.sPortArray[3][0x10..0x1F];
    
        // single to array
        foo.addr_mPortArray[2][0x0..0xF] => bar.sPortArray[0x10..0x1F];
    
        // array to single
        foo.addr_mPortArray[0x0..0xF] => bar.sPortArray[3][0x10..0x1F];
    
        // array to array
        foo.addr_mPortArray[0x0..0xF] => bar.sPortArray[0x10..0x1F];
    }
}

Note

Addressable port arrays that appear in connection statements are expanded just like non-addressable ones, but with the addition of the address range specification

Note

Single-to-array connections are not applicable to addressable port arrays because the overlapping range conflicts are resolved by the order of declaration. This type of connection is always broken down to a sequence of single-to-single connections between the master port and each element of the slave port array, in ascending order. For the example given above, it would be:

foo.addr_mPortArray[2][0x0..0xF] => bar.sPortArray[0][0x10..0x1F];
foo.addr_mPortArray[2][0x0..0xF] => bar.sPortArray[1][0x10..0x1F];
foo.addr_mPortArray[2][0x0..0xF] => bar.sPortArray[2][0x10..0x1F];
// last declaration for the [0x0..0xF] range: has priority
foo.addr_mPortArray[2][0x0..0xF] => bar.sPortArray[3][0x10..0x1F];

Therefore, a single-to-array connection between addressable ports is equivalent to a single-to-single connection between the master port and the last element of the slave port array.

Addressable port arrays implementation

Addressable port arrays combine the features of addressable ports and port arrays. This means that slave methods must add the ADDRESS keyword before the address parameter and the extra unsigned int parameter for the array index:

Example 2.30. Implementation of addressable port arrays

protocol SimpleProtocol
{
    slave behavior read(ADDRESS uint32_t address);
}

slave port<SimpleProtocol> s[4]
{
    slave behavior read(unsigned int portIndex, ADDRESS uint32_t address)
    {
        // behavior implementation
    }
}

Using addressable port arrays in behaviors

Addressable port arrays are to be used in LISA+ behaviors just like normal port arrays. As is used in the connection section, the requirement to designate specific elements of a port array is managed by the use of indices in square brackets:

Example 2.31. Using addressable ports in behaviors

protocol SimpleProtocol
{
    slave behavior read(ADDRESS uint32_t address);
}

component Foo
{
    addressable master port<SimpleProtocol> addr_mPortArray[2];
}

component Bar
{
    slave port<SimpleProtocol> sPortArray[2]
    {
        slave behavior read(unsigned int portIndex, ADDRESS uint32_t address)
        {
            printf("index: %d, address: 0x%x\n", portIndex, address);
        }
    }
}

component Bar
{
    connection
    {
        foo.addr_mPortArray[0x0..0xF] => bar.sPortArray[0];
        foo.addr_mPortArray[0x10..0x1F] => bar.sPortArray[1];
    }

    behavior callRead()
    {
        foo.addr_mPortArray[0].read(0xA);
        foo.addr_mPortArray[1].read(0xE);
        foo.addr_mPortArray[0].read(0x12);
        foo.addr_mPortArray[1].read(0x1C);
    }
}

The standard output of behavior callRead() is:

index: 0, address: 0xaindex: 0, address: 0xeindex: 1, address: 0x12index: 1, address: 0x1c
Copyright © 2007-2010 ARM Limited. All rights reserved.ARM DUI 0372I
Non-Confidential