FPGA 20个例程篇:20.USB2.0/RS232/LAN控制并行DAC输出任意频率正弦波、梯形波、三角波、方波(四)
接着同样地我们也需要完成对千兆网口ETH模块和USB2.0模块的编写,实际上和UART串口模块的设计思想大同小异,也同样地需要完成两项关键功能即识别并解析报文、接收并发送数据,千兆网口ETH和USB2.0的底层驱动在前面的例程中也详细说明了,所以在这里笔者不想再重复赘述,当然相比之前千兆网口实现ARP、ICMP协议和UDP报文的自发自收、USB2.0接收并回复CRC16校验等例程,显然要对之前的代码进行一些修改,使其满足整个项目的实际需求。
典型地在eth_control_top顶层模块中需要把UDP协议收到的数据、在usb_control_top顶层模块中需要把USB2.0中收到的数据,通过信号udp_dout和udp_dout_vld、信号rxd_data和rxd_data_vld分别例化出来,再在顶层模块中完成报文解析,有效提取出1字节的指令码和4字节的数据码送到下游指令解析模块中进行解析,指令解析模块把相应的参数通过FIFO写入任意波和正弦波模块中即可实现上位机程控开发板输出不同波形的效果。
在这里笔者就只简单说明下ETH顶层模块和USB2.0顶层模块的代码设计,如图1和2所示是两个顶层模块的代码设计供大家参考,其余底层模块的修改细节可直接查看源工程代码即可。
图1 千兆网口顶层模块的代码设计
图2 USB2.0接口顶层模块的代码设计
在介绍完RS232串口、ETH千兆网口、USB2.0接口顶层模块的代码设计后,下面就去着重说明指令解析模块的代码设计,如表1所示是command_detect模块信号列表,如图3所示是指令解析模块的代码设计。
在这个模块中我们需要去实现下面几个重要的能:1. 解析上游模块三种接口中传来的指令码和数据码;2. 如果指令码是0x00即检测当前链路连接是否正常则回复“+RIGHT”或“-ERROR”;3. 使用FIFO解决跨时钟域的数据传输问题,但对于指令码0x01到0x07这7条设置指令全都用FIFO缓存数据码,则要用21个异步FIFO将会导致设计非常繁琐,这里每种接口用2个异步FIFO缓存数据码、1个异步FIFO缓存“+RIGHT”或“-ERROR”回复报文,所以把指令码0x02、0x05、0x06、0x07即设置波形种类、上升时间、下降时间、保持时间都存储到一个104位宽的FIFO中,而把指令码0x01、0x03、0x04即设置DAC输出开关、正弦波频率、相位控制字存到一个65位宽的FIFO中;4. 当然如果FIFO接到数据码就立刻发送到下游任意波模块和正弦波模块显然会出现问题,典型地如任意波模块状态机跑飞,正弦波相位控制字偏移不对等,所以需要下游模块传来wave_rdy和ddsip_rdy后才把FIFO中的数据写入;5. 在前面Modelsim的仿真中也注意到正弦波的相位控制字需要复位DDS IP核后才方便观察起始相位,所以在这个模块里设计选取开关机的上升沿作为DDS IP核的复位标志,即检测到DAC输出开启后输出4个时钟周期的DDS IP核复位低电平,再向正弦波模块中输出dds_dout_freq和dds_dout_freq_vld信号。
信号列表 | ||
信号名 | I/O | 位宽 |
clk | I | 1 |
clk_120m | I | 1 |
usb_clkout | I | 1 |
gmii_rx_clk | I | 1 |
gmii_tx_clk | I | 1 |
dac_clk | I | 1 |
rst_n | I | 1 |
wave_rdy | I | 1 |
ddsip_rdy | I | 1 |
uart_txd_rdy | I | 1 |
uart_din_cmd | I | 8 |
uart_din_data | I | 32 |
uart_din_vld | I | 1 |
uart_dout | O | 8 |
uart_dout_vld | O | 1 |
usb_txd_rdy | I | 1 |
usb_din_cmd | I | 8 |
usb_din_data | I | 32 |
usb_din_vld | I | 1 |
usb_rdfifo_empty | O | 1 |
usb_dout | O | 8 |
usb_dout_vld | O | 1 |
eth_txd_rdy | I | 1 |
eth_din_cmd | I | 8 |
eth_din_data | I | 32 |
eth_din_vld | I | 1 |
udp_tx_en | O | 1 |
eth_dout | O | 8 |
eth_dout_vld | O | 1 |
power_onoff | O | 1 |
sinel_waveh_mode | O | 1 |
wave_dout | O | 104 |
wave_dout_vld | O | 1 |
ddsip_sclr | O | 1 |
dds_dout_freq | O | 32 |
dds_dout_freq_vld | O | 1 |
dds_dout_phase | O | 32 |
dds_dout_phase_vld | O | 1 |
表1 command_detect模块信号列表
图3 指令解析模块的代码设计