EmbDev.net

Forum: FPGA, VHDL & Verilog FPGA F.M Radio


von Milruwan P. (Company: Student) (milprasad)


Attached files:

Rate this post
useful
not useful
Sir, I am doing a project on DSP based fm receiver for my final year 
project.
I want to demodulate the IF signal from the receiver and get the FM 
multiplex signal. I am using zero crossing as the demodulation method.
1
always @ (posedge sclk)
2
begin
3
data_now<=adc_dat;
4
if((((data_prv<8'd100 )&&(data_now>8'd100))||((data_now<8'd100)&&(data_prv>8'd100))))
5
6
begin
7
data_save<=timer2;
8
dac_dat<=data_save;
9
data_prv<=data_now;
10
cnt_en<=1'b0;
11
#2 cnt_en<=1'b1;
12
end
13
14
end
According to the zero crossing algorithm I except a specific value for 
specific frequency but this will give a ramp value, continuously varying 
value for the output. I attach the oscilloscope view of the input and 
the output(yellow-input blue-output). I want to get a constant value for 
specific frequency. Please help me regarding this matter.

von Thomas R. (Company: abaxor engineering) (abaxor)


Rate this post
useful
not useful
Hi Milruwan,

I miss the reset of timer2 if the condition

((((data_prv<8'd100 
)&&(data_now>8'd100))||((data_now<8'd100)&&(data_prv>8'd100))))


becomes true. Therefore data_save advances as timer2. You could use the 
difference between timer2 and data_save, but then you run in trouble if 
timer2 wraps.

Furthermore you will experience difficulties if data_save varies around 
8. Don't forget real signals are noisy, apply a hysteresis, only 
filtering will not be sufficient.

Tom

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
I deleted the short and useless discussion about lazy pupils. But in 
fact:

Milruwan Perera wrote:
> I want to get a constant value for specific frequency.
With a litte bit of thinking and analyzing anybody can easily recognize, 
that the steps (and therefore the difference) are the same. And now 
there are two possible solutions:
calculate the difference between two steps and use that difference as a 
result
OR
reset the counter with each (rising) edge

BTW:
Instead of building a monster comparator like this
1
((((data_prv<8'd100 )&&(data_now>8'd100))||((data_now<8'd100)&&(data_prv>8'd100))))
a more experienced electrician would say: the most easiest to see a 
zero-crossing in a signal way would be to look for the sign bit, which 
is usually the leftmost bit in a signed integer. Then only two bits are 
necessary to recongize the crossing: the actual sign bit and the 
previous sign bit. And the whole comparator will result a 2 input XOR...

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Hi, Tom
Thanks for your valuable reply.

This is the code. If you have time please go through it and let me know 
where I have went wrong.
1
module Zero_crossing6(sclk,adc_cs,adc_clk,adc_dat,dac_clk,dac_dat,led,out);
2
3
input sclk;
4
output adc_clk,adc_cs,dac_clk,out;
5
input [7:0] adc_dat;
6
output [7:0] dac_dat;
7
output [7:0] led;
8
9
wire sclk;
10
wire adc_clk,adc_cs,dac_clk;
11
wire [7:0] adc_dat;
12
reg [7:0] dac_dat;
13
reg [7:0] led;
14
reg [3:0] count=1'b0;
15
reg [7:0] adc_store;
16
17
18
reg [7:0] data_now;
19
reg [7:0] data_prv;
20
reg [7:0] data_save;
21
reg cnt_en;
22
23
reg [25:0] timer3;
24
always @(posedge sclk)
25
begin
26
timer3<=timer3+1'b1;
27
if(timer3[25]==1'b1)
28
begin
29
timer3<=1'b0;
30
led<=data_save;
31
end
32
end
33
34
always @ (posedge sclk)
35
begin
36
data_now<=adc_dat;
37
if((((data_prv<8'd100 )&&(data_now>8'd100))||((data_now<8'd100)&&(data_prv>8'd100))))
38
39
begin
40
data_save<=timer2;
41
dac_dat<=data_save;
42
data_prv<=data_now;
43
cnt_en<=1'b0;
44
#2 cnt_en<=1'b1;
45
end
46
47
end
48
49
reg out=1'b0;
50
reg [3:0]timer1;
51
reg [7:0]timer2;
52
wire tick = (timer1[3]==1'b1);
53
always @ (posedge sclk)
54
begin
55
timer1<=timer1+1'b1;
56
if(tick)
57
begin
58
out<=~out;
59
timer1<=1'b0;
60
if(cnt_en==1'b1)
61
timer2<=timer2+1'b1;
62
else
63
timer2<=1'b0;
64
end
65
end
66
67
always @ (posedge sclk)
68
begin
69
count <= count + 1'b1;
70
end
71
72
always @ (posedge sclk)
73
begin
74
adc_store <= adc_dat;
75
end
76
77
78
assign adc_cs = 1'b0;
79
assign adc_clk=count[3];
80
assign dac_clk=count[3];
81
//assign dac_dat=adc_dat;
82
83
84
endmodule

Thank you.
Milruwan

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Hi..  Lothar Miller,

Thanks for your valuable reply.

I am getting the IF signal through ADC. Then how can I detect the rising 
edge through 8bit samples (values from 0 to 255) that's why I use that 
monster comparator. I observe that the mid value of the signal is 100.

1
((((data_prv<8'd100 )&&(data_now>8'd100))||((data_now<8'd100)&&(data_prv>8'd100))))

like to know your opinion.

Milruwan

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Milruwan Perera wrote:
> This is the code.
And whats the problem with it?

> If you have time please go through it and
> let me know where I have went wrong.
Its fairly annoying to scan through an ugly formated code snippet with 
no hint what it should do and what it does.
Why du you start each line of code at the leftmost position of a line?
That makes the code extremely unreadable: no way to see which end 
belongs to which begin...

Milruwan Perera wrote:
> I am getting the IF signal through ADC. Then how can I detect the rising
> edge through 8bit samples (values from 0 to 255) that's why I use that
> monster comparator. I observe that the mid value of the signal is 100.
I (as a more binary person) would take the step from 127 (=01111111) to 
128 (=10000000) as the mid value (in fact with a FM signal that doesn't 
matter). And now have a look for the "sign bit" (aka. MSB and aka. the 
leftmost bit) of those two numbers: with 127 it is '0'. After crossing 
the "zero-line" it is 128 and therefore '1'...

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Lothar Miller wrote:
> And whats the problem with it?

The problem is I don't get a constant value for specific frequency 
through zero crossing detection. It is clearly shown in the picture I 
had attached in the first conversation.

eg: assume for 10Khz zero crossing detected value should be 200 counts,
    but  the zero crossing detected value vary from 0 to 200 
continuously.

Lothar Miller wrote:
>> If you have time please go through it and
>> let me know where I have went wrong.
> Its fairly annoying to scan through a ugly formated code snippet with no
> hint what it should do and what it does.
> Why du you start each line of code at the leftmost position of a line?
> That makes the code extremely unreadable: no way to see which end
> belongs to which begin...

Thanks for telling this. I wrote those codes in order to test the code 
is working for zero crossings. Now onwards I will write my every code in 
a readable format.

Here is the full code used for zero crossing detection.
1
// zero_crossing detection code
2
// ***********************************************************************************************
3
reg [7:0] data_now;
4
reg [7:0] data_prv;
5
reg [7:0] data_save;
6
reg cnt_en;
7
8
always @ (posedge sclk)
9
  begin
10
  data_now<=adc_dat;
11
    if((((data_prv<8'd100 )&&(data_now>8'd100))||((data_now<8'd100)&&(data_prv>8'd100))))
12
13
      begin
14
      data_save<=timer2;
15
      dac_dat<=data_save;
16
      data_prv<=data_now;
17
      cnt_en<=1'b0;
18
      #2 cnt_en<=1'b1;
19
      end
20
end
21
//*************************************************************************************************
22
23
24
//Timer2 is the counter used to count the number of zero_crossing
25
// Timer1 sets the counting rate of the timer2
26
//*************************************************************************************************
27
reg out=1'b0;
28
reg [3:0]timer1;
29
reg [7:0]timer2;
30
wire tick = (timer1[3]==1'b1);
31
32
always @ (posedge sclk)
33
begin
34
  timer1<=timer1+1'b1;
35
  if(tick)
36
    begin
37
      out<=~out;
38
      timer1<=1'b0;
39
        if(cnt_en==1'b1)
40
          timer2<=timer2+1'b1;
41
        else
42
          timer2<=1'b0;
43
    end
44
end
45
//*************************************************************************************************

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Milruwan Perera wrote:
1
     cnt_en<=1'b0; 
2
     #2 cnt_en<=1'b1;
I'm a VHDL man, but this here seems to be some kind of "wait" statement.
Maybe this is simply not synthesizeable and therefore cnt_en results 
in a static value of 1'b1 on your FPGA?

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Lothar Miller,
Can you Please suggest me a method to to detect zero crossings in an 
effective way.(In pseudo code or your comfortable VHDL code). It will be 
really helpful to me.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
> Can you Please suggest me a method
Did you at least think one second about my question?

>  It will be really helpful to me.
You have already a solution, you just have to get around that little 
problem...

As already said: I'm doing VHDL and I'm pretty unknown to Verilog, but 
taking your code I would try it by changing it this way:
1
  
2
  :
3
  begin
4
     data_now<=adc_dat;
5
     if((((data_prv<8'd100 )&&(data_now>8'd100))||((data_now<8'd100)&&(data_prv>8'd100))))
6
     begin
7
        data_save<=timer2;
8
        dac_dat<=data_save;
9
        data_prv<=data_now;
10
        cnt_en<=1'b0;
11
     else
12
        cnt_en<=1'b1;
13
     end
14
  end
15
  :
Try it and if it works: think about it...

von Milruwan P. (Company: Student) (milprasad)


Attached files:

Rate this post
useful
not useful
The following code is not resetting at when timer_reset==1'b1 ,Here I 
attached the modelsim simulation result. I need to know where I went 
wrong. Please help me.
1
module Zero_crossing8 (sclk,sig_in,result);
2
3
input sclk,sig_in;
4
output [7:0] result;
5
6
reg [7:0] result=8'b0;
7
reg [7:0] timer_val=8'b0;
8
reg timer_reset=1'b0;
9
10
11
always @ (posedge sclk)
12
begin
13
  if(timer_reset==1'b1)
14
    #80 timer_val<=8'b0;
15
  else
16
    timer_val<=timer_val+1'b1;
17
end
18
19
20
always @ (posedge sig_in)
21
begin
22
  #100 result<=timer_val;
23
  #5000 timer_reset<=1'b1;
24
  #4000 timer_reset<=1'b0;
25
end
26
27
endmodule

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Lothar Miller,
Can you please write a simple VHDL code to detect zero crossings(Similar 
as the code in my previous post(Posted on: 2013-07-22 21:54)).The code I 
wrote is not resetting the value of result register. I do not have a 
VHDL code writing experience. So help me about this matter.

von Hmm (Guest)


Rate this post
useful
not useful
The solution was given as well as a hint about non-synthesizable code.
Please consider that, instead of asking for somebody else doing it for 
you.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Hmm wrote:
> a hint about non-synthesizable code.
Once more: forget about things like
#80
#100
#5000
#4000
in code that you want to run on hardware!
These "delays" are only good for simulation!

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Attached files:

Rate this post
useful
not useful
Milruwan Perera wrote:
> Can you please write a simple VHDL code to detect zero crossings
Here you are, a short fingers excercise in the lunch break. Attached is 
also the waveform of a testbench that modulates a sine which is handed 
over to input. Then this FM sine is demodulated and results in the 
output. There you see some granularity due to the used sampling 
frequency...

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Lothar Miller,

Thanks for your valuable work.
I will try to understand this code and write it in Verilog. Once again 
thank you so much....

Milruwan

von Student (Guest)


Rate this post
useful
not useful
Why do you think others write their thesis on there own??
Waiting for the young talent to appear in my department...

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Lothar Miller,
What is the simulator you are using? I think it is not modelsim. How do 
you apply those Analog signal data to the testbench? I also wrote a 
similar code Verilog but I don't know how to give an analog signal as 
input and simulate in modelsim. May I know the steps you went through to 
apply a Analog signal in.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Attached files:

Rate this post
useful
not useful
Milruwan Perera wrote:
> Lothar Miller, What is the simulator you are using? I think it is not
> modelsim.
No, that was Active HDL from Aldec. But you can do that also with 
ModelSim also.

> How do you apply those Analog signal data to the testbench?
Why did I know, that this question will arise?   ;-)
I calculate the modulated fm sine. The output of this calculation is a 8 
bit vector. This vector is input to the fm demodulator. And the analog 
waveform is just an analog representation of that vectors value. You can 
change that easily in the properties of the specific vectors waveform. 
Here it is shown for ModelSim:
http://forums.xilinx.com/t5/General-Technical-Discussion/how-to-see-output-as-sine-wave-in-modelsim/td-p/65238

> I also wrote a similar code Verilog but I don't know how to give an analog
> signal as input and simulate in modelsim. May I know the steps you went
> through to apply a Analog signal in.
1. calculate the (low frequency) modulation
2. calc the carrier frequency and modulate it with the result of 1.
3. scale the result to the desired vector
See the attached testbench.

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Hi, I have some how manage to detect the zero crossings, but the problem 
is it is not accurate to detect small frequency deviations, due to the 
oscillator clock frequency. I need to know is it possible to change the 
crystal to 100MHz? I am using the Altera EP2C8Q208C8 Fpga chip. I went 
several times through the datasheet to determine the Oscillator 
frequency, but I was not able.

Is Altera EP2C8Q208C8 Fpga chip can be driven with 100MHz crystal?

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
The chip can be driven with more than 100MHz.

But: can your design be driven with 100MHz after it is synthesised for 
this chip?

A way to find that out is to set a constraint for the designs clock...

von jjhhzzuu (Guest)


Rate this post
useful
not useful
Milruwan Perera wrote:
> Is Altera EP2C8Q208C8 Fpga chip can be driven with 100MHz crystal?

You obviously don't know anything about FPGAs and/or toolchains for 
synthesis ...

Why did you choose a project you impossibly can do on your own?

von Tehehe (Guest)


Rate this post
useful
not useful

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
In this project I need to take the IF signal and demodulate it in an 
FPGA. In order to do the demodulation I need to amplify the IF signal 
and get in to ADC resolution range (0V to 5V). Received IF signal 
amplitude is 5mv and I need to amplify it to 5V. I ordered  THS3202 dual 
current-feedback amplifier for the amplification process. But the 
amplified output was a noisy signal ( I applied 10.7MHz  5mv sine wave 
from the signal generator and try to amplify it to 1V).

1)  Can this be used to amplify 10.7MHz signal ?

2) Please suggest me a method to amplify the IF signal to 5V range?

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Milruwan Perera wrote:
>  I applied 10.7MHz 5mv sine wave
What is this 5mV? RMS? Peak? Peak to peak?

> But the amplified output was a noisy signal
To amplify a signal by 1000 is a very demanding job. Decoupling of the 
amplifiers stages (if there hopefully is more than one) is the primary 
task. Can you show your schematics and post a picture of your assembly?

2) Please suggest me a method to amplify the IF signal to 5V range?
Read and understand AppNotes and UserGuides. Amplify it in two well 
decoupled stages. Have a look for a low impedance design and a good 
layout. Keep in mind that those GHz amps are little beasts...
See the decoupling there page 11:
http://www.ti.com/lit/an/slyt102/slyt102.pdf
And the sample layout on the last pages there:
http://www.ti.com/lit/ug/slou148/slou148.pdf

BTW:
If you are doing cross posts, then at least inform us and them about 
that fact. And don't use either one as a "fall back option"...

BTW2:
> eilert
> 07-21-2013 11:32 PM
>  #2 cnt_en<=1'b1;
> I don't think this will work in synthesis.
And you posted on: 2013-07-22 11:10
> cnt_en<=1'b0;
>    #2 cnt_en<=1'b1;
That leads me to one question (I already asked):
Do you at least read the answers given to you?

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Lothar Miller wrote:
> If you are doing cross posts, then at least inform us and them about
> that fact.

Sorry for cross posting. I have done this in order to get a better 
solution for my problem.

von Milruwan P. (Company: Student) (milprasad)



Rate this post
useful
not useful
Hi.. all these days I am designing the filters for my radio receiver 
project. I used Matlab HDL coder for implementing the filters.

filter specification is shown below
1
// Filter Specifications:
2
//
3
// Sampling Frequency : 1.527 MHz
4
// Response           : Lowpass
5
// Specification      : Fp,Fst,Ap,Ast
6
// Passband Edge      : 50 kHz
7
// Stopband Edge      : 60 kHz
8
// Passband Ripple    : 1 dB
9
// Stopband Atten.    : 100 dB

The proublem of this filter is, when I give a 10kHz input to this filter 
it will generate more frequency components.
When I give 80kHz then it will filter(cutoff 60kHz) the 80kHz but it 
will generate some frequency components lower than the cut-off 
frequency.
What is the reason for this problem?
How can I design an accurate filters (LPF and BPF)?

The output of my filter is attached.

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Sir,Please help me on creating Fir filters in Matlab HDL Coder.

von Milruwan P. (Company: Student) (milprasad)


Attached files:

Rate this post
useful
not useful
Hi... I detect the zero crossing using the actual hardware.But the 
detected sine wave is a noisy signal.Here I attach the picture.Please 
give your suggestions.

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
I implement a Zero crossing detector in a fpga. It can detect the zero 
crossings of a signal and it could successfully demodulate a FM 
modulated signal. The problem is the demodulated signal doesn't have a 
fixed sample rate,Because when a zero crossing is met counter will 
start. when the other zero crossing is met counter save the present 
value to a register and restart the counter.This process will 
continue.... The value of the register is the demodulated signal.But it 
doesn't have a fixed sample rate. So the demodulated signal cannot be 
filtered.

1) How to get a fixed sample rate?
2)What is the sample rate we should take as the sampling rate of the 
filter?
3)How to overcome this problem?

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
The answer to all of the three questions is the same: oversampling

But to question 2 some additional questions arise:
- What frequencies are in your system?
- Whats the carrier frequency?
- Whats the signal frequency range?

Milruwan Perera wrote:
> The problem is the demodulated signal doesn't have a fixed sample rate
Actually thats not a problem. You simply demodulate the fm signal and 
look at the demodulated signal as if it is the "analog" output of an 
externally connected demodulator. An external (analog) demodulator also 
has no time relation to the filter inside the FPGA, and so the filter 
itself takes the current input level and samples it with the filters 
sampling frequency...

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Lothar Miller wrote:
> The answer to all of the three questions is the same: oversampling

Sorry sir in my question i forgot to say that I am doing the filtering 
part inside the fpga (designing a digital filter). I am doing to do all 
the processing inside the fpga.Due to the variable sample rate I could 
not process the signal(filter the signal). What should I need to do?

Lothar Miller wrote:
> But to question 2 some additional questions arise:
> - What frequencies are in your system?
> - Whats the carrier frequency?
> - Whats the signal frequency range?

What frequencies are in your system? 300kHz center frequency with 50kHz 
frequency deviation.

Whats the carrier frequency? 300kHz

Whats the signal frequency range? frequencies from 20Hz to 60kHz (FM 
multiplex signal)

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Milruwan Perera wrote:
> Due to the variable sample rate I could not process the signal(filter
> the signal). What should I need to do?
Just use the current demodulator output as input for the filter. You do 
not have anything else...

von Milruwan P. (Company: Student) (milprasad)


Rate this post
useful
not useful
Lothar Miller wrote:
> Just use the current demodulator output as input for the filter. You do
> not have anything else...

What should be the sampling rate (Fs) of the filter?

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Milruwan Perera wrote:
> What should be the sampling rate (Fs) of the filter?
It should be (according to Nyquist and Shannon) at least twice the 
highest signal frequency...

von Milruwan P. (Company: Student) (milprasad)


Attached files:

Rate this post
useful
not useful
AS  you told I created a iir filter using Matlab coder. How to reset and 
enable the filter? Filtering is not working but other part is working.

von Milruwan P. (Company: Student) (milprasad)


Attached files:

Rate this post
useful
not useful
I design a filter using Matlab hdl coder. But the problem is filter 
doesn't give filtered output. When I do the simulation in matlab filter 
works perfectly, but when I test with modelsim filter is not giving the 
filtered output. Problem is with the way of resetting and enabling the 
filter.

filter inputs and outputs

Code:
1
module filter
2
               (
3
                clk,
4
                clk_enable,
5
                reset,
6
                filter_in,
7
                filter_out
8
                );

input_reg_process
Code:
1
always @ (posedge clk or posedge reset)
2
    begin: input_reg_process
3
      if (reset == 1'b1) begin
4
        input_register <= 0;
5
      end
6
      else begin
7
        if (clk_enable == 1'b1) begin
8
          input_register <= filter_in;
9
        end
10
      end
11
    end // input_reg_process

Here is the output I got (reset and enable signal are also shown in the 
figure)

reset_my : is the reset
ce_my: is the enable

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.