Verilog(1)UART串口通信

这篇具有很好参考价值的文章主要介绍了Verilog(1)UART串口通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Verilog(1)UART串口通信

第一部分为uart串口通信的接收部分,用pc端虚拟串口来对其发送数据。

第三部分为uart串口通信的发送部分,用此部分对pc端虚拟串口发送数据。

第二部分loop,处理数据,形成回环,使发送部分有数据来源,以此来保证实验的完成。

Verilog(1)UART串口通信

串口接收: 

输入: sys_clk、sys_rst_n、uart_rxd(数据)。

输出: uart_data(数据)、uart_done(状态标志)。

reg:   rx_data(寄存数据)、rx_cnt(帧计数)、clk_cnt(clk计数)、uart_rxd_d0\d1(抓取边沿)、rx_flag。

wire:start_flag。

串口发送

输入: sys_clk、sys_rst_n、uart_din、uart_en(使能)。

输出: uart_txd(数据)、uart_tx_busy(状态标志)。

reg:      tx_data(寄存数据)、tx_cnt(帧计数)、clk_cnt(clk计数)、uart_en_d0\d1(抓取边沿)、tx_flag。

wire:  en_flag。

loop

输入: sys_clk、sys_rst_n、recv_done(接收端状态)、recv_data(数据)、tx_busy(发送端状态)。

输出: send_en(发送使能)、send_data(数据)。

reg:   tx_ready(准备阶段为1,使能为0,此时使recv_data等于send_data)、uart_done_d0\d1(抓取边沿)。

wire: recv_done_flag。

(1)约定波特率,clk频率除以波特率为一帧所包含的时钟个数。

parameter  CLK_FREQ=50000000;    
parameter  UART_BPS=115200;
localparam BPS_cnt=CLK_FREQ/UART_BPS;  

(2)抓取边沿。

assign start_flag=~uart_rxd_d0 & uart_rxd_d1;
always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)begin
        uart_rxd_d0<=1'b0;
        uart_rxd_d1<=1'b0;
    end
    else begin
        uart_rxd_d0<=uart_rxd;
        uart_rxd_d1<=uart_rxd_d0;
    end
end

(3)计数。

always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)            
        clk_cnt<=9'b0;
    else if(rx_flag)begin
        if(clk_cnt<BPS_cnt-1)
            clk_cnt<=clk_cnt+1'b1;
    else
        clk_cnt<=9'b0;
    end
    else
        clk_cnt<=9'b0;
end
always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)  
        rx_cnt<=4'd0;
    else if(rx_flag)begin
        if(clk_cnt==BPS_cnt-1)
            rx_cnt<=rx_cnt+1'b1;
        else
            rx_cnt<=rx_cnt;
    end
    else 
            rx_cnt<=4'd0;
end

(4)串转并。

always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        rx_data<=8'd0;
    else if(rx_flag)
        if(clk_cnt==BPS_cnt/2)begin
            case(rx_cnt)
                4'd1:rx_data[0]<=uart_rxd_d1;
                4'd2:rx_data[1]<=uart_rxd_d1;
                4'd3:rx_data[2]<=uart_rxd_d1;
                4'd4:rx_data[3]<=uart_rxd_d1;
                4'd5:rx_data[4]<=uart_rxd_d1;
                4'd6:rx_data[5]<=uart_rxd_d1;
                4'd7:rx_data[6]<=uart_rxd_d1;
                4'd8:rx_data[7]<=uart_rxd_d1;
                default:;
             endcase
        end
        else
            rx_data<=rx_data;
     else
        rx_data<=8'd0;
end

uart_rxd使用延迟两个时钟的d1,更稳定,防止亚稳态。

(5)并转串。

always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)  
        uart_txd<=1'b1;
    else if(tx_flag)
        case(tx_cnt)
            4'd0:uart_txd<=1'b0;
            4'd1:uart_txd<=tx_data[0];
            4'd2:uart_txd<=tx_data[1];
            4'd3:uart_txd<=tx_data[2];
            4'd4:uart_txd<=tx_data[3];
            4'd5:uart_txd<=tx_data[4];
            4'd6:uart_txd<=tx_data[5];
            4'd7:uart_txd<=tx_data[6];
            4'd8:uart_txd<=tx_data[7];
            4'd9:uart_txd<=1'b1;
            default:;
        endcase
    else
            uart_txd<=1'b1;
end

(6)loop。文章来源地址https://www.toymoban.com/news/detail-436708.html

