FPGA实现uart协议

article/2025/9/17 12:10:34

简介

使用verilog实现uart协议,能够和pc进行通信,实现串口回环功能,各参数设置如下:

  • 波特率:115200
  • 数据位:8
  • 停止位:任意
  • 校验位:无

系统时钟为50M,115200波特率下,每一个bit占50M/115200 = 434时钟周期。
停止位任意即不考虑停止位。代码追求简洁,能用就行。
注意:uart协议是LSB优先的

接收模块

接收模块从pc端接收到异步的串行信号,解析为valid信号+一字节并行数据,传递到其他模块,回环的话,直接传递到发送模块。
流程:

  1. 首先对输入的异步信号rx打两拍防止亚稳态
  2. 检测rx下降沿,拉高计数器使能
  3. 波特计数器循环计数0到433,比特计数器根据波特计数器溢出,从0计数到8,其中0是起始位,1-8是数据位
  4. 在每一位中间进行采样,即波特计数器=433/2时,数据比较稳定,所以在此刻采样进移位寄存器
  5. 波特计数器和比特计数器都结束时,拉低计数器使能,拉高valid一时钟周期,输出移位寄存器中的数据。

代码:

module uart_rx(input               clk,            // 50Minput               rst_n,// uart sideinput               rx,// host sideoutput reg          valid,output reg  [7:0]   data
);
//---------------------------------信号声明-----------------------------------localparam BAUD_RATE    = 115200;localparam BAUD_CNT_MAX = (50_000_000 / BAUD_RATE) - 1;// rx打两拍,第三拍检测下降沿reg [2:0]   rx_shift;// 计数器使能reg         cnt_ena;// baud计数器reg [12:0]  baud_cnt;// bit计数器reg [3:0]   bit_cnt;
//---------------------------------------------------------------------------// rx打两拍,第三拍检测下降沿always @(posedge clk, negedge rst_n) beginif(!rst_n)rx_shift <= 3'b111;elserx_shift <= {rx, rx_shift[2:1]};end// 计数器使能always @(posedge clk, negedge rst_n) beginif(!rst_n)cnt_ena <= 0;else if(~rx_shift[1] & rx_shift[0])// rx下降沿cnt_ena <= 1'b1;else if(baud_cnt == BAUD_CNT_MAX && bit_cnt == 4'd8)cnt_ena <= 1'b0;end// baud cntalways @(posedge clk, negedge rst_n) beginif(!rst_n)baud_cnt <= 0;else if(cnt_ena) beginif(baud_cnt == BAUD_CNT_MAX)baud_cnt <= 0;elsebaud_cnt <= baud_cnt + 13'd1;end  end// bit cntalways @(posedge clk, negedge rst_n) beginif(!rst_n)bit_cnt <= 0;else if(cnt_ena && baud_cnt == BAUD_CNT_MAX) beginif(bit_cnt == 4'd8)bit_cnt <= 0;elsebit_cnt <= bit_cnt + 4'd1;endend// output validalways @(posedge clk, negedge rst_n) beginif(!rst_n)valid <= 0;else if(baud_cnt == BAUD_CNT_MAX && bit_cnt == 4'd8)valid <= 1'b1;elsevalid <= 1'b0;end// output dataalways @(posedge clk, negedge rst_n) beginif(!rst_n)data <= 0;else if(cnt_ena && baud_cnt == (BAUD_CNT_MAX / 2))    // 在每个bit中间采样进入移位寄存器data <= {rx_shift[0], data[7:1]};end
endmodule

对该模块进行简单的波形仿真,对其发送三次数据,分别是8’h01, 8’hab, 8’hff, tb如下:

