Intel8251可编程串行扩展RS232串口

随着集成电路技术的发展,电子设计自动化(EDA)逐渐成为重要的设计手段,已经广泛应用于模拟与数字电路系统等许多领域。电子设计自动化是一种实现电子系统或电子产品自动化设计的技术,它与电子技术,微电子技术的发展密切相关,它吸收了计算机科学领域的大多数最新研究成果,以高性能的计算机作为工作平台,促进了工程发展。EDA的一个重要特征就是使用硬件描述语言(HDL)来完成的设计文件,VHDL语言是经IEEE确认的标准硬件语言,在电子设计领域受到了广泛的接受。本文介绍了串行通信的基本理论;综述了EDA技术的发展概况,介绍了MAX+PLUSll软件;熟悉Intel8251基本结构和工作原理;最后设计仿真了Intel8251的顶级功能模块和子功能模块.

在系统中嵌入式CPU 往往要通过各种串行数据总线与外界进行通信,在应用中,异步的串行数据通信用得较多,而通用异步收发器(UART Universal Asynchronous Receiver/Transmitter )在其中扮演着重要角色,它可以完成数据的串并转换,即把并行数据按照通信波特率转化为通信协议中规定的串行数据流,也可从串行数据流中取出有用数据转变为并行数据。而UART 与CPU 接口简单,CPU只需通过执行读写操作即可完成收发数据,从而完成与外界的通信。有许多现成的芯片可以实现UART的功能:如常用的Intel8250/8251接口芯片就可以作为RS232、RS422串口的UART控制芯片。

FPGA/CPDL是20世纪90年代发展起来的大规模可编程逻辑器件,随着EDA技术和微电子技术的进步,FPGA的时钟延迟可达到ns级,结合其并行工作方式,在超高速、实时测控方面有非常广阔的应用前景;并且FPGA具有高集成度、高可靠性,几乎可以将整个设计系统下载于同一芯片中,实现所谓片上系统,从而大大缩小其体积,因此以FPAG/CLPD为代表的可编程逻辑器件受到了世界范围内广大电子设计工程师的普遍欢迎,应用日益广泛。在国外,FGPA的技术发展与应用己达到相当高的程度;在国内,FPAG技术发展十分迅速,然而与国外相比还存在较大的差距。

2.1数据通信概述

随着人类社会的不断进步、经济的迅猛发展以及计算机的广泛应用,人们对信息的需求越来越大,数据通信得到长足发展。

通信的目的是双方信息的互知,是信息的远距离传送。随着社会的进步。传统的电话、电报通信方式已远远不能满足大信息量的需要。以数据作为信息载体的通信手段已成为人们的迫切要求。但“数据”还没有统一严格的定义,一般可以这样认为:数据是预先约定的具有某种含义的数字、字母或符号的组合。计算机出现以后,为了实现远距离的资源共享,很快计算机就与通信技术相结合,产生了数据通信。所以说数据通信是为了实现计算机与计算机或终端与计算机之间信息交互而产生的一种通信技术,是计算机与通信相结合的产物。

综上所述,可对数据通信作如下定义:依照通信协议,利用数据传输技术在两个功能单元之间传递数据信息。它可实现计算机与计算机、计算机与终端或终端与终端之间的数据信息传递。

2.2数据传输方式

数据传输方式指的是通过某种方式建立一个数据传输通道将数据信号在其中传输,它是数据通信的基础。数据的传输方式分为并行传输和串行传输,在串行传输中又分为异步传输和同步传输。按照电路的传输能力,可以分为单工、半双工、全双工传输。

2.2.1 并行传输与串行传输

并行传输指的是数据以成组的方式,在多条并行信道上同时进行传输。常用的是将构成一个字符的几位二进制码同时分别在几个并行的信道上传输。另外加一条控制信号即“选通”脉冲,它在数据信号发出之后传送,用以通知接收设备所有的位己经发送完毕,可以对各条信道上的信号进行采样了。收、发双方不存在字符同步的问题,不需要额外的措施来实现收发双方的字符同步,这是并行传输的主要优点。但是并行传输必须有多条并行信道,成本比较高,不适宜远距离传输,因此一般较少使用。

串行传输指的是组成字符的若干位二进制码排列成数据流以串行的方式在一条信道上传输。通常传输顺序为由低位到高位,传完这个字符再传下一个字符。因此收、发双方必须保持字符同步,以使接收方能够从接收的数据比特流中正确区分出与发送方相同的一个一个的字符。这是串行传输必须解决的问题。串行传输只需要一条传输信道,易于实现,是目前主要采用的一种传输方式。

2.2.2 异步传输与同步传输

