Skip to content
Snippets Groups Projects
Commit cc64cacc authored by Pepping's avatar Pepping
Browse files

Initial commit

parent c555e2bc
No related branches found
No related tags found
No related merge requests found
#! /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()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment