UART

1 篇文章 0 订阅

uart_rx

`define		NONE					0
`define		ODD					1
`define		SEVEN					2
`define		SPACE					3
`define		MARK					4
			
`define		STOP_ONE				0
`define		STOP_ONEHALF		1
`define		STOP_TWO				2

module uart_rx
#(	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	[DATABITS-1:0]		data,
output	reg				err,
output	reg				done				//回复接受完毕
);
reg	[2:0]		rx_r;
always@(posedge clk or posedge rst)
	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
		
reg	flag;
always@(posedge clk or posedge rst)
	if(rst)
		flag<=0;
else if((cstate==FSM_START&&sampling&&rx_r[2]==1)||(cstate==FSM_STOP&&sampling))
		flag<=0;
	else if(rx_r[2:1]==2'b10)
		flag<=1;
	else
		flag<=flag;
		
reg		[12:0]	cnt;
always@(posedge clk or posedge rst)
	if(rst)
		cnt<=0;
	else if(flag==0 || cnt==CLK/BAUD)
		cnt<=0;
	else if(flag==1)
		cnt<=cnt+1;

reg		sampling;
always@(posedge clk or posedge rst)
	if(rst)
		sampling<=0;
	else if(cnt==(CLK/BAUD>>1))
		sampling<=1;
	else
		sampling<=0;
		
//状态机
localparam 		FSM_IDEL				=0,
					FSM_START			=1,
					FSM_DATA				=2,
					FSM_PARITY			=3,
					FSM_STOP				=4;
					
reg	[2:0]		cstate;
reg	[3:0]		number=0;

always@(posedge clk or posedge rst)
	if(rst)
		begin
			cstate<=FSM_IDEL;
			err<=0;
			done<=0;
			number<=0;
			data<=0;
		end
	else
		case(cstate)
			FSM_IDEL		:		begin
										done<=0;
										if(flag)	
											cstate<=FSM_START;
										else
											cstate<=FSM_IDEL;
									end
										
         FSM_START	:		if(sampling)
										if(rx_r[2]==0)
											cstate<=FSM_DATA;
										else
											cstate<=FSM_IDEL;
									else
										cstate<=FSM_START;
										
         FSM_DATA		:		if(sampling&&number<DATABITS)
										begin
											data[number]<=rx_r[2];
											number<=number+1;
										end
									else if(number==DATABITS)
										begin
											number<=0;
											if(ifparity==0)
												cstate<=FSM_STOP;
											else if(ifparity)
												cstate<=FSM_PARITY;
										end
									else
										cstate<=FSM_DATA;
										
         FSM_PARITY	:		if(sampling)
										begin
											cstate<=FSM_STOP;
											if(parity_value==rx_r[2])
												err<=0;
											else
												err<=1;
										end
									else
										cstate<=FSM_PARITY;
										
         FSM_STOP		:		if(sampling)
										begin
											done<=1;
											if(rx_r[2])
												cstate<=FSM_IDEL;
											else
												err<=1;
										end
									else
										cstate<=FSM_STOP;	
									
			default		:		begin
										cstate<=FSM_IDEL;
										err<=0;
										done<=0;
										number<=0;
										data<=0;
									end
										
		endcase

reg	parity_value;
reg	ifparity;		
		
always@(*)
	if(rst)
		begin
			parity_value=0;
			ifparity=0;
		end
	else
		case(PARITY)
			`NONE	:		begin
								parity_value=0;
								ifparity=0;
							end
							
        `ODD	:		begin
								parity_value=~(^data);
								ifparity=1;
							end
							
        `SEVEN	:		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=0;
							end
		
		endcase



endmodule 

uart_tx

下面展示一些 内联代码片

`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_tx
#(
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	[DATABITS-1:0]		data,
input	wire							enable,

output	reg						tx,
output	reg						busy //在发送数据的过程中,不接受新的发送任务
);
//缓存外部传输数据
reg	[DATABITS-1:0]		data_r;
reg	[3:0]		number=0;
always@(posedge clk or posedge rst)
	if(rst)
		data_r<=0;
	else if(enable && busy==0)
		data_r<=data;
	else
		data_r<=data_r;

