Exemple #1
0
    def __init__(self, pins, roi_engine_count=16, res_width=12, count_shift=0):
        self.config = rtlink.Interface(
            rtlink.OInterface(res_width,
                              bits_for(4*roi_engine_count-1)))
        self.gate_data = rtlink.Interface(
            rtlink.OInterface(roi_engine_count),
            rtlink.IInterface(1+ROI.count_len(res_width, count_shift),
                              timestamped=False))

        self.submodules.deserializer = deserializer_7series.Deserializer(pins)
        self.submodules.frequency_counter = FrequencyCounter()
        self.submodules.parser = Parser(res_width)
        self.comb += self.parser.cl.eq(self.deserializer.q)
        self.roi_engines = [ROI(self.parser.pix, count_shift) for _ in range(roi_engine_count)]
        self.submodules += self.roi_engines
        self.submodules.synchronizer = Synchronizer(self.roi_engines)
        self.submodules.serializer = Serializer(self.synchronizer.update, self.synchronizer.counts,
                                                self.gate_data.i)

        for n, roi_engine in enumerate(self.roi_engines):
            for offset, target in enumerate([roi_engine.cfg.x0, roi_engine.cfg.y0,
                                             roi_engine.cfg.x1, roi_engine.cfg.y1]):
                roi_boundary = Signal.like(target)
                roi_boundary.attr.add("no_retiming")
                self.sync.rtio += If(self.config.o.stb & (self.config.o.address == 4*n+offset),
                    roi_boundary.eq(self.config.o.data))
                self.specials += MultiReg(roi_boundary, target, "cl")

        self.sync.rio += If(self.gate_data.o.stb,
            self.serializer.gate.eq(self.gate_data.o.data))
Exemple #2
0
 def __init__(self, *args, **kwargs):
     _ChannelPHY.__init__(self, *args, **kwargs)
     self.phys = []
     cfg = self.i[0]
     rl = rtlink.Interface(rtlink.OInterface(
         data_width=len(cfg.data), address_width=len(cfg.addr),
         enable_replace=False))
     self.comb += [
         cfg.stb.eq(rl.o.stb),
         rl.o.busy.eq(~cfg.ack),
         cfg.data.eq(rl.o.data),
         cfg.addr.eq(rl.o.address),
     ]
     self.phys.append(_Phy(rl, [], []))
     for i in self.i[1:]:
         rl = rtlink.Interface(rtlink.OInterface(len(i.payload),
                                                 delay=-i.latency))
         self.comb += [
             i.stb.eq(rl.o.stb),
             rl.o.busy.eq(~i.ack),
             i.payload.raw_bits().eq(rl.o.data),
         ]
         # TODO probes, overrides
         self.phys.append(_Phy(rl, [], []))
     self.phys_named = dict(zip(self.i_names, self.phys))
Exemple #3
0
 def __init__(self, o_width, i_width):
     self.rtlink = rtlink.Interface(
         rtlink.OInterface(o_width),
         rtlink.IInterface(i_width, timestamped=True))
     self.received_data = Signal(o_width)
     self.sync.rio_phy += If(self.rtlink.o.stb,
                             self.received_data.eq(self.rtlink.o.data))
Exemple #4
0
    def __init__(self, pad, pad_n=None):
        self.rtlink = rtlink.Interface(rtlink.OInterface(2, 2),
                                       rtlink.IInterface(1))
        self.overrides = []
        self.probes = []

        # # #

        sensitivity = Signal(2)

        sample = Signal()
        self.sync.rio += [
            sample.eq(0),
            If(self.rtlink.o.stb & self.rtlink.o.address[1],
               sensitivity.eq(self.rtlink.o.data),
               If(self.rtlink.o.address[0], sample.eq(1)))
        ]

        i = Signal()
        i_d = Signal(reset_less=True)
        pad_i = Signal()
        if pad_n is None:
            self.comb += pad_i.eq(pad)
        else:
            self.specials += DifferentialInput(pad, pad_n, pad_i)
        self.specials += MultiReg(pad_i, i, "rio_phy")
        self.sync.rio_phy += i_d.eq(i)
        self.comb += [
            self.rtlink.i.stb.eq(sample | (sensitivity[0] & (i & ~i_d))
                                 | (sensitivity[1] & (~i & i_d))),
            self.rtlink.i.data.eq(i)
        ]

        self.probes += [i]
Exemple #5
0
    def __init__(self, pad, pad_n=None, ftw_width=24, dci=False):
        self.rtlink = rtlink.Interface(rtlink.OInterface(ftw_width))

        # # #

        pad_o = Signal()
        if pad_n is None:
            self.comb += pad.eq(pad_o)
        else:
            self.specials += DifferentialOutput(pad_o, pad, pad_n)
        ftw = Signal(ftw_width)
        acc = Signal(ftw_width)
        self.sync.rio += If(self.rtlink.o.stb, ftw.eq(self.rtlink.o.data))
        self.sync.rio_phy += [
            acc.eq(acc + ftw),
            # rtlink takes precedence over regular acc increments
            If(
                self.rtlink.o.stb,
                If(
                    self.rtlink.o.data != 0,
                    # known phase on frequency write: at rising edge
                    acc.eq(2**(ftw_width - 1))).Else(
                        # set output to 0 on stop
                        acc.eq(0))),
            pad_o.eq(acc[-1])
        ]
