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.
Tool/software: Code Composer Studio
I have a piece of code that I am working on (that you guys have already helped me immensely with) that calculates the powers of 2 and places them into two separate arrays (one array for HW multiplication and one array for SW multiplication). I have all of the array logic in place and functional as well as the HW multiplier function. I have some vague documentation on how to implement the Shift-and-Add algorithm, but it doesn't actually include anything for basic integer-integer multiplication. It also doesn't include any code examples at all. If you guys have any input on how I can write a block to perform this operation, I would greatly appreciate it. I will include my code here for anyone who wishes to look at it.
.cdecls C,LIST,"msp430.h" ;Include device header file .def RESET ;Export program entry-point to ;make it known to linker. .def hcalc_power .def scalc_power .def SW_Mult .def HW_Mult .text ;Assemble into program memory. .retain ;Override ELF conditional linking ;and retain current section. .retainrefs ;And retain any sections that have ;references to current section. .data b: .int 2 ;Create variable and initialize it to 2 hval: .int 1 ;Create variable for product placement init 0 sval: .int 1 ;Create variable for product placement init 0 hwarr: .int 2, 2, 2, 2, 2 ;hw mult array swarr: .int 1, 1, 1, 1, 1 ;sw mult array RESET: mov.w #__STACK_END,SP ;Initialize stack pointer mov.w #WDTPW|WDTHOLD,&WDTCTL ;Stop watchdog timer ;------------------------------------------------------------------------------- ; Main loop ;------------------------------------------------------------------------------- main: mov.w #hwarr, R7 ;starting address of hwarr to R7 mov.w #swarr, R8 ;starting address of swarr to R8 clr.w R9 hwnext: mov.b @R7+, R9 ;get next hwarr element cmp #2, R9 ;is it a 2? jne swnext ;if not, go to swnext call #hcalc_power;calculate powers of 2 mov.w hval, 0(R7) ;put product into current array element inc.w R7 ;increment R7 or it won't fully move to next element jmp hwnext swnext: mov.w @R8+, R9 ;get next swarr element cmp #1, R9 ;is it a 1? jne lend ;if not, go to end call #scalc_power;calculate powers of 2 again jmp swnext hcalc_power: mov.w b, R5 ;pass b to register for HW_Mult subroutine mov.w hval, R6 ;ditto for hval call #HW_Mult ret scalc_power: mov.w b, R5 ;pass b to register for HW_Mult subroutine mov.w sval, R6 ;ditto for hval call #SW_Mult ret HW_Mult: mov.w R5, &MPY ;get R5 mov.w R6, &OP2 ;get R6 nop ;3 clock cycles nop nop mov RESLO, &hval;multiply and put product in hval ret SW_Mult: ret lend: nop ;------------------------------------------------------------------------------- ; Stack Pointer definition ;------------------------------------------------------------------------------- .global __STACK_END .sect .stack ;------------------------------------------------------------------------------- ; Interrupt Vectors ;------------------------------------------------------------------------------- .sect ".reset" ; MSP430 RESET Vector .short RESET .end
I have made SOME progress understanding how this should work, but it still doesn't function.
.cdecls C,LIST,"msp430.h" ;Include device header file .def RESET ;Export program entry-point to ;make it known to linker. .def hcalc_power .def scalc_power .def SW_Mult .def HW_Mult .text ;Assemble into program memory. .retain ;Override ELF conditional linking ;and retain current section. .retainrefs ;And retain any sections that have ;references to current section. .data b: .int 2 ;Create variable and initialize it to 2 hval: .int 1 ;Create variable for product placement init 0 sval: .int 1 ;Create variable for product placement init 0 hwarr: .int 2, 2, 2, 2, 2 ;hw mult array swarr: .int 1, 1, 1, 1, 1 ;sw mult array RESET: mov.w #__STACK_END,SP ;Initialize stack pointer mov.w #WDTPW|WDTHOLD,&WDTCTL ;Stop watchdog timer ;------------------------------------------------------------------------------- ; Main loop ;------------------------------------------------------------------------------- main: mov.w #hwarr, R7 ;starting address of hwarr to R7 mov.w #swarr, R8 ;starting address of swarr to R8 clr.w R9 clr.w R10 clr.w R11 mov.w b, R5 ;pass b to R5 for calc_power hwnext: mov.b @R7+, R9 ;get next hwarr element cmp #2, R9 ;is it a 2? jne swnext ;if not, go to swnext call #hcalc_power ;calculate powers of 2 -- takes 36 cc mov.w hval, 0(R7) ;put product into current array element inc.w R7 ;increment R7 or it won't fully move to next element jmp hwnext ;loop swnext: mov.b @R8+, R9 ;get next swarr element cmp #1, R9 ;is it a 1? jne lend ;if not, go to end call #scalc_power ;calculate powers of 2 again -- takes mov.w sval, 0(R8) ;put product into current array element inc.w R8 ;increment R8 or it won't fully move to next element jmp swnext ;loop hcalc_power: mov.w hval, R6 ;pass hval to R6 for HW_Mult call #HW_Mult ret scalc_power: mov.w sval, R6 ;pass R9 to R6 for SW_Mult call #SW_Mult ret HW_Mult: mov.w R5, &MPY ;get R5 mov.w R6, &OP2 ;get R6 nop ;3 clock cycles nop nop mov RESLO, &hval ;multiply and put product in hval ret SW_Mult: bit.w #1, R6 jz skp add.w R9, R5 skp: rla.w R9 rra.w R6 add.w #1, R6 cmp #16, R6 jl SW_Mult add.b #1, R15 cmp.b #4, R15 mov.w R5, 0(R8) ;jeq ret lend: nop ;------------------------------------------------------------------------------- ; Stack Pointer definition ;------------------------------------------------------------------------------- .global __STACK_END .sect .stack ;------------------------------------------------------------------------------- ; Interrupt Vectors ;------------------------------------------------------------------------------- .sect ".reset" ; MSP430 RESET Vector .short RESET .end
I think you can refer to the assemble code generated by compiler for software multiplication.
Of course it doesn't work. You are using R6 as both the loop counter and one of the arguments. But I think that you will also find that you are testing the bits in the wrong order.
I recall reading a TI document on their fixed point routines that included cycle counts for both the hardware and software versions so you might want to look that up.
**Attention** This is a public forum