uart16550IP核的设计与FPGA的实现_第1页
uart16550IP核的设计与FPGA的实现_第2页
uart16550IP核的设计与FPGA的实现_第3页
uart16550IP核的设计与FPGA的实现_第4页
uart16550IP核的设计与FPGA的实现_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

兰州大学本科生毕业论文键入文字uart16550IP核的设计与FPGA的实现 键入文字键入文字兰州大学本科生毕业论文键入文字uart16550IP核的设计与FPGA的实现 uart16550IP核的设计与FPGA的实现串行通信在数字信息系统以及控制系统中得到了广泛的应用。针对传统UART8250和UART16450传输速率低、稳定性相对较差,满足不了PC机通信速率的状况,介绍了高速异步串口UART16550的工作原理与设计实现,并且给出在现场可编程门阵列FPGA上的实现与验证仿真。这项设计对于片上系统之间以及与PC机之间的串行数据传输有了很大程度的改善。关键词:UART16550,串口通信,FIFO,FPGA。 第一章 绪论1.1 引言自第三次科技革命以来计算机技术飞速发展,计算机网络技术和数字通信技术的日益普及。由电子工业协会所制定的异步传输标准接口RS-232(ANSI/EIA-232标准)成为IBM-PC及其兼容机上的串行连接标准。RS-232串行通信接口被内置到许多计算机系统中作为外围设备接口,如鼠标、打印机或者Modem,同时也可以连接工业仪器仪表。基于RS-232串行通讯标准,异步串行通信IP核在连接嵌入式系统和SOC系统中不可或缺。UART是用于实现CPU与串行设备通信的芯片。其将从外部传输来的串行数据去除起始位、停止位和校验位转化为字节使供内部并行器件使用,如处理由键盘或鼠标发出的中断信号。反过来内部待发送的数据通过加入起始位、校验位和停止位并进行串并行转换也可以向外发送数据。通过UART我们可以实现计算机内部与外部串行设备的同步管理问题。常见的UART有INS8250和PC16450,PC16650,PC16750而在这里我们要介绍的16550优势在于它可以在计算机需要处理数据前在其FIFO内存储16字节数据,减少数据发送的次数,从而更有效的利用CPU,从而提高系统的整体性能。随着FPGA技术的迅速发展和广泛应用,我们常需要将FPGA与其他数字系统进行串行通信。专用的UART集成电路如8250、8251等既要考虑异步收发功能又要兼容RS-232C接口等设计过于繁琐。而实际中我们往往只是用UART的一些基本功能,在这里我们通过将所需的UART功能集成到FPGA内部,实现FPGA与其他数字系统的直接通信,从而简化整个系统电路,使系统更为灵活紧凑,性能也更加稳定。本实验基于通用FPGA开发软件quatus ii 9.0实现UART16550的模块化编程和波形仿真。Verilog HDL语言最初是于1983年由Gateway Design Automation公司(后被Cadence收购)为其模拟器产品开发的硬件建模语言,后成为IEEE的标准语言。能形象化地抽象表示电路的行为和结构,支持硬件的设计、验证、综合和测试。在此我们采用Verilog HDL语言来进行设计。1.2历史在计算机出现之前就已经存在早期的串口设备(工控测量设备,电传打字机等),为了连接这些串口EIA制定了RS232标准,采用DB25接插件,支持同步和异步串口。设计的 D型接口有效的防止插反带来的不便。这一标准化带来了许多便利。随着计算机的出现,大型的生产商更倾向于新的体积小、成本低的DB9。DB9是通过去除DB25中未使用的和支持同步模式的引脚得来。但最初情况很混乱,因为DB9只定义了信号却没有定义信号和引脚的关系,制造厂商只能自行定义。随着IBM的计算机成为工业标准,DB9逐渐统一于IBM的定义上。随着计算机的普及,许多非RS232的串口也要接入PC端。但给每一个新出现的串口增加一个新的I/O口也不现实。因此将 RS232串口和非RS232串口都通过RS232口接入的UART产生。1981年,IBMPC主板上主要使用8250UART与外围设备通信。几年后,出现了16450UART,其速度有明显加快。但是 PC机的中断和软件响应时间仍然明显不足。因此,出现了一种解决办法就是在UART中增加硬件缓存,其代表性产品就是16550。其内部增加了2个16字节的FIFO。后来随着FIFO字节的增加出现了32字节FIFO的16C650和64字节FIFO的16C750。现如今我们主要使用的仍然是UART16550。1.3串行并行、异步同步串行是只有一根数据线,每当一个时钟脉冲到来只能发送一位数据。并行有多个数据线,在每个时钟脉冲下可以发送多个数据位(n位并行口就可以发送n位)。现如今主流是串行,因为在高速状态下,并行口的数据线之间串扰,而且并行口需要信号数据同时发送同时接收,任何一根数据线延迟均会引起问题。而串行不存在这些并且串行可以采用低压差分信号来大大提高抗干扰能力。正因为如此串行可以将速度做到很高。同步就是指发送发出数据后等待接收方返回响应后才继续发送下一个数据。异步是发送方发送完数据后直接开始发送下一数据无需得到接收方响应。 4兰州大学本科生毕业论文键入文字uart16550IP核的设计与FPGA的实现 第二章 UART的基本结构和应用2.1UART16550的基本结构如图2.1所示,UART16550的基本结构由七部分组成分别为CPU接口模块、波特率发生器模块、FIFO控制器模块、发送FIFO模块、接收FIFO模块和发送/接受模块。图2.1 UART16550基本结构图下面将介绍整个UART工作原理。CPU通过CPU接口模块设定整个UART初始状态,如是奇校验还是偶校验、波特率数值和停止位的位数。波特率发生器分频出设定好的波特率并以设定的波特率控制发送和接收模块以达到发送和接收的同步。发送数据时CPU将待发送的并行数据输入发送FIFO,在发送FIFO中有16字节的缓存以减少发送数据时CPU中断次数。发送模块将并行数据转化为串行数据并在数据位前加上起始位后面加上奇偶校验位和停止位,通过串行发送方式发送给外设。接收模块会时刻监视串行输入端口,一旦检测到电平转换(即起始位)接收模块会马上进行状态判断并接收数据,通过奇偶校验和启停位检测有效的排除掉错误数据,然后将启停位和校验位去除,剩余的数据位发送到发送FIFO,并通知CPU在CPU接口模块接收的数据,最后数据就被传输至中央处理区。2.2 串行通讯原理图2.2 异步串行数据传输格式UART16550采用国际通用的RS-232C串行接口标准(IEEE标准),至少仅需2根导线(RX/TX)即可实现数据的发送与接收。在RS-232C标准中规定了逻辑1即高电平为相对于地325V,逻辑0低电平为相对于地-3-25V。每帧数据由起始位、数据位、奇偶校验位和停止位组成。其中起始位为低电平占用1位;数据位5-8位不等发送和接收数据时均是从最低位开始的(如数据 a其二进制位1100001接收发送顺序为1000011);奇偶校验位有奇校验、偶校验或者无校验;停止位为高电平有1位、1.5位、2位3种。当无数据发送时,发送和接受引脚均保持高电平。2.3功能与特征UART16550是美国国家半导体公司生产的一种为pc配套的异步串口通信接口专用芯片主要功能有:1.具有全双工、双缓冲器发送器和接收器。全双工也就是仅需要两条信号线 (RXD和 TXD)即可完成互相通信,接收发送互不干扰,从而大大降低传送费用。2.是一种串行异步通信接口(UART),不具有同步通信功能。3.通讯波特率为50-115 200 bit/s,由编程决定。4.异步通信格式可通过编程选择。5.支持内部回环模式,具有奇偶校验、帧出和溢出错误等校验,片内具有优先级中断控制逻辑。其主要特征有:1.wishbone接口有2中可选择的交互模式分别为32-bit和8-bit。2.FIFO部分只进行操作。3.注册级别和功能兼容于NS16550A(不是16450)。4.调试接口的交互模式为32-bit。 现如今UART现在包含在微控制器中用于电脑和外围设备的串行端口。 第三章 UART16550IP核的设计3.1 UART16550的设计思路数据的发送,当发送模块接收到发送FIFO的数据后,发送模块自动添加由CPU设定好的配置寄存器内设定好的起始位、停止位和奇偶校验位。通过移位寄存器通过串口通讯方式打包传送给接受仪器。当无数据时发送端保持高电平1。接受是发送的逆序过程,接受时将去除起始位、停止位和奇偶校验位,并进行校验若无错误将把数据发送至接收FIFO传输给CPU。在此过程中FIFO对数据进行缓存,大大的减少了数据发送的次数提高了CPU的运行效率。而在此期间CPU对波特率发生器的波特率进行预设以使串口两端设备在同一波特率下完成数据的发送和接收。数据帧如图3.1 数据位起始位 D0 D1 D2 D3 D7 校验位 停止位 空闲波特率通常为9600b/s。最高可为115200b/s。图3.1 数据帧格式 当空闲时总线上为高电平。开始数据发送首先为低电平的起始位当接收器接收到低电平的起始位时即开始逐位数据接收。然后发送的是数据位,数据位可以是5-8位在此之前收发双方要约定好,数据位从数据低位LSB到数据高位MSB逐位发送。奇偶校验位是用来为了保证数据远距离传输的安全可靠,这个校验位在此之前需要约定是否加入,奇偶校验就是在数据位后面加入低电平0或高电平1使得数据位中的1+校验位中的1总和个数为奇数或偶数,奇数则为奇校验,偶数则为偶校验。停止位为高电平为数不固定有 1位、1.5位和2位。波特率是单位时间内传送的二进制数据的位数,单位为b/s,也叫数据位移。波特率与收发时钟频率关系为:收发时钟频率=波特率NN可取8,16,32和64这个数值在一开始硬件设计时就已设定好。一般选择16以保证速度和稳定性,通过2个8位的数据寄存器组合成16位分频寄存器实现系统频率的分频。 3.2 UART模块仿真将一个完整的硬件从功能上分为几大模块,通过对各个模块分别进行建模、仿真以达到各个模块功能实现任务的分工并最终在系统级进行综合来实现整个硬件功能。这是现如今构建复杂数字系统的主要手段。这一方式大大提高了数字系统设计效率和设计质量。CPU接口模块发送器波特率发生器接收器 FIFO控制器CPUTXRX 图3.2 UART系统模块结构图如上为系统级模块关系左边为CPU,右边为外部串行设备。CPU接口模块实现UART与CPU数据发送。发送/接收模块实现与外部串行设备的数据发送。收发FIFO提高了CPU工作效率而波特发生模块解决了接收与发送可能不同步的问题(收发设备之间的时钟积累)。3.3 CPU接口模块CPU接口模块主要用于寄存器配置、UART状态读取和CPU指令解读等功能。通过3位地址线和8位数据线,CPU对波特率进行预先设定,以保证串口两端在同一波特率下完成发送和接收。而且起到连接的作用,将CPU发送来的5-8位数据发送到发送模块以及将接收模块接收到的数据传送给CPU进行数据处理。CPU接口模块由一系列控制和状态寄存器组成,包括IIR(Interrupt ID Register)中断寄存器、THR(Transmit Hold Register)发送保持寄存器、LSR(Line Status Register)线状态寄存器、IER(Interrupt Enable Register)中断使能寄存器、RBR(Receiver Buffer Register)接收缓冲寄存器、LCR(Line Control Register)线控制寄存器、SCR(Scratchpad Register)临时寄存器和FCR(FIFO Control Register)FIFO控制寄存器。可编程的UART16550使用前我们必须先要对控制器进行配置,设定包括波特率、奇偶校验、数据位数、FIFO的控制和停止位数的数值。没有经过设定的UART16550将无法进行正常的工作。3.4 波特率发生模块波特率发生器主要功能就是从输入时钟转换出需要的波特率clk。波特率发生器实际就是一个分频器,通过设计一个计数器,使工作频率很高的系统时钟分频为所需的波特率时钟。之所以需要设定这样一个时钟是因为收发设备间的时钟会积累导致接收数据不正确。而波特率发生器就是专门产生一个远远高于波特率的本地时钟信号对输入RXD不断采样以保证接收器和发送器保持同步。波特率发生器并不产生波特率时钟,其波特率=系统时钟频率/波特率因子。如假设系统时钟频率为10MHz,需要设计波特率为9600bps射频模块,这所需的波特率因子=10MHz/9600Hz=1042。波特率因子是一个22位数有16位整数和6位小数。波特率发生器通过使用带有小数的除法器,对高频系统时钟进行分频,可以产生所有标准波特率,并十分精确。3.5 FIFO模块UART16550带有2个8位宽、16字节的异步FIFO控制,分别为发送FIFO和接受FIFO。FIFO控制器从CPU接口读取信息、配置发送/接收FIFO并能通过CPU接口将数据快速传递给CPU。FIFO解决了由于数据逐位传递中断过于频繁导致CPU工作效率低下的问题。如果没有FIFO每发送一个数据都要中断处理一次,而通过添加FIFO可连续收发若干个数据,至多14个,一次中断克进行一并处理大大地提高了工作效率。并且完全无需担心 FIFO机制可能导致数据来不及处理和数据丢失的问题。只要初始化配置好UART,FIFO会自己解决所有问题。发送FIFO工作:发送是一个相对较为缓慢的过程,在发送的同时数据会填充入发送FIFO里,发送FIFO会将数据一个一个发送出去,直到发送完毕与此同时发送完毕的数据会自动删除。在此无须担心因为数据填充满导致数据丢失,在此以波特率为9600Hz为例,等待出现一个空位时间在1ms左右十分短暂。接收FIFO工作:当接受模块接收到数据,就会将数据传送给接收FIFO在接收FIFO中填充数据。程序及时取走这些数据同时FIFO里的数据自动删除。3.6 UART发送模块发送原理:空闲时发送模块会以逻辑1(高电平)表示暂不发送数据的空闲状态。当发送模块接收到复位信号时马上进入就绪发送状态,并读取来自CPU的8位并行数据到寄存器内。先输出逻辑0(低电平)作为起始位,当下一个串行通信要求的波特率时钟上升沿到来开始发送,每个位寄存器从高到低将数据发送到TXD端,经过8个单位时钟后确保8位数据完全发送完毕,此时8位并行数据转换为8位串行数据 ,最后在输出奇偶校验位和一到两位的停止位逻辑1(高电平),数据发送完成。位数起始位05-8位910-11操作发送低电平发送数据位发送奇偶校验位发送停止位高电平图3.3 数据发送顺序简述:1、信号线上只有两种状态,分别以逻辑1和逻辑0来表示。在空闲状态是数据线保持逻辑1。2、起始位(start bit)占一位总是在每一帧的开始以逻辑0表示数据传输即将开始。3、数据位(data bits)有5-8位从低位(LSB)到高位(MSB)依次发送。4、校验位(parity bit)能在一定程度上检测传输错误排除干扰,担当出现双位错时将无法检测出。5、停止位在每帧的末尾表示数据传输结束有1位、1.5位和2位。6、从起始位到停止位之间的一组数据成为一帧。UART数据发送原理如图所示Y空闲状态检测CPU发送数据位检测拉低电平NY奇偶结果发送拉高电平回到空闲状态发送数据 和奇偶校验导入待发送的数据 图3.4发送流程图3.7 UART接收模块接收模块的作用是接收串行设备输入的数据。接收模块始终监视总线RXD端的电平状态。当检测到总线RXD端低电平时接收模块接收并解析RXD线上的电平得到传输数据并最终发送给CPU。接收数据时我们用波特率时钟(保证接收发送同步)上升沿计数,每接受一位计数一次。逐位接收完数据后,开始接收奇偶校验位和停止位,并进行校验和判断。确定无误后接收模块去除起始位、奇偶校验位和停止位并将串行数据转换为8位的并行数据并将并行数据送入接收FIFO并通知CPU来取数据。计数器05-89-1011操作数据起始位检测数据位接收进行奇偶校验接收完成?图3.5 UART数据接收顺序UART的接收状态一共有4个:1、state0起始位检测:当UART接收到起始位,也就是接收到从RX发送来的输入信号,由逻辑1到逻辑 0。一旦检测到起始位,就对采样时钟上升沿计数当计数到8(确保在起始位中点),转入下一状态。2、state1数据接收处理和串并行转换:对clk_rev上升沿计数,当计数到16时对数据采样。然后每个16位倍频采样一位串行数据,同时进行串并转换,当检测到已接受8位时,进入下一状态。3、state2奇偶校验 :对接收到的数据进行奇偶校验,奇偶校验成功后进入下一状态。4、state3数据帧判断:对该帧进行校验,检测若为高电平逻辑1则结束该帧。UART发送原理如下图:复位空闲检测CPU接受位检测出错放弃Y奇偶校验停止位检测送入接收FIFO接收数据图3.6 UART发送原理图Y第四章 主要模块的程序及仿真结果4.1 UART主体程序将大规模电路的设计从系统级开始,划分为若干可操作模块进行仿真并在系统级进行组合。UART的系统模块可以划分为4大部分波特率发生器、控制器、接收器和发送器。其结构图如图4.1所示。图4.1 UART结构图主要模块:read 接收模块 send 发送模块 counters控制模块CLK 时钟计数器模块 clear_check 寄存器清零选择模块 主要引脚及功能:read:串行输入 send:串行输出 data_in:并行输入data_out:并行输出 cs:通知CPU接收数据位 ks:通知CPU发送准备位 reset:重启输入 state:UART状态输入 clk:48M时钟输入主体程序:module uart(read,send,cs,ks,reset,state,clk,dat_in,dat_out);input read,clk,reset,state;/read为串行输入,clk为时钟输入48MHZ,reset为重启键,state为UART状态控制CPU控制模块input7:0 dat_in;/8位并行数据输入output send,cs,ks;/send为串行输出,cs为通知CPU接收数据位,ks为通知CPU发送准备位output7:0 dat_out;/8位并行数据输出wire clear,clk_enable,read_enable,clear3,send_enable,clear4,t1;/连续赋值wire7:0 counters,dat_in;read u1 (dat_out,cs,read,reset,clk_enable,clk,read_enable,clear3,counters);/接收数据modulesend u2 (dat_in,ks,send,reset,clk_enable,clk,send_enable,clear4,counters);/发送数据moduleclk u3 (clk,t1,clk_enable); /时钟计数器模块counters u4 (read_enable,send_enable,clk,state,t1,read,counters,reset,clear);check u5 (state,clear3,clear4,clear,clk_enable3,clk_enable4,clk_enable);/控制模块 endmodule/module read(dat_out,cs,read,reset,clk_enable3, clk,read_enable,clear3,counters);/接收数据moduleinput read_enable;input read,reset,clk;/read为串行输入,read_control为时钟控制,reset为重启键input7:0 counters;output cs,clear3,clk_enable3;/cs为通知cpu读取数据位output7:0 dat_out;/8位并行数据输出 endmodule/module send(dat_in,ks,send,reset,clk_enable4,clk,send_enable,clear4,counters);/发送数据moduleinput7:0 dat_in,counters; input reset,clk,send_enable;output send,clk_enable4,clear4,ks;/ks为通知cpu发送准备位endmodule/module counters(read_enable,send_enable,clk,state,t1,read,counters,reset,clear);/控制器moduleinput clk,state,t1,read,reset,clear;/state为uart状态输入,/clear为程序计数寄存器清零控制位output7:0 counters;output read_enable,send_enable;endmodule/module clk(clk,t1,clk_enable);/时钟计数器模块input clk,clk_enable;output t1;endmodule/module check(state,clear3,clear4,clear,clk_enable3,clk_enable4,clk_enable);/clear选择模块input state,clear3,clear4,clk_enable3,clk_enable4;output clear,clk_enable;assign clear=state?clear4:clear3;assign clk_enable=state?clk_enable4:clk_enable3;endmodule此处我们定义了UART的主要要引脚及内部连线,并定义了顶层分为4大模块发送模块(send)、接收模块(read)、波特发生模块(clk)以及控制模块(counters)。定义了clear选择模块。下面我们逐一介绍波数据发送模块、数据接收模块、控制模块和波特率发生模块的程序及仿真。 4.2 UART数据发送模块UART的数据发送操作如图4.2图4.2 UART数据发送操作解释: 导入待发送的数据:是指将从data_in端口的数据存入寄存器中。CPU发送位检测:是指将ks寄存器置位,即数据发送完毕。数据发送模块主体程序:module send(dat_in,send,reset,clk_enable4,clk,send_enable,clear4,counters);/发送数据moduleinput7:0 dat_in,counters;input reset,clk,send_enable;output send,clk_enable4,clear4;wire clear;wire7:0 dat_s;/8位连线reg send,parity_result;/parity_result是寄存器类型reg clk_enable4,clear1,clear4;reg7:0 date_s;/8位寄存器/always(posedge clk)beginif(send_enable & !reset)/当send_enable为高电平时为发送操作状态beginclk_enable4=1;clear4=clear1;/非阻塞赋值clk_enable4和clear4endelsebeginclear4=1;/非阻塞赋值,将1赋值给clear4endend/always(posedge clk)/时钟沿触发if(send_enable & !reset)beginif(counters=8b00000001)/0拉低电平beginsend=0;date_s=dat_in;parity_result=1;endelse if(counters=8b00010000)/1发送数据位并计算parity_result作为偶校验位beginsend=date_s0; parity_result=parity_result + date_s0;endelse if(counters=8b00100000)/2beginsend=date_s1;parity_result=parity_result + date_s0;endelse if(counters=8b00110000)/3beginsend=date_s2;parity_result=parity_result + date_s0;endelse if(counters=8b01000000)/4beginsend=date_s3;parity_result=parity_result + date_s0;endelse if(counters=8b01010000)/5beginsend=date_s4;parity_result=parity_result + date_s0;endelse if(counters=8b01100000)/6beginsend=date_s5;parity_result=parity_result + date_s0;endelse if(counters=8b01110000)/7beginsend=date_s6;parity_result=parity_result + date_s0;endelse if(counters=8b10000000)/8beginsend=date_s7;parity_result=parity_result + date_s0;endelse if(counters=8b10010000)/9发送奇校验结果beginsend=parity_result; endelse if(counters=8b10100000)/0发送高电平beginsend=1;endelse if(counters=8b10101111)/0beginclear1=1;endelse if(counters=8b00000000)beginsend=1;endelse clear1=0; end elsesend=1;/endmodule起始设定发送module的输入输出及内部连线,然后设定了发送模块的起始条件(send_enable为高电平 且reset为低电平)此时send_enable将会被赋值为1、clear4将会被赋值为clear1当工作状态也就是低电平0。否则clear4赋值为1,send模块也就不会向外发送数据。下面当满足起始条件,当时时钟上升沿到来时我们将进入数据发送部分。步骤0.完成初始设置和拉低电平输出起始位,步骤1-8.依次从低到高输出数据位。步骤9我们发送奇偶校验位。我们通过加入parity_result来进行奇校验,如我们说要发送的数据位为01010101那么经过0-8各部分我们可以得到parity_result为(使用2进制加法)1在这里总共高点平1的位数为5位,这样在外接串口设备中奇校验就会成功。然后我们将会发送停止位也就是send发出高电平1。最后我们定义了个空闲状态的发出信号send出高电平1。仿真结果:当rest为0时图4.3 reset为零时仿真图如图4.3为UART的数据发送模块的quartsii9.0功能仿真图,为方便观察,给出部分时钟,由图判断,其功能正常,数据发送模块编译成功。当计时器为110ns时,为数据接收拉低电平,输出起始位。当计时器为545ns时,为数据发送,按照由低到高依次输出。当计时器为835ns时,为奇偶校验结果发送,此处为奇校验,因为数据位的1的个数为4故奇偶校验位为1,数据位加奇偶校验位1的总数为5。当计时器为875ns时,发送高电平,停止位。之后再次进入空闲状态输出高电平。当reset为1时如图4.4图4.4 reset为1时仿真图重启输入reset为1,数据发送模块将不会发送数据,符合设计要354.3 UART数据接收模块 UART数据接收模块操作如图4.5:CPU接受位检测空闲检测起始位检测毛刺检测数据帧检测检测数据位读取和奇偶校验奇偶结果比较等待接受 图4.5 UART数据接收操作原理图解释:数据接收速度9600波特率,以16倍频接收。UART接收模块处于一直工作状态,因为并不知道何时会有数据接收,所以要一直不停地进行空闲状态检测。毛刺分为高脉冲和低脉冲毛刺。奇偶结果比较和数据帧检测在很大程度上排除了错误数据接收的可能性。cpu接收位检测:当奇偶结果比较和数据帧检测都正确时,cpu检测接收位cs置位。UART数据接收模块程序:module read(dat_out,cs,read,reset,clk_enable3,clk,read_enable,clear3,counters);/接收数据moduleinput read_enable;input read,reset,clk;/read为串行输入,read_control为时钟控制,reset为重启键input7:0 counters;output cs,clear,clk_enable3;/cs为通知cpu读取数据位output7:0 dat_out;wire clear3;reg cs,cs1,clk_enable3;reg7:0 data_out;/移位寄存器reg parity_check_result,parity_result, clear1;/always(posedge clk)beginif(read_enable)/当read_enable为高电平时为接收操作状态beginclk_enable3=1;clear3=clear1;endelsebeginclear3=1;endend/always(negedge counters0) /接收if(read_enable & !reset)begin if (counters=8b00011000) /1begindata_out7=read;parity_check_result=parity_check_result + read;endelse if (counters=8b00101000) /2begindata_out6=read;parity_check_result=parity_check_result + read;endelse if (counters=8b00111000) /3 begindata_out5=read;parity_check_result=parity_check_result + read;endelse if (counters=8b01001000) /4begindata_out4=read;parity_check_result=parity_check_result + read;endelse if (counters=8b01011000) /5begindata_out3=read;parity_check_result=parity_check_result + read;endelse if (counters=8b01101000) /6begindata_out2=read;parity_check_result=parity_check_result + read;endelse if (counters=8b01111000) /7begindata_out1=read;parity_check_result=parity_check_result + read;endelse if (counters=8b10001000) /8begindata_out0=read;parity_check_result=parity_check_result + read;endelse if (counters=8b10011000) /9进行奇偶校验检测beginparity_result=read;parity_result=#2 (parity_check_result = parity_result) ? 1:0;endelse if (counters=8b10101000) /0进行帧检测begincs1=(read) ? 1:0;endelse if (counters=8b10101010) /01给cpu发送接收信号begincs=(cs1 & parity_result) ? 1:0;/当奇偶校验结果与帧检测结果都为1时,cs置位clear1=1;clk_enable=0;endelse if(counters=8b00001000)/检测是否是毛刺beginclear1=(!read)?0:1;endelse clear1=0;endelse clear1=1;endmodule定义完输入输出引脚和内部连线后,我们设定read_enable为高电平1时当时钟下降沿到来clk_enable3为“1”,clear1赋值给clear3进入接收否则clear3为“1”。当read_enable为高电平且reset为“0”进入接收部分,接收模块编程1-8部分依次从高到低接收数据位。奇偶校验位赋值给parity_result,当parity_check_result与parity_result相同parity_result的值为1。帧检测是通过停止位当停止位高电平1到来帧检测 cs1将被赋值为1帧校验成功。然后当cs1与parity_result均为高电平1,cs置位。毛刺检测部分通过对counters为8b00001000时当read为低电平clear1赋值为0毛刺检测未通过。反之,clear1赋值为1数据接收成功。 仿真结果:当counters指定时间时功能仿真图4.6 当counters指定时间时解释:从图中可以观察到data0、data1的变化仿真成功。当counters未指定时间时功能仿真图4.7 当counters未指定时间时功能仿真4.4 UART控制器模块控制模块就是由state决定数据发送对象以起到控制作用。当state为1发送到UART接收模块,反之发送到UART发送模块。计数到指定数据将触发制定操作。UART控制器模块程序:module counters(read_enable,send_enable,clk,state,t1,read,counters,reset,clear,control);/程序计数寄存器input clk,state,t1,read,reset,clear;/state为uart状态输入/clear为程序计数寄存器清零控制位output7:0 counters;output read_enable,send_enable,control;reg read_enable,send_enable,control;/read_enable为接收控制位,send_enable为发送控制位,control为程序计数寄存器零状态寄存位reg7:0 counters;/8位程序计数寄存器always(posedge clk)/当程序计数寄存器为零时,程序计数寄存器为零状态寄存位置位begincontrol=(!counters)? 1 : 0;end/always(negedge re

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论