Model of the Month


We can update you automatically when this page changes.
To receive regular notification of updates to our Model of the Month section, click here.


Universal Asynchronous Receiver (UAR)

Many thanks to Gerard Blair at the University of Edinburgh for allowing us to use his UAR model for February’s Model of the Month. Gerard’s home page is http://www.ee.ed.ac.uk/~gerard/. If you have a model that you are willing to have advertised on these pages, please drop us a line by clicking here.

OK, on with this month’s Model...

The above figure shows a simplified picture of an asynchronous serial interface of the type commonly used to transfer data in computer and communications systems. The data transfer is referred to as `asynchronous' because the spacing between the characters may be of any length. In contrast, the timing of the bits within the character is well defined (and is related to the baud rate of the interface). The Tx clock and Rx clock signals are nominally of the same frequency, but are generated locally at each end of the transmission link and therefore cannot be assumed to be ‘locked’ together. The design of a suitable transmitter circuit is not difficult, but the receiver must be able to detect the start of an incoming character and then store the value of each data bit, despite the fact that the relative frequency and phase of the Tx and Rx clocks may vary.

As shown in the data diagram above, the beginning and end of each character is delimited by a start bit whose value is always 0, and a stop bit whose value is always 1. In between characters, the transmitter outputs a constant value of 1. In operation, the receiver continually samples the input data. Following a 1 -> 0 data input transition, the eight data bits must be stored, and this is where a problem may occur, since for maximum reliability we wish to sample the data bits in the centre of their bit times and not close to either edge, so that small differences between the Tx and Rx clocks can be accommodated. This may be accomplished by using an Rx clock frequency which is a multiple of the data bit rate. In this exercise we shall assume that the Rx clock signal is eight times the bit rate.

Following the detection of a start bit, the stop bit should be detected 76 clock cycles later. If so, the Data Available output is set high; if not, the Framing Error output is set. Both status outputs are reset low by the detection of the next start bit.

There is thought to be a danger of spikes on the communication channel falsely starting the receiver. This means that a momentary LOW on the input to the receiver would be seen as a one-to-zero transition where-as it is really just noise.

To counter this, the specification is changed as follows:

Thus you will have to update your design for detectng a valid start bit.

Note:- the flexibility of 3-4-5 clock periods is to allow you to implement whichever is simplest - BUT there is no definition of what value is on the input at the sample AFTER the one-to-zero transition: this is to avoid problems associated with signal bounce.

Well, that’s the specification for a UAR model. Here is a design based on sound synchronous design principles.

The following Verilog code has five major sub-modules:

As with all good synchronous modules, a global_reset signal is included so that the registers can be put into a known state at the start of testing.

You are welcome to use the source code we provide but you must keep the copyright notice with the code (see the Acknowledgements page for more details).


// Universal Asynchronous Receiver
//
// +-----------------------------+
// |     Library : Datacomms     |
// |   designer : Gerard Blair   |
// |     opened: 03 Feb 1997     |
// +-----------------------------+
 
// Architectures:
//   03.02.97 uar

        // Start detection
        module start_detect (valid, clk, reset, gl_reset, dIn);
        output       valid;
        input        clk, reset, gl_reset, dIn;
        reg    [3:0] shift_reg;

        always @ (posedge clk) begin
             if (reset | gl_reset)
                  shift_reg = 0;
             else
                  shift_reg = { shift_reg[2:0], dIn };
             end

        assign valid = (shift_reg [0] == 0) &
                       (shift_reg [2] == 0) &
                       (shift_reg [3] == 1);

        endmodule

        // controller
        module counter (count72, count8, clk, enable);
        output       count72, count8;
        input        clk, enable;
        wire         each8;
        reg    [8:0] count_reg;

        always @ (posedge clk)
             if (enable == 0)
                  count_reg <= 0;
             else begin
                  count_reg <= count_reg + 1;
             end

        assign each8   = ((count_reg % 8) == 7);
        assign count72 = (count_reg == 71);
        assign count8  = each8 & ~count72;

        endmodule

        // serial parallel converter
        module ser_par_conv (dOut, clk, enable, dIn);
        output [7:0] dOut;
        input        clk, enable, dIn;
        reg    [7:0] dOut;

        always @ (posedge clk)
             if (enable == 1)
                  dOut = {dIn, dOut[7:1]};

        endmodule

        // flags for ready and data error
        module flags (dReady, dError,  clk, set,  reset, dIn);
        output dReady, dError;
        input  clk, set,  reset, dIn;
        reg    dReady, dError;

        always @(posedge clk)
             if (reset == 1) begin
                  dReady = 0;
                  dError = 0;
                  end
             else if (set == 1) begin
                  dReady <= dIn;
                  dError <= ~dIn;
                  end

        initial $monitor("dReady %b %b", dReady, dError, $time);

        endmodule

        // generating the run signals
        module control (running, clk, reset, gl_reset, set);
        output running;
        input  clk, reset, gl_reset, set;
        reg    running;

        always @ (posedge clk)
             if ((reset == 1) | (gl_reset == 1))
                  running  =  0;
             else if (set == 1)
                  running = 1;
        endmodule

        // overall receiver definition
        module uar (dOut, dReady, dError, clk, gl_reset, dIn);
        output [7:0] dOut;
        output       dReady, dError;
        input        clk, gl_reset, dIn;

        wire         running, finish, count8, start;

        start_detect s_d (start, clk, running, gl_reset, dIn);
        counter      cov (finish, count8, clk, running);
        ser_par_conv s_p (dOut, clk, count8, dIn);
        flags        fla (dReady, dError, clk, finish, start, dIn);
        control      con (running, clk, finish, gl_reset, start);

        endmodule

VHDL source code for other Models of the Month
can be downloaded from here.


accumulator diagramASIC Design and Project Services
idea iconAdvanced VHDL Techniques
wand iconDoulos Training Courses


river iconDoulos Home Page

Copyright 1995-1997 Doulos
This page was last updated 4th February 1997.

mail iconWe welcome your e-mail comments. Please contact us at: webmaster@doulos.co.uk