Skip to content

Verilog implementation of PAL, NTSC and SECAM color encoding

License

Notifications You must be signed in to change notification settings

Slamy/fpga-composite-video

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FPGA Composite Video Baseband Signal Encoder

This project aims to implement an encoder on FPGA basis to convert a digital YUV signal to PAL/NTSC or SECAM composite video.

After having started using a Xilinx Spartan-3AN in 2012, I've decided to port this project to the Tang Nano 9K as it is quite affordable, small and also usable for experimentation on a breadboard so it can be build by everyone.

Motivation

  • Learning more about IIR filters and their implementation in HDL
  • Setting again a foot into FPGA development
  • Learning more about alternatives to Xilinx and Altera
  • Finding a smaller and cheaper FPGA to build the smallest color Pong machine possible
  • Old video signals are quite interesting
  • Learning about Verilator

Features

  • PAL and NTSC
    • Single QAM and burst generator for both.
    • Phase alternation switchable on the fly
  • SECAM (not optimal due to lack of information)
    • Video pre-emphasis (not conform to standard, help from expert required)
    • HF Pre-emphasis (not conform to standard, help from expert required)
  • Comes with generator for video timing.
    • Variable number of lines for 50 and 60 Hz. Configuration on the fly.
    • Interlaced and non-interlaced mode (eg. 625 line PAL or 312 line PAL)
  • Comes with framebuffer device for bitmap test pictures.
    • Optional internal RGB to YCbCr conversion
    • Reads 24 bit and 32 bit pixel format
  • Optional delay lines to match luma and chroma filter delays.
  • Uses 8 bit R2R ladder as digital analog converter.
  • Uses direct digital synthesis for color carrier sine wave generation.
  • Sample rates and filter coefficients configurable via Python script.
  • Realtime configuration interface via UART and Python scripts.
    • Uses SciPy to generate filter coefficients
    • DAC sample rate can be changed using configure.py
  • "Hardware in the Loop" testing using USB video grabber
  • Verilator testbench with PNG export of raw video data
    • Verilator testbench also checks the IIR filters in lockstep against wider bit width

Project structure

  • rtl
    • composite_video_encoder.sv (the CVBS encoder itself)
    • top_testpic_generator.sv (example top level module for use with a framebuffer device)
  • sim
    • sim_top.sh (execute Verilator model which produces a png file with raw video data)
  • gowin
    • testpic_gen.gprj.gprj (GOWIN EDA example project for Tang Nano 9K)
  • tools
    • configure.py (calculates filter coefficients and direct digital synthesis parameters)
    • debugcom.py (interface class to access registers using the UART busmaster)
    • debugcom_hil_ebu75.py (produces EBU75 color stripes using all video norms, captures and checks them using USB video grabber)
    • debugcom_hil_parrot.py (records a reference picture for comparsion)
    • debugcom_hil_all.py (produces a whole set of test results)
    • debugcom_imageviewer.py (transfers an image into the framebuffer for display)
    • vlc_*.sh (helper functions to start VLC to show the input of the USB video grabber)

Architecture

System architecture of the encoder unit

How to build

Compared to other projects using GOWIN FPGAs, this is based on the official GOWIN EDA synthesis tools. The free educational version should be sufficient here. Open gowin/testpic_gen.gprj and start the synthesis.

Implementation on hardware

  • Proven in use on Tang Nano 9K (based on GW1NR-9)
    • 48 MHz sample rate
    • GOWIN EDA (V1.9.9 Beta-6) used as Synthesis tool
    • Uses 42% of logic elements for whole test picture generator project
    • Should take only 20% of logic elements as about the half is spent on the PSRAM controller and the debugging interface
    • Uses 68% of DSP units
      • 3 MULT9X9
      • 11 MULT18X18
      • 1 ALU54D

Photo of bread board with Tang Nano 9K and DAC circuit

Schematic of external video DAC

Example results

Picture of a parrot

These were recorded using this USB videograbber and OpenCV.

Reference

This picture of a parrot was cropped to fit into 4:3 and is then resized by the Python script to fit into the framebuffer. Parrot reference picture

PAL

PAL is the clear winner here. Reproduced in interlacing mode at a resolution of 720 x 576. It looks a little bit too bright though.

Parrot via PAL

NTSC

NTSC should show similar results to PAL but sadly doesn't. The color carrier is clearly visible. The used resolution here is 720 x 480. Also OpenCV doesn't scale the output to 4:3 and instead uses square pixels. This is more noticable with NTSC as with PAL where it is the opposite problem.

Parrot via NTSC

SECAM

SECAM is the problem child of this project. The preemphasis (Video and RF) doesn't work correctly, causing some horizontal artefacts in form of the popular "SECAM fire".

Parrot via SECAM

EBU75 and EBU100

From top to bottom we have EBU 75% color bars for NTSC, PAL and SECAM.

EBU75 color bards

This picture clearly shows the problems with SECAM as not the color itself is transmitted but instead the color transition. The preemphasis doesn't fit the deemphasis.

EBU100

Here EBU 100% to check for edge case problems.

SECAM stress test

As SECAM continued to cause issues a very specific test was created for analysis. A sepcial test picture with color gradients and multiple color bars. As SECAM doesn't transmit the current color but instead color changes this should help to check various scenarios in one picture.

It also contains a part from my Pong machine I'm currently working one.

SECAM stress test reference

Here is the result, received from the USB video grabber:

SECAM stress test result

It doesn't look that bad but SECAM surely has problems with sharp edges when it comes to my implementation.

Used devices to verify produced video signal

  • Fushicai USBTV007 Video Grabber [EasyCAP] 1b71:3002
  • Sony Bravia KDL-55W828B
  • Commodore 1084 (PAL decoding only)
  • FLUKE PM3394A

Used Tools

Troubleshooting

The color hue of NTSC is off

For some reason my USB video grabber has a 17 degree offset on the color burst. On my TV set this is not the case and the burst must occur with 0 degrees. Please use configure.py and set ntsc_burst_phase to 0 to fix this. The problem should then go away. I don't understand why I have this problem. Maybe someone else has an idea...

TODOs

  • NTSC chroma artefacts very present at the moment
  • There might be a gamma correction missing
  • Reduce amount of used DSPs
  • Ask GOWIN support for help with synthesis problems
  • Fixing SECAM (might be impossible due to lack of info)
  • HIL verify issues, OpenCV is not very consistent when capturing video footage
    • VLC is as bright as a 1084 but seems to change brightness on the fly.
    • Auto Gain Control on VLC and 1084 but not OpenCV?
  • Cleanup register map

Used Resources to create this

System Verilog:

IIR filter design:

PAL/NTSC/SECAM:

PAL:

NTSC:

SECAM:

PSRAM:

YUV Framebuffer formats:

DAC:

Modelsim:

Colorful parrot picture for testing which is published under free license and can therefore be packaged with this project