Shop OBEX P1 Docs P2 Docs Learn Events
Prop-2 Release Date and Price - Page 16 — Parallax Forums

Prop-2 Release Date and Price

11416181920

Comments

  • If you checkout my ZiCog and Pullmolls qz80 Z80 emulators for the Prop projects you will see that they did at least have access to 64K or more of memory via and external memory driver with caches. That kind of idea could probably be extended into a more complex MMU. It's OK if you don't mind running slowly It's not clear that adding interrupts to those systems would have helped the emulator performance much.

    Heater,

    I would love to look over your and pullmolls' Z80 emulators' source code myself to get a better idea of what you're talking about. Do you have any links to them? I checked the obex and didn't see it. TY.
  • Heater.Heater. Posts: 21,230
    edited 2015-07-12 09:24
    Not in OBEX I'm afraid.
    A very long thread about the progress of ZiCog is here:http://forums.parallax.com/discussion/110804/zicog-a-zilog-z80-emulator-in-1-cog

    Before that was the simpler PropAltair: Intel 8080 only opcodes:http://forums.parallax.com/discussion/101495/propaltair-cp-m-operating-system-for-propeller-anyone

    PullMoll's qz80 is here:
    http://forums.parallax.com/discussion/121579/qz80-the-third-shot
    Forum member cluso99 built a tiny board with Prop and external RAM to run ZiCog and CP/Mhttp://forums.parallax.com/discussion/116893/ramblade-prop-sram-microsd-addon-to-run-zicog-cpm-propdos-catalina-etc   
    Featured on Hackaday no less!http://hackaday.com/2009/12/27/zilog-in-a-matchbox/

  • David BetzDavid Betz Posts: 14,516
    edited 2015-07-12 10:44
    The Norsk Data NORD-10 had 16 full sets of registers (including status registers and some of the internal registers). An interrupt switched register sets and continued from there. No explicit saving of state (or push/pop) was necessary for the interrupt itself. An interrupt could interrupt an interrupt, that's what all the levels were for. An interrupt could be handled in 1.2us back then in 1969, which was pretty good for the time.

    Sounds like an infinite loop to me.
    1) we have processors with no interrupts that have to resort to polling for asynchronous events.
    2) someone adds interrupts to allow the simulation of multiple processors in a crude way
    3) someone adds extra register sets to avoid the overhead of having to save state when an interrupt occurs
    4) someone adds the rest of the logic to form an entire separate processor to handle these events (the Propeller)
    5) we run out of extra processors so someone suggests that each of the extra processors have interrupts
    6) loop back to 2.....
  • Heater.Heater. Posts: 21,230
    edited 2015-07-12 13:18
    I think you summed it up nicely there David.Fake sig: Raspberry Pi web cam via the resin.io service.
  • kwinnkwinn Posts: 8,697
    Heater,

    I don't really see how addition of a feature would destroy its attraction to its current markets. If you don't need all eight cogs, just use seven. Same with any other added feature, no?

    The additional complexity for the hardware depends on how much you're willing to offload to software. I think just adding interrupts is really enough. Even something as massive as Linux doesn't need a full-blown MMU if you can find a way to handle physical memory locations in software. Just an MPU. And even an MPU isn't necessary, just a way to send an interrupt if a seg fault occurs.

    ---

    Here's what I'm proposing: add interrupt support. That way, a cog could be programmed as an MMU, and send the interrupts if necessary. No huge integrated MMU, no MPU, no other additional features really, just interrupts. That way you can make an MMU if you want, AND it's an additional feature in the target embedded market anyway.

    Would anyone else like to see interrupt support? Or is everyone really satisfied with polling?


    m00tykins, While I agree that a simple interrupt (actually more of an event initiated task switch) would only enhance the Propeller my advice is to give it up. I was involved in the discussion mentioned in a previous post, and this topic has become almost totally polarized. Some are adamantly opposed to the idea, others strongly in favor of it, and very few in between.
  • Heater.Heater. Posts: 21,230
    edited 2015-07-12 15:26
    kwinn wrote:...this topic has become almost totally polarized.
    It certainly has. However I have recently been pondering a "half way house" solution. How about an event driven system built in hardware?Here is what I have been thinking:
    1) A Cog does nothing until it gets the "event" signal.
    2) The code that handles that event runs from top to bottom and when it is done the COG halts and waits for the next event.
    3) The most obvious event source is "reset". which would be given automatically when the COG is loaded.
    4) Now, the interesting parts: Firstly we arrange that all the WAITxxx instructions halt the COG, and it enters the waiting state described in 1)
    5) Having issued a WAITxxx instruction the appropriate external event puts a jump vector into FIFO and the COG gets the event signal.
    6) At which point the jump vector at the head of the FIFO is removed and used to restart the COG at the given address.
    7) That code proceeds as in 2) above.


    No stacks required. No need to divert from the currently executing thread, remeber where you were and then return to it later. No data race conditions to deal with

    One down side is not having priorities, but I'm not going to worry about that. If you have a high priority thing do it on a different COG.
    Fake sig: Raspberry Pi web cam via the resin.io service.




  • potatoheadpotatohead Posts: 10,261
    edited 2015-07-12 16:30
    That's essentially what "Start COG at Address" would do.  We had this talk, and centered in on about the same place, realizing that being able to start a COG either running HUBEXEC mode, or by loading and then running at a specific address, and I think we even talked about just starting the COG with what's in the COG, not loading it again too.

    Then you get a supervisor COG to manage things.  The key was to always be in charge of the path of execution, not have it changed outside of programmer control, which is what the interrupt is on a very basic level.

    All in the P2 "Hot" dialog.
  • Heater.Heater. Posts: 21,230
    edited 2015-07-12 17:23
    I don't recall that conversation but is sounds like it was heading a similar direction.

    The problem with the current Propeller architecture that I'm looking to solve is that it can only WAITxxx on one thing at a time. So you either have to poll events from a loop, like the original FullDuplex Serial, which means you never go to a power saving mode and it's inefficient in code execution anyway. Or you need to wait on a time and then poll to see if anything happened.

    My event FIFO is intended to allow WAITxxx on many things at once. Then: Get event, run it's handler to completion, sleep. Get event, run it's handler to completion, sleep. Rather like the event model of programming in JavaScript.

    As I said reset would be one such event give when code is loaded and or given by other COGs. This is not a "hard reset" as it would not divert execution from midway though an event handler but rather be queued like everything else. For a hard reset stop the cog and restart it from scratch.

    Of course I'd want to see this scheme work for HUB exec as well :)


    Fake sig: Raspberry Pi web cam via the resin.io service.





  • I don't recall that conversation but is sounds like it was heading a similar direction.

    The problem with the current Propeller architecture that I'm looking to solve is that it can only WAITxxx on one thing at a time. So you either have to poll events from a loop, like the original FullDuplex Serial, which means you never go to a power saving mode and it's inefficient in code execution anyway. Or you need to wait on a time and then poll to see if anything happened.

    My event FIFO is intended to allow WAITxxx on many things at once. Then: Get event, run it's handler to completion, sleep. Get event, run it's handler to completion, sleep. Rather like the event model of programming in JavaScript.

    As I said reset would be one such event give when code is loaded and or given by other COGs. This is not a "hard reset" as it would not divert execution from midway though an event handler but rather be queued like everything else. For a hard reset stop the cog and restart it from scratch.

    Of course I'd want to see this scheme work for HUB exec as well :)




    Fake sig: Raspberry Pi web cam via the resin.io service.





    Hey Heater,
    Dont' know if that fake sig is impacting bandwidth, but it takes 20 secondonds to download the photo.
  • That would be a good addition someday, IMHO.

    Can't a person juat wait on a whole pile of pins, then jump based on a masked result?

    Doing that is only a few instructions at most.

  • Heater.Heater. Posts: 21,230
    Publison, yes it is slow. That Raspi Pi is connected via a WIFI dongle to a WIFI router which is in turn connected to the net via a 3G dongle. Up load speed through all that is terrible.

    Also I'm not sure how much of speed hit going through resin.io causes. It should not have any bad effect on forum visitors though.

    Fake sig: Raspberry Pi web cam via the resin.io service.




  • jmgjmg Posts: 15,175
     Heater wrote:
    How about an event driven system built in hardware?
    The problem with the current Propeller architecture that I'm looking to solve is that it can only WAITxxx on one thing at a time. So you either have to poll events from a loop, like the original FullDuplex Serial, which means you never go to a power saving mode and it's inefficient in code execution anyway. Or you need to wait on a time and then poll to see if anything happened.

    My event FIFO is intended to allow WAITxxx on many things at once. Then: Get event, run it's handler to completion, sleep. Get event, run it's handler to completion, sleep. Rather like the event model of programming in JavaScript.

    Makes sense to me, the WAITxx hardware of Prop works very nicely, and it should be given smart but simple hardware support.

    You would also need some simple One-shot control on your FIFO load trigger, as some designs would want to queue multiple WAITxx events, and others would just want a single response to any extra same-Events that may fire during the event-code-block.

    Also, some launches would want to complete, others may tolerate being paused.
  • But @jmg you can waitxxx on more then one pin. It is a mask. So you can wait for multiple interrupt pins in one cog while in low power state.

    You just need to read ina and switch to your handlers in software after the waitxxx.

    if you need timeouts use a counter and another pin in the mask.

    Now you have a interrupt handler in low power state in one cog and seven other independent cogs, low power or not, depending on state.
    Fullduplex serial is a example of how to use jumpret. Not a example of how to have a power saving serial communication.

    For really low power you might need one cog for receive and one for send. No problem we have 8 and in future hopefully 16. In Tachyon for example the 'sending' is done by the main cog and the receiving part can use waitxxx without problem very fast and in low power mode if nothing happens.

    Enjoy!
    Mike

    .



  • Exactly.

    And I very strongly suspect we will get some of the better COG options from the "hot" chip.  Those seemed very useful and not too big of a deal power or complexity wise. 

    On mask change, parse it, launch or do it, then return to low power, wait state again, if desired.


  • kwinnkwinn Posts: 8,697
    kwinn wrote:...this topic has become almost totally polarized.
    It certainly has. However I have recently been pondering a "half way house" solution. How about an event driven system built in hardware?Here is what I have been thinking:
    1) A Cog does nothing until it gets the "event" signal.
    2) The code that handles that event runs from top to bottom and when it is done the COG halts and waits for the next event.
    3) The most obvious event source is "reset". which would be given automatically when the COG is loaded.
    4) Now, the interesting parts: Firstly we arrange that all the WAITxxx instructions halt the COG, and it enters the waiting state described in 1)
    5) Having issued a WAITxxx instruction the appropriate external event puts a jump vector into FIFO and the COG gets the event signal.
    6) At which point the jump vector at the head of the FIFO is removed and used to restart the COG at the given address.

    7) That code proceeds as in 2) above.


    No stacks required. No need to divert from the currently executing thread, remeber where you were and then return to it later. No data race conditions to deal with

    One down side is not having priorities, but I'm not going to worry about that. If you have a high priority thing do it on a different COG.
    Fake sig: Raspberry Pi web cam via the resin.io service.






    If that's a "half way house" then what I proposed might be considered a tenth way house. What I suggested was a secondary program counter and flag register that would be used for executing a bit of code in cog ram when the designated event occurred. A designated event could be the state of one or more pins, a counter, a cnt value, etc. No need to save state, pop or push data, or anything like that. Just a very simple task switch mechanism based on an internal or external event. If someone wants to make something more from it then it would be done in SOFTWARE.

  • kwinnkwinn Posts: 8,697
    That would be a good addition someday, IMHO.

    Can't a person juat wait on a whole pile of pins, then jump based on a masked result?

    Doing that is only a few instructions at most.



    Yes, one can wait on multiple pins and handle external events like that. It's a good way of handling multiple events that need fast response times.
  • jmgjmg Posts: 15,175
    edited 2015-07-13 03:55


    If that's a "half way house" then what I proposed might be considered a tenth way house. What I suggested was a secondary program counter and flag register that would be used for executing a bit of code in cog ram when the designated event occurred. A designated event could be the state of one or more pins, a counter, a cnt value, etc.



    That's very close to Heater's framework, but just with a simpler FIFO ?

    Somewhere needs to store the Go-To Address, and some simple conditions.
    The Prop cannot really have hard-vector address like other simple MCUs, as you loose too much backward compatible, not to mention the high cost of using Multiport RAM for that.
    The challenge is then how to manage those Go-To Address & conditions.
    It may be able to pair with a WAITxx opcode - ie the event driven system built in hardware Needs a destination address, and some control bits, as well as what to wait on.
    That could mean a paired-opcode design, where this Event opcode immediately before a WAITxx loads Dest Address, Conditionals, and then skips across the usual SW WAITXX,  and doing so arms the event branch HW.
    Some finite limit on Event address.conditionals will exist, & a FIFO is one way to manage that. It needs to not consume very precious CODE.DATA space.

  • kwinnkwinn Posts: 8,697
    The problem with the waitxxx solutions is that it ties up the cog. What I wanted was to be able to use the cog to handle an event (very short simple code) when it happened and still perform another task (longer time constrained code with loops) when not handling the event.
  • jmgjmg Posts: 15,175
    But @jmg you can waitxxx on more then one pin. It is a mask. So you can wait for multiple interrupt pins in one cog while in low power state.

    You just need to read ina and switch to your handlers in software after the waitxxx.

    if you need timeouts use a counter and another pin in the mask.




    True, but that mask is limited to 32 pins, and needs complex MASK management, (with aperture issues) and currently cannot include Timers/capture events.
    Consuming a physical pin for this is a high cost.

  • kwinnkwinn Posts: 8,697
    That's very close to Heater's framework, but just with a simpler FIFO ?

    Somewhere needs to store the Go-To Address, and some simple conditions.
    Much simpler, no fifo required. The hardware supports only the main and a secondary task. When the event occurs the secondary program counter and flags control execution. The main code sets up the secondary program counter, and the event that triggers the switch FF. The secondary code clears the switch FF when it has finished. Both main and secondary program counters and flags are maintained when not in use. Both main and secondary code are in cog ram so they could share subroutines.
  • Wait a minute.

    There is "need to enter low power state" and there is "need to respond to events" and "need to more fully employ the COG"

    No interrupts are needed.

    If there isn't much to do, having a COG wait is no big deal, and it satisfies the low power state too.

    If there is more to do, than the COG can poll and respond and that can be adjusted in software.  That same COG can manage timers and such too.

    One could always use a few COGS to arrive at a solution, and there will be 16 of them, much faster than we are used to now, and it's very likely we get the COG management options already explored as well.

    There will be 64 pins as well, and the pin may well serve some purpose in addition to performing these tasks. 


  • But @jmg you can waitxxx on more then one pin. It is a mask. So you can wait for multiple interrupt pins in one cog while in low power state.

    You just need to read ina and switch to your handlers in software after the waitxxx.

    if you need timeouts use a counter and another pin in the mask.



    True, but that mask is limited to 32 pins, and needs complex MASK management, (with aperture issues) and currently cannot include Timers/capture events.
    Consuming a physical pin for this is a high cost.



    Wrong again. Did you read my post? There is no problem at all to have a counter switching a pin state in the same cog waiting for waitxxx in low power mode. It is all there already in the P1.

    And sure the mask is limited to 32 pins. The propeller has just 32 pins available. Not sure what you mean by complex mask management or aperture issues. Can you elaborate this?

    And yes if you want a interrupt pin you will need a physical pin on the propeller. What else you would use on other controllers?

    slightly confused
    Mike

  • kwinnkwinn Posts: 8,697
    Wait a minute.

    There is "need to enter low power state" and there is "need to respond to events" and "need to more fully employ the COG"

    No interrupts are needed.

    If there isn't much to do, having a COG wait is no big deal, and it satisfies the low power state too.

    If there is more to do, than the COG can poll and respond and that can be adjusted in software.  That same COG can manage timers and such too.

    One could always use a few COGS to arrive at a solution, and there will be 16 of them, much faster than we are used to now, and it's very likely we get the COG management options already explored as well.

    There will be 64 pins as well, and the pin may well serve some purpose in addition to performing these tasks. 




    What I posted was my wish for the P1 when the project I was working on required all 8 cogs and I still needed to deal with a fast but infrequent external event. Such a simple addition would add a lot of flexibility to each cog.

    This wouldn't have been a problem for a P2 with it's 16 cogs, but at some point the limits of even 16 faster cogs will be reached. Adding an event switch capability would stretch those limits.
  • I'll bet there was a way to deal with it, and as mentioned so many times before, it's not just a simple addition. 
  • jmgjmg Posts: 15,175
    edited 2015-07-13 03:51


    Wrong again. Did you read my post? There is no problem at all to have a counter switching a pin state in the same cog waiting for waitxxx in low power mode. It is all there already in the P1



    Err, the problem is you have consumed a pin.
    There was talk of virtual pins to avoid this, but I'm not sure where that is P2 design wise. 
    Ideally, trigger events are not limited to PIN based ones, and a design that only pivots off pins, is a kludge.Events can be timer or capture/compare based too.
  • @jmg,

    ok for the counter pins it would be nice to have virtual pins. I agree. But the p1 is a 32 bit processor and so a mask has 32 bits aka pins.

    So any external interrupt will need a hardware pin to be useful. Even in the P1 this can be any of them pins. Still see no complex mask management or aperture issues. Capture and compare based events will need hardware pins too, so that leaves timer based events. Yes. There a internal port B would be useful.

    Still do not see the kludge.

    A interrupt is usually a external event. Either binary or as you said some capture/compare thing (done by some counter mode?). All of them will need hardware pins. The only use for internal pins would be the counters of each cog and a way for signaling events between cogs without using hub ram. Sort of a internal mailbox for communication.

    By now nobody knows if or if not anything is there on the P2. Besides Chip and I am not even sure there.

    So lets wait and see.

    Mike

  • jmgjmg Posts: 15,175
    Still do not see the kludge.



    Yet you admit it would be nice to have virtual pins ? To me that shows you do see the kludge.

    A interrupt is usually a external event. Either binary or as you said some capture/compare thing (done by some counter mode?). All of them will need hardware pins.

    Counter overflow does not need to consume a hardware pin, nor does compare or some captures (eg those captures done after N counts of an external pin, or Armed captures.
    - the Capture signal is not quite the same as the pin signal.)
    Others have talked about memory-write traps, again, no physical pin involved there.

    Aperture issues can arise anytime software has to update a hardware mask.

    The WAITxx opcode reacts to the pin state at that clock edge, then some clocks later, a new compare mask is provided by software (to avoid retrigger), but that reads on a later clock edge.
    However, if mutliple events occur within that window, you risk update with a mask that includes not-yet-actioned changes.

  • How would there be a retrigger?  There aren't any interrupts!

    Once the reaction has taken place, it's entirely up to the programmer as to when it makes sense to respond again.


  • jmgjmg Posts: 15,175
    How would there be a retrigger?  There aren't any interrupts!

    Once the reaction has taken place, it's entirely up to the programmer as to when it makes sense to respond again.

    Yup, and therein lies the problem. - the programmers software has to sample the pins, at a different time from the WAIT opcode, and so you are never really sure if that sample is what the HW opcode reacted to.
    This is why it is best to use HW for HW tasks and SW for others. Mixing the two, has many dangers novices have no idea about.

  • Heater.Heater. Posts: 21,230
    edited 2015-07-13 05:27
    To be clear, in the hardware event system I described I was thinking that only one event of a particular source, e.g. a particular pin change, would be registered. If another edge occurs before the last one was handled it would be lost.
    That is the same behaviour as we have with WAITxxx now.
    Doing it this way limits the required size of the event FIFO to the number of possible event sources. Otherwise it becomes a "capture buffer" and who is to say how deep that should be?
    It has been pointed out that you can sort of kludge this already this by funnelling everything through the pins and doing a WAIT on the state change in multiple pins. Doesn't that become impossible when we have 64 pins and two 32 bit pin registers? 
    One advantage of my proposed event FIFO is that it keeps events in time order and ensures they all get handled. Whereas kludging it through a pin mask register does not and faster events can block slower ones unless the  programmer is taking care of that.  
    Has anyone clamouring for interrupts on the Prop here ever thought of using that technique to achieve what they think they want interrupts for?
    For those who say "but I want a long running background task plus an interrupt to handler to handle an incoming event occasionally" I would point out this:
    Your long running "background" need not be written as an endless loop, rather it would do it's thing for one iteration and when it wants to loop it would actually run to it's end and terminate waiting for an event. That event it is waiting for is "run me again". Basically your background loop is turned it to just another event handler. Nice and simple.      
Sign In or Register to comment.