Exemplo n.º 1
0
    def test_union(self):
        union_mix = dl.Union([
            dl.Int(dl.Size(16)),
            dl.Bool(),
            dl.Str(dl.Size(10)),
            dl.Tuple([
                dl.Int(dl.Size(8)),
                dl.UInt(dl.Size(16)),
                dl.Float(dl.Size(64)),
                dl.Complex(dl.Size(128)),
                dl.Bool(),
                dl.Str(dl.Size(10))
            ]),
            dl.Record(RecATI)
        ])

        @dl.Interactive([("ack_union_mix", bool)],
                        [("out_union_mix", union_mix)])
        def testbench(node: dl.PythonNode):
            node.send(out_union_mix=5)
            assert node.receive("ack_union_mix")

            node.send(out_union_mix=False)
            assert node.receive("ack_union_mix")

            node.send(out_union_mix='abcd')
            assert node.receive("ack_union_mix")

            node.send(out_union_mix=(-5, 10, -1.5, (1.5 + 2.5j), False,
                                     'hello'))
            assert node.receive("ack_union_mix")

            node.send(out_union_mix=RecATI([1, 2], (3.0, 4), 5))
            assert node.receive("ack_union_mix")

            raise DeltaRuntimeExit

        s_union_mix = dl.lib.StateSaver(union_mix, verbose=True)

        with dl.DeltaGraph() as graph:
            p = dl.placeholder_node_factory()

            p.specify_by_node(
                testbench.call(s_union_mix.save_and_ack(p.out_union_mix)))

        self.check_executes_graph(
            graph, """\
            saving 5
            saving False
            saving abcd
            saving (-5, 10, -1.5, (1.5+2.5j), False, 'hello')
            saving RecATI(x=[1, 2], y=(3.0, 4), z=5)
            """)
Exemplo n.º 2
0
    def test_compound(self):
        tuple_mix = dl.Tuple([
            dl.Int(dl.Size(8)),
            dl.UInt(dl.Size(16)),
            dl.Float(dl.Size(64)),
            dl.Complex(dl.Size(128)),
            dl.Bool(),
            dl.Str(dl.Size(10))
        ])
        array_float = dl.Array(dl.Float(dl.Size(64)), dl.Size(3))
        record_mix = dl.Record(RecATI)

        @dl.Interactive([("ack_tuple_mix", bool), ("ack_array_float", bool),
                         ("ack_record_mix", bool)],
                        [("out_tuple_mix", tuple_mix),
                         ("out_array_float", array_float),
                         ("out_record_mix", record_mix)])
        def testbench(node: dl.PythonNode):
            node.send(out_tuple_mix=(-5, 1000, -100.5, (1.5 + 2.5j), False,
                                     '0123456789'))
            assert node.receive("ack_tuple_mix")

            node.send(out_array_float=[0.5, -0.25, 0.125])
            assert node.receive("ack_array_float")

            node.send(out_record_mix=RecATI([1, 2], (3.0, 4), 5))
            assert node.receive("ack_record_mix")

            raise DeltaRuntimeExit

        s_tuple_mix = dl.lib.StateSaver(tuple_mix, verbose=True)
        s_array_float = dl.lib.StateSaver(array_float, verbose=True)
        s_record_mix = dl.lib.StateSaver(record_mix, verbose=True)

        with dl.DeltaGraph() as graph:
            p = dl.placeholder_node_factory()

            p.specify_by_node(
                testbench.call(s_tuple_mix.save_and_ack(p.out_tuple_mix),
                               s_array_float.save_and_ack(p.out_array_float),
                               s_record_mix.save_and_ack(p.out_record_mix)))

        self.check_executes_graph(
            graph, """\
            saving (-5, 1000, -100.5, (1.5+2.5j), False, '0123456789')
            saving [0.5, -0.25, 0.125]
            saving RecATI(x=[1, 2], y=(3.0, 4), z=5)
            """)
