实验1的目标是通过vio更改dds生成的正弦波频率,通过ila检验另外还在matlab检查下波形文件是否正确
关于dds和ila,我在之前的博客中已经有详细的论述,这里介绍vio ip
什么是VIO
Vivado中的VIO(Virtual Input/Output) IP核是一种用于调试和测试FPGA设计的IP核。它允许设计者通过使用JTAG接口读取和写入FPGA内部的寄存器,从而检查设计的运行状态并修改其行为。VIO IP核提供了一个简单易用的接口,使得用户可以轻松地与FPGA内部寄存器进行交互.
通过使用VIO IP核,用户可以实时监视和修改设计中的信号,以便进行调试和验证。此外,VIO IP核还可以与其他IP核和设计组件配合使用,从而帮助设计者更好地理解和调试整个系统。
主要用作虚拟IO使用;VIO的输出可以控制模块的输入,VIO的输入可以显示模块的输出值。
ip配置
还是先配置dds ip:
设置位数为2控制四种频率控制字,得到四种不同频率的正弦波。
添加ila
fword和顶层模块
fword_set拥有模拟按键切换频率
`timescale 1ns / 1ps
//simulated key part
module Fword_set(
input clk ,
input rst_n ,
input [1:0] key_PINC ,
output reg [23:0] Fword
);
always@(*)
begin
case(key_PINC)
0: Fword <= 'h51eb; //1Mhz 20971.52 取整20971
1: Fword <= 'ha3d7; //2Mhz 41943.04 取整41943
2: Fword <= 'hf5c2; //3Mhz 62914.56 取整62914
3: Fword <= 'h33333; //10Mhz 209715.2 取整209715
endcase
end
endmodule
module vio_top(input clk,input rstn);
wire [1:0] key_PINC;
wire s_axis_config_tvalid,m_axis_data_tvalid,m_axis_phase_tvalid;
wire [23:0] m_axis_phase_tdata,Fword;
wire [7:0]m_axis_data_tdata;
assign s_axis_config_tvalid=1'b1;
dds_compiler_0 dds_compiler_u (
.aclk(clk), // input wire aclk
.s_axis_config_tvalid(s_axis_config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tdata(Fword), // input wire [23 : 0] s_axis_config_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata), // output wire [7 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(m_axis_phase_tvalid), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata) // output wire [23 : 0] m_axis_phase_tdata
);
vio_0 vio_u (
.clk(clk), // input wire clk
.probe_out0(key_PINC) // output wire [1 : 0] probe_out0
);
ila_0 ila_u (
.clk(clk), // input wire clk
.probe0(key_PINC), // input wire [1:0] probe0
.probe1(Fword), // input wire [23:0] probe1
.probe2(m_axis_data_tdata) // input wire [7:0] probe2
);
Fword_set Fword_u(
.clk (clk ),
.rst_n (rstn ),
.key_PINC (key_PINC ),
//output
.Fword (Fword )
);
endmodule
调试
在调试时,我们可以不断修改vio的值来观察到不同的仿真结果,
key_PINC[1]=0,key_PINC[0]=0的波形,此时一个周期大约25个步长
key_PINC[1]=1,key_PINC[0]=0的波形,此时一个周期大约13步长
key_PINC[1]=1,key_PINC[0]=0的波形,此时一个周期大约7步长
上面硬件测试中输出频率为1MHz的正弦波,一个周期大概是25个单位长度;输出频率为2MHz的正弦波,一个周期大概是13个单位长度;而输出频率为3MHz的正弦波,一个周期大概是7个单位长度。根据输出频率之间的倍数关系可以判断其周期的对应关系是正确的
matlab验证
将三种情况的仿真结果分别导出为csv文件到matlab分析
matlab代码
csv1_row6 = ila0{:,7}; %iladata_1MHz.csv文件中的第六列数据
csv2_row6 = ila1{:,7}; %iladata_2MHz.csv文件中的第六列数据
csv3_row6 = ila2{:,7}; %iladata_3MHz.csv文件中的第六列数据
fs=50000000; %设置采样频率为50MHz
N=2048; %采样点
n=0:N-1;
t=n/fs;
f=n*fs/N; %频率序列
figure;
subplot(2,1,1);plot(t,csv1_row6);grid on;title('1MHz输出频率对应的正弦波');
y1=abs(fft(csv1_row6,N));
subplot(2,1,2);plot(f,y1,'r');grid on;title('1MHz输出频率对应的频谱');
figure;
subplot(2,1,1);plot(t,csv2_row6);grid on;title('2MHz输出频率对应的正弦波');
y2=abs(fft(double(csv2_row6),N));
subplot(2,1,2);plot(f,y2,'r');grid on;title('2MHz输出频率对应的频谱');
figure;
subplot(2,1,1);plot(t,csv3_row6);grid on;title('3MHz输出频率对应的正弦波');
y3=abs(fft(double(csv3_row6),N));
subplot(2,1,2);plot(f,y3,'r');grid on;title('3MHz输出频率对应的频谱');
第一个尖峰位于2Mhz,第二个尖峰位于48Mhz(共轭对称特性)
第一个尖峰位于4Mhz,第二个尖峰位于46Mhz(共轭对称特性)
第一个尖峰位于6Mhz,第二个尖峰位于44Mhz(共轭对称特性)