CORDIC Coprocessor
The Propeller 2 contains a 54-stage pipelined CORDIC solver that can compute various math functions.
When a cog issues a CORDIC instruction, it must wait for its hub slot, which is 0..7 clocks away, in order to hand off the command to the CORDIC coprocessor. 55 clocks later, results will be available via the GETQX and GETQY instructions, which will wait for the results, in case they haven't arrived yet.
Because each cog's hub slot comes around every 8 clocks and the pipeline is 54 clocks long, it is possible to overlap CORDIC commands, where several commands are initially given to the coprocessor, and then results are read and another command is given, indefinitely, until, at the end, the trailing results are read. One must not have interrupts enabled during such a juggle, or enough clocks could be stolen by the interrupt service routine that one or more of the results could be overwritten before you can read them.
TODO: Reword above
If results are attempted to be read when none are available and no commands are in progress, GETQX/GETQY will only take 2 cycles and the QMT (CORDIC empty) event flag will be set.
Binary Angles
TODO explain binrads For now, see Wikipedia.
Result retrieval
GETQX D {WC/WZ/WCZ} - Get CORDIC result X
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101011 CZ0 DDDDDDDDD 000011000 | D | X[31] | Result == 0 | 2..58 | 2..58 | No |
---|
Retrieves the X result from the CORDIC coprocessor into Destination. TODO: What gets written if QMT flag gets set?
If the WC or WCZ effect is specified, the C flag is set to the MSB of the X result.
If the WZ or WCZ effect is specified, the Z flag is set (1) if the X result equals zero, or is cleared (0) if it is non-zero.
GETQY D {WC/WZ/WCZ} - Get CORDIC result Y
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101011 CZ0 DDDDDDDDD 000011001 | D | Y[31] | Result == 0 | 2..58 | 2..58 | No |
---|
Retrieves the Y result from the CORDIC coprocessor into Destination. TODO: What gets written if QMT flag gets set?
If the WC or WCZ effect is specified, the C flag is set to the MSB of the Y result.
If the WZ or WCZ effect is specified, the Z flag is set (1) if the Y result equals zero, or is cleared (0) if it is non-zero.
Commands
{ SETQ {#}Q }
QROTATE {#}D,{#}S - Rotate 2D vector
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101010 0LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 2..9 | 2..9 | No |
---|
QROTATE instructs the CORDIC coprocessor to rotate a signed 2D vector by the binary angle in Source. The X component of the vector is given in Destination and if QROTATE is immediately preceded by SETQ, the Q value provides the Y component (otherwise, Y=0).
When it is done, GETQX/GETQY will return the X'/Y' of the rotated vector, respectively.
Mathematically, it performs this operation:
\[\begin{align*} \mathit{QX} \approx D \cos(S) - Q \sin(S)\\ \mathit{QY} \approx D \sin(S) + Q \cos(S) \end{align*}\]Thus, if Q=0 (as happens when SETQ is not used), QROTATE can be used to compute sine/cosine pairs at a scale given by D. i.e.
'' Compute sine/cosine for theta, 32 bit precision.
QROTATE ##$7FFF_FFFF, theta
' Can do other stuff while waiting
GETQX cosine ' cosine with 32 bit precision
GETQY sine ' cosine with 32 bit precision
This is also the same operation as converting a polar vector (length/angle) into a carthesian(X/Y) one:
'' Convert polar to carthesian
QROTATE length,angle
' Can do other stuff while waiting
GETQX x
GETQY y
QVECTOR {#}D,{#}S - Angle and length of 2D vector
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101010 1LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 2..9 | 2..9 | No |
---|
QROTATE instructs the CORDIC coprocessor to convert a carthesian vector (X/Y) in Destination (X) and Source (Y) into a polar vector (length/angle). When it is done, GETQX will return the angle (as a binary angle) and GETQY will return the length of the vector.
Mathematically:
\[\mathit{QX} \approx \operatorname{atan2}(S,D)\\ \mathit{QY} \approx \sqrt{D^2+S^2}\]QMUL {#}D,{#}S - Unsigned 32-bit multiply
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101000 0LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 2..9 | 2..9 | No |
---|
QMUL instructs the CORDIC coprocessor to perform unsigned multiplication of Destination and Source. When it is done, GETQX will return the lower 32 bits of the result and GETQY will return the upper 32 bits.
Note that the lower half of a multiply result is the same regardless of wether the operation is signed or unsigned. Thus QMUL can be used for signed multiplication as-is, as long as the upper half of the result from GETQY isn't needed.
{ SETQ {#}Q }
QDIV {#}D,{#}S - Unsigned divide
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101000 1LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 2..9 | 2..9 | No |
---|
QDIV instructs the CORDIC coprocessor to perform unsigned division of Destination by Source. If QDIV is immediately preceded by SETQ, the Q value provides the upper 32 bits of a 64-bit dividend.
When it is done, GETQX will return the quotient and GETQY will return the remainder.
{ SETQ {#}Q }
QFRAC {#}D,{#}S - Unsigned divide (fractional)
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101001 0LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 2..9 | 2..9 | No |
---|
QFRAC instructs the CORDIC coprocessor to perform fractional division of Destination by Source. It works identically to QDIV, except that Destination is the upper 32 bits of the dividend and the optional SETQ value is the bottom 32 bits (zero if no SETQ).
TODO maybe write more here
QSQRT {#}D,{#}S - Square root
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101001 1LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 2..9 | 2..9 | No |
---|
QSQRT instructs the CORDIC coprocessor to compute the square root of the unsigned 64-bit number formed by Destination (lower half) and Source (upper half).
When it is done, GETQX will return the result, rounded down. ? TODO verify rounding. Also what happens to Y???
QLOG {#}D - Fixed-point logarithm
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101011 00L DDDDDDDDD 000001110 | none | --- | --- | 2..9 | 2..9 | No |
---|
QLOG instructs the CORDIC coprocessor to compute the base-2 logarithm of the unsigned 32-bit number in Destination. When it is done, GETQX returns the logarithm, in 5.27 fixed-point format (i.e. the top five bits containing the whole part).
\[\mathit{QX} \approx 2^{27}(\log _{2} D)\]QEXP {#}D - Fixed-point exponent
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1101011 00L DDDDDDDDD 000001111 | none | --- | --- | 2..9 | 2..9 | No |
---|
QLOG instructs the CORDIC coprocessor to compute two to the power of the 5.27 fixed-point exponent in Destination. When it is done, GETQX returns the result (TODO rounded down?).
\[\mathit{QX} \approx 2^{D/2^{27}}\]