fpga领域--uart异步串行通信--uart接收模块1

4 篇文章 0 订阅
3 篇文章 0 订阅

uart rx 接收(rx)模块
第一部分 接收模块
第二部分 数码管显示
第三部分 顶层调用

结合图片理解

//uart       接收模块
// 宏定义 校验位
`define     NONE           				    0
`define     ODD             				1
`define     EVEN            				2
`define     SPACE         				    3
`define     MARK          			   	    4
//宏定义停止位
`define      STOP_ONE              0
`define      STOP_ONEHALF          1
`define       STOP_TWO             2


module  uart_rx2 
#(
parameter           CLK             =50_000_000,     //时钟
parameter           BAUD            =9600,           //波特率
parameter           DATABITS        = 8,             //数据位
parameter           PARITY          = `NONE ,        //校验情况
parameter           STOPBITS        =`STOP_ONE      //停止位数量
)
(
input               wire           clk,
input               wire            rst,
input               wire            rx,
output             reg            done,                            //接收完成,输出信号
output            reg             err,                             // 错误输出
output            reg  [DATABITS  -1:0]   data      //数据位个数
);
//*****************************************************************
reg       [31:0 ]    cnt;
reg       [2:0]      rx_r;
reg                     flag;                         //定义检测开始时,信号拉起
reg            sampling;                        //采样信号
wire               enable;                       // 边沿检测信号
reg  [3:0]           num;                       //数据位个数变量
reg  [2:0]        cstate;					    // 状态变量
reg           	  databit;                     //检测到第一位数据
localparam            cnt_max=CLK /BAUD ;      //接收数据的时钟周期 
localparam     fsm_idel         =0;
localparam     fsm_start        =1;
localparam     fsm_data        =2;
localparam     fsm_parity      =3;
localparam     fsm_stop        =4;

//******************************************************************

// 边沿检测,寄存两拍
always@(posedge clk or posedge rst) begin
	if(rst)
			rx_r<=0;
	else  begin
			rx_r[1:0]<={rx_r[0] , rx };
			rx_r[2:1]<={rx_r[1] , rx_r[0]};
	end
	end

	assign enable=(rx_r[2:1]== 2'b10) ? 1 :0;  
	
//拉起信号
always@(posedge clk or posedge rst) begin
	if(rst)
		  flag<=0;
    else  if(sampling  && cstate==fsm_stop) 
		  flag<=0;
	else if(enable)
		 flag<=1;
	else
		 flag<=flag;
end		  

//取值信号
always@(posedge clk or posedge rst) begin
	if(rst)
		sampling<=0;
	else if(cnt==cnt_max>>1)
		sampling<=1;
	else
		sampling<=0;
end

//计数器
always@(posedge clk or posedge rst) begin
	if(rst)
		cnt<=0;
	else if(flag==0 || cnt==cnt_max-1)
		cnt<=0;
	else if(flag)
		cnt<=cnt+1;
end
//状态的输出,转移和判断
always@(posedge clk or posedge rst) begin
	if(rst) begin
		cstate<=fsm_idel;
		err<=0;
		done<=0;
	end
	else
			case(cstate)
						fsm_idel                   :                 begin
																				err<=0;
																				done<=0;
																				if (flag)
																					cstate<=fsm_start;
																				else
																					cstate<=fsm_idel;
						                                                     end
						fsm_start                   :                 begin
																				if (sampling) begin
																						databit=rx;
																				        if(databit)
																							cstate<=fsm_idel;
																						else
																					        cstate<=fsm_data;
																				        end
																				else
																					        cstate<=fsm_start;
						                                                        end
						fsm_data                  :                 begin
																				if (sampling && num<=DATABITS   -1)  
																				     begin
																				            data[num]<=rx;
																							num<=num+1;
																					  end
																				else  if (num==DATABITS  ) begin
																					        cstate<=ifparity ? fsm_parity : fsm_stop;
																							num<=0;
																				  end
																				 else
																							cstate<=fsm_data;
						                                                        end
						fsm_parity                 :                     begin
																					if(sampling) begin
																					        cstate<=fsm_stop;
																							if(parity_value==rx)
																								err<=0;
																							else
																					  			err<=1;
																							end
																					else
																							cstate<=fsm_parity;
																					end
						                                                          
						fsm_stop                   :                  begin
																					if(sampling ) begin
																						done<=1;
																						if(rx)
																						    cstate<=fsm_idel;
																						else
																							err<=1;
																					end	
																					else
																						cstate<=fsm_stop;
																			   end
						
						
						default                        :           cstate<=fsm_idel;
	
					endcase
	end
	
	reg           parity_value;      //检验位的值
	reg           ifparity;              //有无校验位
	always@(*) begin
	 if(rst)
				parity_value=0;
	 else
				case(PARITY  )
						`NONE             :begin          parity_value=0 ;  ifparity=0;         end
						`ODD              :begin          parity_value=~(^data);ifparity=1 ; end
					    `EVEN             :begin          parity_value=^data; ifparity=1;      end
					   `SPACE             :begin          parity_value=0;ifparity=1;              end
					   `MARK              :begin          parity_value=1;ifparity=1;              end
					   default            :begin          parity_value=0;ifparity=1;              end
				endcase	
	
	end
		endmodule    
	
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值