267 TT08 VGA FUN!

267 : TT08 VGA FUN!

Design render

Overview

tt08-vga-fun GDS layout

This is a mixed-signal design which is intended to drive an analog VGA display by producing analog colour signals (red, green, and blue) as well as digital HSYNC/VSYNC signals. It uses (roughly-designed) current steering DACs to hopefully produce analog outputs that can present an adequate RGB888 (24-bit) VGA image. A number of different test modes are available both for testing the performance of the design's DACs, as well as making simple pretty effects.

NOTE: Some external hardware will be required for actually buffering/biasing the analog signals to make them fully-compatible with a VGA monitor. See the "External hardware" section.

The "How to test" section will help you get things running quickly, but otherwise here are the features of this design:

  • There's a digital control block that offers different test modes and patterns. It operates from a 25MHz clock.
  • It latches your selected test mode on reset: set ui_in to the mode you want, and then reset the design.
  • It produces digital VGA outputs on uo_out pins, compatible with the Tiny VGA PMOD.
  • It implements three 8-bit DACs which produce analog outputs for each of the red, green, and blue channels.
  • The red and green channels (ua[1] and ua[2] respectively) produce output voltages estimated to be in the range 0.8-1.8V, using a current-steering design with internal pull-up resistors.
  • The red channel's "Vbias" voltage is exposed on ua[0]. This is set with a simple current mirror to be a nominal 1.373V, and could be pulled up or down a little externally.
  • The blue channel (ua[3]) uses a different segmented current-switching DAC design. It requires an external pull-up resistor of about 1.65k (to 1.8V) to produce an output voltage in the range 0.6-1.8V.
  • The blue channel's internal Vbias voltage can be set to one of 8 levels using a binary code on uio_in[7:5] (and can be varied, live).

The estimated typical current required by this design is on the order of 3mA: 500uA for each of the red and green channels (constant, due to their current steering nature), 750uA for the blue channel (varying, as it is just a current switching design), and some overhead for the digital control block.

NOTE: This design is flagged as using the 3.3V TT analog template, but it is only using the VDPWR (1.8V) and VGND lines -- a 3.3V strap is present, but unused.

This design improves on my previous tt06-grab-bag -- my 1st analog ASIC project, included on TT06, using 3 RDAC instances instead. With these current steering DACs, I'm hoping for an improved slew rate (estimated to be about 60-80ns; still below the target of 40ns, but better than the TT06 version which was estimated to be about 240ns, and demonstrated to be able to get down to ~100ns in silicon).

How it works

There is a digital control block which can be controlled by the state of the ui_in pins at reset. It has various test modes -- some of which are sensitive to changes in ui_in after reset -- and also a pass-through mode (i.e. digital input code on ui_in passes directly through to all 3 DACs, live).

The figure below shows some of the test patterns it can produce, but note that the image probably won't be this clear because of: (a) poor matching; and (b) slew simulated to be worse than 40nS will lead to a little bit of horizontal smearing:

Some example VGA patterns

The digital control block internally drives 3 (RGB) colour channels. Two of these (R/G) each have 8 positive and 8 negative polarity bits. This complementary polarity is required for switching those two channels' binary-weighted current steering transistors either one way or the other, maintaining an equal (estimated) current of 500µA per channel. Each channel's internal current sum is then converted to a voltage with an internal pull-up resistor that is about 2.34kΩ.

Current-steering DACs as used by Red and Green channels

Simulation of Red/Green DACs

Additionally the first analog output pin (ua[0]) is the internal VbiasR of the red channel DAC (gate voltage for current mirroring); this is for testing, but could possibly also be pulled up or down a little to see what effect it has on the red channel's output.

The blue channel has a different type of current-switching DAC (i.e. not differential internally) and relies on an external pull-up resistor (recommended: 1.65kΩ up to 1.8V) to convert its current sinking range of 0~730uA to a voltage in the range 0.6V-1.8V. It is a "segmented" design where each pair of input bits goes through a simple 2-to-3 thermometer encoder to switch on up to 3 current sink transistors each, which are binary-weighted (1x, 4x, 16x, 64x) per set. NOTE: The Vbias voltage inside this DAC is set to one of 8 different levels using a binary code on uio_in[7:5].

Segmented DAC schematic

Simulated performance of segmented DAC

