In SPA models we generally rely on the neuron saturation behaviour to provide a soft normalization. Because LIF neurons “flatten out” for higher and higher input values, trying to represent vectors with magnitude significantly greater than 1 will all tend to result in the same representation (with magnitude ~1). You can change where that saturation happens by playing with the Ensemble’s radius
parameter.
If you want an exact normalization you can use nengo.Node
(e.g. nengo.Node(lambda t, x: x / np.linalg.norm(x))
). The output of that node will always be exactly normalized (but it’s not being done in a biologically plausible way, if that is important to you).