2962|10

32

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

安路SF1系列FPGA(三)USB2.0高速通信-1 [复制链接]

 
 
本帖最后由 瓜弟 于 2023-3-28 21:46 编辑

        FPGA使用USB与PC进行通信的方式通常有以下几种方案:1、通过FT232、CH340等转接芯片使用SPI、UART进行通信;2、CY7C68013等第三方MCU进行转发;3、直接使用FPGA的IO口进行低速USB通信;4、使用FPGA+USBPHY进行高速通信。本文使用外接USBPHY进行USB2.0高速通信,方案框图如下

1、概述

        USBD协议栈使用ASICS.ws公司的开源USB2_Dev核,该公司开源产品GitHub地址为www-asics-ws · GitHub,框图如下图所示。从框图可知,该IP核与FPGA与其他功能模块之间使用Wishbone总线进行通信,与USBPHY芯片之间使用UTMI接口进行通信,同时移植过程中还需要实现SSRAM功能。通过该IP,可实现USB2.0的高速通信(480Mbps)。由于安路的SF1系列FPGA的RISCV硬核与外部交互的总线为AHB,所以再USBD核与AHB总线之间需要使用AHB转Wishbone总线模块。该USBD核与USBPHY之间的接口使用的是UTMI接口,该接口信号众多,且当前UTMI接口的USBPHY芯片也较少,故使用UTMI2ULPI接口,将其转换为ULPI接口以减少IO口的占用,该模块使用开源项目core_ulpi_wrapper

2、AHB2Wishbone总线转换

        

        如上图所示为Wishbone的主从连接关系,各引脚功能如下:

