CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

MAC instruction Assembly dsp 4.092 mysterious

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ddorling



Joined: 24 Dec 2007
Posts: 13

View user's profile Send private message Send e-mail

MAC instruction Assembly dsp 4.092 mysterious
PostPosted: Tue May 19, 2009 5:46 pm     Reply with quote

Can someone see what's going wrong here.

A simple snippet using the MAC instruction. I thought the instruction pretches for the next instruction, so loaded the first values myself.
The prefetche operations appear correct and the data registers have the correct values at the post instruction step.

This is the disassembly listing for the MAC instruction MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6
Code:
mac 0x000a*0x000c,a,[0x0010]+=2,0x000a,[0x0014]+=2,0x000c

Here's the wacky stuff.

The first accum prefetches for the next instruction but doubles a correct(15) result.

The second accum prefetches for the next instruction accumulates a correct(0) result but then doubles this result. Shouldn't have changed at all.

The third accum prefetches for the next instruction but accumulates a zero result where the accumlation should have been -5. doesn't seem to have done the multiply.

The fourth accum prefetches for the next instruction but accumulates a -10 result where the accumlation should have been -5

The fifth accum prefetches for the next instruction but accumulates a -8 result where the accumlation should have been -6


Code:
//CCS Compiler ver 4.092

#include <30F3013.h>
#device ICD=TRUE

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES EC_IO                    //External clock
#FUSES PR                       //Primary Oscillator
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES WPSB16                   //Watch Dog Timer PreScalar B 1:16
#FUSES WPSA512                  //Watch Dog Timer PreScalar A 1:512
#FUSES PUT64                    //Power On Reset Timer value 64ms
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV47                   //Brownout reset at 4.7V
#FUSES LPOL_HIGH                //Low-Side Transistors Polarity is Active-High (PWM 0,2,4 and 6)
#FUSES HPOL_HIGH                //High-Side Transistors Polarity is Active-High (PWM 1,3,5 and 7)
#FUSES NOPWMPIN                 //PWM outputs drive active state upon Reset
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
#FUSES DEBUG                    //Debug mode for use with ICD
#FUSES NOCOE                    //Device will reset into operational mode
#FUSES ICSP1                    //ICD uses PGC1/PGD1 pins
#FUSES RESERVED                 //Used to set the reserved FUSE bits

#use delay(clock=20000000)

#word ACCA=0x022

#BankX signed int ACoef[5]={5,0,-5,-2,3};
#BankY signed int Xdata[5]={3,0, 1, 2,-2};

int *ptrAcoef,*ptrXdata;
   
void main()
{
   setup_wdt(WDT_OFF);
   setup_timer1(TMR_DISABLED);

   ptrAcoef= ACoef;
   ptrXdata= Xdata;

 *ACCA=0;

ptrAcoef= ACoef;  //set coef pointers
ptrXdata= Xdata;  //set data pointers
#asm

MOV ptrAcoef,W8            //load coef address
MOV ptrXdata,W10     //load data address

MOV Acoef[0],W5        //move first values to registers
MOV Xdata[0],W6

   // xx? accA result   (xx) correct result   +(x*x) operation

//accumulate terms
nop
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6   //30? (15)  +(5*3)
nop
nop
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6   //60? (15)  +(0*0)
nop
nop
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6   //60? (10)  +(-5*1)
nop
nop
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6   //50? (6)   +(-2*2)
nop
nop
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6   //42? (0)   +(3*-2)
nop
nop

#endasm

}

Wink Wink
ddorling



Joined: 24 Dec 2007
Posts: 13

View user's profile Send private message Send e-mail

accumulator doubling multiply result
PostPosted: Tue May 19, 2009 8:58 pm     Reply with quote

Here is some more info.
Rather than using the prefetch part of the instruction I move the data directly into the registers. This works except that the accumulator adds a doubling of the multiply result.
Code:

#asm

MOV ptrAcoef,W8       //load coef address
MOV ptrXdata,W10     //load data address

    //accumulate terms
