Beispiel #1
0
    def __init__(self,
                 fft_size,
                 avg_freq_axis=2,
                 avg_time_axis=1,
                 window_type='hanning',
                 fft_twiddle_bits=18,
                 window_bits=18,
                 dc_removal_len=1024):

        self._pyha_simulation_input_callback = NumpyToDataValid(
            dtype=default_complex)
        self.AVG_FREQ_AXIS = avg_freq_axis
        self.AVG_TIME_AXIS = avg_time_axis
        self.FFT_SIZE = fft_size
        self.WINDOW_TYPE = window_type

        # components
        self.dc_removal = DCRemoval(dc_removal_len)
        self.windower = Windower(fft_size,
                                 self.WINDOW_TYPE,
                                 coefficient_bits=window_bits)
        self.fft = R2SDF(fft_size, twiddle_bits=fft_twiddle_bits)
        self.power = FFTPower()
        self.dec = BitreversalFFTshiftAVGPool(fft_size, avg_freq_axis,
                                              avg_time_axis)
Beispiel #2
0
    def __init__(self,
                 fft_size,
                 twiddle_bits=9,
                 inverse=False,
                 input_ordering='natural'):
        self._pyha_simulation_input_callback = NumpyToDataValid(
            dtype=default_complex)
        self.INPUT_ORDERING = input_ordering
        self.INVERSE = inverse
        self.FFT_SIZE = fft_size
        self.N_STAGES = int(np.log2(fft_size))

        max_gain_control_stages = 10
        self.POST_GAIN_CONTROL = max(self.N_STAGES - max_gain_control_stages,
                                     0)

        self.stages = [
            StageR2SDF(self.FFT_SIZE,
                       i,
                       twiddle_bits,
                       inverse,
                       input_ordering,
                       allow_gain_control=i < max_gain_control_stages)
            for i in range(self.N_STAGES)
        ]

        self.output = DataValid(
            Complex(0, -self.POST_GAIN_CONTROL, -17 - self.POST_GAIN_CONTROL))
Beispiel #3
0
    def __init__(self, window_len, dtype=Sfix):
        self._pyha_simulation_input_callback = NumpyToDataValid(
            dtype=dtype.default())

        self.WINDOW_LEN = window_len
        self.BIT_GROWTH = int(np.log2(window_len))

        self.shr = ShiftRegister([dtype()] * self.WINDOW_LEN)
        self.acc = dtype(0.0, self.BIT_GROWTH, -17)

        self.output = DataValid(
            dtype(0, 0, -17,
                  round_style='round'))  # negative trend without rounding!
        self.start_counter = DownCounter(1)
Beispiel #4
0
    def __init__(self, window_len, dtype=Complex):
        assert window_len > 2
        self._pyha_simulation_input_callback = NumpyToDataValid(
            dtype=dtype.default())

        self.WINDOW_LEN = window_len
        self.averages = [
            MovingAverage(window_len, dtype),
            MovingAverage(window_len, dtype)
        ]

        # input must be delayed by group delay, we can use the SHR from the first averager to get the majority of the delay.
        self.delayed_input = ShiftRegister([dtype(0.0, 0, -17)] * 3)
        self.output = DataValid(dtype(0, 0, -17))
Beispiel #5
0
def test_nonstandard_input_size():
    input_power = 0.0001
    dut = FFTPower()

    dtype = Complex(0, -4, -21, round_style='round')

    dut._pyha_simulation_input_callback = NumpyToDataValid(dtype)
    inp = (np.random.uniform(-1, 1, size=64) +
           np.random.uniform(-1, 1, size=64) * 1j) * input_power
    inp = [complex(dtype(x)) for x in inp]
    sims = simulate(dut,
                    inp,
                    pipeline_flush='auto',
                    conversion_path='/tmp/pyha_output')
    assert sims_close(sims, rtol=1e-20, atol=1e-20)
Beispiel #6
0
    def __init__(self, window_length, window='hanning', coefficient_bits=18):
        self._pyha_simulation_input_callback = NumpyToDataValid(
            dtype=default_complex)
        self.WINDOW_LENGTH = window_length
        self.window_pure = get_window(window, window_length)
        self.WINDOW = [
            Sfix(x,
                 0,
                 -(coefficient_bits - 1),
                 round_style='round',
                 overflow_style='saturate') for x in self.window_pure
        ]

        self.output = DataValid(Complex(0, 0, -17, round_style='round'))
        self.index_counter = 1
        self.coef = self.WINDOW[0]