Exemple #6
0
    def __init__(self, address_width, wb=None):
        if wb is None:
            wb = wishbone.Interface()
        self.wb = wb
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(flen(wb.dat_w),
                              address_width + 1,
                              suppress_nop=False),
            rtlink.IInterface(flen(wb.dat_r), timestamped=False))

        # # #

        active = Signal()
        self.sync.rio += [
            If(self.rtlink.o.stb, active.eq(1),
               wb.adr.eq(self.rtlink.o.address[:address_width]),
               wb.we.eq(~self.rtlink.o.address[address_width]),
               wb.dat_w.eq(self.rtlink.o.data),
               wb.sel.eq(2**flen(wb.sel) - 1)),
            If(wb.ack, active.eq(0))
        ]
        self.comb += [
            self.rtlink.o.busy.eq(active),
            wb.cyc.eq(active),
            wb.stb.eq(active),
            self.rtlink.i.stb.eq(wb.ack & ~wb.we),
            self.rtlink.i.data.eq(wb.dat_r)
        ]
Exemple #7
0
    def __init__(self, pad):
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(2, 2),
            rtlink.IInterface(1))
        self.overrides = []
        self.probes = []

        # # #

        sensitivity = Signal(2)

        sample = Signal()
        self.sync.rio += [
            sample.eq(0),
            If(self.rtlink.o.stb & self.rtlink.o.address[1],
                sensitivity.eq(self.rtlink.o.data),
                If(self.rtlink.o.address[0], sample.eq(1))
            )
        ]

        i = Signal()
        i_d = Signal()
        self.specials += MultiReg(pad, i, "rio_phy")
        self.sync.rio_phy += i_d.eq(i)
        self.comb += [
            self.rtlink.i.stb.eq(
                sample |
                (sensitivity[0] & ( i & ~i_d)) |
                (sensitivity[1] & (~i &  i_d))
            ),
            self.rtlink.i.data.eq(i)
        ]

        self.probes += [i]
Exemple #8
0
 def __init__(self, regs):
     self.rtlink = rtlink.Interface(
         rtlink.OInterface(data_width=32,
                           address_width=4,
                           enable_replace=True))
     self.sync.rtio += [
         If(self.rtlink.o.stb,
            Array(regs)[self.rtlink.o.address].eq(self.rtlink.o.data))
     ]
Exemple #9
0
    def __init__(self, pad):
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(2, 2),
            rtlink.IInterface(1))
        override_en = Signal()
        override_o = Signal()
        override_oe = Signal()
        self.overrides = [override_en, override_o, override_oe]
        self.probes = []

        # # #
        
        ts = TSTriple()
        self.specials += ts.get_tristate(pad)
        sensitivity = Signal(2)

        o_k = Signal()
        oe_k = Signal()
        self.sync.rio_phy += [
            If(self.rtlink.o.stb,
                If(self.rtlink.o.address == 0, o_k.eq(self.rtlink.o.data[0])),
                If(self.rtlink.o.address == 1, oe_k.eq(self.rtlink.o.data[0])),
            ),
            If(override_en,
                ts.o.eq(override_o),
                ts.oe.eq(override_oe)
            ).Else(
                ts.o.eq(o_k),
                ts.oe.eq(oe_k)
            )
        ]
        sample = Signal()
        self.sync.rio += [
            sample.eq(0),
            If(self.rtlink.o.stb & self.rtlink.o.address[1],
                sensitivity.eq(self.rtlink.o.data),
                If(self.rtlink.o.address[0], sample.eq(1))
            )
        ]
        
        i = Signal()
        i_d = Signal()
        self.specials += MultiReg(ts.i, i, "rio_phy")
        self.sync.rio_phy += i_d.eq(i)
        self.comb += [
            self.rtlink.i.stb.eq(
                sample |
                (sensitivity[0] & ( i & ~i_d)) |
                (sensitivity[1] & (~i &  i_d))
            ),
            self.rtlink.i.data.eq(i)
        ]

        self.probes += [i, ts.oe]
