当前位置: 首页 > news >正文

16路串口光纤通信FPGA项目实现指南

16路串口光纤通信FPGA项目实现指南 - 第一部分

项目概述

本项目实现了一个基于Xilinx FPGA的16路RS422串口光纤通信系统,通过Aurora 8B/10B协议将16路串口数据通过光纤进行高速传输。系统包含32个LED状态指示器,能够实时显示每路串口的数据活动状态。

系统特点

  • 16路串口并行处理
  • 光纤高速传输
  • 实时状态指示
  • 模块化设计
  • IP核复用

一、硬件设计与引脚约束

1.1 引脚分配策略

系统总计使用71个引脚:

  • 时钟引脚:1个(25MHz输入时钟)
  • 串口引脚:32个(16路接收 + 16路发送)
  • LED引脚:34个(32个状态LED + 2个系统LED)
  • 光纤引脚:4个(时钟和收发差分信号)

1.2 引脚约束文件

文件位置uart_fiber.srcs/constrs_1/new/pin.xdc

系统配置设置
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
时钟引脚定义
set_property PACKAGE_PIN P14 [get_ports clk_25m]
set_property IOSTANDARD LVCMOS33 [get_ports clk_25m]
串口引脚定义
# 16路串口接收引脚
set_property PACKAGE_PIN T4 [get_ports {uart_rx[0]}]
set_property PACKAGE_PIN U2 [get_ports {uart_rx[1]}]
# ... 其他14路接收引脚# 16路串口发送引脚
set_property PACKAGE_PIN P4 [get_ports {uart_tx[0]}]
set_property PACKAGE_PIN V2 [get_ports {uart_tx[1]}]
# ... 其他14路发送引脚# 电平标准设置
set_property IOSTANDARD LVCMOS33 [get_ports {uart_rx[*]}]
set_property IOSTANDARD LVCMOS33 [get_ports {uart_tx[*]}]
LED引脚定义
# 16个接收LED引脚
set_property PACKAGE_PIN G17 [get_ports {uart_rx_led[0]}]
set_property PACKAGE_PIN D16 [get_ports {uart_rx_led[1]}]
# ... 其他14个接收LED# 16个发送LED引脚
set_property PACKAGE_PIN G16 [get_ports {uart_tx_led[0]}]
set_property PACKAGE_PIN C17 [get_ports {uart_tx_led[1]}]
# ... 其他14个发送LED# 电平标准设置
set_property IOSTANDARD LVCMOS33 [get_ports {uart_rx_led[*]}]
set_property IOSTANDARD LVCMOS33 [get_ports {uart_tx_led[*]}]
光纤通信引脚定义
set_property PACKAGE_PIN D6 [get_ports GTPQ0_P]
set_property PACKAGE_PIN D5 [get_ports GTPQ0_N]
set_property PACKAGE_PIN E4 [get_ports RXP]
set_property PACKAGE_PIN H2 [get_ports TXP]
系统状态LED引脚定义
set_property PACKAGE_PIN G14 [get_ports {fpga_led[0]}]
set_property PACKAGE_PIN F14 [get_ports {fpga_led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fpga_led[*]}]

二、顶层模块设计与实现

2.1 模块接口定义

文件位置uart_fiber.srcs/sources_1/new/uart_fiber_top.v

module uart_fiber_top(input           clk_25m,        // 25MHz系统时钟input [15:0]    uart_rx,        // 16路串口接收output [15:0]   uart_tx,        // 16路串口发送output [15:0]   uart_rx_led,    // 接收LED指示output [15:0]   uart_tx_led,    // 发送LED指示input           GTPQ0_P,        // 光纤时钟正端input           GTPQ0_N,        // 光纤时钟负端input           RXP,            // 光纤接收正端input           RXN,            // 光纤接收负端output          TXP,            // 光纤发送正端output          TXN,            // 光纤发送负端output [1:0]    fpga_led        // 系统状态LED
);

2.2 时钟管理实现

wire clk_50m;        // 50MHz时钟信号
wire locked;         // 时钟锁定状态// 时钟IP核实例化
init_clk inst_init_clk (.clk_out1(clk_50m),     // 输出50MHz时钟.reset(1'b0),           // 不复位.locked(locked),        // 时钟锁定状态.clk_in1(clk_25m)       // 输入25MHz时钟
);

2.3 复位逻辑实现

