在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 1345|回复: 2

[原创] 孩子都能学会的FPGA:第九课——多字节数据的发送和接收

[复制链接]
发表于 2023-11-23 15:50:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 chdaj58 于 2023-11-23 15:50 编辑

(原创声明:该文是作者的原创,面向对象是FPGA入门者,后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门作者不光让大家知其然,还要让大家知其所以然!每个工程作者都搭建了全自动化的仿真环境,只需要双击top_tb.bat文件就可以完成整个的仿真(前提是安装了modelsim),降低了初学者的门槛。如果需要整个工程请留言索要(微信15092150280索要也可以),不收任何费用,但是仅供参考,不建议大家获得资料后从事一些商业活动!

前面通过计数器实现了UART单字节数据的发送了接收,上节课又学习了状态机,那现在实现多字节数据的通讯就相对简单了。首先把多字节的数据拆分成多个单字节的数据,然后通过UART的发送模块一个个发送即可;接收端把接收的单字节数据组合起来,就可以得到实际的数据。

思路很简单,但是实际工程应用中还要考虑更多的问题。最主要的就是如何保证数据的正确性。UART线上的数据一个个的接收下来,但是有效的数据从什么位置开始,有效数据的长度是多少,数据的正确性应该如何保证?这就要加一些冗余的信息,比如帧头,长度,校验,帧尾之类的。其中帧头是必须要加的,帧头就是一个定位,检测到帧头后面就可以正确采集数据了。

本节工程要求:系统时钟是100MHz,低电平复位,使用UART协议完成4byte数据的传输,为了保证数据传输的正确性,每帧数据添加帧头(5a),数据长度(4)和帧尾(a5)。UART的波特率是115200,有奇偶校验位,偶校验。

我们根据需求分析一下,由于UART单字节收发的模块设计都设计完毕了,那新的发送模块只需要把要发送的数据排好队,一个个往UART发送模块里面放即可,新的接收模块从UART接收模块里面收数,根据协议把有效的数据解析出来即可。

如下所示,一帧的数据由帧头,长度,数据1,数据2,数据3,数据4和帧尾组成,每个拆分的数据都是单字节。那我们可以设计发送状态机,发帧头->发长度->发数据1->发数据2->发数据3->发数据4->发帧尾即可,但是这样设计有个问题,如果数据不是4个字节而是100个字节,难道要写100个发送数据的状态机?这样既增加了代码量,又让设计的代码通用性降低!因为数据长度改变一次代码就要重新设计一次。


v2-81cd673a92bd103f51703d26aacb78ea_720w.png

其实可以把4个发数据状态合并成发送数据的状态,在该状态里面设置一个计数器,发送一次计数一次,根据计数值跳出发送数据状态机,进入发送帧尾的状态机。所以发送的状态机应该如下所示。当又数据要发送的时候先进入发送帧头(HEAD)状态,帧头发送完毕后(tx_over拉高)进入发送数据长度(LEN)的状态,数据长度发送完毕后(tx_over拉高)进入数据发送(SEND)状态,然后进入数据发送等待状态(WAIT),如果一次数据发送完毕(tx_over拉高)判断已经发送数据的个数(send_cnt),如果有效数据没有发送完毕跳转到数据发送状态,如果有效数据发送完毕进入发送帧尾的状态(TAIL),帧尾发送完毕后(tx_over拉高)进入IDLE状态等待下一帧数据的发送。


v2-8b6f48352df0ff6addde1fe95d311e3c_720w.png

接收状态机也是一样,当UART线上有数据的时候状态由IDLE跳转到帧头检测(CHK_HEAD)状态,在帧头接收完毕后(rx_over_dly),判读帧头是不是期望的帧头(chk_head_flag == 2'd1),如果是,就可以继续接收数据长度了,如果不是,那就回到IDLE状态继续等待接收。在数据长度检测(CHK_LEN)状态,在数据长度接收完毕后(rx_over_dly),判读长度是不是期望的长度(chk_head_flag == 2'd1),如果是,就可以继续接收数据了,如果不是,那就回到IDLE状态继续等待接收。经过了两轮的考验,终于可以接收数据了,也是将接收数据分为接收数据(RECV_DATE)和接收数据等待(RECV_WAIT)两个状态,如果接收的数据没有完成就会继续接收,等接收数据完成跳转到接收帧尾状态。在帧尾接收完毕后(rx_over_dly),判读帧尾是不是期望的帧头(chk_tail_flag == 2'd1),如果是,就可以跳转到END状态再跳转到IDLE状态,如果不是,那就直接回到IDLE状态等待接收。


v2-cef3a2f48aab4b19106a6437c33cb35b_720w.png

有了上面的状态机,其实模块设计就很简单了,下面进行发送模块的讲解。通过参数传递的方式进行要发送数据的长度,帧头和帧尾的传递。


v2-a4b7867fcbaaafacb60aed08cdbe2588_720w.png

定义了相关的寄存器和状态机参数,本模块采用三段式的状态机设计方式。


v2-33ac36f391e2fa450491e5315d9f18c1_720w.png

第一段,用时序逻辑控制状态机的更新。


v2-c852f796595c89d5ec13af3ef8f2e000_720w.png

第二段,用组合逻辑控制状态机的跳转。


v2-df120f6f4d4f4625503764e846f75496_720w.png

后面的都是第三段,主要控制数据传递给UART发送模块。首先是发送使能信号的产生,这儿之所以把发送数据分成SEND和WAIT两个状态就,就是为了方便tx_start信号的产生!


v2-46bf2aef6bfa049eb90c48b1645515e9_720w.png

设置了发送数据的计数器send_cnt,在发送数据的状态下每发送一个数据增加一次,在IDLE状态清零,为下次传输做准备。4字节的数据通过移位的方式取出来要发送的数据。


v2-47e17775c4b2a72cdc3536a7d13535ba_720w.png

下面是产生UART发送模块的数据tx_data,在不同的状态机下赋值即可,数据采用左移动的方式,所以每次取高8位即可。一帧数据发送完毕,产生send_done标志信号。


v2-1f43625da42e192b96619c4eb54f4c5a_720w.png

最后例化UART发送模块即可。


v2-b9fcc4d2e0cb305c73ce480370c38e2b_720w.png

数据的接收模块类似,通过参数传递的方式进行要发送数据的长度,帧头和帧尾的传递。


v2-8e9b7bfc892e04ae2a1901ceaa2d01a1_720w.png

定义了相关的寄存器和状态机参数,本模块采用三段式的状态机设计方式。


v2-2c62f05c6c946879798dfa45b0f6f5ac_720w.png

首先要时刻检测UART线上的变化,如果线上由空闲态(高电平)变成低电平,说明一次UART传输开始,检测到这个变化rx_signal_fedge,作为状态机跳转的依据。


v2-88c4432664cfe68f79e33ece5a8214f1_720w.png

第一段,用时序逻辑控制状态机的更新。


v2-8752410fd525b0fc67360ac5fcf2e35f_720w.png

第二段,用组合逻辑控制状态机的跳转。


v2-26d8424aec888cc6e84eec589ca54de6_720w.png

后面的都是第三段,主要控制从UART接收模块接收数据。从UART接收的帧头,数据长度,和帧尾只要有一个校验不过该帧的数据就不能使用。


v2-0fb5d0d9595afe40eea2a9ea560cc81d_720w.png

使用计数器recv_cnt控制数据的接收,同时接收的数据右移动进行存储。这儿需要说明一下为什么会有一个END的状态机,主要是方便判读数据受否正确,状态机能运行到END状态说明帧头,数据长度和帧尾都是正确的,直接把数据锁存即可。


v2-d13abeec03009bb7ed5494a334a72e96_720w.png

为了方便管理,新建了一个顶层文件uart_top,接口信号如下所示,该文件直接对新设计的发送和接收模块例化。


v2-8a0a2ebbfac9d1e190e3efd5b000ce00_720w.png

在仿真tb文件中,对uart_top文件进行例化和参数的传递,并产生4字节的随机数进行仿真,仿真结果如下所示,发送的数据和接收的数据是一致的,功能设计正确。


v2-fbf67ff65710422a933a1c8445476d89_720w.png

目前设计的工程再加上约束文件,编译后下载都FPGA内部是可以直接使用的!所以仅仅使用计数器和状态机模块,就可以完成大多数需求的设计!所以到现在为止,如果你能很快的手动写成这个工程的所有代码并且仿真通过,那你就入门FPGA了,而且达到一般FPGA开发者的水平!


发表于 2024-6-25 13:43:11 | 显示全部楼层
感谢分享
发表于 2024-7-16 09:08:25 | 显示全部楼层
三段式状态机的第二段,用组合逻辑控制状态机的跳转部分是不是漏了SEND状态跳转到WAIT状态的描述呀,不然进入SEND状态后,好像会出问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-27 05:29 , Processed in 0.022610 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表