nop
MOV Acoef[0],W5   
MOV Xdata[0],W6
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6  //30? (15)  +(5*3)
nop
nop
MOV Acoef[1],W5   
MOV Xdata[1],W6
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6  //30? (15)  +(0*0)
nop
nop
MOV Acoef[2],W5   
MOV Xdata[2],W6
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6  //20? (10)  +(-5*1)
nop
nop
MOV Acoef[3],W5   
MOV Xdata[3],W6
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6  //12? (6)   +(-2*2)
nop
nop
MOV Acoef[4],W5   
MOV Xdata[4],W6
MAC w5*w6,A,[w8]+=2,w5,[w10]+=2,w6  //0? (0)   +(3*-2)
nop
nop

#endasm

Shocked
sevak
Guest







Re: accumulator doubling multiply result
PostPosted: Wed Jul 15, 2009 12:28 am     Reply with quote

Hi,

Have you got the reason why it is happening so?

If you got the reason please let me know. I am facing the same problem but not getting anything. Confused
ddorling



Joined: 24 Dec 2007
Posts: 13

View user's profile Send private message Send e-mail

MAC assembly 30f
PostPosted: Thu Jul 16, 2009 1:37 am     Reply with quote

Hi
I am just an average programmer and came to the conclusion that the MAC assembly instruction isn't implemented in the CCS compiler to accomplish what it is suppose to do according to the microchip specification. This conclusion I arrived at by default, since my request to CCS and this forum had zero response. Since I needed this instruction for a filtering application I had to resort to the C30 compiler.

I hope you didn't have the frustration I did since I usually think it's my programming causing the problem. Unfortunately I wasted too many days banging my head against the wall before reaching the conclusion.

I don't think the CCS compiler has much functionality regarding the 24f and 30f family and heavens to mercy don't even think about the 33f family.

I wish CCS would respond or a programmer knowledgeable in CCS and say my statement is incorrect. This would make me very happy since I liked the compiler for 8 bit chips and wish I could use the compiler for 16 bit chips. But the improvements to the compiler, now 4.093? show that improving and fixing 16 bit functionality is low priority.

CCS has a daunting task, when you think about it, accommodating so many different chips. They do a good job providing a user friendly programming environment for the 8 bits but the 16 bit are in another league of capability. I wish CCS would make a statement about this regarding the functionality of their compiler regarding the 16 bit chips. From the advertising on their website you think the compiler can get the job done to tame these 16 bit animals but this is far from true.

Unfortunately there has been an expense to my $ to find this out, one year maintenance plan and PCD.

You can download the C30 compiler for free and it will provide full optimization for 60 days. For me it is a matter of time before I can afford the expense to buy C30 but until then reboot computer and reload, and endure the inconvenience. And I'll continue to use CCS for 8 bit animals.

Good Luck
ddorling

C30 code for digital filter
Code:
#include "p30f3013.h"

#include "dsp.h"  //some or all of the includes not necessary for this snippet
#include "spi.h"
#include "libpic30.h"
#include "math.h"

//BP3 1152  Microchip elliptic 1152
signed int   XYdata3[6] _YDATA(32) = {0,0,0,0,0,0}; // input/output samples
signed int   ABcoef3[6] _XDATA(32) = {1275,0,-1275,-16392,22620,-13833}; // BCoef negated
int         ACCUMAold3[3]_XDATA(16) ={0,0,0};
int       BPout3=0;

int *ADCptr0;    //ADC Buffer0
int audio_in0=0, 

void ADC_Init(void);

