39.简易频率计(基于等精度测量法)(2)

(1)Verilog代码实现:

module freq_meter_calc
(
	input					clk			,
	input					reset_n		,
	input					clk_test		,
	
	output	reg [31:0]	freq			
);
	
	reg	[26:0]	cnt0;
	reg   			gata_r;
	reg				gata_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;
	wire				gata_t_test_nedge;
	wire				gata_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;

pll	pll_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;

reg		clk			;
reg		reset_n		;
reg		clk_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;

reg		clk			;
reg		reset_n		;
reg		clk_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;

reg		clk			;
reg		reset_n		;
reg		clk_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)仿真波形:

相关推荐

  1. 基于FPGA的频率与串口通信(二)

    2024-07-18 07:08:03       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 07:08:03       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 07:08:03       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 07:08:03       57 阅读
  4. Python语言-面向对象

    2024-07-18 07:08:03       68 阅读

热门阅读

  1. Redis数据结构--跳跃表 Skip List

    2024-07-18 07:08:03       20 阅读
  2. feign 接口调用下载接口技巧

    2024-07-18 07:08:03       22 阅读
  3. 简述机器学习中常用的一些统计量

    2024-07-18 07:08:03       23 阅读
  4. VSCODE 驯服日记(二)对MPE的格式进行调整

    2024-07-18 07:08:03       21 阅读
  5. 建造者模式例题

    2024-07-18 07:08:03       20 阅读
  6. Electron 配置macOS平台的安装图标

    2024-07-18 07:08:03       22 阅读
  7. jQuery 语法

    2024-07-18 07:08:03       21 阅读
  8. 71、Flink 的 Hybrid Source 详解

    2024-07-18 07:08:03       19 阅读