Bootstrap

Modelsim仿真实现Verilog HDL频率检测器

 检测输入信号的频率,输出8位数码显示,十进制。可以用于八段式数码管显示屏。

1

clk

产生1Hz的方波,这是个很低的频率,被检测的频率都比这个高,因此,1个周期(即1s)内,可以有很多很多个signal的上升沿,只需要统计signal上升沿的数量,就可以算出signal的频率。

在clk第1个上升沿发生后,令程序处于count state;

在clk第2个上升沿发生后,令程序处于latch state;

在clk第3个上升沿发生后,令程序处于clear state;

在clk第4个上升沿发生后,令程序处于count state;

依此类推。

2

signal

产生XHz的方波,例如10Hz,800Hz,200kHz,10MHz

3

rst

复位,高电平有效,上升沿有效,初始1,100ns后变为0,即刚开始时复位100ns,然后正式开始工作。

4

d0~d7

锁存器输出的4位寄存器变量,共8个。d7是最高位。latch state时用于锁存q0~q7。也可以理解为数码管的显示器。

5

q0~q7

wire格式,用于表示频率检测的结果,10进制,q7是最高位,可以表示的范围最小是0,最大是99999999。掐头去尾,常用频段10Hz~10MHz。

主程序: 

module freq_detector(input wire clk, signal, rst, output reg [3:0] d0, d1, d2, d3, d4, d5, d6, d7);
reg count, latch, clear;
reg [1:0] state;
wire [3:0] q0,q1,q2,q3,q4,q5,q6,q7;
counter_10 u0(rst, clear, signal, count, high_out1, q0);
counter_10 u1(rst, clear, signal, high_out1, high_out2, q1);
counter_10 u2(rst, clear, signal, high_out2, high_out3, q2);
counter_10 u3(rst, clear, signal, high_out3, high_out4, q3);
counter_10 u4(rst, clear, signal, high_out4, high_out5, q4);
counter_10 u5(rst, clear, signal, high_out5, high_out6, q5);
counter_10 u6(rst, clear, signal, high_out6, high_out7, q6);
counter_10 u7(rst, clear, signal, high_out7, high_out8, q7);
always@(posedge clk or posedge rst) begin
	if(rst) begin
		state <= 0;
		count <= 0;
		latch <= 0;
		clear <= 0;
	end
	else begin
		case (state)
		0: begin
			state <= 1;
			count <= 1;
			latch <= 0;
			clear <= 0;
		end
		1: begin
			state <= 2;
			count <= 0;
			latch <= 1;
			clear <= 0;
		end
		2: begin
			state <= 0;
			count <= 0;
			latch <= 0;
			clear <= 1;
		end
		default: begin
			state <= 0;
			count <= 0;
			latch <= 0;
			clear <= 0;
		end
		endcase
	end
end
always@(posedge signal or posedge rst) begin
	if(rst | clear) begin
		d0 <= 0;
		d1 <= 0;
		d2 <= 0;
		d3 <= 0;
		d4 <= 0;
		d5 <= 0;
		d6 <= 0;
		d7 <= 0;
	end
	else begin
		if(latch) begin
			d0 <= q0;
			d1 <= q1;
			d2 <= q2;
			d3 <= q3;
			d4 <= q4;
			d5 <= q5;
			d6 <= q6;
			d7 <= q7;
		end
	end
end
endmodule

module counter_10(input wire rst, clear, signal, low_in, output reg high_out, output reg [3:0] low_out);
always@(posedge signal or posedge rst) begin
	if(rst | clear) begin
		high_out <= 0; 
		low_out <= 0;
	end
	else begin
		if(low_in) begin
			if(low_out==9) begin
				high_out <= 1;			
				low_out <= 0;
			end
			else begin
				high_out <= 0;
				low_out <= low_out + 1;
			end
		end
		else begin
			high_out <= 0;
		end
	end
end
endmodule

 测试程序:

`timescale 1us/1ns
module freq_detector_tb();
reg clk, signal, rst;
wire[3:0] d0, d1, d2, d3, d4, d5, d6, d7;
freq_detector u1(clk, signal, rst, d0, d1, d2, d3, d4, d5, d6, d7);
always #500_000 clk <= ~clk;
always #2.5 signal <= ~signal;
initial begin
	clk <= 0;
	signal <= 0;
	rst <= 1;
	#0.1;
	rst <= 0;
	#3_000_000 $stop;
end
endmodule

以200kHz为例,结果如下:

;