自学内容网 自学内容网

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)!