ZYNQ从入门到秃头11 DAC FIFO实验(AXI-stream FIFO IP核配置)
Posted “逛丢一只鞋”
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZYNQ从入门到秃头11 DAC FIFO实验(AXI-stream FIFO IP核配置)相关的知识,希望对你有一定的参考价值。
文章目录
- DAC FIFO实验要求
- AXI-stream FIFO介绍
- DAC FIFO实验例化模块
- DAC FIFO实验程序代码
- DAC FIFO实验实验效果
- DAC FIFO实验工程下载
- 进阶:AD/DA FIFO实验
- AD/DA FIFO实验工程下载
- 补充:DDS
DAC FIFO实验要求
DAC FIFO实验
基于“DDS IP 数字波形合成DAC ” “ ADDA测试” 实验方案
用MMCM 把 合成出100MHz的时钟,让DDS工作在100MHz时钟
让DAC和DAC的接口电路工作在50MHz,此时DAC的采样率为50MHz
在DDS和DAC接口电路之间,放置一个带独立时钟的AXI-Stream-Data FIFO,FIFO两端的时钟分别为DDS的工作时钟100MHz和DAC的工作时钟50MHz
生成FIFO需要带data count信号(本实验仅用于观察,以后的实验中这些信号有用。)
DDS的数据输出接口需要有TREADY信号
DAC接口电路需要将FIFO输出端的AXI-S接口转换成DAC的接口格式,自行编写RTL代码完成该功能。另外由于DAC的工作频率小于DDS工作频率,所以DAC接口控制器给FIFO的RDY信号应该一直为高。
以上结构的意义在于,把接口电路和信号处理电路分离在不同的时钟域,从而使得各部分保持独立
本实验添加2个system ILA,分别观察FIFO两端接口的信号时序,注意观察 data count端口的变化。
用VIO配置频率字,分别生成1MHz和3MHz的DDS正弦波形,用system ILA抓取DAC的输入数据,用Matlab分析频谱,验证频率正确。
本实验是一个典型的带反向流控的跨时钟域传输信号的例子
关于DDS还有频率字的一些概念,见传送门
AXI-stream FIFO介绍
这里有一篇文章不错,如果还是不理解,可以去学习一下
带你快速入门AXI4总线–AXI4-Stream篇(3)----详解XILINX IP AXI4 STREAM DATA FIFO
基于地址形式的交互与基于流形式的交互
流式传输和基于地址的传输有什么区别?
直观的看,基于地址的数据传输就像是CPU访问内存,每次访问数据都需要一个地址。基于流的数据传输方式类似于FIFO,队列的访问,每次读取会把数据“读走”,下次再读取的时候已经是下一个数据,写入也是类似。
FPGA中,流式数据传输是以时钟为驱动,加一些控制信号。stream常见的实例就是AD/DA转换,AD/DA转换器在采样时钟的驱动下,不停的产生数据流,外界根据一个ready信号来决定是否读取数据。address形式常见的例子例如MCU读取AT24C04,每次发生数据的读写都会提前设置地址。
可以看出来,基于stream的数据传输更适合批量数据的传输,基于Address的数据传输适合位置型的数据。
AXI-stream总线读写协议
axis工作模式
axis分为:
-
tready信号:从告诉主做好传输准备;
-
tvalid信号:主告诉从数据传输有效;
-
tlast信号:主告诉从该次传输为突发传输结尾;
-
tdata信号:数据,可选宽度32,64,128,256bit
-
tstrb信号:为1的bit为对应tdata有效字节,宽度为tdata/8
-
tuser信号 :用户定义信号,宽度为128bit
-
aclk信号:总线时钟,上升沿有效;
-
aresetn信号:总线复位,低电平有效;
axi总线分为五个通道:
-
读地址通道,包含ARVALID, ARADDR, ARREADY信号;
-
写地址通道,包含AWVALID,AWADDR, AWREADY信号;
-
读数据通道,包含RVALID, RDATA, RREADY, RRESP信号;
-
写数据通道,包含WVALID, WDATA,WSTRB, WREADY信号;
-
写应答通道,包含BVALID, BRESP, BREADY信号;
-
系统通道,包含:ACLK,ARESETN信号;
其中ACLK为axi总线时钟,ARESETN是axi总线复位信号,低电平有效;读写数据与读写地址类信号宽度都为32bit;READY与VALID是对应的通道握手信号;WSTRB信号为1的bit对应WDATA有效数据字节,WSTRB宽度是32bit/8=4bit;BRESP与RRESP分别为写回应信号,读回应信号,宽度都为2bit,‘h0代表成功,其他为错误。
读操作
顺序为主与从进行读地址通道握手并传输地址内容,然后在读数据通道握手并传输所读内容以及读取操作的回应,时钟上升沿有效。如图所示:
写操作
顺序为主与从进行写地址通道握手并传输地址内容,然后在写数据通道握手并传输所读内容,最后再写回应通道握手,并传输写回应数据,时钟上升沿有效。如图所示:
READY,VALID握手
面的时序图进行点说明,在AXI-STREAM总线中,有两个握手信号很关键,明白了握手信号,根据这两个信号就可以进行数据的传输。
在说信号之前,先说一下AXI-stream是分为主设备和从设备的,主设备会发出clk信号和data,从设备在条件允许的情况下,进行数据的读取。
- tvalid信号:此信号说明主机的数据已经准备好了,数据允许被从机读取。
- tready信号:此信号是从机目前可以读取的信号,当该信号置位时说明从机准备好了读取主机的信号;
上图是可以看出tready & tvalid = 1的时刻,数据开始被传输 。
这种握手机制,相互确定了对方是否准备好进行数据传输,一旦双方都确认,数据传输就会开始
总结
1、从机拉高tready信号,表示此刻从机空闲,可以进行数据传输;
2、主机把tdata、tkeep、tuser准备就绪以后,再把tvalid拉高,此时数据在clk的驱动下进行传输;
3、TKEEP是字节修饰符。用来表明TDATA相关字节的内容是否作为数据流的一部分被处理。TKEEP字节修饰符未被确认的那些相关字节是空字节,可以从数据流中去除。
4、tlast 数据包结束;
AXI-stream FIFO IP核
FIFO的深度
可以在16到32768之间变化,具体情况视情况而定,但要是2的n次幂。
Enable packet mode
使能包模式:此项设定需要TLAST信号被使能。FIFO的操作在包模式下被修改为存储传送的数据,直到TLAST信号被响应。当TLAST信号被响应或者FIFO满了,存储的数据将被送至AXI4-Stream master interface.
Asynchronous Clocks
异步时钟:启用后S_AXIS_ACLK和M_AXIS_ACLK将会是异步时钟。
Synchronization Stages across Cross Clock Domain Logic
当启用异步时钟后,才会有该选项,其作用相当于跨时钟域时的打拍操作。一般默认即可。
ACLKEN Conversion Mode
此选项用来选择ACLKEN信号的转换模式。
None 没有和这个IP相关的ACLKEN 信号相关
S AXIS Only 有一个与S_AXIS_ACLKEN 相关联的 S_AXIS_ACLK信号,但没有M_AXIS_ACLKEN信号
M AXIS Only 有一个与M_AXIS_ACLKEN 相关联的 M_AXIS_ACLK信号,但没有S_AXIS_ACLKEN 信号
S AXIS & M AXIS 两个时钟都有与它们相关的ACLKEN信号。
Signal Properties
信号特性:可以看到,软件可以自动计算,当然我们也可以手动修改。
TDATA width (bytes)
参数指定axi4流上TData信号的宽度(以字节为单位接口。此参数是一个整数,可以从0到512不等。设置为0以忽略TDATA信号。如果省略了tdata信号,则tkeep和tstb信号也会省略。如图设置为4则可以看到位宽为32bit。
Enable TSTRB
是否使能TSTRB信号,只有当TData width(bytes)参数大于0时,才能启用此选项。
Enable TKEEP
是否使能TKEEP信号,只有当TData width(bytes)参数大于0时,才能启用此选项。
Enable TLAST
是否使能TKEEP信号,只有当TData width(bytes)参数大于0时,才能启用此选项。
TID width (bits)
用来指定TID信号的位宽,0为忽略,1~32为相应的位宽。
TDEST width (bits)
用来指定TDEST 信号的位宽,0为忽略,1~32为相应的位宽。
TUSER Width (bits)
用来指定TUSER 信号的位宽,0为忽略,1~32为相应的位宽。
关于这些信号的具体含义以及时序关系,可以通过仿真观察。
再来看一下此时的FIFO框图:
其中除了标志信号、时钟、复位信号外,就是两个接口M_AXIS、S_AXIS。
我们知道AXIS是一种半双工的总线,数据传输永远是从MASTER发送给SLAVE,所以可以判断出M_AXIS是发送接口来发送FIFO中的数据,即FIFO读取端;S_AXIS是接收接口来将数据写入FIFO中,即FIFO写入端。
我们在例化IP核之后,会发现生成了这么一大段的代码,我们要怎么塞进去我们的变量
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
axis_data_fifo_0 your_instance_name (
.s_axis_aresetn(s_axis_aresetn), // input wire s_axis_aresetn
.m_axis_aresetn(m_axis_aresetn), // input wire m_axis_aresetn
.s_axis_aclk(s_axis_aclk), // input wire s_axis_aclk
.s_axis_aclken(s_axis_aclken), // input wire s_axis_aclken
.s_axis_tvalid(s_axis_tvalid), // input wire s_axis_tvalid
.s_axis_tready(s_axis_tready), // output wire s_axis_tready
.s_axis_tdata(s_axis_tdata), // input wire [7 : 0] s_axis_tdata
.m_axis_aclk(m_axis_aclk), // input wire m_axis_aclk
.m_axis_aclken(m_axis_aclken), // input wire m_axis_aclken
.m_axis_tvalid(m_axis_tvalid), // output wire m_axis_tvalid
.m_axis_tready(m_axis_tready), // input wire m_axis_tready
.m_axis_tdata(m_axis_tdata), // output wire [7 : 0] m_axis_tdata
.axis_data_count(axis_data_count), // output wire [31 : 0] axis_data_count
.axis_wr_data_count(axis_wr_data_count), // output wire [31 : 0] axis_wr_data_count
.axis_rd_data_count(axis_rd_data_count) // output wire [31 : 0] axis_rd_data_count
);
// INST_TAG_END ------ End INSTANTIATION Template ---------
这就要从手册说起,具体的细节可以去看官方英文文档pg085-axi4stream-infrastructure.pdf
文档中几乎涵盖了全部的说明,这里针对我们所涉及到的进行阅读和理解
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
axis_data_fifo_0 u_axis_data_fifo_0 (
.s_axis_aresetn(s_axis_aresetn), // input wire s_axis_aresetn 复位,低电平有效;当复位信号拉高后的第三个时钟上升沿s_axis_tready信号会自动拉高,该fifo处于等待接收数据状态。
.s_axis_aclk(s_axis_aclk), // input wire s_axis_aclk 写入数据时钟
.s_axis_aclken(s_axis_aclken), // input wire s_axis_aclken 输入时钟使能信号
.s_axis_tvalid(s_axis_tvalid), // input wire s_axis_tvalid 数据有效标志端,将s_axis_tvalid信号置高,在下个时钟上升沿,STREAM FIFO便开始收数
.s_axis_tdata(s_axis_tdata), // input wire [7 : 0] s_axis_tdata 数据输入端
.m_axis_aresetn(m_axis_aresetn), // input wire m_axis_aresetn 复位,低电平有效
.m_axis_aclk(m_axis_aclk), // input wire m_axis_aclk 读取数据时钟
.m_axis_aclken(m_axis_aclken), // input wire m_axis_aclken 输出时钟使能信号
.m_axis_tready(m_axis_tready), // input wire m_axis_tready 当FIFO的后端将m_axis_tready拉高时,MASTER接口便会将数据送出去。
.s_axis_tready(s_axis_tready), // output wire s_axis_tready 当STREAM FIFO的前端有数据需要发送时,在s_axis_tready为高时将s_axis_tvalid信号置高,在下个时钟上升沿,STREAM FIFO便开始收数。接收进最后一个数据的同时,s_axis_tready将会变为低,告诉前级fifo已满,不能再收数据了。
.m_axis_tvalid(m_axis_tvalid), // output wire m_axis_tvalid 当STREAM FIFO接收到数据并传到MASTER接口上时,m_axis_tvalid便会拉高,由于使用的STREAM FIFO为异步时钟模式,数据写入时钟比数据读出时钟要快,而读数据计数器的刷新是在读数据时钟的上升沿,所以可以从仿真图中看到读数据计数器的值是跳跃上升的。
.m_axis_tdata(m_axis_tdata), // output wire [7 : 0] m_axis_tdata 数据输出端;
.axis_data_count(axis_data_count), // output wire [31 : 0] axis_data_count 指示数据FIFO内的写入计数。使用数据包模式FIFO时不产生有效输出。当在接口之间使用公共时钟时,可以使用该信号。
.axis_wr_data_count(axis_wr_data_count), // output wire [31 : 0] axis_wr_data_count 写数据计数器
.axis_rd_data_count(axis_rd_data_count) // output wire [31 : 0] axis_rd_data_count 读数据计数器
);
// INST_TAG_END ------ End INSTANTIATION Template ---------
DAC FIFO实验例化模块
CLK
系统的时钟是50Mhz,所以这里输入clk in是50
按照实验任务要求,DDS工作在100MHz时钟,DAC和AD的接口电路工作在50MHz,所以输出50 和 100
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
clk_wiz_0 u_clk_wiz_0
(
// Clock out ports
.clk_out1(clk_50M), // output clk_out1
.clk_out2(clk_100M), // output clk_out2
// Status and control signals
.reset(~sys_rst_n), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1(sys_clk)); // input clk_in1
// INST_TAG_END ------ End INSTANTIATION Template ---------
添加VIO IP核
设置虚拟按键,来控制DDS输出的波形频率
这里只需要两位长度就可以了
vio_0 u_vio_0 (
.clk(sys_clk), // input wire clk
.probe_out0(key_PINC) // output wire [1 : 0] probe_out0
);
添加AXI-Stream-Data FIFO IP核
核心就是AXI-Stream-Data FIFO的配置,相关的详细内容已经在前面介绍过了
这里选择FIFO的位深为1024
选择异步,也就是输入输出时钟频率不同
TDATA Width数据宽度1 Byte,也就是8 bit
这个IP核最让我头疼的就是这个部分了,涉及到的参数太多了,并且是一个典型的AXI通信
捣鼓了两三天后,起始也没有想象中那么复杂,其实就按照AXI通信的原理,还有说明往里面填写变量就可以了,并且FIFO是个半双工,这就比较好缕清一些关系
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
axis_data_fifo_0 u_axis_data_fifo_0 (
// 系统端口
.s_axis_aresetn(fifo_s_axis_aresetn), // input wire s_axis_aresetn 复位,低电平有效;当复位信号拉高后的第三个时钟上升沿s_axis_tready信号会自动拉高,该fifo处于等待接收数据状态。
.s_axis_aclk(fifo_s_axis_aclk), // input wire s_axis_aclk 写入数据时钟
.m_axis_aclk(fifo_m_axis_aclk), // input wire m_axis_aclk 读取数据时钟
//写FIFO端口
.s_axis_tvalid(dds_m_axis_data_tvalid), // input wire s_axis_tvalid 数据有效标志端,将s_axis_tvalid信号置高,在下个时钟上升沿,STREAM FIFO便开始收数
.s_axis_tready(fifo_s_axis_tready), // output wire s_axis_tready FIFO满了拉低,当FIFO的后端将m_axis_tready拉高时,MASTER接口便会将数据送出去。
.s_axis_tdata(dds_m_axis_data_tdata), // input wire [7 : 0] s_axis_tdata 数据输入端
.axis_wr_data_count(fifo_axis_wr_data_count), // output wire [31 : 0] axis_wr_data_count 已经写入的数据量
//读FIFO端口
.m_axis_aresetn(fifo_m_axis_aresetn), // input wire m_axis_aresetn
.m_axis_tready(fifo_m_axis_tready), // input wire m_axis_tready
.m_axis_tvalid(fifo_m_axis_tvalid), // output wire m_axis_tvalid
.m_axis_tdata(fifo_m_axis_tdata), // output wire [7 : 0] m_axis_tdata 数据输出端;
.axis_rd_data_count(fifo_axis_rd_data_count), // output wire [31 : 0] axis_rd_data_count 可读数据量
.axis_data_count(fifo_axis_data_count) // output wire [31 : 0] axis_data_count 指示数据FIFO内的写入计数
);
// INST_TAG_END ------ End INSTANTIATION Template ---------
可以分成三个部分
第一个就是系统端口
这里就包括了复位,还有写入和读取的时钟
// 系统端口
.s_axis_aresetn(fifo_s_axis_aresetn), // input wire s_axis_aresetn 复位,低电平有效;当复位信号拉高后的第三个时钟上升沿s_axis_tready信号会自动拉高,该fifo处于等待接收数据状态。
.s_axis_aclk(fifo_s_axis_aclk), // input wire s_axis_aclk 写入数据时钟
.m_axis_aclk(fifo_m_axis_aclk), // input wire m_axis_aclk 读取数据时钟
第二部分就是写端口,这里指的是DDS生成的数据,写到我们的FIFO中
.s_axis_tvalid(dds_m_axis_data_tvalid)
,当dds_m_axis_data_tvalid
是高电平时候,FIFO就开始接收数据,这个变量需要从外部输入,分析我们的整体设计,这个变量应该是DDS IP核产生,DDS IP核的.m_axis_data_tvalid(dds_m_axis_data_tvalid)
,产生输出,然后输入到FIFO
.s_axis_tready(fifo_s_axis_tready)
,当fifo_s_axis_tready
是高电平时侯,代表FIFO还没有满,当FIFO满了的时候,fifo_s_axis_tready
会拉低,这个是输出信号,要反馈给DDS,告诉DDS IP核FIFO已经满了
.s_axis_tdata(dds_m_axis_data_tdata),
,其中dds_m_axis_data_tdata
就是我们要真正写入FIFO中的数据,这里就是DDS生成的数据
//写FIFO端口
.s_axis_tvalid(dds_m_axis_data_tvalid), // input wire s_axis_tvalid 数据有效标志端,将s_axis_tvalid信号置高,在下个时钟上升沿,STREAM FIFO便开始收数
.s_axis_tready(fifo_s_axis_tready), // output wire s_axis_tready FIFO满了拉低,当FIFO的后端将m_axis_tready拉高时,MASTER接口便会将数据送出去。
.s_axis_tdata(dds_m_axis_data_tdata), // input wire [7 : 0] s_axis_tdata 数据输入端
.axis_wr_data_count(fifo_axis_wr_data_count), // output wire [31 : 0] axis_wr_data_count 已经写入的数据量
第三个部分就是读FIFO端口,这里指的是从FIFO中读取数据,也就是经过存储调节速率后的数据要传入下一个目标模块
.m_axis_aresetn(fifo_m_axis_aresetn),
,当fifo_m_axis_aresetn
为高电平时,拉高复位,系统进入工作状态
.m_axis_tready(fifo_m_axis_tready),
当fifo_m_axis_tready
为高电平时,FIFO需要保持向外读取,因为输入时钟比输出时钟高,所以这里读取要一直为高才可以
.m_axis_tvalid(fifo_m_axis_tvalid),,
这里的fifo_m_axis_tvalid
是输出,告诉下一个模块数据开始传输
.m_axis_tdata(fifo_m_axis_tdata),
,数据输出fifo_m_axis_tdata
//读FIFO端口
.m_axis_aresetn(fifo_m_axis_aresetn), // input wire m_axis_aresetn
.m_axis_tready(fifo_m_axis_tready), // input wire m_axis_tready
.m_axis_tvalid(fifo_m_axis_tvalid), // output wire m_axis_tvalid
.m_axis_tdata(fifo_m_axis_tdata), // output wire [7 : 0] m_axis_tdata 数据输出端;
.axis_rd_data_count(fifo_axis_rd_data_count), // output wire [31 : 0] axis_rd_data_count 可读数据量
添加DDS IP核
对于DDS IP核设置输入频率 100 MHz,输出数据位宽8 bit,相位宽度16bit
参数控制,仅输出sine波形
DDS带TREADY
配置完成后的示意图
DDS IP核的配置核FIFO IP核的配置联系紧密,这里重点关注的就是两个输入信号,两个输出信号
输入信号一个是跟频率控制有关,DDS作为从机,接受频率控制模块DDS_frequency_value
的控制
.s_axis_config_tdata(DDS_frequency_value), // input wire [15 : 0] s_axis_config_tdata
另一个输入信号就是产生信号的标志,FIFO模块发出fifo_s_axis_tready
为高电平时,表示FIFO目前可以继续接收数据, .m_axis_data_tready(fifo_s_axis_tready),
便可以继续生成正弦信号
.m_axis_data_tready(fifo_s_axis_tready), // input wire m_axis_data_tready
输出信号dds_m_axis_data_tvalid
为高电平表示DDS可以生成正弦信号,输入到FIFO的指定端口,高速FIFO这边正弦信号正常生成
.m_axis_data_tvalid(dds_m_axis_data_tvalid), // output wire m_axis_data_tvalid
输出信号dds_m_axis_data_tdata
就是我们实际需要的正弦波数据
.m_axis_data_tdata(dds_m_axis_data_tdata), // output wire [7 : 0] m_axis_data_tdata
然后就是完整的DDS配置代码
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
dds_compiler_0 u_dds_compiler_0 (
.aclk(clk_100M), // input wire aclk
.s_axis_config_tvalid(dds_s_axis_config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tdata(DDS_frequency_value), // input wire [15 : 0] s_axis_config_tdata
.m_axis_data_tready(fifo_s_axis_tready), // input wire m_axis_data_tready
.m_axis_phase_tready(fifo_s_axis_tready), // input wire m_axis_phase_tready
.m_axis_data_tvalid(dds_m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(dds_m_axis_data_tdata), // output wire [7 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(dds_m_axis_phase_tvalid), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(dds_m_axis_phase_tdata), // output wire [15 : 0] m_axis_phase_tdata
.s_axis_config_tready(dds_s_axis_config_tready) // output wire s_axis_config_tready
);
// INST_TAG_END ------ End INSTANTIATION Template ---------
添加ILA IP核
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
ila_0 u_ila_0 (
.clk(clk_50M), // input wire clk
.probe0(key_PINC), // input wire [1:0] probe0
.probe1(dds_m_axis_data_tdata), // input wire [7:0] probe1
.probe2(fifo_m_axis_tdata), // input wire [7:0] probe2
.probe3(da_data), // input wire [7:0] probe3
.probe4(fifo_axis_data_count) // input wire [31:0] probe4
);
// INST_TAG_END ------ End INSTANTIATION Template ---------
DAC FIFO实验程序代码
顶层模块
首先贴一下全部的代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/03/13 10:26:26
// Design Name:
// Module Name: da_fifo
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module da_fifo(
input sys_clk,
input sys_rst_n,
// DA芯片接口
output da_clk,
output [7 : 0] da_data,
// AD芯片接口
output ad_clk,
input [7 : 0] ad_data
);
wire clk_50M; // PLL产生50Mhz时钟
wire clk_100M; // PLL产生100Mhz时钟
wire locked; // PLL lock信号,可作为系统复位 高电平有效
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
clk_wiz_0 u_clk_wiz_0
(
// Clock out ports
.clk_out1(clk_50M), // output clk_out1
.clk_out2(clk_100M), // output clk_out2
// Status and control signals
.reset(~sys_rst_n), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1(sys_clk)); // input clk_in1
// INST_TAG_END ------ End INSTANTIATION Template ---------
// VIO按键控制频率
wire [1 : 0] key_PINC;
vio_0 u_vio_0 (
.clk(sys_clk), // input wire clk
.probe_out0(key_PINC) // output wire [1 : 0] probe_out0
);
//input
wire [0:0] fre_m_axis_config_tvalid;
// 信号频率控制模块
wire [15 : 0] DDS_frequency_value; // 频率字
Fword_set u_Fword_set (
.clk(clk_100M),
.rst_n(sys_rst_n),
.key_PINC(key_PINC),
.fre_m_axis_config_tvalid(fre_m_axis_config_tvalid),
.DDS_frequency_value(DDS_frequency_value)
);
//output
wire [0 : 0] dds_m_axis_data_tvalid;
wire [7 : 0] dds_m_axis_data_tdata;
wire [0 : 0] dds_m_axis_phase_tvalid;
wire [15 : 0] dds_m_axis_phase_tdata;
wire [0 : 0] dds_s_axis_config_tready;
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
dds_compiler_0 u_dds_compiler_0 (
.aclk(clk_100M), // input wire aclk
.s_axis_config_tvalid(fre_m_axis_config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tdata(DDS_frequency_value), // input wire [15 : 0] s_axis_config_tdata
.s_axis_config_tready(dds_s_axis_config_tready), // output wire s_axis_config_tready
.m_axis_data_tready(fifo_s_axis_tready), // input wire m_axis_data_tready
.m_axis_phase_tready(fifo_s_axis_tready), // input wire m_axis_phase_tready
.m_axis_data_tvalid(dds_m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(dds_m_axis_data_tdata), // output wire [7 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(dds_m_axis_phase_tvalid), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(dds_m_axis_phase_tdata) // output wire [15 : 0] m_axis_phase_tda以上是关于ZYNQ从入门到秃头11 DAC FIFO实验(AXI-stream FIFO IP核配置)的主要内容,如果未能解决你的问题,请参考以下文章
ZYNQ从入门到秃头08 FPGA片内异步FIFO读写测试实验
ZYNQ从入门到秃头08 FPGA片内异步FIFO读写测试实验
ZYNQ从入门到秃头09番外 DDS增强版实验(基于ALINX 7020 && AN108)
ZYNQ从入门到秃头10 DDS增强版实验ADDA测试(基于ALINX 7020 && AN108)