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

mul 16x16

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



Joined: 12 Sep 2008
Posts: 7

View user's profile Send private message Yahoo Messenger

mul 16x16
PostPosted: Sat Nov 07, 2009 5:55 am     Reply with quote

Hello,

For my FIR filter, I need a multiplier. I use pic18f2455 and I found on his datasheet (pp 98). This is asm code for hardware multiplier.
Code:

#asm
MOVF ARG1L, W
MULWF ARG2L ; ARG1L * ARG2L ->
; PRODH:PRODL
MOVFF PRODH, RES1 ;
MOVFF PRODL, RES0 ;
;
MOVF ARG1H, W
MULWF ARG2H ; ARG1H * ARG2H ->
; PRODH:PRODL
MOVFF PRODH, RES3 ;
MOVFF PRODL, RES2 ;
;
MOVF ARG1L,W
MULWF ARG2H ; ARG1L * ARG2H ->
; PRODH:PRODL
MOVF PRODL, W ;
ADDWF RES1, F ; Add cross
MOVF PRODH, W ; products
ADDWFC RES2, F ;
CLRF WREG ;
ADDWFC RES3, F ;
;
MOVF ARG1H, W ;
MULWF ARG2L ; ARG1H * ARG2L ->
; PRODH:PRODL
MOVF PRODL, W ;
ADDWF RES1, F ; Add cross
MOVF PRODH, W ; products
ADDWFC RES2, F ;
CLRF WREG ;
ADDWFC RES3, F ;
;
BTFSS ARG2H, 7 ; ARG2H:ARG2L neg?
BRA SIGN_ARG1 ; no, check ARG1
MOVF ARG1L, W ;
SUBWF RES2 ;
MOVF ARG1H, W ;
SUBWFB RES3
;
SIGN_ARG1
BTFSS ARG1H, 7 ; ARG1H:ARG1L neg?
BRA CONT_CODE ; no, done
MOVF ARG2L, W ;
SUBWF RES2 ;
MOVF ARG2H, W ;
SUBWFB RES3
;
#endasm

This code is not running in my CCS compiler, with errors:
"This must be a Microchip mnemonic such as MOVLW or BTFSC". I have only the BTFSS, and this mnemonic is defined on my ccs compiler. What is the problem?

Then, I tried this asm code on mplab, and it works.

Thanks
yo4hsp



Joined: 12 Sep 2008
Posts: 7

View user's profile Send private message Yahoo Messenger

PostPosted: Sat Nov 07, 2009 5:56 am     Reply with quote

I need a 16x 16 multiplier with sign. For up side code, the formula is:
Code:

RES3:RES0 = ARG1H:ARG1L • ARG2H:ARG2L
= (ARG1H • ARG2H • 216) +
(ARG1H • ARG2L • 28) +
(ARG1L • ARG2H • 28) +
(ARG1L • ARG2L) +
(-1 • ARG2H<7> • ARG1H:ARG1L • 216) +
(-1 • ARG1H<7> • ARG2H:ARG2L • 216)

Thanks
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Nov 07, 2009 7:08 am     Reply with quote

Generally, you can expect your C compiler to know how to imlement signed int16 mupltiply.
What's the purpose of a DIY assembler implementation?
Guest








mul 16x16 with sign
PostPosted: Mon Nov 09, 2009 2:14 am     Reply with quote

Hello,

I need to multiply two large numbers with sign (on 16 bits), and the
results will be on 32 bits. I try the hardware multiply (pic18f2455
datasheet) and I receive lots of errors from unrecognized mnemonics.
I used pic18f2455.
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Mon Nov 09, 2009 3:17 am     Reply with quote

Like:
Code:

signed int16 a,b;
signed int32 c;

c= a*b;

Rolling Eyes
Ttelmah
Guest







PostPosted: Mon Nov 09, 2009 10:19 am     Reply with quote

var = _mul(x,y);

This is a built in function, that multiplies two 8 bit values, producing a 16bit result, or two 16bit values, producing a 32 bit result - exactly what you want... Smile
A lot more efficient than using 32bit internal arithmetic.

Best Wishes
yo4hsp



Joined: 12 Sep 2008
Posts: 7

View user's profile Send private message Yahoo Messenger

multiply 16 x 16 with sign
PostPosted: Mon Nov 09, 2009 12:55 pm     Reply with quote