在串行传输中,如何解决字符的同步问题,目前主要存在两种方式:即异步传输和同步传输。异步传输方式的优点是实现字符同步比较简单,收发双方的时钟信号不需要严格同步。缺点是对每个字符都需加入起始位和终止位,因而传输效率低。

同步传输是以固定的时钟节拍来发送数据信号的,因此在一个串行数据流中,各信号码元之间的相对位置是固定的(即同步)。接收方为了从接收到的数据流中正确地区分一个个信号码元,必须建立准确的时钟信号。与异步传输方式相比,由于它发送每一字符时不需要单独加起始位和终止位,故具有较高的传输效率,但实现起来比较复杂。

有关异步传输和同步传输的数据格式将在2.3中介绍。

2.2.3 单工、半双工、全双工传输

数据传输是有方向性的,根据数据电路的传输能力,可以有三种不同的传输方式或通信方式。

(1)单工传输:传输系统的两端数据只能沿单一方向发送和接收,这种方式传输系统的一端固定为发送端,另一端固定为接收端。反向信道的速率一般较低,为5-75bi/ts。实际应用中可以使用反向信道,也可以不用。气象数据的收集、计算机与监视器及硬盘与计算机的数据传输就是单工传输的例子。

(2)半双工传输:系统两端可以在两个方向上进行数据传输,但两个方向的传输不能同时进行,当其中一端发送时,另一端只能接收,反之亦然。无论哪一方开始传输,都使用信道的整个带宽。对讲机和民用无线电都是半双工传输。

(3)全双工传输:系统两端可以在两个方向上同时进行数据传输,即两端都可同时发送和接收数据。

    综上所述,异步串行全双工的数据传输方式是较为容易实现的方式,应用较为广泛。

2.3串行通信协议

数据通信是在各种类型的用户终端和计算机之间以及同一型号的计算机之间进行的。它不同于电话通信方式,其通信控制也复杂得多,因此必须有一系列行之有效的、共同遵守的通信协议。所谓通信协议是指通信双方的一种约定,约定包括对数据格式、同步方式、传送速度、传送步骤、检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守。因此,也叫做通信控制规程,或称传输控制规程,它属于国际标准化组织ISO(International Standards Organization)的开放系统互连OSI(Open System Interconnection)七层参考模型中的数据链路层口。

2.3.1串行通信接口标准

串行通信接口按电气标准及协议来划分包括Rs-232、Rs-422、Rs485、LVDS等。RS-232、RS-422与RS-485标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。LVDS是近几年发展起来的新型接口标准,主要应用于高速数据传输领域。

(l)RS-232串行接口

1969年,美国电子工业协会(EIA)公布了RS-232作为串行通信接口的电气标准,该标准定义了数据终端设备(DTE)和数据通信设备(DCE)间按位串行传输的接口信息,合理安排了接口的电气信号和机械要求。目前RS-232是PC机与通信工业中应用最广泛的一种串行接口。RS-232被定义为一种在低速率串行通信中增加通信距离的标准,它采取不平衡传输方式,即所谓单端通信。典型的RS-232信号在正负电平之间摆动,在发送数据时,发送端驱动器输出正电平在+5到+l5V,负电平在-5到-15v电平。当无数据传输时,线上为TTL电平,从开始传送数据到结束,线上电平从TTL电平到RS-232电平再返回TTL电平。接收器典型的工作电平在+3到+l2v与-3到-12v。Rs-232是为点对点(即只用一对收、发设备)通信而设计的,其驱动器负载为3到7k。。由于RS-232发送电平与接收电平的差仅为2V至3V左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最大为约30米,最高速率为20kb/s。所以RS-232适合本地设备之间的通信。

(2)RS-422串行接口

RS-422-B全名为“平衡电压数字接口电路的电气特性”  (Electrical Characteristics of Balanced Voltage Digital Interface Circuits),它是美国电子工业协会EIA(Electronic Industry Association)制定的一种串行物理接口标准。RS是英文“推荐标准”的缩写,422为标识号,B表示修改次数。

RS-422由RS-232发展而来,它是一种单机发送、多机接收的单向、平衡传输规范。为改进RS-232通信距离短、速度低的缺点,RS-422定义了一种平衡通信接口,将传输速率提高到10Mbit/s,并允许在一条平衡总线上连接最多10个接收器。

RS-422采用平衡驱动,差分接收电路,即在发送端,驱动器将TTL电平信号转换成差分信号输出;在接收端,接收器将差分信号变成CMOS/TTL电平。从根本上取消了信号地接法,大大减少了地电平所带来的共模干扰。平衡驱动器相当于两个单端驱动器,其输入信号相同,两个输出信号互为反相信号。外部输入的干扰信号是以共模方式出现的,两根传输线上的共模干扰信号相同,因接收器是差分输入,共模信号可以相互抵消,从而大大提高了抗共模干扰的能力,并能在较长距离内明显提高传输速率。

