392 8N1 UART Transceiver

392 : 8N1 UART Transceiver

Design render

How it works

The tt_um_nuatlabs_uart design is a full-duplex, 8N1 (8 data bits, no parity, 1 stop bit) Universal Asynchronous Receiver-Transmitter (UART) peripheral hardened on the 130nm IHP SG13G2 BiCMOS process via Tiny Tapeout. It fits into a single standard tile (1x1) and features a runtime time-multiplexed bidirectional data bus that allows full 8-bit parallel data transfer using Tiny Tapeout's 8 shared GPIO pins (uio).

Architecture Overview

                      +---------------------------------------+
                      |         tt_um_nuatlabs_uart           |
                      |                                       |
    ui_in[0] (rxd) -->|--> [2-Stage Sync] --> [UART RX]       |
                      |                           |           |
                      |                        rx_data        |
                      |                           |           |
    ui_in[1] (tx_st)->|---------------------> [UART TX]       |
                      |                           |           |
                      |                          txd -------->|--> uo_out[0] (txd)
                      |                        tx_busy ------>|--> uo_out[1] (tx_busy)
                      |                        rx_valid ----->|--> uo_out[2] (rx_valid)
                      |                                       |
    ui_in[2] -------->|-- [Bus Multiplexer & Dir Control]     |
 (uio_load_mode)      |       |                      ^        |
                      |       v                      |        |
                      |   tx_data_bus             rx_data     |
                      |       |                      |        |
                      +-------|----------------------|--------+
                              v                      |
                         uio[7:0] (Input)       uio[7:0] (Output)
  1. UART Transmitter (uart_tx):

    • Implemented as a clean 3-block Moore Finite State Machine (ST_IDLE, ST_START, ST_DATA, ST_STOP).
    • Latches tx_data from the uio_in bus upon detecting a single-cycle high pulse on ui_in[1] (tx_start).
    • Drives uo_out[1] (tx_busy) high throughout transmission.
    • Frames the byte by outputting a low start bit (0), shifting 8 data bits out (LSB first), and terminating with a high stop bit (1) onto uo_out[0] (txd).
    • Bit duration is governed by the parameter BAUD_DIV = f_clk / baud_rate.
  2. UART Receiver (uart_rx):

    • Asynchronous serial input ui_in[0] (rxd) passes through a 2-stage flip-flop synchronizer (rxd_sync1, rxd_sync2) to eliminate metastability risks.
    • Falling edge detection initiates the start bit sequence.
    • Samples incoming data at the exact midpoint of each bit interval (BAUD_DIV / 2), providing maximum noise immunity and tolerance against clock jitter.
    • Shifts incoming bits into an internal shift register (LSB first).
    • Upon successful verification of the stop bit, latches the parallel byte into rx_data and asserts uo_out[2] (rx_valid) for exactly one clock cycle.
  3. Time-Multiplexed Bidirectional Data Bus (uio[7:0]):

    • Because standard Tiny Tapeout tiles provide 8 dedicated inputs, 8 dedicated outputs, and 8 bidirectional IOs, dedicating 16 separate pins for parallel TX and RX bytes is impossible.
    • This design uses ui_in[2] (uio_load_mode) to dynamically govern the direction of the bidirectional uio bank:
      • Load / Transmit Mode (uio_load_mode = 1): Sets uio_oe = 8'h00 (input mode). The external host or microcontroller presents the 8-bit byte to transmit on uio_in[7:0].
      • Read / Display Mode (uio_load_mode = 0): Sets uio_oe = 8'hFF (output mode). The chip drives the last successfully received byte onto uio_out[7:0].

Baud Rate Configuration

The hardware divider is parameterized via BAUD_DIV = f_clk / baud_rate:

  • In this build, BAUD_DIV is defaulted to 4 for rapid, deterministic simulation in Cocotb.
  • For physical silicon running at a typical devkit clock (e.g., 50 MHz internal clock, or 10 MHz), set the external clock frequency or divider according to the target baud (e.g. 9600, 115200, 1Mbaud).

How to test