Exemple #10
0
    def __init__(self, serdes):
        serdes_width = len(serdes.o)
        assert len(serdes.i) == serdes_width
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(2, 2, fine_ts_width=log2_int(serdes_width)),
            rtlink.IInterface(1, fine_ts_width=log2_int(serdes_width)))
        self.probes = [serdes.i[-1], serdes.oe]
        override_en = Signal()
        override_o = Signal()
        override_oe = Signal()
        self.overrides = [override_en, override_o, override_oe]

        # # #

        # Output
        self.submodules += _SerdesDriver(serdes_o=serdes.o,
                                         stb=self.rtlink.o.stb &
                                         (self.rtlink.o.address == 0),
                                         data=self.rtlink.o.data[0],
                                         fine_ts=self.rtlink.o.fine_ts,
                                         override_en=override_en,
                                         override_o=override_o)

        oe_k = Signal()
        self.sync.rio_phy += [
            If(self.rtlink.o.stb & (self.rtlink.o.address == 1),
               oe_k.eq(self.rtlink.o.data[0])),
            If(override_en, serdes.oe.eq(override_oe)).Else(serdes.oe.eq(oe_k))
        ]

        # Input
        sensitivity = Signal(2)
        sample = Signal()
        self.sync.rio += [
            sample.eq(0),
            If(self.rtlink.o.stb & self.rtlink.o.address[1],
               sensitivity.eq(self.rtlink.o.data),
               If(self.rtlink.o.address[0], sample.eq(1)))
        ]

        i = serdes.i[-1]
        i_d = Signal()
        self.sync.rio_phy += [
            i_d.eq(i),
            self.rtlink.i.stb.eq(sample | (sensitivity[0] & (i & ~i_d))
                                 | (sensitivity[1] & (~i & i_d))),
            self.rtlink.i.data.eq(i),
        ]

        pe = PriorityEncoder(serdes_width)
        self.submodules += pe
        self.comb += pe.i.eq(serdes.i ^ Replicate(i_d, serdes_width))
        self.sync.rio_phy += self.rtlink.i.fine_ts.eq(pe.o)
Exemple #11
0
    def __init__(self, pad):
        self.rtlink = rtlink.Interface(rtlink.OInterface(2, 2),
                                       rtlink.IInterface(1))
        override_en = Signal()
        override_o = Signal()
        override_oe = Signal()
        self.overrides = [override_en, override_o, override_oe]
        self.probes = []

        # Output enable, for interfacing to external buffers.
        self.oe = Signal()
        # Registered copy of the input state, in the rio_phy clock domain.
        self.input_state = Signal()

        # # #

        ts = TSTriple()
        self.specials += ts.get_tristate(pad)
        sensitivity = Signal(2)

        o_k = Signal()
        oe_k = Signal()
        self.oe.attr.add("no_retiming")
        self.sync.rio_phy += [
            If(
                self.rtlink.o.stb,
                If(self.rtlink.o.address == 0, o_k.eq(self.rtlink.o.data[0])),
                If(self.rtlink.o.address == 1, oe_k.eq(self.rtlink.o.data[0])),
            ),
            If(override_en, ts.o.eq(override_o),
               self.oe.eq(override_oe)).Else(ts.o.eq(o_k), self.oe.eq(oe_k))
        ]
        self.comb += ts.oe.eq(self.oe)
        sample = Signal()
        self.sync.rio += [
            sample.eq(0),
            If(self.rtlink.o.stb & self.rtlink.o.address[1],
               sensitivity.eq(self.rtlink.o.data),
               If(self.rtlink.o.address[0], sample.eq(1)))
        ]

        i = Signal()
        i_d = Signal()
        self.specials += MultiReg(ts.i, i, "rio_phy")
        self.sync.rio_phy += i_d.eq(i)
        self.comb += [
            self.rtlink.i.stb.eq(sample | (sensitivity[0] & (i & ~i_d))
                                 | (sensitivity[1] & (~i & i_d))),
            self.rtlink.i.data.eq(i),
            self.input_state.eq(i)
        ]

        self.probes += [i, ts.oe]
Exemple #12
0
    def __init__(self, regs, name, identifier=None):
        self.name = name
        self.regs = regs

        data_width = max([x[1] for x in regs])

        self.rtlink = rtlink.Interface(
            rtlink.OInterface(data_width=data_width,
                              address_width=len(regs).bit_length() + 1),
            rtlink.IInterface(data_width=data_width, timestamped=False))

        write_enable = self.rtlink.o.address[0]
        address = self.rtlink.o.address[1:]

        data_signals_list = []
        for idx, r in enumerate(regs):
            if len(r) > 2:
                reset_value = r[2]
            else:
                reset_value = 0
            if len(r) > 3:
                mode = r[3]
            else:
                mode = "rw"
            signal = Signal(bits_sign=r[1], name=r[0], reset=reset_value)
            setattr(self, r[0], signal)
            data_signals_list.append(signal)

            if mode == "rw":
                ld_signal_name = r[0] + "_ld"
                setattr(self, ld_signal_name,
                        Signal(bits_sign=1, name=ld_signal_name))
                ld_signal = getattr(self, ld_signal_name)
                self.sync.rio_phy += [
                    ld_signal.eq(0),
                    If(self.rtlink.o.stb & write_enable & (address == idx),
                       signal.eq(self.rtlink.o.data), ld_signal.eq(1))
                ]

        data_signals = Array(data_signals_list)
        self.sync.rio_phy += [
            self.rtlink.i.stb.eq(0),
            If(self.rtlink.o.stb & ~write_enable, self.rtlink.i.stb.eq(1),
               self.rtlink.i.data.eq(data_signals[address]))
        ]

        if identifier is not None:
            self.add_rtio_channels(channel=Channel.from_phy(self),
                                   device_id=identifier,
                                   module="elhep_cores.coredevice.rtlink_csr",
                                   class_name="RtlinkCsr",
                                   arguments={"regs": regs})