// 复位控制信号
(*mark_debug = "true"*)reg [31:0] rst_cnt;    // 复位计数器
(*mark_debug = "true"*)reg rst_gen;           // 复位生成信号
(*mark_debug = "true"*)reg rst_state;         // 复位状态机// 复位控制状态机
always@(posedge clk_50m) beginif(!locked) beginrst_cnt <= 32'b0;rst_gen <= 1'b0;rst_state <= 1'b0;end else begincase(rst_state)1'd0 : beginif(channle_up_reg) beginrst_cnt <= 32'b0;rst_gen <= 1'b0;rst_state <= 1'b0;end else beginrst_cnt <= 32'b0;rst_gen <= 1'b1;rst_state <= 1'b1;endend    1'd1 : beginif(rst_cnt == 32'd50000000) beginif(channle_up_reg) beginrst_cnt <= 'b0;rst_gen <= 1'b0;rst_state <= 1'b0;end else beginrst_cnt <= 'b0;rst_gen <= 1'b1;rst_state <= 1'b1;end    end else if(rst_cnt < 32'd10000) beginrst_cnt <= rst_cnt + 1'b1;rst_gen <= 1'b1;rst_state <= 1'b1;end else beginrst_cnt <= rst_cnt + 1'b1;rst_gen <= 1'b0;rst_state <= 1'b1;endend    endcase end    
end

2.4 Aurora通信模块实例化

aurora_top inst_aurora_top (.init_clk(clk_50m),            // 初始化时钟.user_clk_i(user_clk_i),       // 用户时钟.CHANNEL_UP(CHANNEL_UP),       // 通道建立状态.RESET(rst_gen),               // 复位信号.GT_RESET_IN(rst_gen),         // GT复位信号.GTPQ0_P(GTPQ0_P),             // 光纤时钟正端.GTPQ0_N(GTPQ0_N),             // 光纤时钟负端.RXP(RXP),                     // 光纤接收正端.RXN(RXN),                     // 光纤接收负端.TXP(TXP),                     // 光纤发送正端.TXN(TXN),                     // 光纤发送负端.uart_rx(uart_rx),             // 串口接收.uart_tx(uart_tx)              // 串口发送
);

三、LED控制逻辑实现

3.1 信号声明与同步

// LED控制相关寄存器
reg [27:0] uart_rx_led_cnt [15:0];     // 接收LED计数器数组
reg [27:0] uart_tx_led_cnt [15:0];     // 发送LED计数器数组
reg [15:0] uart_rx_led_flag;           // 接收LED标志
reg [15:0] uart_tx_led_flag;           // 发送LED标志// 串口信号寄存器
reg [15:0] uart_rx_reg0, uart_tx_reg0, uart_rx_reg1, uart_tx_reg1;// 信号同步逻辑
always@(posedge clk_50m) beginuart_rx_reg0 <= uart_rx;uart_tx_reg0 <= uart_tx;uart_rx_reg1 <= uart_rx_reg0;uart_tx_reg1 <= uart_tx_reg0;
end

3.2 生成循环与状态机

genvar i;
generate for(i=0; i<16; i=i+1) begin : rs422_uart// 接收LED控制逻辑always@(posedge clk_50m) beginif(locked == 1'b0) beginuart_rx_state[i] <= 'b0;uart_rx_led_cnt[i] <= 'b0;uart_rx_led_flag[i] <= 1'b1;end else begincase(uart_rx_state[i]) 2'd0 : begin// 边沿检测if((!uart_rx_reg1[i]) && uart_rx_reg0[i] || (!uart_rx_reg0[i]) && uart_rx_reg1[i]) beginuart_rx_state[i] <= 2'd1;uart_rx_led_cnt[i] <= uart_rx_led_cnt[i] + 1'b1;uart_rx_led_flag[i] <= !uart_rx_led_flag[i];end else beginuart_rx_state[i] <= 'b0;uart_rx_led_cnt[i] <= 'b0;uart_rx_led_flag[i] <= 1'b1;endend2'd1 : beginif(uart_rx_led_cnt[i] == 28'd12500000) beginuart_rx_state[i] <= 2'd0;uart_rx_led_cnt[i] <= 'b0;uart_rx_led_flag[i] <= 1'b1;end else beginuart_rx_state[i] <= 2'd1;uart_rx_led_cnt[i] <= uart_rx_led_cnt[i] + 1'b1;uart_rx_led_flag[i] <= uart_rx_led_flag[i];end   enddefault : uart_rx_state[i] <= 2'd0;endcase                                                                endend   // 发送LED控制逻辑(类似接收逻辑)always@(posedge clk_50m) beginif(locked == 1'b0) beginuart_tx_state[i] <= 'b0;uart_tx_led_cnt[i] <= 'b0;uart_tx_led_flag[i] <= 1'b1;end else if(channle_up_reg == 1'b1) begincase(uart_tx_state[i]) 2'd0 : beginif((!uart_tx_reg1[i]) && uart_tx_reg0[i] || (!uart_tx_reg0[i]) && uart_tx_reg1[i]) beginuart_tx_state[i] <= 2'd1;uart_tx_led_cnt[i] <= uart_tx_led_cnt[i] + 1'b1;uart_tx_led_flag[i] <= !uart_tx_led_flag[i];end else beginuart_tx_state[i] <= 'b0;uart_tx_led_cnt[i] <= 'b0;uart_tx_led_flag[i] <= 1'b1;endend2'd1 : beginif(uart_tx_led_cnt[i] == 28'd12500000) beginuart_tx_state[i] <= 2'd0;uart_tx_led_cnt[i] <= 'b0;uart_tx_led_flag[i] <= 1'b1;end else beginuart_tx_state[i] <= 2'd1;uart_tx_led_cnt[i] <= uart_tx_led_cnt[i] + 1'b1;uart_tx_led_flag[i] <= uart_tx_led_flag[i];endenddefault : uart_tx_state[i] <= 'b0;endcase                                                             end else beginuart_tx_state[i] <= 'b0;uart_tx_led_cnt[i] <= 'b0;uart_tx_led_flag[i] <= 1'b1;    endendend
endgenerate

3.3 LED输出赋值

assign uart_rx_led = uart_rx_led_flag;
assign uart_tx_led = uart_tx_led_flag;
assign fpga_led[0] = !channle_up_reg;
assign fpga_led[1] = !channle_up_reg;

3.4 关键设计原理

边沿检测原理
// 检测信号从低到高的上升沿
(!uart_rx_reg1[i]) && uart_rx_reg0[i]// 检测信号从高到低的下降沿  
(!uart_rx_reg0[i]) && uart_rx_reg1[i]// 综合检测上升沿或下降沿
(!uart_rx_reg1[i]) && uart_rx_reg0[i] || (!uart_rx_reg0[i]) && uart_rx_reg1[i]
状态机设计
  • 状态0:等待信号变化,检测到变化后转到状态1
  • 状态1:LED闪烁延时,延时结束后回到状态0
时序控制
  • 使用50MHz时钟,计数到12500000需要0.25秒
  • LED闪烁持续0.25秒后自动熄灭
  • 每次检测到信号变化都会重新触发闪烁

第一部分结束,请查看第二部分文档继续了解Aurora通信接口、核心控制逻辑、调试功能和项目总结。

http://www.dtcms.com/a/283191.html

相关文章:

  • Kotlin获取集合中的元素操作
  • Java与Vue精心打造资产设备管理系统,提供源码,适配移动端与后台管理,助力企业高效掌控资产动态,提升管理效能
  • 【Java】JUC并发(synchronized进阶、ReentrantLock可重入锁)
  • 二重循环:输入行数,打印直角三角形和倒直角三角形
  • Java后端开发核心笔记:分层架构、注解与面向对象精髓
  • 基于Android的旅游计划App
  • Web基础 -MYSQL
  • 冷库耗电高的原因,冷链运营者的降本增效的方法
  • LVS四种模式及部署NAT、DR模式集群
  • CD53.【C++ Dev】模拟实现优先级队列(含仿函数)
  • 【计算机网络】数据通讯第二章 - 应用层
  • 深度学习之反向传播
  • 【迭代】PDF绘本录音播放,点读笔方案调研和初步尝试
  • leetcode 725 分割链表
  • 微算法科技研究量子视觉计算,利用量子力学原理提升传统计算机视觉任务的性能
  • Kafka入门
  • 语音增强论文汇总
  • Go基本数据类型
  • 81、面向服务开发方法
  • Redisson实现分布式锁
  • Redisson实现限流器详解:从原理到实践
  • HTML 入门教程:从零开始学习网页开发基础
  • 前端知识:浏览器工作原理与开发者工具知识笔记
  • WIN10系统优化篇(一)
  • Leetcode 02 java
  • IDEA报错“资源找不到”?重启就好了!!?
  • 使用Dify构建HR智能助理,深度集成大模型应用,赋能HR招聘管理全流程,dify相关工作流全开源。
  • 城市蓝影.
  • 服务注册nacos和OpenFerign(用于封装跨服务之间的调用方法)
  • kubernetes学习笔记(一)