Esempio n. 1
0
    def transform_instance(self, submodule):
        for ep_name, direction in self.endpoint_dict.items():
            endpoint = getattr(submodule, ep_name)
            try:
                ios = submodule.ios
            except:
                ios = []
                setattr(submodule, "ios", ios)

            prefix = "_s_axis_t" if direction == DIR_SINK else "_m_axis_t"
            _map = [
                ("valid", DIR_M_TO_S),
                ("ready", DIR_S_TO_M),
                ("last", DIR_M_TO_S),
                ("data", DIR_M_TO_S),
            ]

            for sn, _dir in _map:
                ss = getattr(endpoint, sn)
                ps = Signal.like(ss, name=endpoint.name + prefix + sn)
                if direction == DIR_SINK:
                    submodule.comb += ss.eq(
                        ps) if _dir == DIR_M_TO_S else ps.eq(ss)
                else:
                    submodule.comb += ss.eq(
                        ps) if _dir == DIR_S_TO_M else ps.eq(ss)
                ios.append(ps)

            submodule.ios = ios
Esempio n. 2
0
    def __init__(self, width=14, N_points=16383, max_delay=16383):
        self.restart = Signal()
        self.writing_data_now = Signal()

        self.input = Signal((width, True))
        self.delay_value = Signal(bits_for(N_points))

        sum_value_bits = bits_for(((2**width) - 1) * N_points)
        self.sum_value = Signal((sum_value_bits, True))
        delayed_sum = Signal((sum_value_bits, True))
        current_sum_diff = Signal((sum_value_bits + 1, True))
        self.output = Signal.like(current_sum_diff)

        self.submodules.delayer = DynamicDelay(sum_value_bits,
                                               max_delay=max_delay)

        self.sync += [
            If(
                self.restart,
                self.sum_value.eq(0),
            ).Else(
                If(
                    self.writing_data_now,
                    # not at start
                    self.sum_value.eq(self.sum_value + self.input),
                ))
        ]

        self.comb += [
            self.delayer.writing_data_now.eq(self.writing_data_now),
            self.delayer.restart.eq(self.restart),
            self.delayer.delay.eq(self.delay_value),
            self.delayer.input.eq(self.sum_value),
            delayed_sum.eq(self.delayer.output),
            current_sum_diff.eq(self.sum_value - delayed_sum),
            self.output.eq(current_sum_diff),
        ]
Esempio n. 3
0
    def __init__(self, width=14, N_points=16383, max_delay=16383):
        self.init_submodules(width, N_points, max_delay)
        peak_height_bit, x_data_length_bit = self.init_csr(N_points)
        self.init_inout_signals(width)

        # is the autolock actively trying to detect peaks? This is set to true
        # if lock is requested and once the ramp is at start
        watching = Signal()

        # the following signals are property of the peak that the autolock is
        # trying to detet right now
        self.current_instruction_idx = Signal(
            bits_for(AUTOLOCK_MAX_N_INSTRUCTIONS - 1))
        current_peak_height = Signal((peak_height_bit, True))
        abs_current_peak_height = Signal.like(current_peak_height)
        current_wait_for = Signal(x_data_length_bit)
        self.comb += [
            current_peak_height.eq(
                Array([
                    peak_height.storage for peak_height in self.peak_heights
                ])[self.current_instruction_idx]),
            current_wait_for.eq(
                Array([wait_for.storage for wait_for in self.wait_for
                       ])[self.current_instruction_idx]),
        ]

        # after detecting the last peak, how many cycles have passed?
        waited_for = Signal(bits_for(N_points))
        # after all peaks have been detected, how many cycles have passed?
        final_waited_for = Signal(bits_for(N_points))

        # this is the signal that's used for detecting peaks
        sum_diff = Signal((len(self.sum_diff_calculator.output), True))
        abs_sum_diff = Signal.like(sum_diff)
        self.comb += [
            self.sum_diff_calculator.writing_data_now.eq(
                self.writing_data_now),
            self.sum_diff_calculator.restart.eq(self.at_start),
            self.sum_diff_calculator.input.eq(self.input),
            self.sum_diff_calculator.delay_value.eq(self.time_scale.storage),
            sum_diff.eq(self.sum_diff_calculator.output),
        ]

        # has this signal at the moment the same sign as the peak we are looking
        # for?
        sign_equal = Signal()
        # is this signal higher than the peak we are looking for?
        over_threshold = Signal()
        # since detecting the previous peak, has enough time passed?
        waited_long_enough = Signal()
        # have we detected all peaks (and can turn on the lock)?
        all_instructions_triggered = Signal()

        self.comb += [
            sign_equal.eq((sum_diff > 0) == (current_peak_height > 0)),
            If(sum_diff >= 0,
               abs_sum_diff.eq(sum_diff)).Else(abs_sum_diff.eq(-1 * sum_diff)),
            If(
                current_peak_height >= 0,
                abs_current_peak_height.eq(current_peak_height),
            ).Else(abs_current_peak_height.eq(-1 * current_peak_height)),
            over_threshold.eq(abs_sum_diff >= abs_current_peak_height),
            waited_long_enough.eq(waited_for > current_wait_for),
            all_instructions_triggered.eq(
                self.current_instruction_idx >= self.N_instructions.storage),
            self.turn_on_lock.eq(
                all_instructions_triggered
                & (final_waited_for >= self.final_wait_time.storage)),
        ]

        self.sync += [
            If(
                self.at_start,
                waited_for.eq(0),
                # fpga robust autolock algorithm registeres trigger events delayed.
                # Therefore, we give it a head start for `final_waited_for`
                final_waited_for.eq(ROBUST_AUTOLOCK_FPGA_DELAY),
                self.current_instruction_idx.eq(0),
                If(self.request_lock, watching.eq(1)).Else(watching.eq(0)),
            ).Else(
                # not at start
                If(
                    ~self.request_lock,
                    # disable `watching` if `request_lock` was disabled while
                    # the ramp is running. This is important for slow scan
                    # speeds when disabling the autolock and enabling it again
                    # with different parameters. In this case we want to take
                    # care that we start watching at start.
                    watching.eq(0),
                ),
                If(
                    self.writing_data_now & ~all_instructions_triggered
                    & self.sweep_up,
                    If(
                        watching & sign_equal & over_threshold
                        & waited_long_enough,
                        self.current_instruction_idx.eq(
                            self.current_instruction_idx + 1),
                        waited_for.eq(0),
                    ).Else(waited_for.eq(waited_for + 1)),
                ),
                If(
                    self.writing_data_now & all_instructions_triggered
                    & self.sweep_up,
                    final_waited_for.eq(final_waited_for + 1),
                ),
            ),
        ]

        self.signal_out = []
        self.signal_in = []
        self.state_out = [
            watching,
            self.turn_on_lock,
            sign_equal,
            over_threshold,
            waited_long_enough,
        ]
        self.state_in = []