Sunday, 26 February 2017
As I have mentioned before I have been interested in the digital pre-distortion of
Digital TV signals for some time. I have now finally got around to looking at
this problem again.
After a literature search I settled on using the polynomial filter model with memory
to do the pre-distortion. The plan is to use a LimeSDR to do the actual modulation and
a CUDA graphics card to do the maths.
The diagram above is actually quite clever, it uses the input z(n) and output y(n) of the PA
to train a filter to produce the inverse of the PA characteristic. Then it takes the signal to
be transmitted x(n) and passes it through this filter to pre-distort it. The PA then distorts
it back into a signal that looks like the original drive signal x(n).
The filter is not a normal FIR filter whose taps multiply and accumulate a series of
samples, instead the FIR filter is fed with a power series
x(0) x(0)*|x(0)| x(0)*|x(0)|^2 ... x(0)*|x(0)|^N etc
As the PA's characteristic will change slowly over time it should only be necessary to
update the filter coefficients on an infrequent basis. This is good because it means the
very intensive Minimum Mean Square Error (MMSE) estimator does not need
to run all the time.
I plan to use QR Decomposition followed by backwards substitution to estimate the filter
tap values. Fortunately clever people have already written a library to do this for me.
NVIDIA have a library called cuSolver that does it, cuSolver in turn is based on
LAPACK. NVIDIA have very kindly given an example in Appendix C.1 of their toolkit
documentation showing exactly how to do this. The example has to be modified to
deal with complex numbers but that change is trivial.
It may well be better to run the MMSE estimator on the CPU using LAPACK, rather
than on the GPU as for small matrices the CPU is faster. It is only when the matrices
become large that the GPU excels.
The beauty of the LimeSDR is that because of it's USB3 interface there is plenty of
bandwidth available. This is needed because the DPD needs to see about 7 times the
bandwidth of the transmitted signal if it is going to reduce the 3rd, 5th and 7th order
IMD products (shoulders to you DATVers).
Hopefully by doing all this on a PC host rather than using an FPGA I should be able to
get something running fairly quickly. Moving it to an FPGA can come later when I get
some idea of how well it works.
There are a lot of subtleties to this and I have just glossed over it as I didn't want people
to get too bogged down in the maths.
If you are interested in more detail please have a look here Keysight DPD
Wish me luck!
Monday, 12 December 2016
|Icom RS-BA1 Remote Control Software|
|Icom IC7100 rear panel|
The workshop has minimal heating so it does not get used during the winter months.
To remedy this situation I bought a used IC7100 on eBay from W&S. I already had
an Ethernet cable going from the house to the workshop, so it was fully networked.
I had an old Belkin Ethernet to USB hub which I connected to the workshop
network and then plugged the USB2 port on the IC7100 into it. Also connected I
have an LDG AT200PC. The AT200PC is no longer made but has an RS232
control port which was ideal for this application. The 2m/70 cms port on the IC7100
is connected to a Diamond Diplexor which splits the output so it can connect to a
2m and 70 cms yagi. The HF port of the radio goes into the LDG which as well as
being an antenna tuner also is an antenna switch which I can control remotely allowing
me to switch between an HF antenna and a 6m/4m beam. The ATU will be controlled
by a simple Windows dialog application I am writing (the app can currently only read
the version number of the ATU's firmware but that shows it has comms).
Initially the Belkin would not work with my Windows 10 machine
(it worked fine on Win7). After some Googling I found that while
Bekin don't support it on Windows 10 (their tec support said it could not be done)
it is possible to use under Win10 by downloading updated drivers from the
chip manufacturers website (Silex Technology).
Now using Icom's RS-BA1 remote software I can fully control my radio and use PC
connected headphones and microphone with it from the warmth of the main house.
To the RS-BA1 software the radio appears to be locally connected via USB2.
To rotate the VHF/UHF antennas I used my homebrew Arduino based rotator
controller. It appears as a command line application on my desktop and allows
me either to input a bearing or a QRA locator. I have blogged about the rotator
I also have plans to add a multi-mode TNC to the set-up so I can use legacy modes
like Pactor and Amtor remotely. There are still some spare USB2 sockets left on the
Digital Beam Forming on 70 cms
|70 cms Turnstile antenna|
My current thoughts are to use 16 of these antennas connected to phase/time
locked Lime SDRs to produce a Digital Beam Forming demonstrator. This will
allow the tracking of multiple Cubesats / balloons simultaneously. Unlike a conventional
antenna which can only point in one direction at a time this can have multiple
receiver channels each pointing at a different satellite. It can also steer nulls in the
radiation patterns to null out interferers on each of the beams (It is only maths).
Ideally I would like many more than 16 antennas but there is a limit to the
space and money I have available for this project.
The signal processing will be done using CUDA C and NVIDIA graphics cards
allowing for potentially hundreds of independent beams. I am happy to collaborate
with others on this project.
So that is it for this month. I hope you enjoyed my thoughts.
Friday, 14 October 2016
For those that have not seen it here is the talk I gave at CAT16. I also have it on my
YouTube channel but the BATC version includes the Q&A at the end.
Since that talk was given I have been adding some more features to the program.
I have added better filtering in the FPGA for low symbol rates on DVB-S2,
unfortunately to make that change I had to remove support for the tighter roll-off
filters as there was no room left in the FPGA.
I plan to add a couple of more features to the program in the next couple of weeks
then put the software into maintenance mode so I can work on other projects.
As some of you know my entry was selected for the latest
LimeSDR design challenge
The last few days I have been researching how actually to implement an RF
channel simulator. I now have some ideas on how to generate random
numbers and how to give them a normal distribution. I also now
know the difference between Rayleigh and a Rician fading channels.
The first is a channel where there is no direct path
(for example an HF ionospheric channel) and the latter is where there is a
direct line of sight path as well as other reflected paths. The Rician
channel is more like the type of channels we see with terrestrial DATV.
Originally I hoped to do most of the maths in the FPGA but now I am beginning to
think a better solution might be to move a lot of the maths into the host and do the
hard real time stuff on the FPGA. There appears to be a lot of log, sine and cosine
operations involved in producing the fading models and while Altera provide mega
functions to do these things they consume quite a lot of space and valuable multipliers.
At the end of the day what will be needed will be a trade-off between precision,
bandwidth, number of paths and ease of development.
It is an interesting project never the less and should make use of some of the maths
I learn't when I took some O.U courses a few years ago. At least I can
understand most of the concepts that are described in the various internet articles
I have found on the subject. I am sure if I get really stuck I can get help with the
maths. Anyone that helps will get a credit on the project! I may have an A level
in maths, studied Electronics at University and taken some O.U refresher courses
but that doesn't make me an expert.
I plan first to simply produce software than can set the S/N of a signal. That is not
actually as simple as it first seems but it will be a start.
Thursday, 8 September 2016
I now have a decoder for the bi-orthogonal code that S2 uses to
encode the Mode and Code field (MODCOD). Some Googling showed
that the way to do this is to multiply the received codeword by a
Hadamard matrix. You use the index of the maximum entry in the result
and it's sign to give you the received MODCOD value.
The Original S2 protocol used a (32,6) code and this works fine with the
Hadamard approach. S2X has extended this to (32,7) and it is slightly more
tricky to decode. What I have done is to decode it as normal save the maximum
value then subtract the extra line in the S2X generator matrix from the received
codeword then re-run the matrix multiply again. That way I can tell if the extra
bit in the S2X code is a 1 or a 0 by selecting which of the two matrix multiplies
results in the largest maximum value. If the bit is a 1 it means the waveform
conforms to S2X and if it is a zero then it is S2 so the receiver can handle
both standards. There is another bit that is differentially encoded in the
codeword as well which has to be detected and remove before the
bi-orthogonal decode can occur but that is fairly trivial to do.
I have tested it using a modified version of my S2 transmitter C++ class
so I know it is working (and correcting errors).
I noticed on Twitter yesterday that there is now a proposal to launch a
lunar orbiting Cubesat in 2018 Heimdallr Lunar Cubesat and that they are
proposing that a S2X 1/5 code be used as part of the experiment.
The proposal is for a 25 kbps data rate. If this makes it off the launchpad
then it will be a very interesting thing to listen for and I should have the
software working long before then.
I hope to make my S2 decoder scalable so that it can be used on everything
from a TK1 single board computer up to a high end graphics card. Having a
portable TK1 based solution would be ideal but if that fails then there will be
one of my many GPU based PCs to fall back on. The more GPU power
available the closer to the theoretical performance I can achieve so there
is room for a trade off.
I love challenging (for me) projects!
Saturday, 27 August 2016
|NVIDIA Jetson TK1|
ago as you can see in the photo above. The red box is a Hammond enclosure.
I mounted the Jetson on a piece of 1.6 mm Aluminium sheet and below that I
added an SSD.
The Jetson has a 192 Core GPU as well as USB3 and Gigabit Ethernet so may
well make a nice basis for a portable computer to use with one of the LimeSDRs
I have on order. Last time I played with it I had difficulty in getting the expected
USB3 performance out of it. By default it sets the USB3 port to USB2 only (daft).
I have done some work on the DVB-S2 receiver software since I last posted.
I managed to write a BCH hard decision decoder. So far I have only tested it with
one of the S2 Normal frame formats but it should work on all the various formats.
The Short frames use slightly different generator polynomials so some extra work
will have to be done to support that. I based it on the RS decoder I wrote a while
I have also moved the syndrome calculation code to run on the CUDA device, in my
case that is a GTX980 TI.
The reason for doing that is the syndrome calculation has to run on every received
frame to check to see if there are any errors. If no errors are detected further
processing is not required. The Host communicates with the Device (GPU)
via PCI and that is very time consuming so it is best to make as few memory
transfers between the GPU and host as possible. The syndromes are quite small
compared to the data frame so the overhead is not very great.
The BCH decoder is implement as a predictor so is not easy to implement using
parallelism, well at least not for me. So it makes more sense to do it on the host.
One thing I learned today is that if the GPU code takes more than a couple of
seconds to run then Windows times out and resets the graphics card. This can be
avoided by either changing a registry entry or by breaking the code up into smaller
tasks. There is a lot for me to learn. The different types of memory on the GPU
and how you use them is also something that needs careful attention to when
I am not sure how much time I am going to be able to spend on this little project in
the next few weeks as I have been asked to create a video to go with my CAT16
talk at the end of September and that is going to be time consuming no doubt.
That is it for now.......
Sunday, 14 August 2016
After the AMSAT-UK conference it became obvious that DVB-S2 would take
a staring role in the new Es'hailsat 2 Satellite (which apparently is named after the
Arabic name for the star we know as Canopus). The satellite is now scheduled for
a Q3 2017 Launch.
To this end I have ported my Linux DVB-S2 implementation over to Windows.
The actual implementation is a C++ class and runs almost entirely on the host.
This means it uses more CPU than the DVB-S implementation does. I am still
ironing out bugs, by that I mean stuff I have working fine, when given to others
to test is not quite as successful.
While we have receiver support for normal symbol rates it may be a while before
we have RBTV (Reduced Bandwidth TV) support in place. Still we have a year
to get this all up and running.
I have also started a new challenge and that is the development of a GPU based
DVB-S2 receiver. I have done some similar work in the past but not at these
high symbol rates. DVB-S2 was specifically designed to take advantage of
parallel processing. I have been looking for an excuse to use the 2816 cores on
my graphics GTX 980 TI card. Originally I had planned on just implementing
the LDPC decoder on the GPU using the "Belief Propagation" algorithm but
bit by bit it is looking like most of the modem will in fact be on the GPU as
it is a better fit than on the CPU.
After having struggled with Graphics Drivers when installing the NVIDIA
Cuda 7.5 toolkit on my Linux machine it came as a relief when I found how
simple the Windows Toolkit was to install. My only mistake was not installing
Visual Studio 2013 before the toolkit. The current Toolkit does not support
the 2015 edition I was using for development.
The GPU modem is more an academic exercise than something that would be
practical for most people.
I am currently looking at ways to estimate the noise variance on the
communications channel as this is required to calculate the Log Likelyhood
Ratios LLRs which are required for the BP algorithm.
This is really pushing my maths skills. Wish me luck!
Saturday, 11 June 2016
Above is the EVM measurement taken of DATV-Express using an Agilent E4406A.
It is of an unmodified board with no IQ offset applied. Some of the error is due to
a symbol rate mismatch between Express and the test gear. Express derives it's
symbol rate from a cheap xtal oscillator (the one used for the USB2 clock).
When generating the same waveform using an Agilent E4437B using a common
reference the EVM is only a couple of percent better.
The tests were done using the W-CDMA option that allows QPSK EVM
measurements to be taken provided the symbol rate is around
4 MSymbols per second.
EVM (%) = √(Perror/Pref) x 100
Where Perror is the power of the error vector and Pref is the power of the ideal reference.