本文继续探讨微控制器(uC)到现场可编程门阵列(FPGA)接口。
第1部分 介绍了指导大型系统开发的Verilog设计理念。介绍寄存器传输电平(RTL)设计准则的关键部分,如时钟边界、频闪器的使用和双缓冲区的必要性。
第2部分 介绍了SPI协议。回想一下,所选择的协议改编自802.3以太网帧,具有可变有效载荷长度和循环冗余校验(CRC)等概念,以提供数据完整性的度量。
上一期的重点是命令和响应帧,这里重复如图1所示。命令框描述了从uC到FPGA的信息传输协议。响应帧描述了从FPGA到uC的数据流。回想一下,该协议是为使用SPI的全双工通信而设计的。这个要求需要仔细注意与FPGA硬件相关的时序。响应帧必须在接收到命令帧时实时生成。例如,当uC向FPGA发送长度字节时,FPGA同时发送用户定义的状态标志。同样,当uC为命令帧发送CRC时,FPGA为响应帧发送CRC。
这种实时流要求使设计变得复杂。因此,本文将专门以框图格式描述顶级FPGA实现。未来的部分将从深入分析双缓冲模块开始,深入研究各个FPGA模块。
图1 :命令和响应帧构成了uC到FPGA SPI协议的基础。
图1 :命令和响应帧构成了uC到FPGA SPI协议的基础。
10000英尺高度看uC到FPGA的数据传输
高级FPGA硬件视图如图2所示。我们先从右到左的概览开始,以便更好地理解硬件的操作。如果您还没有这样做,您可能想回顾一下第1部分,它指出了与系统级设计相关的一些挑战,特别是关于双缓冲区的部分。
在右上角,我们发现一个脉冲宽度调制器(PWM)模块。需要注意的是,这个模块有一个16位接口。与此同时,有一个隐含的期望,即使用8位格式通过SPI传输数据,如图1所示。这是有问题的,因为如果PWM一次更新一个字节,将发生意外操作。相反,所有16位必须同步注册,确保所有16位在单个时钟周期内呈现给PWM。
这种同步更新由双缓冲器执行。该模块接收来自SPI硬件和方框图中间的各种缓冲和控制模块的数据。双缓冲区等待,直到两个字节都被接收,并同时更新PWM。然后,PWM模块将在已知的起始位置(如下一个PWM占空比的开始)实现变化。
每个双缓冲区都用两个参数实例化,包括字节宽度和地址,如图3所示。选择字节宽度以匹配相关硬件,如16位PWM或32位直接数字合成器(DDS)。该地址与图1所示的命令帧相关。例如,要将PWM设置为占空比,具有代表性的最小命令帧将是:0x07, 0x00, 0x00, 0x02, 0x00, 0xAA, 0x55, 0xFD, 0x07。在本例中,我们将把0xAA55的值写入位于地址0x0200的16位PWM。在这个例子中,设置为0x0000的读地址并不重要。请注意,CRC模块将在以后的文章中探讨。
图2 :显示FPGA数据流的顶层FPGA框图。
继续从右向左的旅程,我们遇到了由缓冲区提供的消息写入器和由SPI接口提供的CRC验证器。消息写入器代理由结束帧频闪和CRC验证器触发。该频闪表示已接收到图1所示的命令帧,并通过将接收到的CRC与CRC验证器计算出的CRC进行比较来验证。激活后,双缓冲区写入器将帧缓冲区的内容传输到与各种FPGA硬件模块(如PWM、DAC和DDS)相关的双缓冲区。
帧缓冲器是数据完整性验证过程的关键组件。首先,帧缓冲区在数据通过SPI接口传入时收集数据。同时,CRC验证器正在计算流数据的CRC。如图1所示,CRC被附加到帧中。因此,在接收到整个帧之前,CRC和帧验证的完整性是未知的。帧缓冲区是至关重要的,因为它允许CRC完成的时间。它允许在FPGA硬件对数据进行操作之前对数据进行验证。缓冲器消除了对损坏帧所做的更改进行unwind的需要。
正如图1和图2的帧协议所暗示的那样,长度、读、写地址字段和有效负载都由双缓冲区写入器处理。当CRC被验证后,双缓冲区写入器将断言基址和第一个有效负载字节。然后,它将发送一个写频闪,激活双缓冲区内的第一个字节范围的缓冲区。然后双缓冲区写入器将移动到下一个数据,重复该过程N次。其中N为帧长度字段减去报头字段的5个字节。通过检查如图3所示的双缓冲区的结构,可以更好地理解这个过程。
图3:双缓冲区的框图表示。
回想一下,每个双缓冲区都是用一个基址和一个长度实例化的。它有一个受控制的操作序列。在双缓冲区内的所有字节级第一阶段缓冲区被填满后,双缓冲区将自动将信息传输到第二阶段。这种自动传输简化了消息写入器的设计,因为它不需要控制双缓冲区的操作。相反,它可以自由地一个字节接一个字节地传输帧负载。
在继续讨论uC到FPGA数据流之前,我们对双缓冲区写入器的速度进行了评论。回想一下,图2中的所有项目在一个时钟域内都是同步的。在接收到CRC验证器的频闪后,双缓冲区写入器将以仅受FPGA 100mhz时钟限制的速率写入双缓冲区。因此,读取100%全帧缓冲器大约需要5个uS。
缓冲区从位置8’b05读取到8’bFF。同时,uC有能力启动另一个帧,同时填充帧缓冲区,因为它正在被清空。干扰不是问题,因为FPGA消息写入器将比uC填充缓冲区更快地清空缓冲区。即使SPI模块被替换为四进制或八进制SPI,该声明也应该是正确的。
技术提示:具有讽刺意味的是,本文中描述的uC到FPGA接口可以从基于FPGA的软核处理器中受益。这包括将专用uC实例化到FPGA结构中,用于uC到FPGA接口。对于赛灵思fpga, PicoBlaze等控制器将是一个很好的匹配。这个小型状态机可以替换除SPI模块、各种双缓冲区及其相关外设之外的所有内容。这取决于你用汇编器编码的能力,它可能仍然是一个优雅的解决方案。还有其他功能强大的选择,比如使用传统C编程的MicroBlaze。您甚至可以使用赛灵思Zynq将uC移动到FPGA中。类似的选项可用于大多数FPGA平台。
10000英尺看FPGA到uC的数据传输
本系列文章中描述的SPI接口是全双工的,能够发送单独的读写地址,如图1所示。这是一个流处理过程,其中数据被时钟输入MOSI线上的FPGA,同时将数据发送到MISO线上的uC。现在,我们将使用从右到左的信号流来检查图2中概述的RTL FPGA传输过程。
如本系列的第1部分所述,双缓冲区进程是一个基本需求。对于图2左下角所示的实体来说,这一点最为明显。观察FPGA的选择器开关,16位DAC,用户定义的状态标志和错误消息计数都已注册。在每个SPI帧的开始处捕获数据。这种注册确保数据值在流回uC时不会改变。这消除了与更新多字节数据的一个字节相关的危险。
从FPGA到uC的所有数据流都发送到图2右下角所示的多路复用器。多路复用器的选择过程根据命令帧的读地址确定,如图1所示。当SPI接口输入一个字节时,控制机器将把多路复用器推进到下一个连续的读地址。此操作允许具有独立读写寻址的全双工通信。例如,FPGA滑动开关可以在写入PWM的同时进行读取。为了简单起见,图2中的多路复用器被简化为隐式的n字节输入到字节宽度输出。
请注意,图2中有两个CRC验证器实例。如前所述,上层模块涉及uC到FPGA的数据,而下层模块涉及FPGA到uC的数据流。
从FPGA继续从右到左的数据流到uC数据RTL,我们看到较大的复用器的输出被呈现给CRC验证器。它也通过一个较小的复用器在它的方式到SPI接口和最终MISO线。回想一下,CRC验证器模块在流数据上构造CRC。较小的mux允许将CRC附加到FPGA到uC消息。这个切换动作是基于MSG Reader Control对帧缓冲区中保存的Num_bytes的理解。
请继续关注第4部分,我们将探索双缓冲区模块的Verilog实现。
欢迎您的评论和建议。特别欢迎进一步讨论高级RTL系统设计方法。