summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames McKenzie <root@ka-ata-killa.panaceas.james.local>2025-04-27 01:50:05 +0100
committerJames McKenzie <root@ka-ata-killa.panaceas.james.local>2025-04-27 01:50:05 +0100
commit1b2a1318c6e00dacdb70682332558abf3263a5d2 (patch)
tree2d6a704c3f0f4e6eae26f26acc5d482cac6a386d
parent9b0c9c5c83a75c6190687a07177dfedcc2077fda (diff)
downloadhp_instrument_lcds-1b2a1318c6e00dacdb70682332558abf3263a5d2.tar.gz
hp_instrument_lcds-1b2a1318c6e00dacdb70682332558abf3263a5d2.tar.bz2
hp_instrument_lcds-1b2a1318c6e00dacdb70682332558abf3263a5d2.zip
note quite working
-rw-r--r--spartan6/hp_lcd_driver/Makefile4
-rw-r--r--spartan6/hp_lcd_driver/hp_lcd_driver.ucf15
-rw-r--r--spartan6/hp_lcd_driver/hp_lcd_driver.vhdl87
-rw-r--r--spartan6/hp_lcd_driver/output_analog.vhdl42
-rw-r--r--spartan6/hp_lcd_driver/output_stage.vhdl78
-rw-r--r--spartan6/hp_lcd_driver/pll_50_p10_p2_p.xco (renamed from spartan6/hp_lcd_driver/pll_50_91_18.xco)30
-rw-r--r--spartan6/hp_lcd_driver/serdes_n_to_1.vhdl118
-rw-r--r--spartan6/hp_lcd_driver/tmds_encoder.vhdl117
-rw-r--r--spartan6/hp_lcd_driver/tmds_output.vhdl167
-rw-r--r--spartan6/hp_lcd_driver/tmds_phy.vhdl66
10 files changed, 628 insertions, 96 deletions
diff --git a/spartan6/hp_lcd_driver/Makefile b/spartan6/hp_lcd_driver/Makefile
index bd2180e..39963a2 100644
--- a/spartan6/hp_lcd_driver/Makefile
+++ b/spartan6/hp_lcd_driver/Makefile
@@ -3,10 +3,10 @@ include relpath.mk
PART=xc6slx9-2-tqg144
TOP=hp_lcd_driver
BUILD=build
-VSRCS=synchronizer.vhdl debounce.vhdl edge_det.vhdl input_formatter.vhdl input_stage.vhdl output_formatter.vhdl output_analog.vhdl output_stage.vhdl hp_lcd_driver.vhdl
+VSRCS=synchronizer.vhdl debounce.vhdl edge_det.vhdl input_formatter.vhdl input_stage.vhdl output_formatter.vhdl output_analog.vhdl serdes_n_to_1.vhdl tmds_encoder.vhdl tmds_phy.vhdl tmds_output.vhdl output_stage.vhdl hp_lcd_driver.vhdl
UCF=hp_lcd_driver.ucf
UT=hp_lcd_driver.ut
-IPSRCS= pll_50_80.xco pll_50_91_18.xco vram.xco
+IPSRCS= pll_50_80.xco pll_50_p10_p2_p.xco vram.xco
DESIGN_NAME=${TOP}
ISE_HOME=/software/apps/xilinx/ISE/14.7/ISE_DS/ISE
ISE_BINDIR_32=${ISE_HOME}/bin/lin
diff --git a/spartan6/hp_lcd_driver/hp_lcd_driver.ucf b/spartan6/hp_lcd_driver/hp_lcd_driver.ucf
index 8e67eae..e4a5fc2 100644
--- a/spartan6/hp_lcd_driver/hp_lcd_driver.ucf
+++ b/spartan6/hp_lcd_driver/hp_lcd_driver.ucf
@@ -1,3 +1,14 @@
-NET "hdmi_r" IOSTANDARD = LVCMOS33;
-NET "hdmi_b" LOC = P67;
+#NET "hdmi_r" IOSTANDARD = LVCMOS33;
+#NET "hdmi_b" LOC = P67;
+NET "clk_50m_in" IOSTANDARD = LVCMOS33;
+NET "sys_rst_n" IOSTANDARD = LVCMOS33;
+NET "video(0)" IOSTANDARD = LVCMOS33;
+NET "video(1)" IOSTANDARD = LVCMOS33;
+NET "hsync_in" IOSTANDARD = LVCMOS33;
+NET "vsync_in" IOSTANDARD = LVCMOS33;
+NET "r_out" IOSTANDARD = LVCMOS33;
+NET "b_out" IOSTANDARD = LVCMOS33;
+NET "g_out" IOSTANDARD = LVCMOS33;
+NET "hsync_out" IOSTANDARD = LVCMOS33;
+NET "vsync_out" IOSTANDARD = LVCMOS33;
diff --git a/spartan6/hp_lcd_driver/hp_lcd_driver.vhdl b/spartan6/hp_lcd_driver/hp_lcd_driver.vhdl
index 7f52ca1..a5fc8d7 100644
--- a/spartan6/hp_lcd_driver/hp_lcd_driver.vhdl
+++ b/spartan6/hp_lcd_driver/hp_lcd_driver.vhdl
@@ -41,15 +41,20 @@ entity hp_lcd_driver is
video : in std_logic_vector(video_width-1 downto 0);
hsync_in : in std_logic;
vsync_in : in std_logic;
- red_out : out std_logic;
- blue_out : out std_logic;
- green_out : out std_logic;
+ r_out : out std_logic;
+ b_out : out std_logic;
+ g_out : out std_logic;
hsync_out : out std_logic;
vsync_out : out std_logic;
- hdmi_c : out std_logic;
- hdmi_r : out std_logic;
- hdmi_g : out std_logic;
- hdmi_b : out std_logic);
+ hdmi_c_p : out std_logic;
+ hdmi_c_n : out std_logic;
+ hdmi_r_p : out std_logic;
+ hdmi_r_n : out std_logic;
+ hdmi_g_p : out std_logic;
+ hdmi_g_n : out std_logic;
+ hdmi_b_p : out std_logic;
+ hdmi_b_n : out std_logic);
+
end hp_lcd_driver;
architecture Behavioral of hp_lcd_driver is
@@ -61,15 +66,19 @@ architecture Behavioral of hp_lcd_driver is
signal rd_addr : std_logic_vector(addr_width-1 downto 0);
signal rd_data : std_logic_vector(video_width-1 downto 0);
- signal red : std_logic_vector(7 downto 0);
- signal green : std_logic_vector(7 downto 0);
- signal blue : std_logic_vector(7 downto 0);
+ signal r : std_logic_vector(7 downto 0);
+ signal g : std_logic_vector(7 downto 0);
+ signal b : std_logic_vector(7 downto 0);
signal i_clk : std_logic;
- signal o_clk_5 : std_logic;
+
+ signal o_clk_locked : std_logic;
+-- signal o_clk_ub : std_logic;
signal o_clk : std_logic;
- signal o_clk_n : std_logic;
+-- signal o_clk_x2_ub : std_logic;
+ signal o_clk_x2 : std_logic;
+ signal o_clk_x10 : std_logic;
signal clk_50m : std_logic;
@@ -86,7 +95,6 @@ begin
);
-
ipll : entity work.pll_50_80
port map (
reset => sys_rst,
@@ -94,14 +102,25 @@ begin
clk_80_out => i_clk
);
- opll : entity work.pll_50_91_18
+ opll : entity work.pll_50_p10_p2_p
port map (
reset => sys_rst,
clk_50_in => clk_50m,
- clk_91_666_out => o_clk_5,
- clk_18_333_out => o_clk
+ pclk_x10_out => o_clk_x10,
+ pclk_x2_out => o_clk_x2,
+ pclk_out => o_clk,
+ LOCKED => o_clk_locked
);
+-- o_clk_x2_buf: BUFG port map (
+-- I=>o_clk_x2_ub,
+-- O=>o_clk_x2
+-- );
+-- o_clk_buf: BUFG port map (
+-- I=>o_clk_ub,
+-- O=>o_clk
+-- );
+
input0 : entity work.input_stage
generic map(
video_width => video_width,
@@ -137,6 +156,15 @@ begin
);
+ r<= x"ff" when rd_data(1)='1' else
+ x"00";
+ g<= x"ff" when rd_data(0)='1' else
+ x"ff" when rd_data(1)='1' else
+ x"00";
+ b<=x"00";
+
+
+
output0 : entity work.output_stage
-- works at 60Hz xrandr --newmode "$M" 18.24 384 400 440 600 592 593 596 613 -HSync +Vsync
@@ -154,22 +182,29 @@ begin
v_stride => 384
)
port map(
+ clk_locked => o_clk_locked,
clk => o_clk,
+ clk_x2 => o_clk_x2,
+ clk_x10 => o_clk_x10,
sys_rst_n => sys_rst_n,
vsync_in => vsync_in,
- red_in => red,
- green_in => green,
- blue_in => blue,
+ r_in => r,
+ g_in => g,
+ b_in => b,
addr_out => rd_addr,
- red_out => red_out,
- green_out => green_out,
- blue_out => blue_out,
+ r_out => r_out,
+ g_out => g_out,
+ b_out => b_out,
hsync_out => hsync_out,
vsync_out => vsync_out,
- hdmi_r => hdmi_r,
- hdmi_g => hdmi_g,
- hdmi_b => hdmi_b,
- hdmi_c => hdmi_c
+hdmi_c_p=> hdmi_c_p,
+hdmi_c_n=> hdmi_c_n,
+hdmi_r_p=> hdmi_r_p,
+hdmi_r_n=> hdmi_r_n,
+hdmi_g_p=> hdmi_g_p,
+hdmi_g_n=> hdmi_g_n,
+hdmi_b_p=> hdmi_b_p,
+hdmi_b_n=> hdmi_b_n
);
diff --git a/spartan6/hp_lcd_driver/output_analog.vhdl b/spartan6/hp_lcd_driver/output_analog.vhdl
index 35b509f..29870cf 100644
--- a/spartan6/hp_lcd_driver/output_analog.vhdl
+++ b/spartan6/hp_lcd_driver/output_analog.vhdl
@@ -9,16 +9,16 @@ entity output_analog is
clk : in std_logic;
sys_rst_n : in std_logic;
- red_in : in std_logic;
- green_in : in std_logic;
- blue_in : in std_logic;
+ r_in : in std_logic;
+ g_in : in std_logic;
+ b_in : in std_logic;
hsync_in : in std_logic;
vsync_in : in std_logic;
blank_in : in std_logic;
- red_out : out std_logic;
- green_out : out std_logic;
- blue_out : out std_logic;
+ r_out : out std_logic;
+ g_out : out std_logic;
+ b_out : out std_logic;
hsync_out : out std_logic;
vsync_out : out std_logic
);
@@ -28,9 +28,9 @@ end output_analog;
architecture beh of output_analog is
- signal red_r : std_logic;
- signal green_r : std_logic;
- signal blue_r : std_logic;
+ signal r_r : std_logic;
+ signal g_r : std_logic;
+ signal b_r : std_logic;
signal hsync_r : std_logic;
signal vsync_r : std_logic;
@@ -43,16 +43,16 @@ begin
process (sys_rst_n, clk)
begin
if sys_rst_n = '0' then
- red_r <= '0';
- green_r <= '0';
- blue_r <= '0';
+ r_r <= '0';
+ g_r <= '0';
+ b_r <= '0';
hsync_r <= '0';
vsync_r <= '0';
blank_r <= '0';
elsif rising_edge(clk) then
- red_r <= red_in;
- green_r <= green_in;
- blue_r <= blue_in;
+ r_r <= r_in;
+ g_r <= g_in;
+ b_r <= b_in;
hsync_r <= hsync_in;
vsync_r <= vsync_in;
blank_r <= blank_in;
@@ -64,15 +64,15 @@ begin
process (sys_rst_n, clk)
begin
if sys_rst_n = '0' then
- red_out <= '0';
- green_out <= '0';
- blue_out <= '0';
+ r_out <= '0';
+ g_out <= '0';
+ b_out <= '0';
hsync_out <= '0';
vsync_out <= '0';
elsif rising_edge(clk) then
- red_out <= red_r and not blank_r;
- green_out <= green_r and not blank_r;
- blue_out <= blue_r and not blank_r;
+ r_out <= r_r and not blank_r;
+ g_out <= g_r and not blank_r;
+ b_out <= b_r and not blank_r;
hsync_out <= hsync_r;
vsync_out <= vsync_r;
end if;
diff --git a/spartan6/hp_lcd_driver/output_stage.vhdl b/spartan6/hp_lcd_driver/output_stage.vhdl
index d5cf87a..8c33685 100644
--- a/spartan6/hp_lcd_driver/output_stage.vhdl
+++ b/spartan6/hp_lcd_driver/output_stage.vhdl
@@ -24,35 +24,41 @@ entity output_stage is
);
port
(
+ clk_locked : in std_logic;
clk : in std_logic;
+ clk_x2 : in std_logic;
+ clk_x10 : in std_logic;
sys_rst_n : in std_logic;
vsync_in : in std_logic;
addr_out : out std_logic_vector(addr_width - 1 downto 0);
- red_in : in std_logic_vector(7 downto 0);
- green_in : in std_logic_vector(7 downto 0);
- blue_in : in std_logic_vector(7 downto 0);
+ r_in : in std_logic_vector(7 downto 0);
+ g_in : in std_logic_vector(7 downto 0);
+ b_in : in std_logic_vector(7 downto 0);
- red_out : out std_logic;
- green_out : out std_logic;
- blue_out : out std_logic;
+ r_out : out std_logic;
+ g_out : out std_logic;
+ b_out : out std_logic;
hsync_out : out std_logic;
vsync_out : out std_logic;
- hdmi_c : out std_logic;
- hdmi_r : out std_logic;
- hdmi_g : out std_logic;
- hdmi_b : out std_logic
+ hdmi_c_p : out std_logic;
+ hdmi_c_n : out std_logic;
+ hdmi_r_p : out std_logic;
+ hdmi_r_n : out std_logic;
+ hdmi_g_p : out std_logic;
+ hdmi_g_n : out std_logic;
+ hdmi_b_p : out std_logic;
+ hdmi_b_n : out std_logic
);
end output_stage;
architecture beh of output_stage is
- signal n_clk : std_logic;
signal s_vsync_in : std_logic;
signal d_vsync_in : std_logic;
@@ -113,41 +119,53 @@ begin
output_analog : entity work.output_analog
port map(
sys_rst_n => sys_rst_n,
+
clk => clk,
hsync_in => hsync,
vsync_in => vsync,
blank_in => blank,
- red_in => green_in(7),
- green_in => green_in(6),
- blue_in => blue_in(7),
+ r_in => g_in(7),
+ g_in => g_in(6),
+ b_in => b_in(7),
- red_out => red_out,
- green_out => green_out,
- blue_out => blue_out,
+ r_out => r_out,
+ g_out => g_out,
+ b_out => b_out,
hsync_out => hsync_out,
vsync_out => vsync_out
);
+output_tmds: entity work.tmds_output
+ port map (
+ sys_rst_n => sys_rst_n,
+ pclk_locked => clk_locked,
+ pclk => clk,
+ pclk_x2 => clk_x2,
+ pclk_x10 => clk_x10,
+
+ r_in => r_in,
+ g_in => g_in,
+ b_in => b_in,
+ hsync => hsync,
+ vsync => vsync,
+ blank => blank,
+
+ tmds_c_out_p => hdmi_c_p,
+ tmds_c_out_n => hdmi_c_n,
+ tmds_r_out_p => hdmi_r_p,
+ tmds_r_out_n => hdmi_r_n,
+ tmds_g_out_p => hdmi_g_p,
+ tmds_g_out_n => hdmi_g_n,
+ tmds_b_out_p => hdmi_b_p,
+ tmds_b_out_n => hdmi_b_n
+);
- n_clk <= not clk;
- hdmi_r <= hsync;
- hdmi_g <= vsync;
- hdmi_b <= green_in(7);
- o_clk_buf : ODDR2
- port map (
- D0 => '1',
- D1 => '0',
- C0 => clk,
- C1 => n_clk,
- CE => '1',
- Q => hdmi_c
- );
end beh;
diff --git a/spartan6/hp_lcd_driver/pll_50_91_18.xco b/spartan6/hp_lcd_driver/pll_50_p10_p2_p.xco
index 1d02dba..9d75f11 100644
--- a/spartan6/hp_lcd_driver/pll_50_91_18.xco
+++ b/spartan6/hp_lcd_driver/pll_50_p10_p2_p.xco
@@ -1,7 +1,7 @@
##############################################################
#
# Xilinx Core Generator version 14.7
-# Date: Sat Apr 26 17:51:02 2025
+# Date: Sat Apr 26 23:17:11 2025
#
##############################################################
#
@@ -41,11 +41,11 @@ SELECT Clocking_Wizard xilinx.com:ip:clk_wiz:3.6
# BEGIN Parameters
CSET calc_done=DONE
CSET clk_in_sel_port=CLK_IN_SEL
-CSET clk_out1_port=clk_91_666_out
+CSET clk_out1_port=pclk_x10_out
CSET clk_out1_use_fine_ps_gui=false
-CSET clk_out2_port=clk_18_333_out
+CSET clk_out2_port=pclk_x2_out
CSET clk_out2_use_fine_ps_gui=false
-CSET clk_out3_port=CLK_OUT3
+CSET clk_out3_port=pclk_out
CSET clk_out3_use_fine_ps_gui=false
CSET clk_out4_port=CLK_OUT4
CSET clk_out4_use_fine_ps_gui=false
@@ -74,14 +74,14 @@ CSET clkout1_requested_out_freq=91.667
CSET clkout1_requested_phase=0.000
CSET clkout2_drives=BUFG
CSET clkout2_requested_duty_cycle=50.000
-CSET clkout2_requested_out_freq=18.333
+CSET clkout2_requested_out_freq=36.667
CSET clkout2_requested_phase=0.000
CSET clkout2_used=true
CSET clkout3_drives=BUFG
CSET clkout3_requested_duty_cycle=50.000
-CSET clkout3_requested_out_freq=100.000
+CSET clkout3_requested_out_freq=18.333
CSET clkout3_requested_phase=0.000
-CSET clkout3_used=false
+CSET clkout3_used=true
CSET clkout4_drives=BUFG
CSET clkout4_requested_duty_cycle=50.000
CSET clkout4_requested_out_freq=100.000
@@ -103,17 +103,17 @@ CSET clkout7_requested_out_freq=100.000
CSET clkout7_requested_phase=0.000
CSET clkout7_used=false
CSET clock_mgr_type=AUTO
-CSET component_name=pll_50_91_18
+CSET component_name=pll_50_p10_p2_p
CSET daddr_port=DADDR
CSET dclk_port=DCLK
CSET dcm_clk_feedback=2X
CSET dcm_clk_out1_port=CLKFX
-CSET dcm_clk_out2_port=CLK2X
-CSET dcm_clk_out3_port=CLK0
+CSET dcm_clk_out2_port=CLKDV
+CSET dcm_clk_out3_port=CLK2X
CSET dcm_clk_out4_port=CLK0
CSET dcm_clk_out5_port=CLK0
CSET dcm_clk_out6_port=CLK0
-CSET dcm_clkdv_divide=2.0
+CSET dcm_clkdv_divide=15.0
CSET dcm_clkfx_divide=6
CSET dcm_clkfx_multiply=11
CSET dcm_clkgen_clk_out1_port=CLKFX
@@ -189,7 +189,7 @@ CSET mmcm_notes=None
CSET mmcm_ref_jitter1=0.010
CSET mmcm_ref_jitter2=0.010
CSET mmcm_startup_wait=false
-CSET num_out_clks=2
+CSET num_out_clks=3
CSET override_dcm=false
CSET override_dcm_clkgen=false
CSET override_mmcm=false
@@ -203,10 +203,10 @@ CSET pll_clkin_period=20.000
CSET pll_clkout0_divide=6
CSET pll_clkout0_duty_cycle=0.500
CSET pll_clkout0_phase=0.000
-CSET pll_clkout1_divide=30
+CSET pll_clkout1_divide=15
CSET pll_clkout1_duty_cycle=0.500
CSET pll_clkout1_phase=0.000
-CSET pll_clkout2_divide=1
+CSET pll_clkout2_divide=30
CSET pll_clkout2_duty_cycle=0.500
CSET pll_clkout2_phase=0.000
CSET pll_clkout3_divide=1
@@ -266,4 +266,4 @@ CSET use_status=false
MISC pkg_timestamp=2012-05-10T12:44:55Z
# END Extra information
GENERATE
-# CRC: 95fa1f8c
+# CRC: d987c511
diff --git a/spartan6/hp_lcd_driver/serdes_n_to_1.vhdl b/spartan6/hp_lcd_driver/serdes_n_to_1.vhdl
new file mode 100644
index 0000000..dccf6af
--- /dev/null
+++ b/spartan6/hp_lcd_driver/serdes_n_to_1.vhdl
@@ -0,0 +1,118 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+library UNISIM;
+use UNISIM.vcomponents.all;
+
+
+entity serdes_n_to_1 is
+ generic (
+ SF : natural :=8
+ );
+ port (
+
+ioclk: in std_logic;
+serdesstrobe: in std_logic;
+reset : in std_logic;
+gclk : in std_logic;
+datain : in std_logic_vector(SF-1 downto 0);
+iob_data_out : out std_logic
+);
+end serdes_n_to_1;
+
+
+architecture beh of serdes_n_to_1 is
+
+signal cascade_di:std_logic;
+signal cascade_do:std_logic;
+signal cascade_ti:std_logic;
+signal cascade_to:std_logic;
+signal mdatain:std_logic_vector(8 downto 0);
+
+begin
+
+datain_for_1 : for b in 0 to SF -1 generate
+ mdatain(b)<=datain(b);
+end generate;
+
+datain_for_2 : for b in SF to 8 generate
+ mdatain(b)<='0';
+end generate;
+
+-- mdatain <= ( SF-1 downto 0 => datain, others =>'0');
+
+ oserdes_m : OSERDES2
+ generic map (
+ DATA_WIDTH => SF,
+ DATA_RATE_OQ => "SDR",
+ DATA_RATE_OT => "SDR",
+ SERDES_MODE => "MASTER",
+ OUTPUT_MODE => "DIFFERENTIAL"
+ )
+ port map (
+ OQ => iob_data_out,
+ OCE => '1',
+ CLK0 => ioclk,
+ CLK1 => '0',
+ IOCE => serdesstrobe,
+ RST => reset,
+ CLKDIV => gclk,
+ D4 => mdatain(7),
+ D3 => mdatain(6),
+ D2 => mdatain(5),
+ D1 => mdatain(4),
+-- TQ => ,
+ T1 => '0',
+ T2 => '0',
+ T3 => '0',
+ T4 => '0',
+ TRAIN => '0',
+ TCE => '1',
+ SHIFTIN1 => '1', -- Dummy input in Master
+ SHIFTIN2 => '1', -- Dummy input in Master
+ SHIFTIN3 => cascade_do, -- Cascade output D data from slave
+ SHIFTIN4 => cascade_to, -- Cascade output T data from slave
+ SHIFTOUT1 => cascade_di, -- Cascade input D data to slave
+ SHIFTOUT2 => cascade_ti -- Cascade input T data to slave
+-- SHIFTOUT3 => , -- Dummy output in Master
+-- SHIFTOUT4 => -- Dummy output in Master
+ );
+
+ oserdes_s : OSERDES2
+ generic map (
+ DATA_WIDTH=>SF, -- SERDES word width. This should match the setting is BUFPLL
+ DATA_RATE_OQ=>"SDR", -- <SDR>, DDR
+ DATA_RATE_OT =>"SDR", -- <SDR>, DDR
+ SERDES_MODE =>"SLAVE", -- <DEFAULT>, MASTER, SLAVE
+ OUTPUT_MODE =>"DIFFERENTIAL"
+ )
+ port map (
+-- OQ => ,
+ OCE => '1',
+ CLK0 => ioclk,
+ CLK1 => '0',
+ IOCE => serdesstrobe,
+ RST => reset,
+ CLKDIV => gclk,
+ D4 => mdatain(3),
+ D3 => mdatain(2),
+ D2 => mdatain(1),
+ D1 => mdatain(0),
+-- TQ => ,
+ T1 => '0',
+ T2 => '0',
+ T3 => '0',
+ T4 => '0',
+ TRAIN => '0',
+ TCE => '1',
+ SHIFTIN1 => cascade_di, -- Cascade input D from Master
+ SHIFTIN2 => cascade_ti, -- Cascade input T from Master
+ SHIFTIN3 => '1', -- Dummy input in Slave
+ SHIFTIN4 => '1', -- Dummy input in Slave
+-- SHIFTOUT1 => , -- Dummy output in Slave
+-- SHIFTOUT2 => , -- Dummy output in Slave
+ SHIFTOUT3 => cascade_do, -- Cascade output D data to Master
+ SHIFTOUT4 => cascade_to) ; -- Cascade output T data to Master
+
+end beh;
diff --git a/spartan6/hp_lcd_driver/tmds_encoder.vhdl b/spartan6/hp_lcd_driver/tmds_encoder.vhdl
new file mode 100644
index 0000000..0a83498
--- /dev/null
+++ b/spartan6/hp_lcd_driver/tmds_encoder.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/spartan6/hp_lcd_driver/tmds_output.vhdl b/spartan6/hp_lcd_driver/tmds_output.vhdl
new file mode 100644
index 0000000..3d169ee
--- /dev/null
+++ b/spartan6/hp_lcd_driver/tmds_output.vhdl
@@ -0,0 +1,167 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+library UNISIM;
+use UNISIM.vcomponents.all;
+
+
+entity tmds_output is
+ port (
+ sys_rst_n : in std_logic;
+ pclk_locked: in std_logic;
+ pclk: in std_logic;
+ pclk_x2: in std_logic;
+ pclk_x10: in std_logic;
+ r_in: in std_logic_vector(7 downto 0);
+ g_in: in std_logic_vector(7 downto 0);
+ b_in: in std_logic_vector(7 downto 0);
+ hsync: in std_logic;
+ vsync: in std_logic;
+ blank: in std_logic;
+ tmds_c_out_p: out std_logic;
+ tmds_c_out_n: out std_logic;
+ tmds_r_out_p: out std_logic;
+ tmds_r_out_n: out std_logic;
+ tmds_g_out_p: out std_logic;
+ tmds_g_out_n: out std_logic;
+ tmds_b_out_p: out std_logic;
+ tmds_b_out_n: out std_logic
+);
+end tmds_output;
+
+
+architecture beh of tmds_output is
+
+signal ctrl: std_logic_vector(1 downto 0);
+signal r_p10:std_logic_vector(9 downto 0);
+signal g_p10:std_logic_vector(9 downto 0);
+signal b_p10:std_logic_vector(9 downto 0);
+
+signal phy_reset: std_logic;
+signal bufpll_lock:std_logic;
+signal upper:std_logic;
+signal ioclk: std_logic;
+signal serdesstrobe:std_logic;
+
+begin
+
+
+ ctrl <= vsync & hsync;
+
+
+
+
+ enc_r: entity work.tmds_encoder
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk => pclk,
+ ctrl => ctrl,
+ blank => blank,
+ din => r_in,
+ dout => r_p10
+ );
+
+
+ enc_g: entity work.tmds_encoder
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk => pclk,
+ ctrl => "11",
+ blank => blank,
+ din => g_in,
+ dout => g_p10
+ );
+
+
+
+ enc_b: entity work.tmds_encoder
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk => pclk,
+ ctrl => "11",
+ blank => blank,
+ din => b_in,
+ dout => b_p10
+ );
+
+
+ioclk_buf: BUFPLL
+ generic map ( DIVIDE => 5)
+ port map (
+ PLLIN => pclk_x10,
+ GCLK => pclk_x2,
+ LOCKED => pclk_locked,
+ IOCLK => ioclk,
+ SERDESSTROBE => serdesstrobe
+ );
+
+
+ phy_reset <= not sys_rst_n or not bufpll_lock;
+
+ process (pclk_x2) begin
+ if phy_reset='1' then
+ upper<='1';
+ elsif rising_edge(pclk_x2) then
+ upper<= not upper;
+ end if ;
+ end process;
+
+
+--phy_c : entity work.tmds_phy
+-- port map (
+-- reset => phy_reset,
+-- pclk_x2 => pclk_x2,
+-- serdesstrobe => serdesstrobe,
+-- ioclk => ioclk,
+-- upper => upper,
+-- din => "1111100000",
+-- tmds_out_p => tmds_c_out_p,
+-- tmds_out_n => tmds_c_out_n
+--);
+tmds_c_out_p <= '0';
+tmds_c_out_n <= '1';
+
+phy_r : entity work.tmds_phy
+ port map (
+ reset => phy_reset,
+ pclk_x2 => pclk_x2,
+ serdesstrobe => serdesstrobe,
+ ioclk=>ioclk,
+ upper=>upper,
+ din => r_p10,
+ tmds_out_p => tmds_r_out_p,
+ tmds_out_n => tmds_r_out_n
+);
+
+
+phy_g : entity work.tmds_phy
+ port map (
+ reset => phy_reset,
+ pclk_x2 => pclk_x2,
+ serdesstrobe => serdesstrobe,
+ ioclk=>ioclk,
+ upper=>upper,
+ din => g_p10,
+ tmds_out_p => tmds_g_out_p,
+ tmds_out_n => tmds_g_out_n
+);
+
+
+phy_b : entity work.tmds_phy
+ port map (
+ reset => phy_reset,
+ pclk_x2 => pclk_x2,
+ serdesstrobe => serdesstrobe,
+ ioclk=>ioclk,
+ upper=>upper,
+ din => b_p10,
+ tmds_out_p => tmds_b_out_p,
+ tmds_out_n => tmds_b_out_n
+);
+
+
+
+
+
+end beh;
diff --git a/spartan6/hp_lcd_driver/tmds_phy.vhdl b/spartan6/hp_lcd_driver/tmds_phy.vhdl
new file mode 100644
index 0000000..84c37f9
--- /dev/null
+++ b/spartan6/hp_lcd_driver/tmds_phy.vhdl
@@ -0,0 +1,66 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+library UNISIM;
+use UNISIM.vcomponents.all;
+
+entity tmds_phy is
+ port (
+ reset : in std_logic;
+ pclk_x2: in std_logic;
+ ioclk: in std_logic;
+ serdesstrobe: in std_logic;
+ din: in std_logic_vector(9 downto 0);
+ upper: in std_logic;
+ tmds_out_p: out std_logic;
+ tmds_out_n: out std_logic
+);
+end tmds_phy;
+
+
+architecture beh of tmds_phy is
+
+signal din_s:std_logic_vector(9 downto 0);
+signal p5_n:std_logic_vector(4 downto 0);
+signal p5:std_logic_vector(4 downto 0);
+signal s:std_logic;
+
+
+
+begin
+
+ process (pclk_x2) begin
+ if rising_edge(pclk_x2) then
+ if upper='1' then
+ din_s <= din;
+ p5 <= din_s(9 downto 5);
+ p5_n <= din_s(4 downto 0);
+ else
+ p5<=p5_n;
+ end if;
+ end if;
+ end process;
+
+
+ serdes : entity work.serdes_n_to_1
+ generic map(SF=>5)
+ port map (
+ ioclk => ioclk,
+ serdesstrobe => serdesstrobe,
+ reset => reset,
+ gclk => pclk_x2,
+ datain => p5,
+ iob_data_out =>s
+ );
+
+ obuf : OBUFDS
+ generic map ( IOSTANDARD => "TMDS_33")
+ port map (
+ I=>s,
+ O=>tmds_out_p,
+ OB=>tmds_out_n
+ );
+
+
+end beh;