串口通信USART接收程序

使用Verilog代码编写的串口接收程序:

数据位8位,停止位1位,校验位没有,流控没有

波特率由波特率模块生成

串口时序大致如下图所示:


module uart_recv(GClk,clk_bps,reset,rx_en,Rxd,datain,rx_ok);
input GClk,clk_bps,reset,rx_en,Rxd;
output [7:0]datain;
output rx_ok;
//neg_rx:__/\______________________________
//rx_ok:_________________________________/^\_
//rx_en:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//RxAv:____/^^^^^^^^^^^^^^^^^^^^^^^^^^^^\___

wire clk_bps;
reg [7:0]data;//接收数据缓存
reg [7:0]data_temp;
reg rx_ok;
reg [3:0]BitPos;//结构位置定义
/*  捕获rx的下降沿,即起始信号  */
reg rx0,rx1,rx2;          
always@(posedge GClk or negedge reset)
begin
if(!reset) begin
rx0<=1'b0;
rx1<=1'b0;
rx2<=1'b0;
end else begin
rx0<=Rxd;
rx1<=rx0;
rx2<=rx1;
end
end

wire neg_rx;   //表示数据线接收到下降沿
assign neg_rx = (rx2 & rx1 & !rx0 & !Rxd);
//neg_rx:________/\________

wire RxAv;//接收有效
reg RxAv1;//接收有效控制使能
always @(posedge GClk or negedge reset)
begin
if(!reset)//当接收寄存器读时,位有效信号复位
RxAv1 <= 1'b0;
else if(neg_rx)//接收到Rx端下降沿
RxAv1 <= 1'b1;//当接收寄存器写时,位有效信号置1,,,,,,,,需要回复为0;
else if(BitPos==4'd9) 
RxAv1<= 1'b0;
else RxAv1<=RxAv1;
end
assign RxAv = RxAv1 & rx_en;
//neg_rx:__/\______________________________
//rx_ok:_________________________________/^\_
//rx_en:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//RxAv:____/^^^^^^^^^^^^^^^^^^^^^^^^^^^^\___

always @(posedge GClk or negedge reset)
begin
if(!reset) begin
data_temp<=8'd0;
BitPos <= 4'd0;
end
else if(RxAv==1'b1) begin
if(clk_bps) begin
BitPos<=BitPos+1'b1;
case(BitPos)
4'd0:;
4'd1:begin//当前结构位置为1时
data_temp[0]<=Rxd;//接收第1位
end
4'd2:begin//当前结构位置为2时
data_temp[1]<=Rxd;//接收第2位
end
4'd3:begin//当前结构位置为3时
data_temp[2]<=Rxd;//接收第3位
end
4'd4:begin//当前结构位置为4时
data_temp[3]<=Rxd;//接收第4位
end
4'd5:begin//当前结构位置为5时
data_temp[4]<=Rxd;//接收第5位
end
4'd6:begin//当前结构位置为6时
data_temp[5]<=Rxd;//接收第6位
end
4'd7:begin//当前结构位置为7时
data_temp[6]<=Rxd;//接收第7位
end
4'd8:begin//当前结构位置为8时
data_temp[7]<=Rxd;//接收第8位
end
default:;//当前结构位置为9时
endcase
end
else begin
if(BitPos==4'd9)
BitPos<=4'd0;
end
end else BitPos<=4'd0;
end

//rx_ok:____________________/^^^^^^\_____
/*  接收停止位,输出接收到的数据  */
always @(posedge GClk or negedge reset)
begin
if(!reset)begin
rx_ok<=1'b0;
data<=8'd0;
end
else if(BitPos==4'd9) begin
rx_ok<=1'b1;
data<=data_temp;
end
else begin
rx_ok<=1'b0;
data<=data;
end
end
assign datain = data;
endmodule





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章