EDA综合课程设计实验报告

更新时间:2024-06-19 05:05:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

EDA综合课程设计实验报告

题 目:设计一个全双工院 系:学 号:姓 名:教 师:时 间:

UART电路 XXXX学院 XXXXX 严XX 林XX 2012.06.02

1 课程设计的摘要原理 ..................................................................... 2 2 设计一个全双工UART电路,具体要求如下: ........................... 6 3. UART设计 .................................................................................. 7 3.1 UART结构 ........................................................................... 7 3.2 UART的帧格式 .................................................................... 8 4 UART的Verilog HDL语言设计 ................................................... 9 4.1 UART分频器 .......................................................................... 9 4.2UART发送模块...................................................................... 10 4.3 UART的接收模块 ................................................................. 14 4.4 UART的硬件测试 ................................................................. 18 5 课程设计总结 ................................................................................ 19

1摘 要

UART协议是数据通信及控制系统中广泛使用的一种全双工串行数据传输协议,在实际工业生产中有时并不使用UART的全部功能。只需将其核心功能集成即可。波特率发生器、接收器和发送器是UART的三个核心功能模块,利用Vefilog-HDL语言对这三个功能模块进行描述并加以整合UART(即Universal AsynchronousReceiver Transmitter 通用异步收发器)是广泛使用的串行数据传输协议。UART允许在串行链路上进行全双工的通信。串行外设用到RS232-C异步串行接口,一般采用专用的集成电路即UART实现。如8250、8251、NS16450等芯片都是常见的UART器件,这类芯片已经相当复杂,有的含有许多辅助的模块(如FIFO),有时我们不需要使用完整的UART的功能和这些辅助功能。或者设计上用到了FPGA/CPLD器件,那么我们就可以将所需要的UART功能集成到FPGA内部。使用VHDL或Veriolog -HDL将UART的核心功能集成,从而使整个设计更加紧凑、稳定且可靠。本文应用EDA技术,基于FPGA/CPLD器件设计与实现UART。

实际应用上,有时我们不需要使用完整的UART的功能和这些辅助功能。使用Verilog-HDL将所需要的UART的核心功能集成到FPGA/CPLD内部,就可以实现紧凑、稳定且可靠的UART数据传输。这样,既可以满足实际的应用,实现所要求的简单的通信和控制,又能够去除更多不需要的繁杂复杂的功能实现。

一、UART的原理

串行通信是指外部设备和计算机间使用一根数据线(另外需要地线,可能还需要控制线)进行数据传输的方式。数据在一根数据线上一位一位传输,每一位数据都占据一个固定的时间长度。与并行通信方式相比,串行通信方式的传输速度较慢,但这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,因此得到了广泛的应用。

基本的UART只需要发送和接收两条数据线就可以完成数据的全双工通信,其基本功能是在发送端将控制器通过总线传过来的并行数据,以设定的格式,设定的频率串行地传输出去,并同时在接收端将串行接收到的数据,转换成相应的并行数据发送出去。UART的基本帧格式如图1所示。其中,起始位总是逻辑O状态,停止位总是逻辑l状态,其持续时间可选为1位、1.5位或2位,其数据位可为5、6、7、8位,校验位可根据需要选择奇校验位,偶校验位或无校验位。

二、URAT整体结构的设计

2 设计一个全双工UART电路,具体要求如下:

1)

支持数据格式:起始位(1bit)+数据(8bit)+奇偶校验位(1bit)

+终止位(1bit) 2) 3) 4)

奇/偶校验可配置

可配置支持115200以下的常见波特率

支持115200以下的波特率自适应,自适应过程如下:

a. 复位后,UART首先接收输入,不断自动调整波特率,直到以一定波特率正确连续接收到3个bytes的0x55

b. 接着UART以此波特率连续发送3个bytes 0xaa c. 之后两端以此波特率进行通信

d. 波特率自适应只在电路复位后进行一次,如欲再次自适应波特率应对电路再次复位

e. 波特率自适应过程中不能对UART的波特率作任何设置,自适应完成后可以对波特率作设置 5)

自动计算校验位用于发送数据;对接收到的校验位和数据进行校验,

发现错误应设置错误标志,并丢弃数据 6)

对接收不正常数据(如无终止位、无校验位、数据位数不正确等)应能自动识别并设置错误

标志、丢弃

3. UART设计

通常设计数字电路大都采用自顶向下将系统按功能逐层分割的层次化设计方法,这

