-
-
Category: Cores
-
-
Hits: 12059
Author: Jose Pinilla
Today, the use of UART serial communication in embedded systems and electronics projects is very common. UART communication is found in Bluetooth devices (SPP), WiFi, Ethernet, USB conversion, audio and video devices, and communication with a wide variety of OEM cards.
UART
Verilog code UART Full Duplex(UART_FullDuplex.v):
change parameter "baud_rate" to change speed rate
//=======================UART_FullDuplex=====================
//Engineer: Jose Pablo Pinilla
//Website: semilleroadt.upbbga.edu.co
module UART_FullDuplex (
input clk,
//Transmitter
input Tx_Start,
input [7:0]Tx_Data,
output Tx,
output TxD_Busy,
//Receiver
input Rx,
output [7:0]Rx_Data,
output RxD_Ready
);
//========================Tx/Rx Control=====================
reg Frame_Rx=0; //Frame is being received
reg Frame_Tx=0; //Frame is being transmitted
assign TxD_Busy = Frame_Tx;
assign RxD_Ready= ~Frame_Rx;
//=====================Baud Rate Generation==================
parameter clk_in_freq = 50000000;
parameter baud_rate = 4800;
localparam counter_limit = clk_in_freq/(2*baud_rate);
//Baud Rate
reg [15:0]div_clk_counter=0;
reg clk_count_reset=0;
reg baud_clk=0;
always @ (posedge clk or posedge clk_count_reset)
if (clk_count_reset)
div_clk_counter <= 0;
else
begin
if (Frame_Tx|Frame_Rx)
div_clk_counter <= div_clk_counter+1;
end
always @ (negedge clk)
clk_count_reset <= (div_clk_counter==counter_limit-1);
always @ (posedge clk_count_reset)
baud_clk <= ~baud_clk;
//======================Tx========================
//Tx Data Frame Counter
reg [3:0]Tx_counter=0;
always @ (negedge baud_clk or negedge Frame_Tx)
if (~Frame_Tx)
Tx_counter <= 0;
else
Tx_counter <= Tx_counter+4'd1;
wire Tx_Counter_Reset = (Tx_counter==10);
//Tx Detection
always@(posedge Tx_Start or posedge Tx_Counter_Reset)
if (Tx_Counter_Reset)
Frame_Tx <= 0;
else
Frame_Tx <= 1;
//Tx Shift Register
reg [9:0]OutBuffer = 10'b11111111_0_1;
always @ (posedge baud_clk or negedge Frame_Tx)
if (~Frame_Tx)
OutBuffer <= {Tx_Data,2'b01};
else
OutBuffer <= {1'b1,OutBuffer[9:1]};
//======================Rx=========================
//Rx Data Frame Counter
reg [3:0]Rx_counter=0;
always @ (negedge baud_clk or negedge Frame_Rx)
if (~Frame_Rx)
Rx_counter <= 0;
else
Rx_counter <= Rx_counter+4'd1;
wire Rx_Counter_Reset = (Rx_counter==10);
//Rx Detection
always@(negedge Rx or posedge Rx_Counter_Reset)
if (Rx_Counter_Reset)
Frame_Rx <= 0;
else
Frame_Rx <= 1;
//Rx Shift Register
reg [9:0]InBuffer=0;
always @ (posedge baud_clk)
if (Frame_Rx)
InBuffer <= {Rx,InBuffer[9:1]};
//================Output Assignment==============
assign Tx = OutBuffer[0];
assign Rx_Data = InBuffer[8:1];
endmodule