# Practical problems in down-converting via Hilbert filter

While teaching communication system to my students, I showed different ways to define the diagram block of the system responsible for transforming a bandpass signal, $$x(t) \in \mathbb{R}$$, into its lowpass equivalent signal, $$x_l(t)\in\mathbb{C}$$. This module is commonly called a down-converter (some authors ambiguously refer to it as demodulator).

Here are the most common approaches (sorry for the different notations, I am extracting these images from multiple sources):

### 3 Implementation via Hilbert filter (more called Hilbert transform)

You find the first two notations in the most elementary communication systems textbooks, while the third one is preferable in the most advanced ones. Nevertheless, all architectures must result in the same signal since their mathematical definitions agree.

I am used to implement and use the first two architectures. The system model, implemented in Simulink, has the following architecture (shown here is the complex-valued implementation):

where the FIR filter is a lowpass filter implemented in direct-form and using the equiripple design method. The real-part of the complex envelope agrees with the baseband signal, except for the delay that is naturally introduced by the filtering (there is no impairments, such as white noise or loss of synchronism):

However, out of curiosity, I implemented the third one. To my surprise, it didn't work well... The down-converter has the following architecture:

where the Hilbert filter is a built-in Simulink block that filters the input signal via Hilbert transform. Unfortunately, the complex envelope does not agree with the transmitted one (again, only the real part is shown).

• Is there a practical constrainment regarding the Hilbert transform?
• Has anyone here already down-converted signals via Hilbert transform?

Here is my Simulink model, if you are up for seeing it. Any feedback is welcome :)

• I suspect that one issue is that you have to compensate for the delay of the Hilbert filter and it's combination with the main signal Commented Nov 23, 2022 at 18:50
• @David That is right, I must do so. I just corrected here, but the result is not good yet :( Commented Nov 23, 2022 at 22:39

Having a look at the design of your Hilbert FIR filter, I don't think having +5 dB to -10 dB ripple on the magnitude response will give a good result. You might want to play with the design parameters and get a flatter response.

• How did you figger out how his Hilbert filter was designed? Commented Nov 23, 2022 at 19:36
• @robertbristow-johnson I opened up the SLX file (Simulink file) that was in the OP. Then I opened up the Hilbert block to see what the filter looked like. It looks like that.
– Peter K.
Commented Nov 23, 2022 at 19:51
• @PeterK. that is a good guess. I will investigate it and give a feedback soon. Commented Nov 23, 2022 at 22:08

I've found some interesting clues so far. Matlab have a command called hilbert() and I decided to compare the output of a getting on Simulink with this function.

If you pay attention, the Hilbert block

is actually a mask. If you click on the down arrow, you will see the coefficients of a FIR filter, which are the coefficients of the implemented Hilbert filter on Simulink. I saved these coefficients in the variable h.

In order to get rid of Simulink and go to Matlab command window, I collected the signals of my model

In addition, I collect the output of the complex-based implementation as well (this signal was called r_hat_n).

On command window, I got the data only:

r_n = reshape(out.r_n.Data(1:10e3),[], 1);
r_hat_n = reshape(out.r_hat_n.Data(1:10e3),[], 1);
r_hathilbert_n = reshape(out.r_hathilbert_n.Data(1:10e3),[], 1);


Then, the convolution of r_n and h confirmed that h is, indeed, that impulse response of Simulink block as both it matches with r_hathilbert_n:

By taking the low-pass equivalent via Hilbert transform in code-line, we get

t = out.tout(1:10e3);
r_hat2_n = (circshift(r_n,-length(h)) + 1i*hilbert(r_n)).*exp(-1i*2*pi*fc.*circshift(t,-length(h)));
plot([real(r_hat2_n) real(r_hat_n)])


Note that I took into account the delay of the Hilbert transform. It resembles the low-pass equivalent base-band, but with high-order interference...

The signal of code-line is rather different from the signal obtained in Simulink model, though...

plot([real(r_hat2_n) real(r_hathilbert_n)])


### My partial conclusions

• Hilbert filter differs from the hilbert() command line. Honestly, I only know the mathematical definition of the Hilbert transform, but I never went after the implementation aspects of it.
• The Hilbert transform seems to have implementation issues, probably due to its exotic transfer function (abrupt discontinuity on DC level and unlimited in frequency). Such limitation leads to a poor down-conversion.