关于上FPGA的UART的调试课程这回事,感觉这学期开了Verilog之后代码已经深深融入菜春春的血液中,在学期结束后我会总结这学期一整个学习过程和博客,如果想求完整工程的请见我网页资料下载(让孩子赚点积分),因为下学期还要学习在FPGA上搭建CPU(俊良哥哥yyds),所以博客有可能会一直更新。
- 思路&原理&代码&仿真
- 原理:
1、FIFO仿真理解:
观察输入和输出,可以得到:
2、整体URAT数据原理:
RX取位置的时候在中间取位置。TX发送的时候在边沿发送。
- 思路:
0、总体实现状态图:
1、顶层模块:
顶层模块只输入UART_RX,时钟clk以及复位rst_n,输出UART_TX,并调用假顶层,但并不在顶层模块进行连接。
2、假顶层模块:
假顶层模块中使用了四个子模块,分别是RX,rx_fifo,TX,tx_fifo。流程大概为数据从UART_RX接收,传入RX的子模块,然后进入rx_fifo的子模块,再从rx_fifo,进入tx_fifo,然后进入TX子模块完成数据的发送。
3、RX:
功能为拆解发送数据,拆为开始位,数据位,校验位,停止位四个位,然后将数据位(8)位进行打包处理,通过data_out将数据传送进rx_fifo,同时还要实现矫错:
·关于校验位的矫错,区分奇数校验模式和偶数校验模式,然后看是否校验位正确。
·关于噪音的矫错,当下降沿来了之后并非是数据传输而是噪声,需要进行延时检验来矫正错误。
计数器:
状态机:
4、rx_fifo:
收到RX发送的数据后,根据两个使能端,wr_en&rd_en,进行控制,当有数的时候,即valid为1,则读使能为1开始进行读取并将数据传入tx_fifo,写使能收到RX传入的5、receive_valid控制,如果此时RX接收完成就开启wr使能。需要注意的是!此时如果需要对rx_fifo中的数据进行处理,即并不直接传入tx,则需要更改rd_en,使其不仅仅受valid的控制。
5、tx_fifo:
原理与rx_fifo几乎相同,不同的地方是,其写使能端收到rx_fifo的读控制,即rx_fifo在读的时候将数据写入tx_fifo,同时其读使能受TX的busy和tx_fifo的valid的共同控制。
6、TX:
发送数据,功能为打包发送数据,打包开始位,数据位,校验位,停止位四个位,然后将传入的8位数据进行分装处理,通过UART_TX将数据发送出去。
在代码的编写里,我利用了让其计数器和状态机合在一起的写法。
二、实现和检验
基础功能:
将假顶层中tx_fifo的输入数据写死为8’d1,打开wr的使能写为1.
当校验位为none的时候
打开串口助手可以得到:
当校验位为奇数校验或者偶数校验的时候,可以得到同样的结果,证明正确。
进阶功能:
发数和收数:
得到正确的结果,并且S=R,证明正确。
三、注意事项和思考
这次遇到了一个问题:首先是在写状态三校验位的时候,出现了第一个数收不到的情况,经过多次尝试,发现是当含1为偶的数变为含1为奇的数就会产生丢包现象,经过分析,发现是
将even_bit和odd_bit的计算写到了判断后,意味着此时利用even_bit的判断的值仍为上一时刻的值,即上一个数的校验,因此是不对的,将其改为
发现此时结果正确,每个时钟沿都计算even_bit和odd_bit,这样可以及时更新。