ZYNQ从入门到秃头10 DAC FIFO实验(AXI-stream FIFO IP核配置)

Posted “逛丢一只鞋”

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZYNQ从入门到秃头10 DAC FIFO实验(AXI-stream FIFO IP核配置)相关的知识,希望对你有一定的参考价值。

文章目录

实验任务

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分析频谱,验证频率正确。
本实验是一个典型的带反向流控的跨时钟域传输信号的例子

AXI-stream 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,从设备在条件允许的情况下,进行数据的读取。

  1. tvalid信号:此信号说明主机的数据已经准备好了,数据允许被从机读取。
  2. 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 ---------

例化模块

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

设置虚拟按键,来控制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

核心就是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

对于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


//----------- 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 ---------

程序代码

顶层模块

首先贴一下全部的代码

`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_tdata
  
);
// INST_TAG_END ------ End INSTANTIATION Template ---------


wire				fifo_s_axis_aresetn;	
wire				fifo_s_axis_aclk;
wire				fifo_m_axis_aclk;

// 写FIFO端口			
wire  	[31 : 0] 	fifo_axis_wr_data_count;
wire			    fifo_s_axis_tready;               // FIFO tready	

// 读FIFO端口
wire				da_m_axis_aresetn;	
wire				da_m_axis_tready;		

wire				fifo_m_axis_tvalid;		
wire  	[7 ZYNQ从入门到秃头08 FPGA片内异步FIFO读写测试实验

ZYNQ从入门到秃头08 FPGA片内异步FIFO读写测试实验

ZYNQ从入门到秃头10 DDS增强版实验ADDA测试(基于ALINX 7020 && AN108)

ZYNQ从入门到秃头09番外 DDS增强版实验(基于ALINX 7020 && AN108)

ZYNQ从入门到秃头07 FPGA 片内 RAM && ROM 读写测试实验

ZYNQ从入门到秃头07 FPGA 片内 RAM && ROM 读写测试实验