diff --git a/dvi-12bit/Makefile b/dvi-12bit/Makefile new file mode 100644 index 0000000..b903381 --- /dev/null +++ b/dvi-12bit/Makefile @@ -0,0 +1,13 @@ +PROJ = dvi-12bit +ADD_SRC = vga_core.v vga_timing.v + +PIN_DEF = ../icebreaker.pcf +DEVICE = up5k + +include ../main.mk + +gen_gamma_table: gen_gamma_table.o + gcc $< -o $@ -lm + +gamma_table.hex: gen_gamma_table + ./gen_gamma_table > gamma_table.hex diff --git a/dvi-12bit/README.txt b/dvi-12bit/README.txt new file mode 100644 index 0000000..d87db63 --- /dev/null +++ b/dvi-12bit/README.txt @@ -0,0 +1,17 @@ +This is an example design for driving the 3b and 12b HDMI PMOD modules from + Black Mesa Labs. The design drives 800x600 video with a 40 MHz input clock. + The actual video is an alternating display of: + 1) Color Test Pattern bars. + 2) Bouncing dot with changing colors ( Pong'ish ). + 3) Moving lines. + +Original design targets Xilinx Spartan3 FPGA and makes use of 2 Xilinx specific + primitive: + 1) BUFG : Global Clock Tree buffer + 2) FDDRCPE : "ODDR" output flop for mirroring internal clock tree outside. + +top.v : top level for FPGA design. +vga_core.v : Generates color test pattern, bouncing ball and moving lines. +vga_timing.v : Generates low level VGA timing for 800x600 with 40 MHz clock. + +Kevin M. Hubbard @ Black Mesa Labs 2017.12.14 diff --git a/dvi-12bit/dvi-12bit.v b/dvi-12bit/dvi-12bit.v new file mode 100644 index 0000000..4121fc2 --- /dev/null +++ b/dvi-12bit/dvi-12bit.v @@ -0,0 +1,202 @@ +/* **************************************************************************** +-- (C) Copyright 2017 Kevin M. Hubbard @ Black Mess Labs - All rights reserved. +-- Source file: top.v +-- Date: December 2017 +-- Author: khubbard +-- Description: Spartan3 Test Design +-- Language: Verilog-2001 and VHDL-1993 +-- Simulation: Mentor-Modelsim +-- Synthesis: Xilinst-XST +-- License: This project is licensed with the CERN Open Hardware Licence +-- v1.2. You may redistribute and modify this project under the +-- terms of the CERN OHL v.1.2. (http://ohwr.org/cernohl). +-- This project is distributed WITHOUT ANY EXPRESS OR IMPLIED +-- WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY +-- AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL +-- v.1.2 for applicable Conditions. +-- +-- 3b Module - Facing module pins +-- ------------------------------- +-- | 1-GRN 3-CLK 5-HS 7-NC GND 3V | +-- | 0-RED 2-BLU 4-DE 6-VS GND 3V | +-- ___|_______________________________|___ +-- | BML HDMI 3b color PMOD board | +-- --------------------------------------- +-- pmod_*_*<0> = red +-- pmod_*_*<1> = green +-- pmod_*_*<2> = blue +-- pmod_*_*<3> = pixel_clock +-- pmod_*_*<4> = data_enable +-- pmod_*_*<5> = hsync +-- pmod_*_*<6> = vsync +-- pmod_*_*<7> = nc +-- +-- +-- +-- 12b Module - Facing module pins +-- ---------------------------- ---------------------------- +-- | 1-R3 3-R1 5-G3 7-G1 GND 3V | | 1-B3 3-ck 5-B0 7-HS GND 3V | +-- | 0-R2 2-R0 4-G2 6-G0 GND 3V | | 0-B2 2-B1 4-DE 6-VS GND 3V | +-- ___|____________________________|______|____________________________|__ +-- | BML HDMI 12b color PMOD board | +-- ----------------------------------------------------------------------- +-- pmod_*_*<0> = r[2] pmod_*_*<0> = b[2] +-- pmod_*_*<1> = r[3] pmod_*_*<1> = b[3] +-- pmod_*_*<2> = r[0] pmod_*_*<2> = b[1] +-- pmod_*_*<3> = r[1] pmod_*_*<3> = ck +-- pmod_*_*<4> = g[2] pmod_*_*<4> = de +-- pmod_*_*<5> = g[3] pmod_*_*<5> = b[0] +-- pmod_*_*<6> = g[0] pmod_*_*<6> = vs +-- pmod_*_*<7> = g[1] pmod_*_*<7> = hs +-- +-- Revision History: +-- Ver# When Who What +-- ---- -------- -------- --------------------------------------------------- +-- 0.1 12.14.17 khubbard Creation +-- ***************************************************************************/ +`default_nettype none // Strictly enforce all nets to be declared + +module top +( + input CLK, + + output LEDR_N, // on board red + output LEDG_N, // on board green + input BTN_N, // user button aka reset + + output P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10, + output P1B1, P1B2, P1B3, P1B4, P1B7, P1B8, P1B9, P1B10 + + +);// module top + + + wire reset_loc; + wire clk_40m_tree; + reg [29:0] led_cnt; + reg [29:0] led_cnt_p1; + wire vga_de; + wire vga_ck; + wire vga_hs; + wire vga_vs; + wire [23:0] vga_rgb; + reg [31:0] random_num; + wire [7:0] r; + wire [7:0] g; + wire [7:0] b; + reg mode_bit; + wire ok_led_loc; + + + assign reset_loc = ~BTN_N; + +//----------------------------------------------------------------------------- +// PLL. +//----------------------------------------------------------------------------- +SB_PLL40_PAD #( + .DIVR(4'b0000), + // 40MHz ish to be exact it is 39.750MHz + //.DIVF(7'b0110111), // 42MHz + .DIVF(7'b0110101), // 39.750MHz + .DIVQ(3'b100), + .FILTER_RANGE(3'b001), + .FEEDBACK_PATH("SIMPLE"), + .DELAY_ADJUSTMENT_MODE_FEEDBACK("FIXED"), + .FDA_FEEDBACK(4'b0000), + .DELAY_ADJUSTMENT_MODE_RELATIVE("FIXED"), + .FDA_RELATIVE(4'b0000), + .SHIFTREG_DIV_MODE(2'b00), + .PLLOUT_SELECT("GENCLK"), + .ENABLE_ICEGATE(1'b0) +) usb_pll_inst ( + .PACKAGEPIN(CLK), + .PLLOUTCORE(clk_40m_tree), + //.PLLOUTGLOBAL(), + .EXTFEEDBACK(), + .DYNAMICDELAY(), + .RESETB(1'b1), + .BYPASS(1'b0), + .LATCHINPUTVALUE(), + //.LOCK(), + //.SDI(), + //.SDO(), + //.SCLK() +); + +//----------------------------------------------------------------------------- +// Flash an LED. Also control the VGA demos, toggle between color pattern and +// either a bouncing ball or moving lines. +//----------------------------------------------------------------------------- +always @ ( posedge clk_40m_tree or posedge reset_loc ) begin : proc_led + if ( reset_loc == 1 ) begin + random_num <= 32'd0; + led_cnt <= 30'd0; + led_cnt_p1 <= 30'd0; + ok_led_loc <= 0; + mode_bit <= 0; + end else begin + random_num <= random_num + 3; + ok_led_loc <= 0; + led_cnt_p1 <= led_cnt[29:0]; + led_cnt <= led_cnt + 1; + if ( led_cnt[19] == 1 ) begin + ok_led_loc <= 1; + end + if ( led_cnt[29:27] == 3'd0 ) begin + mode_bit <= 0; + end else begin + mode_bit <= 1; + end + + end // clk+reset +end // proc_led + +assign LEDG_N = ok_led_loc; + +// ---------------------------------------------------------------------------- +// VGA Timing Generator +// ---------------------------------------------------------------------------- +vga_core u_vga_core +( + .reset ( reset_loc ), + .random_num ( random_num[31:0] ), + .color_3b ( 1'b0 ), + .mode_bit ( mode_bit ), + .clk_dot ( clk_40m_tree ), + .vga_active ( vga_de ), + .vga_hsync ( vga_hs ), + .vga_vsync ( vga_vs ), + .vga_pixel_rgb ( vga_rgb[23:0] ) +); + assign r = vga_rgb[23:16]; + assign g = vga_rgb[15:8]; + assign b = vga_rgb[7:0]; + + +// ---------------------------------------------------------------------------- +// Assign the PMOD(s) for either 3b or 12b HDMI Module from Black Mesa Labs +// DDR Flop to Mirror pixel clock to TFP410 +// ---------------------------------------------------------------------------- +//FDDRCPE u1_FDDRCPE +//( +// .C0 ( clk_40m_tree ), .C1 ( ~ clk_40m_tree ), +// .CE ( 1'b1 ), +// .CLR ( 1'b0 ), .PRE ( 1'b0 ), +// .D0 ( 1'b1 ), .D1 ( 1'b0 ), +// .Q ( vga_ck ) +//); + +assign vga_ck = clk_40m_tree; + +// 3b for single-PMOD +//assign {P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10} = +// {g[7], vga_ck, vga_hs, 1'b0, r[7], b[7], vga_de, vga_vs}; + + +// 12b for dual-PMOD +assign {P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10} = + {r[7], r[5], g[7], g[5], r[6], r[4], g[6], g[4]}; +assign {P1B1, P1B2, P1B3, P1B4, P1B7, P1B8, P1B9, P1B10} = + {b[7], vga_ck, b[4], vga_hs, b[6], b[5], vga_de, vga_vs}; + +endmodule // top.v diff --git a/dvi-12bit/vga_core.v b/dvi-12bit/vga_core.v new file mode 100644 index 0000000..81265db --- /dev/null +++ b/dvi-12bit/vga_core.v @@ -0,0 +1,267 @@ +/* **************************************************************************** +-- (C) Copyright 2017 Kevin M. Hubbard @ Black Mesa Labs - All rights reserved. +-- Source file: vga_core.v +-- Date: 12.14.2017 +-- Author: khubbard +-- Description: Test design for VGA core. +-- Language: Verilog-2001 and VHDL-1993 +-- Simulation: Mentor-Modelsim +-- Synthesis: Xilinst-XST +-- License: This project is licensed with the CERN Open Hardware Licence +-- v1.2. You may redistribute and modify this project under the +-- terms of the CERN OHL v.1.2. (http://ohwr.org/cernohl). +-- This project is distributed WITHOUT ANY EXPRESS OR IMPLIED +-- WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY +-- AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL +-- v.1.2 for applicable Conditions. +-- +-- Revision History: +-- Ver# When Who What +-- ---- -------- -------- --------------------------------------------------- +-- 0.1 12.14.17 khubbard Creation +-- ***************************************************************************/ +`default_nettype none // Strictly enforce all nets to be declared + +module vga_core +( + input wire reset, + input wire color_3b, // 0 for 12b color, 1 for 3b color + input wire mode_bit, // 0 for test pattern, 1 for demos + input wire clk_dot, // 40 MHz dot clock + input wire [31:0] random_num, // seed for color and direction changes + output wire [23:0] vga_pixel_rgb, // Output pixel in Red,Green,Blue + output wire vga_active, // aka DE + output wire vga_hsync, // aka HS + output wire vga_vsync // aka VS +); + + reg [15:0] u0_pel_x; + reg [15:0] u0_pel_y; + reg [23:0] vga_rgb_tp; + reg [23:0] vga_rgb_ball; + reg [23:0] vga_rgb_line; + reg [23:0] vga_rgb; + wire [7:0] ramp; + reg [15:0] ball_x_dir; + reg [15:0] ball_y_dir; + reg [23:0] ball_x_pos; + reg [23:0] ball_y_pos; + reg [3:0] dir_chg_sr; + reg [23:0] ball_rgb; + reg [3:0] demo_mode; + reg mode_bit_p1; + reg [15:0] line_x_pos; + reg [15:0] line_y_pos; + reg [23:0] line_rgb; + + + wire u0_vid_new_frame; + wire u0_vid_new_line; + wire u0_vid_active; + wire u0_vga_hsync; + wire u0_vga_vsync; + + assign vga_active = u0_vid_active; + assign vga_hsync = u0_vga_hsync; + assign vga_vsync = u0_vga_vsync; + assign vga_pixel_rgb = vga_rgb[23:0]; + assign ramp = { u0_pel_x[6:0], 1'b0 }; + + +// ---------------------------------------------------------------------------- +// RGB Output Mux: Drive RGB with Either Test Pattern or one of two demos +// ---------------------------------------------------------------------------- +always @ ( posedge clk_dot ) begin : proc_out_mux + begin + mode_bit_p1 <= mode_bit; + if ( color_3b == 0 ) begin + if ( mode_bit == 0 ) begin + vga_rgb <= vga_rgb_tp[23:0]; + end else begin + if ( mode_bit_p1 == 0 ) begin + demo_mode <= ~demo_mode[3:0]; + end + if ( demo_mode[0] == 0 ) begin + vga_rgb <= vga_rgb_ball[23:0]; + end else begin + vga_rgb <= vga_rgb_line[23:0]; + end + end + end else begin + if ( mode_bit == 0 ) begin + vga_rgb[23:16] <= ( vga_rgb_tp[23:16] >= 8'd128 ) ? 8'hFF : 8'h00; + vga_rgb[15:8 ] <= ( vga_rgb_tp[15:8 ] >= 8'd128 ) ? 8'hFF : 8'h00; + vga_rgb[7:0 ] <= ( vga_rgb_tp[7:0 ] >= 8'd128 ) ? 8'hFF : 8'h00; + end else begin + if ( mode_bit_p1 == 0 ) begin + demo_mode <= ~demo_mode[3:0]; + end + if ( demo_mode[0] == 0 ) begin + vga_rgb[23:16] <= ( vga_rgb_ball[23:16] >= 8'd128 ) ? 8'hFF : 8'h00; + vga_rgb[15:8 ] <= ( vga_rgb_ball[15:8 ] >= 8'd128 ) ? 8'hFF : 8'h00; + vga_rgb[7:0 ] <= ( vga_rgb_ball[7:0 ] >= 8'd128 ) ? 8'hFF : 8'h00; + end else begin + vga_rgb[23:16] <= ( vga_rgb_line[23:16] >= 8'd128 ) ? 8'hFF : 8'h00; + vga_rgb[15:8 ] <= ( vga_rgb_line[15:8 ] >= 8'd128 ) ? 8'hFF : 8'h00; + vga_rgb[7:0 ] <= ( vga_rgb_line[7:0 ] >= 8'd128 ) ? 8'hFF : 8'h00; + end + end + end + end +end // proc_out_mux + + +// ---------------------------------------------------------------------------- +// Moving Lines +// ---------------------------------------------------------------------------- +always @ ( posedge clk_dot ) begin : proc_line + begin + if ( mode_bit == 0 ) begin + line_x_pos <= 16'd400; + line_y_pos <= 16'd300; + line_rgb <= random_num[23:0];// Change color + end else begin + if ( u0_vid_new_frame == 1 ) begin + line_x_pos <= line_x_pos - 1; + line_y_pos <= line_y_pos - 1; + if ( line_x_pos == 16'd0 || line_y_pos == 16'd0 ) begin + line_x_pos <= 16'd400; + line_y_pos <= 16'd300; + line_rgb <= random_num[23:0];// Change color + end + end + vga_rgb_line[23:0] <= { 8'd0, 8'd0, 8'd0 }; + if ( u0_pel_x == 16'd400 - line_x_pos[15:0] || + u0_pel_x == 16'd400 + line_x_pos[15:0] || + u0_pel_y == 16'd300 - line_y_pos[15:0] || + u0_pel_y == 16'd300 + line_y_pos[15:0] ) begin + vga_rgb_line[23:0] <= { 1'b1, line_rgb[22:0] }; + end + end + end // clk+reset +end // proc_line + + +// ---------------------------------------------------------------------------- +// Bouncing Ball +// ---------------------------------------------------------------------------- +always @ ( posedge clk_dot ) begin : proc_ball + begin + if ( mode_bit == 0 ) begin + ball_x_pos <= {8'd0, 8'd400, 8'd0 }; // Start in center of 800x600 + ball_y_pos <= {8'd0, 8'd300, 8'd0 }; + ball_rgb <= random_num[23:0]; // Get a random RGB Ball color + ball_x_dir <= { 2'b01, random_num[11:2] };// 4bit int,8bit fract direction + ball_y_dir <= { 2'b01, random_num[23:14] };// 4bit int,8bit fract direction + end else begin + // Move the ball every VSYNC and check for out of bounds. + // If out of bounds this VSYNC, but not previous VSYNC then invert the + // direction vectors. This effectively bounces a ball off perimeter wall + if ( u0_vid_new_frame == 1 ) begin + dir_chg_sr <= { dir_chg_sr[2:0], 1'b0 }; + ball_x_pos <= ball_x_pos + { {12{ball_x_dir[11]}}, ball_x_dir[11:0] }; + ball_y_pos <= ball_y_pos + { {12{ball_y_dir[11]}}, ball_y_dir[11:0] }; + + if ( ball_x_pos[23:8] < 32 && dir_chg_sr == 4'd0 ) begin + ball_x_dir <= ~ ball_x_dir[11:0]; + dir_chg_sr[0] <= 1; + end else if ( ball_x_pos[23:8] > 768 && dir_chg_sr == 4'd0 ) begin + ball_x_dir <= ~ ball_x_dir[11:0]; + dir_chg_sr[0] <= 1; + end + if ( ball_y_pos[23:8] < 32 && dir_chg_sr == 4'd0 ) begin + ball_y_dir <= ~ ball_y_dir[11:0]; + dir_chg_sr[0] <= 1; + end else if ( ball_y_pos[23:8] > 550 && dir_chg_sr == 4'd0 ) begin + ball_y_dir <= ~ ball_y_dir[11:0]; + dir_chg_sr[0] <= 1; + end + if ( dir_chg_sr[0] == 1 ) begin + ball_rgb <= random_num[23:0];// Change ball color every bounce + end + end + + vga_rgb_ball[23:0] <= { 8'h00, 8'h00, 8'h00 }; + // ~Ball~ is actually a 16x16 square centered around the ball x,y + if ( u0_pel_x > ball_x_pos[23:8] - 16'd8 && + u0_pel_x < ball_x_pos[23:8] + 16'd8 && + u0_pel_y > ball_y_pos[23:8] - 16'd8 && + u0_pel_y < ball_y_pos[23:8] + 16'd8 ) begin + vga_rgb_ball[23:0] <= { 1'b1, ball_rgb[22:0] }; + end + end + end // clk+reset +end // proc_ball + + +// ---------------------------------------------------------------------------- +// Test Pattern +// ---------------------------------------------------------------------------- +always @ ( posedge clk_dot ) begin : proc_test_pattern + begin + // Red Green Blue + if ( u0_pel_x[9:7] == 3'd6 ) begin + vga_rgb_tp <= { ramp, ramp, ramp };// White + end else if ( u0_pel_x[9:7] == 3'd5 ) begin + vga_rgb_tp <= { ramp, ramp, 8'd0 };// Yellow + end else if ( u0_pel_x[9:7] == 3'd4 ) begin + vga_rgb_tp <= { 8'd0, ramp, ramp };// Cyan + end else if ( u0_pel_x[9:7] == 3'd3 ) begin + vga_rgb_tp <= { 8'd0, ramp, 8'd0 };// Green + end else if ( u0_pel_x[9:7] == 3'd2 ) begin + vga_rgb_tp <= { ramp, 8'd0, ramp };// Magenta + end else if ( u0_pel_x[9:7] == 3'd1 ) begin + vga_rgb_tp <= { ramp, 8'd0, 8'd0 };// Red + end else if ( u0_pel_x[9:7] == 3'd0 ) begin + vga_rgb_tp <= { 8'd0, 8'd0, ramp };// Blue + end + + end // clk+reset +end // proc_test_pattern + + +// ---------------------------------------------------------------------------- +// Raster Counters. Count the Pixel Location in X and Y +// ---------------------------------------------------------------------------- +always @ ( posedge clk_dot ) begin : proc_u0_raster_cnt + begin + if ( u0_vid_new_frame == 1 ) begin + u0_pel_y <= 16'd0; + end else if ( u0_vid_new_line == 1 ) begin + if ( u0_pel_y == 16'hFFFF ) begin + u0_pel_y <= 16'hFFFF;// Prevent rollover + end else begin + u0_pel_y <= u0_pel_y + 1; + end + end // if ( vid_new_frame == 1 ) begin + + if ( u0_vid_new_line == 1 ) begin + u0_pel_x <= 16'd0; + end else begin + if ( u0_pel_x == 16'hFFFF ) begin + u0_pel_x <= 16'hFFFF;// Prevent rollover + end else begin + u0_pel_x <= u0_pel_x + 1; + end + end // if ( vid_new_line == 1 ) begin + + end // clk+reset +end // proc_u0_raster_cnt + + +// ---------------------------------------------------------------------------- +// VGA Timing Generator +// ---------------------------------------------------------------------------- +vga_timing u0_vga_timing +( + .reset ( reset ), + .clk_dot ( clk_dot ), + .vid_new_frame ( u0_vid_new_frame ), + .vid_new_line ( u0_vid_new_line ), + .vid_active ( u0_vid_active ), + .vga_hsync ( u0_vga_hsync ), + .vga_vsync ( u0_vga_vsync ) +); + + +endmodule // vga_core diff --git a/dvi-12bit/vga_timing.v b/dvi-12bit/vga_timing.v new file mode 100644 index 0000000..40465b1 --- /dev/null +++ b/dvi-12bit/vga_timing.v @@ -0,0 +1,284 @@ +/* **************************************************************************** +-- (C) Copyright 2013 Kevin M. Hubbard @ Black Mesa Labs - All rights reserved. +-- Source file: vga_timing.v +-- Date: April 20, 2013 +-- Author: khubbard +-- Description: Generate Analog VGA Timing signals +-- Language: Verilog-2001 and VHDL-1993 +-- Simulation: Mentor-Modelsim +-- Synthesis: Xilinst-XST +-- License: This project is licensed with the CERN Open Hardware Licence +-- v1.2. You may redistribute and modify this project under the +-- terms of the CERN OHL v.1.2. (http://ohwr.org/cernohl). +-- This project is distributed WITHOUT ANY EXPRESS OR IMPLIED +-- WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY +-- AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL +-- v.1.2 for applicable Conditions. +-- +-- Binary +-- -------- 2.5V ---------- 4V Node +-- | FPGA |----->| 74ACT245 |----[220ohm]--+--[100ohm]-GND : Red 0,0.7V +-- | |----->| |----[220ohm]--+--[100ohm]-GND : Grn 0,0.7V +-- | |----->| |----[220ohm]--+--[100ohm]-GND : Blu 0,0.7V +-- | |----->| |------------------------------> HSYNC +-- | |----->| VCC=5V |------------------------------> VSYNC +-- -------- ---------- +-- +-- 2 Shades +-- R(0)----->| 74ACT245 |----[560ohm]--+--[100ohm]-GND : Red at + +-- R(1)----->| |----[560ohm]--+ : Grn at + +-- +-- Note: Monitor has 75 termination for all signals, so the resistor divider +-- was adjusted to get 0.7V Max on the line. Assert R(0) and R(1) for +-- bright Red, or just one for a dimmer Red. +-- +-- Video Timing: +-- |-BP-|Active Video|-FP| +-- SYNC __/ \_____________________/ \_ +-- +-- HSYNC BP H FP Htotal VSYNC BP V FP Vtotal +-- 800x600 40MHz 60Hz 128 88 800 40 1056 4 23 600 1 628 +-- 1024x768 65MHz 60Hz 136 160 1024 24 1344 6 29 768 3 806 +-- 1280x1024 108MHz 60Hz 112 248 1280 48 1688 3 38 1024 1 1066 +-- 640x1024 54MHz 60Hz 56 124 640 24 844 3 38 1024 1 1066 +-- +-- Odd - Does this work ?? +-- 800x480 40MHz 45Hz 128 88 800 127 1143 128 32 480 127 767 +-- +-- Note: 40 / 10 = 4 x 27 = 108 +-- +-- ---------------------------------------------------------------------------- +-- The pinout for a standard 15-pin VGA-out connector Monitor side (male plug): +-- +-- /----------------------------------------------\ +-- \ 1 2 3 4 5 / +-- \ / +-- \ 6 7 8 9 10 / +-- \ / +-- \ 11 12 13 14 15 / +-- \------------------------------------/ +-- +-- 1: Red Video 0 - 0.7V +-- 2: Green Video 0 - 0.7V +-- 3: Blue Video 0 - 0.7V +-- 4: Monitor ID 2 (To video card from monitor) +-- 5: TTL Ground (Monitor self-test, used for testing purposes only) +-- +-- 6: Red Analog Ground +-- 7: Green Analog Ground +-- 8: Blue Analog Ground +-- 9: Key (Plugged hole, not used for electronic signals) +-- 10: Sync Ground (For both sync pins) +-- +-- 11: Monitor ID 0 (To video card from monitor) +-- 12: Monitor ID 1 (To video card from monitor) +-- 13: Horizontal Sync (To monitor from video card) 0 or 5.0V +-- 14: Vertical Sync (To monitor from video card) 0 or 5.0V +-- 15: Monitor ID 3 (To video card from monitor) +-- +-- +-- vid_active ___/ \_____/ \____/ \______/ .... / \___/ \___ +-- vid_new_frame _/ \___________________________________________________/ \___ +-- vid_new_line _/ \________/ \_________/ \_________/ \__ .... / \_____/ \___ +-- 0 1 2 3 1023 +-- +-- VGA to HDMI Converter $25 from Amazon +-- IO Crest VGA to HDMI Convertor with Audio support (SY-ADA31025). +-- Supports Resolutions: +-- 800x600 +-- 1024x768 1280x720 1280x800 1280x960 1280x1024 +-- 1360x768 +-- 1600x900 1600x1200 1680x1050 +-- 1920x1080 +-- +-- Lilliput 7" 669GL LCD Display +-- Native Resolution 800x480. Accepts HDMI 1920x1080 +-- +-- Revision History: +-- Ver# When Who What +-- ---- -------- -------- --------------------------------------------------- +-- 0.1 06.20.08 khubbard Creation +-- ***************************************************************************/ +`default_nettype none // Strictly enforce all nets to be declared + + +module vga_timing + ( + input wire reset, + input wire clk_dot, + output reg vid_new_frame, + output reg vid_new_line, + output reg vid_active, + output reg vga_hsync, + output reg vga_vsync + );// module vga_timing + +// 800x600 40MHz 60Hz +`define def_h_sync 16'd128 +`define def_h_bp 16'd88 +`define def_h_actv 16'd800 +`define def_h_fp 16'd40 +`define def_h_total 16'd1056 +`define def_v_sync 16'd4 +`define def_v_bp 16'd23 +`define def_v_actv 16'd600 +`define def_v_fp 16'd1 +`define def_v_total 16'd628 + +// 1280x1024 108MHz 60Hz +/* +`define def_h_sync 16'd112 +`define def_h_bp 16'd248 +`define def_h_actv 16'd1280 +`define def_h_fp 16'd48 +`define def_h_total 16'd1688 +`define def_v_sync 16'd3 +`define def_v_bp 16'd38 +`define def_v_actv 16'd1024 +`define def_v_fp 16'd1 +`define def_v_total 16'd1066 +*/ + +/* Attempt at 480p with 27.7MHz 60 Hz */ +/* From http://www.3dexpress.de/displayconfigx/timings.html */ +/* +`define def_h_sync 16'd40 +`define def_h_bp 16'd96 +`define def_h_actv 16'd720 +`define def_h_fp 16'd24 +`define def_h_total 16'd880 + +`define def_v_sync 16'd3 +`define def_v_bp 16'd32 +`define def_v_actv 16'd480 +`define def_v_fp 16'd10 +`define def_v_total 16'd525 +*/ + +`define state_h_sync 2'd0 +`define state_h_bp 2'd1 +`define state_h_actv 2'd2 +`define state_h_fp 2'd3 + +`define state_v_sync 2'd0 +`define state_v_bp 2'd1 +`define state_v_actv 2'd2 +`define state_v_fp 2'd3 + + reg [15:0] cnt_h; + reg [15:0] cnt_v; + reg [1:0] fsm_h; + reg [1:0] fsm_v; + reg hsync_loc; + reg vsync_loc; + reg vsync_loc_p1; + reg h_rollover; + + +//----------------------------------------------------------------------------- +// Flop the outputs +//----------------------------------------------------------------------------- +always @ (posedge clk_dot or posedge reset ) begin : proc_dout + if ( reset == 1 ) begin + vga_hsync <= 1'b0; + vga_vsync <= 1'b0; + vsync_loc_p1 <= 1'b0; + end else begin + vga_hsync <= hsync_loc; + vga_vsync <= vsync_loc; + vsync_loc_p1 <= vsync_loc; + end +end + + +//----------------------------------------------------------------------------- +// VGA State Machine for Horizontal Timing +//----------------------------------------------------------------------------- +always @ (posedge clk_dot or posedge reset ) begin : proc_vga_h + if ( reset == 1 ) begin + hsync_loc <= 1'b0; + vid_new_line <= 1'b0; + vid_new_frame <= 1'b0; + vid_active <= 1'b0; + cnt_h <= 16'd1; + fsm_h <= `state_h_sync; + h_rollover <= 1'b1; + end else begin + h_rollover <= 1'b0; + vid_new_line <= 1'b0; + vid_new_frame <= 1'b0; + vid_active <= 1'b0; + hsync_loc <= 1'b0; // Default to HSYNC OFF + cnt_h <= cnt_h + 16'd1; // Default to counting + + if ( fsm_h == `state_h_sync ) begin + hsync_loc <= 1'b1; + end + if ( fsm_h == `state_h_actv && fsm_v == `state_v_actv ) begin + vid_active <= 1'b1; + end + + if ( fsm_h == `state_h_sync && cnt_h == `def_h_sync ) begin + cnt_h <= 16'd1; + fsm_h <= fsm_h + 2'd1; + end + if ( fsm_h == `state_h_bp && cnt_h == `def_h_bp ) begin + cnt_h <= 16'd1; + fsm_h <= fsm_h + 2'd1; + vid_new_line <= 1'b1; + if ( fsm_v == `state_v_actv && cnt_v == 16'd2 ) begin + vid_new_frame <= 1'b1; + end + end + if ( fsm_h == `state_h_actv && cnt_h == `def_h_actv ) begin + cnt_h <= 16'd1; + fsm_h <= fsm_h + 2'd1; + end + if ( fsm_h == `state_h_fp && cnt_h == `def_h_fp ) begin + cnt_h <= 16'd1; + fsm_h <= fsm_h + 2'd1; + h_rollover <= 1'b1; + end + end +end // proc_vga_h + + +//----------------------------------------------------------------------------- +// VGA State Machine for Vertical Timing +//----------------------------------------------------------------------------- +always @ (posedge clk_dot or posedge reset ) begin : proc_vga_v + if ( reset == 1 ) begin + cnt_v <= 16'd1; + vsync_loc <= 1'b0; + fsm_v <= `state_v_fp; + end else begin + if ( h_rollover == 1'b1 ) begin + cnt_v <= cnt_v + 16'd1; // Default to counting + vsync_loc <= 1'b0; // Default to VSYNC OFF + if ( fsm_v == `state_v_sync && cnt_v == `def_v_sync ) begin + cnt_v <= 16'd1; + fsm_v <= fsm_v + 2'd1; + end + if ( fsm_v == `state_v_bp && cnt_v == `def_v_bp ) begin + cnt_v <= 16'd1; + fsm_v <= fsm_v + 2'd1; + end + if ( fsm_v == `state_v_actv && cnt_v == `def_v_actv ) begin + cnt_v <= 16'd1; + fsm_v <= fsm_v + 2'd1; + end + if ( fsm_v == `state_v_fp && cnt_v == `def_v_fp ) begin + cnt_v <= 16'd1; + fsm_v <= fsm_v + 2'd1; + vsync_loc <= 1'b1; + end + + if ( fsm_v == `state_v_sync && cnt_v != `def_v_sync ) begin + vsync_loc <= 1'b1; + end + end + end +end // proc_vga_v + + +endmodule // vga_timing