From 7f512741992ea4fb7d210a4b915b128b75f91675 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 5 Oct 2025 17:30:19 +0100 Subject: sync, and alternate tmds_encoders --- fpga/hp_lcd_driver/Makefile | 9 +- fpga/hp_lcd_driver/clkgen_artix7.vhdl | 15 ++- fpga/hp_lcd_driver/ebaz4205.xdc | 34 ++++--- fpga/hp_lcd_driver/output_stage.vhdl | 2 - fpga/hp_lcd_driver/tmds_encode.vhdl | 6 +- fpga/hp_lcd_driver/tmds_encoder_a.vhdl | 117 +++++++++++++++++++++++ fpga/hp_lcd_driver/tmds_encoder_b.vhdl | 143 ++++++++++++++++++++++++++++ fpga/hp_lcd_driver/tmds_encoder_c.vhdl | 162 ++++++++++++++++++++++++++++++++ fpga/hp_lcd_driver/tmds_phy_artix7.vhdl | 2 +- fpga/hp_lcd_driver/zynq7_ip/mmcm_0.tcl | 39 ++++---- fpga/hp_lcd_driver/zynq7_wrapper.vhdl | 5 +- 11 files changed, 479 insertions(+), 55 deletions(-) create mode 100644 fpga/hp_lcd_driver/tmds_encoder_a.vhdl create mode 100644 fpga/hp_lcd_driver/tmds_encoder_b.vhdl create mode 100644 fpga/hp_lcd_driver/tmds_encoder_c.vhdl (limited to 'fpga/hp_lcd_driver') diff --git a/fpga/hp_lcd_driver/Makefile b/fpga/hp_lcd_driver/Makefile index 6b72967..f61517d 100644 --- a/fpga/hp_lcd_driver/Makefile +++ b/fpga/hp_lcd_driver/Makefile @@ -1,14 +1,17 @@ DIP=10.16.66.113 -TARGETS= ebaz4205 #rando_a7 #smh-ac415b #spartan6 #ep4ce6 smh-ac415 +#TARGETS=rando_a7 +TARGETS=ebaz4205 +#TARGETS= ebaz4205 #rando_a7 #smh-ac415b #spartan6 #ep4ce6 smh-ac415 #fish:smh-ac415 -#better_default: build_rando_a7/hp_lcd_driver.svf -# ./prog_a7 better_default: ${TARGETS:%=build_%/hp_lcd_driver.svf} scp build_ebaz4205/out/hp_lcd_driver.bin ${DIP}:/boot/uboot/hp_lcd_driver.bin ssh -n ${DIP} reboot < /dev/null & +qbetter_default: build_rando_a7/hp_lcd_driver.svf + ./prog_a7 + default: ${TARGETS:%=build_%/hp_lcd_driver.svf} diff --git a/fpga/hp_lcd_driver/clkgen_artix7.vhdl b/fpga/hp_lcd_driver/clkgen_artix7.vhdl index 643b91f..046437f 100644 --- a/fpga/hp_lcd_driver/clkgen_artix7.vhdl +++ b/fpga/hp_lcd_driver/clkgen_artix7.vhdl @@ -21,9 +21,8 @@ architecture Behavioural of clkgen is signal clk_260m : std_logic; signal clk_78_571m : std_logic; - signal clk_80m : std_logic; - signal clk_24m : std_logic; - signal clk_48m : std_logic; + signal clk_26m : std_logic; + signal clk_52m : std_logic; signal clk_50m : std_logic; signal reset : std_logic; @@ -39,9 +38,9 @@ begin mmcm_0_i : mmcm_0 port map ( clk_in1 => clk_50m, clk_out1 => clk_260m, - clk_out2 => clk_80m, - clk_out3 => clk_48m, - clk_out4 => clk_24m, + clk_out2 => open, + clk_out3 => clk_52m, + clk_out4 => clk_26m, reset => reset, locked => locked ); @@ -53,8 +52,8 @@ begin ); o_clk_phy <= clk_260m; - o_clk <= clk_24m; - o_clk_x2 <= clk_48m; + o_clk <= clk_26m; + o_clk_x2 <= clk_52m; i_clk <= clk_78_571m; diff --git a/fpga/hp_lcd_driver/ebaz4205.xdc b/fpga/hp_lcd_driver/ebaz4205.xdc index 64660eb..30b073a 100644 --- a/fpga/hp_lcd_driver/ebaz4205.xdc +++ b/fpga/hp_lcd_driver/ebaz4205.xdc @@ -27,8 +27,8 @@ set_property PACKAGE_PIN W14 [get_ports {red_led}] set_property IOSTANDARD LVCMOS33 [get_ports *_led] -#set_property IOSTANDARD LVCMOS33 [get_ports clk_50m] -#set_property PACKAGE_PIN R4 [get_ports clk_50m] +set_property IOSTANDARD LVCMOS33 [get_ports clk_50m] +set_property PACKAGE_PIN N18 [get_ports clk_50m] #set_property PACKAGE_PIN T1 [get_ports {led_1}] #set_property IOSTANDARD LVCMOS33 [get_ports {led_1}] @@ -37,14 +37,10 @@ set_property PACKAGE_PIN G19 [get_ports {hdmi_b_p}]; #data2-5 set_property PACKAGE_PIN G20 [get_ports {hdmi_b_n}]; #data2-7 set_property PACKAGE_PIN K19 [get_ports {hdmi_g_p}]; #data2-13 set_property PACKAGE_PIN J19 [get_ports {hdmi_g_n}]; #data2-9 -#set_property PACKAGE_PIN T20 [get_ports {hdmi_g_p}]; #data3-16 -#set_property PACKAGE_PIN U20 [get_ports {hdmi_g_n}]; #data3-17 set_property PACKAGE_PIN L19 [get_ports {hdmi_r_p}]; #data2-16 set_property PACKAGE_PIN L20 [get_ports {hdmi_r_n}]; #data2-18 set_property PACKAGE_PIN L16 [get_ports {hdmi_c_p}]; #data2-15 set_property PACKAGE_PIN L17 [get_ports {hdmi_c_n}]; #data2-20 -#set_property PACKAGE_PIN N17 [get_ports {hdmi_c_p}]; #data3-9 -#set_property PACKAGE_PIN P18 [get_ports {hdmi_c_n}]; #data3-7 set_property IOSTANDARD TMDS_33 [get_ports {hdmi_c_p}] set_property IOSTANDARD TMDS_33 [get_ports {hdmi_c_n}] @@ -55,13 +51,13 @@ set_property IOSTANDARD TMDS_33 [get_ports {hdmi_g_n}] set_property IOSTANDARD TMDS_33 [get_ports {hdmi_b_p}] set_property IOSTANDARD TMDS_33 [get_ports {hdmi_b_n}] -##set_property DRIVE 16 [get_ports {hdmi_c_p}] -##set_property DRIVE 16 [get_ports {hdmi_c_n}] -##set_property DRIVE 16 [get_ports {hdmi_r_p}] -##set_property DRIVE 16 [get_ports {hdmi_r_n}] -##set_property DRIVE 16 [get_ports {hdmi_g_p}] -##set_property DRIVE 16 [get_ports {hdmi_g_n}] -##set_property DRIVE 16 [get_ports {hdmi_b_p}] +set_property DRIVE 16 [get_ports {hdmi_c_p}] +set_property DRIVE 16 [get_ports {hdmi_c_n}] +set_property DRIVE 16 [get_ports {hdmi_r_p}] +set_property DRIVE 16 [get_ports {hdmi_r_n}] +set_property DRIVE 16 [get_ports {hdmi_g_p}] +set_property DRIVE 16 [get_ports {hdmi_g_n}] +set_property DRIVE 16 [get_ports {hdmi_b_p}] # set_property PACKAGE_PIN K18 [get_ports {hdmi_vcc}]; #data2-11 (12 is gnd) set_property IOSTANDARD LVCMOS33 [get_ports {hdmi_vcc}] @@ -120,7 +116,8 @@ set_property IOSTANDARD LVCMOS33 [get_ports {hsync_in}] #set_property IOSTANDARD LVCMOS33 [get_ports {sys_rst_n}] #set_property PULLTYPE PULLUP [get_ports {sys_rst_n}] # -#create_clock -period 20.000 -name pcie_clkin [get_ports clk_50m] + +create_clock -period 20.000 -name pcie_clkin [get_ports clk_50m] ##set_false_path -from [get_ports pci_exp_rst_n] # @@ -147,10 +144,11 @@ set_property CONFIG_VOLTAGE 3.3 [current_design] set_property CFGBVS VCCO [current_design] -set_max_delay -from [get_pins {common_i/output0/tmds_o/phy_g/ld2_reg[*]/C}] -to [get_pins {common_i/output0/tmds_o/phy_g/ld_reg[*]/D}] 9 -set_max_delay -from [get_pins {common_i/output0/tmds_o/phy_b/ld2_reg[*]/C}] -to [get_pins {common_i/output0/tmds_o/phy_b/ld_reg[*]/D}] 9 -set_max_delay -from [get_pins {common_i/output0/tmds_o/phy_r/ld2_reg[*]/C}] -to [get_pins {common_i/output0/tmds_o/phy_r/ld_reg[*]/D}] 9 -set_max_delay -from [get_pins {common_i/output0/tmds_o/phy_c/ld2_reg[*]/C}] -to [get_pins {common_i/output0/tmds_o/phy_c/ld_reg[*]/D}] 9 +set_max_delay -from [get_pins {common_i/output0/tmds_o/phy_g/ld2_reg[*]/C}] -to [get_pins {common_i/output0/tmds_o/phy_g/ld_reg[*]/D}] 7 +set_max_delay -from [get_pins {common_i/output0/tmds_o/phy_b/ld2_reg[*]/C}] -to [get_pins {common_i/output0/tmds_o/phy_b/ld_reg[*]/D}] 7 +set_max_delay -from [get_pins {common_i/output0/tmds_o/phy_r/ld2_reg[*]/C}] -to [get_pins {common_i/output0/tmds_o/phy_r/ld_reg[*]/D}] 7 +set_max_delay -from [get_pins {common_i/output0/tmds_o/phy_c/ld2_reg[*]/C}] -to [get_pins {common_i/output0/tmds_o/phy_c/ld_reg[*]/D}] 7 + diff --git a/fpga/hp_lcd_driver/output_stage.vhdl b/fpga/hp_lcd_driver/output_stage.vhdl index 37ae297..9808a42 100644 --- a/fpga/hp_lcd_driver/output_stage.vhdl +++ b/fpga/hp_lcd_driver/output_stage.vhdl @@ -143,8 +143,6 @@ begin b <= b_in; - - dh : entity work.delay generic map(stages => 2) port map ( diff --git a/fpga/hp_lcd_driver/tmds_encode.vhdl b/fpga/hp_lcd_driver/tmds_encode.vhdl index fe69a56..ed5e288 100644 --- a/fpga/hp_lcd_driver/tmds_encode.vhdl +++ b/fpga/hp_lcd_driver/tmds_encode.vhdl @@ -30,7 +30,11 @@ architecture beh of tmds_encode is begin - c_p10 <= "1111100000"; +-- c_p10 <= "1111000001"; + c_p10 <= "1111100000"; +-- c_p10 <= "0111110000"; +-- c_p10 <= "0011111000"; +-- c_p10 <= "0001111100"; ctrl <= vsync & hsync; diff --git a/fpga/hp_lcd_driver/tmds_encoder_a.vhdl b/fpga/hp_lcd_driver/tmds_encoder_a.vhdl new file mode 100644 index 0000000..40f8dd4 --- /dev/null +++ b/fpga/hp_lcd_driver/tmds_encoder_a.vhdl @@ -0,0 +1,117 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity tmds_encoder is + port ( + clk : in std_logic; + sys_rst_n : in std_logic; + blank : in std_logic; + ctrl : in std_logic_vector(1 downto 0); + din : in std_logic_vector(7 downto 0); + dout : out std_logic_vector(9 downto 0) + ); +end tmds_encoder; + +architecture beh of tmds_encoder is + signal n_ones_din : integer range 0 to 8; + + signal xored, xnored : std_logic_vector(8 downto 0); + signal q_m : std_logic_vector(8 downto 0); + + -- a positive value represents the excess number of 1's that have been transmitted + -- a negative value represents the excess number of 0's that have been transmitted + signal disparity : signed(3 downto 0) := to_signed(0, 4); + -- difference between 1's and 0's (/2 since the last bit is never used) + signal diff : signed(3 downto 0) := to_signed(0, 4); + +begin + + -- ones counter for input data + process(din) is + variable c : integer range 0 to 8; + begin + c := 0; + for i in 0 to 7 loop + if din(i) = '1' then + c := c + 1; + end if; + end loop; + n_ones_din <= c; + end process; + + -- create xor encodings + xored(0) <= din(0); + encode_xor : for i in 1 to 7 generate + begin + xored(i) <= din(i) xor xored(i - 1); + end generate; + xored(8) <= '1'; + + -- create xnor encodings + xnored(0) <= din(0); + encode_xnor : for i in 1 to 7 generate + begin + xnored(i) <= din(i) xnor xnored(i - 1); + end generate; + xnored(8) <= '0'; + + -- use xnored or xored data based on the ones + q_m <= xnored when n_ones_din > 4 or (n_ones_din = 4 and din(0) = '0') else xored; + + -- ones counter for internal data + process(q_m) is + variable c : integer range 0 to 8; + begin + c := 0; + for i in 0 to 7 loop + if q_m(i) = '1' then + c := c + 1; + end if; + end loop; + diff <= to_signed(c-4, 4); + end process; + + process(clk) is + begin + if rising_edge(clk) then + if blank = '1' then + case ctrl is + when "00" => dout <= "1101010100"; + when "01" => dout <= "0010101011"; + when "10" => dout <= "0101010100"; + when others => dout <= "1010101011"; + end case; + disparity <= (others => '0'); + else + if disparity = 0 or diff = 0 then + -- xnored data + if q_m(8) = '0' then + dout <= "10" & not q_m(7 downto 0); + disparity <= disparity - diff; + -- xored data + else + dout <= "01" & q_m(7 downto 0); + disparity <= disparity + diff; + end if; + elsif (diff(diff'left) = '0' and disparity(disparity'left) = '0') or + (diff(diff'left) = '1' and disparity(disparity'left) = '1') then + dout <= '1' & q_m(8) & not q_m(7 downto 0); + if q_m(8) = '1' then + disparity <= disparity + 1 - diff; + else + disparity <= disparity - diff; + end if; + else + dout <= '0' & q_m; + if q_m(8) = '1' then + disparity <= disparity + diff; + else + disparity <= disparity - 1 + diff; + end if; + end if; + end if; + end if; + end process; +end beh; + diff --git a/fpga/hp_lcd_driver/tmds_encoder_b.vhdl b/fpga/hp_lcd_driver/tmds_encoder_b.vhdl new file mode 100644 index 0000000..a6e8b54 --- /dev/null +++ b/fpga/hp_lcd_driver/tmds_encoder_b.vhdl @@ -0,0 +1,143 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: tmds_encoder.vhd +-- Dependencies: none +-- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Full Version +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 8/7/2014 Scott Larson +-- Initial Public Release +-- Version 2.0 2/24/2014 Scott Larson +-- Corrected bug in the control signals +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY tmds_encoder IS + PORT( + clk : in std_logic; + sys_rst_n : in std_logic; + blank : in std_logic; + ctrl : in std_logic_vector(1 downto 0); + din : in std_logic_vector(7 downto 0); + dout : out std_logic_vector(9 downto 0) + ); +END tmds_encoder; + +ARCHITECTURE logic OF tmds_encoder IS + SIGNAL q_m : STD_LOGIC_VECTOR(8 DOWNTO 0); --internal data + SIGNAL ones_din : INTEGER RANGE 0 TO 8; --number of ones in the input data + SIGNAL ones_q_m : INTEGER RANGE 0 TO 8; --number of ones in the internal data + SIGNAL diff_q_m : INTEGER RANGE -8 TO 8; --number of ones minus the number of zeros in the internal data + SIGNAL disparity : INTEGER RANGE -16 TO 15; --disparity +BEGIN + + --count the ones in the input data byte + PROCESS(din) + VARIABLE ones: INTEGER RANGE 0 TO 8; + BEGIN + ones := 0; + FOR i IN 0 TO 7 LOOP + IF(din(i) = '1') THEN + ones := ones + 1; + END IF; + END LOOP; + ones_din <= ones; + END PROCESS; + + --process interval data to minimize transitions + PROCESS(din, q_m, ones_din) + BEGIN + IF(ones_din > 4 OR (ones_din = 4 AND din(0) = '0')) THEN + q_m(0) <= din(0); + q_m(1) <= q_m(0) XNOR din(1); + q_m(2) <= q_m(1) XNOR din(2); + q_m(3) <= q_m(2) XNOR din(3); + q_m(4) <= q_m(3) XNOR din(4); + q_m(5) <= q_m(4) XNOR din(5); + q_m(6) <= q_m(5) XNOR din(6); + q_m(7) <= q_m(6) XNOR din(7); + q_m(8) <= '0'; + ELSE + q_m(0) <= din(0); + q_m(1) <= q_m(0) XOR din(1); + q_m(2) <= q_m(1) XOR din(2); + q_m(3) <= q_m(2) XOR din(3); + q_m(4) <= q_m(3) XOR din(4); + q_m(5) <= q_m(4) XOR din(5); + q_m(6) <= q_m(5) XOR din(6); + q_m(7) <= q_m(6) XOR din(7); + q_m(8) <= '1'; + END IF; + END PROCESS; + + --count the ones in the internal data + PROCESS(q_m) + VARIABLE ones: INTEGER RANGE 0 TO 8; + BEGIN + ones := 0; + FOR i IN 0 TO 7 LOOP + IF(q_m(i) = '1') THEN + ones := ones + 1; + END IF; + END LOOP; + ones_q_m <= ones; + diff_q_m <= ones + ones - 8; --determine the difference between the number of ones and zeros + END PROCESS; + + --determine output and new disparity + PROCESS(clk) + BEGIN + IF(clk'EVENT AND clk = '1') THEN + IF(blank = '0') THEN + IF(disparity = 0 OR ones_q_m = 4) THEN + IF(q_m(8) = '0') THEN + dout <= NOT q_m(8) & q_m(8) & NOT q_m(7 DOWNTO 0); + disparity <= disparity - diff_q_m; + ELSE + dout <= NOT q_m(8)& q_m(8 DOWNTO 0); + disparity <= disparity + diff_q_m; + END IF; + ELSE + IF((disparity > 0 AND ones_q_m > 4) OR (disparity < 0 AND ones_q_m < 4)) THEN + dout <= '1' & q_m(8) & NOT q_m(7 DOWNTO 0); + IF(q_m(8) = '0') THEN + disparity <= disparity - diff_q_m; + ELSE + disparity <= disparity - diff_q_m + 2; + END IF; + ELSE + dout <= '0' & q_m(8 DOWNTO 0); + IF(q_m(8) = '0') THEN + disparity <= disparity + diff_q_m - 2; + ELSE + disparity <= disparity + diff_q_m; + END IF; + END IF; + END IF; + ELSE + CASE ctrl IS + WHEN "00" => dout <= "1101010100"; + WHEN "01" => dout <= "0010101011"; + WHEN "10" => dout <= "0101010100"; + WHEN "11" => dout <= "1010101011"; + WHEN OTHERS => NULL; + END CASE; + disparity <= 0; + END IF; + END IF; + END PROCESS; + +END logic; diff --git a/fpga/hp_lcd_driver/tmds_encoder_c.vhdl b/fpga/hp_lcd_driver/tmds_encoder_c.vhdl new file mode 100644 index 0000000..03415aa --- /dev/null +++ b/fpga/hp_lcd_driver/tmds_encoder_c.vhdl @@ -0,0 +1,162 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: tmds_encoder.vhd +-- Dependencies: none +-- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Full Version +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 8/7/2014 Scott Larson +-- Initial Public Release +-- Version 2.0 2/24/2014 Scott Larson +-- Corrected bug in the control signals +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY tmds_encoder IS + PORT( + clk : in std_logic; + sys_rst_n : in std_logic; + blank : in std_logic; + ctrl : in std_logic_vector(1 downto 0); + din : in std_logic_vector(7 downto 0); + dout : out std_logic_vector(9 downto 0) + ); +END tmds_encoder; + +ARCHITECTURE logic OF tmds_encoder IS + SIGNAL dind : std_logic_vector(7 downto 0); + SIGNAL q_m : STD_LOGIC_VECTOR(8 DOWNTO 0); --internal data + SIGNAL q_md : STD_LOGIC_VECTOR(8 DOWNTO 0); --internal data + SIGNAL ones_din : INTEGER RANGE 0 TO 8; --number of ones in the input data + SIGNAL ones_dind : INTEGER RANGE 0 TO 8; --number of ones in the input data + SIGNAL ones_q_md : INTEGER RANGE 0 TO 8; --number of ones in the internal data + SIGNAL diff_q_md : INTEGER RANGE -8 TO 8; --number of ones minus the number of zeros in the internal data + SIGNAL disparity : INTEGER RANGE -16 TO 15; --disparity +BEGIN + + --count the ones in the input data byte + PROCESS(din) + VARIABLE ones: INTEGER RANGE 0 TO 8; + BEGIN + ones := 0; + FOR i IN 0 TO 7 LOOP + IF(din(i) = '1') THEN + ones := ones + 1; + END IF; + END LOOP; + ones_din <= ones; + END PROCESS; + + process(clk) begin + if rising_edge(clk) then + dind<=din; + ones_dind<=ones_din; + end if; + end process; + + + --process interval data to minimize transitions + PROCESS(dind, q_m, ones_dind) + BEGIN + IF(ones_dind > 4 OR (ones_dind = 4 AND dind(0) = '0')) THEN + q_m(0) <= dind(0); + q_m(1) <= q_m(0) XNOR dind(1); + q_m(2) <= q_m(1) XNOR dind(2); + q_m(3) <= q_m(2) XNOR dind(3); + q_m(4) <= q_m(3) XNOR dind(4); + q_m(5) <= q_m(4) XNOR dind(5); + q_m(6) <= q_m(5) XNOR dind(6); + q_m(7) <= q_m(6) XNOR dind(7); + q_m(8) <= '0'; + ELSE + q_m(0) <= dind(0); + q_m(1) <= q_m(0) XOR dind(1); + q_m(2) <= q_m(1) XOR dind(2); + q_m(3) <= q_m(2) XOR dind(3); + q_m(4) <= q_m(3) XOR dind(4); + q_m(5) <= q_m(4) XOR dind(5); + q_m(6) <= q_m(5) XOR dind(6); + q_m(7) <= q_m(6) XOR dind(7); + q_m(8) <= '1'; + END IF; + END PROCESS; + + process(clk) begin + if rising_edge(clk) then + q_md<=q_m; + end if; + end process; + + + + --count the ones in the internal data + PROCESS(q_md) + VARIABLE ones: INTEGER RANGE 0 TO 8; + BEGIN + ones := 0; + FOR i IN 0 TO 7 LOOP + IF(q_md(i) = '1') THEN + ones := ones + 1; + END IF; + END LOOP; + ones_q_md <= ones; + diff_q_md <= ones + ones - 8; --determine the difference between the number of ones and zeros + END PROCESS; + + --determine output and new disparity + PROCESS(clk) + BEGIN + IF(clk'EVENT AND clk = '1') THEN + IF(blank = '0') THEN + IF(disparity = 0 OR ones_q_md = 4) THEN + IF(q_md(8) = '0') THEN + dout <= NOT q_md(8) & q_md(8) & NOT q_md(7 DOWNTO 0); + disparity <= disparity - diff_q_md; + ELSE + dout <= NOT q_md(8)& q_md(8 DOWNTO 0); + disparity <= disparity + diff_q_md; + END IF; + ELSE + IF((disparity > 0 AND ones_q_md > 4) OR (disparity < 0 AND ones_q_md < 4)) THEN + dout <= '1' & q_md(8) & NOT q_md(7 DOWNTO 0); + IF(q_md(8) = '0') THEN + disparity <= disparity - diff_q_md; + ELSE + disparity <= disparity - diff_q_md + 2; + END IF; + ELSE + dout <= '0' & q_md(8 DOWNTO 0); + IF(q_md(8) = '0') THEN + disparity <= disparity + diff_q_md - 2; + ELSE + disparity <= disparity + diff_q_md; + END IF; + END IF; + END IF; + ELSE + CASE ctrl IS + WHEN "00" => dout <= "1101010100"; + WHEN "01" => dout <= "0010101011"; + WHEN "10" => dout <= "0101010100"; + WHEN "11" => dout <= "1010101011"; + WHEN OTHERS => NULL; + END CASE; + disparity <= 0; + END IF; + END IF; + END PROCESS; + +END logic; diff --git a/fpga/hp_lcd_driver/tmds_phy_artix7.vhdl b/fpga/hp_lcd_driver/tmds_phy_artix7.vhdl index 604ec23..81e4b7e 100644 --- a/fpga/hp_lcd_driver/tmds_phy_artix7.vhdl +++ b/fpga/hp_lcd_driver/tmds_phy_artix7.vhdl @@ -77,8 +77,8 @@ begin sr <= ld; else sr(8 downto 0) <= sr (9 downto 1); - s <= sr(0); end if; + s <= sr(0); end if; end process; diff --git a/fpga/hp_lcd_driver/zynq7_ip/mmcm_0.tcl b/fpga/hp_lcd_driver/zynq7_ip/mmcm_0.tcl index 089476d..f394b48 100644 --- a/fpga/hp_lcd_driver/zynq7_ip/mmcm_0.tcl +++ b/fpga/hp_lcd_driver/zynq7_ip/mmcm_0.tcl @@ -5,32 +5,33 @@ source $source_dir/zynq7_config.tcl create_ip -name clk_wiz -vendor xilinx.com -library ip -version 6.0 -module_name mmcm_0 -dir $ip_dir set_property -dict [list \ - CONFIG.PRIM_IN_FREQ {50} \ + CONFIG.PRIM_IN_FREQ {50.0} \ CONFIG.CLKOUT2_USED {true} \ CONFIG.CLKOUT3_USED {true} \ CONFIG.CLKOUT4_USED {true} \ - CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {260} \ - CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {86.667} \ - CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {52} \ - CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {26} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {259.89583} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {86.63194} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {51.97917} \ + CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {25.98958} \ CONFIG.CLKIN1_JITTER_PS {200.0} \ - CONFIG.MMCM_CLKFBOUT_MULT_F {26.000} \ + CONFIG.MMCM_DIVCLK_DIVIDE {3} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {62.375} \ CONFIG.MMCM_CLKIN1_PERIOD {20.000} \ CONFIG.MMCM_CLKIN2_PERIOD {10.0} \ - CONFIG.MMCM_CLKOUT0_DIVIDE_F {5.000} \ - CONFIG.MMCM_CLKOUT1_DIVIDE {15} \ - CONFIG.MMCM_CLKOUT2_DIVIDE {25} \ - CONFIG.MMCM_CLKOUT3_DIVIDE {50} \ + CONFIG.MMCM_CLKOUT0_DIVIDE_F {4.000} \ + CONFIG.MMCM_CLKOUT1_DIVIDE {12} \ + CONFIG.MMCM_CLKOUT2_DIVIDE {20} \ + CONFIG.MMCM_CLKOUT3_DIVIDE {40} \ CONFIG.NUM_OUT_CLKS {4} \ - CONFIG.CLKOUT1_JITTER {120.627} \ - CONFIG.CLKOUT1_PHASE_ERROR {154.678} \ - CONFIG.CLKOUT2_JITTER {146.190} \ - CONFIG.CLKOUT2_PHASE_ERROR {154.678} \ - CONFIG.CLKOUT3_JITTER {165.425} \ - CONFIG.CLKOUT3_PHASE_ERROR {154.678} \ - CONFIG.CLKOUT4_JITTER {202.151} \ - CONFIG.CLKOUT4_PHASE_ERROR {154.678} \ - ] [get_ips mmcm_0] + CONFIG.CLKOUT1_JITTER {233.255} \ + CONFIG.CLKOUT1_PHASE_ERROR {408.086} \ + CONFIG.CLKOUT2_JITTER {268.940} \ + CONFIG.CLKOUT2_PHASE_ERROR {408.086} \ + CONFIG.CLKOUT3_JITTER {287.637} \ + CONFIG.CLKOUT3_PHASE_ERROR {408.086} \ + CONFIG.CLKOUT4_JITTER {316.603} \ + CONFIG.CLKOUT4_PHASE_ERROR {408.086} \ + ] [get_ips mmcm_0] generate_target all [get_ips] diff --git a/fpga/hp_lcd_driver/zynq7_wrapper.vhdl b/fpga/hp_lcd_driver/zynq7_wrapper.vhdl index 529a1b1..2c732a0 100644 --- a/fpga/hp_lcd_driver/zynq7_wrapper.vhdl +++ b/fpga/hp_lcd_driver/zynq7_wrapper.vhdl @@ -75,6 +75,7 @@ entity zynq7_wrapper is red_led : out std_logic; --in + clk_50m : in std_logic; video : in std_logic_vector(input_video_width -1 downto 0); hsync_in : in std_logic; vsync_in : in std_logic; @@ -142,7 +143,6 @@ architecture arch of zynq7_wrapper is signal eth0_mdio_mdio_o : std_logic; signal eth0_mdio_mdio_t : std_logic; - signal clk_50m : std_logic; signal sys_rst_n : std_logic; signal vnc_clk : std_logic; @@ -154,7 +154,6 @@ architecture arch of zynq7_wrapper is begin - clk_50m <= hp0_aclk; common_i : entity work.common generic map ( @@ -213,7 +212,7 @@ begin FCLK_CLK0 => eth0_clk_o, FCLK_CLK1 => gp0_aclk, FCLK_CLK2 => hp0_aclk, - FCLK_CLK2 => clk_50m, + FCLK_CLK2 => open, FCLK_RESET1_N => gp0_nrst, FCLK_RESET2_N => hp0_nrst, FCLK_RESET3_N => sys_rst_n, -- cgit v1.2.3