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
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), ]
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 = []