Exemple #13
0
    def __init__(self, ctrl):
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(len(ctrl.profile) + 2))

        # # #

        self.comb += [ctrl.stb.eq(self.rtlink.o.stb), self.rtlink.o.busy.eq(0)]
        self.sync.rio_phy += [
            If(
                self.rtlink.o.stb,
                Cat(ctrl.en_out, ctrl.en_iir,
                    ctrl.profile).eq(self.rtlink.o.data))
        ]
Exemple #14
0
    def __init__(self, pad):
        self.rtlink = rtlink.Interface(rtlink.OInterface(1))
        self.probes = [pad]
        override_en = Signal()
        override_o = Signal()
        self.overrides = [override_en, override_o]

        # # #

        pad_k = Signal()
        self.sync.rio_phy += [
            If(self.rtlink.o.stb, pad_k.eq(self.rtlink.o.data)),
            If(override_en, pad.eq(override_o)).Else(pad.eq(pad_k))
        ]
Exemple #15
0
 def __init__(self, *args, **kwargs):
     _ChannelPHY.__init__(self, *args, **kwargs)
     self.phys = []
     for i in self.i:
         rl = rtlink.Interface(rtlink.OInterface(len(i.payload),
                                                 delay=-i.latency))
         self.comb += [
             i.stb.eq(rl.o.stb),
             rl.o.busy.eq(~i.ack),
             i.payload.raw_bits().eq(rl.o.data),
         ]
         # TODO probes, overrides
         self.phys.append(_Phy(rl, [], []))
     self.phys_named = dict(zip(self.i_names, self.phys))
Exemple #16
0
    def __init__(self, serdes):
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(1, fine_ts_width=log2_int(len(serdes.o))))
        self.probes = [serdes.o[-1]]
        override_en = Signal()
        override_o = Signal()
        self.overrides = [override_en, override_o]

        # # #

        self.submodules += _SerdesDriver(serdes.o, self.rtlink.o.stb,
                                         self.rtlink.o.data,
                                         self.rtlink.o.fine_ts, override_en,
                                         override_o)
Exemple #17
0
    def __init__(self):
        self.rtlink = rtlink.Interface(rtlink.OInterface(1),
                                       rtlink.IInterface(1))
        self.overrides = []
        self.probes = []

        # # #

        counter = Signal(2)
        trigger = Signal()
        self.sync += [
            Cat(counter, trigger).eq(counter + 1),
            self.rtlink.i.stb.eq(0),
            If(trigger, self.rtlink.i.stb.eq(1),
               self.rtlink.i.data.eq(~self.rtlink.i.data))
        ]
    def _add_rtlink(self):
        # Address 0: enabled
        # Address 1: pulse length
        # Address 2: mask

        mask_adr_no = (len(self.mask) + 31) // 32
        adr_width = len(Signal(max=mask_adr_no + 1)) + 2

        self.rtlink = rtlink.Interface(
            rtlink.OInterface(data_width=32, address_width=adr_width),
            rtlink.IInterface(data_width=32, timestamped=False))

        self.rtlink_address = rtlink_address = Signal.like(
            self.rtlink.o.address)
        self.rtlink_wen = rtlink_wen = Signal()
        self.comb += [
            rtlink_address.eq(self.rtlink.o.address[1:]),
            rtlink_wen.eq(self.rtlink.o.address[0]),
        ]

        mask_array = self.signal_to_array(self.mask)

        self.sync.rio_phy += [
            self.rtlink.i.stb.eq(0),
            If(
                self.rtlink.o.stb,
                # Write
                If(rtlink_wen & (rtlink_address == 0),
                   self.enabled.eq(self.rtlink.o.data[0])).Elif(
                       rtlink_wen & (rtlink_address == 1),
                       self.pulse_length.eq(self.rtlink.o.data)).Elif(
                           rtlink_wen & (rtlink_address >= 2),
                           mask_array[rtlink_address - 2].eq(
                               self.rtlink.o.data)).
                # Readout
                Elif(~rtlink_wen & (rtlink_address == 0),
                     self.rtlink.i.data.eq(self.enabled),
                     self.rtlink.i.stb.eq(1)).Elif(
                         ~rtlink_wen & (rtlink_address == 1),
                         self.rtlink.i.data.eq(self.pulse_length),
                         self.rtlink.i.stb.eq(1)).Elif(
                             ~rtlink_wen & (rtlink_address >= 2),
                             self.rtlink.i.data.eq(mask_array[rtlink_address -
                                                              2]),
                             self.rtlink.i.stb.eq(1)))
        ]
Exemple #19
0
    def __init__(self, pad, pad_n=None):
        self.rtlink = rtlink.Interface(rtlink.OInterface(1))
        pad_o = Signal(reset_less=True)
        self.probes = [pad_o]
        override_en = Signal()
        override_o = Signal()
        self.overrides = [override_en, override_o]

        # # #

        pad_k = Signal()
        self.sync.rio_phy += [
            If(self.rtlink.o.stb, pad_k.eq(self.rtlink.o.data)),
            If(override_en, pad_o.eq(override_o)).Else(pad_o.eq(pad_k))
        ]
        if pad_n is None:
            self.comb += pad.eq(pad_o)
        else:
            self.specials += DifferentialOutput(pad_o, pad, pad_n)
