自己编写的串口UART的接收Verilog模块

源代码在线查看: rxd.v

软件大小: 3 K
上传用户: edan1181
关键词: Verilog UART 编写 串口
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*
				自己编写的串口UART的接收程序,在工程应用中测试通过。
				支持中断和查询模式,基本的设计思路是:先用比波特率高16倍的速率检测串行输入数据,
				如果检测到连续的低电平,则认为收到了起始位,接着按照波特率的速率,检测输入串行数据,
				完成指定位数的数据接收后,将数据锁存在输出锁存器中(这样有一个字节的数据缓冲能力,同样也可以将数据写入外部的FIFO),
				并且产生中断信号。
				该设计对串行输入信号的畸变(经过光耦或线路的传输电容较大)的情况均能较好的适应。
				由于是初学Verilog时编写的,条理和移植性较差,但总算能正确运行,希望批评指正。liyzz99@163.com。
				
				*/
				
				module uart_rx(clk,txd,rd,check,outd,int);
					input clk;		输入时钟60mhz
					input txd;    输入串行线
					input rd;     读取接收到的数据,高有效,读取数据会使outd[9]位自动清零
					input check;       查询是否有数据接收到 在outd[9]位检测,为“1”时有数据到。
					output [9:0]outd;  输出数据
					output int;        中断输出
				reg [9:0]d;          内部数据暂存
				wire bps;            波特率计数溢出线
				reg [3:0]bps_cnt;         波特率计数器
				reg [8:0]start_check;     起始位检测移位器
				reg start;                起始位有效标记
				reg [9:0]shift;           串并转换移位器
				reg [2:0]rd_clr;          rd信号下沿延时
				reg [3:0]bit_cnt;         接收到的数据位计数器
				wire clr_out;             rd信号下沿后的清零信号
				reg [6:0]s;								16倍波特率的时钟计数器。
				wire xx;									16倍波特率的时钟计数器溢出信号
				wire end_rxd;
				assign xx = (s[6]&s[5]&s[0])?1:0;  /*(0x61+1) = 97 = 60,000,000/38400/16 */
				assign bps = (bps_cnt[3]&bps_cnt[2]&bps_cnt[1]&bps_cnt[0]&xx);	
				assign end_rxd = bit_cnt[3]&bit_cnt[0]&bps;		/*8bit data 2bit stop,如果没有校验位,则需要将个数减小到9位*/
				assign clr_out = (~rd_clr[2]&rd_clr[1]);
				assign outd = (rd|check)?d:10'bzzzzzzzzzz;
				assign int = ~d[9];
				always @(posedge(clk))
				begin
					rd_clr 					rd_clr[0] 					if(clr_out)
						d[9] 					else
						begin
						if(end_rxd)
							begin
							d[0] 							d[1] 							d[2] 							d[3] 							d[4] 							d[5] 							d[6] 							d[7] 							d[8] 							d[9] 				/*
				如果没有校验位,则程序变为。
							d[0] 							d[1] 							d[2] 							d[3] 							d[4] 							d[5] 							d[6] 							d[7] 							d[8] 							d[9] 				*/
							end
						end
					if(xx | ~start&txd)
						s 					else
						begin
						s 						end
					if(~start)
						bps_cnt 					else
						begin
						if(xx)
							bps_cnt 						end
					if(end_rxd)
						begin
						start_check 						start 						end
					else
						begin
						if(xx)
							begin
							start_check 							start_check[0] 							start 				 					  		&start_check[6]&start_check[5]
											&start_check[4]&start_check[3]
											&start_check[2]&start_check[1]
											&start_check[0]));
							end
						end
					if(~start)
						bit_cnt 					else
						begin
						if(bps)
							bit_cnt 						end	
					if(bps)
						begin
						shift 						shift[0] 						end
				end
				endmodule			

相关资源