串行数据收发器课程设计.doc
《串行数据收发器课程设计.doc》由会员分享,可在线阅读,更多相关《串行数据收发器课程设计.doc(25页珍藏版)》请在冰点文库上搜索。
学号11700224
天津城建大学
EDA技术及应用
设计说明书
题目
串行数据收发器设计
起止日期:
2014年12月22日至2014年12月26日
学生姓名
杨棋焱
班级
11电信2班
成绩
指导教师(签字)
计算机与信息工程学院
天津城建大学
课程设计任务书
2012—2013学年第1学期
电子与信息工程系电子信息工程专业
课程设计名称:
EDA技术及应用
设计题目:
串行数据收发器设计
完成期限:
自2014年12月22日至2014年12月26日共1周
一.课程设计依据
在掌握常用数字电路原理和技术的基础上,利用EDA技术和硬件描述语言,EDA开发软件(QuartusⅡ)和硬件开发平台(达盛试验箱CycloneⅡFPGA)进行初步数字系统设计。
二.课程设计内容
采用状态机结构设计简易全双工串行数据收发器,串行数据收发速率为9600bit/s,数据帧为RS232标准:
1个起始位,8位数据,1位校验位,1.5位停止位。
要求把数据发送、接收结果分别在2对数码管上以16进制显示出来。
要求采用状态机或计数器设计,具有奇偶校验功能,接受错误时显示----,并编写串行数据测试程序进行仿真。
扩展设计:
采用16倍超采样频率方法,实现串行数据接收和发送。
三.课程设计要求
1. 要求独立完成设计任务。
2. 课程设计说明书封面格式要求见《天津城建大学课程设计教学工作规范》附表1
3. 课程设计的说明书要求简洁、通顺,计算正确,图纸表达内容完整、清楚、规范。
4. 测试要求:
根据题目的特点,采用相应的时序仿真或者在实验系统上观察结果。
5. 课设说明书要求:
1)说明题目的设计原理和思路、采用方法及设计流程。
2)对各子模块的功能以及各子模块之间的关系作明确的描述。
3)对实验和调试过程,仿真结果和时序图进行说明和分析。
4)包含系统框图、电路原理图、HDL设计程序、仿真测试图。
指导教师(签字):
教研室主任(签字):
批准日期:
2014年12月18日
目录
第一章设计方案 1
1.1设计原理 1
1.1.1UART介绍 1
第二章设计内容 3
2.1模块组成 3
2.2模块设计 3
2.2.1顶层模块 3
2.2.2波特率发生器 3
2.2.3UART接收器 3
2.2.4UART发送器 5
第三章实验仿真及调试 7
3.1创建工程文件 7
3.2子模块电路设计 7
3.2.1波特率发生器 7
3.2.2UART接收器 17
3.2.3其它功能模块 21
3.2.4顶层文件设计 24
3.2.5器件管脚分配 25
3.2.6硬件下载及调试 26
第四章总结 27
第一章设计方案
1.1设计原理
由任务书要求可知道全双工串行数据收发器由FPGAUART系统组成:
波特率发生器;接收模块;发送模块,本次实验通过通用异步收发器实现简易全双工串行数据收发器的设计。
图1设计总体框图
1.1.1UART介绍
UART(UniversalAsynchronousReceiverTransmitter通用异步收发器)是一种应用广泛的短距离串行传输接口。
常常用于短距离、低速、低成本的通讯中。
8250、8251、NS16450等芯片都是常见的UART器件。
基本的UART通信只需要两条信号线(RXD、TXD)就可以完成数据的相互通信,接收与发送是全双工形式。
TXD是UART发送端,为输出;RXD是UART接收端,为输入。
1.UART的基本特点是:
(1)在信号线上共有两种状态,可分别用逻辑1(高电平)和逻辑0(低电平)来区分。
在发送器空闲时,数据线应该保持在逻辑高电平状态。
(2)起始位(StartBit):
发送器是通过发送起始位而开始一个字符传送,起始位使数据线处于逻辑0状态,提示接受器数据传输即将开始。
(3)数据位(DataBits):
起始位之后就是传送数据位。
数据位一般为8位一个字节的数据(也有6位、7位的情况),低位(LSB)在前,高位(MSB)在后。
(4)校验位(parityBit):
可以认为是一个特殊的数据位。
校验位一般用来判断接收的数据位有无错误,一般是奇偶校验。
在使用中,该位常常取消。
(5)停止位:
停止位在最后,用以标志一个字符传送的结束,它对应于逻辑1状态。
(6)位时间:
即每个位的时间宽度。
起始位、数据位、校验位的位宽度是一致的,停止位有0.5位、1位、1.5位格式,一般为1位。
(7)帧:
从起始位开始到停止位结束的时间间隔称之为一帧。
(8)波特率:
UART的传送速率,用于说明数据传送的快慢。
在串行通信中,数据是按位进行传送的,因此传送速率用每秒钟传送数据位的数目来表示,称之为波特率。
如波特率9600=9600bps(位/秒)。
2.UART的数据帧格式为:
START
D0
D1
D2
D3
D4
D5
D6
D7
P
STOP
起始位
数据位
校验位
停止位
表1UART的数据帧格式表
第二章设计内容
2.1模块组成
FPGAUART系统组成:
如下图所示,FPGAUART由三个子模块组成:
波特率发生器;接收模块;发送模块。
2.2模块设计
系统由四部部分组成:
顶层模块;波特率发生器;UART接收器;UART发送器
2.2.1顶层模块
异步收发器的顶层模块由波特率发生器、UART接收器和UART发送器构成。
UART发送器的用途是将准备输出的并行数据按照基本UART帧格式转为TXD信号串行输出。
UART接收器接收RXD串行信号,并将其转化为并行数据。
波特率发生器就是专门产生一个远远高于波特率的本地时钟信号对输入RXD不断采样,使接收器与发送器保持同步。
2.2.2波特率发生器
波特率发生器实际上就是一个分频器。
可以根据给定的系统时钟频率(晶振时钟)和要求的波特率算出波特率分频因子,算出的波特率分频因子作为分频器的分频数。
波特率分频因子可以根据不同的应用需要更改。
2.2.3UART接收器
1.由于串行数据帧和接收时钟是异步的,由逻辑1转为逻辑0可以被视为一个数据帧的起始位。
然而,为了避免毛刺影响,能够得到正确的起始位信号,必须要求接收到的起始位在波特率时钟采样的过程中至少有一半都是属于逻辑0才可认定接收到的是起始位。
由于内部采样时钟bclk周期(由波特率发生器产生)是发送或接收波特率时钟频率的16倍,所以起始位需要至少8个连续bclk周期的逻辑0被接收到,才认为起始位接收到,接着数据位和奇偶校验位将每隔16个bclk周期被采样一次(即每一个波特率时钟被采样一次)。
如果起始位的确是16个bclk周期长,那么接下来的数据将在每个位的中点处被采样。
UART接收器的接收状态机:
图2UART接收器的接收状态机
接收状态机一共有5个状态:
R_START(等待起始位);R_CENTER(求中点);
R_WAIT(等待采样);R_SAMPLE(采样);R_STOP(停止位接收)。
(1)R_START状态
当UART接收器复位后,接收状态机将处于这一个状态。
在此状态,状态机一直在等待RXD的电平跳转,从逻辑1变为逻辑0,即起始位,这意味着新的一帧UART数据帧的开始,一旦起始位被确定,状态机将转入R_CENTER状态。
状态图中的RXD_SYNC信号是RXD的同步信号,因为在进行逻辑1或逻辑0判断时,不希望检测的信号是不稳定的,所以不直接检测RXD信号,而是检测经过同步后的RXD_SYNC信号。
(2)R_CENTER状态
对于异步串行信号,为了使每一次都检测到正确的位信号,而且在较后的数据位检测时累计误差较小,显然在每位的中点检测是最为理想的。
在本状态,就是由起始位求出每位的中点,通过对bclk的个数进行计数(RCNT16),但计数值不是想当然的“1000”,要考虑经过一个状态,也即经过了一个bclk周期,所希望得到的是在采样时1/2位。
另外,可能在R_START状态检测到的起始位不是真正的起始位,可能是一个偶然出现的干扰尖脉冲(负脉冲)。
这种干扰脉冲的周期是很短的,所以可以认为保持逻辑0超过1/4个位时间的信号一定是起始位。
(3)R_WAIT状态
当状态机处于这一状态,等待计满15个bclk,在第16个bclk是进入R_SAMPLE状态进行数据位的采样检测,同时也判断是否采集的数据位长度已达到数据帧的长度(FRAMELEN),如果到来,就说明停止位来临了。
FRAMELEN在设计时是可更改的(使用了Generic),在本设计中默认为8,即对应的UART工作在8位数据位、无校验位格式。
(4)R_SAMPLE状态
即数据位采样检测,完成后无条件状态机转入R_WAIT状态,等待下次数据位的到来。
(5)R_STOP状态
无论停止位是1还是1.5位,或是2位,状态机在R_STOP不具体检测RXD,只是输出帧接收完毕信号(REC_DONE<=‘1’),停止位后状态机转回到R_START状态,等待下一个帧的起始位。
2.2.4UART发送器
1.发送器只要每隔16个bclk周期输出1个数据即可,次序遵循第1位是起始位,最后一位是停止位。
在本设计中没有校验位,但只要改变Generic参数FrameLen,也可以加入校验位,停止位是固定的1位格式。
2.发送状态机
图3发送状态机的状态图
发送状态机一共有5个状态:
X_IDLE(空闲);X_START(起始位);X_WAIT(移位等待);X_SHIFT(移位);X_STOP(停止位)。
(1)X_IDLE状态:
当UART被复位信号复位后,状态机将立刻进入这一状态。
在这个状态下,UART的发送器一直在等待一个数据帧发送命令XMIT_CMD。
XMIT_CMD_P信号是对XMIT_CMD的处理,XMIT_CMD_P是一个短脉冲信号。
这时由于XMIT_CMD是一个外加信号,在FPGA之外,不可能对XMIT_CMD的脉冲宽度进行限制,如果XMIT_CMD有效在UART发完一个数据帧后仍然有效,那么就会错误地被认为,一个新的数据发送命令又到来了,UART发送器就会再次启动UART帧的发送,显然该帧的发送是错误的。
在此对XMIT_CMD进行了脉冲宽度的限定,XMIT_CMD_P就是一个处理后的信号。
当XMIT_CMD_P=‘1’,状态机转入X_START,准备发送起始位。
(2)X_START状态:
在这个状态下,UART的发送器一个位时间宽度的逻辑0信号至TXD,即起始位。
紧接着状态机转入X_WAIT状态。
XCNT16是bclk的计数器
(3)X_WAIT状态
同UART接收状态机中的R_WAIT状态类似。
(4)X_SHIFT状态
当状态机处于这一状态时,实现待发数据的并串转换。
转换完成立即回到X_WAIT状态。
(5)X_STOP
停止位发送状态,当数据帧发送完毕,状态机转入该状态,并发送16个bclk周期的逻辑1信号,即1位停止位。
状态机送完停止位后回到X_IDLE状态,并等待另一个数据帧的发送命令。
第三章实验仿真及调试
3.1创建工程文件
按照Quartus软件新建工程向导建立工程,工程名设为:
uart_test(可自行命名)。
3.2子模块电路设计
3.2.1波特率发生器
1.程序编写:
在“文件”菜单下选择“New”,在弹出的窗口点击“VHDLFile”点击“OK”打开vhdl编辑窗口。
图4vhdl窗口
编辑输入波特率发生器程序,编辑完毕后保存,文件名保存为“baud”
(注:
文件名必须与程序中实体名一致)
图5文件保存窗口
选中“Addfiletocurrentproject”选项,添加当前文件到项目。
--文件名:
baud.vhd.
--功能:
本实验想要实现的波特率为:
9600,EDA实验箱上晶振频率为:
4MHZ,
--波特率发生器的分频数计算如下式:
--4000000/(16*9600)=26
libraryIEEE
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitybaudis
generic(framlenr:
integer:
=26);
Port(clk,resetb:
instd_logic;
bclk:
outstd_logic);
endbaud;
architectureBehavioralofbaudis
begin
process(clk,resetb)
variablecnt:
integer;
begin
ifresetb='1'thencnt:
=0;bclk<='0';--复位
elsifrising_edge(clk)then
ifcnt>=framlenrthencnt:
=0;bclk<='1';--设置分频系数
elsecnt:
=cnt+1;bclk<='0';
endif;
endif;
endprocess;
endBehavioral;
2.文件编译:
保存文件后,选择“Project”菜单,点击“SetasTop-LevelEntity”项,把当前文件设置为顶层实体。
(注:
Quartus环境下所有操作(综合、编译、仿真、下载等)都只对顶层实体进行,所以编译任何程序前,必须先设置该选项,把当前要编译的文件设置为顶层实体后,才能对该文件进行编译等操作)
图6project窗口
打开“Processing”菜单,点击“StartCompilation”执行完全编译
图7编译窗口
编译结束,系统会弹出编译结束窗口,报告错误与警告数,点击“确定”。
编译报告给出所有编译结果信息,包括硬件信息、资源占用率等。
3.错误修改:
如果程序中有错误,需要根据“Messages”消息栏给出的错误提示修改程序,保存后须再次编译,直至所有错误均改正后,方可执行下一步操作。
警告信息可以忽略。
4.波形仿真:
建立波形图文件,关闭编译报告窗口,在“文件”菜单下选择“New”,选中“otherfiles”标签页,在弹出的窗口点击“VectorWaveformFile”点击“OK”打开波形编辑窗口。
图8建立波形图文件
图9波形图编辑窗口
5.定义仿真观测的输入输出节点
(1)在波形编辑窗口左侧栏内单击鼠标右键,出现浮动菜单,选择“InsertNoteorBus…”出现“InsertNoteorBus…”对话框,点击“NodeFinder…”按键,出现“NodeFinder”对话框,如下图所示。
图10“NodeFinder”对话框
(2)在图中“Filter:
”选项下选择管脚类型为“Pins:
all”,然后单击List按钮,可在左下侧区域看到设计项目中的输入输出信号,单击按钮“=〉”,将这些信号选择到“SelectedNodes”区,表示对这些信号进行观测,单击OK
图11Filter图
此时的波形编辑窗口如下图所示。
保存波形文件,文件名为uart_test.vwf(注:
扩展名默认不填,文件名与项目名同名)
图12波形编辑窗口
6.为输入信号赋值
波形编辑器窗口左侧为信号赋值工具条,根据实际要求点选工具按钮对输入信号赋值。
1)为时钟信号clk赋值:
单击clk,使其呈蓝色即选中了clk,单击为时钟信号赋值工具按钮,弹出Clock对话框,在Period框中输入合适的时钟周期数,其它值按默认即可,点击OK。
图13信号赋值工具条
2)为复位信号resetb赋值:
选中resetb,单击赋值0工具条按钮,为期赋值为逻辑0。
3)设置仿真时间
选择Edit菜单下的EndTime…选项,打开EndTime对话框,在time框内入输100单位为us。
再次保存波形文件,窗口如下
图14波形图
7.时序仿真
选择Processing菜单下的BeginSimulation选项,即开始波形仿真。
状态窗口会显示出仿真进程仿真结束后可以看到仿真结果波形,如下图所示。
观察波形可用工具条上的放大缩小按钮放大缩小波形图,下图即为已经缩小了很多倍后的波形图。
结果分析:
图上可以观察到输出端bckl等间隔的有脉冲信号输出,通过标尺可以计算出它的脉冲输出频率及其与clk输入信号的关系。
该程序实现的是波特率发生器,输出频率为时钟输入频率的1/26。
生成符号文件:
通过波形仿真可以确定程序功能是否正确后,就可以把该程序生成符号文件,以便在后面的程序中调用。
具体操作是:
打开File文件菜单,选择Creat/Updata菜单项,右侧弹出子菜单再选择CreatSymbolfilesforCurrentfile把当前文件创建成符号文件。
状态窗口有进度信息显示。
生成的符号文件可以通过打开原理图窗口调入,进行验证。
下图为生成的波特率模块。
图15生成波特率模块
按照生成波特率模块的步骤完成以下其它模块的程序编写,并进行仿真波形、功能验证,仿真通过后生成各自的符号文件。
这里只给出仿真得到的波形图。
UART发送器
UART发送器程序:
--文件名:
transfer.vhd
--功能:
UART发送器
--说明:
系统由五个状态(x_idle,x_start,x_wait,x_shift,x_stop)和一个进程构成。
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitytransferis
generic(framlent:
integer:
=8);--类属说明
Port(bclkt,resett,xmit_cmd_p:
instd_logic;--定义输入输出信号
txdbuf:
instd_logic_vector(7downto0);
txd,txd_done:
outstd_logic);
endtransfer;
architectureBehavioraloftransferis
typestatesis(x_idle,x_start,x_wait,x_shift,x_stop);--定义5个子状态
signalstate:
states:
=x_idle;
signaltcnt:
integer:
=0;
begin
process(bclkt,resett,xmit_cmd_p,txdbuf)--主控时序进程
variablexcnt16:
std_logic_vector(4downto0):
="00000";--定义中间变量
variablexbitcnt:
integer:
=0;
variabletxds:
std_logic;
begin
ifresett='1'thenstate<=x_idle;--复位,txd输出保持1
txd_done<='0';
txds:
='1';
elsifrising_edge(bclkt)then
casestateis
whenx_idle=> --状态1,等待数据帧发送命令
ifxmit_cmd_p='1'thenstate<=x_start;txd_done<='0';
elsestate<=x_idle;
endif;
whenx_start=>--状态2,发送信号至起始位
ifxcnt16="01111"thenstate<=x_shift;xcnt16:
="00000";
elsexcnt16:
=xcnt16+1;txds:
='0';state<=x_start;--输出开始位,'0'
endif;
whenx_wait=>--状态3,等待状态
ifxcnt16>="01110"then
ifxbitcnt=framlentthenstate<=x_stop;xbitcnt:
=0;xcnt16:
="00000";
elsestate<=x_shift;
endif;
xcnt16:
="00000";
elsexcnt16:
=xcnt16+1;state<=x_wait;
endif;
whenx_shift=>--状态4,将待发数据进行并串转换
txds:
=txdbuf(xbitcnt);
xbitcnt:
=xbitcnt+1;
state<=x_wait;
whenx_stop=>--状态5,停止位发送状态
ifxcnt16>="01111"then
ifxmit_cmd_p='0'thenstate<=x_idle;--高电平保持时间应低于一个帧发送的时间
xcnt16:
="00000";
elsexcnt16:
=xcnt16;state<=x_stop;
endif;
txd_done<='1';
elsexcnt16:
=xcnt16+1;txds:
='1';state<=x_stop;
endif;
whenothers=>state<=x_idle;
endcase;
endif;
txd<=txds;
endproces