◇ Digital Logic Lab

CS203 / DIGITAL LOGIC DESIGN / GROUP 20

Small operations.
Precise results.

From a 48-bit product to a rounded fraction. From a sequence of shifts to sine and cosine. An interactive look inside my digital design work.

DESIGNED & EXPLAINED BYKanav Miglani
ROLL NUMBER2025CSB1557
VECTOR STUDY / 01θ = 60°
60-degree unit vector60°cos θ = 0.5sin θ≈ 0.866(cos θ, sin θ)xy

01 / MY CONTRIBUTION

One part of a collaborative design

Three ideas, made inspectable.

The floating-point multiplier is Group 20’s project. My work covers mantissa normalization and round to nearest, ties to even. The CORDIC sine/cosine extension is a separate contribution.

See the group’s module split

Sidda: input processing. Neeraf: mantissa multiplication. Kanav: normalization and rounding. Srijan: sign and exponent. Md. Sahil: multiplier testbench, as described in the PDF. The supplied ZIP includes a separate basic sine/cosine testbench. These are source attributions, not claims that tests passed.

02 / NORMALIZATION EXPLORER

Exact BigInt bit operations

Keep the precision. Track the rest.

This explorer reproduces normalization_unit in the supplied design.sv, including its 24-bit adder carry behavior.

Normalized input significands are in [1, 2), so their product is in [1, 4). This unit chooses between two bit windows; it is not a general leading-zero normalizer.

What happens when rounding carries out?

The CLA computes a 24-bit sum and a separate carry. On overflow, the RTL sets mant_final = rounded_mant[23:1] and norm_shift_flag = 1. For 0xFFFFFF + 1, the stored sum wraps to zero, so the final fraction is zero. The flag is one Boolean adjustment, not a count of two shifts. Arbitrary raw 48-bit inputs are accepted here to inspect that exact behavior.

03 / ROUND TO NEAREST, TIES TO EVEN

Four bits. One decision.

Exactly halfway? Look at the last bit.

“Even” means the retained significand’s last bit is zero. For an exact tie, G = 1 and R = S = 0: keep an even significand, increment an odd one.

round_up = G ∧ (R ∨ S ∨ L)

The full truth table

GRSLIncrement

Sticky is the OR of all remaining discarded bits. The highlighted row follows the toggles.

04 / THE CORDIC LAB

24 iterations · educational JS model

A little rotation goes a long way.

Change the angle to recompute the complete solution immediately. Step through the rotations separately to see how the vector converges.

Supported domain: approximately −360° to +360°. Exact limit: ±6.2831854820251465 rad (FP32 0x40C90FDB). This model does not quantize the input to FP32.

FINAL ESTIMATES / AFTER ALL 24 ITERATIONSIndependent of playback

Reference

Absolute error

Reference

Absolute error

Rotation view

CORDIC target and current rotation vectorxy1−11−1
Current vector Reference target

Vectors are shown in the original quadrant. Table x/y values are the reduced core coordinates, before sign restoration.

Follow the residual

dᵢ = +1 if zᵢ ≥ 0, else −1
xᵢ₊₁ = xᵢ − dᵢ · yᵢ · 2⁻ⁱ
yᵢ₊₁ = yᵢ + dᵢ · xᵢ · 2⁻ⁱ
zᵢ₊₁ = zᵢ − dᵢ · atan(2⁻ⁱ)

Both new coordinates use the previous x and y. Initialize x₀ = K₂₄ ≈ 0.607252935, y₀ = 0. K compensates the gain ∏√(1 + 2⁻²ⁱ).

State after each rotation; z in radians
Stepdxyz (rad)

Model boundary. These estimates use JavaScript double precision and 24 mathematical rotations, including at very small angles. They do not emulate Q28 truncation, arithmetic shifts, the RTL small-angle bypass, or FP32 output rounding. Math.sin/Math.cos supply only the reference values and target vector. This is not a bit-accurate RTL simulation.

05 / FROM ALGORITHM TO RTL

Grounded in the supplied source

What the hardware actually describes.

FP32 radiansValidate & convert
→
Range reductionRecord sign flip
→
24 Q28 stagesShift & add/subtract
→
FP32 resultNormalize & RNE

01 / Interface & range

fp_sincos_cordic accepts a 32-bit binary32 angle in radians. The cosine bit selects sine (0) or cosine (1), returning one FP32 result. Inputs with exponent 255 (NaN or infinity), or magnitude bits above 0x40C90FDB, return quiet NaN 0x7FC00000.

