FPGA(Verilog)实现uart传输协议传输数据(含仿真)

这篇具有很好参考价值的文章主要介绍了FPGA(Verilog)实现uart传输协议传输数据(含仿真)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

实现功能:

1.接收uart串行数据,输出并行数据(1byte)。

2.输入并行数据(1byte),输出uart串行数据。

3.完成uart传输的1次环回。

uart协议的1帧数据传输

模块封装-port设置

Verilog代码实现

1.uart接收模块:接收串行数据,输出并行数据和其有效标志。

仿真结果:

2.uart发送模块:接收并行数据,发送串行数据。

仿真结果:

3.uart环回测试。

仿真验证:

仿真结果:

FPGA系统集成-RTL框图


实现功能:

1.接收uart串行数据,输出并行数据(1byte)。

2.输入并行数据(1byte),输出uart串行数据。

3.完成uart传输的1次环回。

uart协议的1帧数据传输

module uart_top #(parameter dvsr = 651,data_width = 8, sb_tick = 16) ( input,FPGA,Verilog,fpga开发,Verilog

模块封装-port设置

module uart_top #(parameter dvsr = 651,data_width = 8, sb_tick = 16) ( input,FPGA,Verilog,fpga开发,Verilog文章来源地址https://www.toymoban.com/news/detail-852743.html

Verilog代码实现
1.uart接收模块:接收串行数据,输出并行数据和其有效标志。
module uart_rx#(
	parameter	UART_BPS='d9600			,	//波特率:1s传输9600个bit
	parameter	CLK_FREQ='d50_000_000		//时钟频率:50MHz
)(
	input 	wire			clk			,
	input 	wire			rst_n		,
	input 	wire			rx			,	//接收的串行数据

	output 	reg		[7:0]	po_data		,	//输出并行数据
	output 	reg				po_flag			//输出有效并行数据的标志信号
);

首先对rx进行时钟同步,消除亚稳态,以及打拍处理提取下降沿;

always@(posedge clk or negedge rst_n)
	if(!rst_n) begin
		rx_d1<=1'b1;
		rx_d2<=1'b1;
		rx_d3<=1'b1;
	end
	else begin
		rx_d1<=rx;		//时钟同步,消除亚稳态
		rx_d2<=rx_d1;	//时钟同步,消除亚稳态
		rx_d3<=rx_d2;	//打拍处理
	end

assign rx_fall = ~rx_d2 & rx_d3 ;	//提取rx下降沿

然后需要数据帧的有效信号,以便知道什么时候计数;

always@(posedge clk or negedge rst_n)
	if(!rst_n) frame_val<=1'b0;
	else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)	//接收完1帧数据
		frame_val<=1'b0;
	else if(rx_fall)
		frame_val<=1'b1;
	else
		frame_val<=frame_val;

1码元符号(1bit)所需的计数器;