CLK_O 输出信号,系统时钟,作为MASTER和SLAVE的时钟输入
RST_O 输出复位信号,作为MASTER和SLAVE的复位输入,使得WISHBONE接口内部的状态机全部恢复到起始态
CLK_I 输入信号,MASTER和SLAVE的时钟输入端,所有WISHBONE输出信号都在CLK-I的上升沿有效
DAT_O 数据输出信号,最大位宽为64位
RST_I 输入信号,使得WISHBONE接口内部的状态机全部恢复到起始态
TGD_I 输入信号,数据标签类型
TGD_O 输出信号,数据标签类型
ACK_I 输入信号,确认信号,当该信号有效时,表明一个总线周期结束
ADR_O 输出信号,地址输出
CYC_O 周期输出信号,当该信号有效,表明进程中的总线是有效的,即它确定了总线周期的持续时间。CYC_O从数据传输的第一个比特开始有效,到数据传输结束为止
ERR_l 输入信号,当该信号有效,表明总线周期非正常结束,表示有错误发生
LOCK_O 输出信号,当该信号有效,表明当前总线周期锁定,不能被其他进程中断
RTY_I 输入信号,当该信号有效,表明MASTER还没有准备好接收或发送数据,重新请求总线
SEL_O 输出信号,用于选择数据信号线的输出
STB_O 输出信号,表明一个有效数据传送周期
WE_O 读使能信号,决定信号的读和写功能

        上述信号可裁剪,本文使用了ADR_O、WE_O、STB_O、SEL_O、ACK_I、CLK_O、RST_O等信号,AHB转Wishbone代码如下

  • module AHB2WB
  • (
  • input wire CLK,
  • input wire RSTn,
  • output reg[31:0] WB_ADDR,
  • input wire[31:0] WB_DATA_IN,
  • output reg[31:0] WB_DATA_OUT,
  • output reg WB_WE,
  • output reg[3:0] WB_SEL,
  • output reg WB_STB,
  • input wire WB_ACK,
  • output reg WB_CYC,
  • input wire HSEL,
  • input wire[1:0] HTRANS,
  • input wire[31:0] HADDR,
  • input wire HWRITE,
  • input wire[2:0] HSIEZ,
  • input wire[2:0] HBURST,
  • input wire[3:0] HPROT,
  • input wire[31:0] HWDATA,
  • output reg[31:0] HRDATA,
  • output reg HREADY,
  • output reg[1:0] HRESP
  • );
  • parameter HTRANS_IDLE = 2'b00; //Slave忽略掉此时的传输
  • parameter HTRANS_BUSY = 2'b01; //表示master正在处理数据,slave需要忽略掉此时的传输
  • parameter HTRANS_NONSEQ = 2'b10; //表明当前是单笔的数据,或者是Burst的第一笔数据
  • parameter HTRANS_SEQ = 2'b11; //是Burst传输的剩余数据
  • parameter HBURST_SINGLE = 3'b000; //单笔数据传输
  • parameter HBURST_INCR = 3'b000; //不定长递增方式批量传输
  • parameter HBURST_WRAP4 = 3'b000; //4个数据回绕方式批量传输
  • parameter HBURST_INCR4 = 3'b000; //4个数据递增方式批量传输
  • parameter HBURST_WRAP8 = 3'b000; //8个数据回绕方式批量传输
  • parameter HBURST_INCR8 = 3'b000; //8个数据递增方式批量传输
  • parameter HBURST_WRAP16 = 3'b000; //16个数据回绕方式批量传输
  • parameter HBURST_INCR16 = 3'b000; //16个数据递增方式批量传输
  • parameter HREADY_REDY = 1'b1;
  • parameter HREADY_BUSY = 1'b0;
  • parameter HRESP_OKEY = 2'b00; //传输完成
  • parameter HRESP_ERROR = 2'b01; //传输错误
  • parameter HRESP_RETRY = 2'b10; //传输未完成,请求主设备重新开始一个传输,
  • //arbiter会继续使用通常的优先级
  • parameter HRESP_SPLIT = 2'b11; //传输未完成,请求主设备分离一次传输,
  • //arbiter会调整优先级方案以便其他请求总线的主设备可以访问总线
  • parameter HSIZE_8b = 3'b000;
  • parameter HSIZE_16b = 3'b001;
  • parameter HSIZE_32b = 3'b010;
  • parameter HSIZE_64b = 3'b011;
  • parameter HSIZE_128b = 3'b100;
  • parameter HSIZE_256b = 3'b101;
  • parameter HSIZE_512b = 3'b110;
  • parameter HSIZE_1024b = 3'b111;
  • parameter HWRITE_WR = 1'b1;
  • parameter HWRITE_RD = 1'b0;
  • parameter FSM_IDLE = 4'h0;
  • //parameter FSM_ADDR = 4'h1;
  • parameter FSM_WR = 4'h2;
  • parameter FSM_RD = 4'h4;
  • reg[3:0] FSM_Current;
  • reg[3:0] FSM_Next;
  • always@(posedge CLK)
  • begin
  • if(RSTn == 0)
  • begin
  • FSM_Current <= FSM_IDLE;
  • end
  • else
  • begin
  • FSM_Current <= FSM_Next;
  • end
  • end
  • always @(*)
  • begin
  • if(RSTn == 0)
  • begin
  • FSM_Next <= FSM_IDLE;
  • end
  • else
  • begin
  • case(FSM_Current)
  • FSM_IDLE:
  • begin
  • if(
  • (HSEL == 1)
  • &&(HTRANS == HTRANS_NONSEQ)
  • )
  • begin
  • if(HWRITE == HWRITE_WR)
  • begin
  • FSM_Next <= FSM_WR;
  • end
  • else
  • begin
  • FSM_Next <= FSM_RD;
  • end
  • end
  • else
  • begin
  • FSM_Next <= FSM_IDLE;
  • end
  • end
  • FSM_WR:
  • begin
  • if(WB_ACK == 1)
  • begin
  • FSM_Next <= FSM_IDLE;
  • end
  • else
  • begin
  • FSM_Next <= FSM_WR;
  • end
  • end
  • FSM_RD:
  • begin
  • if(WB_ACK == 1)
  • begin
  • FSM_Next <= FSM_IDLE;
  • end
  • else
  • begin
  • FSM_Next <= FSM_WR;
  • end
  • end
  • default:
  • begin
  • FSM_Next <= FSM_IDLE;
  • end
  • endcase
  • end
  • end
  • always@(posedge CLK)
  • begin
  • if(RSTn == 0)
  • begin
  • HRDATA <= 32'hZ;
  • HREADY <= HREADY_REDY;
  • HRESP <= HRESP_OKEY;
  • WB_ADDR <= 32'hZ;
  • WB_DATA_OUT <= HWDATA;
  • WB_WE <= 1'b0;
  • WB_STB <= 1'b0;
  • WB_CYC <= 1'b0;
  • WB_SEL <= 4'h0;
  • end
  • else
  • begin
  • case(FSM_Current)
  • FSM_IDLE:
  • begin
  • if(
  • (HSEL == 1)
  • &&(HTRANS == HTRANS_NONSEQ)
  • )
  • begin
  • HRDATA <= HRDATA;
  • HREADY <= HREADY_BUSY;
  • HRESP <= HRESP_OKEY;
  • WB_ADDR <= HADDR;
  • WB_DATA_OUT <= HWDATA;
  • WB_WE <= 1'b0;
  • WB_STB <= 1'b0;
  • WB_CYC <= 1'b0;
  • WB_SEL <= 4'h0;
  • end
  • else
  • begin
  • HRDATA <= HRDATA;
  • HREADY <= HREADY_REDY;
  • HRESP <= HRESP_OKEY;
  • WB_ADDR <= HADDR;
  • WB_DATA_OUT <= HWDATA;
  • WB_WE <= 1'b0;
  • WB_STB <= 1'b0;
  • WB_CYC <= 1'b0;
  • WB_SEL <= 4'h0;
  • end
  • end
  • FSM_WR:
  • begin
  • HRDATA <= HRDATA;
  • HREADY <= HREADY_BUSY;
  • HRESP <= HRESP_OKEY;
  • WB_ADDR <= WB_ADDR;
  • WB_DATA_OUT <= HWDATA;
  • WB_WE <= 1'b1;
  • WB_STB <= 1'b1;
  • WB_CYC <= 1'b1;
  • case(HSIEZ)
  • HSIZE_8b :
  • begin
  • WB_SEL <= 4'h1;
  • end
  • HSIZE_16b:
  • begin
  • WB_SEL <= 4'h3;
  • end
  • HSIZE_32b:
  • begin
  • WB_SEL <= 4'hF;
  • end
  • default :
  • begin
  • WB_SEL <= 4'h0;
  • end
  • endcase
  • end
  • FSM_RD:
  • begin
  • HRDATA <= WB_DATA_IN;
  • HREADY <= HREADY_BUSY;
  • HRESP <= HRESP_OKEY;
  • WB_ADDR <= WB_ADDR;
  • WB_DATA_OUT <= HWDATA;
  • WB_WE <= 1'b0;
  • WB_STB <= 1'b1;
  • WB_CYC <= 1'b1;
  • case(HSIEZ)
  • HSIZE_8b :
  • begin
  • WB_SEL <= 4'h1;
  • end
  • HSIZE_16b:
  • begin
  • WB_SEL <= 4'h3;
  • end
  • HSIZE_32b:
  • begin
  • WB_SEL <= 4'hF;
  • end
  • default :
  • begin
  • WB_SEL <= 4'h0;
  • end
  • endcase
  • end
  • default:
  • begin
  • HRDATA <= 32'hZ;
  • HREADY <= HREADY_REDY;
  • HRESP <= HRESP_OKEY;
  • WB_ADDR <= 32'hZ;
  • WB_DATA_OUT <= HWDATA;
  • WB_WE <= 1'b0;
  • WB_STB <= 1'b0;
  • WB_CYC <= 1'b0;
  • WB_SEL <= 4'h0;
  • end
  • endcase
  • end
  • end
  • endmodule

        Riscv端的软件代码如下

  • #include <stdio.h>
  • #include "nuclei_sdk_hal.h"
  • #include "anl_printf.h"
  • int main(void)
  • {
  • unsigned long test;
  • while(1)
  • {
  • *((unsigned long *)0x40000000) = 0x5A5A5A;
  • test = *((unsigned long *)0x40000004);
  • }
  • }

        使用片上逻辑分析仪对Wishbone的关键信号进行分析,截图如下,可见其符合Wishbone时序。

