FPGA学习之串口接收模块设计与验证 |
您所在的位置:网站首页 › vhdl串口发送模块 › FPGA学习之串口接收模块设计与验证 |
FPGA学习之串口接收模块设计与验证
1.实验目的:
实现一个串口接收,通过上位机发送数据,查看串口接收模块是否收到数据。 2.实验介绍:学习UART通信原理及其硬件电路设计,使用FPGA实现UART通信中的数据接收部分设计,并使用ISSP工具来进行板级验证。 3.实验原理在上篇串口发送模块中提到串口发送一个字节的时序图,如下图所示:
在中间时期(上图浅灰色部分)认定数据处于稳定状态,即中间采样方法,但也不能否定该期间受到干扰而产生错误电平,因此对该时段电平多次采样,本次对中间时刻采样6次,采样后对高低电平求发生概率,多次出现电平作为该位数据电平。 (1)系统框架对于实现整个串口接收模块,理解以下输入输出端口: 1.时钟Clk及复位信号Rst_n必不可少; 2.如串口发送一样,选择不同波特率信号baud_set[2:0]; 3.由串口发送得知,数据是一位位的传过来的,一次接收模块接收信号Rx232_Rx信号为1位即可; 4.数据接收完毕,应需要1个时钟周期的高脉冲Rx_Done信号; 5.接收数据组成[7:0]data_byte信号输出查看。 在按键消抖篇提到按键信号需做异步信号同步处理,同理,Rx232_Rx信号跨越时钟域时,也需做异步信号同步处理,以及如何去做边沿检测,实现具体原理在按键消抖篇已详细介绍,这里不做赘述。 与串口发送模块一致,串口接收模块的主要组成部分也是波特率时钟生成设计。 不同的是,这里接收采用单bit位16点采样,速度提升到原来的16倍,假设原来发送波特率是9600bps,现在接收波特率为9600*16=153600bps; 根据上篇串口发送波特率表格,计算得出接收模块设计分频计数值,如下表所示 当我们所需要采样时钟bps_clk已经具备了,下一步就要开始对时钟上升沿开始计数了。 还有就是起始位的检测,我们知道起始位START_BIT其实是一个持续的低电平,但是如何去判断该起始位是干扰信号而不是真正的起始位呢? 现在当数据线上出现了下降沿,假设此时是起始位,那么中间采样6次所得的计算值累加结果大于2,那么可知中间6次采样中至少有一半是高电平,不满足起始信号持续低电平要求,故可以判断此时数据线上的信号是干扰信号。(src:《FPGA系统设计与验证实战指南_V1.2》) 当我们接收到的数据经过同步处理后,最终需要传到data_byte[7:0]中,但是我们对每一位采样16次,取中间6次,因此需要中间过渡取值过程。 因此首先第一步先将10位数据的每位采样6次值累加赋给每一位,然后在与4(当出现111000,该次设计不做处理,发现1或0的次数为4次,110000,111100)比较,得出该位数据。 (1)第一步:6次采样值累加
因此在这里我们需要定义一个ram,将中间8位数据寄存,起始位和停止位单独定义,故该ram具有8位地址,而且每一位位宽是3位。
中间8位数据位如何去判断是什么数据呢?这里(src:《FPGA系统设计与验证实战指南_V1.2》)提供将高位比较,因为3(011)和4(100)会出现高位转换,因此当数据位寄存值最高位是1还是0就可以得出该位是1还是0。 1.在这里使用上篇串口发送数据模块的输出来实现产生待测模块数据的输入,因此只需要将发送模块的Rx232_Tx连接到接收模块上的Rx232_Rx上即可。 //-------------------------------------------------------------------------------------------- // Component name : uart_rx_tb // Author : 硬件嘟嘟嘟 // time : 2020.04.23 // Description : 串口发送模块 // src : FPGA系统设计与验证实战指南_V1.2 //-------------------------------------------------------------------------------------------- `timescale 1ns/1ns `define clk_period 20 module uart_rx_tb; reg Clk; reg Rst_n; wire [7:0]data_byte_r; wire Rx_Done; reg [7:0]data_byte_t; reg send_en; reg [2:0]baud_set; wire Rx232_Tx; wire Tx_Done; wire uart_state; uart_rx uart_rx( .Clk(Clk), .Rst_n(Rst_n), .baud_set(baud_set), .Rx232_Rx(Rx232_Tx), .data_byte(data_byte_r), .Rx_Done(Rx_Done) ); uart_tx uart_tx( .Clk(Clk), .Rst_n(Rst_n), .data_byte(data_byte_t), .send_en(send_en), .baud_set(baud_set), .Rx232_Tx(Rx232_Tx), .Tx_Done(Tx_Done), .uart_state(uart_state) ); initial Clk = 1; always#(`clk_period/2)Clk = ~Clk; initial begin Rst_n = 1'b0; data_byte_t = 8'd0; send_en = 1'd0; baud_set = 3'd4; #(`clk_period*20 + 1 ); Rst_n = 1'b1; #(`clk_period*50); data_byte_t = 8'hbb; send_en = 1'd1; #`clk_period; send_en = 1'd0; @(posedge Tx_Done) #(`clk_period*5000); data_byte_t = 8'h66; send_en = 1'd1; #`clk_period; send_en = 1'd0; @(posedge Tx_Done) #(`clk_period*5000); $stop; end endmodule在功能仿真中查看波形输出是否与设计一致 在ISSP中能够正确读到串口所发信息。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |