From cc64cacc9e0a80b83d46f91ca0fc4f637ca32c4d Mon Sep 17 00:00:00 2001 From: Pepping <pepping> Date: Thu, 27 Aug 2015 11:47:04 +0000 Subject: [PATCH] Initial commit --- .../tc_apertif_unb1_set_bg.py | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 applications/apertif/designs/apertif_unb1_correlator/revisions/apertif_unb1_correlator_filter/tc_apertif_unb1_set_bg.py diff --git a/applications/apertif/designs/apertif_unb1_correlator/revisions/apertif_unb1_correlator_filter/tc_apertif_unb1_set_bg.py b/applications/apertif/designs/apertif_unb1_correlator/revisions/apertif_unb1_correlator_filter/tc_apertif_unb1_set_bg.py new file mode 100644 index 0000000000..ef064e9d86 --- /dev/null +++ b/applications/apertif/designs/apertif_unb1_correlator/revisions/apertif_unb1_correlator_filter/tc_apertif_unb1_set_bg.py @@ -0,0 +1,154 @@ +#! /usr/bin/env python +############################################################################### +# +# Copyright (C) 2015 +# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################### + +# Purpose: +# . Create lists of waveform samples and write them to the block gen RAM. +# Description: +# . Design apertif_unb1_fn_bf_emu uses 4 block generators to emulate the output +# of 4 BF units; +# . Each of the 4 output streams carries 2 interleaved signals; +# . Each of these 8 signals consists of 64 timesamples (stored in RAM) that are +# looped through by the block generator; +# . Each BG stream contains 2*64 = 128 timesamples; +# . This TC overwrites the default block gen RAM contents. +# . All 4*2=8 BG output signals will be the same. +# Usage: +# . python tc_apertif_unb1_fn_bf_emu.py --unb 3 --fn 0 -r [channels]*1000 -n [phase shift] +# . Pass -s noplot to disable plotting. +# Example: +# . python tc_apertif_unb1_fn_bf_emu.py --unb 3 --fn 0 -r 3000,5000,7000,34000,60000 -n 0 + +import test_case +import node_io +import numpy as np +import pi_diag_block_gen +from common import * +import matplotlib +matplotlib.use('TkAgg') +import matplotlib.pyplot as plt +from scipy.fftpack import fft,ifft, fftfreq, fftshift + +NOF_STREAMS = 1 # emulates 4 BF units +NOF_WORDS_PER_SIGNAL = 64 +NOF_RAM_WORDS_PER_STREAM = 2*NOF_WORDS_PER_SIGNAL # 128 words per BG stream RAM + +COMPLEX_WIDTH = 8 #8b real + 8b imag +AMPL_MAX = 127 # 8b signed data so a range of -127..127 + +############################################################################### +# Instantiate TC, IO, BG instance. +############################################################################### +tc = test_case.Testcase('TC - ', '') +io = node_io.NodeIO(tc.nodeImages, tc.base_ip) +#bg = pi_diag_block_gen.PiDiagBlockGen(tc, io, NOF_STREAMS, NOF_RAM_WORDS_PER_STREAM) +bg = pi_diag_block_gen.PiDiagBlockGen(tc, io, NOF_STREAMS, NOF_RAM_WORDS_PER_STREAM, instanceName='PROC') + +bg.write_block_gen_settings(128, 16, 64, 0, 127, 42) + + +############################################################################### +# Assign the user passed arguments -r and -n +# . CHANNELS (-r): +# . Define which channels are present in the BG output signal +# . A sub-signal is created for each channel number (a.k.a. bin number) defined +# in CHANNELS. +# . All sub-signals are added yielding our composite signal +# . PHASE_SHIFT_DEG (-n): +# . Pass a phase shift in degrees that is applied to each channel signal +############################################################################### +CHANNELS = tc.gpNumbers # -r argument +PHASE_SHIFT_DEG = tc.number # -n argument +NOPLOT=tc.gpString=='noplot' # True if -s noplot is passed + +for cnt in range(len(CHANNELS)): + CHANNELS[cnt] = float(CHANNELS[cnt])/1000 + +############################################################################### +# Create the channel sub-signals and the resulting composite signal +############################################################################### + +# Sample spacing +T = 1.0 / NOF_WORDS_PER_SIGNAL +x = np.linspace(0.0, NOF_WORDS_PER_SIGNAL*T, NOF_WORDS_PER_SIGNAL) +x = np.linspace(0.0, 1-T, num = NOF_WORDS_PER_SIGNAL) + +# Create a list of sub-signals; one per channel +channel_signals = [] +NOF_CHANNELS = len(CHANNELS) +for bin_nr in CHANNELS: + phase_shift_rad = phase_shift_rad = math.radians(PHASE_SHIFT_DEG) + + # Make sure the summed amplitude of all channels does not exceed AMPL_MAX + ampl=AMPL_MAX/NOF_CHANNELS + # Create the signal in this channel and append to list + channel_signal = ampl * np.exp( bin_nr*1.j*(2.0*np.pi*x+(phase_shift_rad/bin_nr)) ) + channel_signals.append( channel_signal ) + +# Adding all channel sub-signals yields our composite signal +composite_signal=np.sum(channel_signals, axis=0) + +############################################################################### +# Plot our composite signal + FFT +# . This step is optional and not required to overwrite the RAM contents. +############################################################################### +if NOPLOT==False: + # Convert the float values to 8-bit complex + s_bits = [] + for fword in composite_signal: + re_signed = to_signed(fword.real, COMPLEX_WIDTH) + im_signed = to_signed(fword.imag, COMPLEX_WIDTH) + s_bits.append( complex(re_signed, im_signed) ) + + # Define our axes and plot the signal + s = np.array(s_bits) + t = range(NOF_WORDS_PER_SIGNAL) + plt.plot(t, s.real, 'b-', t, s.imag, 'r--') + plt.legend(('real', 'imaginary')) + plt.show() + + # Calculate and plot the FFT + yf = fft(s) + xf = fftfreq(NOF_WORDS_PER_SIGNAL, T) + xf = range(NOF_WORDS_PER_SIGNAL) + xf = fftshift(xf) + yplot = fftshift(yf) + plt.bar(xf, 1.0/NOF_WORDS_PER_SIGNAL * np.abs(yplot)) + plt.grid() + plt.show() + +############################################################################### +# Prepare the data to be written to RAM +############################################################################### +# Convert complex floats to concatenated integers +composite_signal_concat = concat_complex(composite_signal, COMPLEX_WIDTH) + +# Interleave the 64-sample composite signal into 2*64=128 samples +# . [0..63] -> [0,0,1,1,..63,63] +composite_signal_concat_inter = interleave([composite_signal_concat,composite_signal_concat]) + +############################################################################### +# Write the 128-word list to BG RAMs +############################################################################### +for STREAM_INDEX in range(NOF_STREAMS): + bg.write_waveform_ram(composite_signal_concat_inter, STREAM_INDEX) + +bg.write_enable() -- GitLab