首页 > 编程知识 正文

verilog用什么编程,基于fpga的串口通信设计

时间:2023-05-05 09:41:42 阅读:44130 作者:1077

上一篇文章介绍了DAC81416的配置过程。 本文使用Verilog代码具体实现了这个过程。 此代码具有普遍性,今后所有DA/AD的配置代码都可以在本文所示的代码中进行修改。 这里首先提供了指向源代码的链接,以及指向作为子模块的通用fifo的代码链接。 这是我在FPGA教学系列文章中第一次展示代码,所以我希望从设计者的角度恢复代码编写时的设计步骤,也就是设计思想的展示,供初学者们参考。 当然只是参考,并不意味着萌新们一定要这样做。 你可能觉得我的文章太罗嗦了,请无视文章直接下载源代码。 的文章中,除非有特定情况,否则没有这种设计思想的展示。

一、端口的定义我们对设计需求的建立过程是我们模块端口的定义过程。 一般来说,我们在编写代码时,首先要从整体上考虑我们的需要,也就是我们的目的。 我们知道它的目的是通过SPI配置DAC81416,并在配置完成后发送数据,因此我们不仅定义了与DAC通信的端口,还定义了用户端端口。 用户端端口可以根据情况定制。 这里是我定义的格式。 不同的读者定义格式也不同。 如果你觉得好用,你觉得符合或符合你的思维习惯

图1 SPI接口上的端口现在必须注意的是,端口定义的初始化不一定是充分的。 实际上,只需要给出端口的大致定义,许多具体细节可以通过在以后正式编写代码的过程中适当添加和删除来获得。

二、流程描述端口定义后,必须清晰思考两个流程。 第一个过程是站在用户的角度,用户如何使用我们的模块; 第二个过程是采取什么样的操作来满足用户的使用。

用户使用的过程:用户在启用configStart后等待ready,用户在启用ready后禁用configStart信号并握手结束后,即可输出数模转换的数据。 数据输出方法是dout_en以有效的速度输出dout_num和dout_data,分别表示输出通道和数模,在此过程中,可以只输出一个通道,也可以多次输出一个通道由dout_en的长度和dout_num的值决定。 然后,用户必须启用complete以完成这次输出,在下次输出时用户必须再次启用configStart并等待ready,然后重复上述过程。

本模块的操作步骤:本模块在确认初次配置开始有效后进行初始化配置操作,但如果不是初次发送数据,且配置开始有效,则本模块可能还处于数据发送状态然后,本模块在dout_en有效时剪切dout_num和dout_data,获取输出端口和输出数据后,进行配置DACn Register的操作,完成数据发送。 在此过程中,dout_en连续有效,可能表示连续的单端口输出或一次多端口输出。如果收到complete,则必须结束此回合的发送过程,但本模块将完成completete 在这种情况下,也需要缓存完成。 收到complete后,在下一个初始化配置完成之前,必须禁用“ready (就绪)”,以防止用户误以为本模块已准备好。

这里需要注意的有两点。 第一,正如端口定义一样,上面的两个过程也不是一开始就可以做到完美的。 强烈建议初学者用文字或图表描述这两个过程。 即使不能完美地考虑,这个训练也是必要的。 编写这两个过程可以帮助您了解代码中必须包含哪些子模块,以及主状态机如何首先定义和跳转,然后在编写代码的过程中可以找到答案。 在正式编写代码的过程中,这两个过程相反互补,改善子模块和状态机的详细问题。 第二,我们可能在写中间模块。 这必须考虑到高级用户、下级用户甚至公共汽车级用户的使用过程。 有多少用户,我们必须写多少个过程。 即使用户提供了标准界面,我们也最好写下这个过程,让我们整理线索。

三、状态转移图在清晰考虑过程后,状态机很容易定义。 每个人定义的状态机可能不同。 这里只展示了我定义的一种,仅供参考。

图2在SPI接口的状态转移图上的图中,IDLE是初始状态,CFIG是配置状态,CFIG (配置下一步)是判断配置是否完成的状态,wtdt (等待输出)是等待输出的数据dtnt ) doutnext )是判断输出是否完成的状态这个步骤的设计技巧,在画状态转移图时,不需要准确地写转移条件,用文字记述转移条件即可,具体的转移条件根据情况进行设定。 和前两步一样,状态转移图从一开始就不完美,状态的增减和条件的变化经常发生在设计上。

四、其他设计的细节考虑到这里的时候,我们可以列出自己所想的设计细节(只要是能在脑海中一闪而过的东西,什么都可以,不管好坏)。 这里只写五个榜样。 当然,即使暂时不考虑细节而跳过这一步,只要有灵感就可以随时记录下来。

1、我们可以设计频率变化的SPI输出时钟,这有利于今后的调试。

2、构成DAC的数据是固定数据,可以实例化一个ROM。

/p>

3、缓存就用FIFO。

4、因为对DAC的每次操作都是24位数据,所以应该设置一个模24的计数器。

5、普通模式下不用的端口信号全部输出0或1(保证其无效就行)。

准备工作到此结束。至于具体编写Verilog代码时中间的信号线和寄存器,都是边写边定义的,每个always语句块怎么给变量赋值,也是边写边考虑的。至于时序问题,先不用考虑太多,我会专门写一篇文章讲,代码写多了之后自然就知道该如何避免时序上踩雷,事实上,很多时序问题反而是在仿真和调试过程中发现并调整的,对于新手来说,最开始写代码时真不用特别考虑。

编写testbench,用modelsim把本文开头给出的源代码进行仿真,可以看到SDI满足SCLK下降沿采样,CSN满足低电平有效。关于如何编写testbench,如何使用modelsim的基本功能,我会另外写一篇文章,就以本篇的源代码为例子来探讨。

图3 modelsim仿真的spi波形

本人水平有限,如有错误,欢迎留言指正。 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。