基于FPGA的频率测量

该博客介绍了如何使用MATLAB生成400Hz的正弦波,并将其10位量化数据写入文本文件。接着展示了Verilog代码实现频率测量模块,该模块接收10位数字输入并计算频率。测试代码读取输入数据并进行仿真,结果显示初始由于复位影响计数不准确,后续计数正确,验证了频率测量模块的功能。
摘要由CSDN通过智能技术生成

正弦波由matlb产生;

clc;
clear all;
close all;
%Sin400hz.m程序清单
%设置系统参数
fi=400;					%输入信号的频率
Fs=8000;				%采样频率
L=10024;				%数据长度
N=10;					%量化位数
x=0:1/(100*fi):2/fi;
figure('name','sin(2*pi*fi*x)');
plot(x,sin(2*pi*fi*x));
title('sin(2*pi*fi*x)');
xlabel('x');
ylabel('sin');
%产生400hz正弦信号
t=0:1/Fs:(1/Fs)*(L-1);		%产生采样频率的时间序列
si=sin(2*pi*fi*t);  	

%归一化处理
f_s=si/max(abs(si));
%10bit量化
Q_s=round(f_s*(2^(N-1)-1));

%将生成的输入正弦信号数据,写入外部文本文件(din.txt)中
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%新建文本文件前,必须建好文件存放的目录文件夹,否则出现提示信息:
%??? Error using ==> fprintf
%Invalid file identifier
fid=fopen('D:\a_FPGA\frequency_measure\sim\din.txt','w');
for k=1:length(Q_s)
    B_s=dec2bin(Q_s(k)+(Q_s(k)<0)*2^N,N);
    for j=1:N
       if B_s(j)=='1'
           tb=1;
       else
           tb=0;
       end
       fprintf(fid,'%d',tb);  
    end
    fprintf(fid,'\r\n');
end
fprintf(fid,';'); 
fclose(fid);

Verilog源代码:

module frequency_measure(
	//input
	clk,//8000Hz;
	rst_n, //0 valid;
	data_in, 
	f
);
input clk,rst_n;
input [9:0] data_in;//10bit digital data;
output[9:0] f;	//frequency,unit is Hz;
//reg define
reg [6:0] cnt0,cnt1;//the count of input signal's period needs
reg [1:0] transfer;

//main code;
always @(posedge clk or negedge rst_n)
	if(!rst_n)
		transfer <= 2'b00;
	else 
		begin 
			transfer[0] <= data_in[9];
			transfer[1] <= transfer[0];
		end 

always @(posedge clk or negedge rst_n)
	if(!rst_n)	//if reset ,cnt  <= 0;
		begin
			cnt0 <= 7'b0;
		end 
	else		//not reset;
		begin
			if(transfer == 2'b01)	
				begin
					cnt1<= cnt0 + 1'b1 ;
					cnt0 <= 7'b0;
				end 
				
			else 
				cnt0 <= cnt0 + 1'b1;
		end 
assign f = 8000/cnt1; //
		
		
endmodule 

测试代码:

`timescale 1ns/1ns 
module tb_frequency_measure();
//clk period;
parameter clk_period = 125000;
//data length;
parameter data_num = 10000;
//input;
reg clk,rst_n;
reg [9:0] data_in;
//output;
wire [9:0] f;

//frequency_measure instance;
frequency_measure u0_frequency_measure(
	.clk(clk),
	.rst_n(rst_n),
	.data_in(data_in),
	.f(f)
);
//clk;
always #(clk_period/2) clk = ~clk;
//parameter
initial 
	begin
		clk = 1'b0;
		rst_n = 1'b0;
		
		#(5*clk_period) rst_n = 1'b1;	
        data_in = 10'd0;		
	end 
//read din.txt as data_in;
integer pattern;
reg [9:0] stim_data[1:data_num];
initial 
	begin 
		//din.txt and tb_frequency_measure.v must in a same folder;
		$readmemb("D:/a_FPGA/frequency_measure/sim/din.txt",stim_data);
		pattern = 0;
		repeat(data_num)
			begin
				pattern = pattern + 1;
				data_in = stim_data[pattern];
				#clk_period;
			end 
	end 
endmodule

仿真结果:

起始因复位不能得到完整的1个周期的计数,所以计数会不对,计数结果为8,频率为1000;后面的都是对的,计数为20,频率为400。

仅供学习。

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值