forked from M-Labs/artiq
gateware/suservo: Sign-extend data on RTIO read-back
See GitHub #1327 for original patch by Brad Bondurant.
This commit is contained in:
parent
720838a23e
commit
0353966ef7
|
@ -23,6 +23,13 @@ class RTServoCtrl(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _eq_sign_extend(t, s):
|
||||||
|
"""Assign target signal `t` from source `s`, sign-extending `s` to the
|
||||||
|
full width.
|
||||||
|
"""
|
||||||
|
return t.eq(Cat(s, Replicate(s[-1], len(t) - len(s))))
|
||||||
|
|
||||||
|
|
||||||
class RTServoMem(Module):
|
class RTServoMem(Module):
|
||||||
"""All-channel all-profile coefficient and state RTIO control
|
"""All-channel all-profile coefficient and state RTIO control
|
||||||
interface.
|
interface.
|
||||||
|
@ -49,6 +56,11 @@ class RTServoMem(Module):
|
||||||
IIR state mem | 0 | 1
|
IIR state mem | 0 | 1
|
||||||
config (write) | 1 | 1
|
config (write) | 1 | 1
|
||||||
status (read) | 1 | 1
|
status (read) | 1 | 1
|
||||||
|
|
||||||
|
Values returned to the user on the Python side of the RTIO interface are
|
||||||
|
32 bit, so we sign-extend all values from w.coeff to that width. This works
|
||||||
|
(instead of having to decide whether to sign- or zero-extend per address), as
|
||||||
|
all unsigned values are less wide than w.coeff.
|
||||||
"""
|
"""
|
||||||
def __init__(self, w, servo):
|
def __init__(self, w, servo):
|
||||||
m_coeff = servo.iir.m_coeff.get_port(write_capable=True,
|
m_coeff = servo.iir.m_coeff.get_port(write_capable=True,
|
||||||
|
@ -66,6 +78,9 @@ class RTServoMem(Module):
|
||||||
assert len(m_coeff.dat_w) == 2*w.coeff
|
assert len(m_coeff.dat_w) == 2*w.coeff
|
||||||
# ensure that the DDS word data fits into the coefficient mem
|
# ensure that the DDS word data fits into the coefficient mem
|
||||||
assert w.coeff >= w.word
|
assert w.coeff >= w.word
|
||||||
|
# ensure all unsigned values will be zero-extended on sign extension
|
||||||
|
assert w.word < w.coeff
|
||||||
|
assert 8 + w.dly < w.coeff
|
||||||
|
|
||||||
# coeff, profile, channel, 2 mems, rw
|
# coeff, profile, channel, 2 mems, rw
|
||||||
internal_address_width = 3 + w.profile + w.channel + 1 + 1
|
internal_address_width = 3 + w.profile + w.channel + 1 + 1
|
||||||
|
@ -77,7 +92,7 @@ class RTServoMem(Module):
|
||||||
address_width=rtlink_address_width,
|
address_width=rtlink_address_width,
|
||||||
enable_replace=False),
|
enable_replace=False),
|
||||||
rtlink.IInterface(
|
rtlink.IInterface(
|
||||||
data_width=w.coeff,
|
data_width=32,
|
||||||
timestamped=False)
|
timestamped=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -152,7 +167,7 @@ class RTServoMem(Module):
|
||||||
]
|
]
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.rtlink.i.stb.eq(read),
|
self.rtlink.i.stb.eq(read),
|
||||||
self.rtlink.i.data.eq(
|
_eq_sign_extend(self.rtlink.i.data,
|
||||||
Mux(read_state,
|
Mux(read_state,
|
||||||
Mux(read_config,
|
Mux(read_config,
|
||||||
status,
|
status,
|
||||||
|
|
Loading…
Reference in New Issue