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

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

前面通过计数器实现了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个发送数据的状态机?这样既增加了代码量,又让设计的代码通用性降低!因为数据长度改变一次代码就要重新设计一次。

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

接收状态机也是一样,当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状态等待接收。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 53
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FPGA字节串口接收是指针对FPGA芯片进行的串口通信中,实现一次接收多个字节数据的功能。在串口通信中,常见的是逐个字节传输数据,而FPGA字节串口接收则可以一次接收并处理多个字节数据,提高数据传输效率。 实现FPGA字节串口接收的方法有多种,下面介绍一种常见的实现方式。 首先,需要使用FPGA芯片上的串口接口,并将其配置为接收模式。接着,通过时钟信号来控制数据接收。一般来说,串口通信中使用的是异步通信协议,需要使用时钟信号来同步数据的传输。通过在FPGA设计中引入一个时钟模块,可以在接收数据时进行同步处理。 在数据接收过程中,需要通过串口接收模块将接收到的数据存储在FPGA的缓存中,以便后续的处理。可以使用FIFO(First In First Out)模型来实现数据的缓存,通过设置合适的缓存大小来存储多个字节数据。 对于接收到的多个字节数据,可以通过FPGA中的处理逻辑进行解析和处理。根据具体的需求,可以使用不同的解析算法来获取有效的数据,并进行相应的处理操作,比如数据存储、数据分析等。 需要注意的是,在进行FPGA字节串口接收时,需要考虑数据的一致性和完整性。通过设计合理的通信协议和校验机制,可以确保接收到的数据准确无误。 总之,FPGA字节串口接收是一种提高数据传输效率的方法。通过合适的硬件设计和处理逻辑,可以实现快速、准确地接收和处理多个字节的串口数据。这对于需要高效通信和数据处理的应用场景具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值