02 / Signed Q28 arithmetic

The sine/cosine modules use signed 32-bit integers with 28 fractional bits (Q4.28, counting the sign in the four integer bits). One unit is 2⁻²⁸; range is [−8, 8 − 2⁻²⁸]. Normal FP32 significands shift by E − 127 + 5. Conversion discards low bits rather than rounding them.

03 / Gain & quadrants

The initial x is K = 163008219 / 2²⁸. The code first reduces to approximately [−π, π], then [−π/2, π/2] using integer constants. Reducing by ±π sets a flip flag; both output coordinates are negated afterward. The arctangent table contains 24 quantized constants.

04 / Structure, not clock cycles

The standalone Q28 module uses a 24-iteration loop inside always @(*). The ZIP version explicitly instantiates 24 combinational stages, with three 32-bit CLA adders per stage. Subtraction is A + (~B) + 1. There is no clock input: these stages are not 24 clock cycles.

05 / Small angles & output

For |angle| ≤ 2⁻²⁰ radians (0x35800000), Q28 sine returns the input bits, preserving signed zero and subnormals; cosine returns 1.0. Otherwise the selected Q28 coordinate is normalized by locating its leading one. Output rounding uses guard ∧ (sticky ∨ retained LSB); carry increases the exponent. The conversion contains overflow-to-infinity and underflow-to-zero branches.

06 / The Q48 alternative

fp_trig_cordic.sv uses signed 64-bit Q16.48 and 48 combinational rotations. It adds tangent using 128-bit integer division and uses a 2⁻¹⁶ small-angle threshold. Modes 01/10/11 select sine/cosine/tangent. Mode 00 returns NaN on the normal path but passes through the angle on the small-angle path. This differs from the ZIP top-level op=11, which always returns NaN.

Implementation limits and source differences

The slides illustrate 16 rotations, while the Q28 RTL uses 24 and the Q48 alternative uses 48. The standalone and ZIP Q28 files define the same module name: choose one, do not compile both together. The ZIP CLA is a binary integer adder, not a floating-point adder; its 4-bit blocks use lookahead internally and propagate carries between blocks.

The multiplier normalization assumes normalized significands. Subnormal results are not fully supported and underflow is flushed to zero. The exponent unit also checks bit 8 before the ≥255 condition; some large exponent sums are therefore classified as underflow. The portfolio preserves the supplied source rather than claiming complete IEEE 754 compliance. No FPGA utilization, synthesis timing, or hardware simulation pass is claimed.

06 / VIVA NOTEBOOK

Explain the decision, not just the result

A few questions worth being ready for.

Why inspect product bit 47?

Two normalized significands each lie in [1, 2). Their product lies in [1, 4). Bit 47 identifies the [2, 4) case, so the retained window moves one bit and the exponent receives a +1 adjustment.

Why are guard, round and sticky bits enough?

They distinguish a discarded value below halfway, exactly halfway, and above halfway. At an exact tie, the retained LSB resolves which result has an even significand. Sticky records whether any lower bit is nonzero.

Does ties-to-even mean the decimal number is even?

No. It means the retained binary significand’s least-significant bit is zero. A tie with L=0 stays; a tie with L=1 increments.

Why begin CORDIC at approximately 0.607253?

Each shift-and-add rotation stretches the vector by √(1 + 2⁻²ⁱ). Starting at the reciprocal product of those factors compensates the total gain, giving a final vector of approximately unit length.

Why not update y using the new x?

The rotation equations are simultaneous. Using an already updated x changes the transformation and corrupts the rotation. The RTL uses nx/ny or separate stage wires to preserve the previous coordinates.

Why reduce the angle and restore a sign?

The rotation sequence has a limited convergence range. Reduction to [−π/2, π/2] puts the target safely inside it. Adding or subtracting π reverses both sine and cosine, so both signs must be restored.

How many clock cycles does this implementation take?

No cycle latency is specified: the supplied CORDIC is combinational, with no clock or register pipeline. Delay, area, and a suitable clock period would require synthesis and timing analysis.

Why do the web results differ slightly from the RTL?

The web model uses double-precision real arithmetic. Hardware quantizes the input to FP32, uses integer constants and arithmetic shifts, bypasses small angles, and rounds its output to FP32. The 16-step slide example also stops earlier.

07 / SOURCE DESK

Original files · available to download

Trace every explanation to the source.