RS-422的数据信号采用差分传输方式,也称作平衡传输。它使用一对双绞线,将其中一线定义为A,另一线定义为B。通常情况下,发送驱动器之间的差分电压正电平在+2V - +6V,是一个逻辑状态,负电平在-2V - 6V之间,是另一个逻辑状态。另有一个信号地C。在RS一485中还有一“使能”端,“使能”端是用于控制发送驱动器与传输线的切断与连接。当“使能”端起作用时,发送驱动器处于高阻状态,称作“第三态”,即它是有别于逻辑“1”与“0”的第三态。接口信号电平比RS-232-C降低了,就不易损坏接口电路的芯片,且该电平与TTL电平兼容,可方便与TTL电路连接。

接收器作与发送端相对的规定,收、发端通过平衡双绞线将AA与BB对应相连,当在接收端AB之间有大于+200mV的电平时,输出正逻辑电平,小于-200mV时,输出负逻辑电平。定义A端B端与地之间电压的平均值为共模电压,RS-422接收器可以承受[-7V,+7V]的共模电压。接收器符号见图2.1。

 

A

B

DOUT

 

 

图2.1 平衡差分输入线接收器

由于接收器采用高输入阻抗和发送驱动器比RS-232更强的驱动能力,故RS-422允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Slave),从设备之间不能通信,所以RS-422支持点对多的双向通信。RS-422四线接口由于采用单独的发送和接收通道,因此不必控制数据方向,各装置之间任何必须的信号交换均可以按软件方式(XON汉OFF握手)或硬件方式(一对单独的双绞线)实现。

RS-422的最大传输距离为4000英尺(约1200米),最大传输速率为10Mb/s。其平衡双绞线的长度与传输速率成反比在100kb/s速率以下刁一可能达到最大传输距离。

(3)RS-485串行接口

为扩展应用范围,EIA在RS-422的基础上制定了RS-485标准,增加了多点、双向通信能力,通常在要求通信距离为几十米至上千米时,广泛采用RS-485收发器。

RS-485许多电气规定与RS-422相仿。如都采用平衡传输方式、都需要在传输线上接终端电阻等。RS-485可以采用二线与四线方式,二线制可实现真正的多点双向通信。而采用四线连接时,与RS-422一样只能实现点对多的通信,即只能有一个主(Master)设备,其余为从设备,但它比RS一422有改进,无论四线还是二线连接方式总线上可连接多达32个设备,SIPEX公司新推出的SP485R最多可支持400个节点。

RS-485与RS-422的共模输出电压是不同的。RS-485共模输出电压在-7V至+l2V之间,RS-422在-7V至+7V之间,RS-485接收器最小输入阻抗为12k;RS-422是4k;RS-485满足所有RS-422的规范,所以RS-485的驱动器可以用在RS-422网络中应用。但RS-422的驱动器并不完全适用于RS-485网络。

为方便起见将上述几种主流通信接口的电气特性比较列表如表2.1:

表2.1  RS-232\RS-422\RS-485电气特性比较

规定

RS-232

RS-422

RS-485

工作方式

单端

差分

差分

节点数

1收1发

10收1发

32收1发

最大传输速率

20Kb\s

10Mb\s

10Mb\s

最大驱动电压

+\-25V

-0.25V-+6V

-7V-+12V

接收器输入电压范围

+\-15V

-10V-+10V

-7V-+12V

接收器输入门限

+\-3V

+\-200mV

+\-200mV

接收器输入电阻

3K-7K

4K(最小)

12K

驱动器共模电压

 

+\-3V

-1V-+3V

接收器共模电压

 

+\-7V

-7V-+12V

RS-232串行接口属于个人计算机(PC)及电信应用领域中最为成功的串行数据标准;而RS-422和RS-485串行接口则是工业应用领域中最为成功的串行数据标准。由于可减少布线成本并实现较长的传输距离,RS-422和RS-485串行接口被广泛应用于汽车电子设备、销售点终端(POs)、工业控制、仪器仪表、局域网、蜂窝基站及电信领域,较高的输入电阻允许多个节点连至总线上。由于该类电路的优异性能,国外市场上目前己经出现了种类繁多的同类电路。几乎国际上几家大的集成电路开发公司都有相关产品,产品型号不胜枚举。但大多为双极工艺制造,采用CMOS工艺制作的产品还不多。

(4)LVDS

在被称为信息时代的今天,为适应信息化的高速发展,高速处理器、多媒体、虚拟现实以及网络技术对信号的带宽要求越来越大,多信道应用日益普及,所需传送的数据量越来越大,速度越来越快,l0Mbps的速率已然不能满足现代计算机之间高速互联的要求。因此采用新的技术解决I/O接口问题成为必然趋势,LVDS这种高速低功耗接口标准为解决这一瓶颈问题提供了可能。

