1、产生FPGA仿真需要使用到的正弦波采样数据,10bit量化,以二进制形式写入文本,以分号(;)结尾:
%设置参数
fi=5000;
L=1024;
N=10;
fs=20000;
%产生信号
t=0:1/fs:(L-1)/fs;
theta=rand()*2*pi;
si=sin(2*pi*fi*t+theta);
f_s=si/max(abs(si)); %归一化
Q_s=round(f_s*(2^(N-1)-1)); %10bit量化
fid=fopen('C:\Users\HLPC\Desktop\Sin.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);
生成的TXT文件如图:
2、从外部txt文件读入一定数据长度的10bit二进制数据作为测试激励:
integer cnt;
reg [9:0]stimulus[1:data_num]; //data_num仿真数据长度
initial begin
$readmemb("Sin.txt",stimulus);
cnt = 0;
repeat(data_num)begin
cnt = cnt + 1;
din = stimulus[cnt];
#clk_period;
end
end
3、将FPGA仿真的数据写入txt文件,可通过改变waveform style修改输出数据格式:
integer file_out;
initial
begin
//文件放置在"工程目录\simulation\modelsim"路径下
file_out = $fopen("out.txt");
if(!file_out)
begin
$display("could not open file!");
$finish;
end
end
wire signed [31:0] dout_s;
assign dout_s = data_o; //将dout转换成有符号数据
always @(posedge clk)begin
if(m_axis_data_tvalid)
$fdisplay(file_out,"%d",dout_s);
end
4、Matlab对十进制仿真数据进行读取分析
Fs=20000; %采样频率
L=256; %数据长度
%从文本文件中读取数据
fid=fopen('C:\Users\HLPC\Desktop\Sin.txt');
[FpgaOut,count]=fscanf(fid,'%d',inf);
fclose(fid);
%取出一段数据进行计算
FpgaOut=FpgaOut(1:L)'; %读出的数据为列向量,转换成行向量
Fout=abs(fft(FpgaOut,L)); %求FFT变换的幅度值
FpgaOut=FpgaOut/max(abs(FpgaOut));%归一化处理
Fout=Fout/max(Fout);
Fout=[Fout(L/2+1:L),Fout(1:L/2)]; %转换成相对于原点对称的信号
%画图
t=[0:L-1]; %生成时间坐标轴,单位为ms
t=t*(1/Fs)*(10^3);
m=[-L/2:1:(L/2-1)]*Fs/L*(10^(-3));%生成频率坐标轴,单位为KHz
subplot(211);plot(t(1:32),FpgaOut(1:32));
xlabel('时间(ms)','fontsize',10); ylabel('幅度','fontsize',10);
title('FPGA输出信号','fontsize',10);
subplot(212);plot(m,Fout);
xlabel('频率(KHz)','fontsize',10); ylabel('幅度','fontsize',10);
title('FPGA输出信号的幅频响应','fontsize',10);
5、Matlab读取二进制文件,转化为十进制
cstr = textread('C:\Users\HLPC\Desktop\Sin.txt','%s');
m = length(cstr{1});
n = length(cstr);
d = zeros(n,1);
for i=1:n
s = bin2dec( cstr{i}(1) ); % 符号
if s==1
d(i)=bin2dec(cstr{i})-2^m;
else
d(i) = bin2dec( cstr{i} ) ;
end
end
注意:
二进制文本必须由字符 0 和 1 组成,文本结尾不能有分号(;)。
6、Vivido中ROM IP核的使用
生成位宽为16bit,深度为1024的rom生成初始化文件:
width=16; %rom的位宽
depth=1024; %rom的深度
x=linspace(0,2*pi,depth); %在一个周期内产生1024个采样点
y_cos=cos(x); %生成余弦数据
y_cos=round(y_cos*(2^(width-1)-1))+2^(width-1)-1; %将余弦数据全部转换为整数
fid=fopen('C:\Users\Administrator\Desktop\cos_coe.coe','w'); %创建.coe文件
fprintf(fid,'%d,\n',y_cos); %向.coe文件中写入数据
fclose(fid); %关闭.coe文件
注意:
1、在前两行添加:
memory_initialization_radix=10;
memory_initialization_vector =
2、将最后一行的逗号改为分号.
在Vivado中,对rom进行初始化的文件是.coe文件.它的格式如下:
memory_initialization_radix=10;
memory_initialization_vector =
65534,
65533,
...,
60211;
其中,*memory_initialization_radix=10;*表示文件存储数据的进制,10即为10进制,
memory_initialization_vector是数据向量,等号后面的数字就是数据向量,使用逗号隔开数据,分号表示结束.