forked from M-Labs/artiq
shuttler: change 0th order accumulator width
It now truncates the LSBs instead of the MSBs.
This commit is contained in:
parent
bafb85a274
commit
a772dee1cc
@ -12,7 +12,7 @@ def shuttler_volt_to_mu(volt):
|
|||||||
"""Return the equivalent DAC code. Valid input range is from -10 to
|
"""Return the equivalent DAC code. Valid input range is from -10 to
|
||||||
10 - LSB.
|
10 - LSB.
|
||||||
"""
|
"""
|
||||||
return round((1 << 14) * (volt / 20.0)) & 0x3fff
|
return round((1 << 16) * (volt / 20.0)) & 0xffff
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@ -25,7 +25,7 @@ class Config:
|
|||||||
output data with pre-DAC gain, then adds the offset.
|
output data with pre-DAC gain, then adds the offset.
|
||||||
|
|
||||||
.. note::
|
.. 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 channel: RTIO channel number of this interface.
|
||||||
:param core_device: Core device name.
|
:param core_device: Core device name.
|
||||||
@ -152,8 +152,8 @@ class Volt:
|
|||||||
|
|
||||||
a_3 &= p_3T^3
|
a_3 &= p_3T^3
|
||||||
|
|
||||||
:math:`a_0`, :math:`a_1`, :math:`a_2` and :math:`a_3` are 14, 30, 46
|
:math:`a_0`, :math:`a_1`, :math:`a_2` and :math:`a_3` are 16, 32, 48
|
||||||
and 46 bits in width respectively. See :meth:`shuttler_volt_to_mu` for
|
and 48 bits in width respectively. See :meth:`shuttler_volt_to_mu` for
|
||||||
machine unit conversion.
|
machine unit conversion.
|
||||||
|
|
||||||
Note: The waveform is not updated to the Shuttler Core until
|
Note: The waveform is not updated to the Shuttler Core until
|
||||||
@ -238,8 +238,8 @@ class Dds:
|
|||||||
|
|
||||||
c_2 &= r_2T^2
|
c_2 &= r_2T^2
|
||||||
|
|
||||||
:math:`b_0`, :math:`b_1`, :math:`b_2` and :math:`b_3` are 14, 30, 46
|
:math:`b_0`, :math:`b_1`, :math:`b_2` and :math:`b_3` are 16, 32, 48
|
||||||
and 46 bits in width respectively. See :meth:`shuttler_volt_to_mu` for
|
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
|
machine unit conversion. :math:`c_0`, :math:`c_1` and :math:`c_2` are
|
||||||
16, 32 and 32 bits in width respectively.
|
16, 32 and 32 bits in width respectively.
|
||||||
|
|
||||||
|
@ -26,15 +26,15 @@ def shuttler_volt_amp_mu(volt):
|
|||||||
|
|
||||||
@portable
|
@portable
|
||||||
def shuttler_volt_damp_mu(volt_per_us):
|
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
|
@portable
|
||||||
def shuttler_volt_ddamp_mu(volt_per_us_square):
|
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
|
@portable
|
||||||
def shuttler_volt_dddamp_mu(volt_per_us_cube):
|
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
|
@portable
|
||||||
def shuttler_dds_amp_mu(volt):
|
def shuttler_dds_amp_mu(volt):
|
||||||
|
@ -124,16 +124,18 @@ class Dac(Module):
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Infer signed multiplication
|
# Infer signed multiplication
|
||||||
data_raw = Signal((14, True))
|
data_raw = Signal((16, True))
|
||||||
data_buf = Signal(16)
|
# 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 += [
|
self.sync.rio += [
|
||||||
data_raw.eq(reduce(add, [sub.data for sub in subs])),
|
data_raw.eq(reduce(add, [sub.data for sub in subs])),
|
||||||
# Extra buffer for timing for the DSP
|
# Extra buffer for timing for the DSP
|
||||||
data_buf.eq(((data_raw * Cat(self.gain, ~self.gain[-1])) + (self.offset << 16))[16:]),
|
data_buf.eq(((data_raw * Cat(self.gain, ~self.gain[-1])) + (self.offset << 16))[16:]),
|
||||||
If(overflow,
|
If(overflow,
|
||||||
self.data.eq(0x1fff),
|
self.data.eq(0x7fff),
|
||||||
).Elif(underflow,
|
).Elif(underflow,
|
||||||
self.data.eq(0x2000),
|
self.data.eq(0x8000),
|
||||||
).Else(
|
).Else(
|
||||||
self.data.eq(data_buf),
|
self.data.eq(data_buf),
|
||||||
),
|
),
|
||||||
@ -350,7 +352,7 @@ class Shuttler(Module, AutoCSR):
|
|||||||
dac.clear.eq(self.cfg.clr[idx]),
|
dac.clear.eq(self.cfg.clr[idx]),
|
||||||
dac.gain.eq(self.cfg.gain[idx]),
|
dac.gain.eq(self.cfg.gain[idx]),
|
||||||
dac.offset.eq(self.cfg.offset[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:
|
for i in dac.i:
|
||||||
|
Loading…
Reference in New Issue
Block a user