Skip to content

Simple fixed-point integrator

The goal is to implement the fixed-point integrator of this block diagram:

block diagram

The ovf and rnd arguments of the Q function expect integers as inputs. For convenience, constants can be imported from the pyfxp.constants module and used as arguments. Below, the SAT and TRUNC and WRAP constants are imported.

import matplotlib.pyplot as plt
import numpy as np

from pyfxp import FxpSpec, Q, fxp
from pyfxp.constants import SAT, TRUNC, WRAP

We will start by implementing the integrator as a function. The integrator receives two specs:

  • spec_input: fixed-point specification for the input of the integrator.
  • spec_output: fixed-point specification for the output of the integrator.
def integrator(x: np.ndarray, spec_input: FxpSpec, spec_output: FxpSpec) -> np.ndarray:
    """Example of a simple fixed-point integrator."""
    len_x = len(x)

    # convert float input to sQ4.5 and saturation
    # fxp accepts receiving numpy arrays
    x_fxp = fxp(x, spec_input)

    # implement accumulator
    acc = 0
    y_fxp = np.zeros(len_x)
    for i in range(len_x):
        y_fxp[i] = fxp(acc + x_fxp[i], spec_output)
        acc = y_fxp[i]

    return y_fxp

The fixed-point specifications are created using the Q function. The first spec is used to convert the input of the integrator to sQ4.5. The second spec sQ7.5 is used for the integrator output.

The input stimulus x will be a DC signal with value of 1 with some additive normal noise. Note that an integrator has infinite gain at DC, and it is expected to overflow for a DC signal.

# Create fixed-point specifications
sQ4_5 = Q(4, 5, rnd=TRUNC, ovf=SAT)
sQ7_5 = Q(7, 5, rnd=TRUNC, ovf=WRAP)

# number of samples used for the simulation
n_smp = 1024

# DC value + normal noise
x = np.ones(n_smp) + np.random.normal(0, 0.1, n_smp)
y_fxp = integrator(x, spec_input=sQ4_5, spec_output=sQ7_5)

Plotting the output shows that the integrator overflows, as expected.

fig, ax = plt.subplots(1, 2)
fig.tight_layout()

ax[0].plot(x, label="integrator input")
ax[0].set_ylabel("x")
ax[0].set_xlabel("[samples]")
ax[0].set_title("input x")
ax[0].legend()
ax[0].grid()

ax[1].plot(y_fxp, label="integrator output")
ax[1].set_xlabel("[samples]")
ax[1].set_ylabel("y_fxp")
ax[1].set_title("output y_fxp")
ax[1].legend()
ax[1].grid()
plt.show()

png