How to implement circular buffer using EMAC and MASK register?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to implement circular buffer using EMAC and MASK register?

Jump to solution
492 Views
javiercambra
Contributor II

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

 

 



 

 

 




Labels (1)
0 Kudos
1 Solution
303 Views
TomE
Specialist II

> 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


View solution in original post

0 Kudos
1 Reply
304 Views
TomE
Specialist II

> 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


0 Kudos