ZYNQ_project:uart(odd,even)

news2025/1/11 22:38:40

概念:

UART(Universal Asynchronous Receiver-Transmitter):即通用异步收发器,是一种通用串行数据总线,用于异步通信。一般UART接口常指串口。

UART在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。

单工通信:数据只能沿一个方向传输。

半双工通信:数据可以沿两个方向传输,但需要分时进行。

全双工通信:数据可以同时进行双向传输。

同步通信:带时钟端口的数据传输。

异步通信:没有时钟端口,发送方和接收方使用各自的时钟控制数据的收发过程。

常见串行通信接口:

 模块框图:

时序图:

 

代码:

// uart的接收模块,要求波特率可调,回环实验
// 完成回环实验后加入校验位
// 然后加入led与蜂鸣器的控制模块
`include         "para.v"
module rx (
    input       wire                sys_clk     ,
    input       wire                sys_rst_n   ,
    input       wire                rx          ,

    output      reg     [7:0]       po_data     , // port_output
    output      reg                 po_flag     
);
    // parameter
    parameter   MAX_BPS_CNT = `CLOCK/`BPS   ,//434 ,
                MAX_BIT_CNT = `BIT_CHACK    ;//10   ; 
    localparam  RX_MOD      = 1'b1          ,
                CHECK_MOD   = `EVEN         ;
    // reg signal define
    reg                 rx_r1    ;
    reg                 rx_r2    ;
    reg     [31:0]      cnt_bps  ;
    reg                 work     ;
    reg     [3:0]       cnt_bit  ;
    reg     [7:0]       data_reg ;
    reg                 check    ;
    reg                 check_reg;
    // wire signal define
    wire                nege    ;
    /*******************************************************************/
    // // reg signal define
    // reg                 rx_r1   ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            rx_r1 <= 1'b1 ;
        else
            rx_r1 <= rx ;
    end
    // reg                 rx_r2   ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            rx_r2 <= 1'b1 ;
        else
            rx_r2 <= rx_r1 ;
    end
    // reg                 work    ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            work <= 1'b0 ;
        else if(nege)
            work <= 1'b1 ;
        else if((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1))) // 这俩条件可以用end_cnt_XXX来代替,组合逻辑赋
            work <= 1'b0 ;
        else 
            work <= work ;
    end
    // reg     [31:0]      cnt_bps ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_bps <= 32'd0 ;
        else if(work && (cnt_bps == (MAX_BPS_CNT - 1)))
            cnt_bps <= 32'd0 ;
        else if(work)
            cnt_bps <= cnt_bps + 1'b1 ;
        else 
            cnt_bps <= 32'd0 ;
    end
    // reg     [3:0]       cnt_bit ; 应该会归0
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_bit <= 4'd0 ;
        else if (work && (cnt_bps == (MAX_BPS_CNT - 1) && cnt_bit == (MAX_BIT_CNT - 1)))
            cnt_bit <= 4'd0 ;
        else if (work && (cnt_bps == (MAX_BPS_CNT - 1)))
            cnt_bit <= cnt_bit + 1'b1 ;
        else if(work)
            cnt_bit <= cnt_bit ;
        else 
            cnt_bit <= 8'd0 ;
    end
    // reg     [7:0]       data_reg;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            data_reg <= 8'd0 ;
        else if(work && cnt_bps == (MAX_BPS_CNT/2)) begin // 采样,采集数据的时刻
            case (cnt_bit)
                0 : data_reg <= 8'd0 ;
                1 : data_reg[cnt_bit - 1] <= rx_r2 ;
                2 : data_reg[cnt_bit - 1] <= rx_r2 ;
                3 : data_reg[cnt_bit - 1] <= rx_r2 ;
                4 : data_reg[cnt_bit - 1] <= rx_r2 ;
                5 : data_reg[cnt_bit - 1] <= rx_r2 ;
                6 : data_reg[cnt_bit - 1] <= rx_r2 ;
                7 : data_reg[cnt_bit - 1] <= rx_r2 ;
                8 : data_reg[cnt_bit - 1] <= rx_r2 ;
                default: data_reg <= data_reg ;
            endcase
        end else
            data_reg <= data_reg ;
    end
    // // wire signal define
    // wire                nege    ;
    assign  nege = ~rx_r1 && rx_r2 ;
    // reg                 check    ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            check <= 1'b0 ;
        else if(CHECK_MOD && (cnt_bit == ((MAX_BIT_CNT - 2))) && (cnt_bps == (MAX_BPS_CNT - 1)))
            check <= ~^data_reg ;
        else if(~CHECK_MOD && (cnt_bit == ((MAX_BIT_CNT - 2))) && (cnt_bps == (MAX_BPS_CNT - 1)))
            check <= ^data_reg ;    
        else 
            check <= check ;
    end  
    // reg                 check_reg;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            check_reg <= 1'b0 ;
        else if((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT /2)))
            check_reg <= rx_r2 ;
        else 
            check_reg <= check_reg ;
    end  
    // output      reg     [7:0]       po_data     , // port_output
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            po_data <= 8'd0 ;
        else if((check == check_reg) && (cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1)))
            po_data <= data_reg ;
        else if(RX_MOD)
            po_data <= po_data ;
        else 
            po_data <= 8'd0 ;
    end
    // output      reg                 po_flag   
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            po_flag <= 8'd0 ;
        else if((check == check_reg) && ((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1)))) 
            po_flag <= 1'b1 ;
        else 
            po_flag <= 8'd0 ;
    end  

endmodule
// uart的数据发送模块。停止位 1bit
`include         "para.v"
module  tx(
    input       wire                sys_clk     ,
    input       wire                sys_rst_n   ,
    input       wire    [7:0]       pi_data     ,
    input       wire                pi_flag     ,

    output      reg                 tx         
);
    // parameter
    parameter   MAX_BPS_CNT = `CLOCK/`BPS   ,
                MAX_BIT_CNT = `BIT_CHACK + 1;
    localparam  CHECK_MOD   = `EVEN         ;
    // reg signal define
    reg     [7:0]       data_reg ;
    reg                 work     ;
    reg     [31:0]      cnt_bps  ; 
    reg     [3:0]       cnt_bit  ; 

    /********************************************************************/
    // // reg signal define
    // reg     [7:0]       data_reg ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            data_reg <= 8'd0 ;
        else if(pi_flag)
            data_reg <= pi_data ;
        else 
            data_reg <= data_reg ;
    end
    // reg                 work     ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            work <= 1'b0 ;
        else if(pi_flag)
            work <= 1'b1 ;
        else if(cnt_bps == (MAX_BPS_CNT - 1) && cnt_bit == (MAX_BIT_CNT - 1))
            work <= 1'b0 ;
        else 
            work <= work ;
    end
    // reg     [31:0]      cnt_bps  ; 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_bps <= 32'd0 ;
        else if((work && (cnt_bps == (MAX_BPS_CNT - 1))) 
            || (work && (cnt_bit == (MAX_BIT_CNT - 1)) && cnt_bps == (MAX_BPS_CNT - 1)))
            cnt_bps <= 32'd0 ;
        else if(work)
            cnt_bps <= cnt_bps + 1'b1 ;
        else 
            cnt_bps <= 32'd0 ;
    end
    // reg     [3:0]       cnt_bit  ; 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_bit <= 4'd0 ;
        else if(work && (cnt_bps == (MAX_BPS_CNT - 1)) && cnt_bit == (MAX_BIT_CNT - 1))
            cnt_bit <= 4'd0 ;
        else if(work && (cnt_bps == (MAX_BPS_CNT - 1)))
            cnt_bit <= cnt_bit + 1'b1 ;
        else if(work)
            cnt_bit <= cnt_bit ;
        else 
            cnt_bit <= 4'd0 ;
    end
    // output      reg                 tx          
    always @(*) begin
        if(~sys_rst_n)
            tx = 1'b1 ;
        else if(work) begin
            case (cnt_bit)
            4'd0:   tx = 1'b0 ; 
            4'd1:   tx = data_reg[cnt_bit - 1] ; 
            4'd2:   tx = data_reg[cnt_bit - 1] ; 
            4'd3:   tx = data_reg[cnt_bit - 1] ; 
            4'd4:   tx = data_reg[cnt_bit - 1] ; 
            4'd5:   tx = data_reg[cnt_bit - 1] ; 
            4'd6:   tx = data_reg[cnt_bit - 1] ; 
            4'd7:   tx = data_reg[cnt_bit - 1] ; 
            4'd8:   tx = data_reg[cnt_bit - 1] ; 
            4'd9:   begin 
                    if(CHECK_MOD)
                        tx = ~^data_reg ;
                    else 
                        tx = ^data_reg ;
                    end
            default: tx = 1'b1 ;
            endcase
        end else 
            tx = 1'b1 ;
    end