Exemplo n.º 3
0
    def migen_body(self, template):
        """ This is the body of the migen node connecting
        the pulser and timestamper as 2 submodules.
        """

        # Node inputs
        self.reset = template.add_pa_in_port('reset', dl.Optional(int))
        self.photon = template.add_pa_in_port('photon', dl.Optional(int))

        # Node outputs
        self.time = template.add_pa_out_port('time', dl.UInt())
        self.error = template.add_pa_out_port('error', dl.Int())

        self.rf_trigger = Signal(1)
        self.pmt_trigger = Signal(1)
        self.hit_channels = Signal(2)
        self.clock = Signal(TIME_RES)

        ###

        self.comb += [
            self.hit_channels.eq(self.pmt_trigger + 2 * self.rf_trigger),
            self.photon.ready.eq(1),
        ]

        # error management ( if photon is outside valid range)
        self.sync += [
            If(
                self.photon.valid & ((self.photon.data < 1) |
                                     (self.photon.data > TIME_RES - 1)),
                self.error.data.eq(1), self.error.valid.eq(1)).Elif(
                    self.photon.valid, self.error.data.eq(0),
                    self.error.valid.eq(1)).Else(
                        self.error.data.eq(self.error.data),
                        self.error.valid.eq(0))
        ]

        self.pulser_inst = TimestamperModel.Pulser(self.reset,
                                                   self.pmt_trigger,
                                                   self.rf_trigger,
                                                   self.photon, self.clock)

        self.timestamper_inst = TimestamperModel.Timestamper(
            self.hit_channels, self.time, self.reset, self.clock)

        self.submodules += [self.timestamper_inst, self.pulser_inst]
Exemplo n.º 4
0
    def migen_body(self, template):

        _TIME_RES = 32
        # Node inputs
        self.time_in = template.add_pa_in_port('time_in',
                                               dl.Optional(dl.UInt()))

        # Node outputs
        self.time_out = template.add_pa_out_port('time_out', dl.UInt())
        self.counter_reset = template.add_pa_out_port('counter_reset',
                                                      dl.Int())

        # Internal signals
        self.pmt_reg = Signal(_TIME_RES)
        self.rf_reg = Signal(_TIME_RES)
        self.pmt_trig = Signal(1)
        self.rf_trig = Signal(1)

        self.submodules.fsm = FSM(reset_state="RESET_COUNTER")

        self.sync += [
            If(
                self.pmt_trig,
                self.pmt_reg.eq(self.time_in.data),
            ).Elif(self.fsm.ongoing("RESET_COUNTER"),
                   self.pmt_reg.eq(0)).Else(self.pmt_reg.eq(self.pmt_reg)),
            If(
                self.rf_trig,
                self.rf_reg.eq(self.time_in.data),
            ).Elif(self.fsm.ongoing("RESET_COUNTER"),
                   self.rf_reg.eq(0)).Else(self.rf_reg.eq(self.rf_reg))
        ]
        """FSM
        The FSM is used to control the readouts from the HPTDC chip and
        generate a time signal for the accumulator

        RESET_COUNTER
        This is the dinitial state of the FSM at the start of the experiment.
        It resets the "coarse counter" of the HPTDC chip to establish a TO
        time reference.

        WAIT_FOR_PMT
        This state holds until the PMT timestamp is available at the HPTDC
        chip readout (first data_ready sync pulse)

        WAIT_FOR_RF
        This state holds until the RMT timestamp is available at the HPTDC
        chip readout (second data_ready sync pulse)

        SEND_TIME
        In this state, the difference between t_PMT and t_RF is derived and
        sent to the accumulator.

        WAIT_ACC_LATENCY
        This state is used to wait for any delays on inter-node communication
        """

        self.fsm.act(
            "RESET_COUNTER",
            self.pmt_trig.eq(0),
            self.rf_trig.eq(0),
            self.time_in.ready.eq(1),
            self.counter_reset.data.eq(1),  # reset counters
            self.counter_reset.valid.eq(1),
            NextState("WAIT_FOR_PMT"))

        self.fsm.act(
            "WAIT_FOR_PMT", self.counter_reset.data.eq(0),
            self.time_in.ready.eq(1),
            If(self.time_in.valid, self.pmt_trig.eq(1),
               NextState("WAIT_FOR_RF")))

        self.fsm.act(
            "WAIT_FOR_RF", self.time_in.ready.eq(1),
            If(self.time_in.valid, self.rf_trig.eq(1), NextState("SEND_TIME")))

        self.fsm.act("SEND_TIME", self.time_in.ready.eq(1),
                     self.time_out.data.eq(self.rf_reg - self.pmt_reg),
                     self.time_out.valid.eq(1), NextState("WAIT_ACC_LATENCY"))

        self.fsm.act("WAIT_ACC_LATENCY",
                     If(self.time_in.valid == 0, NextState("RESET_COUNTER")))
