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.




Verilog code UART Full Duplex(UART_FullDuplex.v):

change parameter "baud_rate" to change speed rate

//Engineer: Jose Pablo Pinilla

module UART_FullDuplex (
	input 	clk,
	input 	Tx_Start,
	input 	[7:0]Tx_Data,
	output 	Tx,
	output	TxD_Busy,
	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;
			if (Frame_Tx|Frame_Rx)
				div_clk_counter <= div_clk_counter+1;

always @ (negedge clk)
	clk_count_reset <= (div_clk_counter==counter_limit-1);
always @ (posedge clk_count_reset)
	baud_clk <= ~baud_clk;

//Tx Data Frame Counter

reg [3:0]Tx_counter=0;
always @ (negedge baud_clk or negedge Frame_Tx)
	if (~Frame_Tx)
		Tx_counter <= 0;
		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;
		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};
		OutBuffer <= {1'b1,OutBuffer[9:1]};

//Rx Data Frame Counter

reg [3:0]Rx_counter=0;
always @ (negedge baud_clk or negedge Frame_Rx)
	if (~Frame_Rx)
		Rx_counter <= 0;
		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;
		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];