Hello,
I need to implement a circular buffer for DSP purposes. I am optimizing a code using EMAC unit. I am using the mac instruction with MASK register:
For example, in a simple test: MASK = 0xF0000F and loading A5 with value 0x00800004 (init address of my data buffer)
Doing a loop with:
mac.l d0, d5, (a5)+&, d5, acc0
I am getting the following address sequence:
0x00800004 OK
0x00800008
0x0080000c
0x00800000 BAD
0x00800004 OK
0x00800008
0x0080000c
0x00800000 BAD
0x00800004 OK
0x00800008
0x0080000c
I undestand what is happening, but I want a circular buffer like code below..., I don't want reset to the address 0x00800000 every time.
0x00800004
0x00800008
0x0080000c
0x00800004
0x00800008
0x0080000c
Has anybody an idea of how to implement a circular buffer, for any start address, using only the mac instruction with the mask?
Processor: ColdFire V1+ 51QM128VLH
Thanks
Javier
已解决! 转到解答。
> Has anybody an idea of how to implement a circular buffer, for any start address,
Yes. You can't do it that way. Can ordinary DSPs manage that trick?
From the "ColdFire® Family Programmer’s Reference Manual":
1.3.3 MAC Mask Register (MASK)
Only the low-order 16 bits of the 32-bit mask register (MASK) are implemented ...
When used by an instruction, this register is ANDed with the specified
operand address. Thus, MASK allows an operand address to be effectively
constrained within a certain range defined by the 16-bit value.
So the address range has to be "0, 4, 8, 12, 0, ..." and so on.
> MASK = 0xF0000F
Only the lower 16 bits work. I would have used 0xFFEF to prevent the rollover.
You could always write the code to use the auto-increment, but to manually set the address in an unrolled loop
start:
Load the addresses
MAC (whatever, Rn+)
MAC (whatever, Rn+)
MAC (whatever, Rn+)
Decrement, branch back to start.
Assuming you're trying to implement a filter with three constant parameters that you want to loop over, you could always "unroll the constants" Instead of an array of 3 constants, unroll them into (say) 8 sequential copies of the three constants, and then have the MAC instruction increment through that longer array, resetting the address at the end of the unrolled loop.
Tom
> Has anybody an idea of how to implement a circular buffer, for any start address,
Yes. You can't do it that way. Can ordinary DSPs manage that trick?
From the "ColdFire® Family Programmer’s Reference Manual":
1.3.3 MAC Mask Register (MASK)
Only the low-order 16 bits of the 32-bit mask register (MASK) are implemented ...
When used by an instruction, this register is ANDed with the specified
operand address. Thus, MASK allows an operand address to be effectively
constrained within a certain range defined by the 16-bit value.
So the address range has to be "0, 4, 8, 12, 0, ..." and so on.
> MASK = 0xF0000F
Only the lower 16 bits work. I would have used 0xFFEF to prevent the rollover.
You could always write the code to use the auto-increment, but to manually set the address in an unrolled loop
start:
Load the addresses
MAC (whatever, Rn+)
MAC (whatever, Rn+)
MAC (whatever, Rn+)
Decrement, branch back to start.
Assuming you're trying to implement a filter with three constant parameters that you want to loop over, you could always "unroll the constants" Instead of an array of 3 constants, unroll them into (say) 8 sequential copies of the three constants, and then have the MAC instruction increment through that longer array, resetting the address at the end of the unrolled loop.
Tom