mirror of https://github.com/m-labs/artiq.git
suservo: move overflowing RTIO address bits into data
This commit is contained in:
parent
ae8ef18f47
commit
450a035f9e
|
@ -129,7 +129,10 @@ class SUServo:
|
||||||
:param addr: Memory location address.
|
:param addr: Memory location address.
|
||||||
:param value: Data to be written.
|
:param value: Data to be written.
|
||||||
"""
|
"""
|
||||||
rtio_output((self.channel << 8) | addr | WE, value)
|
addr |= WE
|
||||||
|
value |= (addr >> 8) << COEFF_WIDTH
|
||||||
|
addr = addr & 0xff
|
||||||
|
rtio_output((self.channel << 8) | addr, value)
|
||||||
delay_mu(self.ref_period_mu)
|
delay_mu(self.ref_period_mu)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
@ -140,7 +143,9 @@ class SUServo:
|
||||||
|
|
||||||
:param addr: Memory location address.
|
:param addr: Memory location address.
|
||||||
"""
|
"""
|
||||||
rtio_output((self.channel << 8) | addr, 0)
|
value = (addr >> 8) << COEFF_WIDTH
|
||||||
|
addr = addr & 0xff
|
||||||
|
rtio_output((self.channel << 8) | addr, value)
|
||||||
return rtio_input_data(self.channel)
|
return rtio_input_data(self.channel)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
|
|
@ -43,11 +43,16 @@ class RTServoMem(Module):
|
||||||
# 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
|
||||||
|
|
||||||
|
# coeff, profile, channel, 2 mems, rw
|
||||||
|
# this exceeds the 8-bit RTIO address, so we move the extra ("overflow")
|
||||||
|
# address bits into data.
|
||||||
|
internal_address_width = 3 + w.profile + w.channel + 1 + 1
|
||||||
|
rtlink_address_width = min(8, internal_address_width)
|
||||||
|
overflow_address_width = internal_address_width - rtlink_address_width
|
||||||
self.rtlink = rtlink.Interface(
|
self.rtlink = rtlink.Interface(
|
||||||
rtlink.OInterface(
|
rtlink.OInterface(
|
||||||
data_width=w.coeff,
|
data_width=overflow_address_width + w.coeff,
|
||||||
# coeff, profile, channel, 2 mems, rw
|
address_width=rtlink_address_width,
|
||||||
address_width=3 + w.profile + w.channel + 1 + 1,
|
|
||||||
enable_replace=False),
|
enable_replace=False),
|
||||||
rtlink.IInterface(
|
rtlink.IInterface(
|
||||||
data_width=w.coeff,
|
data_width=w.coeff,
|
||||||
|
@ -65,30 +70,33 @@ class RTServoMem(Module):
|
||||||
[_.clip for _ in servo.iir.ctrl]))
|
[_.clip for _ in servo.iir.ctrl]))
|
||||||
]
|
]
|
||||||
|
|
||||||
assert len(self.rtlink.o.address) == (
|
assert len(self.rtlink.o.address) + len(self.rtlink.o.data) - w.coeff == (
|
||||||
1 + # we
|
1 + # we
|
||||||
1 + # state_sel
|
1 + # state_sel
|
||||||
1 + # high_coeff
|
1 + # high_coeff
|
||||||
len(m_coeff.adr))
|
len(m_coeff.adr))
|
||||||
# ensure that we can fit config/status into the state address space
|
# ensure that we can fit config/status into the state address space
|
||||||
assert len(self.rtlink.o.address) >= (
|
assert len(self.rtlink.o.address) + len(self.rtlink.o.data) - w.coeff >= (
|
||||||
1 + # we
|
1 + # we
|
||||||
1 + # state_sel
|
1 + # state_sel
|
||||||
1 + # config_sel
|
1 + # config_sel
|
||||||
len(m_state.adr))
|
len(m_state.adr))
|
||||||
we = self.rtlink.o.address[-1]
|
internal_address = Signal(internal_address_width)
|
||||||
state_sel = self.rtlink.o.address[-2]
|
self.comb += internal_address.eq(Cat(self.rtlink.o.address, self.rtlink.o.data[w.coeff:]))
|
||||||
config_sel = self.rtlink.o.address[-3]
|
|
||||||
high_coeff = self.rtlink.o.address[0]
|
we = internal_address[-1]
|
||||||
|
state_sel = internal_address[-2]
|
||||||
|
config_sel = internal_address[-3]
|
||||||
|
high_coeff = internal_address[0]
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.rtlink.o.busy.eq(0),
|
self.rtlink.o.busy.eq(0),
|
||||||
m_coeff.adr.eq(self.rtlink.o.address[1:]),
|
m_coeff.adr.eq(internal_address[1:]),
|
||||||
m_coeff.dat_w.eq(Cat(self.rtlink.o.data, self.rtlink.o.data)),
|
m_coeff.dat_w.eq(Cat(self.rtlink.o.data, self.rtlink.o.data)),
|
||||||
m_coeff.we[0].eq(self.rtlink.o.stb & ~high_coeff &
|
m_coeff.we[0].eq(self.rtlink.o.stb & ~high_coeff &
|
||||||
we & ~state_sel),
|
we & ~state_sel),
|
||||||
m_coeff.we[1].eq(self.rtlink.o.stb & high_coeff &
|
m_coeff.we[1].eq(self.rtlink.o.stb & high_coeff &
|
||||||
we & ~state_sel),
|
we & ~state_sel),
|
||||||
m_state.adr.eq(self.rtlink.o.address),
|
m_state.adr.eq(internal_address),
|
||||||
m_state.dat_w[w.state - w.coeff:].eq(self.rtlink.o.data),
|
m_state.dat_w[w.state - w.coeff:].eq(self.rtlink.o.data),
|
||||||
m_state.we.eq(self.rtlink.o.stb & we & state_sel & ~config_sel),
|
m_state.we.eq(self.rtlink.o.stb & we & state_sel & ~config_sel),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue