0 引言
?
随着电子技术的发展,系统级芯片( System-on-a-Chip,SoC) 的发展已经成为一种趋势,广泛应用于各个领域,串行接口已成为当前传输接口的发展趋势。用户希望产品可以与多种设备进行数据交换,所以很多芯片都支持传统串行外设接口( Serial Peripheral Interface,SPI) 、通用串行总线( Universal Serial Bus,USB) 等接口。其中SPI 是由Motorola公司首先在其MC68HCXX 系列处理器上定义的一种高速的、全双工、同步的通信总线,并且在芯片管脚上只占用4 根线,节约了芯片的管脚,同时也为印制电路板( Printed CircuitBoard,PCB) 的布局节省了空间。目前,很多器件如FLASH、液晶显示屏( Liquid Crystal Display,LCD) 、安全数码卡( Secure Digital Memory Card,SD) 等都采用了SPI 接口。SPI 以其独特的优越性得到越来越广泛的应用。
?
在电子科学技术还不发达时,大部分处理器都不集成SPI总线接口芯片,当想要与集成了SPI 总线接口的器件进行信息互通时,电路工程师只能借助软件来实现。近几年随着计算机的发展,先进的计算机控制器内部都会集成SPI 总线接口电路,方便多个器件间实现信息交换。这样不仅很大程度上开拓了SPI 总线的运用范围,而且使越来越多的科技领域可以借助其优势得以发展。由于SPI 接口应用广泛,并且不同的应用场景具体要求也不同,因此现在已经出现了很多SPI 总线接口设计,其功能也有差异。文献考虑到,由于传统SPI 接口使用厂家提供的知识产权核( Intellectual Property core,IP) 实现,因此缺乏灵活性,不利于功能扩展的情形,设计了一种基于Wishbone 总线的高速可复用SPI 总线接口IP 核。文献设计了一个可以支持4 种不同传输时序,并且可以选择先最高位传输或者最低位传输的SPI 模块,增加了一条片选以实现主模块可以和两个从模块在不需要硬件复位的前提下交替工作。
?
对于SoC 内部来说,需要使用高级可扩展接口( AdvancedeXtensible Interface,AXI) 这类面向高性能、高频率的系统设计; 对于SoC 外部而言,为实现与多种设备进行数据交换,SPI设计非常重要。然而传统的SPI 设计与AXI 协议之间无法实现通信。传统的SPI 设计只是针对单一功能、单一slave 而设计,并且一旦通道堵塞,将无法工作。因此,传统的SPI 设计虽然能满足基本的SPI 通信要求,但是设计不灵活,不利于功能的扩展。一方面,为支持扩展,本文设计的SPI 模块面向通用SoC; 另一方面,为支持乱序访问,本文设计的SPI 模块具有8 个独立读写通道,各通道间可乱序访问,有效解决了堵塞问题。完成后的设计在搭建的随机验证环境下得到充分验证。验证结果表明,该SPI 设计在各种情况下都能正确完成数据传输。
?
1 SPI 总线原理
?
1. 1 SPI 协议
?
SPI 总线是一种3 线总线,因其硬件功能很强,所以与SPI 有关的软件就相当简单,使中央处理器( Central ProcessingUnit,CPU) 有更多的时间处理其他事务。正是因为这种简单易用的特性,如今越来越多的芯片集成了这种通信协议,比如AT91RM9200。
?
SPI 是一种高速、高效率的串行接口技术。通常由一个主模块和一个或多个从模块组成,主模块选择一个从模块进行同步通信,从而完成数据的交换。SPI 是一个环形结构,通信时需要至少4 根线( 事实上在单向传输时3 根线也可以) 。1) SCK: 串行同步时钟线,由SPI 主模块产生,数据在时钟脉冲下按位传输,高位在前( 目前应用中的数据速率可达几Mbit /s) 。2) MOSI: 串行数据输出线,当SPI 模块为主模块时,它输出数据; 当SPI 模块为从模块时,它接收数据。3) MISO: 串行数据输入线,当SPI 模块为主模块时,它接收数据; 当SPI 模块为从模块时,它输出数据。4) SS: 从机片选线,低电平有效,由主模块控制。
?
1. 2 SPI 协议时序
?
SPI 协议为了和外部设备进行数据交换,根据外设的工作要求,规定了4 种传输时序,这4 种传输时序共同点是每位数据的发送或接收需要1 个SCK 周期,每次可传输若干个8位数据。4 种时序由时钟极性CPOL 和时钟相位CPHA 的不同配置来区分。CPOL = 0 表示串行同步时钟的空闲状态为低电平,CPOL = 1 表示串行同步时钟的空闲状态为高电平;CPHA = 0 表示在SCK 的第1 个时钟采样数据( 数据必须稳定半个周期) ,CPHA = 1 表示在SCK 的第2 个时钟采样数据。具体4 种传输模式。
?
在CPOL = 0,CPHA = 0 时,在SCK 的上升沿采样数据,下降沿发送数据; 在CPOL = 0,CPHA = 1 时,在SCK 的上升沿发送数据,下降沿采样数据; 在CPOL = 1,CPHA = 0 时,在SCK的上升沿发送数据,下降沿采样数据; 在CPOL = 1,CPHA = 1时,在SCK 的上升沿采样数据,下降沿发送数据。
?
2 SPI 模块设计
?
本文设计的SPI 模块支持4 种时序工作模式,主要作为SoC 的配置或控制模块,其功能为: 通过SPI 接口,接收外部的配置或控制命令,配置或控制内部的各个从设备,比如: 双倍速率同步动态随机存储器( Double Data Rate,DDR) 、外设部件互连标准( Peripheral Component Interconnect Express,PCIE) 、音频编码器及解码器( Audio Coder and Decoder,AudioCODEC) 等。
?
2. 1 SPI 架构
?
SPI 是AXI 总线上的slave 模块,因此除了SPI 协议自身需要的接口外,还增加与AXI 总线连接接口。
?
AXI 是一种总线协议,该协议是ARM 公司提出的高级微控制器总线架构( Advanced Microcontroller Bus Architecture,AMBA) 3. 0 协议中最重要的部分,为SoC 设计提供了较好的可移植和可复用性,同时具有低功耗、高性能和结构可移植的系统设计以及较好的可测性设计。
?
主机发送的命令或数据放在AXI 总线上,经过控制分别写给控制寄存器、扩展寄存器、数据寄存器、状态寄存器。控制寄存器控制数据的传输。扩展寄存器控制时钟产生SPI 的tclk 信号,用来给SPI 设计提供时钟。控制状态机控制8 位数据的串行发送,写缓存模块是一个写FIFO,用来暂存从CPU中发送的数据; 读缓存模块是一个读FIFO,用来暂存从SPI设计接收的数据。移位寄存器用来将缓存中的8 位数据一位一位移入和送出, tdi 数据线接在移位模块上,同时移位模块送出的数据传送给tdo 信号线。
?
设计支持各种SPI 请求,具有8 个独立读写通道,各通道间可乱序访问。实现方式是: 发送的请求命令将地址或数据缓存在标识( IDentification,ID) 控制模块,通过输入状态机状态判断需要缓存在读( 写) 地址区还是读( 写) 数据区,应答命令发出后通过识别读写地址ID 号来确定应答是哪个地址请求命令,同时清空请求命令对应地址或数据队列。
?
2. 2 SPI 功能设计
?
本文的SPI 设计有4 种命令类型,分别为: 读请求、读请求应答、写请求、写请求应答。根据不同的命令类型,SPI 内部状态机作出相应反应。
?
输入状态机: 空闲状态表示SPI 不工作。命令类型表示当前操作是哪种命令。请求地址表示读( 写) 请求在哪个地址进行。在写请求时需要输入数据,其余命令不需要输入数据。
?
输出状态机: 空闲状态表示SPI 不工作。SPI 当前状态为8 位,8’h0 表示SPI 状态正常,其余值表示内部状态错误。命令类型表示当前操作是哪种命令。应答地址是原样将输入地址低24 位返回。应答数据在写请求应答时返回输入的数据;在读请求应答时返回读到的数据; 在其余两种命令时不返回。输出信息包含对当前命令的响应状态,读( 写) 请求时,为8’h2表示AXI 总线,为8’h0 表示出现错误; 读请求应答时,为8’h0表示读成功,为8’h1 表示等待数据返回,其余表示出错; 写请求应答时,为8’h0表示写成功,为8’h1 表示写请求丢在总线上,为8’h2 表示写数据丢在总线上。
?
3 SPI 随机验证环境设计
?
SPI 传输有一个显著优点,那就是普通的串行通信一次连续传送至少8 位数据,而SPI 允许数据一位一位地传送,甚至允许暂停,因为SCK 时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK 时钟线的控制可以完成对通信的控制。SPI 还是一个数据交换协议,因为SPI 的数据输入和输出线独立,所以允许同时完成数据的输入和输出。
?
SPI 协议中没有严格要求SCK 时钟占空比必须为50%,也没有说明是否在片选信号无效时SCK 必须为0。本文提出的验证环境将上述两个值随机变动,可任意配置。验证地址个数可配置,验证方式可配置( 读或写) 。本文验证环境按照发送task 方式驱动SPI 设备。在定义每种task 时,打印必要信息,如果没有按照SPI 设计功能输出,显示出错信息。在验证SPI 设计时,输入的地址及数据利用System Verilog语言编写生成受约束的随机激励。在SPI 工作过程中,将读写地址及数据输出到文件,最后自动对比读操作读出的数据是否与写入的相同。
?
3. 1 验证环境与SPI 设计连接关系
?
验证环境( spi_master) 与SPI 设计连接关系如图6 所示。环境接口中,miso 为主设备输入SPI 从设备输出, spi_reset 为SPI 主从设备复位信号,mosi 为主设备输出SPI 从设备输入,ss 为片选信号,低电平有效。
?
3. 2 验证环境几种主要task
?
本章开始提到,本文提出的验证环境通过发送task 方式驱动SPI 设备。
?
以上task 可根据设计验证要求配置调用,参数可以定点设置也可随机生成。例如,要测试连续写请求后写请求应答,通过多次调用write_data64 任务后再多次调用write_ans 即可。
?
4 代码覆盖率分析
?
SPI 设计的验证是否达到预期要求,仅仅根据各个测试案例是否全部通过来判断是不充分的,因此,本文对代码覆盖率进行了统计分析。代码覆盖率是通过在VCS 编译和运行期间使用- cm line + cond + tgl + branch 覆盖选项进行的。其中: 行覆盖( Line Coverage) 是度量被测代码中每个可执行语句是否都被执行; 条件覆盖( Condition Coverage) 是度量判定中的每个子表达式结果true 和false 是否都被测试; 分支覆盖( Branch Coverage) 是度量程序中每个判定的分支是否都被测试; 翻转覆盖( Toggle Coverage) 是度量代码中信号0 到1 和1 到0 的翻情况是否都被测试。
?
在验证初期,代码覆盖率并不高。主要原因有三类: 1) 验证不充分; 2) 代码错误; 3) 设计需要。针对原因,修改设计、增加验证: 连续发送请求和应答命令( 不超过8 个) ,这样请求的8 项队列都能用到; 判断应答地址时,增加触发信号锁存。经过多次调试修改设计和验证环境后,最终得到令人满意覆盖率结果。
?
5 仿真结果及分析
?
SPI 模块设计在一个完整的写读操作后的波形如图7 所示,首先在32’h26a00ce0的地址上写了64’h82c04cc5a1b70397的数据,之后对同样的地址进行读操作,从波形可以看出读写数据一致,说明设计读写功能正确。SPI 模块设计支持各种SPI 请求的结果如图8 所示,首先对SPI 设计连续发送8 个写请求命令,之后连续发出8 个写请求应答命令,从波形结果可以看出,每次发送写请求应答命令后,之前发送的写请求占用队列清空( 读操作类似) ,说明设计具有8 个独立读写通道,各通道间可乱序访问。
?
6 结语
?
本文设计的SPI 模块,由于其支持转化成SoC 上常见的AXI 协议,因此可以广泛应用在SoC 中。各通道间支持乱序访问的8 个独立读写通道提高了SPI 处理事务的能力,极大地避免了请求堵塞。利用可配置的随机验证环境,通过大量不同的测试组合,对该设计作了充分验证,并利用验证环境中自动对比功能判断读操作读出的数据是否与写入的相同,保证了设计的正确性及有效性。