shuttler: change 0th order accumulator width

It now truncates the LSBs instead of the MSBs.
pull/2229/head
occheung 2023-09-27 17:11:12 -07:00 committed by Sébastien Bourdeauducq
parent bafb85a274
commit a772dee1cc
3 changed files with 16 additions and 14 deletions

View File

@ -12,7 +12,7 @@ def shuttler_volt_to_mu(volt):
"""Return the equivalent DAC code. Valid input range is from -10 to
10 - LSB.
"""
return round((1 << 14) * (volt / 20.0)) & 0x3fff
return round((1 << 16) * (volt / 20.0)) & 0xffff
class Config:
@ -25,7 +25,7 @@ class Config:
output data with pre-DAC gain, then adds the offset.
.. note::
The DAC code is capped at 0x1fff and 0x2000.
The DAC code is capped at 0x7fff and 0x8000.
:param channel: RTIO channel number of this interface.
:param core_device: Core device name.
@ -152,8 +152,8 @@ class Volt:
a_3 &= p_3T^3
:math:`a_0`, :math:`a_1`, :math:`a_2` and :math:`a_3` are 14, 30, 46
and 46 bits in width respectively. See :meth:`shuttler_volt_to_mu` for
:math:`a_0`, :math:`a_1`, :math:`a_2` and :math:`a_3` are 16, 32, 48
and 48 bits in width respectively. See :meth:`shuttler_volt_to_mu` for
machine unit conversion.
Note: The waveform is not updated to the Shuttler Core until
@ -238,8 +238,8 @@ class Dds:
c_2 &= r_2T^2
:math:`b_0`, :math:`b_1`, :math:`b_2` and :math:`b_3` are 14, 30, 46
and 46 bits in width respectively. See :meth:`shuttler_volt_to_mu` for
:math:`b_0`, :math:`b_1`, :math:`b_2` and :math:`b_3` are 16, 32, 48
and 48 bits in width respectively. See :meth:`shuttler_volt_to_mu` for
machine unit conversion. :math:`c_0`, :math:`c_1` and :math:`c_2` are
16, 32 and 32 bits in width respectively.

View File

@ -26,15 +26,15 @@ def shuttler_volt_amp_mu(volt):
@portable
def shuttler_volt_damp_mu(volt_per_us):
return round(float(2) ** 30 * (volt_per_us / 20) / DAC_Fs_MHZ)
return round(float(2) ** 32 * (volt_per_us / 20) / DAC_Fs_MHZ)
@portable
def shuttler_volt_ddamp_mu(volt_per_us_square):
return round(float(2) ** 46 * (volt_per_us_square / 20) * 2 / (DAC_Fs_MHZ ** 2))
return round(float(2) ** 48 * (volt_per_us_square / 20) * 2 / (DAC_Fs_MHZ ** 2))
@portable
def shuttler_volt_dddamp_mu(volt_per_us_cube):
return round(float(2) ** 46 * (volt_per_us_cube / 20) * 6 / (DAC_Fs_MHZ ** 3))
return round(float(2) ** 48 * (volt_per_us_cube / 20) * 6 / (DAC_Fs_MHZ ** 3))
@portable
def shuttler_dds_amp_mu(volt):

View File

@ -124,16 +124,18 @@ class Dac(Module):
]
# Infer signed multiplication
data_raw = Signal((14, True))
data_buf = Signal(16)
data_raw = Signal((16, True))
# Buffer data should have 2 more bits than the desired output width
# It is to perform overflow/underflow detection
data_buf = Signal(18)
self.sync.rio += [
data_raw.eq(reduce(add, [sub.data for sub in subs])),
# Extra buffer for timing for the DSP
data_buf.eq(((data_raw * Cat(self.gain, ~self.gain[-1])) + (self.offset << 16))[16:]),
If(overflow,
self.data.eq(0x1fff),
self.data.eq(0x7fff),
).Elif(underflow,
self.data.eq(0x2000),
self.data.eq(0x8000),
).Else(
self.data.eq(data_buf),
),
@ -350,7 +352,7 @@ class Shuttler(Module, AutoCSR):
dac.clear.eq(self.cfg.clr[idx]),
dac.gain.eq(self.cfg.gain[idx]),
dac.offset.eq(self.cfg.offset[idx]),
self.dac_interface.data[idx // 2][idx % 2].eq(dac.data)
self.dac_interface.data[idx // 2][idx % 2].eq(dac.data[2:])
]
for i in dac.i: