SPRUJ28E November 2021 – September 2024 AM68 , AM68A , TDA4AL-Q1 , TDA4VE-Q1 , TDA4VL-Q1
Circular addressing modifies how the UTC performs address arithmetic so that addresses remain within a power-of-2 sized window. Circular addressing works by holding upper address bits constant during an address update, while allowing the lower address bits to vary. This contrasts with the default—linear addressing—which allows all of the address bits to vary.
The UTC TR provides address mode selection for each level of loop nest. Each level can select between linear addressing or circular addressing with one of two circular block sizes.
Conceptually, selectable addressing mode support replaces all address arithmetic with a function similar to the following.
enum addr_mode_t
{
LINEAR,// Linear addressing mode
CIRC0,// Circular addressing with block size 0
CIRC1// Circular addressing with block size 1
};
uint64_t circ_mask_0;// Circular addressing mask for block size 0
uint64_t circ_mask_1;// Circular addressing mask for block size 1
uint64_t address_add( uint64_t base, int32_t offset, addr_mode_t mode )
{
uint64_t new_addr = base + offset;
if ( mode == LINEAR )
return new_addr;
// Look up address mask based on selected circular buffer size.
// Mask contains 1s for bits that remain fixed, and 0s elsewhere.
uint64_t addr_mask = mode == CIRC0 ? circ_mask_0 : circ_mask_1;
return ( base & addr_mask ) | ( new_addr & ~addr_mask );
}
The address_add primitive then takes the place of plain addition for all TR address computations in this mode. The following example illustrates address_add.
for (i3 = 0; i3 < ICNT3; i3++)
{
ptr3 = ptr; // save current position before entering next level
for (i2 = 0; i2 < ICNT2; i2++)
{
ptr2 = ptr; // save current position before entering next level
for (i1 = 0; i1 < ICNT1; i1++)
{
ptr1 = ptr; // save current position before entering next level
for (i0 = 0; i0 < ICNT0; i0++)
{
fetch( ptr, ELEM_BYTES );
ptr = address_add( ptr, ELEM_BYTES, addr_mode_0 );
}
// Update based on saved pointer for this level
ptr = address_add( ptr1, DIM1, addr_mode_1 );
}
// Update based on saved pointer for this level
ptr = address_add( ptr2, DIM2, addr_mode_2 );
}
// Update based on saved pointer for this level
ptr = address_add( ptr3, DIM3, addr_mode_3 );
}
The values for the circular addressing can be selected by using the 16 bits of the AMODE specific Field as described in the AMODE SPECIFIC Addressing Mode Field.