`timescale 1ps/1ps
module uart_rx_tb;reg clk = 1'b1;always #10 clk = ~clk;reg rst_n = 1'b0;reg rx = 1'b1;wire       valid;wire [7:0] data;integer i = 0;initial begin#30 rst_n = 1'b1;#10;#10000;receieve_data(8'h01);receieve_data(8'hab);receieve_data(8'hff);#100 $stop(2);// $finish;endtask receieve_data;input [7:0] sim_data;begin// 起始位rx <= 1'b0;#(20 * 434);// 8bit数据for(i = 0; i < 8; i = i + 1) beginrx <= sim_data[i];#(20 * 434);end// 停止位rx <= 1'b1;#(20 * 434);#1000;endendtaskuart_rx inst_uart_rx (.clk   (clk), .rst_n (rst_n), .rx    (rx), .valid (valid), .data  (data));endmodule

波形图如下,可以观察到,三次valid拉高时的data正好对应了8’h01, 8’hab, 8’hff
在这里插入图片描述

发送模块

发送模块接收内部的valid+data,转化为uart串行信号通过io输出。
流程:

  1. 检测到valid信号,则对data进行寄存,并拉高计数器使能
  2. 波特计数器循环计数0到433,比特计数器根据波特计数器溢出,从0计数到8,其中0是起始位,1-8是数据位
  3. 根据比特计数器值输出对应的数据位

代码:

module uart_tx(input           clk,            // 50Minput           rst_n,// host sideinput           valid,input   [7:0]   data,// uart sideoutput          tx
);
//------------------------------------信号声明---------------------------localparam BAUD_RATE    = 115200;localparam BAUD_CNT_MAX = (50_000_000 / BAUD_RATE) - 1;// 数据寄存 + 起始位reg [8:0]   data_start_reg;// 计数器使能reg         cnt_ena;// baud计数器reg [12:0]  baud_cnt;// bit计数器reg [3:0]   bit_cnt;
//----------------------------------------------------------------------// 数据寄存 + 起始位always @(posedge clk, negedge rst_n) beginif(!rst_n)data_start_reg <= 0;else if(valid)data_start_reg <= {data, 1'b0};end// cnt_enaalways @(posedge clk, negedge rst_n) beginif(!rst_n)cnt_ena <= 0;else if(valid)cnt_ena <= 1'b1;else if(baud_cnt == BAUD_CNT_MAX && bit_cnt == 4'd8)cnt_ena <= 0;end// baud_cntalways @(posedge clk, negedge rst_n) beginif(!rst_n)baud_cnt <= 0; else if(cnt_ena) beginif(baud_cnt == BAUD_CNT_MAX)baud_cnt <= 0;elsebaud_cnt <= baud_cnt + 13'd1;endend// bit_cntalways @(posedge clk, negedge rst_n) beginif(!rst_n)bit_cnt <= 0;else if(cnt_ena && baud_cnt == BAUD_CNT_MAX) beginif(bit_cnt == 4'd8)bit_cnt <= 0;elsebit_cnt <= bit_cnt + 4'd1;endend// txassign tx = cnt_ena ? data_start_reg[bit_cnt] : 1'b1;
endmodule

对该模块进行简单的波形仿真,让其发送三次数据,分别是8’h01, 8’hab, 8’hff, tb如下:

`timescale 1ps/1ps
module uart_tx_tb;reg clk = 1'b1;always #10 clk = ~clk;reg rst_n = 1'b0;reg       valid = 1'b0;reg [7:0] data  = 8'd0;wire tx;initial begin#30 rst_n = 1'b1;#10;#10000;uart_send(8'h01);uart_send(8'hab);uart_send(8'hff);#100 $stop(2);// $finish;endtask uart_send;input [7:0] send_data;beginvalid <= 1'b1;data  <= send_data;#20;valid <= 1'b0;data  <= 8'd0;#(20 * 434 * 10);   // 10baud#1000;endendtaskuart_tx inst_uart_tx (.clk   (clk),.rst_n (rst_n),.valid (valid),.data  (data),.tx    (tx));endmodule