Exemple #20
0
    def __init__(self, pad, ftw_width=24):
        self.rtlink = rtlink.Interface(rtlink.OInterface(ftw_width))

        # # #

        ftw = Signal(ftw_width)
        acc = Signal(ftw_width)
        self.sync.rio += If(self.rtlink.o.stb, ftw.eq(self.rtlink.o.data))
        self.sync.rio_phy += [
            acc.eq(acc + ftw),
            # rtlink takes precedence over regular acc increments
            If(
                self.rtlink.o.stb,
                If(
                    self.rtlink.o.data != 0,
                    # known phase on frequency write: at rising edge
                    acc.eq(2**(ftw_width - 1))).Else(
                        # set output to 0 on stop
                        acc.eq(0))),
            pad.eq(acc[-1])
        ]
    def __init__(self, data, treshold_length=4, name="baseline_trigger"):

        self.rtlink = rtlink.Interface(rtlink.OInterface(data_width=len(data)))

        # # #

        regs = [("offset_level", len(data))]
        csr = RtLinkCSR(regs, "baseline_trigger_generator")
        self.submodules.csr = csr

        trigger_level_sys = Signal.like(data)

        cdc = BusSynchronizer(len(data), "rio_phy", "sys")
        self.submodules += cdc

        self.comb += [
            cdc.i.eq(self.csr.offset_level),
            trigger_level_sys.eq(cdc.o)
        ]

        super().__init__(data, trigger_level_sys, treshold_length, name)
Exemple #22
0
    def __init__(self, servo):
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(data_width=32, address_width=8,
                enable_replace=False),
            rtlink.IInterface(data_width=32))
        
        ###
        
        # reg addresses - starts with R/!W
        cases = {
            # control/config reg - rst, afe, dac_clr
            0x00: servo.ctrl[:4].eq(self.rtlink.o.data),
            # enable channels
            0x01: servo.ctrl[4:6].eq(self.rtlink.o.data),
            # enable ADC AFE X10 gain
            0x02: servo.ctrl[6:].eq(self.rtlink.o.data),
            # set dac
            0x03: servo.mode.eq(self.rtlink.o.data[-2:]), servo.dac_data.eq(self.rtlink.o.data[:-2])
            # init/status reg
            0x04: servo.init,
            # adc data
            0x05: servo.adc_data,
        }


        input_data = Signal(32, reset_less=True)

        self.sync.rio_phy += [
            If(self.rtlink.o.stb & ~self.rtlink.o.address[-1],
                Case(self.rtlink.o.address[:-1], cases)
            ),
            If(self.rtlink.i.stb,
                input_data.eq(Case(self.rtlink.o.address[:-1], cases))
            )
        ]

        self.comb += [
            self.rtlink.i.stb.eq(self.rtlink.o.stb & self.rtlink.o.address[-1]),
            self.rtlink.i.data.eq(input_data),
        ]
Exemple #23
0
    def __init__(self,
                 address_width,
                 wb=None,
                 rtio_enable_replace=False,
                 write_only=False):
        if wb is None:
            wb = wishbone.Interface()
        self.wb = wb
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(len(wb.dat_w),
                              address_width +
                              1 if not write_only else address_width,
                              enable_replace=rtio_enable_replace),
            rtlink.IInterface(len(wb.dat_r), timestamped=False)
            if not write_only else None)

        # # #

        active = Signal()
        self.sync.rio += [
            If(
                self.rtlink.o.stb, active.eq(1),
                wb.adr.eq(self.rtlink.o.address[:address_width]),
                wb.we.eq(~self.rtlink.o.address[address_width]
                         if not write_only else 1),
                wb.dat_w.eq(self.rtlink.o.data),
                wb.sel.eq(2**len(wb.sel) - 1)),
            If(wb.ack, active.eq(0))
        ]
        self.comb += [
            self.rtlink.o.busy.eq(active),
            wb.cyc.eq(active),
            wb.stb.eq(active),
        ]

        if not write_only:
            self.comb += [
                self.rtlink.i.stb.eq(wb.ack & ~wb.we),
                self.rtlink.i.data.eq(wb.dat_r)
            ]
    def __init__(self, name="sw_trigger", identifier=None):
        super().__init__(name)

        # Outputs
        self.trigger = Signal()  # CD: rio_phy
        self.register_trigger(self.trigger, "trigger", ClockDomain("rio_phy"))

        # Interface - rtlink
        self.rtlink = rtlink_iface = rtlink.Interface(
            rtlink.OInterface(data_width=1))

        self.sync.rio_phy += [
            self.trigger.eq(0),
            If(rtlink_iface.o.stb, self.trigger.eq(1))
        ]

        if identifier is not None:
            self.add_rtio_channels(
                channel=Channel.from_phy(self),
                device_id=identifier,
                module="elhep_cores.coredevice.trigger_generators",
                class_name="RtioTriggerGenerator")
