串口通信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





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