# Module math

This document contains technical documentation for the `math` module. To browse the source code, please visit the repository on GitHub.

This module contains a contains entities and packages for common math operations in VHDL.

## math_pkg.vhd

Package with some common mathematical functions.

## saturate_signed.vhd

Saturate a signed number by removing MSBs. Typically used in fixed-point applications after performing arithmetic operations, such as addition or multiplication. Or to clamp a value from a third source to a certain range.

In digital arithmetic scenarios, the concept of guard bits is commonly used, and the input value will be of the form:

input_value = S G G G N N N N N N N N

Where S is the sign bit, and G are a guard bits. Note that the number of guard bits, three in the example above, is the difference between `input_width` and `result_width`.

### Pseudo code

This entity performs the following operation, which is equivalent to a range clamping with power-of-two limits:

```min_value = - 2 ** (result_width - 1)
max_value = 2 ** (result_width - 1) - 1
if input_value < min_value:
return min_value
if input_value > max_value:
return max_value
return input_value
```

### Fixed-point implementation

The pseudo code above is efficiently implemented in digital logic by looking at the guard bits and the sign bit. If any of them have different value, the input value is outside the result range. If the sign bit is ‘1’, the input is negative, and the result should be greatest negative value possible. If the sign bit is ‘0’, the input is positive, and the result should be the greatest positive value possible.

Note that you have to choose your number of guard bits carefully in any upstream arithmetic operation. If you have too few guard bits, the value might already have wrapped around, and the saturation will not work as expected. This is all dependent on the details of your application.

## unsigned_divider.vhd

Calculates

dividend / divisor = quotient + remainder / divisor

This is a bit serial divider. Algorithm is the same as long division from elementary school, but with number base two. Latency scales linearly with `dividend_width`.