Exemplo n.º 5
0
            If(self.time_in.valid, self.pmt_trig.eq(1),
               NextState("WAIT_FOR_RF")))

        self.fsm.act(
            "WAIT_FOR_RF", self.time_in.ready.eq(1),
            If(self.time_in.valid, self.rf_trig.eq(1), NextState("SEND_TIME")))

        self.fsm.act("SEND_TIME", self.time_in.ready.eq(1),
                     self.time_out.data.eq(self.rf_reg - self.pmt_reg),
                     self.time_out.valid.eq(1), NextState("WAIT_ACC_LATENCY"))

        self.fsm.act("WAIT_ACC_LATENCY",
                     If(self.time_in.valid == 0, NextState("RESET_COUNTER")))


@dl.Interactive(inputs=[('time_out', dl.UInt()), ('reset', dl.Int())],
                outputs=[('output', dl.UInt())])
def testbench(node):
    """ Testbench for Timestamper interface node. Starts with random testing
    and ends with corner cases
    """
    _ITER = 10
    for i in range(_ITER):
        logging.debug(f'---Testbench iter {i}---')
        time_pmt = random.randint(0, 100)
        time_rf = random.randint(0, 100)
        do_test(node, time_pmt, time_rf)

    raise dl.DeltaRuntimeExit

Exemplo n.º 6
0
        self.sync += migen.If(
            i1.valid == 1,
            o1.valid.eq(1),
            o1.data.eq(i1.data+1)
        ).Else(
            o1.data.eq(0),
            migen.If(started == 0,
                     o1.valid.eq(1),
                     started.eq(1)
                     ).Else(
                o1.valid.eq(0)
            )
        )


@dl.Interactive([("measurement", dl.UInt(dl.Size(32)))],
                [("output", dl.UInt(dl.Size(32)))],
                name="interactive_simple")
def send_gates_list_then_exit(node: dl.PythonNode):
    cmds = ["RX", "RZ", "RY"]
    # for non-deterministic tests use random.randint(0, 255)
    args = [99, 250, 11]

    node.send(dl.lib.command_creator("STATE_PREPARATION"))

    for cmd, arg in zip(cmds, args):
        node.send(dl.lib.command_creator(cmd, argument=arg))
    node.send(dl.lib.command_creator("STATE_MEASURE"))

    measurement = node.receive("measurement")
    print(f"Measurement: {measurement}")
Exemplo n.º 7
0
                        self.error.data.eq(self.error.data),
                        self.error.valid.eq(0))
        ]

        self.pulser_inst = TimestamperModel.Pulser(self.reset,
                                                   self.pmt_trigger,
                                                   self.rf_trigger,
                                                   self.photon, self.clock)

        self.timestamper_inst = TimestamperModel.Timestamper(
            self.hit_channels, self.time, self.reset, self.clock)

        self.submodules += [self.timestamper_inst, self.pulser_inst]


@dl.Interactive(inputs=[('time', dl.UInt()), ('error', dl.Int())],
                outputs=[('reset', dl.Int()), ('photon', dl.Int())])
def testbench(node):
    """ Testbench for Timestamper model node. Starts with random testing
    and ends with corner cases
    """

    for i in range(TEST_LENGTH):
        photon = random.randint(1, TIME_RES - 2)
        do_test(i, photon, node)

    # corner cases
    # 1 : photon arrival time 0 - error expected
    do_test(-1, 0, node)
    # 2: photon arrival time TIME_RES - no expected error
    do_test(-2, TIME_RES - 1, node)
