I originally presented this idea a comment elsewhere
, but I recently noticed some documentation that made me feel it was worth re-posting this idea in its own thread. Note that this is not
exactly the same suggestion as in the referenced comment, but a similar one that should be a bit clearer to understand and implement.
Currently, the smart pins signal events to cogs by raising their associated IN bit. Once a cog has dealt with the event, it calls PINACK to clear the event. There are a few issues with this approach:
- While PINACK takes only 2 clock cylces, it takes another 5 clock cycles for IN to be cleared.
- If multiple cogs are interested in the same event, they can all safely call PINGETZ, but they cannot all safely call PINACK.
So, here's my suggestion:
- In each cog, add a 64-bit pin-event register (one bit per pin). The pin-event register captures the high state of the IN line and the bits are "sticky". Once set, the bit requires an explicit unset from user code.
- When a smart pin signals an event, it no longer holds IN high; it only pulses the IN signal.
- Because of this arrangement, reading IN on the same clock as the pulse will detect the pulse directly. Reading IN after the pulse will read the sticky bit.
- Get rid of PINACK as an alias for "PINSETM #1". Instead, make PINACK a new instruction that clears the sticky bit(s). Really, it re-samples the IN signal(s), which will be 1 if another event is occuring on the same clock as the call to PINACK, and 0 otherwise.
- With the removal of PINACK as an alias, this frees up one bit in the PINSETM pattern. Repurpose that bit to indicate whether IN reflects the current state of the pin or the current state of the pin-state register.
What this gives us in return:
- The new PINACK does not have the 5 clock penalty, since you are now updating the pin-event register instead of the smart pin.
- Each cog has its own pin-event register, so it can safely call PINACK without affecting any other cog.
- It would now be possible to react to smart pins using only the pulse. In other words, in cases where a cog is waiting (WAITEDG or WAITINT) for a smart pin, it can be released with the pulse and not have to call PINACK at all.
- Because this change would also work with the "default" pin mode, you can optionally use the pin-event register to capture rising edges (or falling edges if configured for inverted signals) without the use of a smart pin.
- This improves the ability for smart pins to be used as an alternative to ATN when you need to pass more than the ATN event itself. In addition to the one-to-one "mailbox" usage that's already supported, it can also be safely used for one-to-many mailboxes. This will pair nicely with the current ATN event, which covers the many-to-one case (and the slightly faster one-to-one, event-only case).