always@(posedge clk or negedge rst_n)
	if(!rst_n) baud_cnt<=16'd0;
	else if(frame_val==1'b0)	//数据帧无效
		baud_cnt<=16'd0;
	else if(baud_cnt==BAUD_CNT_MAX-1'b1)
		baud_cnt<=16'd0;
	else
		baud_cnt<=baud_cnt+1'b1;

1bit稳定数据的采样标志信号;

always@(posedge clk or negedge rst_n)
	if(!rst_n) bit_flag<=1'b0;
	else if(baud_cnt==BAUD_CNT_MAX_HALF-1'b1)	//采样需要在中间数据才稳定
		bit_flag<=1'b1;
	else
		bit_flag<=1'b0;

对采样到的bit数据进行计数;

always@(posedge clk or negedge rst_n)
	if(!rst_n) bit_cnt<=4'd0;
	else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)	//10bit数据采样完毕
		bit_cnt<=4'd0;
	else if(bit_flag)	//采样到1bit数据
		bit_cnt<=bit_cnt+1'b1;
	else
		bit_cnt<=bit_cnt;

将接收到的串行数据rx转化为并行数据po_data_t;

always@(posedge clk or negedge rst_n)
	if(!rst_n) po_data_t<=8'b0;
	else if((bit_cnt>=4'd1) && (bit_cnt<BIT_CNT_MAX-1'b1) && bit_flag)	//8bit数据
		po_data_t<={rx_d3,po_data_t[7:1]};	//起始位后接的是低位
	else
		po_data_t<=po_data_t;

并行数据全部拼接完成的标志信号;

always@(posedge clk or negedge rst_n)
	if(!rst_n) po_flag_t<=1'b0;
	else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)
		po_flag_t<=1'b1;
	else
		po_flag_t<=1'b0;

输出并行数据和输出有效并行数据的标志信号。

always@(posedge clk or negedge rst_n)
	if(!rst_n) po_data<=8'b0;
	else if(po_flag_t)
		po_data<=po_data_t;
	else
		po_data<=po_data;

//po_flag_t延迟1拍与po_data同步
always@(posedge clk or negedge rst_n)
	if(!rst_n) po_flag<=1'b0;
	else
		po_flag<=po_flag_t;
仿真结果:

module uart_top #(parameter dvsr = 651,data_width = 8, sb_tick = 16) ( input,FPGA,Verilog,fpga开发,Verilog

2.uart发送模块:接收并行数据,发送串行数据。
module uart_tx#(
	parameter	UART_BPS='d9600			,	//波特率:1s传输9600个bit
	parameter	CLK_FREQ='d50_000_000		//时钟频率:50MHz
)(
	input 	wire			clk			,
	input 	wire			rst_n		,
	input	wire			pi_flag		,	//输入并行数据
	input	wire	[7:0]	pi_data		,	//输入有效并行数据的标志信号

	output 	reg 			tx				//输出串行数据
);

首先同样是uart 1帧数据的有效信号;

always@(posedge clk or negedge rst_n)
	if(!rst_n) frame_val<=1'b0;
	else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)	//发送完1帧数据
		frame_val<=1'b0;
	else if(pi_flag)	//接收到有效的并行数据
		frame_val<=1'b1;
	else
		frame_val<=frame_val;

1码元符号(1bit)所需的计数器;

always@(posedge clk or negedge rst_n)
	if(!rst_n) baud_cnt<=16'd0;
	else if(frame_val==1'b0)	//数据帧无效
		baud_cnt<=16'd0;
	else if(baud_cnt==BAUD_CNT_MAX-1'b1)
		baud_cnt<=16'd0;
	else
		baud_cnt<=baud_cnt+1'b1;

1bit数据的发送标志信号;

always@(posedge clk or negedge rst_n)
	if(!rst_n) bit_flag<=1'b0;
	else if(frame_val && !baud_cnt)
		bit_flag<=1'b1;
	else
		bit_flag<=1'b0;

对bit数据的发送进行计数;

always@(posedge clk or negedge rst_n)
	if(!rst_n) bit_cnt<=4'd0;
	else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)	//10bit数据计数完毕
		bit_cnt<=4'd0;
	else if(bit_flag)	//发送完1bit数据
		bit_cnt<=bit_cnt+1'b1;
	else
		bit_cnt<=bit_cnt;

输出串行数据。

always@(posedge clk or negedge rst_n)
	if(rst_n==1'b0) tx<=1'b1;	//空闲
	else if(bit_flag)
		case(bit_cnt)
			4'd0:	tx<=1'b0;		//起始位
			4'd1:	tx<=pi_data[0];	//最低位数据
			4'd2:	tx<=pi_data[1];
			4'd3:	tx<=pi_data[2];
			4'd4:	tx<=pi_data[3];
			4'd5:	tx<=pi_data[4];
			4'd6:	tx<=pi_data[5];
			4'd7:	tx<=pi_data[6];
			4'd8:	tx<=pi_data[7];	//最高位数据
			4'd9:	tx<=1'b1;		//结束位
			default:tx<=1'b1;
		endcase
仿真结果:

module uart_top #(parameter dvsr = 651,data_width = 8, sb_tick = 16) ( input,FPGA,Verilog,fpga开发,Verilog

3.uart环回测试。
module uart_test#(
	parameter	UART_BPS='d9600			,	//波特率:1s传输9600个bit
	parameter	CLK_FREQ='d50_000_000		//时钟频率:50MHz
)(
	input 	wire clk	,
	input 	wire rst_n	,
	input 	wire rx		,	//接收的串行数据

	output 	wire tx			//发送的串行数据
);

wire [7:0] 	data		;
wire 		data_flag	;

uart_rx#(
	.UART_BPS(UART_BPS),
	.CLK_FREQ(CLK_FREQ)
)u_uart_rx(
	.clk	(clk	),
	.rst_n	(rst_n	),
	.rx		(rx		),

	.po_data(data),
	.po_flag(data_flag)
);