Exemplo n.º 8
0
    def test_primitives(self):
        tuple_int = dl.Tuple([
            dl.Int(dl.Size(8)),
            dl.Int(dl.Size(16)),
            dl.Int(dl.Size(32)),
            dl.Int(dl.Size(64))
        ])
        tuple_uint = dl.Tuple([
            dl.UInt(dl.Size(8)),
            dl.UInt(dl.Size(16)),
            dl.UInt(dl.Size(32)),
            dl.UInt(dl.Size(64))
        ])
        tuple_float = dl.Tuple([dl.Float(dl.Size(32)), dl.Float(dl.Size(64))])
        tuple_complex = dl.Tuple(
            [dl.Complex(dl.Size(64)),
             dl.Complex(dl.Size(128))])
        tuple_bool_char = dl.Tuple([dl.Bool(), dl.Str(dl.Size(1))])

        @dl.Interactive([("ack_int", bool), ("ack_uint", bool),
                         ("ack_float", bool), ("ack_complex", bool),
                         ("ack_bool_char", bool)],
                        [("out_int", tuple_int), ("out_uint", tuple_uint),
                         ("out_float", tuple_float),
                         ("out_complex", tuple_complex),
                         ("out_bool_char", tuple_bool_char)])
        def testbench(node: dl.PythonNode):
            node.send(out_int=(-128, -32768, -2147483648,
                               -9223372036854775808))
            assert node.receive("ack_int")

            node.send(out_int=(127, 32767, 2147483647, 9223372036854775807))
            assert node.receive("ack_int")

            node.send(out_uint=(0, 0, 0, 0))
            assert node.receive("ack_uint")

            node.send(out_uint=(255, 65535, 4294967295, 18446744073709551615))
            assert node.receive("ack_uint")

            # this is just a rough estimate
            node.send(out_float=(1.0000001, 1.000000000000001))
            assert node.receive("ack_float")

            node.send(out_complex=((1.0000001 + 1.0000001j),
                                   (1.000000000000001 + 1.000000000000001j)))
            assert node.receive("ack_complex")

            node.send(out_bool_char=(True, 'a'))
            assert node.receive("ack_bool_char")

            raise DeltaRuntimeExit

        s_int = dl.lib.StateSaver(tuple_int, verbose=True)
        s_uint = dl.lib.StateSaver(tuple_uint, verbose=True)
        s_float = dl.lib.StateSaver(tuple_float, verbose=True)
        s_complex = dl.lib.StateSaver(tuple_complex, verbose=True)
        s_bool_char = dl.lib.StateSaver(tuple_bool_char, verbose=True)

        with dl.DeltaGraph() as graph:
            p = dl.placeholder_node_factory()

            p.specify_by_node(
                testbench.call(s_int.save_and_ack(p.out_int),
                               s_uint.save_and_ack(p.out_uint),
                               s_float.save_and_ack(p.out_float),
                               s_complex.save_and_ack(p.out_complex),
                               s_bool_char.save_and_ack(p.out_bool_char)))

        self.check_executes_graph(
            graph, f"""\
            saving (-128, -32768, -2147483648, -9223372036854775808)
            saving (127, 32767, 2147483647, 9223372036854775807)
            saving (0, 0, 0, 0)
            saving (255, 65535, 4294967295, 18446744073709551615)
            saving ({np.float32(1.0000001)}, 1.000000000000001)
            saving (({np.float32(1.0000001)}+{np.float32(1.0000001)}j), (1.000000000000001+1.000000000000001j))
            saving (True, 'a')
            """)
Exemplo n.º 9
0
import matplotlib.pyplot as plt
from matplotlib import ticker
from progress.bar import Bar
import time
import math
import random
import numpy as np
import logging

import deltalanguage as dl

TIME_RES = 30


@dl.Interactive(inputs=[('new_time', dl.UInt()), ('DAC_status', int),
                        ('DAC_voltage', int),
                        ('experiment_start', dl.Optional(bool))],
                outputs=[('DAC_command', int), ('DAC_param', int),
                         ('photon', int), ('reset', int)])
def accumulator(node):
    """ Accumulator Node

    This node collects times sent from the counter FPGA node and issues
    commands to the DAC controller.

    This allows the node to collect data, fit to the data and feedback to the
    experiment. The process can loop until some minimum threshold is reached,
    allowing full automation of micromotion compensation.

    Inputs:
        - new_time: Time from Counter node