How to test

  1. Connect the Tiny VGA PMOD to uo_out.
  2. Set uio_in[7:5] to 110 -- this sets the blue channel's Vbias to mid-range.
  3. Supply a 25MHz clock; this means each pixel is 40ns long.
  4. Set ui_in to 0001_0011.
  5. Pulse RESET.
  6. With a VGA monitor attached to the Tiny VGA PMOD, expect to see basic grey levels, and a binary-coded "line number" along the right-hand edge.
  7. An oscilloscope on each of ua[1] (red) and ua[2] (green), set to trigger on HSYNC, should show both ramping from about 0.8V to 1.8V.
  8. Use about ~1.65kΩ to pull ua[3] (blue) up to 1.8V, and on a scope it should ramp from about 0.6V to 1.8V.

For information on connecting the analog outputs to a VGA monitor, see below ("External hardware").

Other things to try:

  • If things are not working properly, you could try setting ui_in to 0, pulsing RESET, and then feeding in whatever values you want on ui_in (without a reset) after that. This will take whatever binary code you present on ui_in and pass it through to all 3 DACs.
  • Set ui_in to 0010_0001, pulse RESET, and expect to see the outputs inverting on every odd-numbered pixel; can be used to help test the slew rate.
  • Try varying uio_in[7:5] to change the current sink strength of the blue channel (by varying the internal Vbias for the blue DAC). Note that the bit order is reversed, and the codes are inverted, so given a 1.65k pull-up to 1.8V on ua[3]:
    • 111: Level 0, weakest Vbias (~0.3V); expect no output.
    • 011: Level 1, 0.86V; expected output range: 1.47-1.8V
    • 101: Level 2, 0.97V; range: 1.13-1.8V
    • 001: Level 3, 1.05V; range: 0.8-1.8V
    • 110: Level 4, 1.11V; range: 0.6-1.8V
    • 010: Level 5, 1.17V; range: 0.47-1.8V -- starting to become non-linear below 0.6V
    • 100: Level 6, 1.21V; range 0.4-1.8V
    • 000: Level 7, 1.26V; range 0.38-1.8V -- very non-linear
  • Try measuring the red channel's internal Vbias voltage on ua[0], being aware that probing it will probably offset it a little. Try tugging on it (pulling it up or down by 10-100mV) to see what effect it has on the red channel's output level.
  • If you have the analog outputs reliably driving a VGA display (through suitable op-amps), try selecting different interesting patterns by setting different ui_in values (followed by a RESET pulse), e.g. 0101_1010 (or its static equivalent: 0110_0000) or 0100_0000.

External hardware

Besides a 25MHz clock source and a VGA monitor, you can get away with a Tiny VGA PMOD connected to uo_out, but what you really want is something that can convert the analog outputs on ua[3:1] (i.e. {B,G,R} colour channel outputs) to the low-impedance (75Ω) 0-0.7V range required by a VGA monitor.

Note that whatever circuit you use for the red channel, exactly the same circuit will probably be what you use for the green channel too, since they use the same DAC design. The blue channel is the one that's different.

I'm yet to sketch out a suitable pair of op-amp circuits, but in any case you'll want:

  • one circuit that can take the 0.8-1.8V range of the R/G channels and convert them to a 0-0.7V range; and...
  • another circuit that typically converts 0.6-1.8V to the same 0-0.7V range, but which can also be adjusted, given the blue channel's Vbias can be varied using uio_in[7:5].

Note that for my TT06 analog VGA DAC project I used the TI OPA3355.

IO

#InputOutputBidirectional
0mode[0] / dac_in[0]r7vblank_out
1mode[1] / dac_in[1]g7hblank_out
2mode[2] / dac_in[2]b7
3mode[3] / dac_in[3]vsync
4mode[4] / dac_in[4]r6
5mode[5] / dac_in[5]g6bias1_in
6mode[6] / dac_in[6]b6bias2_in
7mode[7] / dac_in[7]hsyncbias3_in

Analog pins

uaPCB PinInternal indexDescription
0B410VbiasR
1B17r
2B39g
3B28b

User feedback

Chip location

