正弦波由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。
仅供学习。