名称:UART FIFO 数据收发 FPGA 设计 Verilog Quartus
软件:Quartus
语言:Verilog
功能介绍
本设计为 UART FIFO 数据收发 FPGA 工程,使用 Verilog 编写,在 Quartus 环境下实现。系统通过 RS232/UART 接口接收 PC 发送的数据,将接收到的 8bit 数据写入 FIFO 缓存,再经过并转串、rc 处理模块、串转并等环节,最终通过 UART 发送模块把处理后的数据返回 PC。
工程适合用于串口通信、FIFO 缓冲、数据流处理和 FPGA 与上位机交互实验。设计中包含 UART 接收、UART 发送、波特率时钟产生、8bit FIFO、并串转换、串并转换以及顶层互连逻辑,能够展示从外部串口输入到内部处理再到串口输出的完整硬件数据通路。
应用流程面向批量二进制数据处理实验:PC 将每组定长 bit 数据发送给 FPGA,FPGA 在系统时钟控制下完成接收、缓存、处理和回传。设计文档中还包含程序综合、RTL 图、Testbench、整体仿真、波特率模块仿真、发送模块仿真、接收模块仿真、发送 FIFO 和接收 FIFO 等说明内容,便于结合工程源码理解各部分逻辑。
运行环境
开发语言:Verilog
开发软件:Quartus
工程顶层:my_uart_top
主要工程文件:my_uart_top.qsf、my_uart_top.qpf、my_uart_top.v、FIFO_8_256.v、speed_select.v、uart_recv.v、my_uart_tx.v、my_uart_rx.v、p_to_b.v、b_to_p.v、rc.v、DelayLine.v、PLL_100M.v 等。
压缩包文件:uart3.rar
设计思路
设计采用“UART 接收 + FIFO 缓冲 + 数据处理 + FIFO/发送控制 + UART 发送”的结构。PC 端发送的串行数据先由 UART 接收模块完成起始位、数据位等串口帧解析,接收完成后输出 8bit 并行数据和有效标志;接收数据写入 8bit 宽、256 深度 FIFO,用于隔离串口接收节拍与后级处理节拍,降低数据连续输入时的丢失风险。
FIFO 中的数据由并转串模块按设计流程读出,形成串行 bit 流后送入 rc 处理模块。rc 模块输出 x_reg 等结果信号,后级再通过串转并模块恢复为 8bit 并行数据,并产生发送侧 FIFO 写使能和写数据。整体流程对应 PC 输入一组定长二进制数据,FPGA 内部完成时钟控制下的处理,再将处理后的数据返回 PC 保存的实验需求。
工程说明中给出的应用场景为多组定长数据处理:已有 60000 组、每组 328bit 长度的数据,数据长度可按实验调整,例如后续可能扩展到 800bit;实际实验时也可以只输入部分数据组,例如 10000 组。该设计的重点在于将 PC 与 FPGA 之间的数据通路、缓存控制和串并格式转换组织成可综合的硬件结构,适合学习 UART 数据链路、FIFO 缓冲和批量数据回传类 FPGA 实验。
模块结构
顶层模块为 my_uart_top,主要端口包括 50MHz 时钟 clk、低电平复位 rst_n、RS232 接收 rs232_rx 和 RS232 发送 rs232_tx。
主要模块包括:
1. speed_select:产生 UART 收发所需的波特率采样时钟 clk_bps。
2. uart_recv / my_uart_rx:UART 接收逻辑,完成串口输入数据解析并输出 rx_data、rx_en。
3. FIFO_8_256:8bit 宽、256 深度 FIFO,用于接收侧数据缓存。
4. p_to_b:并转串模块,从接收 FIFO 读取并行数据并输出串行 bit。
5. rc:核心处理模块,接收串行输入 u_bit,输出 x_wire、x_reg 等处理结果。
6. b_to_p:串转并模块,将处理后的串行结果重新组织为 8bit 并行数据。
7. my_uart_tx / uart_send:UART 发送逻辑,将处理结果通过 rs232_tx 返回 PC。
8. PLL_100M:工程中包含 PLL 相关文件,顶层代码中当前将 clk_100M 直接赋值为输入时钟 clk。
开发板验证
工程包含 Quartus 管脚约束/分配文件,可用于对 UART 接收、UART 发送、时钟、复位等外部信号进行 FPGA 引脚绑定和上板调试。设计面向实际串口链路验证,PC 通过 RS232 接口向 FPGA 发送数据,FPGA 完成接收缓存、串并转换处理后,再通过 UART 发送端返回 PC 保存,便于对输入输出数据进行对比验证。
仿真图/仿真说明/设计文档图片
设计文档包含工程文件、程序文件、程序综合、RTL 图、Testbench、仿真图和整体仿真说明,并对波特率模块、发送模块、接收模块、发送 FIFO、接收 FIFO 等部分给出对应说明。文档还描述了 PC 发送多组定长二进制数据到 FPGA、FPGA 处理后返回 PC 保存的工作流程,可作为理解工程结构和验证思路的参考。
部分代码
以下展示顶层模块 my_uart_top 的部分代码,完整源码请下载压缩包查看。
module my_uart_top(clk,rst_n,rs232_rx,rs232_tx); input clk; // 50MHz主时钟 input rst_n; //低电平复位信号 input rs232_rx; // RS232接收数据信号 output rs232_tx; // RS232发送数据信号 wire bps_start; //接收到数据后,波特率时钟启动信号置位 wire clk_bps; // clk_bps的高电平为接收或者发送数据位的中间采样点 wire[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到 wire rx_en; //接收数据有效 wire[7:0] rd_data; //接收数据寄存器,保存直至下一个数据来到 wire rd_en; //接收数据有效 wire empty; wire clk_100M; wire rx_fifo_rd_en;//fifo读使能 wire [7:0] rx_fifo_rd_data;//fifo读数据 wire tx_fifo_wr_en;//fifo写使能 wire [7:0] tx_fifo_wr_data;//fifo写数据 wire rc_rstn;//rc模块复位 wire u_bit;//串行bit输出 //PLL------------------------------------------------- //PLL_100M PLL_100M_inst ( // .inclk0 ( clk ), // .c0 ( clk_100M ) // ); assign clk_100M=clk; //---------------------------------------------------- //波特率选择模块 speed_select speed_select( .clk(clk_100M), .rst_n(rst_n), .clk_bps(clk_bps) ); //接收数据模块 //my_uart_rx my_uart_rx( .clk(clk_100M), //接收数据模块 // .rst_n(rst_n), // .rs232_rx(rs232_rx), // .clk_bps(clk_bps), // .rx_data(rx_data), // .rx_en(rx_en) // ); uart_recv i_uart_recv( .sys_clk(clk_100M), //系统时钟 .sys_rst_n(rst_n), //系统复位,低电平有效 .uart_rxd(rs232_rx), //UART接收端口 .uart_done(rx_en), //接收一帧数据完成标志信号 .uart_data(rx_data) //接收的数据 ); wire [7:0] usedw_rx; //计数324bit=41字节 wire [7:0] usedw_tx; //接收数据存入FIFO FIFO_8_256 FIFO_8_256_rx ( .clock ( clk_100M ), .aclr(~rst_n), .data ( rx_data ),//FIFO写数据 .rdreq ( rx_fifo_rd_en ),//FIFO读使能 .wrreq ( rx_en ),//FIFO写使能 .empty ( ), .full ( ), .usedw ( usedw_rx ), .q ( rx_fifo_rd_data )//FIFO读数据 ); //并转串 p_to_b i_p_to_b( . clk_100M(clk_100M), . rst_n(rst_n),//复位 . usedw_rx(usedw_rx),//计数324bit=41字节 . rx_fifo_rd_en(rx_fifo_rd_en),//fifo读使能 . rx_fifo_rd_data(rx_fifo_rd_data),//fifo读数据 . rc_rstn(rc_rstn),//rc模块复位 . u_bit(u_bit)//串行bit输出 ); wire x_wire; wire x_reg; rc i_rc( .clk(clk_100M) , .rstn(rc_rstn), .u (u_bit) , .x_wire (x_wire), .x_reg(x_reg) ); //串行转并行 b_to_p i_b_to_p( . clk_100M(clk_100M), . rst_n(rst_n),//复位 . rc_rstn(rc_rstn),//rc模块复位 . x_reg(x_reg),//串行bit输入-x_reg- . tx_fifo_wr_en(tx_fifo_wr_en),//fifo写使能 . tx_fifo_wr_data(tx_fifo_wr_data)//fifo写数据 ); //发送数据模块 my_uart_tx my_uart_tx( .clk(clk_100M), //发送数据模块 .rst_n(rst_n), .clk_bps(clk_bps), .rd_data(rd_data), .rd_en(rd_en), .empty(empty), .rs232_tx(rs232_tx) ); //uart_send i_uart_send( // input sys_clk, //系统时钟 // input sys_rst_n, //系统复位,低电平有效 // // input uart_en, //发送使能信号 // input [7:0] uart_din, //待发送数据 // ... 以下代码略,完整源码请下载压缩包查看
213