Skip to content

UART controller that uses a master-slave architecture to enstablish a communication with the other device during the configuration process. This repository provides RTL code and testbench for the device synthesis and simulation, as well as a simple driver to use it in your system.

License

Notifications You must be signed in to change notification settings

GabbedT/UART-Controller

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Table of contents

Introduction

This repository contains the HDL source code of the device and a little driver written in C that implements the basic functions. The device is a light universal asyncronous receiver transmitter (UART) that implements in addition to the standard UART protocol, a configuration protocol that enables the device to change its configuration at run-time.

Features

  • Highly configurable
  • Low resources usage
  • Can be implemented both in ASIC an FPGA
  • 4 different data width mode
  • 3 different parity mode
  • 2 different stop bit number mode
  • Can change its configuration at run-time
  • 3 different interrupt priority
  • Compatibility with different UART devices

Architecture

Block Diagram

BLOCKDIAGRAM

Top Level View

PACKAGE

Signal Description

Signal Direction Description
D0 - D7 Input / Output Data bus
WR/WR Input Read active high, write active low
CS Input Chip select active low, if deasserted the data line is set in high impedance state
VDD Input Power supply
A0 - A2 Input Address bus for registers
TX Output Transmitter data line
RX Input Receiver data line
RST Input Reset active low
CLK Input Clock
IREQ Output Interrupt request active low
IACK Input Interrupt acknowledge
GND Input Ground

Configuration Protocol

This UART controller implements a configuration protocol that enables two devices to change their configuration. An UART is a communication protocol that doesn't support master/slave configuration: two UARTs that share data have the same priority. In this UART architecture there is a master/slave configuration but only during the configuration process. The process is started once one of the two UARTs change their configuration state (the device won't change his state until the configuration has ended), at that point the device which changed his configuration first become the master and will dictate the data sent to the slave. The slave job is only acknowledging the packet of data received and to convert those packets into a valid device configuration.

The process start with the sending of three SYN (0x16) data packet to advertise the slave device that a configuration request is being sent, if those packets are not received the configuration process cannot start, this enables the use of slower baud rate without starting configuration processes while sending data bits.   The configuration request is then sent by lowering the TX line (logic 0) for 1ms Once this is done, the master will wait for the slave to send an acknowledgment packet (0xFF), the wait lasts for 10ms, if the slave doesn't respond in time, the master will send another request. This is done three times, if the other device doesn't respond for three times, a configuration error is generated.

Configuration Packet

The valid bits are only 4 which enable sending the packet with every data width configuration supported. The ID defines the packet type (data width, stop bits number, parity mode or end configuration), while the OPTION field defines the configuration.

ID DESCRIPTION
00 End configuration packet
01 Data width packet
10 Parity mode packet
11 Stop bits number packet

Data width packet

OPTION DESCRIPTION
00 5 bits
01 6 bits
10 7 bits
11 8 bits

Parity mode packet

OPTION DESCRIPTION
00 Even
01 Odd
10 Disabled
11 Disabled

Stop bits number packet

OPTION DESCRIPTION
00 1 bit
01 2 bits
10 Reserved (set 1 bit)
11 Reserved (set 1 bit)

The end configuration packet has 00 in the OPTION field.

Once the master has finished sending a packet the slave must acknowledge it, this handshake procedure runs until every packet has been sent.

Controller unit

The controller unit is the module that enables the configuration process between two devices. It's an FSM, which at the reset it's setted in the MAIN state, the configuration is the standard one which is defined in the UART_pkg.sv file.   If the programmer writes into the STR register and at least one of the three configuration fields (data width, stop bits number and parity mode) is changed, it sends a configuration request becoming the master (TX low for 1ms). Once the request is acknowledged within 10ms, the controller sends a series of configuration packets to the slave device, the slave must acknowledge every packet received. The process ends by sending of an END CONFIGURATION packet with the subsequent acknowledge.

If the device, instead of sending the request, receives one, the controller sends an acknowledgment packet only if the request is acknowledged by the user by setting the AKREQ bit in the CTR register. At this point the device became the slave, for every configuration packet received, it sends an acknowledgment. The process ends with the reception of an END CONFIGURATION packet and the acknowledgment.

