UART协议及其verilog实现(2)

embedded/2024/9/23 21:46:49/

#学习记录#

1 UART

 在UART协议及其verilog实现(1)_uart协议verilog-CSDN博客这篇文章中介绍了UART发送数据的代码,UART接收端的代码如下。

2 verilog实现

2.1 发送端代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer:mr-pn-junction 
// 
// Create Date: 2024/04/21 20:52:15
// Design Name: 
// Module Name: uart_tx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module uart_tx(input clk,input rst_n,input start,input [7:0] data,output reg rs232_tx,output reg done);reg [7:0] r_data;reg state;reg [12:0] baud_cnt;reg bit_flag;reg [3:0] bit_cnt;
//=======================r_data=================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)r_data<=8'b0;else if(start)r_data<=data;elser_data<=r_data;
end
//=====================state==================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)state<=1'b0;else if(start)state<=1'b1;else if(done)state<=1'b0;elsestate<=state;
end
//======================baud_cnt===================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)baud_cnt<=13'd0;else if(state)beginif(baud_cnt==13'd28)baud_cnt<=13'd0;elsebaud_cnt<=baud_cnt+13'd1;endelsebaud_cnt<=13'd0;end
//================bit_flag===========================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)bit_flag<=1'b0;else if(baud_cnt == 'd1)bit_flag<=1'b1;elsebit_flag<=1'b0;
end
//======================bit_cnt===================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)bit_cnt<=4'b0;else if(bit_flag)bit_cnt<=bit_cnt+4'd1;else if(bit_cnt ==4'd10)bit_cnt<= 4'b0;elsebit_cnt<=bit_cnt;end
//============================rs232_tx========================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)rs232_tx<=1'b1;else if(state)beginif(bit_flag)begincase(bit_cnt)4'd0: rs232_tx<=1'b0;4'd1: rs232_tx<=r_data[0];4'd2: rs232_tx<=r_data[1];4'd3: rs232_tx<=r_data[2];4'd4: rs232_tx<=r_data[3];4'd5: rs232_tx<=r_data[4];4'd6: rs232_tx<=r_data[5];4'd7: rs232_tx<=r_data[6];4'd8: rs232_tx<=r_data[7];4'd9: rs232_tx<=1'b1;default rs232_tx<=1'b1;endcaseendelsers232_tx<=rs232_tx;endelsers232_tx<=1'b1;end
//================================done================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)done<=1'b0;else if(bit_flag &&(bit_cnt == 4'd9))done<=1'b1;elsedone<=1'b0;endendmodule

2.2 接收端代码

`timescale 1ns/1ps
//mr-pn-junctionmodule uart_rx(input           clk,input           rst_n,input           rs232,output reg[7:0] rx_data,output reg      done
);reg             rs232_t;reg             rs232_t1;reg             rs232_t2;reg     [4:0]   bit_cnt;reg             bit_flag;reg             state;reg     [12:0]  baud_cnt;wire            nege;
//?????
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginrs232_t<=1'b1;rs232_t1<=1'b1;rs232_t2<=1'b1;endelse beginrs232_t<=rs232;rs232_t1<=rs232_t;rs232_t2<=rs232_t1;end
end//nege
assign nege=!rs232_t1 && rs232_t2;
//state
always@(posedge clk or negedge rst_n)beginif(!rst_n)state<=1'b0;else if(nege)state<=1'b1;else if(done)state<=1'b0;elsestate<=state;
end
//baud_cnt
always@(posedge clk or negedge rst_n)beginif(!rst_n)baud_cnt<=13'd0;else if(state)beginif(baud_cnt ==13'd28)baud_cnt<=13'd0;elsebaud_cnt<=baud_cnt+13'd1;endelsebaud_cnt<=13'd0;end
//bit_flag
always@(posedge clk or negedge rst_n)beginif(!rst_n)bit_flag<=1'b0;else if(baud_cnt == 13'd14)bit_flag<=1'b1;elsebit_flag<=1'b0;
end
//bit_cnt
always@(posedge clk or negedge rst_n)beginif(!rst_n)bit_cnt<=4'd0;else if(bit_flag)beginif(bit_cnt == 4'd10)bit_cnt<=4'd0;elsebit_cnt<=bit_cnt+4'd1;endelsebit_cnt<=bit_cnt;
end
//rx_data
always@(posedge clk or negedge rst_n)beginif(!rst_n)rx_data<=8'b0;else if (state)beginif(bit_flag)begincase(bit_cnt)4'd1:rx_data[0] <=rs232_t2;4'd2:rx_data[1] <=rs232_t2;4'd3:rx_data[2] <=rs232_t2;4'd4:rx_data[3] <=rs232_t2;4'd5:rx_data[4] <=rs232_t2;4'd6:rx_data[5] <=rs232_t2;4'd7:rx_data[6] <=rs232_t2;default:rx_data<=rx_data;endcaseendelserx_data<=rx_data;endelserx_data<=rx_data;end
//done
always@(posedge clk or negedge rst_n)beginif(!rst_n)done<=1'b0;else if(bit_flag && (bit_cnt ==4'd10))done<=1'b1;elsedone<=1'b0;endendmodule

2.3 testbench

`timescale 1ns / 1ps
//
// Company: 
// Engineer: mr-pn-junction
// 
// Create Date: 2024/04/26 10:45:26
// Design Name: 
// Module Name: tb_uart_tx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module tb_uart( );reg clk;reg rst_n;reg start;reg [7:0] data;wire rs232_tx;wire done;wire [7:0] rx_data;
initial clk=1'b0;
always #10 clk=~clk;
initial beginrst_n=1'b0;start=1'b0;data='d0;#100rst_n=1'b1;#200data='h55;start=1'b1;#20start=1'b0;#20000data='h58;start=1'b1;#20start=1'b0;#20000$stop;end
uart_rx u_uart_rx(.clk(clk),.rst_n(rst_n),.rs232(rs232_tx),.done(),.rx_data(rx_data)
);uart_tx u_uart(.clk(clk),.rst_n(rst_n),.start(start),.data(data),.rs232_tx(rs232_tx),.done(done));
endmodule

