基于CY7C68013A芯片的USB2.0设计

项目简介

我们前面已经写过了USB3.0的FPGA实现,所用到的芯片是FX600Q芯片,这次我们讲解USB2.0的FPGA代码的编写。我们用到的芯片是Cypress厂家的Cy7C68013A,该款芯片在市场上的应用率极广,我们这里不涉及USB的具体协议,也不涉及固件的写法,因为前者已经封装进了USB芯片,后者Cypress厂家给出了例程。与USB3.0一样,我们能将USB芯片看成一个FIFO进行书写。

本次实验所用到的软硬件环境如下:
FPGA开发板:锆石A4plus开发板
软件环境:quartus II 13.1
上位机软件:Cypress官方提供(会放进群里面,有需要的进群下载)

CY7C68013A芯片介绍

我们从开发板的硬件电路中找到关于该款USB芯片的介绍:
在这里插入图片描述
从上图可以看出,芯片中含有一个8051的核。该电路在开发板上的连线如下:
在这里插入图片描述
其实USB芯片在下载官方的固件之后,我们可以把他等价成一个FIFO,如下图:
在这里插入图片描述
当然我们也可以对USB的固件进行编程,然后对数据进行一定的处理,但不在本次实验内容中。
接下来,我们将对上面的引脚做一些简单的说明,当然想具体了解的可以查阅技术手册:
USB_CLKOUT:USB芯片输出时钟引脚,本程序中不使用,不多关注
IFCLK:slave fifo的同步时钟信号,在USB工作在slave模式下,FIFO的同步信号,也是本次实验中使用的时钟引号。
FLAGA:slave FIFO是否可编程的标志信号,在我们的程序中也使用不到。
FLAGB:FIFO的满信号
FLAGC:FIFO的空信号
SLCS:USB芯片的片选信号,低电平使能
SLWR:USB芯片等价FIFO的写信号,低电平有效
SLRD:USB芯片等价FIFO的读信号,低电平有效
SLOE:USB芯片输出的使能信号,该信号为低电平时,USB芯片作为输出,高电平作为输入。
FIFOADR:该款USB芯片相当于4个FIFO,该信号控制着哪一个FIFO被选择,4个FIFO的编号是2,4,6,8分别对应00,01,10,11。具体哪个FIFO被选择是由固件所确定的,在上位机软件上可以查看。
该款USB芯片的驱动与固件程序由于CSDN无法上传文件,我们放在了群里面,需要的同学进群自己下载即可:

其中1是芯片的驱动,2是Cypress官方的配套软件与固件。

CY7C68013A芯片读写时序控制

这里我们从技术手册中找到芯片的读写时序,这里以同步读写为例:

在这里插入图片描述
由于这里时序特别简单,我们便不再画出具体的时序图,直接由上面的时序图进行写代码,相信大家从代码中很容易就可以读懂时序。

CY7C68013A芯片读写代码

USB2.0写代码:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : usb_write.v
// Create Time  : 2020-02-19 12:53:38
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module usb_write(
    //System Interfaces
    input                   rst_n           ,
    //USB Interfaces
    input                   usb_ifclk       ,
    input                   usb_full        ,
    output  wire            usb_slcs        ,
    output  wire            usb_slwr        ,
    output  wire            usb_slrd        ,
    output  wire            usb_sloe        ,
    output  wire    [ 1:0]  usb_fifoadr     ,
    output  reg     [15:0]  usb_data    
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
reg                         usb_slwr_r      ;
 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign      usb_slcs        =       1'b0;
assign      usb_slwr        =       ~((usb_full == 1'b1) && (usb_slwr_r == 1'b0));
assign      usb_slrd        =       1'b1;
assign      usb_sloe        =       1'b1;
assign      usb_fifoadr     =       2'b10;

always @(posedge usb_ifclk or negedge rst_n)
    if(rst_n == 1'b0)
        usb_slwr_r          <=      1'b1;
    else if(usb_full == 1'b1)
        usb_slwr_r          <=      1'b0;
    else
        usb_slwr_r          <=      1'b1;

always @(posedge usb_ifclk or negedge rst_n)
    if(rst_n == 1'b0)
        usb_data            <=      16'd0;
    else if(usb_slwr == 1'b0)
        usb_data            <=      usb_data + 1'b1;
    else
        usb_data            <=      usb_data;

endmodule

USB2.0读代码:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : usb_read.v
// Create Time  : 2020-02-19 13:50:12
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module usb_read(
    //System Interfaces
    input                   rst_n           ,
    //USB Interfaces
    input                   usb_ifclk       ,
    input                   usb_empty       ,
    output  wire            usb_slcs        ,
    output  wire            usb_slwr        ,
    output  wire            usb_slrd        ,
    output  wire            usb_sloe        ,
    output  wire    [ 1:0]  usb_fifoadr     ,
    input           [15:0]  usb_data        ,
    //Communication Interfaces
    output  reg             data_en         ,
    output  reg     [15:0]  data            


);
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
reg                         usb_slrd_r      ;
 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign      usb_slcs        =       1'b0;
assign      usb_slrd        =       ~((usb_empty == 1'b1) && (usb_slrd_r == 1'b0));
assign      usb_sloe        =       1'b0;
assign      usb_slwr        =       1'b1;
assign      usb_fifoadr     =       2'b00;

always @(posedge usb_ifclk or negedge rst_n)
    if(rst_n == 1'b0)
        usb_slrd_r          <=      1'b1;    
    else if(usb_empty == 1'b1)
        usb_slrd_r          <=      1'b0;
    else 
        usb_slrd_r          <=      1'b1;

always @(posedge usb_ifclk or negedge rst_n)
    if(rst_n == 1'b0)
        data_en             <=      1'b0;
    else if(usb_slrd == 1'b0)
        data_en             <=      1'b1;
    else
        data_en             <=      1'b0;

always @(posedge usb_ifclk)
    data                <=      usb_data;
    
endmodule

从上面可以看出控制一个USB2.0的芯片其实就是相当于控制一个FIFO。

USB2.0的测试结果

我们在quartus II中分别下载上面两个程序到开发板中,观察上位机软件的现象。

对于USB写模块,我们在上位机CyConsole看到如下现象,证明了我们程序的正确性:
在这里插入图片描述
在验证USB读模块的正确性的时候,我们在上位机软件中发送如下数据:
在这里插入图片描述
然后利用Signaltap进行抓取数据验证FPGA接受到数据的正确性,抓到图的数据如下:
在这里插入图片描述
将Signaltap中抓取到的数据与CyConsole发送的数据对比,我们可以验证读模块的正确性。

结束语

对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
在这里插入图片描述

发布了34 篇原创文章 · 获赞 17 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zhangningning1996/article/details/104392835