If some errors happen during the configuration process (an illegal packet is received or the request isn't simply acknowledged), the controller will simply set the standard configuration.

Receiver

The receiver module is responsible for managing the right reception timing based on the device configuration and detecting a configuration request sent by the master device.

It contains a 64 bytes FIFO buffer (configurable) which can be used with the RX data stream mode (RXDSM). Instead of interrupting every time the UART receives a packet of data (if RXDSM is disabled), the device will interrupt once the buffer is full or the number of packets received match the threshold value which is stored into the RX THRESHOLD field of the FSR register.

The receiver also checks the data integrity after receiving the data and generate proper error signals which are stored in a 64 x 3 bit FIFO buffer (configurable) which is read/written with the data buffer. Once the packet is received, the module assert the rx_done signal and also rxd_rdy signal if the interrupt conditions are satisfied.

The detection of the configuration request is done initially by checking every data packet received, a counter will keep track of the SYN packets received. Once three consecutive are sent, the receiver goes into a state where it checks that the RX line is held low for 1ms. Once this happens, it will generate a configuration requested signal. If during the request, the RX line is not stable low, the receiver will exit this state and will enter the IDLE state!

Transmitter

The transmitter module is responsible for managing the right transmission timing based on the device configuration and the generation of the configuration request signal.   It contains a 64 bytes FIFO buffer which can be used with the TX data stream mode (TXDSM) to send a burst of data: the programmer will write the TXR register multiple times, then wait for the transmitter to end its task. If the TXDSM is enabled, the transmitter will assert the tx_done signal once the buffer is empty, otherwise it will be asserted for every packet sent.  

If the device wants to send a configuration request, the transmitter will lower the TX line for 1ms (logic 0), then it will enter the main state ready to send configuration packets.

Interrupt

Any interrupt is managed by the interrupt arbiter. Since there are three different priority level, the arbiter must ensure that all the high priority interrupt are cleared before the low priority one.   All the interrupts are generated by other modules, after the pulse is generated, the cause of the interrupt is saved into a register, there are three registers in the arbiter, each one with a specific priority.

One clock cycles after the generation of the interrupt, the pin IRQ is set to low to signal that an interrupt has been generated, additionally the UART can be setted up to enable vectored interrupt, in this case the device will output the associated vector as soon as the CPU acknowledge the interrupt.

To clear the interrupt, the CPU must first recognize that the UART has interrupted. If the CPU can manage interrupts then follows its routine, else the CPU must poll the IPEND bit in the CTR register: if an interrupt is pending, the bit will be set.   After acknowledging the interrupt, the CPU must read the INTID field in the ISR register (read Interrupt Status Register) to know what's the cause of it, then execute the corresponding operation to definitely clear the interrupt.

Registers

Status Register (STR)

STR

The status register contains the device current configuration except for the baud rate.

ADDRESS : 0

Fields Description

Field Access Mode Description
TDSM (R/W) Enable data stream mode for transmitter module.
RDSM (R/W) Enable data stream mode for receiver module.
SBID (R/W) Set stop bit number configuration ID.
PMID (R/W) Set parity mode configuration ID.
DWID (R/W) Set data width configuration ID.

SBID Field

Value Description
00 1 stop bit.
01 2 stop bit.
10 Reserved.
11 Reserved.

PMID Field

Value Description
00 Even.
01 Odd.
10 Disabled.
11 Disabled.

DWID Field

Value Description
00 5 bits.
01 6 bits.
10 7 bits.
11 8 bits.

Divisor Register (DVR)

DVR

The Divisor Register is a 16 bit register split in two different addressable register (LDVR and UDVR). Since the divisor is a 16 bit value and two registers can't be addressed at the same time, to read or write the entire value, two different operation must be executed.   The UART doesn't change its configuration until two writes on two of the two registers happens.

LOWER ADDRESS : 1
UPPER ADDRESS : 2


FIFO Status Register (FSR)

FSR

The FIFO Status Register holds the state of both receiver and transmitter FIFOs. Notice how the only useful status flags are: the full flag for the transmitter FIFO: the empty flag is not really needed because an interrupt will occur when it's empty; the same thing for the empty flag for the receiver FIFO: the full flag is not really needed because an interrupt will occur when it's full.

If the programmer wants the device to interrupt when it receives a fixed amount of data, he can set a threshold for the receiver FIFO buffer.

ADDRESS : 3

Fields Description

Field Access Mode Description
TXF (R) Transmitter FIFO full flag.
RXE (R) Receiver FIFO empty flag.
RX THRESHOLD (R/W) Forces the UART to interrupt when it receives an amount of data that equals that number.

Control Register (CTR)

CTR

The Control Register controls the state of the configuration request for both master and slave. A bit can also be set to set the device into standard configuration.

ADDRESS : 4

Fields Description

Field Access Mode Description
IVECD (R/W) Enable or disable vectored interrupt mode
IPEND (R) An interrupt is pending
COM (R/W) Communication mode.
ENREQ (R/W) Enable the configuration process.
CDONE (R) The configuration process has ended, this bit must be polled during every configuration process (both master and slave).
STDC (W) Set standard configuration.
AKREQ (W) Acknowledge the configuration request

COM Field

Value Description
00 Disabled communication.
01 Simplex TX only.
10 Simplex RX only.
11 Full-Duplex.

Interrupt Status Register (ISR)

ISR

The Interrupt Status Register contains the interrupt status and enable bits, as well as a vector that give the cause of the interruption.

ADDRESS : 5

Fields Description

Field Access Mode Description
TXRDY (R/W) Enable interrupt on data sending completed (works with and without data stream mode).
RXRDY (R/W) Enable interrupt on data received (works with and without data stream mode).
FRM (R/W) Enable interrupt on frame error.
PAR (R/W) Enable interrupt on parity error.
OVR (R/W) Enable interrupt on overrun error.
INTID (R) Returns the interrupt ID with the highest priority.

Interrupt Table

Cause Priority ID Clear
Transmission done 3 000 Acknowledge interrupt.
Configuration error 1 001 Acknowledge interrupt.
Overrun error 1 010 Read the data.
Frame error 1 011 Read the data.
Parity error 1 100 Read the data.
Data received ready 2 101 Standard mode: read RXR. Data stream mode: the fifo has reached his threshold read RXR till the buffer is empty.
Receiver fifo full 2 110 Standard mode: read RXR. Data stream mode: read RXR till the buffer is empty.
Requested configuration 3 111 Acknowledge interrupt.

Data Received Register (RXR)

RXR

The Data Received Register holds the data stored in the FIFO of the receiver.

ADDRESS : 6

Fields Description

Field Access Mode Description
DATA RX (R) Data received

Data Transmitted Register (TXR)

TXR

The Data Transmitted Register holds the data that will be sent by the transmitter.

Fields Description

Field Access Mode Description
DATA TX (W) Data to be transmitted

Operations

Configuration

Configuration request

This section describes the configuration process from both a hardware and a software point of view.

To enable correct communication between two devices, those must agree on four different configuration parameters: baud rate, data width, parity mode and stop bits number. This protocol focus on the configuration of the last three parameter. To start a configuration process, the programmer must ensure that the RX FIFO is empty, then simply write in the STR register a different configuration, once the hardware detects a change in the parameters, it becomes the master and sends three SYN characters. Once the transmission is ended, it sends the request (TX low for 1ms).   At that point, the slave device detects the request and will interrupt, once the programmer acknowledge the interrupt by writing the AKREQ bit in CTR register, the TX and RX FIFOs will be cleared. Once the device (both master and slave) detects that a configuration process is happening, they will reset the CDONE bit in the CTR register.   At this point, the hardware will completely take care of the process (see configuration Protocol and main Controller). Once the configuration process ended, the CDONE bit will be setted, so after a configuration, that bit should be polled before sending any data.  

Enable configuration request

The programmer can choose between two configuration modes by setting or clearing the ENREQ bit in the CTR register.   If the bit is setted, then when a configuration parameter is changed (Data Width, Parity Mode or Stop Bits Number), the device respond by sending the new configuration to the other device. Multiple parameters can be changed with a single configuration request by simply accessing the register one single time.

Transmitter Data Stream Mode

The programmer can enable or disable the data stream mode by setting or clearing the TDSM bit in the STR register.

If the data stream mode is disabled, once the transmission of a packet of data ended, the device will interrupt. If the programmer wants to send a stream of data, interrupting every time a packet is sent would slow the processor. Data stream mode can be enabled in this case: the processor will usually write a burst of data into the TX FIFO, then continue its task. The UART will transmit all the data until the FIFO will be empty, at this point the device will interrupt.

Note that the user can still write data consecutively (storing it into the FIFO) even if TDSM is disabled, this settings works only at the interrupt level.

Receiver Data Stream Mode

The programmer can enable or disable the data stream mode by setting or clearing the RDSM bit in the STR register.   If the data stream mode is not enabled, the device will interrupt every time a new packet is received. If enabled, the device will interrupt when the number of packet received equals the RX THRESHOLD value, if the value is set to zero, then the device will interrupt when the FIFO is full.

Note that the device can still receive multiple bytes of data without losing it (storing it into the FIFO) even if RDSM is disabled, his settings works only at the interrupt level.

Transmission

Data can be sent serially by writing it in the TXR register. Once the transmitter ended its task, the device will interrupt. Multiple sequential write can occur in the TXR while the transmitter is sending data, the data written in this case will be memorized in the TX FIFO.

Reception

Once received and the device interrupted, the data can be retrieved through the RXR register, every time this operation occurs, the FIFO will write the next data into the register. This will happen until the FIFO is empty.

References

S. Harutyunyan, T. Kaplanyan, A. Kirakosyan and A. Momjyan, "Design And Verification Of Autoconfigurable UART Controller," 2020 IEEE 40th International Conference on Electronics and Nanotechnology (ELNANO), 2020, pp. 347-350, doi: 10.1109/ELNANO50318.2020.9088789.

Pong P. Chu (2018) FPGA Prototyping by Systemverilog Examples: Xilinx MicroBlaze MCS SoC Edition (2nd ed.) John Wiley & Sons Inc.

About

UART controller that uses a master-slave architecture to enstablish a communication with the other device during the configuration process. This repository provides RTL code and testbench for the device synthesis and simulation, as well as a simple driver to use it in your system.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published