3 仿真结果

参考文献

[1] FPGA(UART通信协议,手把手学会分析时序并写出UART协议)_哔哩哔哩_bilibili 


http://www.ppmy.cn/embedded/38273.html

相关文章

玩comfyui踩过的坑之使用ComfyUI_Custom_NODES_ALEKPET翻译组件问题

环境&#xff1a; 秋叶安装包&#xff0c;安装ComfyUI_Custom_NODES_ALEKPET组件或者直接下载网盘中的包&#xff0c;直接解压包到comfyui根目录/custom_nodes/&#xff0c;重启后&#xff0c;按指导文件操作。 注意&#xff1a;网盘指导包中有配置好的流程json文件&#xff0…

Qwen大模型实践之初体验

Qwen大模型实践之初体验 测试机器, 使用InternStudio提供的开发机&#xff0c;配置如下&#xff1a; 部分资源详细信息&#xff1a; # CPUIntel(R) Xeon(R) Platinum 8369B CPU 2.90GHz# GPU(base) rootintern-studio-50014188:~# studio-smi Running studio-smi by vgpu-smiW…

计算机网络——网络层——OSPF协议的介绍

什么是 OSPF &#xff1f; OSPF 是一个基于链路状态的自治系统内部路由协议&#xff0c;在 TCP/IP 的网络层中进行路由选择&#xff0c;常用于构建大型企业网络或者服务上的骨干网络。在互联网核心路由器之间也可以使用。 OSPF 概述 OSPF 使用的是 Dijkstra&#xff08;最短…

[Redis] 使用布隆过滤器和分布式锁实现用户注册

布隆过滤器&#xff08;Bloom Filter&#xff09;是一种数据结构&#xff0c;用于快速判断一个元素是否可能存在于一个集合中。它通过使用多个哈希函数和一个位数组来表示一个集合&#xff0c;当一个元素被加入到集合时&#xff0c;通过哈希函数计算出多个哈希值&#xff0c;并…

连接docker中的MySQL出现2058错误

出错场景&#xff1a;在虚拟机中用docker技术下载最新版本的MySQL&#xff0c;在本地电脑上连接发现出现2058错误。 解决方法&#xff1a; 按照以下步骤 1. 2. ALTER USER root% IDENTIFIED WITH mysql_native_password BY 自己MySQL的密码; 3.成功

PEI是聚醚酰亚胺(Polyetherimide)在粘接使用时使用UV胶水的优势有哪些?要注意哪些事项?

在使用UV胶水进行聚醚酰亚胺&#xff08;Polyetherimide&#xff0c;PEI&#xff09;粘接时&#xff0c;有一些优势和注意事项&#xff1a; 优势&#xff1a; 1.快速固化&#xff1a; UV胶水具有快速固化的特性&#xff0c;通过紫外线光源的照射&#xff0c;可以在几秒到几分钟…

数据结构--栈

什么是栈 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。后进先出的意思是…

RabbiMQ-消息可靠性

RabbiMQ消息可靠性 生产者可靠性 生产者重试机制 问题&#xff1a;生产者发送消息时&#xff0c;出现了网络故障&#xff0c;导致与MQ的连接中断 解决&#xff1a; spring:rabbitmq:connection-timeout: 1s # 设置MQ的连接超时时间template:retry:enabled: true # 开启超时…