reg	[13:0]	cnt;
localparam		CNT_MAX=CLK/BAUD-1;
always@(posedge clk or posedge rst)
	if(rst)
		cnt<=0;
	else if(cnt==CNT_MAX ||	busy==0	)
		cnt<=0;
	else if(busy==1)
		cnt<=cnt+1;
	else
		cnt<=cnt;
			
localparam 	FSM_IDEL			=0,
				FSM_START		=1,
				FSM_DATA			=2,
				FSM_PARITY		=3,
				FSM_STOP			=4;

reg		[2:0]		cstate;
reg		stop=0;
always@(posedge clk or posedge rst)
	if(rst)
		begin
			cstate<=FSM_IDEL;
			tx<=1;
			number<=0;
			busy<=0;
			stop<=0;
		end
	else
		case(cstate)
			FSM_IDEL		:		begin
										tx<=1;
										if(enable)
											begin
												busy<=1;
												cstate<=FSM_START;
											end
										else
											cstate<=FSM_IDEL;
									end
						
			FSM_START	:		begin	
										tx<=0;
										if(cnt==CNT_MAX)
											cstate<=FSM_DATA;
										else
											cstate<=FSM_START;
									end
										
			FSM_DATA		:		begin
										tx<=data_r[number];
										if(cnt==CNT_MAX && number<(DATABITS-1))
											number<=number+1;
										else if(number==(DATABITS-1) && cnt==CNT_MAX)
											begin
												number<=0;
												if(!ifparity)
													cstate<=FSM_STOP;
												else
													cstate<=FSM_PARITY;
											end
										else
											begin
												cstate<=FSM_DATA;
												number<=number;
											end
									end
									
			FSM_PARITY	:		begin
										tx<=parity_value;
										if(cnt==CNT_MAX)
											cstate<=FSM_STOP;
										else
											cstate<=FSM_PARITY;
									end
									
			FSM_STOP		:		begin
										tx<=1;
										if(STOPBITS==`STOP_ONE)
											begin
												if(cnt==CNT_MAX)
													begin
														busy<=0;
														cstate<=FSM_IDEL;
													end
												else
													cstate<=FSM_STOP;
											end
										else if(STOPBITS==`STOP_ONEHALF)
											begin
												if(stop==0&&cnt==CNT_MAX)
													stop<=1;
												else if(stop==1 && cnt<=(CNT_MAX>>1))		
													begin
														stop<=0;
														busy<=0;
														cstate<=FSM_IDEL;
													end	
												else
													cstate<=FSM_STOP;
											end
										else if(STOPBITS==`STOP_TWO)
											begin
												if(stop==0&&cnt==CNT_MAX)
													stop<=1;
												else if(stop==1 && cnt<=CNT_MAX)		
													begin
														stop<=0;
														busy<=0;
														cstate<=FSM_IDEL;
													end	
												else
													cstate<=FSM_STOP;
											end	
									end
			
			default		:		begin
										cstate<=FSM_IDEL;
										tx<=1;
										number<=0;
										busy<=0;
										stop<=0;
									end
									
		endcase	
		
reg	ifparity;		//是否有校验位
reg	parity_value;	//校验位的值			
			
always@(*)			
	if(rst)
		begin 
			ifparity=0;
			parity_value=0;
		end
	else
		case(PARITY)
			`NONE		:		begin 
									ifparity=0;
									parity_value=0;
								end
								
			`ODD		:		begin 
									ifparity=1;
									parity_value=~(^data_r);
								end
								
			`EVEN		:		begin 
									ifparity=1;
									parity_value=^data_r;
								end
								
			`SPACE	:		begin 
									ifparity=1;
									parity_value=0;
								end
								
			`MARK		:		begin 
									ifparity=1;
									parity_value=1;
								end
								
			default	:		begin 
									ifparity=0;
									parity_value=0;
								end
		endcase
endmodule 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值