Adam Taylor玩转MicroZed系列34:使用MicroZed驱动Adafruit RGB NeoPixel LED阵列第5部分

FPGA/ASIC技术

211人已加入

描述

在这期博客前面的几期,我们介绍了驱动Adafruit Neopixels设计实例的解决方案架构。我们使用Vivado方块图设计这个解决方案(具体可以查看Adam Taylor玩转MicroZed系列33:使用Zynq SoC驱动Adafruit RGB NeoPixel LED阵列”)。 我们最大化的使用了这些存在的基于Zynq SoC的IP核,所以我们只需要创建一个新的硬件模块来驱动NeoPixels。这正是本篇博客的要点。

我们的NeoPixel驱动将实现下面这些功能:
1. 读取零地址的值到内存模块中来判断LED点阵上像素的个数。
2. 如果像素数不为0:
3. 读下一个地址的第一个像素点的红、绿和蓝通道的字节值,组成一个24位宽的字值。
4. 确定哪种波形值(0或1)的输出能够反应出从内存中读出的24位宽数值中最重要的 位的值。
5. 输出这些波形值为NeoPixel字符串
6. 将24位宽的字值按增量标记
7. 为下一位确定输出值
8. 重复上面的步骤6和7,直到所有24位宽数据全部输出
9. 检查确定正确的24位宽的像素值已经被输出
10. 如果还有24位宽的像素值,重复上面的步骤3到9直到下一个像素的 内存地址
11. 如果正确数量的像素已经输出,等待复位,将像素值锁存
12. 重复上面的步骤1到11

这个算法序列要求两部分,这是大部分FPGA工程师所熟悉的:
1. 和双端口RAM连接的状态机,安排输出 bit序列,记录下输出像素的个数(具体可查看Xcell杂志81期我的一篇文章,“怎样在你的FPGA伤实现状态机”)
2. 一个移位寄存器来生成NeoPixel波形

这个Adafruit NeoPixel是用内置的时钟波形发生器,并且根据输出位的值是0还是1进行转换。我们将使用25位宽的移位寄存器来锁存和输出Adafruit Neopixel每一位的值。我已经定义了俩个常数用来提前加载以为寄存器,根据输出的每一位的值:0或1(可以查看附件的代码和仿真代码0)。

常数的长度和以为寄存器的容量依赖于移位寄存器的时钟频率。在这里我们使用Zynq器件PS部分的FCLK_CLK1时钟来驱动移位寄存器,时钟频率为20MHZ。50ns的时钟周期满足NeoPixel 比特位传输的时序要求,我们可以从器件的时序图和下面的图表看出。

对于传输1或者0的波形周期也是不同的,具体的时钟周期是传输一位0需要1.15?sec,传输一位1的时钟周期是1.3?sec。然而传输全部NeoPixel比特值的误差范围在±300nsec,所以我们可以使用1.25?sec的时钟周期传输0和1,同样能够满足具体的时序要求。传输1的时钟波形周期会短50nsec,传输0的时钟周期会长100nsec,但是都在误差的范围内。

使用50nsec的时钟周期产生1.25?sec的时钟周期来传输一个比特位,我们需要一个25位宽的移位寄存器,这样才能满足上面的0和1传输的时序图。因为我们可以在Zynq SoC的PL(可编程逻辑)部分实现各种硬件模块,实现一个25位宽的移位寄存器不是一件难事。

一旦我完成了实现简单的输入/输出模块的RTL代码,下一步就是验证这个设计。所有经验丰富工程师都知道验证的过程会比原型功能逻辑设计花费更多的时间。在这里我使用Modelsim软件来创建一个简单的test bench来仿真RTL逻辑代码,让我能够确定模块的定义的功能能够实现。在下一篇博客中我们将会介绍验证的方法策略,不且应用到验证和测试这个例程中。

附件:

Adam Taylors MicroZed Chronicles Part 34 code example.docx ?17 KB

原文链接:

? Copyright 2014 Xilinx Inc.
如需转载,请注明出处

附件大小
adam_taylors_microzed_chronicles_part_34_code_example.doc   36.5 KB  

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 相关推荐
  • 热点推荐

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分