通信协议:Uart的Verilog实现(上)

1、前言

        调制解调器是主机/设备与串行数据通路之间的接口,以串行单比特格式发送和接收数据。它也被称为通用异步收发器(Uart, Universal Asynchronous Receiver/Transmitter),这表明该设备能够接收和发送数据,并且发送和接收单元不同步。

        本节中,UART以ASCII码的格式交换文本数据,在ASCII码格式中,每一帧包含1位起始位,5-8位数据位,1位可选的奇偶校验位和1位停止位。在本文的实现中,使用了了7位数据,因此数据格式如下所示。发送时从起始位(低位)开始,向高位逐位发送,每个位持续一个时钟周期(比特位时间),停止位的有效时间则可能会超过一个时钟周期,即两帧之间的间隔可以是多个时钟周期。

停止位校验位数据位6数据位5数据位4数据位3数据位2数据位1数据位0起始位

Uart传送的ASCII文本数据格式

2、UART的操作

        UART发送器通常是更大系统的一部分,其主机以并行格式取出数据并指定UART以串行格式发送。UART接收器需检测传输情况,以串行格式接收数据,去掉起始位和停止位后以并行格式存储数据。因为远程接收器无法得到数据发送时钟——数据异步到达,接收器会比发送器更复杂。接收器必须重新产生本地时钟而不是用发送时钟来同步数据采样。

        UART的简化结构如下图所示,图中给出了主机用于控制UART以及从数据总线接收或发送数据的信号,但没有给出主机的细节。

3、UART发送器

        下面的框图给出了发送器的输入/输出信号。输入信号由主机提供,包括(Load_XMT_datareg, Byte_ready, T_byte, Data_Bus)而输出信号包括串行数据流(Serial_out)。发送器由控制单元和数据通路构成,控制单元是一个FSM,用于给出控制信号给数据通路;而数据通路包含数据寄存器(XMT_datareg)、数据移位寄存器(XMT_shftreg)和用于计数已发送比特数的状态寄存器(bit_count)。状态寄存器包含在数据通路中。

        发送器的内部信号如下所列。注意,信号Load_XMT_datareg本可以直接送至数据通路,但这里将其送入控制器并在idle状态下根据该信号对Load_XMT_DR进行条件赋值。

        控制单元的输入信号及其作用:

        Load_XMT_datareg:idle状态下由其决定Load_XMT_DR信号的值(用于控制将Data_Bus的内容载入XMT_data_reg)。

        Byte_ready:由其决定Load_XMT_shftreg信号的值(用于控制将XMT_data_reg中的内容载入XMT_shftreg)。

        T_byte:用于决定一帧数据传输的开始(将串行输出拉低)。

        BC_lt_BCmax:用于指示数据移位还未完成(即Bit_count < word_size + 1)。

        控制单元的输出信号及其作用:

        Load_XMT_DR:控制Data_Bus的内容载入XMT_data_reg。

        Load_XMT_shftreg:控制将XMT_data_reg中的内容载入XMT_shftreg。

        Start:控制将XMT_shftreg[0]清零表示输出起始位,传输开始。

        Shift:控制将XMT_shftreg右移一位,并在高位补1(停止位)。

        Clear:控制将bit_count清零。

        发送器控制器的状态机ASMD图如下图所示。该状态机包括idle、waiting和sending三个状态。当低有效的同步复位信号rst_b有效时,状态机进入idle状态,同时bit_count被清零,XMT_shftreg被1填充。在idle状态下,主机在令Load_XMT_datareg有效后,控制器输出信号Load_XMT_DR将Data_bus上的内容载入XMT_data_reg。状态机保持idle状态直到主机使Load_XMT_datareg无效并使Byte_ready信号有效,这时会输出Load_XMT_shftreg并进入waiting状态。Load_XMT_shftreg会控制XMT_datareg中的内容载入XMT_shftreg的最左边的比特位,同时令LSB为1(停止位)。

        T_byte有效后输出start信号,下个时钟沿,状态机进入sending状态,同时XMT_shftreg的LSB清零。此时只要计数值未满,sending状态下会一直输出shift信号,这使得XMT_shftreg的数据右移并高位补1。当计数满时(BC_lt_BCmax==0)时,clear信号有效,表示所有有效数字已输出,此时正在输出最后一位停止位,在下一个时钟沿状态机返回idle状态。

        下面给出UART_XMTR的Verilog HDL描述:

module UART_XMTR #(parameter word_size = 8)(output Serial_out,     //Serial output ti data channelinput [word_size - 1 : 0] Data_Bus, //Host data bus containing data wordinput Load_XMT_datareg,             //Used by host to load the data registerByte_ready,                   //Used by host to signal readyT_byte,                  //Used by host to signal start of transmissionClock,                   //Bit clock of the transmitterrst_b                    //Resets internal registers, loads the             //XMT_shftreg with ones 
);wire BC_lt_BCmax;
wire Load_XMT_DR;
wire Load_XMT_shftreg;
wire start;
wire shift;
wire clear;Controller_Unit M0(Load_XMT_DR, Load_XMT_shftreg, start, shift, clear, Load_XMT_datareg,Byte_ready, T_byte, BC_lt_BCmax, Clock, rst_b);Datapath_Unit M1(Serial_out, BC_lt_BCmax, Data_bus, Load_XMT_DR, Load_XMT_shftreg,start, shift, clear, Clock, rst_b);endmodulemodule Control_Unit #(parameter one_hot_count = 3,  //Numbers of one-hot statesstate_count = one_hot_count, //Number of bits in state registersize_bit_count = 3 //Size of the bit counte
)(output reg Load_XMT_DR,  //Loads Data_Bus into XMT_dataregLoad_XMT_shftreg, //Loads XMT_datareg into XMT_shftregstart,        //Launches shifting of bits in XMT_shftregshift,        //Shift bits in XMT_shftregclear,        //Clears bit_count after last bit is sentinput Load_XMT_datareg,  //Asserts Load_XMT_DR in state idleByte_ready,        //Asserts Load_XMT_shftreg in state idleT_byte,            //Asserts start signal in state waitingBC_lt_BCmax,       //Indicates status of bit counter Clock,rst_b
);localparam idle = 3'b001,waiting = 3'b010,sending = 3'b100,all_ones = 9'b1_1111_1111;reg [state_count - 1 : 0] 	state, next_state;  // State machine controlleralways@(*)beginLoad_XMT_DR = 0;Load_XMT_shftreg = 0;start = 0;clear = 0;shift = 0;next_state = idle;case(state)idle: if(Load_XMT_datareg == 1'b1)beginLoad_XMT_DR = 1;next_state = idle;endelse if(Byte_ready == 1'b1)beginLoad_XMT_shftreg = 1;next_state = waiting;endwaiting: if(T_byte == 1)beginstart = 1;next_state = sending;endelse next_state = waiting;sending: if(BC_lt_BCmax == 1)beginshift = 1;next_state = sending;endelse beginclear = 1;next_state = idle;enddefault: next_state = idle;endcaseendalways@(posedge Clock, negedge rst_b)beginif(rst_b == 0) state <= idle;elsestate <= next_state;end
endmodulemodule Datapath_Unit #(parameter word_size = 8,size_bit_count = 3
)(output Serial_out,BC_lt_BCmax,input [word_size - 1 : 0] Data_bus,input Load_XMT_DR,Load_XMT_shftreg,start,shift,clear,Clock,rst_b
);localparam all_ones = 9'b1_1111_1111;reg [word_size - 1 : 0] XMT_datareg; //Transmit Data Registerreg [word_size : 0] XMT_shftreg;     //Transmit Shift Registerreg [size_bit_count : 0] bit_count;  //Counts the bits that are transmittedassign Serial_out = XMT_shftreg[0];assign BC_lt_BCmax = (bit_count < word_size + 1);always@(posedge Clock, negedge rst_b)if(rst_b == 0)beginXMT_shftreg <= all_ones;bit_count <= 0;endelse beginif(Load_XMT_DR == 1)XMT_datareg <= Data_bus;  //Get the data busif(Load_XMT_shftreg == 1)XMT_shftreg <= {XMT_datareg, 1'b1};//Load shift reg, insert stop             //bitif(start == 1)XMT_shftreg[0] <= 0;      //Signal start of transmissionif(clear == 1)bit_count <= 0;if(shift == 1)beginXMT_shftreg <= {1'b1, XMT_shftreg[word_size : 1]};//Shift right, //fill with onesbit_count <= bit_count + 1;endend
endmodule