endmodule

 

module  top(
    input       wire                sys_clk     ,
    input       wire                sys_rst_n   ,
    input       wire                rx          ,

    output      wire                tx          
);
    // 例化间连线 Wiring between instantiations
    wire                clk_100Mhz  ;
    wire                clk_50Mhz   ;
    wire                locked      ; 
    wire                rst_n       ; 
    assign              rst_n   = sys_rst_n && locked ;
    wire    [7:0]       po_data     ;
    wire                po_flag     ;
pll pll_inst(
  .clk_in1          ( sys_clk       ) ,
  .resetn           ( sys_rst_n     ) ,

  .clk_out1         ( clk_100Mhz    ) ,
  .clk_out2         ( clk_50Mhz     ) ,
  .locked           ( locked        ) 
 );

rx rx_inst(
    .sys_clk        ( clk_50Mhz     ) ,
    .sys_rst_n      ( rst_n         ) ,
    .rx             ( rx            ) ,

    .po_data        ( po_data       ) ,
    .po_flag        ( po_flag       )  
);

tx tx_inst(
    .sys_clk        ( clk_50Mhz     ) ,
    .sys_rst_n      ( rst_n         ) ,
    .pi_data        ( po_data       ) ,
    .pi_flag        ( po_flag       ) ,

    .tx             ( tx            )
);
endmodule

 

