PYNQ-Z2_demos/hdmi-out-test/v/display_demo_dvi.v

158 lines
5.9 KiB
Coq
Raw Normal View History

`timescale 1ns / 1ps
//`default_nettype none
// Project F: Display Controller DVI Demo
// (C)2020 Will Green, Open source hardware released under the MIT License
// Learn more at https://projectf.io
// This demo requires the following Verilog modules:
// * display_clocks
// * display_timings
// * dvi_generator
// * serializer_10to1
// * async_reset
// * tmds_encoder_dvi
// * test_card_simple or another test card
module display_demo_dvi(
input wire [1:0] sel, // test card modifier. original output = 0
input wire CLK, // board clock: 100 MHz on Arty/Basys3/Nexys
input wire RST_BTN, // reset button
inout wire hdmi_tx_cec, // CE control bidirectional
input wire hdmi_tx_hpd, // hot-plug detect
inout wire hdmi_tx_rscl, // DDC bidirectional
inout wire hdmi_tx_rsda, // DDC bidirectional
output wire hdmi_tx_clk_n, // HDMI clock differential negative
output wire hdmi_tx_clk_p, // HDMI clock differential positive
output wire [2:0] hdmi_tx_n, // Three HDMI channels differential negative
output wire [2:0] hdmi_tx_p // Three HDMI channels differential positive
);
// Display Clocks
wire pix_clk; // pixel clock
wire pix_clk_5x; // 5x clock for 10:1 DDR SerDes
wire clk_lock; // clock locked?
display_clocks #( // 640x480 800x600 1280x720 1920x1080
.MULT_MASTER(37.125), // 31.5 10.0 37.125 37.125
.DIV_MASTER(5), // 5 1 5 5
.DIV_5X(2.0), // 5.0 5.0 2.0 1.0
.DIV_1X(10), // 25 25 10 5
.IN_PERIOD(10.0) // 100 MHz = 10 ns
)
display_clocks_inst
(
.i_clk(CLK),
.i_rst(~RST_BTN), // reset is active low on Arty & Nexys Video
.o_clk_1x(pix_clk),
.o_clk_5x(pix_clk_5x),
.o_locked(clk_lock)
);
// Display Timings
wire signed [15:0] sx; // horizontal screen position (signed)
wire signed [15:0] sy; // vertical screen position (signed)
wire h_sync; // horizontal sync
wire v_sync; // vertical sync
wire de; // display enable
wire frame; // frame start
display_timings #( // 640x480 800x600 1280x720 1920x1080
.H_RES(1280), // 640 800 1280 1920
.V_RES(720), // 480 600 720 1080
.H_FP(110), // 16 40 110 88
.H_SYNC(40), // 96 128 40 44
.H_BP(220), // 48 88 220 148
.V_FP(5), // 10 1 5 4
.V_SYNC(5), // 2 4 5 5
.V_BP(20), // 33 23 20 36
.H_POL(1), // 0 1 1 1
.V_POL(1) // 0 1 1 1
)
display_timings_inst (
.i_pix_clk(pix_clk),
.i_rst(!clk_lock),
.o_hs(h_sync),
.o_vs(v_sync),
.o_de(de),
.o_frame(frame),
.o_sx(sx),
.o_sy(sy)
);
// test card colour output
wire [7:0] w_red ,red ;
wire [7:0] w_green,green;
wire [7:0] w_blue ,blue ;
// Test Card: Simple - ENABLE ONE TEST CARD INSTANCE ONLY
test_card_simple #(
.H_RES(1280) // horizontal resolution
) test_card_inst (
.i_x (sx ),
.o_red (w_red ),
.o_green(w_green),
.o_blue (w_blue )
);
assign red = ( sel[0] )? ~w_red : w_red ;
assign green = ( sel[0] )? ~w_green: w_green;
assign blue = ( sel[0] )? ~w_blue : w_blue ;
// // Test Card: Squares - ENABLE ONE TEST CARD INSTANCE ONLY
// test_card_squares #(
// .H_RES(1280), // horizontal resolution
// .V_RES(720) // vertical resolution
// )
// test_card_inst (
// .i_x(sx),
// .i_y(sy),
// .o_red(red),
// .o_green(green),
// .o_blue(blue)
// );
// // Test Card: Gradient - ENABLE ONE TEST CARD INSTANCE ONLY
// localparam GRAD_STEP = 2; // step right shift: 480=2, 720=2, 1080=3
// test_card_gradient test_card_inst (
// .i_y(sy[GRAD_STEP+7:GRAD_STEP]),
// .i_x(sx[5:0]),
// .o_red(red),
// .o_green(green),
// .o_blue(blue)
// );
// TMDS Encoding and Serialization
wire tmds_ch0_serial, tmds_ch1_serial, tmds_ch2_serial, tmds_chc_serial;
dvi_generator dvi_out (
.i_pix_clk(pix_clk),
.i_pix_clk_5x(pix_clk_5x),
.i_rst(!clk_lock),
.i_de(de),
.i_data_ch0(blue),
.i_data_ch1(green),
.i_data_ch2(red),
.i_ctrl_ch0({v_sync, h_sync}),
.i_ctrl_ch1(2'b00),
.i_ctrl_ch2(2'b00),
.o_tmds_ch0_serial(tmds_ch0_serial),
.o_tmds_ch1_serial(tmds_ch1_serial),
.o_tmds_ch2_serial(tmds_ch2_serial),
.o_tmds_chc_serial(tmds_chc_serial) // encode pixel clock via same path
);
// TMDS Buffered Output
OBUFDS #(.IOSTANDARD("TMDS_33"))
tmds_buf_ch0 (.I(tmds_ch0_serial), .O(hdmi_tx_p[0]), .OB(hdmi_tx_n[0]));
OBUFDS #(.IOSTANDARD("TMDS_33"))
tmds_buf_ch1 (.I(tmds_ch1_serial), .O(hdmi_tx_p[1]), .OB(hdmi_tx_n[1]));
OBUFDS #(.IOSTANDARD("TMDS_33"))
tmds_buf_ch2 (.I(tmds_ch2_serial), .O(hdmi_tx_p[2]), .OB(hdmi_tx_n[2]));
OBUFDS #(.IOSTANDARD("TMDS_33"))
tmds_buf_chc (.I(tmds_chc_serial), .O(hdmi_tx_clk_p), .OB(hdmi_tx_clk_n));
assign hdmi_tx_cec = 1'bz;
assign hdmi_tx_rsda = 1'bz;
assign hdmi_tx_rscl = 1'b1;
endmodule