以上内容来源于《Verilog HDL高级数字设计》,有删改

        

        

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

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

相关文章

【re】BUUCTF Java逆向解密

题目&#xff1a;BUUCTF Java逆向解密 没壳&#xff0c;是java文件&#xff08;大概&#xff09; ida打开看不懂&#xff0c;找了网页上的java反编译 Decompiler.com 没用过java啊…暂且用sublime打开 还好还挺好懂的 import java.util.ArrayList; import java.util.Scanner;p…

【Spring MVC】Spring MVC如何处理跨域请求(CORS)

文章目录 1. Spring MVC如何处理跨域请求呢2. Spring MVC处理CORS的几个组件2.1. CorsFilter2.2. CrossOrigin 前言&#xff1a;请了解什么是CORS&#xff08;跨域&#xff09; 参考&#xff1a;https://gitee.com/firefish985/article-list/tree/master/Spring/Spring Web MVC…

Java开发需要的网络基础知识,搞清楚计算机网络底层原理

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有需要我的支持&#xff0c;请私信或评论留言&#xff01; 前言 计算机基础是…

手机基带芯片往事

手机基带芯片往事 手机基带芯片往事-虎嗅网 5G手机芯片简史-虎嗅网

Oracle拉链表

目录 -- 准备一个拉链表 -- 2.将所有的数据 同步到拉链表中 TEST_TARGET中 --3. 源表的数据发生了变化 --4. 将新增和修改的数据同步到拉链表 -- 开链的过程 -- 判断源表和目标表的数据,不同数据插入 --5. 修改拉链表中失效的时间和状态(将原本的开链时间,改为当前时间)-- …

怎样提高外贸业务销售能力

怎样提高外贸业务销售能力 一、市场分析与研究1. 了解目标市场&#xff1a;2. 收集客户信息&#xff1a; 二、产品知识和差异化竞争1. 熟悉产品&#xff1a;2. 差异化竞争&#xff1a; 三、制定销售策略和计划1. 制定销售计划&#xff1a;2. 销售策略&#xff1a; 四、谈判技巧…

【插件】页面引导库driver.js:

文章目录 一、效果图:二、实现思路:三、实现代码:【1】Driver.js 的技术特性【2】安装依赖【3】代码实现【4】 配置相关参数 一、效果图: 二、实现思路: 【官网】https://driverjs.com/docs/installation 【npm】https://www.npmjs.com/package/driver.js 【案例】改造driver.j…

HAProxy Data Plane API 实现对 haproxy 的配置管理

文章目录 前言一、安装1. 下载HAProxy Data Plane API2. 创建 Data Plane API 配置文件 /etc/haproxy/dataplaneapi.hcl3. 修改haproxy的配置文件 二、简单使用1. 查询请求2. 提交修改请求 总结 前言 我们平时对 haproxy 配置的修改&#xff0c;往往是 SSH 连接进去节点&#…

