(旁支)2_串口接收模块时序设计与编写 & 仿真及上板验证
2_串口接收模块时序设计与编写 & 仿真及上板验证
A_串口接收模块时序设计
原理介绍
- 串口通信
- 由两根线构成:TXD(发送)和RXD(接收)
- 每次传输一个比特(0或1)
- 按照字节(8位)为单位进行传输
- 先传输低位(LSB),再传输高位(MSB)
- 串口协议
- 定义了传输数据的时序关系
- 包括空闲位、起始位、数据位、校验位和停止位
- 空闲位:高电平,表示没有传输数据
- 起始位:低电平,表示开始传输数据
- 数据位:8个比特,表示要传输的字节内容
- 校验位:可选,用于验证数据是否正确
- 停止位:高电平,表示结束传输数据
硬件电路
- PC端
- 使用USB线连接到Type-C接口
- 使用CH340C芯片转换USB协议为串口协议
- 发送TXD信号到FPGA端
- FPGA端
- 使用两个触发器进行跨时钟域处理
- R1:接收TXD信号
- R2:输出TXD_R2信号给串口接收模块
- 使用串口接收模块进行数据提取和输出
- RX_DATA:8位输出端口,存储字节数据
- RX_DATA_VLD:1位输出端口,表示数据有效
- 使用两个触发器进行跨时钟域处理
设计方法
- 跨时钟域处理
- 使用两个触发器对TXD信号进行打两拍操作
- 防止冒险和毛刺
- 参考MTBF(平均无故障时间)概念
- 使用两个触发器对TXD信号进行打两拍操作
- 数据提取
- 使用波特率(BPS)计算每个比特的传输时间
- 波特率:每秒传输的比特数
- 例:115200 BPS,每个比特约8.68微秒
- 使用时钟周期计算每个比特的采样点
- 时钟周期:电路工作的基本单位时间
- 例:50 MHz,每个时钟周期20纳秒
- 使用计数器在每个比特的中间位置产生采样标志信号
- 中间位置:数据稳定且准确的位置
- 采样标志信号:BIT_FLAG,高电平表示可以采样
- 使用移位拼接操作符将单比特信号转换为多比特信号
- 移位拼接操作符:<<或>>
- 单比特信号:TXD_R2,从串口芯片接收的数据
- 多比特信号:RX_DATA,输出到下一级模块的数据
- 使用波特率(BPS)计算每个比特的传输时间
串口协议和时序的示意图如下:
sequenceDiagram
participant TXD as TXD信号
participant RXD as RXD信号
Note over TXD: 空闲状态(高电平)
TXD->>RXD: 起始位(低电平)
Note over TXD: 数据位(8位)
loop 每个比特
TXD->>RXD: D0(最低位)到D7(最高位)
end
Note over TXD: 校验位(可选)
opt None
Note over TXD: 无校验
end
opt Odd
Note over TXD: 奇校验(使1的个数为奇数)
TXD->>RXD: 校验位(0或1)
end
opt Even
Note over TXD: 偶校验(使1的个数为偶数)
TXD->>RXD: 校验位(0或1)
end
opt Mark
Note over TXD: 标记校验(固定为1)
TXD->>RXD: 校验位(1)
end
Note over TXD: 停止位(高电平)
opt 1位
Note over TXD: 停止位为1位
TXD->>RXD: 停止位(高电平)
end
opt 2位
Note over TXD: 停止位为2位
loop 每个比特
TXD->>RXD: 停止位(高电平)
end
end
串口接收模块的设计思路如下:
- 首先,需要对 TXD 信号进行跨时钟域处理,因为 TXD 信号是由 PC 端或其他设备产生的,它的时钟域和 FPGA 内部的时钟域不一致。跨时钟域处理的目的是避免时序冲突和数据丢失。跨时钟域处理的方法是使用两级触发器(D 触发器或 JK 触发器)对 TXD 信号进行两次采样,从而使 TXD 信号与 FPGA 内部的时钟同步。跨时钟域处理的示意图如下:
sequenceDiagram
participant TXD as TXD信号
participant CLK as FPGA内部时钟
participant R1 as 第一级触发器
participant R2 as 第二级触发器
participant TXD_R2 as 跨时钟域后的TXD信号
Note over TXD: 由PC端或其他设备产生的串口数据
Note over CLK: FPGA内部的时钟信号
Note over R1: 第一级触发器用于采样TXD信号
Note over R2: 第二级触发器用于同步TXD信号
Note over TXD_R2: 跨时钟域后的TXD信号,可以在FPGA内部使用
loop 每个时钟周期
TXD->>R1: 输入TXD信号
CLK->>R1: 输入CLK信号
R1->>R2: 输出TXD_R1信号
CLK->>R2: 输入CLK信号
R2->>TXD_R2: 输出TXD_R2信号
end
- 其次,需要对 TXD_R2 信号进行采样和拼接,从而提取出完整的字节数据。采样和拼接的方法是使用一个计数器和一个移位寄存器。计数器用于计算每个比特的宽度,也就是每个比特占用多少个时钟周期。移位寄存器用于将每个比特按照顺序拼接成一个字节。采样和拼接的示意图如下:
sequenceDiagram
participant TXD_R2 as 跨时钟域后的TXD信号
participant REG as 移位寄存器
participant CHK as 校验器
participant OUT as 输出控制器
participant RX_DATA as 输出字节数据
participant RX_DATA_VLD as 输出数据有效标志
Note over TXD_R2: 跨时钟域后的TXD信号,包含起始位、数据位、校验位、停止位等信息
Note over REG: 移位寄存器用于将每个比特按照顺序拼接成一个字节。移位寄存器可以根据数据位和校验位来确定位宽和移位方向。
Note over CHK: 校验器用于根据校验位的方式,对移位寄存器中的数据进行校验,判断数据是否有误。校验器可以输出一个错误标志(err_flag),表示数据是否通过校验。
Note over OUT: 输出控制器用于根据停止位的方式,对移位寄存器中的数据进行输出,将数据和数据有效标志发送给后续模块。输出控制器可以输出一个清零标志(clr_flag),表示移位寄存器是否需要清零。
Note over RX_DATA: 输出字节数据,也就是提取出来的串口数据。
Note over RX_DATA_VLD: 输出数据有效标志,表示输出字节数据是否可用。输出数据有效标志可以用一个高电平脉冲来表示。
loop 每个时钟周期
TXD_R2->>REG: 输入TXD_R2信号
REG->>CHK: 输出移位寄存器的值(rx_data)
CHK->>OUT: 输出错误标志(err_flag)
OUT->>REG: 输出清零标志(clr_flag)
OUT->>RX_DATA: 输出移位寄存器的值(rx_data)
OUT->>RX_DATA_VLD: 输出数据有效标志(rx_data_vld)
alt 停止位为1位
Note over OUT: 当检测到停止位为高电平时,如果没有错误,则输出数据和数据有效标志;如果有错误,则不输出,并清零移位寄存器。
end
alt 停止位为2位
Note over OUT: 当检测到两个连续的停止位为高电平时,如果没有错误,则输出数据和数据有效标志;如果有错误,则不输出,并清零移位寄存器。
end
end