diff options
author | James McKenzie <james.mckenzie@hp.com> | 2025-08-05 09:00:29 +0100 |
---|---|---|
committer | James McKenzie <james.mckenzie@hp.com> | 2025-08-05 09:00:29 +0100 |
commit | 309f6cc7a094bbe6fd7ee2899cba7e4e4ebbe64e (patch) | |
tree | c631312a1de28348043a427ba2c0824e9484eb55 /fpga/hp_lcd_driver_a7 | |
parent | 1a6dbe19eeccc13abef14bb19aad7750a9e901e0 (diff) | |
download | hp_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')
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; |