This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I have not understood the hardware multiplier and hence need the following clarification:
I have a 24 bit 2's complement and a 16 bit signed number and want to multiply the two using the 32X32 hardware multiplier so I do the following:
eg
A = 0xFFABCD
B= 0x1234
I load MACS32L with 0xABCD
MACS32H with 0x00FF
OP2 with 0x1234
NOP()
NOP()
NOP()
NOP()
NOP()
result = RES3<<48 | RES2<<32 | RES1<<16 | RES0
Would this give me the correct answer?
Would MACS32H loaded as 0x00FF be treated as a positive number? If I am doing something wrong here please let me know the correct procedure?
Regards
Viney Chaddha
No, it will not!
If you don’t need to accumulate, use it as follows;
int main(void) { unsigned int IntState, MPYState; signed long A; signed int B; signed long long result, *presult; WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer IntState = __get_interrupt_state(); __disable_interrupt(); MPYState = MPY32CTL0; MPY32CTL0 &= ~MPYFRAC; A = 0x0FFABCD; B = 0x01234; // 32 x 16 = 48-bit MPYS32L = A; // 16-bit Operand assumed MPYS32H = A>>16; // Override to 32-bit Operand OP2 = B; // Start multiplication //__delay_cycles(7); // Delay for the result to be ready result = RES0; result |= (unsigned long)RES1 << 16; result |= (unsigned long long)RES2 << 32; // RES3 must also be added in case of a negative result result |= (unsigned long long)RES3 << 48; // Or result = ((unsigned long long)RES3 << 48) | ((unsigned long long)RES2 << 32) | ((unsigned long)RES1 << 16) | RES0; // Or presult = (signed long long*)&RES0; result = *presult; MPY32CTL0 = MPYState; __set_interrupt_state(IntState); return 0; }
Leo,
Following is the code, it is returning 0x00000000
Let me know where I am going wrong.
Regards
Viney Chaddha
void ECG_FilterProcess(short * WorkingBuff, short * CoeffBuf, long * FilterOut) { short i; long Val_Hi; RES0 = 0; RES1 = 0; RES2 = 0; RES3 = 0; MPYS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand for ( i = 0; i < FILTERORDER/10; i++) { MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand MACS = *WorkingBuff--; // Load first operand -unsigned mult OP2 = *CoeffBuf++; // Load second operand } _delay_cycles(7); Val_Hi = (RES2<<16) | RES1; *FilterOut = Val_Hi ; // Lower 16 bits ignored as the scaling factor for filter coefficient is 2^16
**Attention** This is a public forum