uart_tx#(
	.UART_BPS(UART_BPS),
	.CLK_FREQ(CLK_FREQ)
)u_uart_tx(
	.clk	(clk	),
	.rst_n	(rst_n	),
	.pi_data(data),
	.pi_flag(data_flag),

	.tx(tx)
);

endmodule
仿真验证:
`timescale 1ns/1ns
module tb_uart_test();

parameter	UART_BPS='d9600			;	//波特率:1s传输9600个bit
parameter	CLK_FREQ='d50_000_000	;	//时钟频率:50MHz

reg clk;
reg rst_n;
reg rx;

wire tx;

initial
begin
	clk=1'b0;
	rst_n<=1'b0;
	rx<=1'b1;
	#20
	rst_n<=1'b1;
end

always #10 clk=~clk;

initial
begin
	#200	//空闲状态
	rx_test();

	#(5208*10*20*3)
	#200
	$stop;
end

//输出uart数据帧(10-13)
task rx_test();	//任务函数,类似C语言
	integer j;
	for(j=10;j<13;j=j+1)
		rx_8bit(j);
endtask

//输入8bit并行数据,输出uart数据帧
task rx_8bit(
	input [7:0] data
);
integer i;

for(i=0;i<10;i=i+1)
begin
	case(i)
		0:rx<=1'b0;		//1帧数据
		1:rx<=data[0];
		2:rx<=data[1];
		3:rx<=data[2];
		4:rx<=data[3];
		5:rx<=data[4];
		6:rx<=data[5];
		7:rx<=data[6];
		8:rx<=data[7];
		9:rx<=1'b1;
	endcase
	#(5208*20);		//9600波特率
end
endtask

uart_test#(
	.UART_BPS(UART_BPS),
	.CLK_FREQ(CLK_FREQ)
)u_uart_test(
	.clk	(clk	),
	.rst_n	(rst_n	),
	.rx		(rx		),

	.tx(tx)
);

endmodule
仿真结果:

module uart_top #(parameter dvsr = 651,data_width = 8, sb_tick = 16) ( input,FPGA,Verilog,fpga开发,Verilog

FPGA系统集成-RTL框图

module uart_top #(parameter dvsr = 651,data_width = 8, sb_tick = 16) ( input,FPGA,Verilog,fpga开发,Verilog

到了这里,关于FPGA(Verilog)实现uart传输协议传输数据(含仿真)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA设计——verilog实现乒乓操作并modelsim仿真

    乒乓操作是FPGA设计中常用的一种技巧,它通过数据流控制实现按节拍相互配合的切换,来提高数据处理效率,达到无缝缓冲和处理的效果。本文针对乒乓操作进行学习总结。 完整工程 一、原理图如下 : 1、二选一控制器来对缓冲模块1和2进行选择。 2、数据缓冲模块一般就是

    2023年04月08日
    浏览(27)
  • FPGA 高速数据采集传输毕业论文【附仿真】

    以 FIFO IP 核以及 Verilog 编程设计的数字逻辑模块对JESD204B IP 核输出数据完成接收,处理成驱动设备可读取的数据格式后,送入设计的数字逻辑缓存部分中,通过AXI 总线送入DDR3 SDRAM 中缓存,并由传输部分数字逻辑模块完成缓存深度配置。  介绍设计的具体实现。在数字采集功

    2024年04月25日
    浏览(32)
  • FPGA-结合协议时序实现UART收发器(五):串口顶层模块UART_TOP、例化PLL、UART_FIFO、uart_drive

    串口顶层模块UART_TOP、例化PLL、UART_FIFO、uart_drive,功能实现。 对照代码,串口发送模块UART_TOP实现功能包括: PLL锁相环,实现稳定系统输入时钟功能 UART_FIFO,数据先进先出,实现数据缓存功能,防止出现数据错乱 w_clk_rst = ~w_system_pll_locked;保证复位电平是先高位再地位 r_use

    2024年02月08日
    浏览(46)
  • 基于FPGA和Verilog实现的9层电梯控制器仿真设计

    资源下载地址:https://download.csdn.net/download/sheziqiong/85628810 资源下载地址:https://download.csdn.net/download/sheziqiong/85628810 电梯最少可以往返于0—9层楼。 乘客要去的楼层数A可手动输入并显示,按取消键可清除本次输入。 可自动显示电梯运行的楼层数B 当AB时,电梯上升; 当AB时,

    2024年02月02日
    浏览(57)
  • FPGA用verilog HDL实现串口通讯协议

    串口通信是一种通过串行传输数据的通信方式。它使用单个数据线将数据位逐个传输,而不是同时传输多个数据位。串口通信常用于连接计算机与外部设备,如打印机、调制解调器、传感器等。 串口通信一般使用的是异步传输方式,即发送方和接收方的时钟不同步。数据传输

    2024年02月05日
    浏览(40)
  • 基于FPGA的通用异步收发传输器(UART)设计

    基本目的:   (1)了解UART通讯原理,包括数据传输格式、电气特性等; (2)研究Basys3开发板与PC之间通讯电平规格的转换; (3)设计并实现UART的发送(TX)功能或接收(RX)功能。 高级任务(可选):可调。 (4)设计并实现UART的发送(TX)功能和接收(RX)功能,构建回

    2024年02月16日
    浏览(32)
  • IIC通信协议详解 & PCF8591应用(Verilog实现FPGA)

    该文章结合PCF8591 8-bit AD/DA 模数/数模转换器来详细介绍IIC通信协议,尽量做到条理清晰,通俗易懂。该文图片均从PCF8591手册中截取,一定程度上引导读者学习阅读data sheet。 之后可能会更新 如何将IIC的Verilog实现变为一个IP核,并在pynq-Z2板子上使用 。 2.1 地址位 在I2C总线系统

    2024年02月04日
    浏览(48)
  • FPGA实现UDP视频传输,带抓拍和录像功能,纯verilog代码 提供工程源码和技术支持

    目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的代码,试想,多机互联,出现了问题,你的网卡都不带ping功能,连基本的问题排查机制都不具备,这样的代

    2024年02月07日
    浏览(37)
  • FPGA实现UART通信(1)---发送数据

    1、基本概念 通用异步收发传输器,是一种异步收发传输器,在发送数据通过将并行数据转换成串行数据进行传输,在接收数据时将串行数据转换成并行数据。 串行通信分为同步串行通信和异步串行通信。同步串行通信即需要时钟的参与,通信双方需要在同一时钟的控制下,

    2024年02月04日
    浏览(27)
  • UART协议——FPGA代码篇

            UART 串口通信有几个重要的参数,分别是波特率、起始位、数据位、停止位和奇偶检验位,对于两个使用UART 串口通信的端口,这些参数必须匹配,否则通 起始位:表示数据传输的开始,电平逻辑为“0” 。 数据位:可能值有5、6、7、8、9,表示传输这几个bit 位数

    2024年01月18日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包