Shop OBEX P1 Docs P2 Docs Learn Events
Propeller Object: Assembly Function Engine Demo (A method for Hybrid Spin/Assem — Parallax Forums

Propeller Object: Assembly Function Engine Demo (A method for Hybrid Spin/Assem

Beau SchwabeBeau Schwabe Posts: 6,548
edited 2007-03-28 19:46 in Propeller 1
Here is a demonstration of how to setup an Assembly Engine running in it's own cog that houses functions which can be called from any Spin program.

This DEMO is designed to be a template only. It was originally derived from the 'graphics.spin' object, so you should see some similarities. The Demo
functions in the Assembly program return Sine, Cosine, and Arcsine ...but anyone can add their own Assembly routines to satisfy their own criteria.
Sine and Cosine are returned from the Propeller's internal lookup table, while the Arcsine function uses an 11-itteration successive approximation reverse
lookup routine, also using the Propeller's internal Sine table.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe

IC Layout Engineer
Parallax, Inc.

Post Edited (Beau Schwabe (Parallax)) : 8/14/2006 3:13:37 AM GMT

Comments

  • Graham StablerGraham Stabler Posts: 2,507
    edited 2006-08-14 12:21
    Now that is VERY useful!

    thanks

    Graham
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-25 11:49
    Beau, I'm just trying to use your code to form the structure of a cordic engine that should in the end do most trigometric operations, hyperbolic operations and some linear.

    Can I first ask a stupid question, in a typical function:

    PUB Sine(Ang)|Arg1_             ' Input = 13-bit angle ranging from 0 to 8191
                                    'Output = 16-bit Sine value ranging from $FFFF0001 ('-1') to $0000FFFF ('1')
        setcommand(_Sine, @Ang)
        Result := Arg1_
    
    



    How does Arg1_ get a value assigned when the result is written to Ang? And am I right in saying that if you want multiple arguments you make sure they are contigious and just pass the first?

    And a less stupid question, how do you think I should implement functions with multiple returned variables?

    Thanks

    Graham
  • Chad GeorgeChad George Posts: 138
    edited 2007-03-25 18:44
    I've always liked the structure of the graphics objects. This helps having the core functionality seperated.

    One question, it looks like the SPIN code that is calling the assembly worker routine will return as soon
    as the assembly cog receives the command, but it seems like it is before the actual final result is calculated.
    Maybe this was intentional or maybe I'm reading it wrong.

    -Chad
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-26 10:36
    The function set command does not return until the command is cleared which indicates it has been performed.

    Graham
  • KaioKaio Posts: 253
    edited 2007-03-27 11:22
    Graham,
    Graham Stabler said...
    How does Arg1_ get a value assigned when the result is written to Ang?
    The result is always written to Arg1_ at the end of each function by the following code.

                  mov       t1,     address                 'Write data back to Arg1
                  add       t1,     #4
                  wrlong    t2,     t1
    
    


    The add instruction changes the pointer t1 to the next long variable, which is Arg1_.

    Graham Stabler said...
    And am I right in saying that if you want multiple arguments you make sure they are contigious and just pass the first?
    That's right. You must only use the add instruction like above to point to the next variable.

    Graham Stabler said...
    And a less stupid question, how do you think I should implement functions with multiple returned variables?
    The best way would be you calculate your result in contiguous variables in Cog memory. So you can return the result using a loop like this.

                            mov     t1,address              'address of parameter
                            add     t1,#4                   'point to first result variable in Spin
                            movs    :writeResult,t1         
                            movd    :writeResult,#results   'pointer to first long of result
                            mov     t3,#3                   'n longs of result                    
    :writeResult            wrlong  0-0,0-0                 
                            add     :writeResult,INCDEC_DESTSRC4
                            djnz    t3,:writeResult     
    
    
    INCDEC_DESTSRC4         long    1 << 9 | 4              '1 for destination, 4 for source 
    results                 res     3
    
    
  • KaioKaio Posts: 253
    edited 2007-03-27 11:31
    Chad,
    Chad George said...
    One question, it looks like the SPIN code that is calling the assembly worker routine will return as soon
    as the assembly cog receives the command, but it seems like it is before the actual final result is calculated.
    Maybe this was intentional or maybe I'm reading it wrong.
    You are right. In my opinion it is a mistake, but it is working while the execution time of Spin is slow enough until the result is written back.
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-27 11:45
    Kaio said...
    Chad,
    Chad George said...
    One question, it looks like the SPIN code that is calling the assembly worker routine will return as soon
    as the assembly cog receives the command, but it seems like it is before the actual final result is calculated.
    Maybe this was intentional or maybe I'm reading it wrong.
    You are right. In my opinion it is a mistake, but it is working while the execution time of Spin is slow enough until the result is written back.

    All the spin functions call setcommand and that includes the line:

    repeat while command
    



    So it will not return until command is cleared and that is done by the assembly AFTER it has completed its task

    Graham
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-27 11:52
    Kaio,

    I guess my next question is why is Arg1 the next long after Command? It must be but its not obvious to me why.

    Graham
  • KaioKaio Posts: 253
    edited 2007-03-27 13:02
    Graham,
    Graham Stabler said...
    All the spin functions call setcommand and that includes the line:

    repeat while command


    So it will not return until command is cleared and that is done by the assembly AFTER it has completed its task
    You are right in saying that the command must be cleared, but this should be at the right time. In the example code it is cleared BEFORE the function has calculated the result. It would be better to do this AFTER the result is written back.

    Graham Stabler said...
    I guess my next question is why is Arg1 the next long after Command? It must be but its not obvious to me why.
    I have nothings found about this in the manual, but I know that all parameters and local method variables are stored on the stack in the order they are specified in the method.

    Post Edited (Kaio) : 3/27/2007 1:12:00 PM GMT
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-27 13:14
    You are right, for some reason I thought I remembered seeing it at the end, duh!

    It raises an important point, it make sense to clear the command at the end but in some cases it would make more sense to allow the spin program to continue while the assembly program did its work, there would just need to be a flag to indicate that the assembly routine had finished, that would allow greater parallel processing potential in some instances and would make the one cog act like lots of little cogs. If I remember correctly someone actually did something like this, combining some of the ps/2 drivers into one object.

    Cheers

    Graham
  • KaioKaio Posts: 253
    edited 2007-03-27 14:57
    It is necessary to understand the generic communication between Spin and assembly or reverse. You can also use this way to communicate with two or more Cogs running only assembly code. But then it is very important when you have to clear the command, because the speed of assembly will not tolerate such a mistake we have seen in the code example.

    I have written a multithread kernel. So you can use some little assembly routines simultaneously in the same Cog.
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-27 15:15
    Although not totally relevant some may find the combined keyboard/mouse driver useful to free a cog:

    http://forums.parallax.com/showthread.php?p=623841
  • Beau SchwabeBeau Schwabe Posts: 6,548
    edited 2007-03-27 20:36
    Graham,

    As you and other have indicated, there are potentially two right or correct ways to do this.· One is to wait while until the assembly command executes, and the other is to allow the assembly command to execute allowing the parallel processing potential to be maximized.· In the DEMO assembly program the 'par' variable is cleared only to signify that the command has been received, not that it has been completed or not.· The PRE or POST significance should be addressed by the programmer based on·his or her·particular needs.






    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-27 23:41
    Beau,

    Re my origional question before we got side tracked:

    I've just modified the code so I can return multiple values from a function, I do this by passing a pointer to both arguments and return values which are declared contigiously in hub ram. I've got my code working for multiple return values but when I try multiple arguments it doesn't seem to work. I've not looked at the code enough to say if it is something I am doing or something in the code (the example only uses single arguments) but could you explain the meaning of the constant d0 which is $200, It looks to me as it increases the destination field of a command by one but why not four?

    Graham
  • KaioKaio Posts: 253
    edited 2007-03-28 11:57
    Graham,

    the destination address points to the memory in Cog. This is organized as long, you can it only access as 32 bit value. Therefore you must increment the pointer only by one.

    In opposition to the main memory which is organized as byte. Therefore you must increment the pointer by four, if you want to access it as long.
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-28 18:10
    Kaio, thanks.

    I'm still having trouble with the code that reads in the arguments, to test it I have removed the loop and written it out but still no joy, the first variable loads OK but not the second.

    rdlong  t1,par
    
    mov  t2,t1
    rdlong arg0,t2
    add     t2,#4
    rdlong arg1,t2
    
    



    If I just make arg0 and arg1 equal something with a mov command it works but not otherwise.

    par contains the pointer to the first of the input variables which are defined in the spin of the test program like so:

    var     
    
    long a,theta
    



    It reads a into arg0 but not theta into arg1

    I'm completely confused by this.

    Graham
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-28 19:46
    Its OK, I solvd my own problem, I just needed to pass the address of the variable to the spin function and then pass that straight through to the setcommand function, before I was passing the variable and then the pointer to the passed variable. Or words to that effect.

    Graham
Sign In or Register to comment.