Exemple #25
0
 def __init__(self):
     self.interface = rtlink.Interface(rtlink.OInterface(32))
     self.probes = []
     self.overrides = []
Exemple #26
0
    def __init__(self, pins, pins_n):
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(data_width=8,
                              address_width=8,
                              enable_replace=False),
            rtlink.IInterface(data_width=10))

        # share a CosSinGen LUT between the two channels
        self.submodules.ch0 = DDSChannel()
        self.submodules.ch1 = DDSChannel(share_lut=self.ch0.dds.cs.lut)
        n_channels = 2
        n_samples = 8
        n_bits = 14
        body = Signal(n_samples * n_channels * 2 * n_bits, reset_less=True)
        self.sync.rio_phy += [
            If(
                self.ch0.dds.valid,  # & self.ch1.dds.valid,
                # recent:ch0:i as low order in body
                Cat(body).eq(
                    Cat(self.ch0.dds.o.i[2:], self.ch0.dds.o.q[2:],
                        self.ch1.dds.o.i[2:], self.ch1.dds.o.q[2:], body)),
            ),
        ]

        self.submodules.serializer = SerDes(n_data=8,
                                            t_clk=8,
                                            d_clk=0b00001111,
                                            n_frame=10,
                                            n_crc=6,
                                            poly=0x2f)
        self.submodules.intf = SerInterface(pins, pins_n)
        self.comb += [
            Cat(self.intf.data[:-1]).eq(Cat(self.serializer.data[:-1])),
            self.serializer.data[-1].eq(self.intf.data[-1]),
        ]

        header = Record([("we", 1), ("addr", 7), ("data", 8), ("type", 4)])
        assert len(Cat(header.raw_bits(), body)) == \
                len(self.serializer.payload)
        self.comb += self.serializer.payload.eq(Cat(header.raw_bits(), body))

        re_dly = Signal(3)  # stage, send, respond
        self.sync.rtio += [
            header.type.eq(1),  # body type is baseband data
            If(
                self.serializer.stb,
                self.ch0.dds.stb.eq(1),  # synchronize
                self.ch1.dds.stb.eq(1),  # synchronize
                header.we.eq(0),
                re_dly.eq(re_dly[1:]),
            ),
            If(
                self.rtlink.o.stb,
                re_dly[-1].eq(~self.rtlink.o.address[-1]),
                header.we.eq(self.rtlink.o.address[-1]),
                header.addr.eq(self.rtlink.o.address),
                header.data.eq(self.rtlink.o.data),
            ),
            self.rtlink.i.stb.eq(re_dly[0] & self.serializer.stb),
            self.rtlink.i.data.eq(self.serializer.readback),
        ]