LVDS接口又称RS-644总线接口,是20世纪90年代才出现的一种数据传输和接口技术。LVDS的全称为Low Voltage Differential Signal,即低电压差分信号,这种技术的核心是采用极低的电压摆幅高速差动传输数据,可以实现点对点或一点对多点的连接,具有低功耗、低误码率、低串扰和低辐射等特点。LVDS在对信号完整性、低抖动及共模特性要求较高的系统中得到了越来越广泛的应用。目前,流行的LVDS技术规范有两个标准:一个是TI/EIA的ANSI/TIA/EIA-644标准,另一个是IEEEI596.3标准。这两个标准注重于对LVDS接口的电特性、互连与线路端接等方面的规范,对于生产工艺、传输介质和供电电压等则没有明确规定。LVDS可采用CMOS、GaAs或其他技术实现,其供电电压可以从+5V到+3.3V,甚至更低;其传输介质可以是铜质的PCB连线,也可以是平衡电缆。标准推荐的最高数据传输速率是655Mbps,而理论上,在一个无衰耗的传输线上,LVDS的最高传输速率可达1.923Gbps。

LVDS技术之所以能够解决目前物理层接口的瓶颈,正是由于其在速度、噪声、EMI、功耗、成本等方面的优点:

①高速传输能力:LVDS技术的恒流源模式低摆幅输出意味着LVDS能高速驱动,例如:对于点到点的连接,传输速率可达800MbPs;对于多点互连FR4背板,十块卡作为负载插入总线,传输速率可达400Mbps。

②低噪声:LVDS产生的电磁干扰低。这是因为低电压摆幅、低边沿速率、奇模式差分信号以及恒流驱动器的Iss尖峰只产生很低的辐射。在传输线上流过大小相等、极性相反的电流,电流在该线对内返回,使面积很小的电流回路产生最低的电磁干扰。当差分传输线紧藕合时,串入的信号是作为共模电压出现在接收器输入的共模噪声中,差分接收器只响应正负输入之差。因此当噪声同时出现在2个输入中时,差分信号的幅度并不受影响。共模噪声抑制也同样适用于其它噪声源,比如电源波动、衬底噪声和接地回跳等。

③低功耗:LVDS器件是用CMOS工艺实现的,这就提供了低的静态功耗。同时LVDS使用恒定电流源驱动器,随着工作频率的增加,其电源电流仍然保持平坦,而CMOS和TTL技术的电源电流则随频率增加而呈指数上升。因此,恒定电流驱动模式大大减少了LVDS的功耗。从对负载功率的计算(3.5mA电流乘以100欧终端电阻上的350mV压降)可看到LVDS仅有1.2mW的功耗。作为对比,TTL在负载电阻上有1V压降,负载电流为40mA,因而负载功耗为40mW。

④节省成本:LVDS器件采用经济的CMOS工艺制造,用低成本的电缆线和连接器件就可以达到很高的速率。由于功耗较低,电源,风扇等其他散热开销就大大降低。LVDS产生极低的噪声,噪声控制和EMI等问题迎刃而解。与并行连接相比,可以减少大量的电缆,连接器和面积费用。

⑤集成能力强:由于可在标准CMOS工艺中实现高速LVDS,因此用LVDS模拟电路集成复杂的数字功能是非常有利的。LVDS内集成的串行化器和解串行化器使它能在一个芯片上集成许多通道。较窄的链路大大减少了引脚数量和链路的总费用。差分信号能承受高电平的切换噪声,因而能用大规模数字电路进行可靠的集成。恒定电流的输出模式使LVDS只产生很低的噪声,因此能实现完整的芯片接口系统。

目前LVDS技术在传输距离上有其局限性,一般应用在20m以下。

LVDS的显著优势使得其应用范围远远超过那些传统器件,标准LVDS产品可广泛应用于计算机、通讯、消费电子、显示等领域。LVDS拥有低噪声的特色,最适用于笔记掌上型计算机的液晶显示器。平板显示器链接需要将大量的显示数据从笔记本计算机传送到平板显示器。美国国家半导体公司(NSC)和日本几家笔记本电脑生产商合作定义了FPD-Link标准用于平板显示器的链接,并生产出使用LVDS方式传输的样片。此外,NSC公司还建立基于LVDS的低摆幅差分信号标准RSDS,该标准将LVDS的性能特点应用到平板显示器的列驱动电路与TCON的芯片的连接上。它在功耗、噪声等方面有进一步改善,为LVDS在显示技术领域的应用提供了新的机遇。