ok, but "var = _mul(x,y);" is for unsigned numbers. in my filter i have a lots of coefficients and samples signed. whas i have to use??? so, i need "mul" or anything like multiplier for signed numbers with 16 bits, and results on 32 bits...

thanks,
Ttelmah
Guest







PostPosted: Mon Nov 09, 2009 1:43 pm     Reply with quote

If you look at your assembler example, all it does is test the top bits to verify the possible results that give a signed result.

Best Wishes
Guest








PostPosted: Mon Nov 09, 2009 2:34 pm     Reply with quote

Thanks, I see the testing for sign:
...
(-1 • ARG2H<7> • ARG1H:ARG1L • 2^16) +
(-1 • ARG1H<7> • ARG2H:ARG2L • 2^16)

I hope is another function for multiply with signed numbers like "_mul" for unsigned.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Nov 09, 2009 3:41 pm     Reply with quote

I think you missed the point. Ttelmah gave you a hint to solve your problem.

Let me establish a bit more: It is basic mathematics to create signed multiply when you have a routine for unsigned multiply. Only the couple of if-statements from your assembly program...
Ttelmah
Guest







PostPosted: Tue Nov 10, 2009 3:10 am     Reply with quote

and, as a further hint, the CCS #bit directive, gives an 'assembly efficient' way of testing/clearing individual bits in a variable...

Best Wishes
yo4hsp



Joined: 12 Sep 2008
Posts: 7

View user's profile Send private message Yahoo Messenger

thanks
PostPosted: Sun Nov 15, 2009 4:42 am     Reply with quote

thanks..

here my code, butt is still with errors. i think my mcu is slow for my application.

signed int32 inmultit;

signed int32 inmultire (signed int16 ARG1H, int16 ARG1L, signed int16 ARG2H, int16 ARG2L)
{ int32 PRODH = 0;
int32 PRODL = 0;
int32 PRODN = 0;
int32 PRODM = 0;

PRODH = _mul( (int16)ARG1H, (int16)ARG2H); //primii 2 octeti (0 si 1) va fi pe 16 biti
PRODM = _mul( (int16)ARG1H, (int16)ARG2L); //cei 2 octeti de mijloc (1 si 2)
PRODN = _mul( (int16)ARG1L, (int16)ARG2H); //cei 2 octeti de mijloc (1 si 2)
PRODL = _mul( (int16)ARG1L, (int16)ARG2L); //ultimii 2 octeti (2 si 3) va fi pe 16 biti

inmultit = _mul( (int16)PRODH, (int16)0x10000) + _mul( (int16)PRODM, (int16)0x100) + _mul( (int16)PRODN, (int16)0x100 ) + (int16)PRODL
- _mul( ( _mul (!bit_test(ARG1H, 3), (int16)ARG2H) ), (int16)0x10000)
- _mul( ( _mul (!bit_test(ARG1H, 3), (int16)ARG2L) ), (int16)0x100 )
- _mul( ( _mul (!bit_test(ARG2H, 3), (int16)ARG1H) ), (int16)0x10000)
- _mul( ( _mul (!bit_test(ARG2H, 3), (int16)ARG1L) ), (int16)0x100 );

return inmultit;
}

///////------------------------------------------------------------------------------
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Nov 15, 2009 5:42 am     Reply with quote

Quote:
inmultit = _mul( (int16)PRODH, (int16)0x10000) + _mul( (int16)PRODM, (int16)0x100) + _mul( (int16)PRODN, (int16)0x100 ) + (int16)PRODL
- _mul( ( _mul (!bit_test(ARG1H, 3), (int16)ARG2H) ), (int16)0x10000)
- _mul( ( _mul (!bit_test(ARG1H, 3), (int16)ARG2L) ), (int16)0x100 )
- _mul( ( _mul (!bit_test(ARG2H, 3), (int16)ARG1H) ), )
- _mul( ( _mul (!bit_test(ARG2H, 3), (int16)ARG1L) ), (int16)0x100 );
Here I am losing you... What are you trying to do?
Can you show the original mathematical equation?

Code:
(int16)0x10000
This is a bug. After the cast you will only yield the lowest 16 bits, which is 0x0000 == 0

11 multiplications will be slow and can be made a lot faster when you know that multiplying by 0x10 is the same as shifting left by 4 bits. Multiplying by 0x100 is shifting left by 8 bits, etc.
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