1. 前言
为验证一款UTMI接口的PHY芯片数据通路是否正常,功能实现是否满足需求,特搭建此工程进行测试。
1.1 平台
FPGA芯片:Xilinx XCVU440 PHY芯片:CY7C68000 平台:Vivado 2019.2
2. 技术背景
下文是我写的几篇技术背景: CY7C68000介绍
开源项目UTMI介绍
USB2.0介绍
PHY 芯片接口: 接口稍微有点不同,这个芯片支持高低八位分别使用的模式,具体可以看一下第一篇博客。
3. 操作
打算使用开源项目中的一下模块来实现 此模块可以将 UTMI接口转内部数据接口。
如何对内部数据接口进行数据的读写呢? 我发现这个内部数据总线接口可以较好的和AXI4-S总线进行连接,就是数据位宽对不上,稍微处理一下就好。
添加一个MicroBlaze,用MicroBlaze对接口访问,代码编写起来更加方便。
MicroBlaze部分这么搭建: 添加了一个AXI4-S 转 AXI4-Full的FIFO,就能对数据进行读写了。
该IP的介绍。使用memory mapped的形式访问AXI4-S接口,看来这样使用是没错的可以使用的。
最终架构:
加了个时钟模块和一个vio模块 UTMI走60MHz,MicroBlaze走100MHz; vio用来提供外部时钟复位。
将所有接口都加上了debug。
顶层代码:
module usb_utmi_top(
(* mark_debug="true" *)input PHY_CLK,
(* mark_debug="true" *)output RESET,
(* mark_debug="true" *)inout [15:0] DATA,
(* mark_debug="true" *)output XCVR_SEL,
(* mark_debug="true" *)output TERM_SEL,
(* mark_debug="true" *)output SUSPEND,
(* mark_debug="true" *)input [1:0] LINESTATE,
(* mark_debug="true" *)output [1:0] OP_MODE,
(* mark_debug="true" *)output TX_VALID,
(* mark_debug="true" *)input TX_READY,
(* mark_debug="true" *)input RX_ACTIVE,
(* mark_debug="true" *)input RX_ERROR,
(* mark_debug="true" *)input RX_VALID,
(* mark_debug="true" *)inout VALIDH,
(* mark_debug="true" *)output DATA16_8,
(* mark_debug="true" *)output UNI_BIDI
);
(* mark_debug="true" *)wire reset;
wire locked;
wire clk_100m;
wire clk_60m;
(* mark_debug="true" *)wire[7:0] rx_data;
(* mark_debug="true" *)wire rx_valid, rx_active, rx_err;
(* mark_debug="true" *)wire[7:0] tx_data;
(* mark_debug="true" *)wire tx_valid,tx_ready,tx_first,tx_valid_last;
wire[31:0] AXI_STR_TXD_0_tdata;
wire mode_hs;
wire usb_reset;
wire usb_suspend;
wire usb_attached;
(* mark_debug="true" *)wire[15:0] data_out_w;
(* mark_debug="true" *)wire[15:0] data_in_w;
assign UNI_BIDI =1'b1;
assign DATA16_8 =1'b0;
assign RESET =reset;
assign data_in_w = DATA;
assign DATA = TX_READY ? data_out_w : 16'hzzzz;
assign tx_data = AXI_STR_TXD_0_tdata[7:0];
clk_wiz_0 u0
(
.clk_out1(clk_100m),
.clk_out2(clk_60m),
.reset(1'b0),
.locked(locked),
.clk_in1(PHY_CLK));
vio_0 u1 (
.clk(clk_100m),
.probe_out0(reset)
);
design_1_wrapper u2(
.AXI_STR_RXD_0_tdata( {4{rx_data}} ),
.AXI_STR_RXD_0_tlast(),
.AXI_STR_RXD_0_tready(),
.AXI_STR_RXD_0_tvalid(rx_valid),
.AXI_STR_TXD_0_tdata(AXI_STR_TXD_0_tdata ),
.AXI_STR_TXD_0_tlast(tx_valid_last),
.AXI_STR_TXD_0_tready(tx_ready),
.AXI_STR_TXD_0_tvalid(tx_valid),
.clk_in1_0(clk_100m),
.dcm_locked_0(locked),
.reset_rtl_0(1'b1));
usbf_utmi_if u3(
.phy_clk( PHY_CLK ),
.rst( reset ),
.DataOut( data_out_w[15:8]),
.TxValid( TX_VALID ),
.TxReady( TX_READY ),
.RxValid( RX_VALID ),
.RxActive( RX_ACTIVE ),
.RxError( RX_ERROR ),
.DataIn( data_in_w[7:0] ),
.XcvSelect( XCVR_SEL ),
.TermSel( TERM_SEL ),
.SuspendM( SUSPEND ),
.LineState( LINESTATE ),
.OpMode( OP_MODE ),
.usb_vbus( ),
.rx_data( rx_data ),
.rx_valid( rx_valid ),
.rx_active( rx_active ),
.rx_err( rx_err ),
.tx_data( tx_data ),
.tx_valid( tx_valid ),
.tx_valid_last( tx_valid_last ),
.tx_ready( tx_ready ),
.tx_first( tx_first ),
.mode_hs( mode_hs ),
.usb_reset( usb_reset ),
.usb_suspend( usb_suspend ),
.usb_attached( usb_attached ),
.resume_req( )
);
搭建完成后编译,会遇到组合逻辑环的问题,是开源项目自带的,我加了一条约束暂时解决了。 组合逻辑环解决
MicroBlaze代码用C写,现场编辑,看看效果。
4. 总结
待测试,测试完成再写总结。提供一种思路
|