39.简易频率计(基于等精度测量法)(2)
(1)Verilog代码实现:
module freq_meter_calc
(
inputclk,
inputreset_n,
inputclk_test,
outputreg [31:0]freq
);
reg[26:0]cnt0;
reg gata_r;
reggata_t;
reg [47:0]cnt_clk_test;
reg gata_t_test_reg;
reg [47:0]max_x;
reg [47:0]cnt_clk100M;
reg gata_t_clk100M_reg;
reg[47:0]max_y;
reg [63:0]freq_reg;
wire clk_100M;
wiregata_t_test_nedge;
wiregata_t_clk100M_nedge;
parameter MCNT0=27'd74_999_999;
//0.25s = 250_000_000 ns = 20ns * 12_500_000 24位
parameter MCNT1= 24'd12_499_999;
parameter STAND_MAX = 27'd100_000_000;
pllpll_inst (
.areset ( ~reset_n ),
.inclk0 ( clk ),
.c0 ( clk_100M ),
.locked( )
);
//1.5s的一个计数器 1.5s = 1_500_000_000 ns = 20ns * 75_000_000; 需要一个27位的寄存器
always@(posedge clk or negedge reset_n)
if(!reset_n)
cnt0 <= 27'd0;
else if(cnt0 == MCNT0)
cnt0 <= 27'd0;
else
cnt0 <= cnt0 + 27'd1;
//软件闸门设计
always@(posedge clk or negedge reset_n)
if(!reset_n)
gata_r <= 1'd0;
else if((cnt0 > MCNT1) && (cnt0 < MCNT0 - MCNT1))
gata_r <= 1'd1;
else
gata_r <= 1'd0;
//实际闸门设计
always@(posedge clk_test or negedge reset_n)
if(!reset_n)
gata_t <= 1'd0;
else
gata_t <= gata_r;
//实际闸门检测时钟计数模块
always@(posedge clk_test or negedge reset_n)
if(!reset_n)
cnt_clk_test <= 48'd0;
else if(gata_t)
cnt_clk_test <= cnt_clk_test + 48'd1;
else
cnt_clk_test <= 48'd0;
//实际闸门在检测时钟下的下降沿设计
always@(posedge clk_test)
gata_t_test_reg <= gata_t;
assign gata_t_test_nedge = ((gata_t_test_reg) && (!gata_t));
//检测时钟在实际闸门中的周期数设计
always@(posedge clk_test or negedge reset_n)
if(!reset_n)
max_x <= 48'd0;
else if(gata_t_test_nedge)
max_x <= cnt_clk_test;
else
max_x <= max_x;
//标准时钟在实际闸门的周期数计数模块设计
always@(posedge clk_100M or negedge reset_n)
if(!reset_n)
cnt_clk100M <= 48'd0;
else if(gata_t)
cnt_clk100M <= cnt_clk100M + 48'd1;
else
cnt_clk100M <= 48'd0;
//标准时钟在实际闸门下的下降沿设计
always@(posedge clk_100M)
gata_t_clk100M_reg <= gata_t;
assign gata_t_clk100M_nedge = ((gata_t_clk100M_reg) && (!gata_t));
//标准时钟在实际闸门中的周期数设计
always@(posedge clk_100M or negedge reset_n)
if(!reset_n)
max_y <= 48'd0;
else if(gata_t_clk100M_nedge)
max_y <= cnt_clk100M;
else
max_y <= max_y;
//频率输出设计
always@(posedge clk or negedge reset_n)
if(!reset_n)
freq_reg <= 64'd0;
else if(cnt0 == MCNT0)
freq_reg <= (max_x * STAND_MAX) / max_y ;
else
freq_reg <= freq_reg;
always@(posedge clk)
freq <= freq_reg[31:0];
endmodule
(2)仿真文件代码(测试时钟为500MHz):
`timescale 1ns/1ns
module freq_meter_calc_tb;
regclk;
regreset_n;
regclk_test;
wire [31:0]freq;
initial clk = 1'd1;
always#10 clk = ~clk;
initial clk_test= 1'd1;
always#1 clk_test = ~clk_test;
initial begin
reset_n <= 1'd0;
#15;
reset_n <= 1'd1;
#2_000_000;
$stop;
end
freq_meter_calc freq_meter_calc_inst
(
.clk(clk),
.reset_n(reset_n),
.clk_test(clk_test),
.freq(freq)
);
defparam freq_meter_calc_inst.MCNT0 = 27'd74_999;
defparam freq_meter_calc_inst.MCNT1 = 27'd12_499;
endmodule
(3)仿真波形:
(3)仿真文件代码(测试时钟修改为20KHz):
`timescale 1ns/1ns
module freq_meter_calc_tb;
regclk;
regreset_n;
regclk_test;
wire [31:0]freq;
initial clk = 1'd1;
always#10 clk = ~clk;
initial clk_test= 1'd1;
always#25000 clk_test = ~clk_test;
initial begin
reset_n <= 1'd0;
#15;
reset_n <= 1'd1;
#2_000_000;
$stop;
end
freq_meter_calc freq_meter_calc_inst
(
.clk(clk),
.reset_n(reset_n),
.clk_test(clk_test),
.freq(freq)
);
defparam freq_meter_calc_inst.MCNT0 = 27'd74_999;
defparam freq_meter_calc_inst.MCNT1 = 27'd12_499;
endmodule
(4)仿真波形:
(5)仿真文件代码(测试时钟修改为7MHz):
`timescale 1ns/1ns
module freq_meter_calc_tb;
regclk;
regreset_n;
regclk_test;
wire [31:0]freq;
initial clk = 1'd1;
always#10 clk = ~clk;
initial clk_test= 1'd1;
always#71 clk_test = ~clk_test;
initial begin
reset_n <= 1'd0;
#15;
reset_n <= 1'd1;
#2_000_000;
$stop;
end
freq_meter_calc freq_meter_calc_inst
(
.clk(clk),
.reset_n(reset_n),
.clk_test(clk_test),
.freq(freq)
);
defparam freq_meter_calc_inst.MCNT0 = 27'd74_999;
defparam freq_meter_calc_inst.MCNT1 = 27'd12_499;
endmodule
(6)仿真波形:
原文地址:https://blog.csdn.net/2301_80417284/article/details/140499976
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!