高速串行通信也是LVDS最引人注目的应用之一。为实现并行数据并串及串并转换功能,德州仪器公司(TI)日前宣布推出一系列新型通用多芯片组器件,该系列器件充分发挥了TI在数据传输技术方面的设计经验和优势。就低电压差分信号(LVDS)链路数据传输而言,新系列产品是业界用途最为广泛的数据并串、串并转换器解决方案。采用该解决方案,设计人员不仅能将电线或电路板走线的数量减少一半以上,而且可将数据传输距离提高10倍。与其它串并转换器解决方案不同,MuxIt系列产品可高度适应各种总线宽度和速度,应用领域包括电信、打印/复印机、视频成像和消费类产业等。

目前,LVDS技术日益受到中国电路设计工程师的重视,LVDS应用前景广阔,在国内的发展非常迅猛。例如银河巨型机的高速互连传输中就采用了LVDS技术。但是国内使用的基本上都是国外厂商提供的成品,几乎没有自主设计的LVDS核心电路和芯片。令人欣慰的是,国内现在己经有几家公司正在研发LVDS核心电路和芯片。

4.2.1 FPGA一般开发流程

一般FPAG的开发大体有如下几个步骤:设计输入一>功能仿真一>代码综合一>实现一>下载。其中最重要的显然是设计部分,因为产品的功能就是在设计上体现出来的;而仿真主要针对设计,采用DEA工具进行波形仿真,只有波形仿真通过才能说明设计的正确性与合理性;综合主要是将用HDL语言所作的硬件描述对应到FPAG芯片上的单位逻辑电路上;实现是将综合后生成的逻辑网表与具体的FGPA相适配;最终生成的位流文件通过某种下载途径下载到FPAG中。

4.2.2 本课题设计难点

在每一个设计模块当中,没有统一的时钟脉冲信号,状态变化的时刻是不固定的,通常输入信号只有在电路处于稳定状态时才发生变化。也就是说,一个时刻仅允许一个输入发生变化,以避免输入信号之间造成的竞争冒险现象。在设计北京化工大学硕士学位论文和使用时序电路时,必须考虑到器件的传输延时,注意竞争冒险问题,注意由于时钟偏移造成的冒险。

设计过程中,根据理论分析,如果各个模块的复位信号频率存在偏差,将使得输入输出之间的信号,不能正常完成转换,同时,虽然各个模块在单独工作的情况下,均能完成各自的功能,但如果将模块合成,就可能出现各种意想不到的问题。

对于CRc校验用于异步串行通信的方法,有关软件处理流程的资料很少。并且其接口时序涉及软硬件的协同操作以及软件硬件控制的相互转换,因此是本设计的一大技术难点。

传统设计过程中,CRC通常应用于同步串行通信,至于在异步串行通信中的应用,其是否可行,还有待进一步分析。

4.2.3 UART的设计与实现

UART(UuvlesraiAs”chronousReeeiverTrnasmitte)r即通用异步收发器,是一种应用广泛的短距离串行传输接口。往往用于短距离、低速、低成本的微机与下位机的通讯中。8250,8251,NS16450等芯片都是常见的UART器件。这类芯片有些已经做得相当复杂,含有许多辅助的模块,比如FIFO。在本节里仅讨论最基本的UART,其实也是最常用的。

4.2.3.1 发送模块的设计

    首先来设计URAT的发送模块,根据系统的要求我们首先定义如下的管脚:

mclkx16 : IN std_logic;                    --系统时钟

      write   : IN std_logic;                    --写时钟

      reset   : IN std_logic;                     --复位,0工作,1复位

      data    : IN std_logic_vector(7 downto 0);  --8位并行数据输入

      tx      : OUT std_logic ;                   --串行输出

      txrdy   : OUT std_logic                     --标志位

该模块的仿真波形图如下图所示:

图4-1

     当信号发送的01000110的时候,将并行信号变为串行信号,data[0]=0, data[1]=1, data[2]=1, data[3]=0, data[4]=0, data[5]=0, data[6]=1, data[7]=0,后3位的010为该数据的校验信号位。由此我们验证了系统发送部分的正确性。

图4-2

上图中状态的转移是靠一个内部变量(Variable)来实现的,该变量在进行完当前状态的处理后指向下一个将处理的状态,进程(Process)的每一次处理都根据变量的内容进行相应状态的处理,由于其功能就像一个指针,因此我们称之为接收或发送指针。

其中的信号的转换过程如下:

            tsr <= '0'&tsr(7 downto 1);

            tsr(7) <= tag1;

            tag1 <= tag2;

                      tag2 <= '0';

            txparity <= txparity XOR tsr(0);

            IF (txdone = '1') THEN

               tx <= '1';

               ELSIF (paritycycle = '1') THEN

                  tx <= txparity;              

               ELSE

                  tx <= tsr(0);

            END IF;