仿真:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1220672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构(二)】稀疏 sparsearray 数组(1)

文章目录 1. 稀疏数组的应用场景1.1. 一个实际的需求1.2. 基本介绍 2. 稀疏数组转换的思路分析3. 稀疏数组的代码实现3.1. 二维数组转稀疏数组3.2. 稀疏数组转二维数组 4. 课后练习 1. 稀疏数组的应用场景 1.1. 一个实际的需求 问题&#xff1a;     编写的五子棋程序中&…

JavaEE初阶 01 计算机是如何工作的

前言 今天开始进行对JavaEE的一些基本总结,希望大家能在阅读中有所收获,如有错误还望多多指正. 1.冯诺依曼体系结构 这个体系结构相信学计算机的同学都不陌生,但是你真的知道这个体系结构说的是什么嘛?请听我娓娓道来.首先我先给出一张冯诺依曼体系结构的简图 你可以理解为当前…

资深品酒师荆芳老师倾情力作,带你品酒选酒,读懂葡萄酒的世界

在美酒琳琅满目的今天&#xff0c;如何才能挑选到适合自己的葡萄酒&#xff1f;如何品鉴葡萄酒的独特魅力&#xff1f;资深品酒师荆芳老师的最新力作《葡萄酒爱好者》正式上线&#xff0c;带你走进葡萄酒的世界&#xff0c;领略品酒选酒的奥秘。作为一位资深的品酒师和教育工作…

leetcode - 串联所有单词的子串 - 最小覆盖子串 - x 的平方根