比传统自下向上的EDA设计方法有更明显的优势(当时的主要设计文件是电路图)。因为由自顶向下的设计过程可以看出,从总体行为设计开始到最终逻辑综合,形成网络表为止。每一步都要进行仿真检查,这样有利于尽早发现系统设计中存在的问题,从而可以大大缩短系统硬件的设计周期。

UART(即Universal Asynchronous Receiver Transmitter 通用异步收发器)是一种应用广泛的短距离串行传输接口。UART允许在串行链路上进行全双工的通信。串行外设用到的RS232-C异步串行接口,一般采用专用的集成电路即UART实现。如8250、8251、NS16450等芯片都是常见的UART器件,这类芯片已经相当复杂,有的含有许多辅助的模块(如FIFO),有时我们不需要使用完整的UART的功能和这些辅助功能。或者设计上用到了FPGA/CPLD器件,那么我们就可以将所需要的UART功能集成到FPGA内部。使用VHDL将UART的核心功能集成,从而使整个设计更加紧凑、稳定且可靠。本文应用EDA技术,基于FPGA/CPLD器件设计与实现UART。

3.1 UART结构

UART主要有由数据总线接口、控制逻辑、波特率发生器、发送部分和接收部分等组成。本设计主要设计UART中最重要的发送部分和接收部分 ,结构如下图1

3.2 UART的帧格式

UART的帧格式如图2所示。

发送数据过程:空闲状态,线路处于高电位;当收到发送数据指令后,拉低线路一

个数据位的时间T,接着数据按低位到高位依次发送,数据发送完毕后,接着发送奇偶校验位和停止位(停止位为高电位),一帧资料发送结束。

接收数据过程:空闲状态,线路处于高电位;当检测到线路的下降沿(线路电位由高电位变为低电位)时说明线路有数据传输,按照约定的波特率从低位到高位接收数据,数据接收完毕后,接着接收并比较奇偶校验位是否正确,如果正确则通知后续设备准备接收数据或存入缓存。

UART是异步传输,没有传输同步时钟。为了能保证数据传输的正确性,UART采用16倍数据波特率的时钟进行采样。每个数据有16个时钟采样,取中间的采样值,以保证采样不会滑码或误码。一般UART一帧的数据位数为8,这样即使每个数据有一个时钟的误差,接收端也能正确地采样到数据。

UART的接收数据时序为:当检测到数据的下降沿时,表明线路上有数据进行传输,这时计数器CNT开始计数,当计数器为24=16+8时,采样的值为第0位数据;当计数器的值为40时,采样的值为第1位数据,依此类推,进行后面6个数据的采样。如果需要进行奇偶校验,则当计数器的值为152时,采样的值即为奇偶位;当计数器的值为168时,采样的值为“1”表示停止位,一帧数据接收完成。

4 UART的Verilog HDL语言设计

4.1 UART分频器

假设数据的波特率为p,则所需时钟的频率为16*p。以波特率p为115200为例,系统时钟为50MHz,则分频系数为50000000/(16*115200) = 27.127,取整为27。分频器Verilog HDL语言代码如下:

module clkdiv(clk, clkout); input clk; //系统时钟 output clkout; //采样时钟输出 reg clkout; reg [15:0] cnt;

always @(posedge clk) //分频进程 begin

