UART串口
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 13:34:04 11/09/2019
// Design Name:
// Module Name: uart-top
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module Uart_Top(Sys_CLK,Sys_RST,Signal_Tx,Signal_Rx,word);
input Sys_CLK;
input Sys_RST;
//input [1:0]Key_In;
input Signal_Rx;
input word;
output Signal_Tx;
//output Key_Signal;
wire Uart_CLK;
//wire [1:0]Key_Out;
//reg Key_Signal;
Uart_ClkDiv Uart_ClkDiv(.Sys_CLK(Sys_CLK),.Uart_CLK(Uart_CLK));
//Key Key(.Sys_CLK(Sys_CLK),.Key_In(Key_In),.Key_Out(Key_Out));
reg [7:0]Data_Tx;
wire [7:0]Data_Rx;
reg [7:0]Data_Reg;
//reg [7:0]Data_Temp;
reg Wrsig;
wire Rdsig;
wire Rx_DataError_Flag;
wire Rx_FrameError_Flag;
reg Error_Flag;
reg [2:0]State;
reg [7:0]cnt;
reg [7:0]Char[7:0];
reg [7:0]Error_Char[5:0];
reg [3:0]Char_Cnt;
wire Idle;
parameter Wait_Rdsig = 3'b000;
parameter Check_Data = 3'b001;
parameter Save_Data = 3'b010;
parameter Trans_Data = 3'b011;
parameter State_Delay = 3'b100;
initial
begin
//Data_Temp <= 8'b0;
Data_Tx <= 8'b0;
Wrsig <= 1'b0;
State <= 2'b0;
cnt <= 8'b0;
Char[0] <= 8'd82; //R
Char[1] <= 8'd101; //e
Char[2] <= 8'd116; //t
Char[3] <= 8'd117; //u
Char[4] <= 8'd114; //r
Char[5] <= 8'd110; //n
Char[6] <= 8'd58; //:
Char[7] <= 8'd32; //Space
Error_Char[0] <= 8'd69; //E
Error_Char[1] <= 8'd114; //r
Error_Char[2] <= 8'd114; //r
Error_Char[3] <= 8'd111; //o
Error_Char[4] <= 8'd114; //r
Error_Char[5] <= 8'd33; //!
Char_Cnt <=4'b0;
end
always@(posedge Uart_CLK or negedge Sys_RST)
begin
if(!Sys_RST)
begin
Wrsig = 1'b0;
cnt = 1'b0;
State = 2'b0;
Char_Cnt = 4'b0;
Data_Reg = 8'b0;
end
else
begin
case(State)
Wait_Rdsig:begin
if(!Rdsig)
State = Wait_Rdsig;
else
State = Check_Data;
end
Check_Data:begin
if(Rdsig)
State = Check_Data;
else
begin
Error_Flag = Rx_DataError_Flag || Rx_FrameError_Flag;
State = Save_Data;
end
end
Save_Data:begin
if(!Error_Flag)
Data_Reg = Data_Rx;
State = Trans_Data;
end
Trans_Data:begin
if(!Error_Flag)
begin
if(Char_Cnt == 4'd8)
begin
Char_Cnt = 4'd0;
Data_Tx = Data_Reg;
State = State_Delay;
end
else
begin
State = Trans_Data;
if(cnt == 254)
begin
Data_Tx = Char[Char_Cnt];
Wrsig = 1'b1;
cnt = 8'd0;
Char_Cnt = Char_Cnt + 1'b1;
end
else
begin
Wrsig = 1'b0;
cnt = cnt + 8'd1;
end
end
end
else
begin
if(Char_Cnt == 4'd6)
begin
Char_Cnt = 4'd0;
State = State_Delay;
end
else
begin
State = Trans_Data;
if(cnt == 254)
begin
Data_Tx = Error_Char[Char_Cnt];
Wrsig = 1'b1;
cnt = 8'd0;
Char_Cnt = Char_Cnt + 1'b1;
end
else
begin
Wrsig = 1'b0;
cnt = cnt + 8'd1;
end
end
end
end
State_Delay:begin
if(cnt == 254)
begin
Data_Tx = 8'd13;
Wrsig = 1'b1;
cnt = 8'd0;
State = Wait_Rdsig;
end
else
begin
Wrsig = 1'b0;
cnt = cnt + 8'd1;
end
end
default:begin
Wrsig = 1'b0;
cnt = 1'b0;
State = 2'b0;
Char_Cnt = 4'b0;
Data_Reg = 8'b0;
end
endcase
end
end
/*
always@(posedge Sys_CLK)
begin
Key_Signal = |Key_Out;
end
always@(posedge Key_Signal or negedge Sys_RST)
begin
if(!Sys_RST)
Data_Temp <= 8'b0;
else
begin
if(Key_Out == 2'b10)
Data_Temp <= Data_Temp + 1'b1;
else if (Key_Out == 2'b01)
Data_Temp <= Data_Temp - 1'b1;
else
Data_Temp <= Data_Temp;
end
end
always@(posedge Uart_CLK)
begin
case(State)
2'b00:begin
if(Data_Temp != Data_Tx)
State = 2'b01;
else
State = 2'b00;
end
2'b01:begin
if(cnt < 8'd5)
cnt = cnt + 1'b1;
else
begin
Data_Tx = Data_Temp;
cnt = 8'd0;
State = 2'b10;
end
end
2'b10:begin
Wrsig = 1'b1;
State = 2'b11;
end
2'b11:begin
Wrsig = 1'b0;
State = 2'b00;
end
default:State = 2'b00;
endcase
end
always@(posedge Uart_CLK or negedge Sys_RST)
begin
if(!Sys_RST)
begin
cnt <= 8'd0;
Wrsig <= 1'b0;
Data_Tx <= 8'b0;
end
else
begin
if(cnt == 254)
begin
Data_Tx <= Data_Tx + 8'b1;
Wrsig <= 1'b1;
cnt <= 8'd0;
end
else
begin
Wrsig <= 1'b0;
cnt <= cnt + 8'd1;
end
end
end */
Uart_Tx Uart_Tx(.Uart_CLK(Uart_CLK),.Data_Tx(Data_Tx),.Wrsig(Wrsig),.Idle(Idle),.Signal_Tx(Signal_Tx));
Uart_Rx Uart_Rx(.CLK(Uart_CLK),.RST(Sys_RST),.Signal_Rx(Signal_Rx),.Data_Rx(Data_Rx),.Rdsig(Rdsig),
.DataError_Flag(Rx_DataError_Flag),.FrameError_Flag(Rx_FrameError_Flag));
endmodule
//
module Uart_ClkDiv(Sys_CLK,Uart_CLK);
input Sys_CLK;
output Uart_CLK;
reg Uart_CLK;
reg [7:0]Uart_CLK_Cnt;
initial
begin
Uart_CLK <= 1'b0;
Uart_CLK_Cnt <= 8'd0;
end
always@(posedge Sys_CLK)
begin
if(Uart_CLK_Cnt <= 8'd161)
Uart_CLK_Cnt = Uart_CLK_Cnt + 1'b1;
else
begin
Uart_CLK = ~Uart_CLK;
Uart_CLK_Cnt = 8'd0;
end
end
endmodule
module Uart_Tx(Uart_CLK,Data_Tx,Wrsig,Idle,Signal_Tx);
input Uart_CLK;
input [7:0]Data_Tx;
input Wrsig;
output Idle;
output Signal_Tx;
reg Idle;
reg Signal_Tx;
reg Send;
reg WrsigBuf;
reg WrsigRise;
reg Presult;
reg [7:0]Tx_Cnt;
parameter paritymode = 1'b0;
always@(posedge Uart_CLK)
begin
WrsigBuf <= Wrsig;
WrsigRise <= (~WrsigBuf) & Wrsig;
end
always@(posedge Uart_CLK)
begin
if(WrsigRise && (~Idle)) //??????é???????¤??????????o?è·ˉ??o??oé?2????????ˉ??¨??°?????°??????é??è???¨?
Send <= 1'b1;
else if(Tx_Cnt == 8'd168) //?????§èμ???????é????????
Send <= 1'b0;
end
always@(posedge Uart_CLK)
begin
if(Send == 1'b1)
begin
case(Tx_Cnt) //?o§???èμ·?§????
8'd0:
begin
Signal_Tx <= 1'b0;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd16:
begin
Signal_Tx <= Data_Tx[0]; //???é????°???0???
Presult <= Data_Tx[0]^paritymode;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd32:
begin
Signal_Tx <= Data_Tx[1]; //???é????°???1???
Presult <= Data_Tx[1]^Presult;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd48:
begin
Signal_Tx <= Data_Tx[2]; //???é????°???2???
Presult <= Data_Tx[2]^Presult;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd64:
begin
Signal_Tx <= Data_Tx[3]; //???é????°???3???
Presult <= Data_Tx[3]^Presult;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd80:
begin
Signal_Tx <= Data_Tx[4]; //???é????°???4???
Presult <= Data_Tx[4]^Presult;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd96:
begin
Signal_Tx <= Data_Tx[5]; //???é????°???5???
Presult <= Data_Tx[5]^Presult;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd112:
begin
Signal_Tx <= Data_Tx[6]; //???é????°???6???
Presult <= Data_Tx[6]^Presult;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd128:
begin
Signal_Tx <= Data_Tx[7]; //???é????°???7???
Presult <= Data_Tx[7]^Presult;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd144:
begin
Signal_Tx <= Presult; //???é???¥???????éa????
Presult <= Data_Tx[0]^paritymode;
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd160:
begin
Signal_Tx <= 1'b1; //???é??????-¢???
Idle <= 1'b1;
Tx_Cnt <= Tx_Cnt + 8'd1;
end
8'd168:
begin
Signal_Tx <= 1'b1;
Idle <= 1'b0; //?????§èμ???????é????????
Tx_Cnt <= Tx_Cnt + 8'd1;
end
default:
Tx_Cnt <= Tx_Cnt + 8'd1;
endcase
end
else
begin
Signal_Tx <= 1'b1;
Tx_Cnt <= 8'd0;
Idle <= 1'b0;
end
end
endmodule
module Uart_Rx(CLK,RST,Signal_Rx,Data_Rx,Rdsig,DataError_Flag,FrameError_Flag);
input CLK; //é????·???é??
input RST; //?¤?????????·
input Signal_Rx; //UART??°???è????¥
output Data_Rx; //??¥?????°???è????o
output Rdsig;
output DataError_Flag; //??°?????oé??????¤o
output FrameError_Flag; //??§??oé??????¤o
reg [7:0]Data_Rx;
reg Rdsig;
reg DataError_Flag;
reg FrameError_Flag;
reg [7:0]cnt;
reg RxBuf;
reg RxFall;
reg Recieve;
reg Presult;
reg Idle;
parameter paritymode = 1'b0;
always@(posedge CLK) //?£??μ??o?è·ˉ??????é???2?
begin
RxBuf <= Signal_Rx;
RxFall <= RxBuf & (~Signal_Rx);
end
//??ˉ??¨??2??£??¥????¨??o?
always@(posedge CLK)
begin
if (RxFall && (~Idle)) //?£??μ???°?o?è·ˉ??????é???2??1???????????o?è·ˉ??o??oé?2?????ˉ??¨??¥?????°???è???¨?
Recieve <= 1'b1;
else if(cnt == 8'd168) //??¥?????°?????????
Recieve <= 1'b0;
end
//??2??£??¥????¨??o?, 16??a???é????¥????????abit
always@(posedge CLK or negedge RST)
begin
if (!RST)
begin
Idle<=1'b0;
cnt<=8'd0;
Rdsig <= 1'b0;
FrameError_Flag <= 1'b0;
DataError_Flag <= 1'b0;
Presult<=1'b0;
end
else if(Recieve == 1'b1)
begin
case(cnt)
8'd0:begin
Idle <= 1'b1;
cnt <= cnt + 8'd1;
Rdsig <= 1'b0;
end
8'd24:begin //??¥??????0?????°???
Idle <= 1'b1;
Data_Rx[0] <= Signal_Rx;
Presult <= paritymode^Signal_Rx;
cnt <= cnt + 8'd1;
Rdsig <= 1'b0;
end
8'd40:begin //??¥??????1?????°???
Idle <= 1'b1;
Data_Rx[1] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8'd1;
Rdsig <= 1'b0;
end
8'd56:begin //??¥??????2?????°???
Idle <= 1'b1;
Data_Rx[2] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8'd1;
Rdsig <= 1'b0;
end
8'd72:begin //??¥??????3?????°???
Idle <= 1'b1;
Data_Rx[3] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8'd1;
Rdsig <= 1'b0;
end
8'd88:begin //??¥??????4?????°???
Idle <= 1'b1;
Data_Rx[4] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8'd1;
Rdsig <= 1'b0 ;
end
8'd104:begin //??¥??????5?????°???
Idle <= 1'b1;
Data_Rx[5] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8'd1;
Rdsig <= 1'b0;
end
8'd120:begin //??¥??????6?????°???
Idle <= 1'b1;
Data_Rx[6] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8'd1;
Rdsig <= 1'b0;
end
8'd136:begin //??¥??????7?????°???
Idle <= 1'b1;
Data_Rx[7] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8'd1;
Rdsig <= 1'b1;
end
8'd152:begin //??¥????¥???????éa????
Idle <= 1'b1;
if(Presult == Signal_Rx)
DataError_Flag <= 1'b0;
else
DataError_Flag <= 1'b1; //?|?????¥???????éa????????ˉ1???è?¨?¤o??°?????oé??
cnt <= cnt + 8'd1;
Rdsig <= 1'b1;
end
8'd168:begin
Idle <= 1'b1;
if(1'b1 == Signal_Rx)
FrameError_Flag <= 1'b0;
else
FrameError_Flag <= 1'b1; //?|?????2??????¥?????°????-¢??????è?¨?¤o??§??oé??
cnt <= cnt + 8'd1;
Rdsig <= 1'b1;
end
default:
cnt <= cnt + 8'd1;
endcase
end
else
begin
cnt <= 8'd0;
Idle <= 1'b0;
Rdsig <= 1'b0;
end
end
endmodule