Skip to main content

UART Receiver in FPGA using Verilog

A UART Receiver follows a UART Transmitter. It receives the serialized data and converts it back to a parallel form. The working of the receiver is a bit more complicated than the transmitter. Since UART is an Asynchronous Protocol, no clock is transmitted along the data. Therefore, the receiver has to identify the start of the incoming data frame to properly convert it to parallel form. To do this the transmitter and the receiver have to agree to the baud rate and the number of bits per frame. The transmitter and the receiver also have to agree with the length of the stop period (1 bit, 1.5 bit or 2 bits). In the given project the UART Receiver is configured for the baud rate of 1 Mbit/s, 1 stop bit, no parity or flow control. The receiver looks for the Rx_pin to go low which indicates the start bit. As the Rx_pin goes low, a Flip_Flop is Set which enables a counter which starts counting as the Rx_pin goes low. When the Counter reaches 25 (The counter is clocked at 50 Mhz in the given code, therefore there are 50 clocks in 1 bit duration at 1 Mbit/s, therefore 25th clock is at the middle of the start bit), it is at the middle of the start bit. An output latch is set whose input is connected to the Rx_pin. Similarly when the counter reaches 25+50 i.e 75, we are at the middle of the first bit. So, another latch is set whose input is connected to the Rx_pin. This goes on until the stop bit. Note that this code does not have an output Shift Register. Therefore an improvement would be to put another Shift Register at the Output so that we know that the entire byte has reached. By changing the values of the clock counter, various baud rates can be achieved. Another output called D_Rdy(Data Ready) is also present which goes high for 50 clock pulses which indicates the completion of the reception of the complete byte.
Now we come to the Verilog Code of the Receiver.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//
// 
//                                                    
// Create Date:    12:05:43 06/01/2019      
// Design Name:                               
// Module Name:    UART_RX_Module         
// Project Name:                                   
// Target Devices:                                 
// Tool versions:                                 
// Description:                           
// Dependencies:                         
//                                           
// Revision:                                      
// Revision 0.01 - File Created            
// Additional Comments:                               
//
//////////////////////////////////////////////////////////////////////////////////
module UART_RX(clk,d_in,D_Out,D_Rdy);
input clk,d_in; //The clock and the data input; clock is at 50 Mhz
output [7:0] D_Out; //8-bit data output
output D_Rdy; //Data Ready output; indicates that the complete byte has been received
//////////////////////////////////////////////////////////////////////////////////
reg [9:0] Clock_Counter=0; //The Clock Counter Register; the value starts from zero
always @(posedge clk) //The register increments at the rising edge of the clock
begin
if (Flip_Flop == 1'b1)
Clock_Counter <= Clock_Counter+1;
if(Clock_Counter==475)
Clock_Counter <= 0;
end
//////////////////////////////////////////////////////////////////////////////////
reg Flip_Flop; //The Flip Flop which gets set at the falling edge of the start bit
always @(posedge clk)
begin
if(d_in == 1'b0)
Flip_Flop <= 1'b1;
if(Clock_Counter==475)
Flip_Flop <= 1'b0; //Flip Flop resets at the center of the stop bit
end
//////////////////////////////////////////////////////////////////////////////////
reg SIPO_0; //The Start Bit
always @(Clock_Counter)
begin
if(Clock_Counter==25)
SIPO_0 <= d_in;
end

reg SIPO_1; //The LSB
always @(Clock_Counter)
begin
if(Clock_Counter==75)
SIPO_1 <= d_in;
end
assign D_Out[0] = SIPO_1;

reg SIPO_2;
always @(Clock_Counter)
begin
if(Clock_Counter==125)
SIPO_2 <= d_in;
end
assign D_Out[1] = SIPO_2;

reg SIPO_3;
always @(Clock_Counter)
begin
if(Clock_Counter==175)
SIPO_3 <= d_in;
end
assign D_Out[2] = SIPO_3;

reg SIPO_4;
always @(Clock_Counter)
begin
if(Clock_Counter==225)
SIPO_4 <= d_in;
end
assign D_Out[3] = SIPO_4;

reg SIPO_5;
always @(Clock_Counter)
begin
if(Clock_Counter==275)
SIPO_5 <= d_in;
end
assign D_Out[4] = SIPO_5;

reg SIPO_6;
always @(Clock_Counter)
begin
if(Clock_Counter==325)
SIPO_6 <= d_in;
end
assign D_Out[5] = SIPO_6;

reg SIPO_7;
always @(Clock_Counter)
begin
if(Clock_Counter==375)
SIPO_7 <= d_in;
end
assign D_Out[6] = SIPO_7;

reg SIPO_8; // The MSB
always @(Clock_Counter)
begin
if(Clock_Counter==425)
SIPO_8 <= d_in;
end
assign D_Out[7] = SIPO_8;

reg SIPO_9; //The Stop bit
always @(Clock_Counter)
begin
if(Clock_Counter==475)
SIPO_9 <= d_in;
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
reg DataReady; //Data Ready Register; turns high after the reception of the MSB
always @(Clock_Counter)
begin
if(Clock_Counter > 425)
DataReady <= 1'b1;
if(Clock_Counter < 425)
DataReady <= 1'b0;
end
assign D_Rdy = DataReady;

endmodule  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
To test this, you can write a Verilog Testbench or you can synthesize and upload it to an FPGA.
To send the data, you can use an Arduino. A Spartan 6 XC6SLX9-TQG144 FPGA was used to test this. The device utilization is as follows :

  • No. of Slice Registers used - 11 out of 11,440 i.e 1%
  • Out of which no. of Registers used as Flip_Flops - 11
  • No. of Slice Look Up Tables used - 37 out of 5,720 i.e 1%
  • No. of LUTs used as Logic - 36 
  • No. of Occupied Slices - 13 out of 1430 i.e 1%
  • No. of IOBs used - 11 out of 102 i.e 10%
As it can be seen, the standalone UART Receiver occupies very little space therefore there is a lot of room for other processes to be implemented.The code was tested using ASCII values .This code is meant for education purposes only. Please write in the comments section if you have any suggestions or remarks. Thanks.

Comments

Popular posts from this blog

FORM G Letter of Appointment Format under Shop & Establishment Act

FORM – G Letter of Appointment (See Rule 21) Name of the Establishment…………………………………………………………………………………. Registration No ……………………………………………………………………………………………… Name of Employer…………………………………………………………………………………………... Address……………………………………………………………………………………………………… To, You, Shri/Shrimati ……………………………………….. is hereby appointed on Probation for a period of three months temporary basis for the period from ……………………………………………………. To casualbasis. Permanent basis For ……………………………………………………………………………………………………………………………………………………… Your time scale of pay including rate of increment shall be ………………………………… (here insert the scale of pay and) you will get the total wages /salary per day6/ month composed of the following : Basic Pay – Rs. Dearness Allowance – Rs. Other Allowances – Rs. In addition to the above you will be entitled to: Free Board Free Lodging Concessional supply of food gains @ ……………. Per Kg. G. Concessional supply of other articles ( here me...

GAON PANCHAYAT MARRIAGE CERTIFICATE FORMAT FOR NRC ASSAM

GOVERNMENT OF ASSAM OFFICE OF THE __________ GAON PANCHAYAT __________ , DIST. - TINSUKIA , ASSAM. ------------------------------------------------------------------------------------------------------------------------------- NO.                                                                                                                                                               Dated : TO WHOM IT MAY CONCERN This is to certify that Smt.____________________ Daughter of _________________ (Father) /(or) _ ________________ (Mother) of Village _________________________...

Download Eradication of Child Labor Self Declaration Form