通过这个代码可以将并型信号转为串型信号,将串行信号发送出去。

其中信号的校验公式如下:

paritycycle <= tsr(1) AND NOT (tag2 OR tag1 OR tsr(7) OR tsr(6) OR tsr(5) OR tsr(4) OR tsr(3) OR tsr(2));

4.2.3.2 接收模块的设计

    首先来设计URAT的发送模块,根据系统的要求我们首先定义如下的管脚:

mclkx16     :  IN std_logic;    -- 输入时钟

     read        :  IN std_logic;    -- 读取信号

     rx          :  IN std_logic;    -- 接收到的信号

     reset       :  IN std_logic;    -- 复位

     rxrdy       :  OUT  std_logic;  -- 接收的数据准备读取

     parityerr   :  OUT  std_logic;  -- 接收校验标志

     framingerr  :  OUT  std_logic; 

     overrun     :  OUT  std_logic; 

     data        :  OUT  std_logic_vector(7 downto 0)); -- 8 bit 数据输出该模块的仿真波形图如下图所示:

图4-3

     当信号接收串型信号01101010的时候,将串行信号变为并行信号,data[0]=0, data[1]=1, data[2]=1, data[3]=0, data[4]=1, data[5]=0, data[6]=1, data[7]=0。由此我们验证了系统发送部分的正确性。

     下面来具体介绍发送部分的工作流程:

图4-4

接收处理首先完成起始位的检测,并自己产生接收时序控制信号,在控制信号的控制下,逐位接收串行输入数据,并根据控制字判断接收数据位数,完成数据的接收后,进行奇偶校验位的判断,最后判断停止位。在接收的过程中设置接收状态输出信号。

 