查看本帖全部内容,请登录或者注册

P3_USB_hardware.zip

3.23 MB, 下载次数: 15

硬件工程

P3_USB_software.zip

356.74 KB, 下载次数: 11

软件工程

最新回复

没有后续了吗?楼主大神   详情 回复 发表于 2023-11-13 09:57
点赞 关注
 
 

回复
举报

2

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
 
 

回复

32

帖子

1

TA的资源

一粒金砂(中级)

4
 

项目还在测试中,测完再发

 
 
 

回复

7794

帖子

18

TA的资源

五彩晶圆(高级)

5
 

牛逼!

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

43

帖子

0

TA的资源

一粒金砂(中级)

6
 

很不错的一个项目,值得深入研究了解。


 
 
 

回复

52

帖子

0

TA的资源

一粒金砂(中级)

7
 

学习了!                                                                                                                                       

 
 
 

回复

7554

帖子

2

TA的资源

版主

8
 

厉害厉害,话说FPGA可以自制成一个USBPHY吗,感觉应该也可以。

点评

USB3好像可以,走LVDS,USB2应该不行  详情 回复 发表于 2023-3-29 17:22
 
 
 

回复

32

帖子

1

TA的资源

一粒金砂(中级)

9
 
wangerxian 发表于 2023-3-29 09:11 厉害厉害,话说FPGA可以自制成一个USBPHY吗,感觉应该也可以。

USB3好像可以,走LVDS,USB2应该不行

 
 
 

回复

195

帖子

0

TA的资源

一粒金砂(高级)

10
 
电子设计新人,来学习学习,看看大神们的思路都是怎么样的。
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

11
 

没有后续了吗?楼主大神

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
【干货上新】电源解决方案和技术第二趴 | DigiKey 应用探索站
当月好物、电源技术资源、特色活动、DigiKey在线实用工具,干货多多~

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 4

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表