Skip to content

tommasocalzolari/e203_HDMI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

e203 HDMI Character Display on FPGA

An FPGA design project integrating a Hummingbird/e203 RISC-V CPU, custom Verilog RTL, dual-port video memory, UART firmware, and a TMDS/DVI transmitter on a Sipeed Tang Primer 20K. The system drives a 1280 × 720 display at 60 Hz, shows color bars after reset, renders a startup message, and then operates as a monochrome UART terminal.

Project information Target hardware
ContributorsTommaso Calzolari, Alessandro Pirini
CourseIntelligent Chip Design
UniversityTongji University
LocationShanghai, China
ProfessorZhang Lei
Project periodMarch 2024 – July 2024
DocumentationFinal project report · Board schematics
Sipeed Tang Primer 20K FPGA board
Tang Primer 20K documentation
HDMI reference design

Project requirements

All baseline and extended requirements defined in the report were implemented.

Type Requirement Result
Baseline Generate vertical color strips at power-up Completed
Baseline Display a predetermined monochrome sentence Completed
Baseline Receive and display ASCII characters over UART Completed
Extended Increase the video resolution 1280 × 720 at 60 Hz
Extended Add terminal behavior Enter and backspace supported
Extended Run on a Tang Primer 20K and physical HDMI display Completed
Extended Position text from software Configurable start cell implemented

Demo and result

Startup text displayed by the FPGA
Text mode — firmware-defined text rendered from DPRAM.
Eight vertical color strips displayed by the FPGA
Power-up mode — eight color strips at 1280 × 720 and 60 Hz.

The extra t in the captured message was deliberately added to confirm that a new ram.hex image had been included in synthesis.

System architecture

UART RX (0x10013004)
        │
        ▼
e203 CPU + C firmware + 16×16 ASCII bitmap
        │ writes to 0x10014004
        ▼
ICB peripheral ──► address generator ──► DPRAM
                                             │
HDMI timing/scanner ◄────────────────────────┘
        │ RGB + sync + data enable
        ▼
rPLL / clock divider ──► DVI_TX ──► TMDS ──► HDMI display

At reset, HDMI.v displays eight color strips while firmware writes the startup message into DPRAM. After the startup interval, mode_flag selects text mode. The first UART character erases the prompt and resets the terminal write position.

The DPRAM read address is:

((character_row × 40) + character_column) × 16 + bitmap_row

The design retains a 19,200 × 16-bit DPRAM (38.4 KiB). Each logical bitmap pixel is repeated as a 2 × 2 physical block, allowing the existing 16 × 16 glyph memory to drive a 40 × 22 character grid at 1280 × 720.

Main files

  • rtl/ip/my_ip/icb_bus_HDMI.v — memory-mapped ICB display register at 0x10014004.
  • rtl/ip/my_ip/address_gen.v — converts bitmap rows and control flags into DPRAM writes.
  • rtl/ip/my_ip/HDMI.v — video timing, color bars, text scanning, and RGB generation.
  • rtl/ip/my_ip/final.v — connects DPRAM, clocks, HDMI logic, and the TMDS transmitter.
  • firmware/hello_world/src/main.c — startup text, UART polling, positioning, and terminal controls.
  • firmware/hello_world/src/bsp/hbird-e200/drivers/bitmap/bitmap.c — 96 ASCII glyphs.
  • sim/sys_tb_top.sv — complete e203 system testbench and VCD setup.
  • gwin_prj/HDMI_fpga_project.gprj — Gowin implementation project using e203_soc_demo as top module.
  • rtl/ip/my_ip/data.v and test_*.v — isolated display-path tests used during development.

ASCII bitmap encoding

ASCII values 32–127 are stored as 16 × 16 monochrome glyphs. Each 16-bit value represents one row: 1 means white and 0 means black. The scanner reads from bit 15 to bit 0.

'y' = ASCII 121 → bitmap index 121 - 32 = 89
bitmap[89][13] = 0x6180 = 0b0110000110000000

Bit scan:   0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0
Pixels:     · █ █ · · · · █ █ · · · · · · ·

This lights logical pixels 1, 2, 7, and 8. Firmware sends row 13 as 0x000D6180: bits [19:16] select the row and bits [15:0] contain its pixels. Bits [31:27] provide startup-delete, backspace, enter, positioning, and terminal-start commands.

Firmware behavior

Firmware places Press any key to start at cell (8, 20), polls UART address 0x10013004, and writes sixteen bitmap rows per character to the HDMI register at 0x10014004. The first received byte clears the prompt; later bytes are displayed from the top-left terminal area. Enter, backspace, and software positioning are sent through control bits decoded by address_gen.v.

Final simulation

The final simulation connects the e203 CPU, compiled firmware, ICB peripheral, address generator, DPRAM, and HDMI scanner.

Color-strip waveform

Color-strip simulation waveform

At H_cnt = 164 and V_cnt = 47, the captured configuration enters active video. color_cnt_2 selects the first strip and all RGB outputs become 0xFF, producing white.

Startup-text waveform

Text rendering simulation waveform

Here mode_flag = 1, character column 12 selects y, and bitmap row 13 returns 0x6180. The four set bits enable pixel and drive white RGB output at the expected positions. The mode timer was shortened so text mode could be reached within the 30 ms simulation.

UART testing also confirmed that 0x79 (y) traveled through UART, firmware, ICB, and into DPRAM as the expected bitmap data.

From simulation to real hardware

  • The monitor did not accept the original 640 × 480 mode, so the timing generator was redesigned for 1280 × 720 at 60 Hz.
  • With about 100 KiB of free FPGA RAM, the design retained its 38.4 KiB DPRAM and enlarged pixels to 2 × 2 blocks instead of increasing framebuffer size.
  • Physical HDMI required a direct 27 MHz board clock, rPLL, divide-by-five pixel clock, and Gowin DVI_TX for differential TMDS output.
  • An asynchronous address generator worked in simulation but synthesized unreliably. The final version is clocked, accounts for DPRAM latency, and waits for stable CPU data before writing.
  • Long video simulations were reduced by shortening the startup timer and verifying UART data directly at the DPRAM boundary.

These changes also delivered the extended requirements: higher resolution, enter/backspace terminal controls, physical-board deployment, and software-defined text positioning.

How to run and test

Required tools are a riscv-none-elf GCC toolchain, GNU Make, Icarus Verilog/GTKWave or a Gowin-compatible simulator, and Gowin EDA/Programmer for hardware.

Firmware

cd firmware/hello_world/Debug
make clean && make

This generates the ram.hex file loaded by the e203 instruction memory.

Simulation

cd sim
bash sim_run_sys_tb.sh
vvp wave.out
gtkwave waveout.vcd

Run from sim/ so the relative ram.hex path resolves. The original scripts use Gowin device models; encrypted vendor IP may require Gowin EDA. Shorten the cnt_mode threshold to reproduce the text waveform in a 30 ms run, then restore it for hardware.

FPGA

Open gwin_prj/HDMI_fpga_project.gprj, relink its original absolute source paths if requested, and select:

  • Device: GW2A-LV18PG256C8/I7
  • Top module: e203_soc_demo
  • Constraints: gwin_prj/src/HDMI_fpga_project.cst

Run synthesis and place-and-route, then program gwin_prj/impl/pnr/HDMI_fpga_project.fs. Connect HDMI and use UART at 115200 baud to test text input, enter, and backspace.

Documentation

About

This repository is used for the Inteligent Chip Design course on RTL development for a physical HDMI peripheral

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors