In certain applications, it is desirable to maintain circular buffers for input data and intermediate results. Thus, circular buffer addressing is supported in VCOP.
- Support circular buffer in VLD and VST instructions in compute loops, table lookup loops, and histogram loops. No circular buffer in VTLD (table load) and VHLD/VHST (histogram bin load/store).
- Support is in pointer increment arithmetic, so no load or store in any iteration should straddle the circular buffer boundary.
- Support only 2’s power buffer size from 1Kbytes, aligned to the size. For example, 1KB circular buffer can only start/end at 1KB alignment of the memory map.
- Support is in all memory regions.
Circular buffer addressing option is encoded in the circ_buf field taking up bits 23..20 of base address:
- 0: no circular buffer addressing
- 1: circular buffer size 1K bytes
- 2: circular buffer size 2K bytes
- 3: circular buffer size 4K bytes
- 4: circular buffer size 8K bytes
- 5: circular buffer size 16K bytes
- 6: circular buffer size 32K bytes
- 7~15: reserved
The base address does not need to be aligned to the circular buffer size, in the abive example’s case, 0x400. To avoid any single load/store straddle the circular buffer boundary, the base address and the pointer increments must all be aligned to the access size of each iteration.
For example, when loading N data points of halfword data, where N = 8. Access size = 16, so the base address and any pointer increment must be aligned to multiples of 16.
Hardware adjusts the memory address for circular buffering by this process:
circ_buf = (base >> 20) & 0xF; // extract circ_buf
mask = (0x200 << circ_buf) - 1; // mask = size of buffer - 1
cbuf = (base & 0xFFFFF) & ~mask; // find base addr of buffer
addr = cbuf + (base + agen) & mask; // add offset from base of buffer
For example, base = 0x10420, agen = 0xFF0.
- Extract circ_buf field by cir_buf = (base >> 20) & 0xF = 1, indicating 1KB circular buffer size.
- Set mask = (0x200 << 1) – 1 = 0x3FF, forming the bit mask that defines the circular addressing bits versus linear, non-circular bits.
- Get rid of the circ_buf field by ANDing base with 0xFFFFF, then zero out the circular addressing bits by ANDing with the complement of mask, to get cbuf = 0x400, so the circular buffer is 0x400 ~ 0x7FF.
- Next, add the address generator value to the base address, and AND with mask to find offset from the cbuf base. (base + agen) & mask = (0x10420 + 0xFF0) & 0x3FF = 0x11410 & 0x3FF = 0x10.
- Finally, add the offset 0x10 to the circular buffer base 0x400 to get the final address, 0x410.
The agen is allowed to go over the circular buffer many times over to wrap back inside, and that agen can even go backward to wrap from the beginning to the end of the buffer.