Controller Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Analog Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Analog Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux tt_um_chip_rom (Chip ROM) tt_um_factory_test (TinyTapeout 8 Factory Test) tt_um_oscillating_bones (Oscillating Bones) tt_um_urish_charge_pump (Dickson Charge Pump) tt_um_bgr_agolmanesh (Bandgap Reference) tt_um_tnt_diff_rx (TT08 Differential Receiver test) tt_um_rejunity_vga_logo (VGA Tiny Logo (1 tile)) tt_um_tommythorn_maxbw (Asynchronous Multiplier) tt_um_mattvenn_r2r_dac_3v3 (Analog 8 bit 3.3v R2R DAC) tt_um_urish_simon (Simon Says memory game) tt_um_rebeccargb_universal_decoder (Universal Binary to Segment Decoder) tt_um_mattvenn_rgb_mixer (RGB Mixer demo5) tt_um_rebeccargb_hardware_utf8 (Hardware UTF Encoder/Decoder) tt_um_find_the_damn_issue (Find The Damn Issue) tt_um_brandonramos_VGA_Pong_with_NES_Controllers (VGA Pong with NES Controllers) tt_um_kb2ghz_xalu (4-bit minicomputer ALU) tt_um_rebeccargb_intercal_alu (INTERCAL ALU) tt_um_a1k0n_demo (Demo by a1k0n) tt_um_rburt16_bias_generator (Bias Generator) tt_um_zec_square1 ("SQUARE-1": VGA/audio demo) tt_um_jmack2201 (Sprite Bouncer with Looping Background Options) tt_um_ran_DanielZhu (Dice) tt_um_gfg_development_tinymandelbrot (TinyMandelbrot) tt_um_LnL_SoC (Lab and Lectures SoC) tt_um_htfab_pi_snake (Pi Snake) tt_um_tt08_aicd_playground (AICD Playground) tt_um_toivoh_demo (Sequential Shadows [TT08 demo competition]) tt_um_quarren42_demoscene_top (asic design is my passion) tt_um_crispy_vga (Crispy VGA) tt_um_MichaelBell_canon (TT08 Pachelbel's Canon demo) tt_um_shuangyu_top (Calculator) tt_um_wokwi_407306064811090945 (DDR throughput and flop aperature test) tt_um_08_sws (Sine Wave Synthesizer) tt_um_favoritohjs_scroller (VGA Scroller) tt_um_tt08_wirecube (Wirecube) tt_um_vga_glyph_mode (Glyph Mode) tt_um_a1k0n_vgadonut (VGA donut) tt_um_roy1707018 (RO) tt_um_analog_factory_test (TT08 Analog Factory Test) tt_um_sign_addsub (CMOS design of 4-bit Signed Adder Subtractor) tt_um_tinytapeout_logo_screensaver (VGA Screensaver with Tiny Tapeout Logo) tt_um_patater_demokit (Patater Demo Kit Waggling Rainbow on a Chip) tt_um_algofoogle_tt08_vga_fun (TT08 VGA FUN!) tt_um_simon_cipher (simon_cipher) tt_um_thexeno_rgbw_controller (Color Controller) tt_um_demosiine_sda (DemoSiine) tt_um_bytex64_munch (Munch) tt_um_alexjaeger_ringoscillator (5MHz Ring Oscillator) tt_um_cfib_demo (cfib Demoscene Entry) tt_um_wokwi_407852791999030273 (Simple 8 Bit ALU) tt_um_Richard28277 (4-bit ALU) tt_um_betz_morse_keyer (Morse Code Keyer) tt_um_nvious_graphics (nVious Graphics) tt_um_tiny_pll (Tiny PLL) tt_um_ezchips_calc (8-Bit Calculator) tt_um_hack_cpu (HACK CPU) tt_um_noritsuna_Vctrl_LC_oscillator (Voltage Controlled LC-Oscillator) tt_um_ring_divider (Divided Ring Oscillator) tt_um_2048_vga_game (2048 sliding tile puzzle game (VGA)) tt_um_morningjava_r2r_from_matt (Bucket Brigade) tt_um_ephrenm_tsal (TSAL_TT) tt_um_kapilan_alarm (Alarm Clock) tt_um_stochastic_addmultiply_CL123abc (Stochastic Multiplier, Adder and Self-Multiplier) tt_um_wokwi_407760296956596225 (tt08-octal-alu) tt_um_dlfloatmac (DL float MAC) tt_um_wakki_0123_Raw_Transistors (Raw_Transistors) tt_um_faramire_rotary_ring_wrapper (Rotary Encoder WS2812B Control) tt_um_devstdin_LDO_OSC (LDO BG IREF OSC) tt_um_frequency_counter (Frequency Counter SSD1306 OLED) tt_um_rom_test (TT08 SKY130 ROM 'YOLO' Test) tt_um_i2c_peripheral_stevej (i2c peripherals: leading zero count and fnv-1a hash) tt_um_yuri_panchul_schoolriscv_cpu_with_fibonacci_program (schoolRISCV CPU with Fibonacci program) tt_um_yuri_panchul_adder_with_flow_control (Adder with Flow Control) tt_um_brailliance (Brailliance) tt_um_nyan (nyan) tt_um_MichaelBell_mandelbrot (VGA Mandelbrot) tt_um_ssp_opamp (2-stage Opamp Designs) tt_um_fountaincoder_top_ad (pulse_add) tt_um_edwintorok (Rounding error) tt_um_mac (MAC) tt_um_dpmu (DPMU) tt_um_JAC_EE_segdecode (7 Segment Decode) tt_um_wokwi_408118380088342529 (Traffic-light-sequence) tt_um_shiftreg_test (TT08 SKY130 Shift Register 'YOLO' Test) tt_um_yuri_panchul_sea_battle_vga_game (Sea Battle) tt_um_benpayne_ps2_decoder (PS2 Decoder) tt_um_meriac_play_tune (Super Mario Tune on A Piezo Speaker) tt_um_comm_ic_bhavuk (Comm_IC) tt_um_daosvik_aesinvsbox (AES Inverse S-box) tt_um_wokwi_408216451206371329 (Logic Test) tt_um_micro_tiles_container (Micro tile container) tt_um_cattuto_sr_latch (TT08 - experiments with latch-based shift registers) tt_um_rejunity_vga_test01 (VGA Drop (audio/visual demo)) tt_um_silice (Warp) tt_um_wokwi_408231820749720577 (Abacus Lock) tt_um_jayjaywong12 (mulmul) tt_um_emmyxu_obstacle_detection (Obstacle Detection) tt_um_neural_navigators (Neural Net ASIC) tt_um_a1k0n_nyancat (VGA Nyan Cat) tt_um_rebeccargb_styler (Styler) tt_um_resfuzzy (resfuzzy) tt_um_cejmu (CEJMU Beers and Adders) tt_um_16_mic_beamformer_arghunter (16 Mic Beamformer) tt_um_pdm_pitch_filter_arghunter (PDM Pitch Filter) tt_um_pdm_correlator_arghunter (PDM Correlator) tt_um_ddc_arghunter (DDC) tt_um_i2s_to_pwm_arghunter (I2S to PWM ) tt_um_georgboecherer_vco (Analog Voltage Controlled Oscillator) tt_um_supermic_arghunter (Supermic ) tt_um_dmtd_arghunter (DMTD ) tt_um_htfab_bouncy_capsule (Bouncy Capsule) tt_um_samuelm_pwm_generator (PWM generator) tt_um_mattvenn_analog_ring_osc (Ring Oscillators) tt_um_toivoh_demo_deluxe (Sequential Shadows Deluxe [TT08 demo competition]) tt_um_vga_clock (VGA clock) tt_um_z2a_rgb_mixer (RGB Mixer demo) tt_um_faramire_stopwatch (Simple Stopwatch) tt_um_micro_tiles_container_group2 (Micro tile container (group 2)) tt_um_johshoff_metaballs (Metaballs) tt_um_top (Flame demo) tt_um_NicklausThompson_SkyKing (SkyKing Demo) tt_um_Electom_cla_4bits (4-bit CLA) tt_um_vga_cbtest (Generate VGA output for Color Blindness Test) tt_um_zoom_zoom (Zoom Zoom) tt_um_dpmunit (DPM_Unit) tt_um_clock_divider_arghunter (Clock Divider ) tt_um_dlmiles_poc_fskmodem_hdlctrx (FSK Modem +HDLC +UART (PoC)) tt_um_emilian_muxpga (TinyFPGA resubmit for TT08) tt_um_pyamnihc_dummy_counter (Dummy Counter) tt_um_whynot (Why not?) tt_um_sudana_ota5t_1 (5-T OTA) tt_um_dlmiles_tt08_poc_uart (UART) tt_um_dendraws_donut (donut) tt_um_wokwi_408237988946759681 (Counter) tt_um_tmkong_rgb_mixer (RGB Mixer) Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available