波形如下,可以看到,valid信号后,tx端会将数据转化为uart串行数据发送出去,由于data只持续1时钟周期,所以图片看不清楚,三次valid对应的data分别是8’h01, 8’hab, 8’hff
在这里插入图片描述

效果演示

顶层模块就不细说了,将接收模块的valid+data接到发送模块的valid+data即可
串口软件使用正点原子的XCOM,发送字符串hello world!,接收如下:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/weXB1Qro.shtml

相关文章

协议篇之UART协议

协议篇之UART协议 一、写在前面二、UART协议简介三、UART协议数据帧结构3.1 UART发送过程3.2 UART接收过程3.3 UART传输速率 四、UART收发模块设计4.1 UART接收模块设计4.2 UART发送模块设计4.3 UART回环顶层模块4.4 UART回环上板验证 五、写在最后 一、写在前面 由于设计需要&…

UART通信协议

UART通信协议 UART ( universal asynchronous receiver-transmitter&#xff09;是一种采用异步串行通信方式的通用异步收发传输器;它在发送数据时将并行数据转换成串行数据来传输&#xff0c;在接收数据时将接收到的串行数据转换成并行数据。UART串口通信需要两根信号线来实现…

UART协议讲解

UART协议讲解 一、什么是UART协议二、通信方式的分类1、串行通信&#xff08;一&#xff09;、同步通信和异步通信&#xff08;二&#xff09;、单工和半双工以及全双工 2、并行通信 三、UART协议具体介绍1、UART数据传输的格式2、UART电平标准 三、UART的优缺点四、参考 一、什…

【数字IC】深入浅出理解UART协议

深入浅出理解UART协议 一、什么是UART&#xff1f;二、UART的帧格式2.1 为什么UART的传输需要起始位&#xff1f;2.2 UART基本的数据形式2.3 为什么UART的数据位可变&#xff1f; 三、UART的波特率3.1 什么是波特率3.2 如何换算波特率3.3 波特率和采样频率是一样的吗&#xff1…

最详细的 UART协议 分析在这里!

1. 协议基础 1.1. 协议简介 UART是“Universal Asynchronous Receiver/Transmitter”&#xff0c;通用异步收发器的缩写。在19世纪60年代&#xff0c;为了解决计算机和电传打字机通信&#xff0c;Bell发明了UART协议&#xff0c;将并行输入信号转换成串行输出信号。因为U…

UART协议

UART协议 简介 UART是通用异步收发传输器&#xff08;Universal Asynchronous Receiver/Transmitter)&#xff0c;通常称作UART&#xff0c;是一种异步收发传输器,是设备间进行异步通信的关键模块。UART负责处理数据总线和串行口之间的串/并、并/串转换&#xff0c;并规定了帧…

【云域网络社区】云域网络社区APP

【软件名称】云域社区 【功能介绍】资源分享&#xff0c;游戏交流交友 【下载地址】http://sss.shmmec.com/apk.apk 图片

怎么划分领域、子域、核心域、通用域和支撑域

怎么划分领域、子域、核心域、通用域和支撑域 如何理解领域和子域&#xff1f;什么是领域什么是子域怎么划分领域和子域如何理解核心域、通用域和支撑域&#xff1f;为什么要划分核心域、通用域和支撑域 总结 DDD 的知识体系提出了很多的名词&#xff0c;像&#xff1a;领域、子…

网络安全-域服务器(二)

域服务器&#xff1a; 域服务器&#xff08;一&#xff09;&#xff1a;网络安全-域&#xff08;一&#xff09;_IT之一小佬的博客-CSDN博客域服务器&#xff08;二&#xff09;&#xff1a;网络安全-域服务器&#xff08;二&#xff09;_IT之一小佬的博客-CSDN博客 域 11.O…

网课管理系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 3. 功能简介 用户中心 1.1用户注册&#xff1a;用户需要注册才能登陆进入web 1.2用户登录&#xff1a;通过判断匹配来进…

如何搭建域服务器

实验名称&#xff1a;如何搭建域服务器 实验环境&#xff1a;wind2003*2 实验过程&#xff1a; 由于Windows Server 2003在默认的安装过程中DNS是不被安装的&#xff0c;所以我们需要手动去添加&#xff0c; 添加方法如下:“开始—设置—控制面板—添加删除程序”&#xff…

搭建域环境(win)

目录 常见域环境是用&#xff1a;win2012 win7 win2003 本blog环境&#xff1a;Windows Server 2012 R2 and Win2008 1.Window Server 2012 R2 服务器配置 1&#xff09;变更计算机名DC&#xff08;用于存储活动目录数据库的计算机&#xff09; 2&#xff09;设置服务器…

网络教学管理系统

1、项目介绍 网络教学管理系统拥有三种角色 管理员&#xff1a;专业管理、班级管理、学生教师管理、公告管理、留言板管理、学习资料管理、教学视频管理、试题管理等 教师&#xff1a;系统留言、发布作业等 学生&#xff1a;可以查看作业视频、登录注册、下载作业资料等 2、…

域控-笔记二(域权限,域组,域管理,Kerberso 协议)

文章目录 一. 域环境搭建1.1 添加AD功能1.2 安装1.3 部署 二. 如何加入域2.1 加入域2.2 域中主机登录2.3 退出域2.4 添加域用户 三. 域权限3.1 A-G-DL-P策略3.2 组几个比较重要的域本地组几个比较重要的全局组、通用组的权限 四. 域管理4.1 域用户账户的管理4.2 组的管理4.3 组…

中职网络搭建 域用户密码设置

中职网络搭建 密码设置 域密码策略&#xff1a; 进入域控制器组策略&#xff08;组策略管理&#xff09; 计算机配置–Windows设置–安全设置–账户策略–密码策略 “密码必须符合复杂性要求”&#xff1a;密码设置必须要有数字、大写字母、小写字母、字符&#xff0c;四种中…

第一讲 数域

1. 引入 数是数学的一个最基本概念, 回顾一下我们曾经学习过的数的发展过程: (1) 代数性质: 关于数的加, 减, 乘 , 除等运算的性质称为数的代数性质. (2) 数集: 数的集合简称数集. 常见的数集: 复试C; 实数R;有理数Q等等. 它们有一个共同的性质就是对加减乘除运算封闭. 2. 数…

域控知识与安全02:初始访问

初始访问 前言信息收集1.Nmap命令参数使用方法 2.Metasploit命令参数使用方法 3.地址解析协议命令参数使用方法 4.ICMP5.Nbtscan命令参数使用方法 6.telnet使用方法 暴力破解1.Hydra命令参数使用方法 2.Hashcat常用参数使用方法 总结系列相关内容 前言 攻击者首先通过初始访问入…

1. 跨域学习

1. 跨域学习 1.1 什么是跨域 出于浏览器的同源策略限制。同源策略&#xff08;Sameoriginpolicy&#xff09;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;如果缺少了同源策略&#xff0c;则浏览器的正常功能可能都会受到影响。可以说Web是构建在同…

域的基础概念

初具规模的办公网络通常以Windows域的形式进行管理&#xff0c;域在内网渗透中的地位举足轻重&#xff0c;本文主要介绍域的基础概念&#xff0c;为后续域渗透的介绍做铺垫 部分内容参考文章&#xff1a;https://blog.csdn.net/wulantian/article/details/42418231 文章目录 1.…

域&#xff0c;Domain。 计算机域是一个有安全边界的计算机集合&#xff0c;在同一个域中的计算机彼此之间已经建立了信任关系&#xff0c;在域内访问其他机器&#xff0c;不再需要被访问机器的许可。 1.一台计算机在内网环境中有两种工作模式&#xff1a; 工作组&#xff1a;默…