其中的信号的转换过程如下:

   sample_data : PROCESS (rxclk, reset)

   BEGIN

      IF (reset = '1') THEN

      -- idle_reset  

         rsr        <= "11111111";             

      rxparity   <= '1';                       

      paritygen  <= paritymode;     

      rxstop     <= '0';    

      ELSIF (rxclk='1') AND (rxclk'EVENT) THEN

         IF (idle='1') THEN

            -- idle_reset  

            rsr        <= "11111111";       

         rxparity   <= '1';                        

         paritygen  <= paritymode;             

         rxstop     <= '0';

         ELSE

              -- shift_data

              rsr         <= '0'&rsr(7 downto 1);   

            rsr(7)      <= rxparity;           

            rxparity    <= rxstop;            

            rxstop      <= rx;                

            paritygen   <= paritygen XOR rxstop; 

         END IF;

      END IF;

   END PROCESS;

通过这个程序,我们可以讲接收端的串行信号变为原始的串行信号。

 

 

4.3 FPAG的综合

在完成了系统逻辑的设计和功能仿真后,我们要对所生成的VHDL文件进行综合,生成门级网表文件,这些文件只是一些门与或非的逻辑关系,与实际的配置还有差距。我们需要对他们进行布局布线和时序验证,来实现芯片内部功能单元的连接和映射哪脚。

在这些工作完成后,即可开始对设计进行综合并优化。其中对设计的约束在整个综合过程中的作用至关重要,它可以方便控制综合、实现过程,使设计满足运行速度、引脚位置等方面的要求,可以说约束是关系到整个FPGA实现成功与否的关键。我们采用编写约束文件并将其导入到综合、实现工具的方法。由于时钟信号具有高扇出的特点,所以必须给时钟加上全局缓冲器,另外全局缓冲器还可以减少时钟歪斜(clockskew),使得设计在布线阶段可以更容易,并取得最佳的效果。  

另外,在器件结构允许的情况下,即器件提供全局缓冲器足够多的时候,应该给高扇出的信号也加上全局缓冲器,比如系统复位信号等,以增加其驱动能力。

另外,对端口的约束也有利于PCB图的完成。

对于数字电路来说,提高工作频率也是非常重要的,因为高工作频率意味着高处理能力。但由于本次实验的频率不是太高,所以我们约束频率缺省,这是因为时钟频率较低时,不加约束自动综合也能达到要求。在这个设置下,综合工具往往会追求最小面积(消耗最少的门电路)。

完成上面的工作后,我们要进行时序验证。时序验证的方法的主要方法包括SAT 和后仿真。在后仿真中将布局布线的时延反标到设计中去,使仿真既包含门延时,又包含线延时信息。这种后仿真是最准确的仿真,能较好地反映芯片的实际工作情况。仿真工具与综合前仿真工具相同。我们本次实验主要根据静态时序分析。综合结束后,我们的工作进入了实现阶段。实现的流程大体可分为以下几个阶段:编译规划、布局布线、程序比特流文件的产生。

硅片上的资源进行映射性规划,并检查物理设计规则。规划映射完FPGA设计之后,就是布局和布线。在布局步骤中,主要在于把整个的逻辑块,包括逻辑配置块(CLB)和输入瀚出块(IOB)分配到电路片土的特定位置上去。如果在部分的逻辑元件中放置了时序约束,那么布局器就会通过移动相应的逻辑块使它们靠近,以满足它们的约束。在布线阶段中,把逻辑网络分配到电路片中与逻辑元胞互连的物理线段上去。如果在部分的逻辑元件中放置了时序约束,那么布线器就会尝试选项择快速的连接以满足它们的约束。

 

 

 

 

附录

·发送模块:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.ALL;

ENTITY txmit IS

PORT (

      mclkx16 : IN std_logic;                    --系统时钟

      write   : IN std_logic;                    --写时钟

      reset   : IN std_logic;                    --复位,0工作,1复位

         data    : IN std_logic_vector(7 downto 0); --8位并行数据输入

         tx      : OUT std_logic ;                  --串行输出

      txrdy   : OUT std_logic                    --标志位

     );

END txmit;

--以下定义一些中间变量,具体使用在以下模块中介绍

ARCHITECTURE behave OF txmit IS

   SIGNAL write1, write2 : std_logic;

   SIGNAL txdone1, txdone : std_logic;

   SIGNAL thr, tsr : std_logic_vector(7 downto 0);

   SIGNAL tag1, tag2 : std_logic;

   CONSTANT paritymode : std_logic :='1';

   SIGNAL txparity : std_logic;

   SIGNAL txclk : std_logic;

   SIGNAL paritycycle : std_logic;

   SIGNAL txdatardy : std_logic;

   SIGNAL cnt : std_logic_vector(2 downto 0);

BEGIN

--校验公式

paritycycle <= tsr(1) AND NOT (tag2 OR tag1 OR tsr(7) OR tsr(6) OR tsr(5) OR tsr(4) OR tsr(3) OR tsr(2));

txdone <= NOT (tag2 OR tag1 OR tsr(7) OR tsr(6) OR tsr(5) OR tsr(4) OR tsr(3) OR tsr(2) OR tsr(1) OR tsr(0));

txrdy <= NOT txdatardy;

--当写信号为0的时候讲数据打入寄存器THR中,THR是一个中间变量

  thr_write : PROCESS (write, data)

  BEGIN

     IF (write = '0') THEN

        thr <= data;

     END IF;

  END PROCESS;

--生成一个分频后的时钟,16分频

   baud_clock_gen : PROCESS (mclkx16, reset)

   BEGIN

      IF (reset ='1') THEN

         txclk <= '0';

         cnt <= "000";

      ELSIF (mclkx16='1') AND mclkx16'EVENT THEN

         IF (cnt = "000") THEN

            txclk <= NOT txclk;

         END IF;

      cnt <= cnt + 1;

      END IF;

   END PROCESS;

--转换过程。

   shift_out : PROCESS (txclk, reset)

   BEGIN

      IF (reset = '1') THEN

           tsr <= (OTHERS => '0');

         tag2 <= '0';

         tag1 <= '0';

         txparity <= paritymode;

         tx <= '1';

         --idle_reset;

      ELSIF txclk = '1' AND txclk'EVENT THEN

         IF (txdone='1' AND txdatardy = '1') THEN

--          load_data;

            tsr <= thr;

            tag2 <= '1';

            tag1 <= '1';

            txparity <= paritymode;

            tx <= '0';

         ELSE

--          shift_data;                    --一下几行就是并-》串的过程。

            tsr <= '0'&tsr(7 downto 1);

            tsr(7) <= tag1;

            tag1 <= tag2;

                            tag2 <= '0';

            txparity <= txparity XOR tsr(0);

            IF (txdone = '1') THEN

               tx <= '1';

               ELSIF (paritycycle = '1') THEN

                  tx <= txparity;             --输出校验位

               ELSE

                  tx <= tsr(0);

            END IF;

         END IF;

      END IF;

   END PROCESS;         

--几个控制信号的生成

   PROCESS (mclkx16, reset)

   BEGIN

      IF (reset='1') THEN

         txdatardy <= '0';

         write2 <= '1';

         write1 <= '1';

         txdone1 <= '1';

      ELSIF mclkx16 = '1' AND mclkx16'EVENT THEN

         IF (write1 = '1' AND write2 = '0') THEN

            txdatardy <= '1';

         ELSIF (txdone = '0' AND txdone1 = '1') THEN

            txdatardy <= '0';

         END IF;

         write2 <= write1;

         write1 <= write;

         txdone1 <= txdone;

      END IF;

   END PROCESS;

END behave;

 

·接收模块:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.ALL;

ENTITY rxcver IS

PORT (mclkx16     :  IN std_logic;    -- 输入时钟

      read        :  IN std_logic;    -- 读取信号

      rx          :  IN std_logic;    -- 接收到的信号

      reset       :  IN std_logic;    -- 复位

         rxrdy       :  OUT  std_logic;  -- 接收的数据准备读取

         parityerr   :  OUT  std_logic;  -- 接收校验标志

         framingerr  :  OUT  std_logic; 

         overrun     :  OUT  std_logic; 

         data        :  OUT  std_logic_vector(7 downto 0));  -- 8 bit 数据输出

END rxcver;

--定义的中间变量

ARCHITECTURE behave OF rxcver IS

SIGNAL rxcnt : std_logic_vector(3 downto 0); 

SIGNAL rx1, read1, read2, idle1 : std_logic; 

SIGNAL hunt  : std_logic; 

SIGNAL rhr : std_logic_vector(7 downto 0); 

SIGNAL rsr : std_logic_vector(7 downto 0); 

SIGNAL rxparity  :  std_logic; 

SIGNAL paritygen :  std_logic;

SIGNAL rxstop : std_logic;  

CONSTANT paritymode : std_logic := '1';

SIGNAL rxclk  : std_logic;  

SIGNAL idle  :  std_logic; 

SIGNAL rxdatardy : std_logic; 

BEGIN

       idle_preset : PROCESS (rxclk, reset)

       BEGIN

              IF reset = '1' THEN

                     idle <= '1';

              ELSIF rxclk'EVENT AND rxclk='1' THEN

                     idle <= (NOT idle) AND (NOT rsr(0));

              END IF;

       END PROCESS;

--时钟分频

       rxclk_sync : PROCESS (mclkx16, reset)

       BEGIN

              IF reset='1' THEN

                     hunt <= '0';

                     rxcnt <= "0001";

                     rx1 <= '1';

                     rxclk <= '0';

              ELSIF (mclkx16='1') AND mclkx16'EVENT THEN

                     IF (idle='1' AND rx='0' AND rx1='1') THEN

                            hunt <= '1';

                     ELSE

                        IF (idle='0' OR rx='1') THEN

                           hunt <= '0';

            END IF;

            IF (idle ='0' OR hunt='1') THEN

               rxcnt <= rxcnt + 1;

            ELSE

               rxcnt <= "0001";

            END IF;

         END IF;

         rx1 <= rx;

         rxclk <= rxcnt(3);       

              END IF;

       END PROCESS;          

--校验位判断过程和数据转换

   sample_data : PROCESS (rxclk, reset)

   BEGIN

      IF (reset = '1') THEN

      -- idle_reset  

         rsr        <= "11111111";             

        rxparity   <= '1';                      

        paritygen  <= paritymode;    

        rxstop     <= '0';    

      ELSIF (rxclk='1') AND (rxclk'EVENT) THEN

         IF (idle='1') THEN

            -- idle_reset  

            rsr        <= "11111111";       

           rxparity   <= '1';                       

           paritygen  <= paritymode;             

           rxstop     <= '0';

         ELSE

               -- shift_data

               rsr         <= '0'&rsr(7 downto 1);   

            rsr(7)      <= rxparity;            

            rxparity    <= rxstop;            

            rxstop      <= rx;                

            paritygen   <= paritygen XOR rxstop; 

         END IF;

      END IF;

   END PROCESS;

--标志信号的生成

   generate_flag : PROCESS (mclkx16, reset)

   BEGIN

      IF (reset='1') THEN

          rhr         <= "00000000";

             rxdatardy   <= '0';

             overrun              <= '0';

             parityerr   <= '0';

             framingerr  <= '0';

             idle1       <= '1';

             read2       <= '1';

             read1       <= '1';

      ELSIF (mclkx16='1') AND (mclkx16'EVENT) THEN

         IF (idle='1' AND idle1='0') THEN

            IF (rxdatardy='1') THEN

               overrun <= '1';

            ELSE

               overrun <= '0';                      

                           rhr <= rsr;                                

                           parityerr <= paritygen;  

                           framingerr <= NOT rxstop;      

                           rxdatardy <= '1';                     

                        END IF;

                 END IF;

                 IF (read2 = '0' AND read1='1') THEN

             rxdatardy  <= '0';

                parityerr  <= '0';

                framingerr <= '0';

                overrun    <= '0';

                 END IF;

             idle1 <= idle;                                 

             read2 <= read1;                             

             read1 <= read;                                             

          END IF;

   END PROCESS;

   rxrdy <= rxdatardy;

   latch_data : PROCESS (read, rhr)

   BEGIN

      IF (read = '1') THEN

         data <= rhr;

      END IF;

   END PROCESS;

END behave;

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fpga和matlab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值