I30. 串联所有单词的子串 - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words ["ab&qu…

卡方检验-python代码

故事背景 问题 卡方检验的结果怎么计算&#xff1f; 方法 python代码 import numpy as np from scipy.stats import chi2_contingency# 观察频数矩阵 observed np.array([[47, 21, 17],[63, 29, 15],[11, 2, 4]])# 进行卡方检验 chi2, p, dof, expected chi2_contingency(o…

电子器件系列44:环形线圈电感

干货&#xff01;电感最重要、最常见的几个作用_线圈 环形线圈电感的原理&#xff1a; 电感中包含了哪三个物理学定律&#xff0c;为什么它能以磁场形式储能_哔哩哔哩_bilibili 电感的基本原理_哔哩哔哩_bilibili 环形线圈电感的作用: 1.储能器&#xff1a; 环形线圈电感能够…

Neo4j安装(Docker中安装Neo4j)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

【漏洞复现】用友U8-Cloud 存在任意文件上传漏洞

漏洞描述 U8 cloud 聚焦成长型、创新型企业的云 ERP,基于全新的企业互联网应用设计理念,为企业提供集人财物客、产供销于一体的云 ERP 整体解决方案,全面支持多组织业务协同、智能财务,人力服务、构建产业链智造平台,融合用友云服务实现企业互联网资源连接、共享、协同。…

Windows 安装 汉化版 burp suite

注&#xff1a;个人笔记&#xff0c;仅供参考。 burpsuite 软件下载链接&#xff1a; https://www.alipan.com/s/cWxMF5S9sq4 提取码: 31ut 注&#xff1a;安装路径不要有中文 安装 配置 Java 环境 因为burpsuite是在JAVA环境下运行的&#xff0c;所以首先应该配置好JAVA环…

浙大恩特客户资源管理系统 SQL注入漏洞复现

0x01 产品简介 浙大恩特客户资源管理系统是一款针对企业客户资源管理的软件产品。该系统旨在帮助企业高效地管理和利用客户资源&#xff0c;提升销售和市场营销的效果。 0x02 漏洞概述 浙大恩特客户资源管理系统中T0140_editAction.entweb接口处存在SQL注入漏洞&#xff0c;未…

解决Error:java: System Java Compiler was not found in classpath

解决Error:java: System Java Compiler was not found in classpath 一、配置maven 注意:我的C盘比较大直接配置在了C盘&#xff0c;建议配置到其他盘&#xff0c;记得做maven环境变量配置 二、卸载本地JDK&#xff0c;换个版本安装配置环境变量 重启电脑或idea&#xff0c;…

React经典初级错误

文章 前言错误场景问题分析解决方案后言 前言 ✨✨ 他们是天生勇敢的开发者&#xff0c;我们创造bug&#xff0c;传播bug&#xff0c;毫不留情地消灭bug&#xff0c;在这个过程中我们创造了很多bug以供娱乐。 前端bug这里是博主总结的一些前端的bug以及解决方案&#xff0c;感兴…

Linux环境下C++ 接入OpenSSL

接上一篇&#xff1a;Windows环境下C 安装OpenSSL库 源码编译及使用&#xff08;VS2019&#xff09;_vs2019安装openssl_肥宝Fable的博客-CSDN博客 解决完本地windows环境&#xff0c;想赶紧在外网环境看看是否也正常。毕竟现在只是HelloWorld级别的&#xff0c;等东西多了&am…

如何在latex中高亮文本

导入soul 包可以使用高亮功能 在文本中插入 \hl{} 即可 导入color 包可以使用颜色功能 color 也可以替换成 xcolor \documentclass{report} \usepackage{xcolor,soul} \begin{document}\textcolor{red}{Text}\hl{Text} \hl{\textbf{Text}} \textbf{\textcolor{red}{\hl{Text}…

PyTorch深度学习原理与实现

PyTorch深度学习原理与实现 1. 引言 深度学习发展历程 感知机网络&#xff08;解决线性可分问题&#xff0c;20世纪40年代&#xff09; BP神经网络&#xff08;解决线性不可分问题&#xff0c;20世纪80年代&#xff09; 深度神经网络&#xff08;海量图片分类&#xff0c;2…

Nginx 可视化管理平台:nginx-proxy-manager

本心、输入输出、结果 文章目录 Nginx 可视化管理平台:nginx-proxy-manager前言nginx-proxy-managernginx-proxy-manager 特性快速开始使用 Docker 网络开启 Docker 健康检查相关可视化页面相关链接弘扬爱国精神Nginx 可视化管理平台:nginx-proxy-manager 编辑:简简单单 Onl…

虚拟化热添加技术在数据备份上的应用

虚拟化中的热添加技术主要是指&#xff1a;无需停止或中断虚拟机的情况下&#xff0c;在线添加物理资源&#xff08;如硬盘、内存、CPU、网卡等&#xff09;的技术。热添加技术也是相比物理机一个非常巨大的优势&#xff0c;其使得资源分配变得更加灵活。 虚拟化中的热添加技术…

Unity优化(1)——合并Mesh的两种方法

在某些移动端项目中&#xff0c;对于DrawCall的要求是很严格的&#xff0c;我们一般查看DrawCall可以通过Statistics里面的Batches进行查看&#xff0c;一般对于移动设备的Batches要控制在200左右比较合适&#xff0c;所以降低Batches是很重要的。 我们常常会遇到一个物体下挂载…

【AI视野·今日Sound 声学论文速览 第三十五期】Fri, 27 Oct 2023

AI视野今日CS.Sound 声学论文速览 Fri, 27 Oct 2023 Totally 8 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Controllable Generation of Artificial Speaker Embeddings through Discovery of Principal Directions Authors Florian Lux, Pascal T…

kubernetes集群编排——k8s高可用集群

实验环境 主机名 IP 角色 k8s1 192.168.92.11 harbor k8s2 192.168.92.12 control-plane k8s3 192.168.92.13 control-plane k8s4 192.168.92.14 control-plane k8s5 192.168.92.15 haproxy,pacemaker k8s6 192.168.92.16 haproxy,pacemaker k8s7 192.16…