forked from M-Labs/artiq
Robert Jordens
6a0e97f161
Once the Sequencer ack's a line, the Parser starts preparing the next one. This includes jumping through the frame table if necessary. To stall the Parser while the Sequencer executes the last line of a frame and to ensure that the frame select lines can be set up and their sampling is synchronized to a trigger, we add a triggered stall line at the end of the frame. When that line is triggered the Parser jumps through the table and starts parsing the first line of the next frame. We let the duration of this last stall line be 10 cycles (200ns@50MHz) to be able to distinguish this sampling of the frame select lines from the triggering of the first line in the next frame. frame f parser n f 0 stb __---________---___ trigger ___----_______----_ ack ____-__________-___ sequencer n-1 n 0
128 lines
3.7 KiB
Python
128 lines
3.7 KiB
Python
import unittest
|
|
import os
|
|
import io
|
|
|
|
from artiq.devices.pdq2.driver import Pdq2
|
|
from artiq.wavesynth.compute_samples import Synthesizer
|
|
|
|
|
|
pdq2_gateware = os.getenv("ARTIQ_PDQ2_GATEWARE")
|
|
|
|
|
|
class TestPdq2(unittest.TestCase):
|
|
def setUp(self):
|
|
self.dev = Pdq2(dev=io.BytesIO())
|
|
self.synth = Synthesizer(3, _test_program)
|
|
|
|
def test_reset(self):
|
|
self.dev.cmd("RESET", True)
|
|
buf = self.dev.dev.getvalue()
|
|
self.assertEqual(buf, b"\xa5\x00")
|
|
|
|
def test_program(self):
|
|
# about 0.14 ms
|
|
self.dev.program(_test_program)
|
|
|
|
def test_cmd_program(self):
|
|
self.dev.cmd("ARM", False)
|
|
self.dev.cmd("START", False)
|
|
self.dev.program(_test_program)
|
|
self.dev.cmd("START", True)
|
|
self.dev.cmd("ARM", True)
|
|
#self.dev.cmd("TRIGGER", True)
|
|
return self.dev.dev.getvalue()
|
|
|
|
def test_synth(self):
|
|
s = self.synth
|
|
s.select(0)
|
|
y = s.trigger()
|
|
return list(zip(*y))
|
|
|
|
def run_gateware(self):
|
|
import sys
|
|
sys.path.append(pdq2_gateware)
|
|
from gateware.pdq2 import Pdq2Sim
|
|
from migen.sim.generic import run_simulation
|
|
|
|
buf = self.test_cmd_program()
|
|
tb = Pdq2Sim(buf)
|
|
tb.ctrl_pads.trigger.reset = 1
|
|
run_simulation(tb, ncycles=len(buf) + 250)
|
|
delays = 7, 10, 30
|
|
y = list(zip(*tb.outputs[len(buf) + 130:]))
|
|
y = list(zip(*(yi[di:] for yi, di in zip(y, delays))))
|
|
self.assertGreaterEqual(len(y), 80)
|
|
self.assertEqual(len(y[0]), 3)
|
|
return y
|
|
|
|
@unittest.skipUnless(pdq2_gateware, "no pdq2 gateware")
|
|
def test_run_compare(self):
|
|
y_ref = self.test_synth()
|
|
y = self.run_gateware()
|
|
|
|
for i, (yi, yi_ref) in enumerate(zip(y, y_ref)):
|
|
for j, (yij, yij_ref) in enumerate(zip(yi, yi_ref)):
|
|
yij = yij*20./2**16
|
|
if yij > 10:
|
|
yij -= 20
|
|
self.assertAlmostEqual(yij, yij_ref, 2, "disagreement at "
|
|
"t={}, c={}".format(i, j))
|
|
|
|
@unittest.skipUnless(pdq2_gateware, "no pdq2 gateware")
|
|
@unittest.skip("manual/visual test")
|
|
def test_run_plot(self):
|
|
from matplotlib import pyplot as plt
|
|
import numpy as np
|
|
y_ref = self.test_synth()
|
|
y_ref = np.array(y_ref)
|
|
y = self.run_gateware()
|
|
y = np.array(y, dtype=np.uint16).view(np.int16)
|
|
y = y*20./2**16
|
|
plt.step(np.arange(len(y)), y)
|
|
plt.step(np.arange(len(y_ref)), y_ref, "k")
|
|
plt.show()
|
|
|
|
|
|
_test_program = [
|
|
[
|
|
{
|
|
"trigger": True,
|
|
"duration": 20,
|
|
"channel_data": [
|
|
{"bias": {"amplitude": [0, 0, 2e-3]}},
|
|
{"bias": {"amplitude": [1, 0, -7.5e-3, 7.5e-4]}},
|
|
{"dds": {
|
|
"amplitude": [0, 0, 4e-3, 0],
|
|
"phase": [.25, .025],
|
|
}},
|
|
],
|
|
},
|
|
{
|
|
"duration": 40,
|
|
"channel_data": [
|
|
{"bias": {"amplitude": [.4, .04, -2e-3]}},
|
|
{"bias": {
|
|
"amplitude": [.5],
|
|
"silence": True,
|
|
}},
|
|
{"dds": {
|
|
"amplitude": [.8, .08, -4e-3, 0],
|
|
"phase": [.25, .025, .02/40],
|
|
"clear": True,
|
|
}},
|
|
],
|
|
},
|
|
{
|
|
"duration": 20,
|
|
"channel_data": [
|
|
{"bias": {"amplitude": [.4, -.04, 2e-3]}},
|
|
{"bias": {"amplitude": [.5, 0, -7.5e-3, 7.5e-4]}},
|
|
{"dds": {
|
|
"amplitude": [.8, -.08, 4e-3, 0],
|
|
"phase": [-.25],
|
|
}},
|
|
],
|
|
},
|
|
]
|
|
]
|