# imports import array import time import machine #==== SIO ============================ # register adddresses for SIO # datasheet page 40 sio_base = 0xd0000000 sio_base_upper = 0xd000 # divider DIV_UDIVIDEND = 0x060 + sio_base DIV_UDIVISOR = 0x064 + sio_base DIV_SDIVIDEND = 0x068 + sio_base DIV_SDIVISOR = 0x06c + sio_base DIV_QUOTIENT = 0x070 + sio_base DIV_REMAINDER = 0x074 + sio_base DIV_CSR = 0x078 + sio_base DIV_CSR_ready = 1 # bit 0 reads 1 when divide complete # === asm interface mem =============== # test assembler # a[5] is sio_base # a[4] is number of interations # a[3] is remainder # a[2] is quotient # a[1] is dividend # a[0] is divisor asm_mem=array.array('i',[ 7, 36, 0, 0, 1000000, sio_base]) #======================================= @micropython.viper def hw_div(asm_mem): machine.mem32[DIV_SDIVISOR] = asm_mem[0] machine.mem32[DIV_SDIVIDEND] = asm_mem[1] while not(machine.mem32[DIV_CSR] & DIV_CSR_ready): pass asm_mem[3] = machine.mem32[DIV_REMAINDER] # read quotient LAST asm_mem[2] = machine.mem32[DIV_QUOTIENT] print('========') hw_div(asm_mem) print ('HW div', asm_mem[0], asm_mem[1], asm_mem[2], asm_mem[3]) #======================================= def sw_div(asm_mem): # integer divides asm_mem[2] = asm_mem[1] // asm_mem[0] asm_mem[3] = asm_mem[1] % asm_mem[0] print('========') asm_mem=array.array('i',[ 7, 36, 0, 0, 100000, sio_base]) sw_div(asm_mem) print ('SW div', asm_mem[0], asm_mem[1], asm_mem[2], asm_mem[3]) #======================================== # now code to run a loop of # retreive-divide-store # assembler is 1 cycle/instruction # except for load, store and branch whihc are two # r7 is max iteration coount # r6 is current iteration count # r5 is data read from asm_mem # r4 is pointer to store in memory # r3 # r2 # r1 # r0 is pointer to asm_mem array (and return value) # DIV_SDIVIDEND = 0x068 + sio_base # DIV_SDIVISOR = 0x06c + sio_base # DIV_QUOTIENT = 0x070 + sio_base # DIV_REMAINDER = 0x074 + sio_base @micropython.asm_thumb def asm_div_loop(r0): # initialize counter ldr(r7,[r0,16]) # get a[4], the iteration count mov(r6, 0) # initialize counter # move divisor to HW reg ldr(r5,[r0,0]) # get a[0] divisor ldr(r4, [r0,20]) # get sio_base str(r5, [r4, 0x6c]) # store signed divvisor # ### compute loop label(loop_pt) # move dividend to HW reg ldr(r5,[r0,4]) # get a[1] dividend str(r5, [r4,0x68]) # store divvidend and start divide # wait 8 cycles for divide to finish nop() nop() nop() nop() nop() nop() nop() nop() # move quotient to mem arrray ldr(r5, [r4,0x70]) str(r5, [r0,8]) # quotient -> a[2] # move remaninder to mem arrray ldr(r5, [r4,0x74]) str(r5, [r0,12]) # remainder -> a[3] # inc loop counter, compare, jump add(r6, 1) # increment the counter cmp(r6, r7) # above limit? ble(loop_pt) #back to loop_pt # use the assembler loop routine def timing_div_loop(): t0 = time.ticks_us() asm_div_loop(asm_mem) t1 = time.ticks_us() # print('========') print('asm_divloop_time =',((t1-t0))/asm_mem[4], 'count=', asm_mem[4]) # at 130 MHz clock rate, and # a loop count of 24 cycles, one # pass through the loop should take # 184 nSec. # asm_mem=array.array('i',[ 7, 36, 0, 0, 100000, sio_base]) timing_div_loop() print ('asm div', asm_mem[0], asm_mem[1], asm_mem[2], asm_mem[3]) #