Exemple #27
0
    def __init__(self, core_link_pads, output_pads, passthrough_sigs, input_phys, simulate=False):
        """
        core_link_pads: EEM pads for inter-Kasli link
        output_pads: pads for 4 output signals (422sigma, 1092, 422 ps trigger, aux)
        passthrough_sigs: signals from output phys, connected to output_pads when core
            not running
        input_phys: serdes phys for 5 inputs – APD0-3 and 422ps trigger in
        """

        event_counter_width = 14
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(
                data_width=32,
                address_width=6,
                enable_replace=False),
            rtlink.IInterface(
                data_width=max(14, event_counter_width),
                timestamped=True)
            )

        # # #


        self.submodules.core = ClockDomainsRenamer("rio")(EntanglerCore(
            core_link_pads, output_pads, passthrough_sigs, input_phys,
            event_counter_width, simulate=simulate))

        read_en = self.rtlink.o.address[5]
        write_timings = Signal()
        write_patterns = Signal()
        self.comb += [
            self.rtlink.o.busy.eq(0),
            write_timings.eq(self.rtlink.o.address[3:6] == 1),
            write_patterns.eq(self.rtlink.o.address[3:6] == 2),
        ]

        output_t_starts = [seq.m_start for seq in self.core.sequencers]
        output_t_ends = [seq.m_stop for seq in self.core.sequencers]
        output_t_starts += [gater.gate_start for gater in self.core.apd_gaters]
        output_t_ends += [gater.gate_stop for gater in self.core.apd_gaters]
        write_timing_cases = {}
        for i in range(len(output_t_starts)):
            write_timing_cases[i] = [output_t_starts[i].eq(self.rtlink.o.data[:16]),
                        output_t_ends[i].eq(self.rtlink.o.data[16:])]

        # Write timeout counter and start core running
        self.comb += [
            self.core.msm.time_remaining_buf.eq(self.rtlink.o.data),
            self.core.msm.run_stb.eq( (self.rtlink.o.address==1) & self.rtlink.o.stb )
        ]

        self.sync.rio += [
            If(write_timings & self.rtlink.o.stb,
               Case(self.rtlink.o.address[:3], write_timing_cases)
            ),
            If(write_patterns & self.rtlink.o.stb,
                Cat(
                    *Array(p.patterns for p in self.core.pattern_counters)[
                        self.rtlink.o.address[:3]]).eq(self.rtlink.o.data)
            ),
            If((self.rtlink.o.address == 0) & self.rtlink.o.stb,
                # Write config
                self.core.enable.eq(self.rtlink.o.data[0]),
                self.core.msm.standalone.eq(self.rtlink.o.data[2]),
            ),
            If((self.rtlink.o.address == 2) & self.rtlink.o.stb,
                # Write cycle length
                self.core.msm.m_end.eq(self.rtlink.o.data[:10])
            ),
            If((self.rtlink.o.address == 3) & self.rtlink.o.stb,
                # Write herald patterns and enables
                *[
                    self.core.heralder.patterns[i].eq(
                        self.rtlink.o.data[4 * i:4 * (i + 1)]) for i in range(4)
                ],
                self.core.heralder.pattern_ens.eq(self.rtlink.o.data[16:20])
            ),
        ]

        # Write is_master bit in rio_phy reset domain to not break 422ps trigger
        # forwarding on core.reset().
        self.sync.rio_phy += If((self.rtlink.o.address == 0) & self.rtlink.o.stb,
            self.core.msm.is_master.eq(self.rtlink.o.data[1])
        )


        read = Signal()
        read_counters = Signal()
        read_timestamps = Signal()
        read_addr = Signal(3)

        # Input timestamps are [apd0, apd1, apd2, apd3, ref]
        input_timestamps = [gater.sig_ts for gater in self.core.apd_gaters]
        input_timestamps.append(self.core.apd_gaters[0].ref_ts)
        cases = {}
        timing_data = Signal(14)
        for i, ts in enumerate(input_timestamps):
            cases[i] = [timing_data.eq(ts)]
        self.comb += Case(read_addr, cases)


        self.sync.rio += [
                If(read,
                    read.eq(0)
                ),
                If(self.rtlink.o.stb,
                    read.eq(read_en),
                    read_counters.eq(self.rtlink.o.address[3:5] == 0b10),
                    read_timestamps.eq(self.rtlink.o.address[3:5] == 0b01),
                    read_addr.eq(self.rtlink.o.address[:3]),
                )
        ]

        status = Signal(3)
        self.comb += status.eq(Cat(self.core.msm.ready,
                                   self.core.msm.success,
                                   self.core.msm.timeout))

        reg_data = Signal(event_counter_width)
        cases = {}
        cases[0] = [reg_data.eq(status)]
        cases[1] = [reg_data.eq(self.core.msm.cycles_completed)]
        cases[2] = [reg_data.eq(self.core.msm.time_remaining)]
        cases[3] = [reg_data.eq(self.core.triggers_received)]
        self.comb += Case(read_addr, cases)

        counter_data = Signal(event_counter_width)
        self.comb += Case(read_addr,
            {i: [counter_data.eq(c.counter)]
             for i, c in enumerate(self.core.counters)})

        # Generate an input event if we have a read request RTIO Output event, or if the
        # core has finished. If the core is finished output the herald match, or 0x3fff
        # on timeout.
        #
        # Simultaneous read requests and core-done events are not currently handled, but
        # are easy to avoid in the client code.
        self.comb += [
            self.rtlink.i.stb.eq(read | self.core.enable & self.core.msm.done_stb),
            self.rtlink.i.data.eq(
                Mux(self.core.enable & self.core.msm.done_stb,
                    Mux(self.core.msm.success, self.core.heralder.matches, 0x3fff),
                    Mux(read_counters,
                        counter_data,
                        Mux(read_timestamps, timing_data, reg_data)
                    )
                )
            )
        ]
Exemple #28
0
 def __init__(self, width):
     self.rtlink = rtlink.Interface(rtlink.OInterface(width))
     self.received_data = Signal(width)
     self.sync.rio_phy += If(self.rtlink.o.stb,
                             self.received_data.eq(self.rtlink.o.data))
