FPGA测量两路同频信号的相位差

  |  

概述

测量两路信号相位差有两种思路:

  • 第一种是在verilog程序中直接让两路信号经过异或门输出,测量该输出信号的占空比,其占空比乘以360度就得到相位差。

该方法的详细内容参考该篇文章:FPGA测两路信号相位差

  • 第二种是在拥有测量时间差和测量信号频率的两个功能模块的基础上,利用基本公式得到相位差。

    下面简单介绍第二种方法。


频率计

频率计模块的原理如图所示:

img

由此可以得到信号的频率。

参考代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
module get_frequence(
clk,
rst_n,
fx,
NA,
NB
);
input clk;
input rst_n;
input fx;
output[31:0] NA;
output[31:0] NB;

reg[31:0] NA;
reg[31:0] NB;

reg[31:0] counter;
reg[31:0] counter_a;
reg[31:0] counter_b;

wire Tp;
reg T;

always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
counter <= 0;
else if(counter < 200000000)
counter <= counter+1;
else if(counter == 200000000)
counter <= 0;
end

assign Tp = ( counter < 100000000)?1:0 ;


always @(posedge fx or negedge rst_n)
if(~rst_n)
T <= 0;
else
T <= Tp;

always @(posedge fx or negedge rst_n)
begin
if(~rst_n)
counter_a <= 0;
else if(~T)
counter_a <= 0;
else if(T)
counter_a <= counter_a + 1;
end

always @(negedge T or negedge rst_n)
if(~rst_n)
NA <= 0;
else
NA <= counter_a;

always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
counter_b <= 0;
else if(~T)
counter_b <= 0;
else if(T)
counter_b <= counter_b + 1;
end

always @(negedge T or negedge rst_n)
if(~rst_n)
NB <= 0;
else
NB <= counter_b;

endmodule

时间间隔电路

测量时间差的模块原理如图所示:

img

由此可得到两路信号的时间差。

参考代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
module measure_time(
clk,
rst_n,
fA,
fB,
NA,
NB
);
input clk;
input rst_n;
input fA;
input fB;
output[31:0] NA;
output[31:0] NB;

reg[31:0] NA;
reg[31:0] NB;

reg[31:0] counter;
reg[31:0] counter_a;
reg[31:0] counter_b;

wire Tp;
reg T;
wire fAA;
wire fBB;
reg clk_NA;

//预置闸门时间Tp = 1s
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
counter <= 0;
else if(counter < 200000000)
counter <= counter+1;
else if(counter == 200000000)
counter <= 0;
end

assign Tp = ( counter < 100000000)?1:0 ;


always @(posedge fA or negedge rst_n)
if(~rst_n)
T <= 0;
else
T <= Tp;

assign fAA = ~(~fA);
assign fBB = ~fB;

always @( posedge fAA or negedge fBB )
if(~fBB)
clk_NA <= 0;
else if(fBB)
clk_NA <= T;


always @(posedge clk_NA or negedge rst_n)
begin
if(~rst_n)
counter_a <= 0;
else if(~T)
counter_a <= 0;
else if(T)
counter_a <= counter_a + 1;
end

always @(negedge T or negedge rst_n)
if(~rst_n)
NA <= 0;
else
NA <= counter_a;

always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
counter_b <= 0;
else if(~T)
counter_b <= 0;
else if(clk_NA)
counter_b <= counter_b + 1;
end

always @(negedge T or negedge rst_n)
if(~rst_n)
NB <= 0;
else
NB <= counter_b;

endmodule

在仿真测试中调用

仿真文件中,需要同时调用两个模块,仿真结果如图所示:

image

根据前面的公式可以得到:信号频率为1MHz,时间差为2x10^-7s

于是,相位差为2Pi/5

textbench参考代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
`timescale 1ns/1ns
module testbench;

reg clk;
reg fA;
reg fB;
reg rst_n;
wire[31:0] NA;
wire[31:0] NB;
wire[31:0] NC;
wire[31:0] ND;
reg clk_d;
reg f_test;
measure_time mt_inst(
.clk(clk),
.rst_n(rst_n),
.fA(fA),
.fB(fB),
.NA(NA),
.NB(NB)
);
get_frequence gf_inst(
.clk(clk),
.rst_n(rst_n),
.fx(fA),
.NA(NC),
.NB(ND)
);

always #5 clk = ~clk; // f0 = 100MHz

always #100 clk_d = ~clk_d;


always
#500 f_test = ~f_test; // fA = 1MHz

always @(posedge clk_d)
begin
fA <= f_test;
fB <= fA;
end

initial
begin

#0 clk = 0;
rst_n = 0;
fA = 0;
f_test = 0;
clk_d =0;

#10 rst_n = 1;

#2500000000 $stop;

end

endmodule
文章目录
  1. 概述
    1. 频率计
    2. 时间间隔电路
    3. 在仿真测试中调用
本站总访问量 | 本页面被访问 | 本站访客数
载入天数...载入时分秒...