The DS has accelerators for division and square-root computations. This section explains the Divider.
Registers for Division
Data registers have been prepared for the dividend, the divisor, the quotient and the remainder.
The relationship between these registers is as follows:
Also, a control register is provided to control the Divider.
Operations of the Divider
To perform calculations, the Divider sets the dividend and the divisor in the data registers DIV_NUMER
and DIV_DENOM
. After the control register DIVCNT
is appropriately set, the results of the division are saved in DIV_RESULT
and DIVREM_RESULT
. (In actuality, the calculation begins right after a value has been set in either DIV_NUMER
, DIV_DENOM
, or DIVCNT
. If data is written to the registers during the calculation, the calculation begins all over again.)
There are three modes for division:
You can switch between modes by changing the value set in the MODE
bit of the DIVCNT
register.
When the Divider begins a division calculation, the DIVCNT
register's BUSY
bit becomes 1
. The bit retains that value until the result are computed. When this bit changes to 0
, the values in the DIV_RESULT
and DIVREM_RESULT
registers hold the completed computation result.
When the divisor is 0
, the DIVCNT
register's DIV0
bit becomes 1
. When this is the case, the calculation result is undefined.
Calculation Cycles
The number of cycles required by the Divider to perform a division calculation varies, depending on the division mode.
To make more efficient use of the Divider, you can perform another task while waiting for the results after setting the parameters in the Divider's data registers.
Setting the Parameters
Use CP_SetDivImm*()
and CP_SetDiv*()
to set the parameters for the Divider. Both functions can set both the dividend and the divisor. The CP_SetDiv*()
function can also be used to set the DIVCNT
register's division mode.
CP_SetDivImm32_32()
, CP_SetDivImm64_32()
, CP_SetDivImm_64_64()
CP_SetDiv32_32()
, CP_SetDiv64_32
, CP_SetDivImm64_64()
Thus, if you plan to perform a succession of division calculations in the same division mode, you can use CP_SetDiv*()
the first time and then use CP_SetDivImm*()
for all subsequent calculations.
Waiting for Calculation to End
To check whether or not the calculation has ended, call CP_IsDivBusy()
.
To wait for the calculation to end, call CP_WaitDiv()
.
Getting the Calculation Result
To get the quotient of the division calculation, call either CP_GetDivResult*()
or CP_GetDivResultImm*()
.
The former waits until the DIVCNT
register is no longer in the BUSY
state before fetching the result. The latter acts immediately.
To get the remainder, call CP_GetDivRemainder()
or CP_GetDivRemainderImm*()
.
The former waits until the DIVCNT
register is no longer in the BUSY
state before fetching the result. The latter acts immediately.
Notes
When the division mode is "32bit divided by 32bit" or "64bit divided by 32bit," the upper 32 bits in data registers for which only 32 bits are being used need to be filled with zeros. The NitroSDK functions do this automatically. However, don't forget to do this when your application directly sets values in the registers.
If you are using the thread system, the Divider calculations are thread safe by default.
Example
The following is an example using the Divider to conduct a division calculation and then displaying the result.
u32 quotient;
u32 remainder;
//---- set parameter and div-mode
CP_SetDiv( 0x12345678, 0x300, CP_DIV_32_32BIT_MODE );
//---- wait for division to finish
CP_WaitDiv();
//---- display result
quotient = CP_GetDivResultImm32();
remainder = CP_GetDivRemainderImm32();
OS_Printf( "quotient=%x, remainder=%x\n", quotient, remainder );
12/27/2004 Initial version.