1. Verification in Simulation (Cocotb)

Run the automated test suite from the repository root:

cd test
make clean
make SIM=icarus

The testbench validates 3 comprehensive scenarios:

  • test_uart_tx_shape: Checks bit timing and serial frame shape: start bit (0), 8 data bits (LSB-first), stop bit (1), and active duration of tx_busy.
  • test_uart_loopback_single_byte: Emulates an external jumper wire by dynamically copying uo_out[0] (txd) to ui_in[0] (rxd) cycle-by-cycle, verifying full transmission, reception, and reconstruction.
  • test_uart_loopback_multiple_bytes: Stress tests back-to-back transmissions across boundary and alternating values (0x00, 0xFF, 0x55, 0xAA, 0x81, 0x7E).

2. Physical Hardware Testing on Tiny Tapeout Devkit

A. Basic Bench Loopback Test (No External Tools Required)
  1. Connect a standard breadboard jumper wire between pin uo[0] (txd) and pin ui[0] (rxd).
  2. Set DIP switch ui[2] (uio_load_mode) to 1 (input mode).
  3. Set the 8 DIP switches on uio[7:0] to the desired 8-bit test byte (e.g., 0xA5 / 10100101).
  4. Pulse DIP switch or push button ui[1] (tx_start) high then low.
  5. Observe uo[1] (tx_busy) LED toggle high while transmitting.
  6. Observe uo[2] (rx_valid) LED pulse when reception completes.
  7. Flip switch ui[2] (uio_load_mode) to 0 (output mode).
  8. The 8 LEDs connected to uio[7:0] will display the received byte, matching the byte sent in step 3.
B. Interfacing with a Host PC (USB-to-UART Adapter)
  1. Connect a 3.3V USB-to-UART bridge (FTDI, CP2102, or RP2040):
    • PC TXD -> Tiny Tapeout ui[0] (rxd)
    • Tiny Tapeout uo[0] (txd) -> PC RXD
    • Common Ground (GND -> GND).
  2. Open a terminal (PuTTY, minicom, screen, or PySerial) at the baud rate configured for your clock frequency.
  3. Transmit characters from PC to chip or trigger transmissions from chip to PC.

External hardware

  • Minimal Loopback Demo: A single jumper wire connecting uo[0] to ui[0].
  • Host PC Interfacing: 3.3V USB-to-UART bridge adapter (CP2102, FT232R, or Raspberry Pi Pico).

IO

#InputOutputBidirectional
0rxd (serial input)txd (serial output)tx_data[0] (in) / rx_data[0] (out)
1tx_start (transmit start pulse)tx_busy (transmitter busy flag)tx_data[1] (in) / rx_data[1] (out)
2uio_load_mode (1=load tx_data, 0=show rx_data)rx_valid (receiver valid pulse)tx_data[2] (in) / rx_data[2] (out)
3tx_data[3] (in) / rx_data[3] (out)
4tx_data[4] (in) / rx_data[4] (out)
5tx_data[5] (in) / rx_data[5] (out)
6tx_data[6] (in) / rx_data[6] (out)
7tx_data[7] (in) / rx_data[7] (out)

Chip location