if(cnt == 16'd12) begin

clkout <= 1'b1; cnt <= cnt + 16'd1; end

else if(cnt == 16'd26) begin

clkout <= 1'b0; cnt <= 16'd0; end else begin

cnt <= cnt + 16'd1; end end endmodule

对此进行仿真,加入输入输出信号,设置系统时钟信号clk的周期为20ns。

仿真波形图如下图3:

4.2UART发送模块

UART发送模块的功能:接收到发送指令后,把数据按UART协议输出,先输出一个低电平的起始位,然后从低到高输出8个数据位,接着是可选的奇偶校验位,最后是高电平的停止位。Verilog HDL语言代码如下:

module uarttx(clk, datain, wrsig, idle, tx); input clk; //UART时钟 input [7:0] datain; //需要发送的数据

input wrsig; //发送命令,上升沿有效

output idle; //线路状态指示,高为线路忙,低为线路空闲 output tx; //发送数据信号 reg idle, tx;

reg send;

reg wrsigbuf, wrsigrise; reg presult;

reg[7:0] cnt; //计数器 parameter paritymode = 1'b0; //检测发送命令是否有效 always @(posedge clk) begin

wrsigbuf <= wrsig;

wrsigrise <= (~wrsigbuf) & wrsig; end

always @(posedge clk) begin

if (wrsigrise && (~idle)) //当发送命令有效且线路为空闲时,启动新的数据发送进程 begin

send <= 1'b1;

end

else if(cnt == 8'd176) //一帧资料发送结束 begin

send <= 1'b0; end end

always @(posedge clk) begin

if(send == 1'b1)

begin

case(cnt) //产生起始位 8'd0: begin tx <= 1'b0; idle <= 1'b1; cnt <= cnt + 8'd1; end

8'd16: begin

tx <= datain[0]; //发送数据0位 presult <= datain[0]^paritymode; idle <= 1'b1; cnt <= cnt + 8'd1; end

8'd32: begin

tx <= datain[1]; //发送数据1位 presult <= datain[1]^presult; idle <= 1'b1;

cnt <= cnt + 8'd1;

end 8'd48: begin

tx <= datain[2]; //发送数据2位 presult <= datain[2]^presult; idle <= 1'b1;

cnt <= cnt + 8'd1; end 8'd64:

begin

tx <= datain[3]; //发送数据3位 presult <= datain[3]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd80: begin

tx <= datain[4]; //发送数据4位 presult <= datain[4]^presult; idle <= 1'b1;

cnt <= cnt + 8'd1; end 8'd96:

begin

tx <= datain[5]; //发送数据5位 presult <= datain[5]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end

8'd112: begin

tx <= datain[6]; //发送数据6位 presult <= datain[6]^presult; idle <= 1'b1;

cnt <= cnt + 8'd1; end 8'd128:

begin

tx <= datain[7]; //发送数据7位 presult <= datain[7]^presult; idle <= 1'b1;

cnt <= cnt + 8'd1; end 8'd144:

begin

tx <= presult; //发送奇偶校验位 presult <= datain[0]^paritymode; idle <= 1'b1;

cnt <= cnt + 8'd1; end 8'd160:

begin

tx <= 1'b1; //发送停止位 idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd176: begin

tx <= 1'b1;

idle <= 1'b0; //一帧资料发送结束 cnt <= cnt + 8'd1;

end

default: begin

cnt <= cnt + 8'd1; end endcase end else begin tx <= 1'b1; cnt <= 8'd0; idle <= 1'b0; end end endmodule

为了测试UART发送模块的正确性,需要编写一个测试模块来测试UART发送模块, Verilog HDL语言代码如下:

module testuart(clk, dataout, wrsig); input clk;

output[7:0] dataout; output wrsig;

reg [7:0] dataout; reg wrsig; reg [7:0] cnt;

always @(posedge clk) begin

if(cnt == 254) begin

dataout <= dataout + 8'd1; //每次数据加“1” wrsig <= 1'b1; //产生发送命令 cnt <= 8'd0; end else begin

wrsig <= 1'b0; cnt <= cnt + 8'd1; end end

endmodule

将发送模块和测试模块生成原理图模块和频率长生模块连接成发送模块电路图,如下图4:

得到的仿真图如下图5

波形仿真报告说明:

对图,当发送命令wrsig的上升沿有效时,启动发送数据。串行数据的波形与发送数据dataout相一致,UART的发送模块得到正确验证。

4.3 UART的接收模块

UART接收模块的功能:时时检测线路,当线路产生下降沿时,即认为线路有数据传输,启动接收数据进程进行接收,按从低位到高位接收数据。UART接收模块的Verilog HDL语言代码如下:

module uartrx(clk, rx, dataout, rdsig, dataerror, frameerror); input clk; //采样时钟

input rx; //UART数据输入 output dataout; //接收数据输出

output rdsig;

output dataerror; //资料出错指示 output frameerror; //帧出错指示 reg[7:0] dataout; reg rdsig, dataerror; reg frameerror; reg [7:0] cnt;

reg rxbuf, rxfall, receive;

parameter paritymode = 1'b0;

reg presult, idle;

always @(posedge clk) //检测线路的下降沿 begin

rxbuf <= rx;

rxfall <= rxbuf & (~rx); end

always @(posedge clk)

begin

if (rxfall && (~idle)) //检测到线路的下降沿并且原先线路为空闲,启动接收数据进程 begin

receive <= 1'b1;

end

else if(cnt == 8'd175) //接收数据完成 begin

receive <= 1'b0; end

end

always @(posedge clk) begin

if(receive == 1'b1) begin case (cnt) 8'd0:

begin

idle <= 1'b1; cnt <= cnt + 8'd1; rdsig <= 1'b0;

end

8'd24: //接收第0位数据 begin idle <= 1'b1; dataout[0] <= rx;

presult <= paritymode^rx; cnt <= cnt + 8'd1; rdsig <= 1'b0;

end

8'd40: //接收第1位数据 begin

idle <= 1'b1;

dataout[1] <= rx; presult <= presult^rx; cnt <= cnt + 8'd1; rdsig <= 1'b0; end

8'd56: //接收第2位数据 begin

idle <= 1'b1;

dataout[2] <= rx;

presult <= presult^rx; cnt <= cnt + 8'd1; rdsig <= 1'b0;

end

8'd72: //接收第3位数据 begin idle <= 1'b1; dataout[3] <= rx; presult <= presult^rx; cnt <= cnt + 8'd1; rdsig <= 1'b0; end

8'd88: //接收第4位数据 begin

idle <= 1'b1;

dataout[4] <= rx;

presult <= presult^rx; cnt <= cnt + 8'd1; rdsig <= 1'b0;

end

8'd104: //接收第5位数据 begin

idle <= 1'b1; dataout[5] <= rx; presult <= presult^rx; cnt <= cnt + 8'd1; rdsig <= 1'b0;

end

8'd120: //接收第6位数据 begin

idle <= 1'b1;

dataout[6] <= rx;

presult <= presult^rx; cnt <= cnt + 8'd1; rdsig <= 1'b0; end

8'd136: //接收第7位数据 begin

idle <= 1'b1;

dataout[7] <= rx; presult <= presult^rx; cnt <= cnt + 8'd1; rdsig <= 1'b1;

end

8'd152: //接收奇偶校验位 begin

idle <= 1'b1;

if(presult == rx) dataerror <= 1'b0; else

dataerror <= 1'b1; //如果奇偶校验位不对,表示数据出错 cnt <= cnt + 8'd1; rdsig <= 1'b1; end 8'd168: begin

idle <= 1'b1; if(1'b1 == rx)

frameerror <= 1'b0; else

frameerror <= 1'b1; //如果没有接收到停止位,表示帧出错 cnt <= cnt + 8'd1; rdsig <= 1'b1; end default:

begin

cnt <= cnt + 8'd1; end endcase end else begin

cnt <= 8'd0; idle <= 1'b0; rdsig <= 1'b0;

end end

endmodule

为接收模块生成原理图模块。并和前面的模块构成接收模块。连接图如下图6:

对其进行UART数据接收的波形仿真,波形仿真报告如图下图所示。

波形仿真报告说明:

对图分析看出,UART接收模块接收到的数据与UART发送模块发送的数据相一至,每接收到一个数据都有一个读取数据指示rdisg,UART接收模块得到正确验证。

4.4 UART的硬件测试

为了测试UART与PC通信的正确性,本例测试方法是,PC将数据发送到FPGA,FPGA接收到数据再发送给PC。FPGA与PC通信模块连接原理图如图8所示。

连接硬件电路图,配置硬件管脚,进行硬件烧录,完成后借助串口助手进行调试通讯。

5 课程设计总结

刚开始做课程设计的时候,看到这个设计题目根本无从着手,只能从最基本的开始,开始查找什么是全双工UART电路,再去研究UART的原理和它的结构设计,慢慢的开始有了设计的整体思路,在开始编写顶层文件程序时,遇到了不少问题,特别是各个元件之间的连接,以及信号的定义,总是有错误,在和同学不断的讨论和请教老师,终于找到了错误和警告。在波形仿真的时候也是遇到了一些困难,想要的结果不能在波形上得到正确的显示,在多次的调试之后,才发现是因为输入的时钟信号对于器件的演示时间来说太短了。在连接各个模块的时候一定要注意各个输入、输出的线宽,因为每个线宽是不一样的,只要让各个线宽相互匹配,才能得到正确的结果,否则,出现很小的误差就会导致整个文件系统的编译出现错误提示。通过这次课程设计使我懂得了理论与实践结合的重要性,只有理论知识是远远不够的,只有把所学的理论知识和实践相结合,才能真正为社会服务,从而提高自己的动手能力和独立思考能力。

本文来源:https://www.bwwdw.com/article/yke3.html

Top