summaryrefslogtreecommitdiffstats
path: root/fpga/hp_lcd_driver_a7
diff options
context:
space:
mode:
authorJames McKenzie <james.mckenzie@hp.com>2025-08-05 09:00:29 +0100
committerJames McKenzie <james.mckenzie@hp.com>2025-08-05 09:00:29 +0100
commit309f6cc7a094bbe6fd7ee2899cba7e4e4ebbe64e (patch)
treec631312a1de28348043a427ba2c0824e9484eb55 /fpga/hp_lcd_driver_a7
parent1a6dbe19eeccc13abef14bb19aad7750a9e901e0 (diff)
downloadhp_instrument_lcds-309f6cc7a094bbe6fd7ee2899cba7e4e4ebbe64e.tar.gz
hp_instrument_lcds-309f6cc7a094bbe6fd7ee2899cba7e4e4ebbe64e.tar.bz2
hp_instrument_lcds-309f6cc7a094bbe6fd7ee2899cba7e4e4ebbe64e.zip
first cut at a7
Diffstat (limited to 'fpga/hp_lcd_driver_a7')
-rw-r--r--fpga/hp_lcd_driver_a7/.gitignore3
-rw-r--r--fpga/hp_lcd_driver_a7/Makefile111
-rwxr-xr-xfpga/hp_lcd_driver_a7/scripts/save_pci45
-rwxr-xr-xfpga/hp_lcd_driver_a7/scripts/vhdl-pretty60
-rwxr-xr-xfpga/hp_lcd_driver_a7/scripts/vivado16
-rw-r--r--fpga/hp_lcd_driver_a7/source/clkgen_artix7.vhdl58
-rw-r--r--fpga/hp_lcd_driver_a7/source/config.tcl42
-rw-r--r--fpga/hp_lcd_driver_a7/source/debounce.vhdl32
-rw-r--r--fpga/hp_lcd_driver_a7/source/delay.vhdl24
-rw-r--r--fpga/hp_lcd_driver_a7/source/edge_det.vhdl28
-rw-r--r--fpga/hp_lcd_driver_a7/source/hp_lcd_driver.tcl159
-rw-r--r--fpga/hp_lcd_driver_a7/source/hp_lcd_driver.vhdl304
-rw-r--r--fpga/hp_lcd_driver_a7/source/input_formatter.vhdl138
-rw-r--r--fpga/hp_lcd_driver_a7/source/input_stage.vhdl145
-rw-r--r--fpga/hp_lcd_driver_a7/source/ip/mmcm_0.tcl39
-rw-r--r--fpga/hp_lcd_driver_a7/source/ip/mmcm_1.tcl35
-rw-r--r--fpga/hp_lcd_driver_a7/source/output_analog.vhdl82
-rw-r--r--fpga/hp_lcd_driver_a7/source/output_formatter.vhdl142
-rw-r--r--fpga/hp_lcd_driver_a7/source/output_stage.vhdl256
-rw-r--r--fpga/hp_lcd_driver_a7/source/rando_a7.tcl8
-rw-r--r--fpga/hp_lcd_driver_a7/source/rando_a7.xdc69
-rw-r--r--fpga/hp_lcd_driver_a7/source/rando_a7_early.xdc4
-rw-r--r--fpga/hp_lcd_driver_a7/source/synchronizer.vhdl26
-rw-r--r--fpga/hp_lcd_driver_a7/source/tmds_encode.vhdl73
-rw-r--r--fpga/hp_lcd_driver_a7/source/tmds_encoder.vhdl117
-rw-r--r--fpga/hp_lcd_driver_a7/source/tmds_output_artix7.vhdl128
-rw-r--r--fpga/hp_lcd_driver_a7/source/vram_artix7.vhdl26
27 files changed, 2170 insertions, 0 deletions
diff --git a/fpga/hp_lcd_driver_a7/.gitignore b/fpga/hp_lcd_driver_a7/.gitignore
new file mode 100644
index 0000000..7594c18
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/.gitignore
@@ -0,0 +1,3 @@
+build-rando_a7
+NOT
+OLD_NOT
diff --git a/fpga/hp_lcd_driver_a7/Makefile b/fpga/hp_lcd_driver_a7/Makefile
new file mode 100644
index 0000000..9a297c2
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/Makefile
@@ -0,0 +1,111 @@
+#
+#RH=10.16.66.168
+RH=10.16.66.111
+#RH=10.16.66.96
+#RH=hagelin
+
+RD=$(shell pwd)
+
+ifeq (${BOARD},)
+BOARD:=rando_a7
+endif
+
+BUILD=build-${BOARD}
+
+#ifeq (${BOARD},rando_a7)
+#S=200
+#A=125
+#else ifeq (${BOARD},litefury)
+#S=200
+#A=125
+#else ifeq (${BOARD},sitlinv_7k325)
+#S=333
+#A=125
+#endif
+
+IP= \
+ source/ip/mmcm_0.tcl \
+ source/ip/mmcm_1.tcl
+
+#
+#
+#
+#
+# source/ip/f_11x512_ft.tcl \
+# source/ip/fa_19x512_ft_${S}_${A}.tcl \
+# source/ip/fa_32x8k_ft_${S}_${A}.tcl \
+# source/ip/fa_64x8k_ft_${S}_${A}.tcl \
+# source/ip/fa_8x4k_ft_${A}_${S}.tcl \
+# source/ip/fa_8x4k_ft_${S}_${A}.tcl \
+# source/ip/mmcm_0.tcl \
+# source/ip/dma_block_0.tcl \
+# source/ip/axi_crossbar_2_1_MDW_LAW.tcl \
+# source/ip/axi_dwidth_converter_128_MDW_LAW_4.tcl \
+# source/ip/axi_protocol_converter_lite_full_64_LAW.tcl \
+# source/ip/axi_dwidth_converter_64_MDW_LAW_1.tcl \
+# source/ip/axi_clock_converter_MDW_MAW_4.tcl \
+# source/ip/mig_7series_${BOARD}.tcl \
+
+BIT=${BUILD}/out/hp_lcd_driver.bit
+
+IP_STAMP=${IP:source/ip/%.tcl=${BUILD}/ip/%/stamp}
+SRCS=$(shell find source -type f -print )
+
+OPENOCD=openocd -f openocd/${BOARD}.cfg
+
+default: ${BUILD}/build.stamp
+
+${BUILD}/build.stamp:${SRCS} ${IP_STAMP}
+ mkdir -p ${BUILD}
+ (cd ${BUILD} && BOARD=${BOARD} ../scripts/vivado -mode batch -source ../source/hp_lcd_driver.tcl)
+ touch $@
+
+${BUILD}/ip/%/stamp:source/ip/%.tcl
+ mkdir -p ${BUILD}/ip
+ /bin/rm -rf $(dir $@)
+ (cd ${BUILD} && BOARD=${BOARD} ../scripts/vivado -mode batch -source ../$<) && touch $@
+
+
+clean:
+ ${MAKE} -C proxy clean
+ /bin/rm -rf build-*
+
+
+${BIT}: ${BUILD}/build.stamp
+
+load: ${BUILD}/out/hp_lcd_driver.bit
+ ${OPENOCD} -c "init; pld load 0 {${BIT}}; exit"
+
+
+
+#flash: build/out/tpm_widget.bit
+# openocd -f openocd/ft4232.cfg -f openocd/xc7k325t.cfg -c "init; fpga_flash {$<}; exit"
+
+rload: ${BUILD}/build.${RH}.synced
+ ssh "${RH}" "cd ${RD} && make BOARD=${BOARD} load"
+
+${BUILD}/build.${RH}.synced: ${BUILD}/build.stamp
+ ssh "${RH}" "mkdir -p '${RD}/${BUILD}/out/'"
+ rsync -varz ${BUILD}/out/ "${RH}:${RD}/${BUILD}/out/"
+ ssh "${RH}" "cd '${RD}' && touch $<"
+ touch $@
+
+rsync-build:
+ ssh "${RH}" "mkdir -p ${RD}"
+ rsync -varz ./${BUILD}/ "${RH}:${RD}/${BUILD}/"
+rsync-git:
+ ssh "${RH}" "mkdir -p ${RD}"
+ rsync -varz ./.git/ "${RH}:${RD}/.git/"
+
+rsync-all:
+ ssh "${RH}" "mkdir -p ${RD}"
+ rsync -varz ./ "${RH}:${RD}/"
+
+tidy:
+ #git diff --exit-code -s source
+ for i in source/*.vhdl; do /bin/cp -f $$i $$i.orig && scripts/vhdl-pretty < $$i.orig > $$i; done
+
+
+
+
+
diff --git a/fpga/hp_lcd_driver_a7/scripts/save_pci b/fpga/hp_lcd_driver_a7/scripts/save_pci
new file mode 100755
index 0000000..5576e4b
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/scripts/save_pci
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+S="$1"
+
+D=""
+
+for i in /sys/bus/pci/devices/*; do
+if [ "$(cat "$i/subsystem_vendor")$(cat "$i/subsystem_device")" == "0x103c0x5450" ]; then
+ D="$(basename $i)"
+fi
+done
+D="$(echo $D | sed -e 's/^0000://' )"
+
+
+# check it's really there -H1 forces talking to the card not the kernel
+
+if [ "$(setpci -H1 -s "${D}" SUBSYSTEM_VENDOR_ID.l)" != "5450103c" ]; then
+ D=""
+fi
+
+if [ -z "$D" ]; then
+ echo "PCIe device not found" 1>&2
+ if [ ! -f "$S" ]; then
+ echo "and no saved config, try a load and then a reboot" 1>^2
+ exit 1
+ fi
+ exit 0
+fi
+
+
+echo "Device found at $D"
+
+echo "#!/bin/sh" > "$S"
+
+for i in $(seq 0 4 255); do
+ R="$(printf "0x%02x.l" $i)"
+ V="$(setpci -H1 -s "${D}" "${R}")"
+ echo "setpci -H1 -s \"${D}\" \"${R}=${V}\"" >> "$S"
+done
+
+echo "if [ \"\$(setpci -H1 -s \"${D}\" SUBSYSTEM_VENDOR_ID.l)\" != \"5450103c\" ]; then exit 1; fi" >> "$S"
+
+
+chmod +x "$S"
+
diff --git a/fpga/hp_lcd_driver_a7/scripts/vhdl-pretty b/fpga/hp_lcd_driver_a7/scripts/vhdl-pretty
new file mode 100755
index 0000000..c514b85
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/scripts/vhdl-pretty
@@ -0,0 +1,60 @@
+#! /bin/sh
+":"; exec emacs --no-site-file --script "$0" -- "$0" "$@" # -*-emacs-lisp-*-
+; vim: noai:ts=4:sw=4:syntax=lisp
+
+(setq arg0 (file-truename (car (cdr argv))))
+(setq args (cdr (cdr argv)))
+(setq argv nil)
+
+; Parse the command line arguments,
+; --xxx -> ("xxx" t)
+; --no-xxx -> ("xxx" nil)
+; --xxx=123 -> ("xxx" 123)
+; --xxx=abc -> ("xxx" "abc")
+; --xxx='abc 123' -> ("xxx" "abc 123")
+; --xxx=abc=123 -> ("xxx" "abc=123")
+(setq args
+ (mapcar
+ (lambda (arg)
+ (cond
+ ((string-match "^--no-\\([^=]*\\)$" arg)
+ (list (intern (match-string 1 arg)) nil))
+ ((string-match "^--\\([^=]*\\)$" arg)
+ (list (intern (match-string 1 arg)) t))
+ ((string-match "^--\\([^=]*\\)=\\([\"']?\\)\\([0-9]+\\)\\2$" arg)
+ (list (intern (match-string 1 arg)) (string-to-number (match-string 3 arg))))
+ ((string-match "^--\\([^=]*\\)=\\([\"']?\\)\\(.+?\\)\\2$" arg)
+ (list (intern (match-string 1 arg)) (match-string 3 arg)))
+ (t nil)
+ ))
+ args))
+
+; Read stdin into buffer
+(defun insert-standard-input ()
+ "insert contents from standard input"
+ (condition-case nil
+ (let (line)
+ (while (setq line (read-from-minibuffer ""))
+ (insert line "\n")))
+ (error nil)))
+
+(insert-standard-input)
+(goto-char (point-min))
+
+; Load library
+(setq basedir (concat (file-name-directory arg0) "vhdl-mode"))
+(setq load-path (cons basedir load-path))
+(load-library "vhdl-mode")
+
+; Default customisation
+(vhdl-set-style "IEEE")
+
+; Customisation from cmdline
+(mapc (lambda (arg) (customize-set-variable (car arg) (car (cdr arg)))) args)
+
+; Turn on mode and beautify
+(vhdl-mode)
+(vhdl-beautify-region (point-min) (point-max))
+
+; Output buffer to stdout
+(princ (buffer-string))
diff --git a/fpga/hp_lcd_driver_a7/scripts/vivado b/fpga/hp_lcd_driver_a7/scripts/vivado
new file mode 100755
index 0000000..0dbf03c
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/scripts/vivado
@@ -0,0 +1,16 @@
+#!/bin/bash
+HS3_BIN=/home/DISTRIB/Xilinx/Digilent-HS3/foo
+HS3_LIB=/home/DISTRIB/Xilinx/Digilent-HS3/foo
+VIVADO=/software/apps/xilinx/Vivado/2022.1/
+VIVADO_BIN=${VIVADO}/bin
+VIVADO_LIB=${VIVADO}/lib64
+
+XILINXD_LICENSE_FILE=${PWD}/xilinx_ise_vivado_license.lic
+export XILINXD_LICENSE_FILE
+
+export LD_LIBRARY_PATH
+
+PATH="${VIVADO_BIN}:${HS3_BIN}:$PATH"
+LD_LIBRAY_PATH="${LD_LIBRARY_PATH}:/usr/lib64:/usr/lib:/lib64:/lib:${VIVADO_LIB}:${HS3_LIB}"
+
+exec ${VIVADO_BIN}/vivado $@
diff --git a/fpga/hp_lcd_driver_a7/source/clkgen_artix7.vhdl b/fpga/hp_lcd_driver_a7/source/clkgen_artix7.vhdl
new file mode 100644
index 0000000..c115478
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/clkgen_artix7.vhdl
@@ -0,0 +1,58 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+use work.all;
+
+library UNISIM;
+use UNISIM.vcomponents.all;
+
+entity clkgen is
+ port (
+ sys_rst_n : in std_logic;
+ clk_in : in std_logic;
+ i_clk : out std_logic;
+ o_clk : out std_logic;
+ o_clk_x2 : out std_logic;
+ o_clk_phy : out std_logic;
+ locked : out std_logic
+ );
+end clkgen;
+architecture Behavioural of clkgen is
+
+ signal clk_200m : std_logic;
+ signal clk_78_571m : std_logic;
+ signal clk_40m : std_logic;
+ signal clk_20m : std_logic;
+ signal clk_50m : std_logic;
+
+ signal reset : std_logic;
+begin
+
+ reset <= not sys_rst_n;
+
+ o_clk_buf : BUFG port map (
+ I => clk_in,
+ O => clk_50m);
+
+ mmcm_0_i : mmcm_0 port map (
+ clk_in1 => clk_50m,
+ clk_out1 => clk_200m,
+ clk_out2 => clk_40m,
+ clk_out3 => clk_20m,
+ reset => reset,
+ locked => locked
+ );
+
+ mmcm_1_i : mmcm_1 port map (
+ clk_in1 => clk_50m,
+ clk_out1 => clk_78_571m,
+ reset => reset
+ );
+
+ o_clk_phy <= clk_200m;
+ o_clk<= clk_20m;
+ o_clk_x2<= clk_40m;
+ i_clk<=clk_78_571m;
+
+
+end Behavioural;
diff --git a/fpga/hp_lcd_driver_a7/source/config.tcl b/fpga/hp_lcd_driver_a7/source/config.tcl
new file mode 100644
index 0000000..238781a
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/config.tcl
@@ -0,0 +1,42 @@
+#
+#set LA_ADDR_WIDTH 34
+
+set board $::env(BOARD)
+set board_tcl $source_dir/$board.tcl
+set build_dir .
+set ip_dir $build_dir/ip
+set bd_dir $build_dir/bd
+set ipl_dir $build_dir/ip_library
+set output_dir $build_dir/out
+source $board_tcl
+create_project -in_memory -part $part_num
+
+file mkdir $build_dir
+file mkdir $bd_dir
+file mkdir $ip_dir
+file mkdir $ipl_dir
+file mkdir $output_dir
+
+#WARNING: [Vivado 12-13651] The IP file '/home/root/projects/hp_instrument_lcds/fpga/artix7/build-rando_a7/ip/mmcm_0/mmcm_0.xci' has been moved from its original location, as a result the outputs for this IP will now be generated in '/home/root/projects/hp_instrument_lcds/fpga/artix7/build-rando_a7/ip/mmcm_0'. Alternatively a copy of the IP can be imported into the project using one of the 'import_ip' or 'import_files' commands.
+set_msg_config -id 12-13651 -suppress
+
+
+
+#WARNING: [Vivado 12-584] No ports matched 'spi_mosi'. [/root/projects/tpm_interposer/logic_analyzer/source/sitlinv-7k325.xdc:215]
+#set_msg_config -id 12-584 -suppress
+
+#WARNING: [Synth 8-3917] design pcie_tpm_widget has port led_d1 driven by constant 0
+#set_msg_config -id 8-3917 -suppress
+
+#WARNING: [Vivado 12-13651] The IP file '/root/projects/tpm_interposer/logic_analyzer/build-sitlinv-7k325/ip/xdma_0/xdma_0.xci' has been moved from its original location, as a result the outputs for this IP will now be generated in '/root/projects/tpm_interposer/logic_analyzer/build-sitlinv-7k325/ip/xdma_0'. Alternatively a copy of the IP can be imported into the project using one of the 'import_ip' or 'import_files' commands.
+#set_msg_config -id 12-13651 -suppress
+
+#WARNING: [Synth 8-2551] possible infinite loop; process does not have a wait statement [/root/projects/tpm_interposer/logic_analyzer/source/pcie.vhdl:123]
+#set_msg_config -id 8-2551 -suppress
+
+#WARNING: [Synth 8-3848] Net dma_axi_awid in module/entity pcie_tpm_widget does not have driver. [/root/projects/tpm_interposer/logic_analyzer/source/pcie_tpm_widget.vhdl:88]
+#set_msg_config -id 8-3848 -new_severity ERROR
+
+#CRITICAL WARNING: [Synth 8-6859] multi-driven net on pin Q with 1st driver pin 'la_i/fifo_to_axi_i/axi_bready_reg/Q' [/root/projects/tpm_interposer/pcie-tpm-emulator/source/fifo_to_axi.vhdl:46]
+#set_msg_config -id 8-6859 -new_severity ERROR
+
diff --git a/fpga/hp_lcd_driver_a7/source/debounce.vhdl b/fpga/hp_lcd_driver_a7/source/debounce.vhdl
new file mode 100644
index 0000000..286367d
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/debounce.vhdl
@@ -0,0 +1,32 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+
+entity debounce is
+ generic (stages : natural := 1);
+ port (clk : in std_logic;
+ i : in std_logic;
+ o : out std_logic);
+end debounce;
+
+architecture Behavioral of debounce is
+ signal flipflops : std_logic_vector(stages-1 downto 0) := (others => '0');
+ constant zero : std_logic_vector(stages-1 downto 0) := (others => '0');
+ constant one : std_logic_vector(stages-1 downto 0) := (others => '1');
+ signal output : std_logic := '0';
+begin
+
+ o <= output;
+
+ process (clk, flipflops, i)
+ begin
+ if rising_edge(clk) then
+ flipflops <= flipflops(flipflops'high-1 downto 0) & i;
+ if flipflops = one and i = '1' then
+ output <= '1';
+ elsif flipflops = zero and i = '0' then
+ output <= '0';
+ end if;
+ end if;
+ end process;
+
+end architecture;
diff --git a/fpga/hp_lcd_driver_a7/source/delay.vhdl b/fpga/hp_lcd_driver_a7/source/delay.vhdl
new file mode 100644
index 0000000..66c5c5d
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/delay.vhdl
@@ -0,0 +1,24 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+
+entity delay is
+ generic (stages : natural := 2);
+ port (clk : in std_logic;
+ i : in std_logic;
+ o : out std_logic);
+end delay;
+
+architecture Behavioral of delay is
+ signal flipflops : std_logic_vector(stages-1 downto 0) := (others => '0');
+begin
+
+ o <= flipflops(flipflops'high);
+
+ clk_proc : process(clk, flipflops, i)
+ begin
+ if rising_edge(clk) then
+ flipflops <= flipflops(flipflops'high-1 downto 0) & i;
+ end if;
+ end process;
+
+end Behavioral;
diff --git a/fpga/hp_lcd_driver_a7/source/edge_det.vhdl b/fpga/hp_lcd_driver_a7/source/edge_det.vhdl
new file mode 100644
index 0000000..2a592a5
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/edge_det.vhdl
@@ -0,0 +1,28 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+
+entity edge_det is
+ port (clk : in std_logic;
+ sig : in std_logic;
+ pe : out std_logic;
+ ne : out std_logic;
+ e : out std_logic
+ );
+end edge_det;
+
+architecture Behavioral of edge_det is
+ signal last : std_logic := '0';
+begin
+
+ process(clk, last, sig)
+ begin
+ if rising_edge(clk) then
+ last <= sig;
+ end if;
+ end process;
+
+ pe <= '1' when sig = '1' and last = '0' else '0';
+ ne <= '1' when sig = '0' and last = '1' else '0';
+
+ e <= sig xor last;
+end Behavioral;
diff --git a/fpga/hp_lcd_driver_a7/source/hp_lcd_driver.tcl b/fpga/hp_lcd_driver_a7/source/hp_lcd_driver.tcl
new file mode 100644
index 0000000..4c9231d
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/hp_lcd_driver.tcl
@@ -0,0 +1,159 @@
+#
+set source_dir [file dirname [file normalize [info script]]]
+
+source $source_dir/config.tcl
+
+file mkdir $output_dir
+
+set files [glob -nocomplain "$output_dir/*"]
+if {[llength $files] != 0} {
+ # clear folder contents
+ puts "deleting contents of $output_dir"
+ file delete -force {*}[glob -directory $output_dir *];
+} else {
+ puts "$output_dir is empty"
+}
+
+#Reference HDL and constraint source files
+
+read_xdc $early_xdc
+
+#read_verilog [ glob ../source/*.v ]
+read_vhdl -vhdl2008 -library work [ glob ../source/*.vhdl ]
+
+set generics {}
+#append generics { } "CLOCKS=\"A${aclk}_S${sclk}\""
+append generics { } "BOARD=\"$board\""
+#append generics { } "LA_ADDR_WIDTH=$LA_ADDR_WIDTH"
+#append generics { } "MEM_DATA_WIDTH=$MEM_DATA_WIDTH"
+#append generics { } "MEM_ADDR_WIDTH=$MEM_ADDR_WIDTH"
+#append generics { } "DDR3_D_WIDTH=$DDR3_D_WIDTH"
+#append generics { } "DDR3_A_WIDTH=$DDR3_A_WIDTH"
+#append generics { } "DDR3_B_WIDTH=$DDR3_B_WIDTH"
+
+set_property generic "$generics" [current_fileset]
+puts $generics
+
+read_ip $ip_dir/mmcm_0/mmcm_0.xci
+read_ip $ip_dir/mmcm_1/mmcm_1.xci
+#read_ip $ip_dir/dma_block_0/dma_block_0.xci
+#read_ip $ip_dir/fa_8x4k_ft_${sclk}_${aclk}/fa_8x4k_ft_${sclk}_${aclk}.xci
+#read_ip $ip_dir/fa_8x4k_ft_${aclk}_${sclk}/fa_8x4k_ft_${aclk}_${sclk}.xci
+#read_ip $ip_dir/fa_19x512_ft_${sclk}_${aclk}/fa_19x512_ft_${sclk}_${aclk}.xci
+#read_ip $ip_dir/fa_32x8k_ft_${sclk}_${aclk}/fa_32x8k_ft_${sclk}_${aclk}.xci
+#read_ip $ip_dir/fa_64x8k_ft_${sclk}_${aclk}/fa_64x8k_ft_${sclk}_${aclk}.xci
+#read_ip $ip_dir/f_11x512_ft/f_11x512_ft.xci
+#read_ip $ip_dir/axi_dwidth_converter_128_MDW_LAW_4/axi_dwidth_converter_128_MDW_LAW_4.xci
+#read_ip $ip_dir/axi_protocol_converter_lite_full_64_LAW/axi_protocol_converter_lite_full_64_LAW.xci
+#read_ip $ip_dir/axi_dwidth_converter_64_MDW_LAW_1/axi_dwidth_converter_64_MDW_LAW_1.xci
+#read_ip $ip_dir/axi_crossbar_2_1_MDW_LAW/axi_crossbar_2_1_MDW_LAW.xci
+#read_ip $ip_dir/axi_clock_converter_MDW_MAW_4/axi_clock_converter_MDW_MAW_4.xci
+#read_ip $ip_dir/mig_7series_$board/mig_7series_$board.xci
+
+read_xdc $normal_xdc
+
+#Run Synthesis
+synth_design -top hp_lcd_driver -part $part_num
+write_checkpoint -force $output_dir/post_synth.dcp
+report_timing_summary -file $output_dir/post_synth_timing_summary.rpt
+report_utilization -file $output_dir/post_synth_util.rpt
+
+set crdl [get_param tcl.collectionResultDisplayLimit]
+set_param tcl.collectionResultDisplayLimit 10000000
+
+set f [open "$output_dir/cells.txt" w]
+puts $f [get_cells -hierarchical]
+close $f
+
+set f [open "$output_dir/nets.txt" w]
+puts $f [get_nets -hierarchical]
+close $f
+set_param tcl.collectionResultDisplayLimit $crdl
+
+set f [open "$output_dir/pins.txt" w]
+puts $f [get_pins -hierarchical]
+close $f
+set_param tcl.collectionResultDisplayLimit $crdl
+
+
+## erugh set_clock_groups can only take thee arguments there are reasonably 5 hierachies in play pci_e refclk, the axi clock, the clock used by the spi_slave and logic analyzer and the mig clock
+##
+#set_clock_groups -asynchronous \
+# -group [get_clocks -include_generated_clocks -of_objects [get_nets clk_100m]] \
+# -group "[get_clocks -include_generated_clocks -of_objects [get_nets clk_200m]] [get_clocks -include_generated_clocks -of_objects [get_nets clk_333m]]" \
+# -group [get_clocks -include_generated_clocks -of_objects [get_nets axi_aclk]]
+#
+#set_clock_groups -asynchronous \
+# -group [get_clocks -include_generated_clocks -of_objects [get_nets clk_100m]] \
+#
+## -group [get_clocks -include_generated_clocks -of_objects [get_nets sys_clk_p]]
+#
+#set_clock_groups -asynchronous \
+# -group "[get_clocks -include_generated_clocks -of_objects [get_nets clk_200m]] [get_clocks -include_generated_clocks -of_objects [get_nets clk_333m]]" \
+#
+## -group [get_clocks -include_generated_clocks -of_objects [get_nets sys_clk_p]]
+#
+#set_clock_groups -asynchronous \
+# -group [get_clocks -include_generated_clocks -of_objects [get_nets axi_aclk]] \
+#
+## -group [get_clocks -include_generated_clocks -of_objects [get_nets sys_clk_p]]
+#
+#
+##set_false_path -from [get_pins {srst_reg/C}] -to [get_pins {srst_sclk_sync/flipflops_reg[0]/D}]
+#
+#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_100m]
+#
+##puts [get_ports -of_objects [get_objects srst_sclk_sync ]]
+##exit
+#
+##puts [get_clocks -include_generated_clocks -of_objects [get_nets axi_aclk]]
+##puts [get_clocks -include_generated_clocks -of_objects [get_nets mmcm_0_i/inst/clk_out1]]
+#
+##set_false_path -from [get_pins {srst_reg/C}] -to [get_pins {srst_sclk_sync/flipflops_reg[0]/D}]
+#
+#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_100m]
+#
+##puts [get_ports -of_objects [get_objects srst_sclk_sync ]]
+##exit
+#
+##puts [get_clocks -include_generated_clocks -of_objects [get_nets axi_aclk]]
+##puts [get_clocks -include_generated_clocks -of_objects [get_nets mmcm_0_i/inst/clk_out1]]
+#
+## JMM because we've clocked the two async domains from the same input - vivado thinks there exist timing relationships
+## tell it there aren't
+#
+##set_false_path -from [get_clocks clk_100m] -to [get_clocks -include_generated_clocks clk_out3_mmcm_0]
+##set_false_path -from [get_clocks -include_generated_clocks clk_out3_mmcm_0] -to [get_clocks clk_100m]
+##
+##set_false_path -from [get_clocks -include_generated_clocks -of_objects [get_nets axi_aclk]] -to [get_clocks -include_generated_clocks clk_out3_mmcm_0]
+##set_false_path -from [get_clocks -include_generated_clocks clk_out3_mmcm_0] -to [get_clocks -include_generated_clocks -of_objects [get_nets axi_aclk]]
+##
+##set_false_path -from [get_clocks -include_generated_clocks -of_objects [get_nets axi_aclk]] -to [get_clocks clk_100m]
+##set_false_path -from [get_clocks clk_100m] -to [get_clocks -include_generated_clocks -of_objects [get_nets axi_aclk]]
+#
+#
+
+#run optimization
+opt_design
+place_design
+report_clock_utilization -file $output_dir/clock_util.rpt
+
+#get timing violations and run optimizations if needed
+if {[get_property SLACK [get_timing_paths -max_paths 1 -nworst 1 -setup]] < 0} {
+ puts "Found setup timing violations => running physical optimization"
+ phys_opt_design
+}
+write_checkpoint -force $output_dir/post_place.dcp
+report_utilization -file $output_dir/post_place_util.rpt
+report_timing_summary -file $output_dir/post_place_timing_summary.rpt
+
+#Route design and generate bitstream
+route_design -directive Explore
+write_checkpoint -force $output_dir/post_route.dcp
+report_route_status -file $output_dir/post_route_status.rpt
+report_timing_summary -file $output_dir/post_route_timing_summary.rpt
+report_power -file $output_dir/post_route_power.rpt
+report_drc -file $output_dir/post_imp_drc.rpt
+report_io -file $output_dir/post_imp_placed.rpt
+write_verilog -force $output_dir/cpu_impl_netlist.v -mode timesim -sdf_anno true
+write_bitstream -force $output_dir/hp_lcd_driver.bit
diff --git a/fpga/hp_lcd_driver_a7/source/hp_lcd_driver.vhdl b/fpga/hp_lcd_driver_a7/source/hp_lcd_driver.vhdl
new file mode 100644
index 0000000..087e475
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/hp_lcd_driver.vhdl
@@ -0,0 +1,304 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+use work.all;
+
+-- on the cyclone iv
+-- i_clk/4 = 19.676158
+-- the scope's pixel clock is 19.66080
+-- (p-0.25)*19.66080 = p * 19.676158
+--p=1/[4*(1-(19.676158/19.66080))]=320.04
+
+
+entity hp_lcd_driver is
+ generic (video_width : natural := 2;
+ addr_width : natural := 18;
+ phase_slip : natural := 320;
+ i_clk_multiple : natural := 4;
+ target : string := "spartan6");
+ port (clk_50m : in std_logic;
+ sys_rst_n : in std_logic;
+ video : in std_logic_vector(video_width-1 downto 0);
+ hsync_in : in std_logic;
+ vsync_in : in 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_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;
+ i_clk_out : out std_logic);
+
+end hp_lcd_driver;
+
+architecture Behavioral of hp_lcd_driver is
+
+ signal wr_addr : std_logic_vector(addr_width-1 downto 0);
+ signal wr_data : std_logic_vector(video_width-1 downto 0);
+ signal wr_en : std_logic;
+
+ signal rd_addr : std_logic_vector(addr_width-1 downto 0);
+ signal rd_data : std_logic_vector(video_width-1 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 clk_locked : std_logic;
+
+ signal i_clk : std_logic;
+
+ signal o_clk : std_logic;
+ signal o_clk_x2 : std_logic;
+ signal o_clk_phy : std_logic;
+ signal sys_rst : std_logic;
+
+ signal pa : natural;
+ signal epk : std_logic;
+ signal ic : natural;
+
+
+ signal h : natural;
+ signal v : natural;
+
+
+
+begin
+
+
+-- clocking:
+-- i_clk is 4*(nominal) 20MHz to give us 4 choices of sampling position
+-- o_clk is the output pixel clock
+-- o_clk_x2 is used by the spartan serdes
+-- o_clk_phy is used the the hdmi phy (cylone4 it's o_clk x5, spartan 6 it's o_clk x 10)
+
+ clkgen : entity work.clkgen
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk_in => clk_50m,
+ i_clk => i_clk,
+ o_clk => o_clk,
+ o_clk_x2 => o_clk_x2,
+ o_clk_phy => o_clk_phy,
+ locked => clk_locked
+ );
+
+
+
+ process (i_clk, sys_rst_n)
+ begin
+ if sys_rst_n = '0' then
+ ic <= 0;
+ pa <= phase_slip;
+ epk <= '0';
+ elsif rising_edge(i_clk) then
+
+ if ic = 0 then
+ epk <= '1';
+ if pa = 0 then
+ pa <= phase_slip;
+ ic <= i_clk_multiple;
+ else
+ ic <= i_clk_multiple-1;
+ pa <= pa -1;
+ end if;
+ else
+ if epk = '1' then
+ epk <= '0';
+ end if;
+ ic <= ic-1;
+ end if;
+ end if;
+ end process;
+
+
+ i_clk_out <= epk;
+
+
+ input0 : entity work.input_stage
+ generic map(
+ video_width => video_width,
+ addr_width => addr_width,
+ clk_multiple => i_clk_multiple,
+-- HP54502A
+-- phase => 1,
+-- h_front_porch => 210,
+-- h_active => 592,
+-- v_front_porch => 1,
+-- v_active => 384,
+-- frame_start => 383,
+-- h_stride => 384,
+-- v_stride => 262143,
+-- HP54522A
+ phase => 1,
+ h_front_porch => 213,
+ h_active => 640,
+ v_front_porch => 22,
+ v_active => 384,
+ frame_start => 383,
+ h_stride => 384,
+ v_stride => 524287,
+ phase_slip => phase_slip
+ )
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk => i_clk,
+ video_in => video,
+ hsync_in => not hsync_in,
+ vsync_in => not vsync_in,
+
+ video_out => wr_data,
+ addr_out => wr_addr,
+ wren_out => wr_en
+ );
+
+--
+-- process (i_clk) begin
+-- if sys_rst_n='0' then
+-- h<=0;
+-- v<=0;
+-- wr_addr <=(others =>'0');
+-- elsif rising_edge(i_clk) then
+-- if h /= 383 then
+-- h<=h+1;
+-- wr_addr <= std_logic_vector(unsigned(wr_addr)+1);
+-- else
+-- h<=0;
+-- if v /= 591 then
+-- v<=v+1;
+-- wr_addr <= std_logic_vector(unsigned(wr_addr)+1);
+-- else
+-- v<=0;
+-- wr_addr <=(others =>'0');
+-- end if;
+-- end if;
+-- end if;
+-- end process;
+--
+-- wr_en <= '1';
+--
+-- wr_data <="01" when (h=0) or (h=383) or (v=0) or (v=591)
+-- else "00";
+--
+ vram0 : entity work.vram
+ generic map (
+ video_width => video_width,
+ addr_width => addr_width
+ )
+ port map (
+ wr_clk => i_clk,
+ wr_en => wr_en,
+ wr_addr => wr_addr,
+ wr_data => wr_data,
+ rd_clk => o_clk,
+ rd_addr => rd_addr,
+ rd_data => rd_data
+ );
+
+
+
+ r<=x"00";
+ b<=x"00";
+
+ g <= x"ff" when rd_data(1) = '1' else
+ x"80" when rd_data(0) = '1' else
+ x"00";
+
+
+
+
+ output0 : entity work.output_stage
+
+-- didn't work for me from this thing, only from mac, works at 60Hz xrandr --newmode "$M" 18.24 384 400 440 600 592 593 596 613 -HSync +Vsync
+-- Modeline "384x592_80.00" 25.40 384 408 448 512 592 593 596 620 -HSync +Vsync
+
+ generic map (
+ target => target,
+ addr_width => addr_width,
+-- h_active => 384,
+-- h_sync_start => 400,
+-- h_sync_end => 440,
+-- h_total => 640,
+-- v_active => 592,
+-- v_sync_start => 593,
+-- v_sync_end => 596,
+-- v_total => 613,
+-- h_stride => 1,
+-- v_stride => 384
+
+-- HP54502A
+-- h_active => 384,
+-- h_sync_start => 400,
+-- h_sync_end => 440,
+-- h_total => 660,
+-- v_active => 592,
+-- v_sync_start => 593,
+-- v_sync_end => 596,
+-- v_total => 613,
+-- h_stride => 1,
+-- v_stride => 384
+
+-- HP54522A
+ h_active => 384,
+ h_sync_start => 400,
+ h_sync_end => 440,
+ h_total => 660,
+-- h_active => 417,
+-- h_sync_start => 440,
+-- h_sync_end => 480,
+-- h_total => 660,
+ v_active => 640,
+ v_sync_start => 641,
+ v_sync_end => 644,
+ v_total => 650,
+ h_stride => 1,
+ v_stride => 384
+
+-- h_active => 800,
+-- h_sync_start => 832,
+-- h_sync_end => 912,
+-- h_total => 1024,
+-- v_active => 600,
+-- v_sync_start => 601,
+-- v_sync_end => 604,
+-- v_total => 622,
+-- h_stride => 1,
+-- v_stride => 384
+ )
+ port map(
+ clk_locked => clk_locked,
+ clk => o_clk,
+ clk_x2 => o_clk_x2,
+ clk_phy => o_clk_phy,
+ sys_rst_n => sys_rst_n,
+ vsync_in => vsync_in,
+ r_in => r,
+ g_in => g,
+ b_in => b,
+ addr_out => rd_addr,
+ r_out => r_out,
+ g_out => g_out,
+ b_out => b_out,
+ hsync_out => hsync_out,
+ vsync_out => vsync_out,
+ 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
+ );
+
+
+end Behavioral;
+
diff --git a/fpga/hp_lcd_driver_a7/source/input_formatter.vhdl b/fpga/hp_lcd_driver_a7/source/input_formatter.vhdl
new file mode 100644
index 0000000..f3bd434
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/input_formatter.vhdl
@@ -0,0 +1,138 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+
+
+entity input_formatter is
+ generic (
+ addr_width : natural := 17;
+ clk_multiple : natural := 4;
+ phase : natural := 2;
+ h_front_porch : natural := 208;
+ h_active : natural := 592;
+ v_front_porch : natural := 2;
+ v_active : natural := 384;
+ frame_start : natural := 0;
+ h_stride : natural := 384;
+ v_stride : natural := 1;
+ phase_slip : natural := 320);
+ port
+ (
+ sys_rst_n : in std_logic;
+ clk : in std_logic;
+ hsync : in std_logic;
+ vsync : in std_logic;
+ addr_out : out std_logic_vector(addr_width-1 downto 0);
+ wren_out : out std_logic;
+ h_grid : out std_logic;
+ v_grid : out std_logic
+ );
+
+end input_formatter;
+
+
+architecture beh of input_formatter is
+
+ signal row_addr : std_logic_vector(addr_width-1 downto 0);
+ signal addr : std_logic_vector(addr_width-1 downto 0);
+ signal wren : std_logic;
+
+ signal hsync_ne : std_logic;
+ signal hsync_pe : std_logic;
+
+ signal v_fp_counter : natural;
+ signal v_active_counter : natural;
+ signal h_fp_counter : natural;
+ signal h_active_counter : natural;
+ signal h_div : natural;
+
+ signal phase_accum : natural;
+
+
+begin
+
+
+ hsync_ed : entity work.edge_det
+ port map(
+ clk => clk,
+ sig => hsync,
+ e => open,
+ ne => hsync_ne,
+ pe => hsync_pe);
+
+
+
+
+ addr_out <= addr;
+
+
+ process (sys_rst_n, clk, hsync_pe, vsync)
+ begin
+ if sys_rst_n = '0' then
+ row_addr <= (others => '0');
+ addr <= (others => '0');
+ h_div <= 0;
+ h_active_counter <= 0;
+ h_fp_counter <= 0;
+ v_active_counter <= 0;
+ v_fp_counter <= 0;
+ phase_accum <= 0;
+ elsif rising_edge(clk) then
+ if hsync_pe = '1' then
+ --if v_active_counter = 0 and v_fp_counter=0 then
+ if vsync = '1' then
+ row_addr <= std_logic_vector(to_unsigned(frame_start, addr_width));
+ v_fp_counter <= v_front_porch;
+ v_active_counter <= v_active;
+ elsif v_fp_counter /= 0 then
+ v_fp_counter <= v_fp_counter -1;
+ elsif v_active_counter /= 0 then
+ v_active_counter <= v_active_counter -1;
+
+ h_fp_counter <= h_front_porch * clk_multiple + phase;
+ h_active_counter <= h_active;
+ phase_accum <= phase_slip;
+ h_div <= 0;
+
+ addr <= row_addr;
+ row_addr <= std_logic_vector(unsigned(row_addr)+v_stride);
+ end if;
+ elsif h_fp_counter /= 0 then
+ h_fp_counter <= h_fp_counter -1;
+ elsif h_active_counter /= 0 then
+
+ if h_div = 0 then
+ wren <= '1';
+ if phase_accum = 0 then
+ phase_accum <= phase_slip;
+ h_div <= clk_multiple;
+ else
+ phase_accum <= phase_accum-1;
+ h_div <= clk_multiple-1;
+ end if;
+ else
+ if wren = '1' then
+ wren <= '0';
+ h_active_counter <= h_active_counter -1;
+ addr <= std_logic_vector(unsigned(addr)+h_stride);
+ end if;
+ h_div <= h_div -1;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ addr_out <= addr;
+ wren_out <= wren;
+
+
+ h_grid <= '1' when ((h_active_counter mod 16) = (h_active mod 16)) or (h_Active_counter = 1)
+-- h_grid <= '1' when (h_active_counter=h_active) or (h_active_counter=h_active-2)
+else '0';
+
+ v_grid <= '1' when ((v_active_counter mod 16) = (v_active mod 16)) or (v_active_counter = 1)
+ else '0';
+
+
+end beh;
diff --git a/fpga/hp_lcd_driver_a7/source/input_stage.vhdl b/fpga/hp_lcd_driver_a7/source/input_stage.vhdl
new file mode 100644
index 0000000..9355a93
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/input_stage.vhdl
@@ -0,0 +1,145 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+entity input_stage is
+ generic (debounce_stages : natural := 2;
+ sync_stages : natural := 2;
+ video_width : natural := 2;
+ addr_width : natural := 17;
+ clk_multiple : natural := 4;
+ phase : natural := 2;
+ h_front_porch : natural := 208;
+ h_active : natural := 592;
+ v_front_porch : natural := 2;
+ v_active : natural := 384;
+ frame_start : natural := 0;
+ h_stride : natural := 384;
+ v_stride : natural := 1;
+ phase_slip : natural := 320);
+ port
+ (
+ clk : in std_logic;
+ sys_rst_n : in std_logic;
+
+ video_in : in std_logic_vector(video_width -1 downto 0);
+
+ hsync_in : in std_logic;
+ vsync_in : in std_logic;
+
+ video_out : out std_logic_vector(video_width-1 downto 0);
+ addr_out : out std_logic_vector(addr_width - 1 downto 0);
+ wren_out : out std_logic
+ );
+end input_stage;
+
+
+architecture beh of input_stage is
+
+ signal s_hsync : std_logic;
+ signal d_hsync : std_logic;
+
+ signal s_vsync : std_logic;
+ signal d_vsync : std_logic;
+
+ signal s_video : std_logic_vector(video_width-1 downto 0);
+
+ signal addr : std_logic_vector(addr_width - 1 downto 0);
+ signal wren : std_logic;
+
+ signal h_grid : std_logic;
+ signal v_grid : std_logic;
+
+ signal addr_test : std_logic_vector(addr_width - 1 downto 0);
+
+begin
+
+ video_sync_for : for b in 0 to video_width -1 generate
+ sync : entity work.synchronizer
+ generic map(stages => sync_stages + debounce_stages +1)
+ port map (
+ clk => clk,
+ i => video_in(b),
+ o => s_video(b)
+ );
+ end generate;
+
+
+
+ hsync_sync : entity work.synchronizer
+ generic map(stages => sync_stages)
+ port map (
+ clk => clk,
+ i => hsync_in,
+ o => s_hsync
+ );
+
+ vsync_sync : entity work.synchronizer
+ generic map(stages => sync_stages)
+ port map (
+ clk => clk,
+ i => vsync_in,
+ o => s_vsync
+ );
+
+ hsync_debounce : entity work.debounce
+ generic map(stages => debounce_stages)
+ port map(
+ clk => clk,
+ i => s_hsync,
+ o => d_hsync);
+
+
+
+ vsync_debounce : entity work.debounce
+ generic map(stages => debounce_stages)
+ port map(
+ clk => clk,
+ i => s_vsync,
+ o => d_vsync);
+
+
+ input_formatter : entity work.input_formatter
+ generic map(
+ -- 20.000 592 608 680 816 384 385 400 402
+ addr_width => addr_width,
+ clk_multiple => clk_multiple,
+ phase => phase,
+ h_front_porch => h_front_porch,
+ h_active => h_active,
+ v_front_porch => v_front_porch,
+ v_active => v_active,
+ frame_start => frame_start,
+ h_stride => h_stride,
+ v_stride => v_stride,
+ phase_slip => phase_slip)
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk => clk,
+ hsync => d_hsync,
+ vsync => d_vsync,
+ addr_out => addr,
+ wren_out => wren,
+ h_grid => h_grid,
+ v_grid => v_grid
+ );
+
+
+--wren_out <='1';
+
+--video_out(0) <='1';
+--video_out(1) <='1';
+
+ addr_out <= addr;
+ wren_out <= wren;
+
+ video_out <= s_video;
+
+--video_out(0) <= s_video(0);
+--video_out(1) <= h_grid or v_grid;
+
+ --video_out(0) <= h_grid;
+ --video_out(1) <= v_grid;
+
+
+end beh;
diff --git a/fpga/hp_lcd_driver_a7/source/ip/mmcm_0.tcl b/fpga/hp_lcd_driver_a7/source/ip/mmcm_0.tcl
new file mode 100644
index 0000000..2dc3648
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/ip/mmcm_0.tcl
@@ -0,0 +1,39 @@
+set source_dir [file dirname [file dirname [file normalize [info script]]]]
+
+source $source_dir/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.CLKOUT2_USED {true} \
+ CONFIG.CLKOUT3_USED {true} \
+ CONFIG.CLKOUT4_USED {true} \
+ CONFIG.CLKOUT5_USED {false} \
+ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {200} \
+ CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {40} \
+ CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {20} \
+ CONFIG.USE_SAFE_CLOCK_STARTUP {false} \
+ CONFIG.CLKIN1_JITTER_PS {100.0} \
+ CONFIG.CLKOUT1_DRIVES {BUFG} \
+ CONFIG.CLKOUT2_DRIVES {BUFG} \
+ CONFIG.CLKOUT3_DRIVES {BUFG} \
+ CONFIG.CLKOUT4_DRIVES {BUFG} \
+ CONFIG.CLKOUT5_DRIVES {BUFG} \
+ CONFIG.CLKOUT6_DRIVES {BUFG} \
+ CONFIG.CLKOUT7_DRIVES {BUFG} \
+ CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} \
+ CONFIG.MMCM_DIVCLK_DIVIDE {1} \
+ CONFIG.MMCM_CLKFBOUT_MULT_F {4.000} \
+ CONFIG.MMCM_CLKIN1_PERIOD {20.000} \
+ CONFIG.MMCM_CLKIN2_PERIOD {20.000} \
+ CONFIG.MMCM_CLKOUT0_DIVIDE_F {1} \
+ CONFIG.MMCM_CLKOUT1_DIVIDE {5} \
+ CONFIG.MMCM_CLKOUT2_DIVIDE {10} \
+ CONFIG.NUM_OUT_CLKS {3} \
+ ] [get_ips mmcm_0]
+
+generate_target all [get_ips]
+
+synth_ip [get_ips]
+
diff --git a/fpga/hp_lcd_driver_a7/source/ip/mmcm_1.tcl b/fpga/hp_lcd_driver_a7/source/ip/mmcm_1.tcl
new file mode 100644
index 0000000..dba6201
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/ip/mmcm_1.tcl
@@ -0,0 +1,35 @@
+set source_dir [file dirname [file dirname [file normalize [info script]]]]
+
+source $source_dir/config.tcl
+
+create_ip -name clk_wiz -vendor xilinx.com -library ip -version 6.0 -module_name mmcm_1 -dir $ip_dir
+
+set_property -dict [list \
+ CONFIG.PRIM_IN_FREQ {50} \
+ CONFIG.CLKOUT2_USED {true} \
+ CONFIG.CLKOUT3_USED {true} \
+ CONFIG.CLKOUT4_USED {true} \
+ CONFIG.CLKOUT5_USED {false} \
+ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {78.571} \
+ CONFIG.USE_SAFE_CLOCK_STARTUP {false} \
+ CONFIG.CLKIN1_JITTER_PS {100.0} \
+ CONFIG.CLKOUT1_DRIVES {BUFG} \
+ CONFIG.CLKOUT2_DRIVES {BUFG} \
+ CONFIG.CLKOUT3_DRIVES {BUFG} \
+ CONFIG.CLKOUT4_DRIVES {BUFG} \
+ CONFIG.CLKOUT5_DRIVES {BUFG} \
+ CONFIG.CLKOUT6_DRIVES {BUFG} \
+ CONFIG.CLKOUT7_DRIVES {BUFG} \
+ CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} \
+ CONFIG.MMCM_DIVCLK_DIVIDE {1} \
+ CONFIG.MMCM_CLKFBOUT_MULT_F {11.000} \
+ CONFIG.MMCM_CLKIN1_PERIOD {20.000} \
+ CONFIG.MMCM_CLKIN2_PERIOD {20.000} \
+ CONFIG.MMCM_CLKOUT0_DIVIDE_F {7} \
+ CONFIG.NUM_OUT_CLKS {1} \
+ ] [get_ips mmcm_1]
+
+generate_target all [get_ips]
+
+synth_ip [get_ips]
+
diff --git a/fpga/hp_lcd_driver_a7/source/output_analog.vhdl b/fpga/hp_lcd_driver_a7/source/output_analog.vhdl
new file mode 100644
index 0000000..af9eb71
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/output_analog.vhdl
@@ -0,0 +1,82 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+
+entity output_analog is
+ port
+ (
+ clk : in std_logic;
+ sys_rst_n : 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;
+
+ 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
+ );
+end output_analog;
+
+
+architecture beh of output_analog is
+
+
+ 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;
+ signal blank_r : std_logic;
+
+
+
+begin
+
+ process (sys_rst_n, clk)
+ begin
+ if sys_rst_n = '0' then
+ r_r <= '0';
+ g_r <= '0';
+ b_r <= '0';
+ hsync_r <= '0';
+ vsync_r <= '0';
+ blank_r <= '0';
+ elsif rising_edge(clk) then
+ r_r <= r_in;
+ g_r <= g_in;
+ b_r <= b_in;
+ hsync_r <= hsync_in;
+ vsync_r <= vsync_in;
+ blank_r <= blank_in;
+
+ end if;
+ end process;
+
+
+ process (sys_rst_n, clk)
+ begin
+ if sys_rst_n = '0' then
+ r_out <= '0';
+ g_out <= '0';
+ b_out <= '0';
+ hsync_out <= '0';
+ vsync_out <= '0';
+ elsif rising_edge(clk) then
+ 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;
+ end process;
+
+
+end beh;
diff --git a/fpga/hp_lcd_driver_a7/source/output_formatter.vhdl b/fpga/hp_lcd_driver_a7/source/output_formatter.vhdl
new file mode 100644
index 0000000..3e26515
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/output_formatter.vhdl
@@ -0,0 +1,142 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+
+
+entity output_formatter is
+ generic (addr_width : natural := 17;
+ h_front_porch : natural := 208;
+ h_active : natural := 384;
+ h_sync_start : natural := 400;
+ h_sync_end : natural := 440;
+ h_total : natural := 600;
+ v_active : natural := 592;
+ v_sync_start : natural := 593;
+ v_sync_end : natural := 596;
+ v_total : natural := 614;
+ h_stride : natural := 1;
+ v_stride : natural := 384
+ );
+ port (
+ sys_rst_n : in std_logic;
+ clk : in std_logic;
+ vsync_in : in std_logic;
+ addr_out : out std_logic_vector(addr_width -1 downto 0);
+ blank_out : out std_logic;
+ vsync_out : out std_logic;
+ hsync_out : out std_logic;
+ h_grid : out std_logic;
+ v_grid : out std_logic
+ );
+end output_formatter;
+
+
+architecture beh of output_formatter is
+
+ signal row_addr : std_logic_vector(addr_width-1 downto 0);
+ signal addr : std_logic_vector(addr_width-1 downto 0);
+
+ signal vsync_in_ne : std_logic;
+
+ signal h : natural;
+ signal v : natural;
+
+
+ signal blank : std_logic;
+ signal vblank : std_logic;
+ signal vsync : std_logic;
+ signal hsync : std_logic;
+
+
+begin
+
+ vsync_ed : entity work.edge_det
+ port map(
+ clk => clk,
+ sig => vsync_in,
+ e => open,
+ pe => open,
+ ne => vsync_in_ne);
+
+ process (clk, vsync_in_ne, sys_rst_n)
+ begin
+ if sys_rst_n = '0' then
+ h <= 0;
+ v <= 0;
+ elsif rising_edge(clk) then
+ if h /= (h_total-1) then
+ h <= h+1;
+ else
+ if v /= (v_total-1) then
+ v <= v+1;
+ h <= 0;
+ else --if vsync_in_ne = '1' then
+ h <= 0;
+ v <= 0;
+ end if;
+ end if;
+ end if;
+ end process;
+
+
+ process (clk, h, h, sys_rst_n)
+ begin
+ if sys_rst_n = '0' then
+ row_addr <= (others => '0');
+ addr <= (others => '0');
+ blank <= '1';
+ vblank <= '1';
+ vsync <= '0';
+ hsync <= '0';
+ elsif rising_edge(clk) then
+
+ if h = 0 then
+ if v = 0 then
+ --row_addr <= std_logic_vector(to_unsigned(-10*v_stride,row_addr'length));
+ row_addr <= std_logic_vector(to_unsigned(v_stride, row_addr'length));
+ --addr <= std_logic_vector(to_unsigned(-10*v_stride,row_addr'length));
+ addr <= (others => '0');
+ blank <= '0';
+ vblank <= '0';
+ elsif v = v_active then
+ vblank <= '1';
+ elsif v = v_sync_start then
+ vsync <= '1';
+ elsif v = v_sync_end then
+ vsync <= '0';
+ else
+ blank <= vblank;
+ row_addr <= std_logic_vector(unsigned(row_addr)+v_stride);
+ addr <= row_addr;
+ end if;
+ elsif h = h_active then
+ blank <= '1';
+ elsif h = h_sync_start then
+ hsync <= '1';
+ elsif h = h_sync_end then
+ hsync <= '0';
+ else
+ addr <= std_logic_vector(unsigned(addr)+h_stride);
+ end if;
+ end if;
+ end process;
+
+ h_grid <= '1' when (h mod 32) = 0
+-- h_grid <= '1' when (h = 0) or (h = (h_active-1))
+ else '0';
+
+ v_grid <= '1' when (v mod 32) = 0
+-- v_grid <= '1' when (v = 0) or (v = (v_active-1))
+ else '0';
+
+
+ addr_out <= addr;
+ blank_out <= blank;
+ hsync_out <= hsync;
+ vsync_out <= vsync;
+
+end beh;
+
+
+
diff --git a/fpga/hp_lcd_driver_a7/source/output_stage.vhdl b/fpga/hp_lcd_driver_a7/source/output_stage.vhdl
new file mode 100644
index 0000000..e02d8ce
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/output_stage.vhdl
@@ -0,0 +1,256 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+entity output_stage is
+ generic (target : string := "spartan6";
+ debounce_stages : natural := 2;
+ sync_stages : natural := 2;
+ addr_width : natural := 17;
+ h_front_porch : natural := 208;
+ h_active : natural := 384;
+ h_sync_start : natural := 400;
+ h_sync_end : natural := 440;
+ h_total : natural := 600;
+ v_active : natural := 592;
+ v_sync_start : natural := 593;
+ v_sync_end : natural := 596;
+ v_total : natural := 614;
+ h_stride : natural := 1;
+ v_stride : natural := 384
+ );
+ port
+ (
+ clk_locked : in std_logic;
+ clk : in std_logic;
+ clk_x2 : in std_logic;
+ clk_phy : 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);
+
+ 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);
+
+
+ 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_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 s_vsync_in : std_logic;
+ signal d_vsync_in : std_logic;
+
+ signal blank : std_logic;
+ signal hsync : std_logic;
+ signal vsync : std_logic;
+
+ signal blank_d : std_logic;
+ signal hsync_d : std_logic;
+ signal vsync_d : std_logic;
+ signal grid_d : std_logic;
+
+ signal addr : std_logic_vector(addr_width - 1 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 h_grid : std_logic;
+ signal v_grid : std_logic;
+
+ 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 c_p10 : std_logic_vector(9 downto 0);
+
+
+begin
+
+
+ vsync_sync : entity work.synchronizer
+ generic map(stages => sync_stages)
+ port map (
+ clk => clk,
+ i => vsync_in,
+ o => s_vsync_in
+ );
+
+ vsync_debounce : entity work.debounce
+ generic map(stages => debounce_stages)
+ port map(
+ clk => clk,
+ i => s_vsync_in,
+ o => d_vsync_in);
+
+
+ output_formatter : entity work.output_formatter
+ generic map(
+ addr_width => addr_width,
+ h_active => h_active,
+ h_sync_start => h_sync_start,
+ h_sync_end => h_sync_end,
+ h_total => h_total,
+ v_active => v_active,
+ v_sync_start => v_sync_start,
+ v_sync_end => v_sync_end,
+ v_total => v_total,
+ h_stride => h_stride,
+ v_stride => v_stride
+ )
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk => clk,
+ vsync_in => d_vsync_in,
+ addr_out => addr,
+ blank_out => blank,
+ vsync_out => vsync,
+ hsync_out => hsync,
+ h_grid => h_grid,
+ v_grid => v_grid
+ );
+
+
+ addr_out <= addr;
+
+-- dg : entity work.delay
+-- generic map(stages => 1)
+-- port map (
+-- clk => clk,
+-- i => h_grid or v_grid,
+-- o => grid_d
+-- );
+
+-- r <= r_in;
+ g <= g_in;
+-- b <= b_in;
+
+ b<=x"00" when v_grid='0'
+ else x"ff";
+
+ r<=x"00" when h_grid='0'
+ else x"ff";
+
+-- b<=x"00" when v_grid='0' and h_grid='0'
+-- else x"ff";
+
+--
+-- dh : entity work.delay
+-- generic map(stages => 10)
+-- port map (
+-- clk => clk,
+-- i => hsync,
+-- o => hsync_d
+-- );
+--
+--
+--
+-- dv : entity work.delay
+-- generic map(stages => 10)
+-- port map (
+-- clk => clk,
+-- i => vsync,
+-- o => vsync_d
+-- );
+--
+--
+--
+ dn : entity work.delay
+ generic map(stages => 1)
+ port map (
+ clk => clk,
+ i => blank,
+ o => blank_d
+ );
+
+
+ hsync_d <= hsync;
+ vsync_d <= vsync;
+
+
+ analog : entity work.output_analog
+ port map(
+ sys_rst_n => sys_rst_n,
+
+ clk => clk,
+
+ hsync_in => hsync_d,
+ vsync_in => vsync_d,
+ blank_in => blank_d,
+ r_in => g(7),
+ g_in => r(7),
+ b_in => b(7),
+
+ r_out => r_out,
+ g_out => g_out,
+ b_out => b_out,
+ hsync_out => hsync_out,
+ vsync_out => vsync_out
+ );
+
+
+ tmds_e : entity work.tmds_encode port map (
+ sys_rst_n => sys_rst_n,
+ pclk => clk,
+
+ r_in => r,
+ g_in => g,
+ b_in => b,
+ hsync => hsync_d,
+ vsync => vsync_d,
+ blank => blank_d,
+
+ r_p10 => r_p10,
+ g_p10 => g_p10,
+ b_p10 => b_p10,
+ c_p10 => c_p10
+
+ );
+
+
+ tmds_o : entity work.tmds_output
+ port map (
+ sys_rst_n => sys_rst_n,
+ pclk_locked => clk_locked,
+ pclk => clk,
+ pclk_x2 => clk_x2,
+ pclk_phy => clk_phy,
+
+ r_p10 => r_p10,
+ g_p10 => g_p10,
+ b_p10 => b_p10,
+ c_p10 => c_p10,
+
+ 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
+ );
+
+
+
+
+end beh;
diff --git a/fpga/hp_lcd_driver_a7/source/rando_a7.tcl b/fpga/hp_lcd_driver_a7/source/rando_a7.tcl
new file mode 100644
index 0000000..c29c369
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/rando_a7.tcl
@@ -0,0 +1,8 @@
+#
+set part_num "xc7a35tfgg484-2L"
+set early_xdc "../source/rando_a7_early.xdc"
+set normal_xdc "../source/rando_a7.xdc"
+#set MEM_DATA_WIDTH 0
+#set MEM_ADDR_WIDTH 0
+#set aclk 125
+#set sclk 200
diff --git a/fpga/hp_lcd_driver_a7/source/rando_a7.xdc b/fpga/hp_lcd_driver_a7/source/rando_a7.xdc
new file mode 100644
index 0000000..b851836
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/rando_a7.xdc
@@ -0,0 +1,69 @@
+# "Normal" constraints file- not early not late
+
+
+###############################################################################
+# DDR
+###############################################################################
+# Note: Most of the pins are set in the constraints file created by MIG
+#set_property IOSTANDARD LVDS_25 [get_ports sys_clk_clk_p]
+#set_property IOSTANDARD LVDS_25 [get_ports sys_clk_clk_n]
+
+###############################################################################
+# LEDs (4)
+###############################################################################
+
+#set_property PACKAGE_PIN G3 [get_ports led_d0]
+#set_property IOSTANDARD LVCMOS33 [get_ports led_d0]
+#set_property PULLUP true [get_ports led_d0]
+#set_property DRIVE 8 [get_ports led_d0]
+#
+#set_property PACKAGE_PIN H3 [get_ports led_d1]
+#set_property IOSTANDARD LVCMOS33 [get_ports led_d1]
+#set_property PULLUP true [get_ports led_d1]
+#set_property DRIVE 8 [get_ports led_d1]
+#
+#set_property PACKAGE_PIN G4 [get_ports {led_d2}]
+#set_property IOSTANDARD LVCMOS33 [get_ports {led_d2}]
+#set_property PULLUP true [get_ports {led_d2}]
+#set_property DRIVE 8 [get_ports {led_d2}]
+#
+#set_property PACKAGE_PIN H4 [get_ports {led_d3}]
+#set_property IOSTANDARD LVCMOS33 [get_ports {led_d3}]
+#set_property PULLUP true [get_ports {led_d3}]
+#set_property DRIVE 8 [get_ports {led_d3}]
+#
+#
+# Timing Constraints
+###############################################################################
+
+#create_clock -period 10.000 -name pcie_clkin [get_ports pcie_clkin_p]
+
+###############################################################################
+# Physical Constraints
+###############################################################################
+
+#create_clock -period 10.000 -name clk_100m [get_ports pci_exp_ref_clk_p]
+
+#set_false_path -from [get_ports pci_exp_rst_n]
+
+
+###############################################################################
+# Additional design / project settings
+###############################################################################
+
+# Power down on overtemp
+set_property BITSTREAM.CONFIG.OVERTEMPPOWERDOWN ENABLE [current_design]
+
+# High-speed configuration so FPGA is up in time to negotiate with PCIe root complex
+set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN Div-1 [current_design]
+set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
+set_property CONFIG_MODE SPIx4 [current_design]
+set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
+set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
+
+set_property CONFIG_VOLTAGE 3.3 [current_design]
+set_property CFGBVS VCCO [current_design]
+
+
+
+
diff --git a/fpga/hp_lcd_driver_a7/source/rando_a7_early.xdc b/fpga/hp_lcd_driver_a7/source/rando_a7_early.xdc
new file mode 100644
index 0000000..e234ae6
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/rando_a7_early.xdc
@@ -0,0 +1,4 @@
+# "Early" constraints file
+# Evaluated before integrated IP
+
+
diff --git a/fpga/hp_lcd_driver_a7/source/synchronizer.vhdl b/fpga/hp_lcd_driver_a7/source/synchronizer.vhdl
new file mode 100644
index 0000000..302cef9
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/synchronizer.vhdl
@@ -0,0 +1,26 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+
+entity synchronizer is
+ generic (stages : natural := 2);
+ port (clk : in std_logic;
+ i : in std_logic;
+ o : out std_logic);
+end synchronizer;
+
+architecture Behavioral of synchronizer is
+ signal flipflops : std_logic_vector(stages-1 downto 0) := (others => '0');
+ attribute ASYNC_REG : string;
+ attribute ASYNC_REG of flipflops : signal is "true";
+begin
+
+ o <= flipflops(flipflops'high);
+
+ clk_proc : process(clk, flipflops, i)
+ begin
+ if rising_edge(clk) then
+ flipflops <= flipflops(flipflops'high-1 downto 0) & i;
+ end if;
+ end process;
+
+end Behavioral;
diff --git a/fpga/hp_lcd_driver_a7/source/tmds_encode.vhdl b/fpga/hp_lcd_driver_a7/source/tmds_encode.vhdl
new file mode 100644
index 0000000..fe69a56
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/tmds_encode.vhdl
@@ -0,0 +1,73 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+
+entity tmds_encode is
+ port (
+ sys_rst_n : in std_logic;
+ pclk : 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;
+
+
+ r_p10 : out std_logic_vector(9 downto 0);
+ g_p10 : out std_logic_vector(9 downto 0);
+ b_p10 : out std_logic_vector(9 downto 0);
+ c_p10 : out std_logic_vector(9 downto 0)
+
+ );
+end tmds_encode;
+
+
+architecture beh of tmds_encode is
+ signal ctrl : std_logic_vector(1 downto 0);
+
+begin
+
+ c_p10 <= "1111100000";
+
+ 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
+ );
+
+
+end beh;
+
+
diff --git a/fpga/hp_lcd_driver_a7/source/tmds_encoder.vhdl b/fpga/hp_lcd_driver_a7/source/tmds_encoder.vhdl
new file mode 100644
index 0000000..40f8dd4
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/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/fpga/hp_lcd_driver_a7/source/tmds_output_artix7.vhdl b/fpga/hp_lcd_driver_a7/source/tmds_output_artix7.vhdl
new file mode 100644
index 0000000..10f064c
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/tmds_output_artix7.vhdl
@@ -0,0 +1,128 @@
+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_phy : in std_logic;
+
+ r_p10 : in std_logic_vector(9 downto 0);
+ g_p10 : in std_logic_vector(9 downto 0);
+ b_p10 : in std_logic_vector(9 downto 0);
+ c_p10 : in std_logic_vector(9 downto 0);
+
+
+ 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 phy_reset : std_logic;
+ signal upper : std_logic;
+ signal pll_locked : std_logic;
+ signal ioclk : std_logic;
+ signal serdesstrobe : std_logic;
+
+begin
+-- phy_reset <= not sys_rst_n or not pll_locked;
+--
+-- process (pclk_x2, phy_reset)
+-- begin
+-- if phy_reset = '1' then
+-- upper <= '1';
+-- elsif rising_edge(pclk_x2) then
+-- upper <= not upper;
+-- end if;
+-- end process;
+--
+--
+-- ioclk_buf : BUFPLL generic map (DIVIDE => 5)
+-- port map (
+-- PLLIN => pclk_phy,
+-- GCLK => pclk_x2,
+-- LOCKED => pclk_locked,
+-- IOCLK => ioclk,
+-- SERDESSTROBE => serdesstrobe,
+-- LOCK => pll_locked);
+--
+--
+-- phy_c : entity work.tmds_phy_spartan6
+-- port map (
+-- reset => phy_reset,
+-- pclk_x2 => pclk_x2,
+-- serdesstrobe => serdesstrobe,
+-- ioclk => ioclk,
+-- upper => upper,
+-- din => c_p10,
+-- tmds_out_p => tmds_c_out_p,
+-- tmds_out_n => tmds_c_out_n
+-- );
+--
+-- phy_r : entity work.tmds_phy_spartan6
+-- 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_spartan6
+-- 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_spartan6
+-- port map (
+-- reset => phy_reset,
+-- pclk_x2 => pclk_x2,
+-- serdesstrobe => serdesstrobe,
+-- ioclk => pclk_phy,
+-- upper => upper,
+-- din => b_p10,
+-- tmds_out_p => tmds_b_out_p,
+-- tmds_out_n => tmds_b_out_n
+-- );
+--
+--
+ tmds_c_out_p <= '0';
+ tmds_c_out_n <= '0';
+ tmds_r_out_p <= '0';
+ tmds_r_out_n <= '0';
+ tmds_g_out_p <= '0';
+ tmds_g_out_n <= '0';
+ tmds_b_out_p <= '0';
+ tmds_b_out_n <= '0';
+
+
+end beh;
diff --git a/fpga/hp_lcd_driver_a7/source/vram_artix7.vhdl b/fpga/hp_lcd_driver_a7/source/vram_artix7.vhdl
new file mode 100644
index 0000000..79af3e6
--- /dev/null
+++ b/fpga/hp_lcd_driver_a7/source/vram_artix7.vhdl
@@ -0,0 +1,26 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity vram is
+ generic (
+ addr_width : natural := 17;
+ video_width : natural := 2
+ );
+ port (
+ wr_clk : in std_logic;
+ wr_en : in std_logic;
+ wr_addr : in std_logic_vector(addr_width-1 downto 0);
+ wr_data : in std_logic_vector(video_width-1 downto 0);
+ rd_clk : in std_logic;
+ rd_addr : in std_logic_vector(addr_width-1 downto 0);
+ rd_data : out std_logic_vector(video_width-1 downto 0)
+ );
+end vram;
+
+architecture beh of vram is
+ signal wr_en_v : std_logic_vector(0 downto 0);
+begin
+
+rd_data <= (others =>'0');
+
+end beh;