Controller Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Analog Mux Mux Mux Mux Mux Mux Mux Mux tt_um_chip_rom (Chip ROM) tt_um_factory_test (Tiny Tapeout Factory Test) tt_um_ieee_LDO (LDO) tt_um_chip_ieee_analog (IEEE Bandgap Reference) tt_um_snn_voice_calculator_mauro_ciccone (snn-voice-calculator) tt_um_hx2003_delay (4 Channel - 32 Tap Programmable Delay with Delay Locked Loop Calibration) tt_um_adxl362_test (tt_um_adxl362_test) tt_um_larsnit_cfar (1D CA/GO/SO CFAR radar detector) tt_um_abeccari_swsynth (Sine Wave Synthesizer) tt_um_dpi_adexp (AdExp DPI Neuron ) tt_um_140oo041_fpu130 (FPU-130) tt_um_blonghi_uart (uart) tt_um_directsgg_mini_proceo_8bit (Mini 8-bit Processor) tt_um_umaece1982_lfsr (Low-Power LFSR-Based Test Pattern Generator) tt_um_deploy_timer (launch deployment timer) tt_um_urish_simon (Simon Says memory game) tt_um_nimelli_kinematic_wave_engine (Kinematic Wave Engine) tt_um_multi_seg_monitor (Multi Segment Monitor) tt_um_UART_TX (project) tt_um_crc8_lfsr (CRC-8 Serial LFSR) tt_um_tinynpu4 (TinyNPU4) tt_um_alu_bns (6-bit multi function ALU ( eldawly_V2) ) tt_um_echoworld424_tpv (Timing-Prediction Test Vehicle) tt_um_gyro_lockin (Laser Gyro Lock-in Readout Core) tt_um_josue_olivos_sar_adc (4-Bit Charge-Redistribution SAR ADC Controller) tt_um_flower (VGA Flower) tt_um_vperumal_l1_fabric (Scalable Banked L1 Memory Fabric for Edge AI) tt_um_preinception_top (Preinception: Simple Compute Accelerator) tt_um_italu (iTALU: Interactive Testable Arithmetic Logic Unit) tt_um_neuron (4-Input Signed Neuron / Perceptron) tt_um_4tap_mac (4-Tap Signed MAC Unit) tt_um_mac_engine (DSP MAC Engine) tt_um_crypto_led_demo (QAMER CryptoUART: Encrypted UART with LED Status) tt_um_layernorm (LayerNorm) tt_um_ez130_8t_mystery (EZ130 8T Mystery Circuit) tt_um_sent2spi (SENT Receiver with SPI Interface) tt_um_llr_hepiarisc (Hepiarisc with SPI flash) tt_um_rebeccargb_vga_pride (VGA Pride) tt_um_hasi_ising (Oscillator Ising Machine) tt_um_c061618g2 (Circuitli C061618G2) tt_um_tiny_dram_pim (Tiny Dual-Channel DRAM-PIM Controller + PU) tt_um_Tbilisi_CORDIC_Engine (Tbilisi CORDIC Engine) tt_um_rahulmascarenhas_folded_nn (Frozen ternary backbone + loadable head) tt_um_miniMAC (miniMAC_IHP26b) tt_um_rumcajs (IEEE DOORSH) tt_um_sg13g2_mystery (SG13G2 Mystery Circuit) tt_um_ULSR88 (ULSR demo) tt_um_ez130_7t_mystery (EZ130 7T Mystery Circuit) tt_um_tinyopt4 (ieee_tt_tinyopt4) tt_um_vga_example (IEEE VGA Animated Beach) tt_um_hyphen133_drone_detection (IEEE Acoustic Drone Detector) tt_um_nuatlabs_fifo_pwm (Async FIFO with CDC + PWM Peripheral) tt_um_nuatlabs_uart (8N1 UART Transceiver) tt_um_eeg_threshold_detector (IEEE Digital EEG Threshold Event Detector) tt_um_smart_traffic (Smart Traffic Light Controller) tt_um_94442024_mini_cpu (Mini 8-bit Accumulator CPU) tt_um_wokwi_475369131246576641 (IEEE_UPB_TT_1) tt_um_aion (AION) tt_um_rebeccargb_hardware_utf8 (Hardware UTF Encoder/Decoder) tt_um_rebeccargb_universal_decoder (Universal Binary to Segment Decoder) tt_um_rebeccargb_intercal_alu (INTERCAL ALU) tt_um_flappy_bird (IEEE Flappy Bird VGA Game) tt_um_oryan01_alu (ALU CASS PUCV) tt_um_S4xU4 (S4xU4) tt_um_vga_ca (Space CA) tt_um_llr_simplenpu (simple SPI flash streaming NPU) tt_um_pucv_pspwm (3LFCC PS-PWM Modulator) tt_um_yuri_fpga (Tiny FPGA) tt_um_mikailgedik_inverted_inverters (Inverted inverters) tt_um_esauqch_hamming74 (Hamming(7,4) encoder/decoder (IEEE)) tt_um_hackin7_analog_experiments (TinyAnalogExperiments) tt_um_snake (snake game) tt_um_mini_kraken (Kraken IO Subprocessor) tt_um_fabien_pio (AstraPIO) tt_um_chiplab (ChipLab) tt_um_wokwi_475490677474407425 (Tiny_Divider) tt_um_c061618g2tr (Circuitli C061618G2TR) tt_um_catalinlazar_nanopio (nanoPIO) tt_um_catalinlazar_uart_spi_i2c_bridge (UART-SPI-I2C Bridge) tt_um_enzonappi_sent_i2c (SENT to I2C bridge) tt_um_kush1434_proof (Proof) tt_um_schwallsunk_signal_discriminator (Highspeed voltage discriminator) tt_um_tiarinix_ttihp_verilog_template (8-bit educational SAP-style CPU) tt_um_vga_glyph_mode (BOOTCAMP) tt_um_GiulioGirelli_packet_processor (Configurable Low-Latency Match-Action Packet Processor) tt_um_vga_tictactoe (Tic Tac Toe) tt_um_vga_dvd_player (DVD player) tt_um_clea_katseye_rain (KATSEYE) tt_um_romd_uart_hello (UART Hello World) tt_um_vga_snake (CDM PYTHON GAME) tt_um_vga_slot_machine (tt_um_vga_slot_machine) tt_um_jet_seq8b (SEQ8 Programmable Sequencer) tt_um_kibo_leak_inspect (KIBO Leak-Inspection Target Controller (VGA)) tt_um_endless_runner (Endless Runner) tt_um_omega_infinity_kaoru (OMEGA INFINITY KAORU 3D Metal Grid Processor) tt_um_nikleberg_mixer (Mixer) tt_um_lahnb_sgdma (TinyDMA: A Descriptor-Based Dual-PSRAM Memory Mover) tt_um_gstj_lockin (Digital IQ Lock-in (IEEE)) tt_um_benpayne_ps2_decoder (PS/2 Keyboard Decoder for 68k) tt_um_cass_s_ui_neuron_lif (Neurona LIF con Aprendizaje STDP Dinamico (IEEE)) tt_um_vga_glyph_mode_CDM_Matrix (CDM Matrix) tt_um_qd39l_xor_stream (Fixed-ROM XOR Stream Engine) tt_um_conv3x3 (3x3 Clock Rate Streaming Input Convolution Engine) tt_um_mc14500b_soc_extended (MC14500B Extended 1-bit Microcontroller SoC) tt_um_vga_hypno_spiral (tt_um_vga_hypno_spiral) tt_um_mattizen_morse_tree (Morse Tree LED Decoder) tt_um_CDM (Colegio de Muntinlupa DVD-like Display) tt_um_romd_uart_loader (UART SPI RAM Loader) tt_um_TscherterJunior_stapel_geraet (stapel gerät) tt_um_das2225_dna_accel (DNA_Accel) tt_um_tinysoc (TinySoC) tt_um_barrel_shifter (Barrel Shifter) tt_um_approx_mac_coprocessor (Approximate DSP: Time-Multiplexed MAC Coprocessor) tt_um_joesagents_market_split_oracle (Market-split oracle) tt_um_mgpauly1458_ringmeter (Ring oscillator frequency meter) tt_um_pettit_prism_lite (PRISM with Risc-V (TinyQV) SoC) tt_um_workshop_cpu (IEEE Workshop Simple CPU) tt_um_algofoogle_analog_junk (Simple comparator + 2 DACs analog layout in a 1x1 tile) tt_um_lkhanh_cordic (TinyQV SoC (Dual Memory Backend)) tt_um_4x4npu (4x4NPU: Dual-Lane INT4 Neural Accelerator) tt_um_abiaselli_izh_bridge_3x2 (Izhikevich event bridge (4 contexts)) tt_um_fabulous_ihp_26b (Tiny FABulous FPGA) tt_um_zanderivo_voronoi (Four-Metric VGA Nearest-Prototype Visualizer)