This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Hardware Implementation

hi i created a hardware that calculates the square root of (a^2+b^2 )

i sent the inputs (a and b) with assembly and that was fine however when i tried to send them using c code the hardware take them as inputs calculates a^2 + b^2 but never do the square root

i am really clueless here i couldn't locate the problem

heeeeeeeeeeeeeeelp

Parents
  • So, if I understand correctly :

    AGAIN  
           LDR R1, =0x59000000
           LDR R0, =0x00000022
           STR R0, [R1]
           LDR R1, =0x59000000
           LDR R0, =0x00002200
           STR R0, [R1]
           B AGAIN
    ENDP
    

    0x59000000 is the address where the input should be sent. I'll call it input_address here.

    Then the first input value (a in your algebraic formulae) is retrieved from address 0x22 and stored at input_address.

    Same thing for second input value (b), which address seems to be 0x2200.

    Then, I guess, once two values provided the hardware do the whole calculation automatically ?

    In that case, do this code work in your case :

    test.c

    int calculate(int a, int b) {
    volatile int *input_address = (int*)0x59000000;
      while(1) {
        *input_address = a;
        *input_address = b;
      }
    }
    

    Compiling it with gcc like this :

    armv7a-hardfloat-linux-gnueabi-gcc -O3 -nostdlib -shared -o test.o test.c

    Generates this machine code :

    armv7a-hardfloat-linux-gnueabi-objdump -d test.o

    00000218 <calculate>:
     218:   e3a03459        mov     r3, #1493172224 ; 0x59000000
     21c:   e5830000        str     r0, [r3]
     220:   e5831000        str     r1, [r3]
     224:   eafffffc        b       21c <calculate+0x4>
    

    Which is roughly the same.

    In any case, in your provided code, did you try this instead :

    int main() {
    the_old_days:
      
      xd[0]=0;
      yd[0]=0;
      int i;
      for(i=0;i<9;i++){ /* with i < 10, when i = 9, xd[i+1] will be equal to xd[10] which is out of bounds */
        xd[i+1]= xd[i]+1;
        yd[i+1]= yd[i]+1;
        regdistance = xd[i];  
        regdistance = yd[i];  
      }
    
      goto the_old_days;
    }
    
Reply
  • So, if I understand correctly :

    AGAIN  
           LDR R1, =0x59000000
           LDR R0, =0x00000022
           STR R0, [R1]
           LDR R1, =0x59000000
           LDR R0, =0x00002200
           STR R0, [R1]
           B AGAIN
    ENDP
    

    0x59000000 is the address where the input should be sent. I'll call it input_address here.

    Then the first input value (a in your algebraic formulae) is retrieved from address 0x22 and stored at input_address.

    Same thing for second input value (b), which address seems to be 0x2200.

    Then, I guess, once two values provided the hardware do the whole calculation automatically ?

    In that case, do this code work in your case :

    test.c

    int calculate(int a, int b) {
    volatile int *input_address = (int*)0x59000000;
      while(1) {
        *input_address = a;
        *input_address = b;
      }
    }
    

    Compiling it with gcc like this :

    armv7a-hardfloat-linux-gnueabi-gcc -O3 -nostdlib -shared -o test.o test.c

    Generates this machine code :

    armv7a-hardfloat-linux-gnueabi-objdump -d test.o

    00000218 <calculate>:
     218:   e3a03459        mov     r3, #1493172224 ; 0x59000000
     21c:   e5830000        str     r0, [r3]
     220:   e5831000        str     r1, [r3]
     224:   eafffffc        b       21c <calculate+0x4>
    

    Which is roughly the same.

    In any case, in your provided code, did you try this instead :

    int main() {
    the_old_days:
      
      xd[0]=0;
      yd[0]=0;
      int i;
      for(i=0;i<9;i++){ /* with i < 10, when i = 9, xd[i+1] will be equal to xd[10] which is out of bounds */
        xd[i+1]= xd[i]+1;
        yd[i+1]= yd[i]+1;
        regdistance = xd[i];  
        regdistance = yd[i];  
      }
    
      goto the_old_days;
    }
    
Children
  • as i told M

    Peter Harris

    I don't why my keil can't allocate a memory address with a pointer however i think that the problem is within the def of the "attribute" which allocate a fixed address that can't be reused by another

    i tried to differentiate the output of yd and xd and  when i compiled my code i observed that regdistance take only the value of xd so i defined another address memory to put the yd and when i simulate my hardware behavior i found that now it calculates the a^2+b^2   but not the square root

    if anyone has a suggestion or any idea how can i resolve this prob please help

  • Well, can you use objdump -d on the bugged binary file and paste the output here.

    I do not think that the variable definition is the problem here. However, one way to be sure is to try defining regdistance within main like this :

    volatile int *regdistance = (int*)0x59000000;

    And see if it works.

    Note that you might want to replace

    for (i = 0; i < 10; i++)
    

    by

    for (i = 0; i < 9; i++)
    

    else you will write into places you did not define (xd[9+1] is not defined).

    However, the "at" behaviour can also be emulated doing something like :

    test.c

    volatile int input_address __attribute__ ((section ("regdistance")));
    
    int calculate(int a, int b) {
      while(1) {
        input_address = a;
        input_address = b;
      }
    }
    

    Using a linker script like this :

    test.ld

    ENTRY(calculate)

    SECTIONS

    {

      . = 0x10000;

      .text : { *(.text*) }

      . = 0x59000000;

      .regdistance : { *(regdistance*) }

    }

    And then compile like this :

    armv7a-hardfloat-linux-gnueabi-gcc -O3 -nostdlib -mthumb -T test.ld -o test test.c

    Code produced :

    LANG=C armv7a-hardfloat-linux-gnueabi-objdump -d test

    test:    file format elf32-littlearm

    Disassembly of section .text:

    00010000 <calculate>:
      10000:      f240 0300      movw    r3, #0
      10004:      f6c5 1300      movt    r3, #22784      ; 0x5900
      10008:      6018            str    r0, [r3, #0]
      1000a:      6019            str    r1, [r3, #0]
      1000c:      e7fc            b.n    10008 <calculate+0x8>
      1000e:      bf00            nop