项目名称:
频率计设计
具体要求:
检测方波的频率和占空比
设计架构
wave:方波输入
freq:检测出的方波频率
duty_cycle:测试出的方波占空比
状态转移图
测试出高电平和低电平的时间,经过计算得出频率和占空比
high_state:高电平状态
low_state:低电平状态
low_cnt:低电平计数
high_cnt:高电平计数
low_time:低电平时间
high_time:高电平时间
代码设计
verilog代码设计
module freq_detect(
input clk,
input rst_n,
input wave,
output [25:0] freq, //检测方波的频率
output [6:0] duty_cycle //检测方波的占空比
);
reg state;
localparam high_state=1'd0;
localparam low_state=1'd1;
reg [25:0]high_cnt;//可测试到1hz
reg [25:0]low_cnt;
reg [25:0]high_time;
reg [25:0]low_time;
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
state<=high_state;
high_cnt<=26'd0;
low_cnt<=26'd0;
high_time<=26'd0;
low_time<=26'd0;
end
else begin
case(state)
high_state: begin
if(wave==1)
begin
high_cnt<=high_cnt+1'b1;
state<=high_state;
end
else begin
high_cnt<=26'd0;
high_time<=high_cnt;
state<=low_state;
end
end
low_state : begin
if(wave==0)
begin
low_cnt<=low_cnt+1'b1;
state<=low_state;
end
else begin
low_time<=low_cnt;
low_cnt<=26'd0;
state<=high_state;
end
end
default:state<=high_state;
endcase
end
//系统时钟为50Mhz,计数需要时间=计数值*20ns,测试频率的周期为high_time*20+low_time*20
assign freq=1000_000_000/(high_time*20+low_time*20);
//占空比乘以100之后化为0-100之间的整数
assign duty_cycle=high_time*100/(high_time+low_time);
endmodule
仿真代码
`timescale 1ns/1ns
module freq_detect_tb;
reg clk;
reg rst_n;
reg wave;
wire [25:0] freq; //检测方波的频率
wire [6:0] duty_cycle; //检测方波的占空比
freq_detect freq_detect(
.clk(clk),
.rst_n(rst_n),
.wave(wave),
.freq(freq), //检测方波的频率
.duty_cycle(duty_cycle) //检测方波的占空比
);
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#200
rst_n=1;
#1_000_000_0 //仿真时间10ms
$stop;
end
initial begin
wave=1;
forever begin //产生占空比为60%,1khz的方波
#600_000;
wave=0;
#400_000;
wave=1;
end
end
endmodule
仿真结果
从结果可以看出待输出稳定之后,检测出1000hz的方波,待测试的方波在第二个周期可以稳定检测到占空比60%,代码中将检测到的占空比乘以100,得到60.