-
Notifications
You must be signed in to change notification settings - Fork 35
Asynchronous serial receiver unit
Asynchronous serial receiver unit for the Icestick board, synthetized with Opensource Icestorm tools
- Baudrates: 300, 600, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
- Clock frequency: 12Mhz
- Start bits: 1
- Data bits: 8
- Parity: None
- Stop bits: 1
- Description language: Verilog
- Toolchain: Opensource: Yosys, Arachne-pnr, Icestorm project
Serial packages consist of three parts: the start bit, the 8-bit data and the stop bit
Example of the serial package for the K character (ASCII 0x4B: Binary: 01001011)
The serial receiver is encapsulated in the uart-rx entity
The receiver unit has 3 inputs and 2 outputs:
-
Inputs:
- clk: System clock (12MHz in the ICEstick board)
- rstn: Active low. When rstn is 0, the serial unit is reset (synchronous reset)
- rx: Serial input. The serial packages are received from this input
-
Outputs:
- data: 8-bit data to transmit
- rcv: Character received. When a new character is received, a pulse of duration 1 clock cycle is emitted, so that it can be used for capturing the data.
The step for receiving a character are the following:
- Wait until the rcv signal is 1. It will remains 1 only during 1 system clock cycle
- Capture the character (8 bits) from the data output
- Repeat the process
The implementation of the receiver is shown in the given block diagram:
It consist of the following parts:
- Data register (8 bits): For storing the received character. It is captured when the load signal is active (1)
- Shift register (10 bits): For storing the serial bits received. Every bit is captured when the clk_baud signal is 1. This signal determines the exact time for sampling the incoming bits
- Baud generator: It generates a pulse of 1 cycle periodically, according to the baud rate configured
- Bit counter: It counts the bits that have already been received. It is reset to 0 when the clear signal is set to 1
- Controller: The finite state machine that generates the clear, load and bauden control signals for controlling the transmitter
- D flip-flops: For registering the rx input signal and get it synchronized
The receiver controller is a finite state machine with four states:
- IDLE: The unit is waiting for the start bit of the character. When it is received, it is changed to the RCV state. The bit counter is set to 0 (clear signal is 1)
- RCV: The baud generator is enabled and the bits are stored into the shift register. When a serial package (10 bits) is received, the state is changed to LOAD
- LOAD: Store the received data. The load control signal is activated (1)
- DAV: (Data available). A new data is available for reading. The signal rcv is set to 1 during one clock cycle
This is a generic code for using the UART-rx in your designs in verilog. Of course, some details can change depending on the particular implementation (as for example the definitions of the wires)
//-- Baudrate definitions
`include "baudgen.vh"
//-- Definitions of wires to connecto to the unit
wire clk;
wire rstn;
wire rcv;
wire [7:0] data;
wire rx;
//-- Receiver unit instantiation
//-- Values for BAUDRATE
//-- `B115200, `B57600, `B38400, `B19200, `B9600, `B4800, `B2400,
//-- `B1200, `B600, `B300
uart_rx #(.BAUDRATE(`B115200))
RX0 (.clk(clk),
.rstn(rstn),
.rx(rx),
.rcv(rcv),
.data(data)
);
Two examples in verilog on how to use the UART-rx unit are shown