软件环境:vivado2018.2
目录
VIO
Vio使用过程:
1、ip catalog搜索vio
2、配置属性
上图设置输入probe数量和输出probe数量
我设置输入1 ,输出 0
如果不对后面可以再次修改
设置位宽。然后ok
Generate
3、例化
例化我一般是先找到veo文件位置,然后再进行例化。
点击文件属性,
复制文件路径
粘贴到文件夹路径,然后找到veo文件
可以右键用记事本打开
里面有例化程序:
4、关于probe
Vio的Probe_out端口,在逻辑上级联的是模块的输入端口,比如模块的一个输入a,
需要注意,a并不能用input去声明,否则会出现“多驱动”错误。
想用vio虚拟控制模块的输入端口a,我是用以下语句(不完整)
Wire a;
Probe_out0(a);
而且,用vio的本意就是用虚拟端口代替实际端口,所以不需要input也是理所当然。
后记:
关于vio的使用
如果按照这个图来的话,我自己认为的操作是这样的
(1)设计一个input indata[7:0]
(2)设计一个output outdata[7:0]
(3)然后创建一个vio核,设置对应的参数
(4)将vio例化,连接对应的端口
但是这样做的话会有几个问题
(1)input的端口还需要进行管脚约束吗?(因为本身就是在管脚不够用的情况下才使用虚拟io来替代,如果还需要管脚约束的话,是不是本末倒置了)
(2)在implement的时候报错,indata是一个多驱动的端口,系统说是input和vio例化程序这两个都是驱动。
(3)如果进行了管脚约束,那么是vio起作用还是实际的按键起作用呢?
后面我只使用了wire indata[7:0]关键字,这样implement时候没有再报错了,使用wire关键字的变量是不能进行管脚约束的。这说明我一开始的想法是错误的,不能用input去定义想要用在vio的端口。
我用led灯的程序实验了一下,发现是可以只用vio去控制wire型变量的。
后续我用了vio尝试去调试分频比,下图是vio的调试界面,我设置了两个端口,一个是输入调试口divnum,一个是输出调试口,spi_pout,其中divnum是分频比,通过改这个分频比,我可以通过示波器观察到波形的变化,这是实际操作成功了的。
示波器显示spi的工作频率已经被改变了。
Vio的例化
DDS Compiler(6.0)
1、打开IP核搜索,搜索dds,选择DDS Compiler(6.0)
2、设置System Parameters参数:
这里选择是否同时输出sincos和相位。
(1)Spurious Free Dynamic Range的设置,这个参数与输出数据的宽度相关
可以参考《LogiCORE IP DDS Compiler v6.0 Products Guide》,根据自己需要的输出数据宽度
在我的设计中,需要得到输出数据宽度8,因此设置Spurious Free Dynamic Range的值为:
8*6 = 48
(2)Frequency Resolution的设置,这个参数与输出相位数据的宽度相关,如果想要得到8bit的宽度,channels为1,系统输入时钟为156.25MHz
Frequency Resolution = 156250000/2^8 = 610351.5625
parameter Selection选择System Parameters
设置好了如下
3、设置Phase Increment Programmability和Phase offset programmability为固定模式,输出为正弦波
4、Detailed Implementation选项卡不需要设置
5、Output Frequencies选项卡设置需要的输出频率,在此设置为1M
6、phase offset Angles通道1设置为0(默认就是0)
7、最后两个选项卡由我们设置的参数生成
这里是0.9155M
8、例化dds
其中aclk是输入时钟
tvalid结尾的参数是指,当tvalid==1时,tdata才是有效的。
tdata就是输出的数据。
Ip例化后,tb文件如下
module tb_dds_top(
);
reg aclk;
wire m_axis_data_tvalid;
wire [7:0] m_axis_data_tdata;
wire m_axis_phase_tvalid;
wire [15:0] m_axis_phase_tdata;
initial
begin
aclk <= 0;
end
always #3.2 aclk <= ~aclk;
dds_compiler_0 dds_compiler_0(
.aclk(aclk), // input wire aclk
.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 [15 : 0] m_axis_phase_tdata
);
Endmodule
然后仿真
找到数据波形,选择模拟
选择进制
我这里仿真了1us,正好是一个周期,可以看到正弦波是一个周期
5us
PLL
上图中选择pll还是mmcm,输入频率,输入port名字等等。
这个就是初始化代码
ila
实际上ila有两种模式可以启动,可以单独启动也可以一次多开。
如果你是想要拉出顶层的信号查看,不关心下面一些小模块里面的信号,那么使用方法1比较快(实际上也不是很快)。
如果是想要看一些特定的信号,这些信号分布很零散,建议使用方法。(建议先看方法2).
方法1
注意,这里放进去的probe信号前面最好加一个(*keep="TRUE"*)
方法2
首先跑一次综合
打开原理图
找到你需要的信号
右键 mark debug
找信号的话,如果信号很多,最好用ctrl+f查找,在原理图按下ctrl+f,或者
把想要看的信号都mark debug之后。
next
next,我这里是有已经创建的
结束