C++之std::function类模板定义函数对象应用总结(二百三十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

C#流Stream与IO详解(4)——如何更快的读写文件

【前言】 在我们追求更快读写速度时&#xff0c;通常都是为了读写二进制文件&#xff0c;而不是文本文件&#xff0c;所以这里只说FileStream、BinaryReader、BinaryWriter的使用。 从前文的源码解读中能看到使用BinaryReader和BinaryWriter进行IO读写时本质还是调用了FileSt…

如何使用canvas实现一个下雪的动效

下面是一个使用Canvas实现下雪动效的代码示例&#xff1a; <!DOCTYPE html> <html> <head><title>下雪特效</title><style>body {margin: 0;padding: 0;}canvas {display: block;background: black;}</style> </head> <bo…

.NET的键盘Hook管理类,用于禁用键盘输入和切换

一、MyHook帮助类 此类需要编写指定屏蔽的按键&#xff0c;灵活性差。 using System; using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; using Microsoft.Win32;namespace MyHookClass {/// <summary>/// 类一/// </su…

一文详解JDK8常用10个更新特性

今日一语&#xff1a;当你发现编程的规律就是世界的规律时&#xff0c;你就是一名真正的程序员 1 Lambda(蓝布达)表达式 编译后会产生一个$XXXImpl1的编译文件&#xff0c;与匿名内部类相似&#xff0c;但不等同于匿名内部类。 其原理是将方法作为参数进行传递&#xff0c; JV…

【深入浅出设计模式--命令模式】

深入浅出设计模式--命令模式 一、背景二、问题三、解决方案四、试用场景总结五、后记 一、背景 命令模式是一种行为设计模式&#xff0c;它可以将用户的命令请求转化为一个包含有相关参数信息的对象&#xff0c;命令的发送者不需要知道接收者是如何处理这条命令&#xff0c;多个…

php文件上传功能(文件上传)

实现文件上传是Web开发中常用的功能之一&#xff0c;而PHP也是支持文件上传的。那么&#xff0c;下面我们就来介绍一下常用的PHP实现文件上传的方法。 使用HTML表单实现文件上传 HTML表单是Web开发中最基本的元素之一&#xff0c;它可以接收用户输入的数据&#xff0c;并通过…

Python 笔记03(多线程)

一 打开命令行&#xff0c;查看本机IP windows r 命令行输入&#xff1a;cmd ipconfig 然后查看IPv4的地址&#xff1a;192.168.1*6.1 ipconfig 二 函数式多进程 from multiprocessing import Process import os, timedef func(name):print(进程的ID&#xff1a;, os.g…

大数据时代,数据治理

一、大数据时代还需要数据治理吗&#xff1f; 数据平台发展过程中随处可见的数据问题 大数据不是凭空而来&#xff0c;1981年第一个数据仓库诞生&#xff0c;到现在已经有了近40年的历史&#xff0c;相对数据仓库来说我还是个年轻人。而国内企业数据平台的建设大概从90年代末…

Docker 自动化部署(保姆级教程)

Docker 自动化部署 1. jenkins 介绍1.1 参考链接&#xff1a;1.2 jenkins 概述1.3 jenkins部署项目的流程 2. jenkins 安装2.1 基于docker 镜像2.2 启动 jenkins 后端服务2.3 登录 jenkins 服务后端 3. jenkins自动化部署开始3.1 下载需要的插件3.2 创建任务3.2.1 描述3.2.2 配…

使用bash脚本编译Qt工程

最近在搭建Qt工程的编译服务器&#xff0c;需要通过shell脚本执行工程的编译过程&#xff0c;写在这里&#xff0c;总结最近的工作。 1. 构建过程 以Windows为例&#xff0c;在QtCreator中左侧选择“项目”便可以看到编译的指令和参数&#xff0c;这些操作也会在我们点击“构建…

git管理常用命令

1、下载代码 git clone 地址2、软件代码提交 1、查看工程中被修改的文件&#xff1a;git status 2.将不需要提交的文件回退&#xff1a;git check <文件路径> 3.更新工程到最新&#xff1a;git pull 4.将本地代码添加到暂存区&#xff1a;git add <将要提交的文件路…