`timescale 1ns / 1ps
module uart_loop(
    input            sys_clk,
    input            sys_rst_n,
    
    input            recv_done,
    input      [7:0] recv_data,
    
    input            tx_busy,
    output  reg      send_en,
    output  reg[7:0] send_data
    );
reg  recv_done_d0;
reg  recv_done_d1;
reg  tx_ready;
wire recv_done_flag;   
   
assign en_flag= recv_done_d0& ~recv_done_d1;

always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)begin
        recv_done_d0<=1'b0;
        recv_done_d1<=1'b0;
    end
    else begin
        recv_done_d0<=recv_done;
        recv_done_d1<=recv_done_d0;
    end
end

always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)begin
        send_en<=1'b0;
        send_data<=8'd0;
        tx_ready<=1'b0;
    end
    else begin
        if(recv_done_flag)begin
            tx_ready<=1'b1;
            send_en<=1'b0;
            send_data<=recv_data;
            end
        else if((~tx_busy)&&tx_ready)begin
            tx_ready<=1'b0;
            send_en<=1'b1;
            end
     end
end
endmodule

到了这里,关于Verilog(1)UART串口通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 第一部分:Spark基础篇

    第一部分:Spark基础篇_奔跑者-辉的博客-CSDN博客 第二部分:Spark进阶篇_奔跑者-辉的博客-CSDN博客 第三部分:Spark调优篇_奔跑者-辉的博客-CSDN博客 第一部分:Flink基础篇_奔跑者-辉的博客-CSDN博客 (*建议收藏*) 实时数仓之 Kappa 架构与 Lambda 架构_奔跑者-辉的博客-CSDN博客(*建议收

    2024年02月05日
    浏览(49)
  • 第一部分-基础篇-第一章:PSTN与VOIP(下篇)

      学习资料来源《FreeSWITCH权威指南》-作者杜金房这本书。我是2022年6月毕业的,偶然的机会接触到FreeSWITCH,但是目前在南京从事java后端开发,FreeSWITCH纯属个人爱好,进行笔记整理。也一直希望有机会可以参与FreeSWITCH相关工作开发,如有需要,请联系我18956043585,先说声谢

    2024年02月06日
    浏览(57)
  • HTML学习 第一部分(前端学习)

    参考学习网站: 网页简介 (w3schools.com) 我的学习思路是:网站+实践+视频。 视频很重要的,因为它会给你一种开阔思路的方式。你会想,噢!原来还可以这样。这是书本或者网站教程 所不能教给你的。而且,对一些教程,它的用法你可能 在工作或者以后都用不上,这种情况下

    2024年02月15日
    浏览(51)
  • Mysql入门基础教程(第一部分)

    MySQL基础教程解释了一些基本的SQL语句。如果这是您第一次使用关系数据库管理系统,本教程将为您提供使用MySQL数据库服务器所需的一切,例如查询数据,更新数据,管理数据库和创建表。 如果您已经熟悉其他关系数据库管理系统(如PostgreSQL,Oracle或Microsoft SQL Server等),

    2024年04月14日
    浏览(40)
  • 51单片机UART串口通信实现接收PC的字符串

            基本思路是触发串口接收中断之后,在串口中断服务函数中处理接收到的字节并将其连接成字符串存入全局变量中。 隐含的额外工作有: 1.区分是发送中断还是接收中断,两者都会进入同一个中断服务子函数; 2.判断已接收到了句末,暂停接收,并通过标志位告知

    2023年04月20日
    浏览(96)
  • 串口通信实现-串口接收(vivado&verilog版)

    串口系列知识分享: (1)串口通信实现-串口发送 (2)串口通信发送多字节数据 (3)串口通信实现-串口接收 (4)UART 通信-使用VIO进行板级验证 (5)串口接收-控制LED闪烁 (6)使用串口发送实现ACX720开发板时钟显示 (7)串口发送+RAM+VGA传图 此文介绍uart串口协议(串口接

    2024年02月12日
    浏览(36)
  • 学成在线项目开发技巧整理---第一部分

    视频项目链接: 学成在线 整理的是我个人认为偏生疏的知识点,不一定涉及的全面。 在系统中某些选项是几个特定的值的一个或多个,并且随着还可以动态添加。比如支付方式,配送方式等。 此时我们应该设计一个数据字典模块,在后台进行管理,然后前台要从后端查询。并

    2023年04月22日
    浏览(60)
  • 字符串---第一部分 序列、字串;上升,公共

    第一部分 最长上升子序列,最长上升子串,最长公共子序列,最长公共子串--dp 第二部分 KMP,trie,双指针 第三部分 待定 动态规划:审题,状态确定,状态转移,边界条件 线性DP 最长上升子序列 403 线性DP 最长上升子序列【动态规划】_哔哩哔哩_bilibili 给定一个无序整数数组

    2024年02月07日
    浏览(50)
  • 阿里服务器怎么用教程[第一部分]

    第一步,登录我们的阿里云账号。   第二步,根据自己的具体情况,选择好服务器的配置,比如你是大型企业,预估网站访问量很大,那么就要选配置较好的服务器,如果是个人网站,预估流量较小,就可以选择配置较低的云服务器。   第三步,购买好云服务器后,我们在

    2024年02月10日
    浏览(49)
  • 【OpenCV入门】第一部分——图像处理基础

    图像处理包括4个基本操作: 读取图像 、 显示图像 、 保存图像 和 获取图像属性 。 imread() filename :目标图像的完整路径名。 flags :图像的颜色类型的标记,有0和1两个值,其中1为默认值。当读取一幅彩色图像时,如果想要得到一幅 彩色图像 ,那么flags的值为1(此时flags的

    2024年02月11日
    浏览(47)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包