Exemple #29
0
    def __init__(self, pads, pads_n=None):
        to_rio_phy = ClockDomainsRenamer("rio_phy")
        if pads_n is None:
            interface = SPIInterface(pads)
        else:
            interface = SPIInterfaceXC7Diff(pads, pads_n)
        interface = to_rio_phy(interface)
        spi = to_rio_phy(SPIMachine(data_width=32, div_width=8))
        self.submodules += interface, spi

        self.rtlink = rtlink.Interface(
            rtlink.OInterface(len(spi.reg.pdo),
                              address_width=1,
                              enable_replace=False),
            rtlink.IInterface(len(spi.reg.pdi), timestamped=False))

        ###

        config = Record([
            ("offline", 1),
            ("end", 1),
            ("input", 1),
            ("cs_polarity", 1),
            ("clk_polarity", 1),
            ("clk_phase", 1),
            ("lsb_first", 1),
            ("half_duplex", 1),
            ("length", 5),
            ("padding", 3),
            ("div", 8),
            ("cs", 8),
        ])
        assert len(config) == len(spi.reg.pdo) == len(spi.reg.pdi) == 32

        config.offline.reset = 1
        config.end.reset = 1
        read = Signal()

        self.sync.rio += [
            If(self.rtlink.i.stb, read.eq(0)),
            If(
                self.rtlink.o.stb & spi.writable,
                If(self.rtlink.o.address,
                   config.raw_bits().eq(self.rtlink.o.data)).Else(
                       read.eq(config.input))),
        ]

        self.comb += [
            spi.length.eq(config.length),
            spi.end.eq(config.end),
            spi.cg.div.eq(config.div),
            spi.clk_phase.eq(config.clk_phase),
            spi.reg.lsb_first.eq(config.lsb_first),
            interface.half_duplex.eq(config.half_duplex),
            interface.cs.eq(config.cs),
            interface.cs_polarity.eq(
                Replicate(config.cs_polarity, len(interface.cs_polarity))),
            interface.clk_polarity.eq(config.clk_polarity),
            interface.offline.eq(config.offline),
            interface.cs_next.eq(spi.cs_next),
            interface.clk_next.eq(spi.clk_next),
            interface.ce.eq(spi.ce),
            interface.sample.eq(spi.reg.sample),
            spi.reg.sdi.eq(interface.sdi),
            interface.sdo.eq(spi.reg.sdo),
            spi.load.eq(self.rtlink.o.stb & spi.writable
                        & ~self.rtlink.o.address),
            spi.reg.pdo.eq(self.rtlink.o.data),
            self.rtlink.o.busy.eq(~spi.writable),
            self.rtlink.i.stb.eq(spi.readable & read),
            self.rtlink.i.data.eq(spi.reg.pdi)
        ]
        self.probes = []
Exemple #30
0
    def __init__(self, w, servo):
        m_coeff = servo.iir.m_coeff.get_port(write_capable=True,
                                             mode=READ_FIRST,
                                             we_granularity=w.coeff,
                                             clock_domain="rio")
        assert len(m_coeff.we) == 2
        m_state = servo.iir.m_state.get_port(
            write_capable=True,
            # mode=READ_FIRST,
            clock_domain="rio")
        self.specials += m_state, m_coeff

        # just expose the w.coeff (18) MSBs of state
        assert w.state >= w.coeff
        # ensure that we can split the coefficient storage correctly
        assert len(m_coeff.dat_w) == 2 * w.coeff
        # ensure that the DDS word data fits into the coefficient mem
        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(
            rtlink.OInterface(data_width=overflow_address_width + w.coeff,
                              address_width=rtlink_address_width,
                              enable_replace=False),
            rtlink.IInterface(data_width=w.coeff, timestamped=False))

        # # #

        config = Signal(w.coeff, reset=0)
        status = Signal(w.coeff)
        pad = Signal(6)
        self.comb += [
            Cat(servo.start).eq(config),
            status.eq(
                Cat(servo.start, servo.done, pad,
                    [_.clip for _ in servo.iir.ctrl]))
        ]

        assert len(self.rtlink.o.address) + len(
            self.rtlink.o.data) - w.coeff == (
                1 +  # we
                1 +  # state_sel
                1 +  # high_coeff
                len(m_coeff.adr))
        # ensure that we can fit config/status into the state address space
        assert len(self.rtlink.o.address) + len(
            self.rtlink.o.data) - w.coeff >= (
                1 +  # we
                1 +  # state_sel
                1 +  # config_sel
                len(m_state.adr))

        internal_address = Signal(internal_address_width)
        self.comb += internal_address.eq(
            Cat(self.rtlink.o.address, self.rtlink.o.data[w.coeff:]))

        coeff_data = Signal(w.coeff)
        self.comb += coeff_data.eq(self.rtlink.o.data[:w.coeff])

        we = internal_address[-1]
        state_sel = internal_address[-2]
        config_sel = internal_address[-3]
        high_coeff = internal_address[0]
        self.comb += [
            self.rtlink.o.busy.eq(0),
            m_coeff.adr.eq(internal_address[1:]),
            m_coeff.dat_w.eq(Cat(coeff_data, coeff_data)),
            m_coeff.we[0].eq(self.rtlink.o.stb & ~high_coeff & we
                             & ~state_sel),
            m_coeff.we[1].eq(self.rtlink.o.stb & high_coeff & we & ~state_sel),
            m_state.adr.eq(internal_address),
            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),
        ]
        read = Signal()
        read_state = Signal()
        read_high = Signal()
        read_config = Signal()
        self.sync.rio += [
            If(read, read.eq(0)),
            If(
                self.rtlink.o.stb,
                read.eq(~we),
                read_state.eq(state_sel),
                read_high.eq(high_coeff),
                read_config.eq(config_sel),
            )
        ]
        self.sync.rio_phy += [
            If(self.rtlink.o.stb & we & state_sel & config_sel,
               config.eq(self.rtlink.o.data)),
            If(read & read_config & read_state,
               [_.clip.eq(0) for _ in servo.iir.ctrl])
        ]
        self.comb += [
            self.rtlink.i.stb.eq(read),
            self.rtlink.i.data.eq(
                Mux(
                    read_state,
                    Mux(read_config, status,
                        m_state.dat_r[w.state - w.coeff:]),
                    Mux(read_high, m_coeff.dat_r[w.coeff:],
                        m_coeff.dat_r[:w.coeff])))
        ]