SATA主机协议的FPGA实现之物理层设计
SATA主机协议的FPGA实现之物理层设计
接上一篇文章,这里讲解SATA主机协议的物理层的实现过程。
下图是标准SATA协议文档中给出的物理层结构。可以看到它包含控制模块、时钟数据提取单元、同步字符源和同步字符检测模块以及模拟前端几个部分。其中,控制模块负责协调控制整个物理层的逻辑功能,并向上层协议提供控制信号、状态信息接口。时钟数据提取模块从串行数据流中提取时钟数据信息。同步字符源和同步字符检测两个模块负责串并/并串转换过程中的字节对齐。模拟前端包含高速差分数据发送接收器和OOB信号检测与生成电路。
上面这个图看上去比较复杂,但是如果仔细理解物理层协议,并对前一篇博客中提到的ALTGX收发器有一定认识之后,我们会发现其实这个收发器已经帮我们实现了时钟数据提取单元、同步字符源和同步字符检测模块以及模拟前端这几个部分,我们要做的就是如何配置这个收发器。另外,物理层还有一个重要的工作就是利用OOB(OUT OF BAND)信号实现设备的识别和上电初始化。因此,这里进一步划分物理层模块,得到下面这个物理层框图。整个物理层被划分为4个模块,OOB生成和检测、ALTGX收发器和物理层状态机。
首先说一下这个ALTGX收发器。关于这个收发器具体结构这些东西这里限于篇幅就不一一介绍,详细的介绍参考StatixIV器件手册,这里只是说明一下为什么会用上它。我们知道现在常见的FPGA的处理速度最高也只是在几百兆的水平,但是SATA1.0的串行数据流的传输速度已经达到了1.5Gbps,这样的速度不可能直接在FPGA里实现,而且SATA最终在传输线上传输的是差分信号,这里会有一个数字到模拟的过程,这也不是一般的FPGA能干的事。上面这两个问题其实并不只是实现SATA协议时会碰到,很多高速串行传输协议在使用FPGA实现时都会遇到,比如PCIe等。FPGA厂商为了满足对这种高速串行传输协议的支持,通常的做法都是在FPGA芯片中集成专用的硬件,这种专用硬件通常是一组满足高速数据传输速率要求的串行器/解串器(SERDES)以及模拟前端。这些集成的专用硬件通常是可以进行比较灵活的配置的,以使它们能满足对不同通信协议的支持。ALTERA公司的ALTGX收发器就属于这种,另外还有XILINX公司的RocketIO MGT等。ALTGX收发器可以通过QuartusII软件中的IP配置向导配置生成,这个配置过程参考“实现Altera器件中的SATA与SAS协议”一文。这篇文档中有详细的配置讲解,这里不再赘述。
接着说说这个OOB信号。带外信号,即OOB信号是物理层特有的一组信号,它通过在数据线上传输一组特定格式的信号实现。OOB信号有3个,分别是COMRESET、COMINIT和COMWAKE,其中COMRESET与COMINIT信号组成形式一样,只不过CONRESET由主机发出,而COMINIT由设备发出,它们的作用是在正常的通信链路没有建立之前主机进行SATA设备识别。关于这三种信号的组成形式请查阅SATA协议文档,这里主要说一下怎么实现这几个信号。上面关于ALTGX配置过程中我们应该注意到两个比较特殊的信号端口,一个是rx_signaldetect,一个是tx_forceelecidle,我们主要是通过控制这两个端口产生和读取OOB信号。查阅SATA文档之后我们知道OOB信号实际是由数据线上的突发信号和空闲周期组成的,突发信号周期比较好理解,在差分数据线上传输特定的原语(ALIGNp)即可,那空闲周期是什么意思呢?简单的理解就是不发送数据,那怎么就代表不发送数据呢?分析tx_forceelecidle这个端口的作用我们大概可以得到一些启示。这个端口的作用是将ALTGX中的发送器强制置为高阻,原来“高阻”才意味着没有数据发送,千万不要以为发送器发送“0”就是空闲周期了,“0”也代表一个数据!相反地,在接受端就比较好理解了,对于差分信号来说,在接受器端设置阈值电平检测电路就能区别差分数据线上“有或没有”信号,也就是区分突发周期和空闲周期,反映阈值检测结果的信号就是rx_signaldetect这个端口。这样就好理解OOB信号的具体实现了,当发送OOB信号时,通过置位或复位tx_forceelecidle端口来发送空闲周期和突发信号周期,接收设备端的OOB信号时,通过检测rx_signaldetect端口信号电平来确定当前设备发送的是空闲周期还是突发信号周期,当该端口被置位,说明接收到的是突发信号周期,否则是空闲周期。这里需要提醒一下的是这两个端口的信号都是高电平有效的,这意味着tx_forceelecidle为高电平时是空闲周期,而rx_signaldetect为低电平时为空闲周期。这一点一定要注意,这跟XILINX FPGA中的信号电平定义好像不太一样,我当时就在这里吃过亏。接下来的OOB生成和检测模块的实现就好办了,我们要做的工作就是实现能产生和检测一组符合OOB信号规定的高低电平电路就可以了。
最后说说这个物理层状态机。物理层状态机是整个物理层电路工作的大脑,它主要负责控制前面提到的三个模块,在上电时完成主机对SATA设备的识别和通信链路的建立。下面这个时序图就是上电时主机初始化的过程。首先是主机发送COMRESET信号,设备接收后响应COMINIT,主机接收之后发送COMWAKE,设备接收后再响应COMWAKE。四个OOB信号交互之后,主机就完成了SATA设备的识别。之后主机与设备之间通过ALIGNp原语进行速度协商并完成通信链路的建立,最后在通信链路建立之后以SYNCp保持。详细的描述参考文档中关于这部分的描述。
根据上面的时序图,我设计了以下的状态机,它的状态转移图如下图所示,供大家参考。
物理层状态机共有12个状态,状态转移图上图所示。主机上电后需要先对ALTGX收发器进行复位操作,使CDR能成功锁定到接收数据。当复位完成后,状态机能接收到power_rst_done信号,状态机进入发送COMRESET状态,使能OOB信号生成模块发送COMRESET信号。如果设备接收到COMRESET信号,设备会向主机发送COMINIT信号,主机接收到COMINIT信号后,状态机进入发送COMWAKE信号状态,使能发送模块发送COMWAKE信号,之后主机等待设备响应COMWAKE信号。主机在接到COMWAKE信号后会向设备发送一段时间D10.2数据,直到检测到设备发送的ALIGNp原语。这时主机存储ALIGNp原语,并以相同的速率返还给设备,完成速度协商。最后设备向主机发送SYNCp原语,主机在接收到该原语后进入Link_ready状态,表示通信链路已经建立。
最终整个物理层的实现情况如下图所示,这是用SignalTapII捕捉到的信号波形。第一个是OOB信号发送,即tx_forceelecidle端口控制信号,第二个是OOB信号接收,即rx_signaldetect端口信号,第三个是ALTGX接收转换后的16位并行数据,第四个是ALTGX发送的16位并行数据。
至此,物理层基本逻辑设计完成,下一篇文章将讲解链路层设计。
SATA主机协议的FPGA实现之物理层设计的更多相关文章
- SATA主机协议的FPGA实现之准备工作
SATA主机协议的FPGA实现之准备工作 从2月中旬准备开始,经过3个月的奋战,我的又一个项目--基于FPGA的固态硬盘读写控制电路,已经基本实现.由于实用资料的匮乏,以及项目本身颇具挑战性,这个 ...
- 千兆以太网TCP协议的FPGA实现
转自https://blog.csdn.net/zhipao6108/article/details/82386355 千兆以太网TCP协议的FPGA实现 Lzx 2017/4/20 写在前面,这应该 ...
- FPGA最小系统分析与电路设计
<FPGA最小系统分析与电路设计> 部分节选自<FPGA应用开发入门与典型.pdf > FPGA最小系统包括:FPGA芯片.下载电路.外部时钟.复位电路和电源. 如果使用NIO ...
- 基于FPGA的HDMI显示设计(三)
上一篇:基于FPGA的VGA显示设计(二) 10月10日 ~ 20日期间实习,令我万万没想到的是实习题目是 “便携式高清电视显示屏测试系统原型设计” 也就是 “基于FPGA的视频显示”. 实习要求用 ...
- 基于FPGA的VGA显示设计(二)
上一篇:基于FPGA的VGA显示设计(一) 参照 CrazyBingo 的 基于FPGA的VGA可移植模块终极设计代码 的工程代码风格,模块化处理了上一篇的代码,并增加了一点其它图形. 顶层 ...
- 四、基于HTTPS协议的12306抢票软件设计与实现--水平DNS并发查询分享
一.基于HTTPS协议的12306抢票软件设计与实现--实现效果 二.基于HTTPS协议的12306抢票软件设计与实现--相关接口以及数据格式 三.基于HTTPS协议的12306抢票软件设计与实现-- ...
- 干货分享,FPGA硬件系统的设计技巧
PGA的硬件设计不同于DSP和ARM系统,比较灵活和自由.只要设计好专用管脚的电路,通用I/O的连接可以自己定义.因此,FPGA的电路设计中会有一些特殊的技巧可以参考. 1. FPGA管脚兼容性设计 ...
- 详解串行通信协议及其FPGA实现
前言 好久没更新博客了,这篇文章写写停停,用了近一周的时间,终于写完了.本篇文章介绍,串口协议数据帧格式.串行通信的工作方式.电平标准.编码方式及Verilog实现串口发送一个字节数据和接收一个字节数 ...
- ARM与FPGA通过spi通信设计2.spi master的实现
这里主要放两个代码第一个是正常的不使用状态机的SPI主机代码:第二个是状态机SPI代码 1.不使用状态机:特权同学<深入浅出玩转FPGA>中DIY数码相框部分代码: /////////// ...
随机推荐
- Github入门操作实录
到目前为止,我已经工作快5年了,这5年最大的感受就是,框架什么的并不难,只要知道api,就能用起来,一开始会遇到一点问题,但是天下的框架都大同小异,无非是jar包,配置文件,模板代码,jar包可以使用 ...
- SpringMVC(十二) RequestMapping使用POJO作为参数
将一个普通的JAVA类对象作为一个参数传入. POJO类Address: package com.tiekui.springmvc.pojo; public class Address { priva ...
- SpringBoot拦截器
在实际开发中,总存在着这样的场景,比如拦截请求的ip地址,或者在所有的请求都返回相同的数据,如果每一个方法都写出相同数据固然可以实现,但是随着项目的变大,重复的代码会越来越多,所以在这种情况我们可以用 ...
- 页面嵌入iframe那些事儿
一.用iframe如何把别人的页面嵌入自己的页面? <iframe src="http://blog.sina.com.cn/abc" frameBorder=0 scrol ...
- Vue发送请求
可以试试玩ajax请求,个人觉得axios用Promise包装了下,代码美观 axios请求使用方法 https://github.com/axios/axios#using-applica ...
- SpringMVC url匹配却404,SimpleUrlHandlerMapping不起作用
代码如下: <mvc:default-servlet-handler/> <bean class="org.springframework.web.servlet.hand ...
- CSS设置文字不能被选中
/*设置文字不能被选中 以下为css样式*/ -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; us ...
- pythonweb服务器编程(二)
Web静态服务器-1-显示固定的页面 #coding=utf-8 import socket from multiprocessing import Process def handleClient( ...
- html5页面拨打电话实现的方法
拨打电话:<p>咨询电话 <a href="tel:17337956096">拨号: 17337956096</a></p> 发送 ...
- 列表去重几种方法 python
1.方法一: >>> a=[1,1,2,2,3,3] >>> b=[] >>> for i in a: ... if i not in b ...