个人学习笔记3----串口(uart)通信及Verilog HDL语法优先级
串口通信
1. 串口通信定义、工作原理及协议传输时序
通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),通常称作 UART,是一种异步收发传输器。将数据由串行通信与并行通信间作传输转换, UART 是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。
UART 作为异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输。
其中每一位(Bit)的意义如下:
起始位:先发出一个逻辑”0”的信号,表示传输字符的开始。
数据位:紧接着起始位之后,数据位的个数可以是 4、5、6、7、8 等,构成一个字符。通常采用 ASCII 码,从最低位开始传送,靠时钟定位。
奇偶校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验
数据传送的正确性。
停止位:它是一个字符数据的结束标志。可以是 1 位、1.5 位、2 位的高电平。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
空闲位:处于逻辑“1”状态,表示当前线路上没有数据传送。UART 协议传输时序如图 1
所示。
2. uart收发过程工作原理
发送数据过程:空闲状态,线路处于高电位 ;当收到发送数据指令后,拉低线路一个数据位的时间 T,接着数据按低位到高位依次发送,数据发送完毕后,接着发送奇偶校验位和停止位 (停止位为高电位),一帧数据发送结束。
接收数据过程:空闲状态,线路处于高电位;当检测到线路的下降沿(线路电位由高电位变为低电位)时说明线路有数据传输,按照约定的波特率从低位到高位接收数据,数据接收完毕后,接着接收并比较奇偶校验位是否正确,如果正确则通知后续设备准备接收数据或存入缓存。由于 UART 是异步传输,没有传输同步时钟。为了能保证数据传输的正确性,UART 采用 16 倍数据波特率的时钟进行采样。每个数据有 16 个时钟采样,取中间的采样值,以保证采样不会滑码或误码。一般 UART 一帧的数据位数为 8,这样即使每个数据有一个时钟的误差,接收端也能正确地采样到数据。一个标准的 10 位异步串行通信协议(包含 1 个起始位、1 个停止位和 8 个数据位)收发时序,如图 2 所示:
3. 波特率
波特率表示每秒钟传送的码元符号的个数,它是对符号传输速率的一种度量,它用单位时间内载波调制状态改变的次数来表示,1波特即指每秒传输1个符号。在串口通信中,我们常用的波特有9600,19200,115200等,9200也就是每秒发送9600个bit数据,称为波特率为9600,其他的以此类推。
4. 串口程序设计
我们接下来的设计的串口程序波特率为115200。
4.1 发送模块(uart_tx)
4.1.1 整体模块图

4.1.2 模块分析
4.1.2.1 顶层模块
4.1.2.1.1 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk | 1 bit | reg | input | 25M时钟 |
| reset | 1 bit | reg | input | 复位信号 |
| data_in_valid | 1 bit | reg | input | 数据输入有效信号 |
| data_in | 8 bit | reg | input | 8位数据输入 |
| uart_tx_port | 1 bit | reg | output | 数据输出 |
4.1.2.1.2 Verilog 程序

4.1.2.2 波特率使能模块(Enable_baud_tx)
首先我们设计的是波特率为115200的串口发送程序,也就是说,需要1s发送115200个bit字节,列式为:1s / 115200 = 8.68us, 也就是需要我们每8.68us进行输出一次脉冲信号,也就是上面模块所示的Enable_baud_tx信号,以25M时钟为例,周期为40ns,计时8.68us,需要计数217。
4.1.2.2.1 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk | 1 bit | reg | input | 25Mz时钟信号 |
| reset | 1 bit | reg | input | 复位信号 |
| start | 1 bit | reg | input | 计数的使能信号 |
| Enable_baud_tx | 1 bit | reg | output | 发送数据使能信号 |
4.1.2.2.2 Verilog 程序

4.1.2.3 数据发送模块(uart_tx)
4.1.2.3.1 状态转移图

4.1.2.3.2 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk | 1 bit | reg | input | 25M时钟信号 |
| reset | 1 bit | reg | input | 复位信号 |
| Enable_baud_tx | 1 bit | reg | input | 状态转移使能信号 |
| data_in_valid | 1 bit | reg | input | 数据输入有效信号 |
| data_in | 8 bit | reg | input | 8位的数据输入 |
| tx_busy | 1 bit | reg | output | 串口正在发送,忙碌信号 |
| uart_tx_port | 1 bit | reg | output | 数据送出 |
4.1.2.3.3 Verilog 程序