int main (void)
{
loop:
   ADC_Init();

//**********  Get New Audio Samples
IFS0bits.ADIF = 0; // clear ADC interrupt flag
ADCON1bits.ASAM = 1; // auto start sampling
while (!IFS0bits.ADIF);// // conversion done?
ADCON1bits.ASAM = 0; // yes then stop sample/convert
audio_in0= ADCBUF0;  // audio sample

//***************************************************
//**********  BP3  IIR 
   //shift the old samples x0 x1 x2 y0 y1 y2            

   XYdata3[5]=XYdata3[4]; XYdata3[4]=XYdata3[3]; //XYdata[3] is Y0
   XYdata3[2]=XYdata3[1]; XYdata3[1]=XYdata3[0]; //XYdata[0] is X0
                     
   XYdata3[0] = audio_in0;      //place new audio sample

// accum results are restored and saved if more than one filter is calculated, say BP1,BP2,BP3

   ACCAL= ACCUMAold3[0];     //restore accum result
    ACCAH= ACCUMAold3[1];
   ACCAU= ACCUMAold3[2];

   WREG8=  (int)ABcoef3;       //load coef address
   WREG10= (int)XYdata3;

asm("MOVSAC A,[w8]+=2,w4,[w10]+=2,w5");
asm("MAC w4*w5,A,[w8]+=2,w4,[w10]+=2,w5");
asm("MAC w4*w5,A,[w8]+=4,w4,[w10]+=4,w5");
asm("MAC w4*w5,A,[w8]+=2,w4,[w10]+=2,w5");
asm("MAC w4*w5,A,[w8]+=2,w4,[w10]+=2,w5");
asm("MAC w4*w5,A");

asm("SFTAC A,#0xF");        //divide by BCoef[0]
                            //plus a RS to adjust for double accumulation behavior

XYdata3[3]= (int)ACCAL;   //save new Y[0]

ACCUMAold3[0]=ACCAL;         //save accum result
ACCUMAold3[1]=ACCAH;
ACCUMAold3[2]=ACCAU;

BPout3= abs(XYdata3[3])<<1;

goto loop;
return(0);}

//*****************************************************
//*****************************************************
void ADC_Init(void)
{
/*
Sampling is a sequence an0. The method uses the internal counter
SSRC, to carry out a sampling period, when finished automaticly converts.
Setting ASAM=1 starts sampling the sequence and automatically repeats samplng
after each conversion. Each ANx is connected to CH0 in sequence for sampling.
When the sequence is finished an intterupt flag is set. Method waits until the
flag is set. Then turns off ASAM. Results are placed sequentially in the Buffers.
*/
_TRISB0=1;_TRISB1=1;  //RB0 RB1 as inputs
//---------------------------------------------------------
        //(ADCON1 Register)
ADCON1=0b0000000011100000;
ADCON1bits.SSRC=7;   //<7-5> internal counter ends sampling and starts covert
ADCON1bits.FORM=0;   //<9-8> integer out
ADCON1bits.ADON=0;   //<15>  adc OFF
//-------------------------------------------------------------
        //(ADCON2 Register)
ADCON2=0b0000000000000000;
ADCON2bits.SMPI = 1;   //<5:2> interupt sequence 0f 2***
ADCON2bits.BUFM = 0;    //<1> single 16 word result buffer***
ADCON2bits.ALTS = 0;   //<0> use MUX A input select***
ADCON2bits.CSCNA = 1;   //<10> scan CH0+ Input MUX A***
ADCON2bits.VCFG = 0;    //<15:13> voltage reference vdd-vss
//------------------------------------------------------------
        //(ADCON3 Register)
ADCON3=0b0000111100000000;
ADCON3bits.SAMC = 7;   //<12:8> auto sample time is is 15 TAD   
ADCON3bits.ADRC = 0;   //<7> conversion clock is System Clock
ADCON3bits.ADCS = 3;   //<5:0>conversion clock speed
//-----------------------------------------------------------
        //(Input select Register)
ADCHS = 0b0000000000000000;
//ADCHSBITS.CHOSA=0;        //CSNA overides this
//ADCHSBITS.CHONA=0;        //select Vref- as negative for Mux A***
//-------------------------------------------------------------------
        //(Port configuration Register)
ADPCFG = 0b1111111111111100;   //Set channel AN0 AN1 as analog***   
//-----------------------------------------------------------
        //Input select scan Register
ADCSSL = 0b0000000000000011;   //Scan AN0 AN1***       
//--------------------------------------------------------------------
ADCON1bits.ADON = 1;   //Turn on the A/D converter

return;
}
Sad
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group