Beispiel #7
0
    def __init__(self):
        self._pyha_simulation_input_callback = NumpyToDataValid(dtype=Complex(
            0.0, 0, -11, overflow_style='saturate', round_style='round'))

        # components
        fft_size = 1024 * 8
        avg_freq_axis = 16
        avg_time_axis = 8
        window_type = 'hamming'
        fft_twiddle_bits = 8
        window_bits = 8
        dc_removal_len = 1024
        self.spect = Spectrogram(fft_size, avg_freq_axis, avg_time_axis,
                                 window_type, fft_twiddle_bits, window_bits,
                                 dc_removal_len)
        # TODO: could be unsigned!
        self.output = DataValid(
            Sfix(0.0, upper_bits=32)
        )  # no need to round because result is positive i.e. truncation = rounding
Beispiel #8
0
 def __init__(self):
     self._pyha_simulation_input_callback = NumpyToDataValid(
         dtype=default_complex)
     self.output = DataValid(Sfix(bits=36))
Beispiel #9
0
    def __init__(self,
                 global_fft_size,
                 stage_nr,
                 twiddle_bits=18,
                 inverse=False,
                 input_ordering='natural',
                 allow_gain_control=True):
        self._pyha_simulation_input_callback = NumpyToDataValid(
            dtype=default_complex)

        self.ALLOW_GAIN_CONTROL = allow_gain_control
        self.INVERSE = inverse
        self.GLOBAL_FFT_SIZE = global_fft_size
        self.STAGE_NR = stage_nr
        self.INPUT_ORDERING = input_ordering

        if input_ordering == 'bitreversed':
            self.IS_NATURAL_ORDER = False
            self.INPUT_STRIDE = 2**stage_nr  # distance from butterfly input a to b
            self.LOCAL_FFT_SIZE = global_fft_size // self.INPUT_STRIDE
            self.CONTROL_MASK = (self.LOCAL_FFT_SIZE - 1)

            twid = [
                W(i, self.LOCAL_FFT_SIZE)
                for i in range(self.LOCAL_FFT_SIZE // 2)
            ]
            twid = toggle_bit_reverse(twid)
            twid = np.roll(twid, 1, axis=0)
            self.TWIDDLES = [
                Complex(x,
                        0,
                        -(twiddle_bits - 1),
                        overflow_style='saturate',
                        round_style='round') for x in twid
            ]

        elif input_ordering == 'natural':
            self.IS_NATURAL_ORDER = True
            self.LOCAL_FFT_SIZE = global_fft_size // 2**stage_nr
            self.INPUT_STRIDE = self.LOCAL_FFT_SIZE // 2
            self.CONTROL_MASK = (self.INPUT_STRIDE - 1)

            self.TWIDDLES = [
                Complex(W(i, self.LOCAL_FFT_SIZE),
                        0,
                        -(twiddle_bits - 1),
                        overflow_style='saturate',
                        round_style='round') for i in range(self.INPUT_STRIDE)
            ]

        self.IS_TRIVIAL_MULTIPLIER = len(
            self.TWIDDLES) == 1  # mult by 1.0, useless
        self.shr = ShiftRegister([Complex() for _ in range(self.INPUT_STRIDE)])
        self.twiddle = self.TWIDDLES[0]
        self.stage1_out = Complex(0, 0, -17)
        self.stage2_out = Complex(0, 0, -17 - (twiddle_bits - 1))
        self.output_index = 0
        self.mode_delay = False
        self.control = 0  # replacing this with fixed-point counter saves no resources..

        self.out = DataValid(Complex(0, 0, -17, round_style='round'),
                             valid=False)
        self.start_counter = DownCounter(2 + self.INPUT_STRIDE)
Beispiel #10
0
    def __init__(self):
        self._pyha_simulation_input_callback = NumpyToDataValid(
            dtype=Complex(0.0, 0, -11, overflow_style='saturate', round_style='round'))

        self.dc_removal = DCRemoval(window_len=2048)
        self.out = DataValid(Complex(0, 0, -15, round_style='round'))