Shop Learn
The New 16-Cog, 512KB, 64 analog I/O Propeller Chip - Page 114 — Parallax Forums

The New 16-Cog, 512KB, 64 analog I/O Propeller Chip

1111112114116117144

Comments

  • jmgjmg Posts: 14,882
    . IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.




    IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?
  • cgraceycgracey Posts: 13,690
    edited 2015-07-25 23:10
    For anyone who wants to see, here is the Verilog code that makes up the interrupt system. The only thing you're not seeing here is the LINK instruction mux in the pipeline and the event sources, both of which are almost nothing to look at.
    This was 4-spaces-per-tab in Quartus, but I reformatted it to 8-spaces-per-tab so that you can look at it in Notepad, if you want:
  • How about a single HOLDINT instruction that takes a 3-bit mask.
    HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
    Just AND the ~MASK bits to see if an interrupt can be inserted!  I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
  • Cluso99Cluso99 Posts: 18,039
    edited 2015-07-25 23:51
    What about IDEFER ON/OFF ?

    Chip, do the hub long r/w interrupts work with WORD and BYTE read and writes too?

    It looks fantastic. Cannot wait to try them!
  • cgraceycgracey Posts: 13,690
    . IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.




    IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?

    I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?
  • cgraceycgracey Posts: 13,690
    edited 2015-07-26 00:24
    How about a single HOLDINT instruction that takes a 3-bit mask.
    HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
    Just AND the ~MASK bits to see if an interrupt can be inserted!  I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.

    It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
  • cgraceycgracey Posts: 13,690
    What about IDEFER ON/OFF ?

    Chip, do the hub long r/w interrupts work with WORD and BYTE read and writes too?

    It looks fantastic. Cannot wait to try them!

    Any write within a sensitive %0000_0000_0000_00xx_xx00 boundary will trigger the event. If you write an overlapping word or long, you would cause two events! Same sensitivity for reading.
  • jmgjmg Posts: 14,882
    IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?

    I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?

    That is a quite common use in MCU interrupts.
    Sometime you want to know you are timing/starting a state engine from an edge about to arrive, not one that (may have) arrived at some unknown time in the past.

    Sometimes sticky bits are useful, and sometimes they are a royal pain, so a means to clear sticky bits is important. Users can then simply choose which they need. A clean slate, or a deferral approach.

    Also, (as I've mentioned before) it is ideal if the time to vector from that event is jitter free.
    The old Scenix parts managed that, IIRC - and it keeps with the Prop's solidly deterministic philosophy.

  • jmgjmg Posts: 14,882


    It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.

    Most small MCUs (even the 25c ones) have individual enables on interrupts.

    An example of where you may want to not disable an INT is Watchdog/COP operation, where a small stub of code, checks the pulse of the COG SW, and tries to catch lockups and freezes.
    Of course, sometimes you do need to turn off all INTs (briefly), and a global flag does that.
  • cgraceycgracey Posts: 13,690
    edited 2015-07-26 00:43
    IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?

    I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?

    That is a quite common use in MCU interrupts.
    Sometime you want to know you are timing/starting a state engine from an edge about to arrive, not one that (may have) arrived at some unknown time in the past.

    Sometimes sticky bits are useful, and sometimes they are a royal pain, so a means to clear sticky bits is important. Users can then simply choose which they need. A clean slate, or a deferral approach.

    Also, (as I've mentioned before) it is ideal if the time to vector from that event is jitter free.
    The old Scenix parts managed that, IIRC - and it keeps with the Prop's solidly deterministic philosophy.



    Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.
    The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.
  • cgraceycgracey Posts: 13,690


    It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.

    Most small MCUs (even the 25c ones) have individual enables on interrupts.

    An example of where you may want to not disable an INT is Watchdog/COP operation, where a small stub of code, checks the pulse of the COG SW, and tries to catch lockups and freezes.
    Of course, sometimes you do need to turn off all INTs (briefly), and a global flag does that.


    You could always do a 'SETINTx #0' to shut off an interrupt source. When you turn it back on later, it would resume responding to its selected interrupt source. It's stateless that way. Does that suffice?
  • Looks good Chip!
  • jmgjmg Posts: 14,882

    Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.That's probably OK, tho hiding that in WC is perhaps too obtuse, and Assembler psuedo ops would be better.eg CLRPER issues  GETPER opcode minus WC&  GETPER issues GETPER opcode, with required / user expected WC included by default.
     

    The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.

     A common minor variant on that, used on small MCUs is to execute one mainline code op, before next interrupt.That allows single-step debug/monitor to be coded using interrupts & also prevents 100% stall on interrupt miss-handle.
  • How about a single HOLDINT instruction that takes a 3-bit mask.
    HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
    Just AND the ~MASK bits to see if an interrupt can be inserted!  I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.

    It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.



    Well, that depends. If I call SETEDG, is that enough to be able to use GETEDG and WAITEDG? Or do I have to also call SETINTx?



    If GETxxx/WAITxxx only works with SETINTx, then you also need a mask to prevent insertion of LINK instructions.



    If SETINTx is not required, then a single flag is probably good enough. The only reason I can otherwise think of having a mask is that you may be combining third-party code (which is more likely to happen with the P2) that each use interrupts. In that case, you wouldn't necessarily want one routine to inadvertently disable interrupt for an unrelated routine.

  • potatoheadpotatohead Posts: 10,222
    edited 2015-07-26 06:42
    Would that third party code have to integrate with a COG?

    Seems to me the majority use case will be to take third party code and run it on a COG like we do now on P1.

    And where that is true, the clash of interrupts really isn't an issue.
  • jmgjmg Posts: 14,882
    I can see use cases where someone cuts and pastes code examples together.
    Of course, any merge of interrupt code is going to need care, but if those code sections can cleanly manage their own interrupt flags there is much less effort needed, and the 'code reuse' mode Parallax strives for is easier.
  • cgraceycgracey Posts: 13,690
    edited 2015-07-26 07:27
    How about a single HOLDINT instruction that takes a 3-bit mask.
    HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
    Just AND the ~MASK bits to see if an interrupt can be inserted!  I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.

    It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.



    Well, that depends. If I call SETEDG, is that enough to be able to use GETEDG and WAITEDG? Or do I have to also call SETINTx?



    If GETxxx/WAITxxx only works with SETINTx, then you also need a mask to prevent insertion of LINK instructions.



    If SETINTx is not required, then a single flag is probably good enough. The only reason I can otherwise think of having a mask is that you may be combining third-party code (which is more likely to happen with the P2) that each use interrupts. In that case, you wouldn't necessarily want one routine to inadvertently disable interrupt for an unrelated routine.



    Once you do SETEDG, you've selected the edge and source signal that will generate EDG events. There is a two-clock delay tied to SETEDG that prevents false EDG events resulting from changing edge and pin settings. Once SETEDG is done, any resulting EDG events are going to set the EDG event flag. Any GETEDG/WAITEDG instructions will clear the EDG event flag. If you select EDG as an interrupt source, the EDG event is used directly, neverminding the EDG event flag. The event flags are just there for the GETxxx and WAITxxx instructions. Interrupts don't use them. Signals that set event flags are also what trigger interrupts.
  • cgraceycgracey Posts: 13,690

    Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.That's probably OK, tho hiding that in WC is perhaps too obtuse, and Assembler psuedo ops would be better.eg CLRPER issues  GETPER opcode minus WC&  GETPER issues GETPER opcode, with required / user expected WC included by default.
     

    The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.

     A common minor variant on that, used on small MCUs is to execute one mainline code op, before next interrupt.That allows single-step debug/monitor to be coded using interrupts & also prevents 100% stall on interrupt miss-handle.


    Ah, yes, single-stepping. We could use some high bit in the SETBRK instruction to set that mode. I think all it would have to do is break on ANY address. One bit and one OR gate in addition to the comparator.
  • cgraceycgracey Posts: 13,690
    edited 2015-07-26 10:14
    I got the single-step interrupt working. The rule is: break when no interrupt service routine is executing. I'm changing that to allow for breaking within INT1 and INT2, though.
    Here is a program:
    dat org
    mov dira,#%1111 'make pins 3..0 outputs
    mov ijmp0,#isr0 'set int0 vector setbrk brk 'set single-step breakpoint setint0 #7 'enable single-step interrupt
    :loop xor outa,#%0001 'this routine is getting single-stepped xor outa,#%0010 xor outa,#%0100 jmp @:loop
    isr0 xor outa,#%1000 'this is the single-step interrupt routine reti0
    brk long 1<<20

    And here is what it looks like running (D3..D0 are pins 3..0):

    0c41f5b0ec2d3d8d53779f4b8143c1.jpg
    The Prop2 is running at 20MHz, so each clock period is 50ns. The interrupt service routine is toggling the top square wave every 600ns, or 12 clocks, or 6 instructions. Here's what is executing:
    XOR outa,#%0001 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dXOR outa,#%0010 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dXOR outa,#%0100 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dJMP @:loop 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'd<repeat>
    1328 x 747 - 344K
  • jmgjmg Posts: 14,882
    edited 2015-07-26 10:17
    I got the single-step interrupt working. The rule is: break when no interrupt service routine is executing. I'm changing that to allow for breaking within INT1 and INT2, though.


    Looks good - how does that cope with REP, and multi-cycle opcodes ?I guess they complete, then yield to the Stepper-INT ?
    If users wanted to step within a REP, the debug SW could swap-in TRAP type opcodes ?
  • cgraceycgracey Posts: 13,690
    I got the single-step interrupt working. The rule is: break when no interrupt service routine is executing. I'm changing that to allow for breaking within INT1 and INT2, though.


    Looks good - how does that cope with REP, and multi-cycle opcodes ?I guess they complete, then yield to the Stepper-INT ?
    If users wanted to step within a REP, the debug SW could swap-in TRAP type opcodes ?

    It would wait until multi-cycle opcodes finished before inserting the LINK. I must test that to see what it looks like.
    You can't step within a REP. Maybe you could fake it, though. You can never step through an INT0 routine, of course, unless you faked that, too.
  • evanhevanh Posts: 12,230
    edited 2015-07-26 10:55
    I've never thought much of adding hardware for debug assistance.  Hand crafting debug code works a treat really.  ISRs aren't much different to mainline then.  Chip has just done one typical hand coded debug type exercise right above.

  • jmgjmg Posts: 14,882
    I've never thought much of adding hardware for debug assistance.  Hand crafting debug code works a treat really.  ISRs aren't much different to mainline then.  Chip has just done one typical hand coded debug type exercise right above.



    ??  The above is the basic framework for single step debug, and that does need hardware assistance.It is that hardware assist, that Chip is testing.
  • cgraceycgracey Posts: 13,690
    I've got it stepping through INT1 and INT2 code now, as well as mainline code. I would like it to be able to do INT0, but that means we need one higher level of interrupt just for debugging. I'm looking into using the hidden RAM registers behind INA and INB for the interrupt LINK target. This way, you could single-step and breakpoint your entire application during development. I just need a gate to cut off reading INA and INB within the debug ISR so that I can read the RAM data behind them. The debug ISR can be a hub-exec affair.
  • cgraceycgracey Posts: 13,690
    edited 2015-07-26 11:23
    I've never thought much of adding hardware for debug assistance.  Hand crafting debug code works a treat really.  ISRs aren't much different to mainline then.  Chip has just done one typical hand coded debug type exercise right above.



    I agree, but single-stepping can be great for learning how an architecture works. I've never had a single-stepping debugger that was easy to use, though. The setup has always been way more troublesome than some little ad hoc solution.
  • jmgjmg Posts: 14,882

    I agree, but single-stepping can be great for learning how an architecture works. I've never had a single-stepping debugger that was easy to use, though. The setup has always been way more troublesome than some little ad hoc solution.
    That's more an upper-level software issue, than a Single Step debug problem. (Plenty of sub standard Debuggers out there.)
    Good simulators give users single-step debug, with 100% visibility, and they certainly are easy to use.
     I would like it to be able to do INT0, but that means we need one higher level of interrupt just for debugging. I'm looking into using the hidden RAM registers behind INA and INB for the interrupt LINK target. This way, you could single-step and breakpoint your entire application during development. 

    That certainly would have appeal.


  • BLOCKI - block interrupts
    ALLOWI - allow interrupts - default


    because you use block elsewhere, a better name and clearer description would help those who are not native English speakers.
    I think BLOCK prevents or defers or pauses or ignores interrupts - then, the  details matter :
    Are pending flags responded to on ALLOWI, or are they discarded, and only those after ALLOWI acted on ?


    Interrupts are still gathered after BLOCKI and then responded to after ALLOWI.
    I think 'defer' is the most descriptive word: DEFERI. Makes a wierd-looking instruction, though. IDEFER would be better, but that doesn't work for IALLOW. We need another word for 'allow' that starts with a consonant. IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.

    I never heard or used the word defer (I'm german). Block I understood. That a interrupt is gathered I would have expected.Hold would also be good. Permit is ok.Frame for the read/write block would be ok.
  • kwinnkwinn Posts: 8,697
    edited 2015-07-26 14:31


    BLOCKI - block interrupts
    ALLOWI - allow interrupts - default


    because you use block elsewhere, a better name and clearer description would help those who are not native English speakers.
    I think BLOCK prevents or defers or pauses or ignores interrupts - then, the  details matter :
    Are pending flags responded to on ALLOWI, or are they discarded, and only those after ALLOWI acted on ?


    Interrupts are still gathered after BLOCKI and then responded to after ALLOWI.
    I think 'defer' is the most descriptive word: DEFERI. Makes a wierd-looking instruction, though. IDEFER would be better, but that doesn't work for IALLOW. We need another word for 'allow' that starts with a consonant. IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.

    I never heard or used the word defer (I'm german). Block I understood. That a interrupt is gathered I would have expected.Hold would also be good. Permit is ok.Frame for the read/write block would be ok.

    Hold and Allow or Hold and Free would also be ok.

    Perhaps even Hold and Release?
  • kwinnkwinn Posts: 8,697
    Would it be possible to produce a listing of the instructions executed when single stepping?
  • MJBMJB Posts: 1,235
    I never heard or used the word defer (I'm german).


    I am german too ...
    There is a great web site and mailing list:  one-word-a-day
    so defer is the word of the day ;-)
Sign In or Register to comment.