4.2 接收模块(uart_rx)
4.2.1 整体模块图

4.2.2 模块分析
4.2.2.1 顶层模块
4.2.2.1.1 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk | 1 bit | reg | input | 25M时钟 |
| reset | 1 bit | reg | input | 复位信号 |
| uart_rx_port | 1 bit | reg | input | 数据输入 |
| data_out_valid | 1 bit | reg | output | 数据输出有效信号 |
| data_out | 8 bit | reg | output | 8位数据输出 |
4.2.2.1.2 Verilog 程序

4.2.2.2 波特率使能模块(Enable_baud_rx)
首先我们设计的是波特率为115200的串口接收程序,也就是说,需要1s接收115200个bit字节,列式为:1s / 115200 = 8.68us, 也就是需要我们每8.68us进行输出一次脉冲信号,也就是上面模块所示的Enable_baud_rx信号,以25M时钟为例,周期为40ns,计时8.68us,需要计数217,但是为了使接收的数据稳定,我们选择在数据中间进行接收,即当计数为108的时候,输出Enable_baud_rx信号。
4.2.2.2.1 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk | 1 bit | reg | input | 25Mz时钟信号 |
| reset | 1 bit | reg | input | 复位信号 |
| start | 1 bit | reg | input | 计数的使能信号 |
| Enable_baud_tx | 1 bit | reg | output | 接收数据使能信号 |
4.2.2.2.2 Verilog 程序

4.2.2.3 数据接收模块(uart_rx)
4.2.2.3.1 状态转移图

4.2.2.3.2 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk | 1 bit | reg | input | 25M时钟信号 |
| reset | 1 bit | reg | input | 复位信号 |
| Enable_baud_rx | 1 bit | reg | input | 状态转移使能信号 |
| uart_rx_port | 1 bit | reg | input | 数据输入 |
| rx_busy | 1 bit | reg | output | 串口正在接收,忙碌信号 |
| data_out_valid | 1 bit | reg | output | 数据输出有效信号 |
| data_out | 8 bit | reg | output | 8位数据输出 |
4.2.2.3.3 判断上升下降沿

串口接收需要判断下降沿,代码附后;
4.2.2.3.4 Verilog 程序

5. 串口实例
5.1 实例需求及分析
我们实例功能要求为,上位机通过串口调试助手发送数据给FPGA,FPGA通过串口接收数据并将接
收到的数据发送给上位机,完成串口数据环回。
5.2 整体模块图

5.3 模块分析
5.3.1 顶层模块
5.3.1.1 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk_50M | 1 bit | reg | input | 开发板50M时钟 |
| uart_rx | 1 bit | reg | input | 数据输入 |
| uart_tx | 1 bit | reg | output | 数据输出 |
5.3.1.2 Verilog 程序

5.3.2 锁相环模块(PLL)
通过调用IP核,创建锁相环,创建输入50M时钟,输出25M时钟信号的PLL。 创建过程略。
5.3.3 uart_rx_top模块
5.3.3.1 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk | 1 bit | reg | input | 25M时钟 |
| reset | 1 bit | reg | input | 复位信号 |
| uart_rx_port | 1 bit | reg | input | 数据输入 |
| data_out_valid | 1 bit | reg | output | 数据输出有效信号 |
| data_out | 8 bit | reg | output | 8位数据输出 |
5.3.3.2 Verilog 程序

5.3.4 uart_tx_top模块
5.3.4.1 输入输出信号描述
| 信号 | 位宽 | 类型 | 输入/输出 | 功能描述 |
|---|---|---|---|---|
| clk | 1 bit | reg | input | 25M时钟 |
| reset | 1 bit | reg | input | 复位信号 |
| data_in_valid | 1 bit | reg | input | 数据输入有效信号 |
| data_in | 8 bit | reg | input | 8位数据输入 |
| uart_tx_port | 1 bit | reg | output | 数据输出 |
5.3.4.2 Verilog 程序

5.4 结果演示

效果符合预期。
5.5 附录
管脚IO约束

Verilog HDL语法优先级
