USB2.0 UTMI PHY芯片测试

1. 前言

为验证一款UTMI接口的PHY芯片数据通路是否正常,功能实现是否满足需求,特搭建此工程进行测试。

1.1 平台

FPGA芯片:Xilinx XCVU440
PHY芯片:CY7C68000
平台:Vivado 2019.2

2. 技术背景

下文是我写的几篇技术背景:
CY7C68000介绍

开源项目UTMI介绍

USB2.0介绍

PHY 芯片接口:
USB2.0 UTMI PHY芯片测试_第1张图片
接口稍微有点不同,这个芯片支持高低八位分别使用的模式,具体可以看一下第一篇博客。

3. 操作

打算使用开源项目中的一下模块来实现
USB2.0 UTMI PHY芯片测试_第2张图片
此模块可以将 UTMI接口内部数据接口

如何对内部数据接口进行数据的读写呢?
我发现这个内部数据总线接口可以较好的和AXI4-S总线进行连接,就是数据位宽对不上,稍微处理一下就好。

添加一个MicroBlaze,用MicroBlaze对接口访问,代码编写起来更加方便。

MicroBlaze部分这么搭建:
USB2.0 UTMI PHY芯片测试_第3张图片
添加了一个AXI4-S 转 AXI4-Full的FIFO,就能对数据进行读写了。
USB2.0 UTMI PHY芯片测试_第4张图片

该IP的介绍。使用memory mapped的形式访问AXI4-S接口,看来这样使用是没错的可以使用的。

USB2.0 UTMI PHY芯片测试_第5张图片

最终架构:

USB2.0 UTMI PHY芯片测试_第6张图片
加了个时钟模块和一个vio模块
UTMI走60MHz,MicroBlaze走100MHz;
vio用来提供外部时钟复位。

USB2.0 UTMI PHY芯片测试_第7张图片
将所有接口都加上了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





    );
//SYS

(* mark_debug="true" *)wire    reset;  
wire        locked;
wire        clk_100m;
wire        clk_60m;    
    
// UTMI Interface
(* 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;	         // High Speed Mode
wire		usb_reset;	         // USB Reset
wire		usb_suspend;	     // USB Suspend
wire		usb_attached;	     // Attached to USB
//   input clk_in1_0;
//   input dcm_locked_0;
//   input reset_rtl_0;


(* 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
   (
    // Clock out ports
    .clk_out1(clk_100m),     // output clk_out1
    .clk_out2(clk_60m),     // output clk_out2
    // Status and control signals
    .reset(1'b0), // input reset
    .locked(locked),       // output locked
   // Clock in ports
    .clk_in1(PHY_CLK));      // input clk_in1

    vio_0 u1 (
        .clk(clk_100m),                // input wire clk
        .probe_out0(reset)  // output wire [0 : 0] probe_out0
    );


    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));


// UTMI Interface
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. 总结

待测试,测试完成再写总结。提供一种思路

你可能感兴趣的:(工程实操,USB系列,fpga开发,USB2.0,UTMI,MicroBlaze)