Shop OBEX P1 Docs P2 Docs Learn Events
jazzed mcu Simulator - Page 2 — Parallax Forums

jazzed mcu Simulator

24

Comments

  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-27 13:52
    Lets see if I have this straight, the interpreter lives in COG RAM, the main facilitator, your program is in HUB RAM which gets used in the COG RAM, as needed. Actually it looks like HUB RAM is just a temporary storage area, and all the action is done by the interpreter, which is in the COG RAM. Is the Spin code, which has to be converted to byte code? look different in the HUB RAM, from the PASM code, that is also held in the HUB RAM area? Right now when I look in the HUB RAM it looks like everything is in machine code, so you really can not tell what part is SPIN and what part is PASM.

    You mention that PropellerGCC has always supported running code directly from COG RAM, but with only 512 bytes of work space, that really looks to be just a flashy example, and not something that you could do some "real world" programming with (I am thinking COG mode in SimpleIDE). Even if you somehow got to use the other 7 COGs COG RAM, still does not seem, at this point, a very beneficial thing.

    jazzed thanks again for this Simulator program, I would never have gotten this deep into COG RAM, HUB RAM, interpreter stuff, specifically programming, without this. I suppose the Parallax Education dept. is looking very closely at this program. This is some good stuff!

    Ray
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-04-27 14:06
    Ray,

    Your questions are great and they make me want to stand up in front of a white board with a handful of colored markers. This understanding is such a fundamental to the Propeller world but really needs a "Chalk Talk". I wish I could figure out how to make a tutorial of all this. Maybe Steve's simulator is the missing key to this.
  • jazzedjazzed Posts: 11,803
    edited 2014-04-27 14:38
    Rsadeika wrote: »
    Lets see if I have this straight, the interpreter lives in COG RAM, the main facilitator, your program is in HUB RAM which gets used in the COG RAM, as needed. Actually it looks like HUB RAM is just a temporary storage area, and all the action is done by the interpreter, which is in the COG RAM. Is the Spin code, which has to be converted to byte code? look different in the HUB RAM, from the PASM code, that is also held in the HUB RAM area? Right now when I look in the HUB RAM it looks like everything is in machine code, so you really can not tell what part is SPIN and what part is PASM.
    Ya, that's pretty much it except that HUB RAM keeps the SPIN or other bytecode/LMM program. Any PASM code in HUB is really wasting space after it gets started with cognew unless the area gets recycled. The colors in the map on the simulator HUB RAM tab show the different usage areas (there is more detail that is not discernable at the moment for multiple object programs).
    Rsadeika wrote: »
    You mention that PropellerGCC has always supported running code directly from COG RAM, but with only 512 bytes of work space, that really looks to be just a flashy example, and not something that you could do some "real world" programming with (I am thinking COG mode in SimpleIDE). Even if you somehow got to use the other 7 COGs COG RAM, still does not seem, at this point, a very beneficial thing.
    This is the way Propeller works. The pong program is actually fairly substantial and it should be a good example or test case for anyone writing COGC code (or compiler models). It has VGA output, reads pins, generates VGA graphics, has game logic in it, and has access to all of hub ram except the part used for stack. For more substantial programs, some sort of HUB RAM convention must be used like storing byte-code or LMM code. What's more important about COGC code though is that you can write 7 different drivers in COGC mode and use those in your SimpleIDE programs. SimpleIDE can do lots of things that simple users never see.

    This observation that COG is to small to be beneficial is consistent with why many people just skip over the Propeller. Clearly it is more capable than that, but it's hard to change anyone's mind once they have formed an opinion whether it is right or wrong. That is, you only get one chance for a good first impression.
    Rsadeika wrote: »
    jazzed thanks again for this Simulator program, I would never have gotten this deep into COG RAM, HUB RAM, interpreter stuff, specifically programming, without this. I suppose the Parallax Education dept. is looking very closely at this program. This is some good stuff!
    Parallax Education is not interested in the simulator project. It's my own initiative.

    Dave Hein's Simulator has been available for years, but it is limited to command line users - It's a great tool, and was used for writing PropellerGCC from the beginning.

    There was also another GUI called GEAR that does simulation - it has advanced interface features like I plan to add. I could never understand how to use GEAR at all though.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-27 15:07
    Thinking more about the Simulator, using the PASM Toggle example, when there is a cognew used why doesn't it show in the COG[1] tab? I thought that when you use cognew, that was a way to start the use of a new COG, other than the main COG 0. And I would imagine that now, the HUB RAM would have some sort of code to associate it with the specific COG, since each COG gets to use some HUB RAM.

    In the Simulator program, across the top, you have a selection called 'Clear', is it to clear the binary file that got loaded? I tried it a few times and nothing seemed to have changed or occurred.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2014-04-27 15:24
    Rsadeika wrote: »
    Thinking more about the Simulator, using the PASM Toggle example, when there is a cognew used why doesn't it show in the COG[1] tab? I thought that when you use cognew, that was a way to start the use of a new COG, other than the main COG 0. And I would imagine that now, the HUB RAM would have some sort of code to associate it with the specific COG, since each COG gets to use some HUB RAM.

    In the Simulator program, across the top, you have a selection called 'Clear', is it to clear the binary file that got loaded? I tried it a few times and nothing seemed to have changed or occurred.

    Ray

    Whenever a cognew is executed, a * is added to the COG[1] to show that code has been loaded. This only shows up in Debug mode. If you do Run, then Stop it won't show up until you do Step or Debug (Continue is like Debug and I'm considering removing that). I suppose at the end of Run a Step can be automatically executed to show the current state.

    Sorry about the Clear button. Only Load can clear and restart a program. The Clear button clears any breakpoints set in the program. How to set a breakpoint? Just click on a line contents or the BP field in the COG display (not the line number). Break points do not work in Run mode ... that may change later.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-28 05:12
    And the adventure continues. I decided to use the PASM Toggle example code as a way to see what the Simulator program reveals. So, after loading, running and stopping the program, you now see that there is a *COG[0] and *COG[1]. After looking at both tab contents I made a general breakdown:
    COG[0] : 496 lines of code <- HUB 72 bytes
    COG[1] : 47 lines of code <- HUB 72 bytes
    As it turns out the HUB data that is associated with COG[0] is the same as the HUB data that is associated with COG[1], as displayed by the Simulator. I was under the impression that each COG would have its own HUB RAM space, so in this case COG[0] HUB RAM space would be blank, right?

    Now the interesting part, COG[1] RAM has 47 lines of code, and the first 6 lines reflects the 6 lines that are shown after the org 0 in your PASM Toggle program. In fact it is very easy to follow at this point. I tried a couple of different things, first I did a Run, which did nothing that I could see. Next I tried the Step, which actually did a step of the defined :loop. Now, when I did a Debug, it started to do a very fast stepping of the :loop, which also toggled Pin16. At this point I was expecting to see the toggle to be at 80_000_000, but it was going way faster than that, what am I really seeing here, the actual processor speed working the code or is it supposed to be the actual code at work with an 80_000_000 pause?

    After this exercise I can see that, in fact, the PASM code gets loaded into COG RAM and executed. Do you have to have both the DAT and org 0 to make this happen. I know that a Spin program can have a DAT section, but where does that code go?

    Some general questions, the COG[1] has 47 lines of code, what are the other 41 lines of code doing? HUB RAM has 72 bytes being used, is that what it takes to convey your last 3 lines of PASM program? And if you removed the cognew from the program would that program still run?

    Ray
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-04-28 06:11
    Is there a pre-built Windows version of the simulator that someone could post? I'd like to try running it.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-28 06:33
    In my earlier post I posed the question about removal of the cognew from the PASM Toggle program, which I just did. I mainly use PropellerIDE for all the building of code, in these tests. With the removal of the cognew from the code, the program was built without any errors. After doing the Load,Run, and Stop, I now see *COG[0], *COG[1], *COG[2], *COG[3], and *COG[4], yes they all have lines of code. The COG[0] looks like it no longer has the correct interpreter code, but when you do a Debug, it does do a continuous Step as do the other COGs. Of course when you do a Run (COG[0]) it does not toggle the Pin16 anymore.

    The PropellerIDE shows that the new build is: "Program size is 60 bytes". How much of the Propeller chip resources are actually being used, in terms of bytes, to run this 60 byte program?

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-28 08:27
    Not sure if there is a problem with the Simulator, but when you Load, Run, Stop the program below, and then look at the COGS, all the COGs have an '*', plus they all have lines of code. I think before only COG[0] had the interpreter loaded in the COG[0].

    Ray
    CON
      _clkmode   = xtal1 + pll16x                           
      _xinfreq   = 5_000_000
    
    PUB main
      
    
  • jazzedjazzed Posts: 11,803
    edited 2014-04-28 08:56
    Ray,

    As explained before you need something in main that repeats.
    CON
      _clkmode   = xtal1 + pll16x                           
      _xinfreq   = 5_000_000
    
    PUB main
      repeat  
    
  • jazzedjazzed Posts: 11,803
    edited 2014-04-28 09:01
    Dave Hein wrote: »
    Is there a pre-built Windows version of the simulator that someone could post? I'd like to try running it.
    No package yet Dave.

    I'll see what I can do, but my schedule is a little rough through Wednesday.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-04-28 09:06
    OK, there's no hurry.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-28 10:11
    As explained before you need something in main that repeats.
    Somewhere along the line I missed that explanation, that did take care of the problem though.

    Below is a Spin version of the PASM Toggle, or at least as close as I could get it. PropellerIDE shows that this program comes in at 60 bytes, just like the PASM Toggle program. So, what do we have here, we only utilize COG[0], saving a COG, and that P16 does blink every 80_000_000. The HUB RAM comes in at 68 bytes while PASM Toggle comes in at 72 bytes of HUB RAM, plus it uses 47 lines of code in COG[1]. The Spin program exists within the interpreter or is the code that is in the HUB RAM the actual Spin program? If that is the case, trying to interpret the machine code could be a little time consuming. In the COG[0] I am still having a difficult time finding the code lines that actually reach out to the HUB RAM to run that code if in fact that is how it works.

    Not sure if this is a fair comparison but it looks like the Spin program works as good as the PASM version, plus the Spin version would be more flexible in terms of having re-usable code in the form of a method(s). In terms of program size, the Spin program can be as large as the availability of HUB RAM exits. While the PASM version would be limited to the availability of COG RAM, of course there is some spill over to the HUB RAM for incidentals, but not for actual code lines.

    Now if Spin had inline asm capabilities, would there be any major improvements in the usability of Spin? Or is there a way to call PASM code subs from methods? As an example something like a 'waitms' method, you could declare the wait length within a method call and the grunt work would be done in PASM.

    Ray
    CON
      _clkmode   = xtal1 + pll16x                           
      _xinfreq   = 5_000_000
    
    '' Main 
    pub main
      DIRA[16] := %1
      repeat
        waitcnt(80_000_000 + cnt)
        OUTA[16] := 1
        waitcnt(80_000_000 + cnt)
        OUTA[16] := 0
    
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-04-28 12:22
    Rsadeika wrote: »
    Somewhere along the line I missed that explanation, that did take care of the problem though.

    Below is a Spin version of the PASM Toggle, or at least as close as I could get it. PropellerIDE shows that this program comes in at 60 bytes, just like the PASM Toggle program. So, what do we have here, we only utilize COG[0], saving a COG, and that P16 does blink every 80_000_000. The HUB RAM comes in at 68 bytes while PASM Toggle comes in at 72 bytes of HUB RAM, plus it uses 47 lines of code in COG[1]. The Spin program exists within the interpreter or is the code that is in the HUB RAM the actual Spin program? If that is the case, trying to interpret the machine code could be a little time consuming. In the COG[0] I am still having a difficult time finding the code lines that actually reach out to the HUB RAM to run that code if in fact that is how it works.
    I'm not sure where we are headed with this but it is a fun discussion.
    PASM equivalent to your SPIN:
     { PASMToggle.spin }}
     CON
       _clkmode = xtal1 + pll16x
       _xinfreq = 5_000_000
       
     PUB Main
     {Launch cog to toggle P16 endlessly}
       coginit(0,@Toggle, 0)
     DAT
     {Toggle P16}
                 org 0
     Toggle             mov    dira, Pin
                        mov     Time, cnt
                       add   Time, Delay
     :loop             waitcnt Time, Delay
                       xor   outa, Pin
                       waitcnt Time, Delay
                       xor   outa, Pin
                       jmp   #:loop
     
    
     Pin   long    |< 16
     Delay long    80_000_000
     Time        res 1
    

    The code above will use 1 cog and will take up 11 LONGs for instructions and data. You can see them right there in the listing (the beauty of PASM). It toggles the pin at the same rate as the Spin program.

    The propeller processor (a COG) can only execute instructions from COG RAM. These instructions are 32 bits in length and certain bits mean certain things to the processor as it decodes the instruction. These instructions are coded as PASM to make them more readable. There are only 496 usable LONGs in a COG that can execute instructions - the remaining LONGs are reserved registers. That's all a COG can ever do is execute propeller instructions from COGRAM.

    The Spin interpreter (or any interpreter or virtual machine for that matter) is a PASM program that executes in COGRAM that for all practical purposes is an implementation of a NEW processor - in this case, one that understands Spin byte codes as its instruction set. This Spin processor can only execute byte codes from HUBRAM. The interpreter will execute many, many PASM instructions for each Spin instruction. If you look at Steve's Spin trace above, you will see a series of RDBYTE instructions - each of those is the Spin interpreter fetching a Spin byte code or parameter from HUBRAM and processing it. If you look at my trace below, you will see a RDBYTE instruction fetching a Spin byte code and then all the PASM instruction that are executed to make that byte code do whatever it is supposed to do.
     
    81904649 COG 0 PC 009  00bc0bee                RDBYTE WC 0 WZ 0 WR 1 DST 005 00000037 SRC  $1ee 00000029 C 1 Z 0 RESULT $03d <<SPIN>>
       81904657 COG 0 PC 00a  80ffdc01                   ADD WC 0 WZ 0 WR 1 DST 1ee 00000029 SRC #$001          C 0 Z 0 RESULT $02a
       81904665 COG 0 PC 00b  857c0a40                   CMP WC 1 WZ 0 WR 0 DST 005 0000003d SRC #$040          C 1 Z 0 RESULT $000
       81904681 COG 0 PC 00d  a0bc0605                   MOV WC 0 WZ 0 WR 1 DST 003 000003a8 SRC  $005 0000003d C 0 Z 0 RESULT $03d
       81904689 COG 0 PC 00e  20fc0604                   ROR WC 0 WZ 0 WR 1 DST 003 0000003d SRC #$004          C 1 Z 0 RESULT $d0000003
       81904697 COG 0 PC 00f  80fc061a                   ADD WC 0 WZ 0 WR 1 DST 003 d0000003 SRC #$01a          C 0 Z 0 RESULT $d000001d
       81904705 COG 0 PC 010  50bc2603                  MOVS WC 0 WZ 0 WR 1 DST 013 a0bc081d SRC  $003 d000001d C 1 Z 0 RESULT $a0bc081d
       81904713 COG 0 PC 011  24fc0602                   ROL WC 0 WZ 0 WR 1 DST 003 d000001d SRC #$002          C 1 Z 0 RESULT $40000077
       81904721 COG 0 PC 012  2cfc0603                   SHL WC 0 WZ 0 WR 1 DST 003 40000077 SRC #$003          C 0 Z 0 RESULT $3b8
       81904729 COG 0 PC 013  a0bc081d                   MOV WC 0 WZ 0 WR 1 DST 004 000000c4 SRC  $01d d6cfc4b4 C 1 Z 0 RESULT $d6cfc4b4
       81904737 COG 0 PC 014  28bc0803                   SHR WC 0 WZ 0 WR 1 DST 004 d6cfc4b4 SRC  $003 000003b8 C 0 Z 0 RESULT $0d6
       81904745 COG 0 PC 015  60fc08ff                   AND WC 0 WZ 0 WR 1 DST 004 000000d6 SRC #$0ff          C 1 Z 0 RESULT $0d6
       81904753 COG 0 PC 016  50bc3204                  MOVS WC 0 WZ 0 WR 1 DST 019 5c7c00c4 SRC  $004 000000d6 C 0 Z 0 RESULT $5c7c00d6
       81904761 COG 0 PC 017  627c0a01                  TEST WC 0 WZ 1 WR 0 DST 005 0000003d SRC #$001          C 1 Z 0 RESULT $000
       81904769 COG 0 PC 018  617c0a02                  TEST WC 1 WZ 0 WR 0 DST 005 0000003d SRC #$002          C 0 Z 1 RESULT $000
       81904777 COG 0 PC 019  5c7c00d6                   JMP WC 0 WZ 0 WR 0 DST 000 00000000 SRC #$0d6          C 1 Z 0 RESULT $000
       81904817 COG 0 PC 0d6  00bc01ee                RDBYTE WC 0 WZ 0 WR 1 DST 000 00000000 SRC  $1ee 0000002a C 0 Z 0 RESULT $0b4
       81904825 COG 0 PC 0d7  80ffdc01                   ADD WC 0 WZ 0 WR 1 DST 1ee 0000002a SRC #$001          C 0 Z 0 RESULT $02b
       81904833 COG 0 PC 0d8  a0bc0a00                   MOV WC 0 WZ 0 WR 1 DST 005 0000003d SRC  $000 000000b4 C 0 Z 0 RESULT $0b4
       81904841 COG 0 PC 0d9  28fc0a05                   SHR WC 0 WZ 0 WR 1 DST 005 000000b4 SRC #$005          C 0 Z 0 RESULT $005
       81904849 COG 0 PC 0da  68fc01e0                    OR WC 0 WZ 0 WR 1 DST 000 000000b4 SRC #$1e0          C 0 Z 0 RESULT $1f4
       81904857 COG 0 PC 0db  50bf8200                  MOVS WC 0 WZ 0 WR 1 DST 1c1 608c05f1 SRC  $000 000001f4 C 0 Z 0 RESULT $608c05f4
       81904865 COG 0 PC 0dc  54bf8600                  MOVD WC 0 WZ 0 WR 1 DST 1c3 a0bfe200 SRC  $000 000001f4 C 0 Z 0 RESULT $a0bfe800
       81904873 COG 0 PC 0dd  50bf9000                  MOVS WC 0 WZ 0 WR 1 DST 1c8 a0bc01f1 SRC  $000 000001f4 C 0 Z 0 RESULT $a0bc01f4
       81904889 COG 0 PC 0df  5ccfbddc        if_nc     CALL WC 0 WZ 0 WR 1 DST 1de 5c7c0096 SRC #$1dc          C 0 Z 0 RESULT $5c7c00e0
       81904897 COG 0 PC 1dc  84ffde04                   SUB WC 0 WZ 0 WR 1 DST 1ef 00000050 SRC #$004          C 0 Z 0 RESULT $04c
       81904937 COG 0 PC 1dd  08bc01ef                RDLONG WC 0 WZ 0 WR 1 DST 000 000001f4 SRC  $1ef 0000004c C 0 Z 0 RESULT $010
       81904945 COG 0 PC 1de  5c7c00e0                   JMP WC 0 WZ 0 WR 0 DST 000 00000010 SRC #$0e0          C 1 Z 0 RESULT $000
       81904953 COG 0 PC 0e0  a08c0200        if_nc      MOV WC 0 WZ 0 WR 1 DST 001 00000003 SRC  $000 00000010 C 0 Z 0 RESULT $010
       81904969 COG 0 PC 0e2  60fc001f                   AND WC 0 WZ 0 WR 1 DST 000 00000010 SRC #$01f          C 1 Z 0 RESULT $010
       81904977 COG 0 PC 0e3  60fc021f                   AND WC 0 WZ 0 WR 1 DST 001 00000010 SRC #$01f          C 1 Z 0 RESULT $010
       81904985 COG 0 PC 0e4  a0bc0e00                   MOV WC 0 WZ 0 WR 1 DST 007 ffffffff SRC  $000 00000010 C 0 Z 0 RESULT $010
       81904993 COG 0 PC 0e5  85bc0e01                   SUB WC 1 WZ 0 WR 1 DST 007 00000010 SRC  $001 00000010 C 0 Z 1 RESULT $000
       81905001 COG 0 PC 0e6  acbc0e07                ABSNEG WC 0 WZ 0 WR 1 DST 007 00000000 SRC  $007 00000000 C 0 Z 1 RESULT $000
       81905009 COG 0 PC 0e7  84fc0e01                   SUB WC 0 WZ 0 WR 1 DST 007 00000000 SRC #$001          C 1 Z 0 RESULT $ffffffff
       81905017 COG 0 PC 0e8  a08fd001        if_nc      MOV WC 0 WZ 0 WR 1 DST 1e8 00000010 SRC  $001 00000010 C 0 Z 0 RESULT $010
       81905033 COG 0 PC 0ea  74bf7fe7                 MUXNC WC 0 WZ 0 WR 1 DST 1bf 3c8c0007 SRC  $1e7 00800000 C 0 Z 0 RESULT $3c8c0007
       81905041 COG 0 PC 0eb  74bf97e7                 MUXNC WC 0 WZ 0 WR 1 DST 1cb 3c8c0007 SRC  $1e7 00800000 C 0 Z 0 RESULT $3c8c0007
       81905049 COG 0 PC 0ec  68fc0a0c                    OR WC 0 WZ 0 WR 1 DST 005 00000005 SRC #$00c          C 1 Z 0 RESULT $00d
       81905057 COG 0 PC 0ed  5c7c0179                   JMP WC 0 WZ 0 WR 0 DST 000 00000010 SRC #$179          C 1 Z 0 RESULT $000
       81905065 COG 0 PC 179  5cfc3217                  CALL WC 0 WZ 0 WR 1 DST 019 5c7c00d6 SRC #$017          C 0 Z 0 RESULT $5c7c017a
       81905073 COG 0 PC 017  627c0a01                  TEST WC 0 WZ 1 WR 0 DST 005 0000000d SRC #$001          C 1 Z 0 RESULT $000
       81905081 COG 0 PC 018  617c0a02                  TEST WC 1 WZ 0 WR 0 DST 005 0000000d SRC #$002          C 0 Z 1 RESULT $000
       81905089 COG 0 PC 019  5c7c017a                   JMP WC 0 WZ 0 WR 0 DST 000 00000010 SRC #$17a          C 1 Z 0 RESULT $000
       81905105 COG 0 PC 17b  5cc7bddc if_nc_and_nz     CALL WC 0 WZ 0 WR 1 DST 1de 5c7c00e0 SRC #$1dc          C 0 Z 0 RESULT $5c7c017c
       81905113 COG 0 PC 1dc  84ffde04                   SUB WC 0 WZ 0 WR 1 DST 1ef 0000004c SRC #$004          C 0 Z 0 RESULT $048
       81905153 COG 0 PC 1dd  08bc01ef                RDLONG WC 0 WZ 0 WR 1 DST 000 00000010 SRC  $1ef 00000048 C 0 Z 0 RESULT $001
       81905161 COG 0 PC 1de  5c7c017c                   JMP WC 0 WZ 0 WR 0 DST 000 00000001 SRC #$17c          C 1 Z 0 RESULT $000
       81905169 COG 0 PC 17c  5c4401b7 if_nc_and_nz      JMP WC 0 WZ 0 WR 0 DST 000 00000001 SRC #$1b7          C 1 Z 0 RESULT $000
       81905177 COG 0 PC 1b7  637c0a0c                  TEST WC 1 WZ 1 WR 0 DST 005 0000000d SRC #$00c          C 0 Z 0 RESULT $000
       81905233 COG 0 PC 1ba  a4cc0401        if_nc      NEG WC 0 WZ 0 WR 1 DST 002 00000101 SRC #$001          C 0 Z 0 RESULT $ffffffff
       81905241 COG 0 PC 1bb  3c8c0407        if_nc      REV WC 0 WZ 0 WR 1 DST 002 ffffffff SRC  $007 ffffffff C 1 Z 0 RESULT $001
       81905249 COG 0 PC 1bc  2c8c05e8        if_nc      SHL WC 0 WZ 0 WR 1 DST 002 00000001 SRC  $1e8 00000010 C 0 Z 0 RESULT $10000
       81905257 COG 0 PC 1bd  6c8c05e5        if_nc      XOR WC 0 WZ 0 WR 1 DST 002 00010000 SRC  $1e5 ffffffff C 1 Z 0 RESULT $fffeffff
       81905265 COG 0 PC 1be  3c8c0007        if_nc      REV WC 0 WZ 0 WR 1 DST 000 00000001 SRC  $007 ffffffff C 1 Z 0 RESULT $001
       81905273 COG 0 PC 1bf  3c8c0007        if_nc      REV WC 0 WZ 0 WR 1 DST 000 00000001 SRC  $007 ffffffff C 1 Z 0 RESULT $001
       81905281 COG 0 PC 1c0  2c8c01e8        if_nc      SHL WC 0 WZ 0 WR 1 DST 000 00000001 SRC  $1e8 00000010 C 0 Z 0 RESULT $10000
       81905289 COG 0 PC 1c1  608c05f4        if_nc      AND WC 0 WZ 0 WR 1 DST 002 fffeffff SRC  $1f4 00000000 C 0 Z 1 RESULT $000
       81905297 COG 0 PC 1c2  688c0002        if_nc       OR WC 0 WZ 0 WR 1 DST 000 00010000 SRC  $002 00000000 C 1 Z 0 RESULT $10000
       81905305 COG 0 PC 1c3  a0bfe800                   MOV WC 0 WZ 0 WR 1 DST 1f4 00000000 SRC  $000 00010000 C 0 Z 0 RESULT $10000
       81905313 COG 0 PC 1c4  5c7c0008                   JMP WC 0 WZ 0 WR 0 DST 000 00010000 SRC #$008          C 0 Z 0 RESULT $000
       81905321 COG 0 PC 008  a0fc0000                   MOV WC 0 WZ 0 WR 1 DST 000 00010000 SRC #$000          C 0 Z 1 RESULT $000
       81905361 COG 0 PC 009  00bc0bee                RDBYTE WC 0 WZ 0 WR 1 DST 005 0000000d SRC  $1ee 0000002b C 0 Z 0 RESULT $03b <<SPIN>>
    

    There are around 60 PASM insturctions executed to do whatever that one Spin Byte code does. That's why PASM runs on average about 40 times faster than Spin.

    The tradeoff as you mentioned is that you can write a Spin program that can be 32K bytes in size whereas your PASM program can never be larger than 496 longs (without getting really fancy). So there is your tradeoff - speed for program size. But, you can make a COG do a lot in 496 longs as far as soft peripheral and other helper type code goes. So it's really a good match - Spin for more complicated logic that can run slower (and is easier for the programmer to write and create more abstract ideas) and then PASM for when you need the speed.

    Most high-level languages on the Propeller work in a similar manner.

    Not sure if this is a fair comparison but it looks like the Spin program works as good as the PASM version, plus the Spin version would be more flexible in terms of having re-usable code in the form of a method(s). In terms of program size, the Spin program can be as large as the availability of HUB RAM exits. While the PASM version would be limited to the availability of COG RAM, of course there is some spill over to the HUB RAM for incidentals, but not for actual code lines.
    I'm not sure there is anything to compare - this trivial example can be written in either and performs the same in either. It is easier to write in Apin but not that much more difficult to write in PASM. They are two different tools that you would normally use for different things in your program. As mentioned above, your Spin program can fill HUBRAm with byte code and your PASM program can only execute from COGRAM but you can use all of HUBRAM for data if you desire.

    For non-trivial programs, the differences become apparent and the best uses for each will soon show themselves.
    Now if Spin had inline asm capabilities, would there be any major improvements in the usability of Spin? Or is there a way to call PASM code subs from methods? As an example something like a 'waitms' method, you could declare the wait length within a method call and the grunt work would be done in PASM.

    Ray
    CON
      _clkmode   = xtal1 + pll16x                           
      _xinfreq   = 5_000_000
    
    '' Main 
    pub main
      DIRA[16] := %1
      repeat
        waitcnt(80_000_000 + cnt)
        OUTA[16] := 1
        waitcnt(80_000_000 + cnt)
        OUTA[16] := 0
    

    Inline PASM is talked about and would be an interesting feature in a Spin program. I'm sure once it shows up, there will be many intersting tricks the Propeller starts performing!
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-28 14:09
    I call and raise you ... :-)
    I just ran your PASM program through the Simulator -
    Program size is 72 bytes.
    HUB RAM 80 bytes
    There is a match for COG use.
    The programs being at this trivial size, having it coded in PASM is not that particularly important. Now if we were to switch gears and start doing FDS, then PASM starts to become a very necessary tool.

    I am really impressed with the Simulator because now you can try out some programming ideas without having to have an actual Propeller board at hand. All you really need is PropellerIDE, MCU Simulator, and a programmers calculator on the computer. In fact how would this work out on a tablet? I wonder how far jazzed is going to take the Simulator program?

    I guess now would be a good time to see how a PropellerGCC program, like maybe a Toggle program, would match up to the Spin and PASM programs. I am thinking a COG C Toggle program, that would be a good match, I think?

    Ray
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-04-28 14:35
    Rsadeika wrote: »

    I guess now would be a good time to see how a PropellerGCC program, like maybe a Toggle program, would match up to the Spin and PASM programs. I am thinking a COG C Toggle program, that would be a good match, I think?

    Ray

    cog_c_toggle uses 2 COGs which the simulator didn't like when I tried it earlier. It will look a lot like the Spin example using the COGNEW since there is a COG running one of the C memory model VMs and then the COG you start to blink running the actual blinking code.

    lmm_toggle will look a lot like your Spin program. One COG running through a BIG loop executing some sort of byte code (or actual instructions) from HUBRAM. Unless you can digest the byte code in HUBRAM, you won't see much interesting.

    The other examples I looked at looked like they were multi-COG examples.
  • jazzedjazzed Posts: 11,803
    edited 2014-04-28 15:39
    mindrobots wrote: »
    cog_c_toggle uses 2 COGs which the simulator didn't like when I tried it earlier.
    Both CMM and LMM work for me. Time to update?
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-04-28 15:46
    jazzed wrote: »
    Both CMM and LMM work for me. Time to update?

    LM who? CM what?? :lol:

    I had two PASM cogs that it didn't like. I do need to update though, it's been 24 hours!! :smile:
  • dgatelydgately Posts: 1,633
    edited 2014-04-28 18:36
    Jazzed!

    What have you done? mcusimulator let out the blue smoke!!!


    mcuPuff.jpg




    :innocent:


    dgately
    1024 x 755 - 118K
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-04-28 19:22
    Wow! Now that's an impressive simulator....the best part is it just took $7.95 out of you paypal account, too!!
  • jazzedjazzed Posts: 11,803
    edited 2014-04-28 19:50
    mindrobots wrote: »
    Wow! Now that's an impressive simulator....the best part is it just took $7.95 out of you paypal account, too!!
    Hey! Don't give me any ideas. ;-)

    I put a little "twist" in the simulator today during lunch. It's all I had time to do.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-29 03:43
    Yes, an animated dot spiral.

    I am using the program example that mindrobots provided, coginit PASM Toggle. What I did was the following:
    1. Load - loads the binary
    2. Step - shows some code starting at $000, looks like the interpreter.
    3. Debug - does a quick step until it hits a loop which is the PASM program code. The PASM code listing is now at $000. What just happened?
    I am not sure what I am seeing here, it looks like the actual Propeller procedure is load the interpreter, then load the actual program, and run. When you do the normal Load, Run, and Stop, the COG[0] code listing looks like you have just been using the PASM code, but in fact you have missed the whole loading of the interpreter step. I got the misconception that you were really just using and running the PASM code, if this makes any sense at all.

    It seems to me that it would be beneficial, to have a sequence, where you get to see the actual program run, starting at $000, stepping through the interpreter to a point where it starts too execute the PASM code. Right now you really do not get to see how the PASM code interacts or is being used by the interpreter or whatever that mechanism is called. Somebody brand new might start getting some wrong ideas as too how all this works when presented with some concept shortcuts. Just my two cents, I am just describing what my impressions are when I use the program.

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-29 05:02
    Using the mindrobots coginit PASM program, it's time for a quiz. So get out a pencil and a sheet of paper ...

    1. If you remove the CON block of code, will the program still run, and why?
    2. If in fact, the program is running, will the P16 be toggling?
    a. At what rate? Please show your work,
    b. Can the rate be manipulated and how? Please show your work.
    Bonus Question.
    3. Can you start another toggling sequence, maybe P17, which will be active in its own cog? Please show your work.

    Ray
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-04-29 05:42
    Rsadeika wrote: »
    Yes, an animated dot spiral.

    I am using the program example that mindrobots provided, coginit PASM Toggle. What I did was the following:
    1. Load - loads the binary
    2. Step - shows some code starting at $000, looks like the interpreter.
    3. Debug - does a quick step until it hits a loop which is the PASM program code. The PASM code listing is now at $000. What just happened?
    I am not sure what I am seeing here, it looks like the actual Propeller procedure is load the interpreter, then load the actual program, and run. When you do the normal Load, Run, and Stop, the COG[0] code listing looks like you have just been using the PASM code, but in fact you have missed the whole loading of the interpreter step. I got the misconception that you were really just using and running the PASM code, if this makes any sense at all.

    It seems to me that it would be beneficial, to have a sequence, where you get to see the actual program run, starting at $000, stepping through the interpreter to a point where it starts too execute the PASM code. Right now you really do not get to see how the PASM code interacts or is being used by the interpreter or whatever that mechanism is called. Somebody brand new might start getting some wrong ideas as too how all this works when presented with some concept shortcuts. Just my two cents, I am just describing what my impressions are when I use the program.

    Ray

    Propeller 101 -

    (Your step #2) When the Prop 1 resets, the first progmatic thing it does is to load a copy of the Spin interpreter into COG0 and start executing it at COGRAM $000. Once the Spin interpreter gets initialized and running, the first thing it does is to execute the Spin byte code at $10 in HUBRAM (or wherever the Spin programs start - I forget). You will see all of this in the simulator if you wish to step through it.

    (Your step #3a) The first Spin instruction is COGINIT, so the interpreter will read that bytecode from HUBRAM (RDBYTE) and start executing it....at some point in processing that byte code, it will execute the PASM instruction COGINIT - you can watch everything up to that point if you care to do a lot of stepping.

    (Your step #3b) The PASM COGINIT instruction tells the COG to load a 496 long section of HUBRAM that it was passed a pointer to into the specified COG's RAM. In this case, the specified COG is COG0, so the PASM program will overlay the Spin interpreter that is currently in COGRAM. Once loaded, program execution starts at COGRAM $000 The simulator won't show you the details of the PASM COGINIT being executed because that is all being done inside the hardware by that one instruction (it's a software simulator, not a hardware simulator :lol:) If you are watching this in DEBUG, then the COGRAM contents will appear to have magically changed from the Spin interpreter code to you PASM code.

    If you start a PASM Trace (not a Spin Trace) of everything from the Load through to the point where you see the PASM program in COG, then you would have a list of all the steps and be able to see how the Spin interpreter does the COGINIT. This would give you the sequence you are asking for: from Spin $000 through to the PASM code executing.
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-04-29 05:50
    Rsadeika wrote: »
    Using the mindrobots coginit PASM program, it's time for a quiz. So get out a pencil and a sheet of paper ...

    1. If you remove the CON block of code, will the program still run, and why?
    2. If in fact, the program is running, will the P16 be toggling?
    a. At what rate? Please show your work,
    b. Can the rate be manipulated and how? Please show your work.
    Bonus Question.
    3. Can you start another toggling sequence, maybe P17, which will be active in its own cog? Please show your work.

    Ray

    I took your quiz about a week ago when I first started playing with the simulator. (I'd like to see your answers to compare! :smile:)

    Bonus question puzzle:

    Why does this code leave you with one blinking LED:
                 COGINIT(0, @TOGGLE16, 0)
                 COGINTI(1, @TOGGLE17, 0)
    
    and this code leaves you with two blinking LEDs?
                COGINIT(1, @TOGGLE16, 0)
                COGINIT(0, @TOGGLE17, 0)
    
    assuming that you have a TOGGLE16 block of PASM code that blinks pin 16 at some rate and a TOGGLE17 block of code that toggles pin 17 at some rate.
    (I got myself with this while I was playing distractedly with multiple LEDs - DOH!)
  • Michel LMichel L Posts: 141
    edited 2014-04-29 06:27
    mindrobots wrote: »
    Bonus question puzzle:

    Why does this code leave you with one blinking LED:
                 COGINIT(0, TOGGLE16, 0)
                 COGINTI(1, TOGGLE17, 0)
    
    and this code leaves you with two blinking LEDs?
                COGINIT(1, TOGGLE16, 0)
                COGINIT(0, TOGGLE17, 0)
    
    assuming that you have a TOGGLE16 block of PASM code that blinks pin 16 at some rate and a TOGGLE17 block of code that toggles pin 17 at some rate.
    (I got myself with this while I was playing distractedly with multiple LEDs - DOH!)

    As far as I know it's because the code that executes these commands are running in cog 0. In the first case you are loading the new code in the current running cog and as such, the second coginit is never reached.
    In the second case, you start cog 1, and afterwards you load TOGGLE17 into the cog that starts all this. If you would put any code after this, it would not be executed.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-04-29 08:32
    1. If you remove the CON block of code, will the program still run, and why?
    Yes, the Propeller chip has an internal RC Oscillator 12MHz or 20kHz. The processor starts at ~20kHz waits 50ms then switches to ~12MHz. So what is the math ~80_000_000 / 12_000_000? You can take the Propeller DIP chip, plug it into the breadboard, provide the necessary power and you can program it. The experiments that I did, I do not remember using the just mentioned setup, having a program that had the previously mentioned CON block code inserted, and would seeing if the program would compile let alone run correctly?

    The reason this question came up is, I am making an assumption that the Simulator is simulating an external 5MHz crystal. So when you do have the CON block code inserted everything runs correctly. Which leads to another question, will the Simulator program be simulating an EEPROM?

    Maybe we should step back and try a PASM Toggle program that would have P16 toggle at 250ms, 500ms, and 1000ms.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2014-04-29 08:35
    Rsadeika wrote: »
    Using the mindrobots coginit PASM program, it's time for a quiz. So get out a pencil and a sheet of paper ...

    1. If you remove the CON block of code, will the program still run, and why?
    2. If in fact, the program is running, will the P16 be toggling?
    a. At what rate? Please show your work,
    b. Can the rate be manipulated and how? Please show your work.
    Bonus Question.
    3. Can you start another toggling sequence, maybe P17, which will be active in its own cog? Please show your work.

    Ray


    1. Yes. It will run with the default 12MHz propeller clock.
    From PropellerManual v1.1: "RCFAST ... Internal fast oscillator (~12 MHz). May be 8 MHz to 20 MHz. (Default)"
    2. Yes.
    2.a. The simulated rate is wrong at the moment for some reason.
    2.b. To change the rate, you must change the clock.
    3. Yes, see @mindrobots and @Michel L answers.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-04-29 11:44
    I tried out the simulator under Windows and it's very nice. There does seem to be a problem with DJNZ. A single-line DJNZ, such as "djnz count, #$" would just exit the loop immediately. If I make the loop two lines by adding a NOP it worked better, but it didn't appear to loop the correct number of times in the RUN mode. In the STEP mode it would sit on the NOP for 4 clicks, and then execute the DJNZ. If I replace the loop with a SUB and conditional jump it works OK.

    Here's a little program that blinks a bit from left to right while jumping up and down. The speed depends on the input bits.
    con
      _clkmode = xtal1+pll16x
      _clkfreq = 80_000_000
    
    pub main
      coginit(0, @entry, 0)
    
    dat
    
    entry           neg     dira, #1
                    mov     outa, #1
    loop2           rol     outa, #15
                    call    #delay
                    ror     outa, #17
                    call    #delay
                    jmp     #loop2
    
    delay           mov     count, ina      wz
            if_z    jmp     delay_ret
    {
                    nop
                    djnz    count, #$-1
    }
                    sub     count, #1       wz
            if_nz   jmp     #$-1
    delay_ret       ret
    
    count           res     1
    
  • jazzedjazzed Posts: 11,803
    edited 2014-04-29 16:56
    Hi Dave.

    Thanks for testing this and providing a good example.

    Let me know if you see other things.

    The Run timing accuracy issue with different clock rates is in the queue too.
Sign In or Register to comment.