1. Verilog串口控制器设计背景与需求
在工业自动化和物联网设备中,串口通信因其简单可靠的特性,仍然是设备间数据交互的主流方式之一。我最近完成的一个工业传感器项目就遇到了这样的需求:需要在FPGA上实现一个稳定可靠的串口控制器,用于与上位机进行数据通信。经过多次迭代,最终设计出了一个无奇偶校验、支持115200bps波特率的通用串口控制器。
这个设计有几个关键特点:首先,它完全采用Verilog HDL实现,不依赖任何第三方IP核,具有很好的可移植性;其次,通过了-40℃到85℃的高低温测试,在恶劣环境下依然能稳定工作;最后,整个设计包含完整的仿真测试环境和实际硬件验证方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 串口控制器整体架构设计
2.1 系统框图与接口定义
整个串口控制器的架构可以分为三个主要模块:
- 波特率发生器:根据系统时钟和设定的波特率参数,生成符合时序要求的采样时钟
- 发送模块:实现并串转换,按照串口协议规范发送数据
- 接收模块:完成串并转换,正确采样和解析输入数据
接口信号定义如下:
verilog复制module uart_controller (
input wire clk, // 系统时钟(50MHz)
input wire rst_n, // 低电平复位
input wire rx, // 串行接收数据线
output wire tx, // 串行发送数据线
input wire [7:0] din, // 并行输入数据
input wire wr, // 写使能信号
output wire [7:0] dout,// 并行输出数据
output wire rx_ready, // 接收数据就绪
output wire tx_busy // 发送忙标志
);
2.2 波特率计算与实现
对于50MHz的系统时钟,要实现115200bps的波特率,需要计算分频系数:
code复制分频系数 = 系统时钟频率 / (16 × 波特率)
= 50,000,000 / (16 × 115200)
≈ 27.1267
实际实现时取整数值27,这样产生的实际波特率为:
code复制实际波特率 = 50,000,000 / (16 × 27) ≈ 115740bps
误差率为(115740-115200)/115200 ≈ 0.47%,在RS-232标准允许的范围内。
波特率生成器的Verilog实现:
verilog复制reg [15:0] baud_counter;
reg baud_tick;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
baud_counter <= 0;
baud_tick <= 0;
end else begin
if (baud_counter == 16'd26) begin
baud_counter <= 0;
baud_tick <= 1;
end else begin
baud_counter <= baud_counter + 1;
baud_tick <= 0;
end
end
end
3. 发送模块详细实现
3.1 发送状态机设计
发送模块采用有限状态机(FSM)实现,包含以下状态:
- IDLE:空闲状态,等待发送请求
- START:发送起始位(0)
- DATA:依次发送8位数据
- STOP:发送停止位(1)
- CLEANUP:完成发送,返回空闲状态
状态转移图如下:
code复制 +-------+
| IDLE |
+---+---+
| wr有效
v
+-------+
| START |
+---+---+
| 1个波特周期
v
+-------+
| DATA |---> 依次发送8位
+---+---+
| 最后1位完成
v
+-------+
| STOP |
+---+---+
| 1个波特周期
v
+-------+
|CLEANUP|
+---+---+
|
v
返回IDLE
3.2 发送模块Verilog实现
verilog复制localparam [2:0]
IDLE = 3'b000,
START
