串口系列知识分享:
(1)串口通信实现-串口发送
(2)串口通信发送多字节数据
(3)串口通信实现-串口接收
(4)UART 通信-使用VIO进行板级验证
(5)串口接收-控制LED闪烁
(6)使用串口发送实现ACX720开发板时钟显示
(7)串口发送+RAM+VGA传图
文章目录
前言
本章将学习 UART 通信的原理及其硬件电路设计,并使用 FPGA 来实现 UART 通信中的数据发送和接收部分设计。在仿真验证时除进行正常的功能仿真以外,还将在 Vivado 中使用
Virtual Input/Output(VIO)工具进行板级验证,具体方法是:通过 VIO 输入需要通过串口发送出去的数据,并且控制 FPGA 将待发送的数据发送出去,并在串口助手中查看 PC 端接收到的数据。
提示:以下是本篇文章正文内容,下面案例可供参考
一、uart串口协议(串口发送)
此部分将介绍uart串口协议(串口发送)的verilog实现和testbench的编写,具体原理参考串口发送述,这里直接展示代码:
1.verilog实现
`timescale 1ns / 1ps
//
// Create Date: 2023/09/01 15:30:48
// Design Name:
// Module Name: uart_tx
// Tool Versions:Vivado 2018.3
//Name : 小王在努力...
// Revision 0.01 - File Created
// Additional Comments:
//
//
module uart_tx(
input clk,
input reset_n,
input send_go,
input [7:0] input_data,
input [1:0]Band,
output reg send_en,
output reg tx_data,
output reg tx_done
);
reg [15:0]Band_set;
reg [7:0]input_data_1,input_data_2;
reg [16:0] Band_cnt;
reg [3:0] Band_num;
//选择波特率
always @ (posedge clk or negedge reset_n)
if(!reset_n)
Band_set <= 16'd433;
else begin
case(Band)
0:Band_set <= 16'd5270;
1:Band_set <= 16'd433;
default:Band_set <= 16'd5270;
endcase
end
//数据寄存防止亚稳态
always @ (posedge clk or negedge reset_n)
if(!reset_n)
begin
input_data_1 <= 0;
input_data_2 <= 0;
end
else
begin
input_data_2 <= input_data;
input_data_1 <= input_data_2;
end
//产生起始信号
always @ (posedge clk or negedge reset_n)
if(!reset_n)
send_en <= 0;
else if(send_go)
send_en <= 1;
else if(Band_num == 10)
send_en <= 0;
else
send_en <= send_en;
//计数波特率
always @ (posedge clk or negedge reset_n)
if(!reset_n)
Band_cnt <= 0;
else if(send_en)
begin
if(Band_cnt >= Band_set)
Band_cnt <= 0;
else
Band_cnt <= Band_cnt + 1;
end
else
Band_cnt <= 0;
always @ (posedge clk or negedge reset_n)
if(!reset_n)
Band_num <= 0;
else if(send_en)
begin
if (Band_num == 10)
Band_num <= 0;
else if(Band_cnt == Band_set)
Band_num <= Band_num + 1;
else
Band_num <= Band_num;
end
else
Band_num <= 0;
//产生输出结果
always @ (posedge clk or negedge reset_n)
if(!reset_n)
tx_data <= 1;
else if(send_en)
begin
case(Band_num)
0:tx_data <= 0;
1:tx_data <= input_data_1[0];
2:tx_data <= input_data_1[1];
3:tx_data <= input_data_1[2];
4:tx_data <= input_data_1[3];
5:tx_data <= input_data_1[4];
6:tx_data <= input_data_1[5];
7:tx_data <= input_data_1[6];
8:tx_data <= input_data_1[7];
9:tx_data <= 1;
10:tx_data <= 1;
default: