[
  {
    "path": "Artix-7-HDMI-processing.xpr",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<!-- Product Version: Vivado v2017.4 (64-bit)              -->\r\n<!--                                                         -->\r\n<!-- Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.   -->\r\n\r\n<Project Version=\"7\" Minor=\"35\" Path=\"C:/Users/Hamster/Desktop/a7/Artix-7-HDMI-processing/Artix-7-HDMI-processing.xpr\">\r\n  <DefaultLaunch Dir=\"$PRUNDIR\"/>\r\n  <Configuration>\r\n    <Option Name=\"Id\" Val=\"487e6670b2224898a3f8937139078585\"/>\r\n    <Option Name=\"Part\" Val=\"xc7a200tfbg484-1\"/>\r\n    <Option Name=\"CompiledLibDir\" Val=\"$PCACHEDIR/compile_simlib\"/>\r\n    <Option Name=\"CompiledLibDirXSim\" Val=\"\"/>\r\n    <Option Name=\"CompiledLibDirModelSim\" Val=\"$PCACHEDIR/compile_simlib/modelsim\"/>\r\n    <Option Name=\"CompiledLibDirQuesta\" Val=\"$PCACHEDIR/compile_simlib/questa\"/>\r\n    <Option Name=\"CompiledLibDirIES\" Val=\"$PCACHEDIR/compile_simlib/ies\"/>\r\n    <Option Name=\"CompiledLibDirXcelium\" Val=\"$PCACHEDIR/compile_simlib/xcelium\"/>\r\n    <Option Name=\"CompiledLibDirVCS\" Val=\"$PCACHEDIR/compile_simlib/vcs\"/>\r\n    <Option Name=\"CompiledLibDirRiviera\" Val=\"$PCACHEDIR/compile_simlib/riviera\"/>\r\n    <Option Name=\"CompiledLibDirActivehdl\" Val=\"$PCACHEDIR/compile_simlib/activehdl\"/>\r\n    <Option Name=\"TargetLanguage\" Val=\"VHDL\"/>\r\n    <Option Name=\"BoardPart\" Val=\"\"/>\r\n    <Option Name=\"ActiveSimSet\" Val=\"sim_1\"/>\r\n    <Option Name=\"DefaultLib\" Val=\"xil_defaultlib\"/>\r\n    <Option Name=\"ProjectType\" Val=\"Default\"/>\r\n    <Option Name=\"IPCachePermission\" Val=\"disable\"/>\r\n    <Option Name=\"EnableCoreContainer\" Val=\"FALSE\"/>\r\n    <Option Name=\"CreateRefXciForCoreContainers\" Val=\"FALSE\"/>\r\n    <Option Name=\"IPUserFilesDir\" Val=\"$PIPUSERFILESDIR\"/>\r\n    <Option Name=\"IPStaticSourceDir\" Val=\"$PIPUSERFILESDIR/ipstatic\"/>\r\n    <Option Name=\"EnableBDX\" Val=\"FALSE\"/>\r\n    <Option Name=\"DSAVendor\" Val=\"xilinx\"/>\r\n    <Option Name=\"DSANumComputeUnits\" Val=\"60\"/>\r\n    <Option Name=\"WTXSimLaunchSim\" Val=\"0\"/>\r\n    <Option Name=\"WTModelSimLaunchSim\" Val=\"0\"/>\r\n    <Option Name=\"WTQuestaLaunchSim\" Val=\"0\"/>\r\n    <Option Name=\"WTIesLaunchSim\" Val=\"0\"/>\r\n    <Option Name=\"WTVcsLaunchSim\" Val=\"0\"/>\r\n    <Option Name=\"WTRivieraLaunchSim\" Val=\"0\"/>\r\n    <Option Name=\"WTActivehdlLaunchSim\" Val=\"0\"/>\r\n    <Option Name=\"WTXSimExportSim\" Val=\"0\"/>\r\n    <Option Name=\"WTModelSimExportSim\" Val=\"0\"/>\r\n    <Option Name=\"WTQuestaExportSim\" Val=\"0\"/>\r\n    <Option Name=\"WTIesExportSim\" Val=\"0\"/>\r\n    <Option Name=\"WTVcsExportSim\" Val=\"0\"/>\r\n    <Option Name=\"WTRivieraExportSim\" Val=\"0\"/>\r\n    <Option Name=\"WTActivehdlExportSim\" Val=\"0\"/>\r\n    <Option Name=\"GenerateIPUpgradeLog\" Val=\"TRUE\"/>\r\n    <Option Name=\"XSimRadix\" Val=\"hex\"/>\r\n    <Option Name=\"XSimTimeUnit\" Val=\"ns\"/>\r\n    <Option Name=\"XSimArrayDisplayLimit\" Val=\"1024\"/>\r\n    <Option Name=\"XSimTraceLimit\" Val=\"65536\"/>\r\n    <Option Name=\"SimTypes\" Val=\"rtl\"/>\r\n  </Configuration>\r\n  <FileSets Version=\"1\" Minor=\"31\">\r\n    <FileSet Name=\"sources_1\" Type=\"DesignSrcs\" RelSrcDir=\"$PSRCDIR/sources_1\">\r\n      <Filter Type=\"Srcs\"/>\r\n      <File Path=\"$PPRDIR/src/alignment_detect.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/audio_meters.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/audio_to_db.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/conversion_to_RGB.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/deserialiser_1_to_10.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/detect_interlace.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/dvid_output.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/edge_enhance.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/edid_rom.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/expand_422_to_444.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/extract_audio_samples.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/extract_video_infopacket_data.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/guidelines.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/hdmi_input.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/hdmi_io.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/input_channel.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/line_delay.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/pixel_processing.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/serialiser_10_to_1.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/symbol_dump.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/tmds_decoder.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/tmds_encoder.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/src/hdmi_design.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <Config>\r\n        <Option Name=\"DesignMode\" Val=\"RTL\"/>\r\n        <Option Name=\"TopModule\" Val=\"hdmi_design\"/>\r\n        <Option Name=\"TopAutoSet\" Val=\"TRUE\"/>\r\n      </Config>\r\n    </FileSet>\r\n    <FileSet Name=\"constrs_1\" Type=\"Constrs\" RelSrcDir=\"$PSRCDIR/constrs_1\">\r\n      <Filter Type=\"Constrs\"/>\r\n      <File Path=\"$PPRDIR/constraints/NexysVideo.xdc\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"implementation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <Config>\r\n        <Option Name=\"TargetConstrsFile\" Val=\"$PPRDIR/constraints/NexysVideo.xdc\"/>\r\n        <Option Name=\"ConstrsType\" Val=\"XDC\"/>\r\n      </Config>\r\n    </FileSet>\r\n    <FileSet Name=\"sim_1\" Type=\"SimulationSrcs\" RelSrcDir=\"$PSRCDIR/sim_1\">\r\n      <Filter Type=\"Srcs\"/>\r\n      <File Path=\"$PPRDIR/test_bench/hdmi_test_generator/hdmi_ouput_test.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/test_bench/hdmi_test_generator/minimal_hdmi_symbols.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/test_bench/hdmi_test_generator/serializers.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/test_bench/hdmi_test_generator/vga_clocking.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/test_bench/hdmi_test_generator/vga_gen.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/test_bench/tb_hdmi_decode.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/test_bench/tb_convert_yCbCr_to_RGB.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"AutoDisabled\" Val=\"1\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <File Path=\"$PPRDIR/test_bench/tb_audio_to_db.vhd\">\r\n        <FileInfo>\r\n          <Attr Name=\"AutoDisabled\" Val=\"1\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"synthesis\"/>\r\n          <Attr Name=\"UsedIn\" Val=\"simulation\"/>\r\n        </FileInfo>\r\n      </File>\r\n      <Config>\r\n        <Option Name=\"DesignMode\" Val=\"RTL\"/>\r\n        <Option Name=\"TopModule\" Val=\"tb_hdmi_decode\"/>\r\n        <Option Name=\"TopLib\" Val=\"xil_defaultlib\"/>\r\n        <Option Name=\"TopAutoSet\" Val=\"TRUE\"/>\r\n        <Option Name=\"TransportPathDelay\" Val=\"0\"/>\r\n        <Option Name=\"TransportIntDelay\" Val=\"0\"/>\r\n        <Option Name=\"SrcSet\" Val=\"sources_1\"/>\r\n        <Option Name=\"XSimWcfgFile\" Val=\"$PPRDIR/tb_hdmi_decode_behav.wcfg\"/>\r\n      </Config>\r\n    </FileSet>\r\n  </FileSets>\r\n  <Simulators>\r\n    <Simulator Name=\"XSim\">\r\n      <Option Name=\"Description\" Val=\"Vivado Simulator\"/>\r\n      <Option Name=\"CompiledLib\" Val=\"0\"/>\r\n    </Simulator>\r\n    <Simulator Name=\"ModelSim\">\r\n      <Option Name=\"Description\" Val=\"ModelSim Simulator\"/>\r\n    </Simulator>\r\n    <Simulator Name=\"Questa\">\r\n      <Option Name=\"Description\" Val=\"Questa Advanced Simulator\"/>\r\n    </Simulator>\r\n    <Simulator Name=\"Riviera\">\r\n      <Option Name=\"Description\" Val=\"Riviera-PRO Simulator\"/>\r\n    </Simulator>\r\n    <Simulator Name=\"ActiveHDL\">\r\n      <Option Name=\"Description\" Val=\"Active-HDL Simulator\"/>\r\n    </Simulator>\r\n  </Simulators>\r\n  <Runs Version=\"1\" Minor=\"10\">\r\n    <Run Id=\"synth_1\" Type=\"Ft3:Synth\" SrcSet=\"sources_1\" Part=\"xc7a200tfbg484-1\" ConstrsSet=\"constrs_1\" Description=\"Vivado Synthesis Defaults\" WriteIncrSynthDcp=\"false\" State=\"current\" Dir=\"$PRUNDIR/synth_1\" IncludeInArchive=\"true\">\r\n      <Strategy Version=\"1\" Minor=\"2\">\r\n        <StratHandle Name=\"Vivado Synthesis Defaults\" Flow=\"Vivado Synthesis 2014\"/>\r\n        <Step Id=\"synth_design\"/>\r\n      </Strategy>\r\n      <GeneratedRun Dir=\"$PRUNDIR\" File=\"gen_run.xml\"/>\r\n      <ReportStrategy Name=\"Vivado Synthesis Default Reports\" Flow=\"Vivado Synthesis 2017\"/>\r\n      <Report Name=\"ROUTE_DESIGN.REPORT_METHODOLOGY\" Enabled=\"1\"/>\r\n    </Run>\r\n    <Run Id=\"impl_1\" Type=\"Ft2:EntireDesign\" Part=\"xc7a200tfbg484-1\" ConstrsSet=\"constrs_1\" Description=\"Vivado Implementation Defaults\" WriteIncrSynthDcp=\"false\" State=\"current\" Dir=\"$PRUNDIR/impl_1\" SynthRun=\"synth_1\" IncludeInArchive=\"true\">\r\n      <Strategy Version=\"1\" Minor=\"2\">\r\n        <StratHandle Name=\"Vivado Implementation Defaults\" Flow=\"Vivado Implementation 2014\"/>\r\n        <Step Id=\"init_design\"/>\r\n        <Step Id=\"opt_design\"/>\r\n        <Step Id=\"power_opt_design\"/>\r\n        <Step Id=\"place_design\"/>\r\n        <Step Id=\"post_place_power_opt_design\"/>\r\n        <Step Id=\"phys_opt_design\"/>\r\n        <Step Id=\"route_design\"/>\r\n        <Step Id=\"post_route_phys_opt_design\"/>\r\n        <Step Id=\"write_bitstream\"/>\r\n      </Strategy>\r\n      <GeneratedRun Dir=\"$PRUNDIR\" File=\"gen_run.xml\"/>\r\n      <ReportStrategy Name=\"Vivado Implementation Default Reports\" Flow=\"Vivado Implementation 2017\"/>\r\n      <Report Name=\"ROUTE_DESIGN.REPORT_METHODOLOGY\" Enabled=\"1\"/>\r\n    </Run>\r\n  </Runs>\r\n  <Board/>\r\n</Project>\r\n"
  },
  {
    "path": "README.txt",
    "content": "README file for Artix 7 HDMI processing\r\n=======================================\r\nHi! \r\n\r\nThis is my design for receiving HDMI input, then extracting the video data, the\r\nVideo Inforframe and audio samples, then using that to display audio db meters \r\non the top corner of the screen. Currently for simplicity the output is only DVID.\r\n\r\nFeatures\r\n--------\r\nSupports HDMI formats:\r\n  -720p@50\r\n - 720p@60, \r\n - 1080i (with a bug)\r\n - 1080p@50\r\n - 1080p@60\r\n and others....\r\n\r\nColourspaces / formats:\r\n - RGB 444\r\n - YCbCr 444\r\n - YCbCr 422\r\n\r\nNew feature 10-AUG-2015!\r\n-----------------------\r\nSwitch 0 will turn real-time edge detect off and on.\r\n\r\nNew feature 6-AUG-2015!\r\n-----------------------\r\nSwitch 1 will turn guidelines off and on. Will only show in 1080p 1080i and 720p resolutions.\r\n\r\nSupported Boards\r\n----------------\r\n - Digilent Nexys Video \r\n\r\nSources tested with:\r\n - Western Digital HD Live\r\n - HP Laptop\r\n\r\nSinks tested with:\r\n - Viewsonic Monitor\r\n - AOC Monitor\r\n - Vivo TV\r\n \r\nKnown issues:\r\n - Currently extracts only two channels of audio \r\n\r\n - Does not adjust PLL settings for input clock, so the PLL is run slightly out\r\n   of spec.\r\n\r\n - Image may re-sync once after a few seconds if symbol errors are seen.\r\n\r\n - There are timings errors, as generating 148.5MHz HDMI using the Artix-7 chip\r\n   is actually out of spec. Expect seven failing paths and about 20ns of negative \r\n   slack.\r\n\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n"
  },
  {
    "path": "constraints/NexysVideo.xdc",
    "content": "#------------------------------------------------------------------------------------ \r\n# HDMI and clock Constraints for the Digilent Nexys Video FPGA development board.\r\n#------------------------------------------------------------------------------------ \r\n\r\n##Clock Signal\r\nset_property -dict { PACKAGE_PIN R4    IOSTANDARD LVCMOS33 } [get_ports { clk100 }];\r\n    create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk100]\r\n    \r\n##HDMI in\r\ncreate_clock -add -name hdmi_clk -period 6.7 -waveform {0 5} [get_ports hdmi_rx_clk_p]\r\n\r\nset_property -dict { PACKAGE_PIN AA5   IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_cec }]; #IO_L10P_T1_34 Sch=hdmi_rx_cec\r\nset_property -dict { PACKAGE_PIN W4    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_clk_n }]; #IO_L12N_T1_MRCC_34 Sch=hdmi_rx_clk_n\r\nset_property -dict { PACKAGE_PIN V4    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_clk_p }]; #IO_L12P_T1_MRCC_34 Sch=hdmi_rx_clk_p\r\nset_property -dict { PACKAGE_PIN AB12  IOSTANDARD LVCMOS25 } [get_ports { hdmi_rx_hpa }]; #IO_L7N_T1_13 Sch=hdmi_rx_hpa\r\nset_property -dict { PACKAGE_PIN Y4    IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_scl }]; #IO_L11P_T1_SRCC_34 Sch=hdmi_rx_scl\r\nset_property -dict { PACKAGE_PIN AB5   IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_sda }]; #IO_L10N_T1_34 Sch=hdmi_rx_sda\r\nset_property -dict { PACKAGE_PIN R3    IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_txen }]; #IO_L3P_T0_DQS_34 Sch=hdmi_rx_txen\r\nset_property -dict { PACKAGE_PIN AA3   IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_n[0] }]; #IO_L9N_T1_DQS_34 Sch=hdmi_rx_n[0]\r\nset_property -dict { PACKAGE_PIN Y3    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_p[0] }]; #IO_L9P_T1_DQS_34 Sch=hdmi_rx_p[0]\r\nset_property -dict { PACKAGE_PIN Y2    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_n[1] }]; #IO_L4N_T0_34 Sch=hdmi_rx_n[1]\r\nset_property -dict { PACKAGE_PIN W2    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_p[1] }]; #IO_L4P_T0_34 Sch=hdmi_rx_p[1]\r\nset_property -dict { PACKAGE_PIN V2    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_n[2] }]; #IO_L2N_T0_34 Sch=hdmi_rx_n[2]\r\nset_property -dict { PACKAGE_PIN U2    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_p[2] }]; #IO_L2P_T0_34 Sch=hdmi_rx_p[2]\r\n\r\n\r\n##HDMI out\r\nset_property -dict { PACKAGE_PIN AA4   IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_cec }]; #IO_L11N_T1_SRCC_34 Sch=hdmi_tx_cec\r\nset_property -dict { PACKAGE_PIN U1    IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_clk_n }]; #IO_L1N_T0_34 Sch=hdmi_tx_clk_n\r\nset_property -dict { PACKAGE_PIN T1    IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_clk_p }]; #IO_L1P_T0_34 Sch=hdmi_tx_clk_p\r\nset_property -dict { PACKAGE_PIN AB13  IOSTANDARD LVCMOS25 } [get_ports { hdmi_tx_hpd }]; #IO_L3N_T0_DQS_13 Sch=hdmi_tx_hpd\r\nset_property -dict { PACKAGE_PIN U3    IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_rscl }]; #IO_L6P_T0_34 Sch=hdmi_tx_rscl\r\nset_property -dict { PACKAGE_PIN V3    IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_rsda }]; #IO_L6N_T0_VREF_34 Sch=hdmi_tx_rsda\r\nset_property -dict { PACKAGE_PIN Y1    IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_n[0] }]; #IO_L5N_T0_34 Sch=hdmi_tx_n[0]\r\nset_property -dict { PACKAGE_PIN W1    IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_p[0] }]; #IO_L5P_T0_34 Sch=hdmi_tx_p[0]\r\nset_property -dict { PACKAGE_PIN AB1   IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_n[1] }]; #IO_L7N_T1_34 Sch=hdmi_tx_n[1]\r\nset_property -dict { PACKAGE_PIN AA1   IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_p[1] }]; #IO_L7P_T1_34 Sch=hdmi_tx_p[1]\r\nset_property -dict { PACKAGE_PIN AB2   IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_n[2] }]; #IO_L8N_T1_34 Sch=hdmi_tx_n[2]\r\nset_property -dict { PACKAGE_PIN AB3   IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_p[2] }]; #IO_L8P_T1_34 Sch=hdmi_tx_p[2]\r\n\r\n# DEBUG on JA\r\nset_property -dict { PACKAGE_PIN AB22  IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[0] }]; #IO_L10N_T1_D15_14 Sch=ja[1]\r\nset_property -dict { PACKAGE_PIN AB21  IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[1] }]; #IO_L10P_T1_D14_14 Sch=ja[2]\r\nset_property -dict { PACKAGE_PIN AB20  IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[2] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=ja[3]\r\nset_property -dict { PACKAGE_PIN AB18  IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[3] }]; #IO_L17N_T2_A13_D29_14 Sch=ja[4]\r\nset_property -dict { PACKAGE_PIN Y21   IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[4] }]; #IO_L9P_T1_DQS_14 Sch=ja[7]\r\nset_property -dict { PACKAGE_PIN AA21  IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[5] }]; #IO_L8N_T1_D12_14 Sch=ja[8]\r\nset_property -dict { PACKAGE_PIN AA20  IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[6] }]; #IO_L8P_T1_D11_14 Sch=ja[9]\r\nset_property -dict { PACKAGE_PIN AA18  IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[7] }]; #IO_L17P_T2_A14_D30_14 Sch=ja[10\r\n\r\n##Switches\r\nset_property -dict { PACKAGE_PIN E22  IOSTANDARD LVCMOS25 } [get_ports { sw[0] }]; #IO_L22P_T3_16 Sch=sw[0]\r\nset_property -dict { PACKAGE_PIN F21  IOSTANDARD LVCMOS25 } [get_ports { sw[1] }]; #IO_25_16 Sch=sw[1]\r\nset_property -dict { PACKAGE_PIN G21  IOSTANDARD LVCMOS25 } [get_ports { sw[2] }]; #IO_L24P_T3_16 Sch=sw[2]\r\nset_property -dict { PACKAGE_PIN G22  IOSTANDARD LVCMOS25 } [get_ports { sw[3] }]; #IO_L24N_T3_16 Sch=sw[3]\r\nset_property -dict { PACKAGE_PIN H17  IOSTANDARD LVCMOS25 } [get_ports { sw[4] }]; #IO_L6P_T0_15 Sch=sw[4]\r\nset_property -dict { PACKAGE_PIN J16  IOSTANDARD LVCMOS25 } [get_ports { sw[5] }]; #IO_0_15 Sch=sw[5]\r\nset_property -dict { PACKAGE_PIN K13  IOSTANDARD LVCMOS25 } [get_ports { sw[6] }]; #IO_L19P_T3_A22_15 Sch=sw[6]\r\nset_property -dict { PACKAGE_PIN M17  IOSTANDARD LVCMOS25 } [get_ports { sw[7] }]; #IO_25_15 Sch=sw[7]\r\n\r\n##LEDs\r\nset_property -dict { PACKAGE_PIN T14   IOSTANDARD LVCMOS25 } [get_ports { led[0] }]; #IO_L15P_T2_DQS_13 Sch=led[0]\r\nset_property -dict { PACKAGE_PIN T15   IOSTANDARD LVCMOS25 } [get_ports { led[1] }]; #IO_L15N_T2_DQS_13 Sch=led[1]\r\nset_property -dict { PACKAGE_PIN T16   IOSTANDARD LVCMOS25 } [get_ports { led[2] }]; #IO_L17P_T2_13 Sch=led[2]\r\nset_property -dict { PACKAGE_PIN U16   IOSTANDARD LVCMOS25 } [get_ports { led[3] }]; #IO_L17N_T2_13 Sch=led[3]\r\nset_property -dict { PACKAGE_PIN V15   IOSTANDARD LVCMOS25 } [get_ports { led[4] }]; #IO_L14N_T2_SRCC_13 Sch=led[4]\r\nset_property -dict { PACKAGE_PIN W16   IOSTANDARD LVCMOS25 } [get_ports { led[5] }]; #IO_L16N_T2_13 Sch=led[5]\r\nset_property -dict { PACKAGE_PIN W15   IOSTANDARD LVCMOS25 } [get_ports { led[6] }]; #IO_L16P_T2_13 Sch=led[6]\r\nset_property -dict { PACKAGE_PIN Y13   IOSTANDARD LVCMOS25 } [get_ports { led[7] }]; #IO_L5P_T0_13 Sch=led[7]\r\n\r\n##UART\r\nset_property -dict { PACKAGE_PIN AA19  IOSTANDARD LVCMOS33 } [get_ports { rs232_tx }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=uart_rx_out\r\n"
  },
  {
    "path": "src/alignment_detect.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz< \r\n-- \r\n-- Module Name: alignment_detect - Behavioral\r\n--\r\n-- Description: Manage the dealy and bitslipping of the SERDES based on invald \r\n--              symbols being received.  \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity alignment_detect is\r\n    Port ( clk            : in  STD_LOGIC;\r\n           invalid_symbol : in  STD_LOGIC;\r\n           delay_count    : out std_logic_vector(4 downto 0);\r\n           delay_ce       : out STD_LOGIC;\r\n           bitslip        : out STD_LOGIC;\r\n           symbol_sync    : out STD_LOGIC);\r\nend alignment_detect;\r\n\r\narchitecture Behavioral of alignment_detect is\r\n    --------------------------------------\r\n    -- Signals for controlling the bitslip \r\n    -- and delay so we can sync symbols\r\n    --------------------------------------\r\n    signal count          : unsigned(19 downto 0) := (others => '0');\r\n    signal signal_quality : unsigned(27 downto 0) := (others => '0');\r\n    signal holdoff        : unsigned(9 downto 0)  := (others => '0');\r\n    signal error_seen     : std_logic := '0';\r\n    signal idelay_ce      : std_logic                    := '0';\r\n    signal idelay_count   : std_logic_vector(4 downto 0) := (others => '0');\r\n    signal symbol_sync_i  : std_logic                    := '0';\r\n\r\nbegin\r\n    delay_count <= idelay_count;\r\n    delay_ce    <= idelay_ce;\r\n \r\ndetect_alignment_proc: process(clk)\r\n    begin\r\n        -------------------------------------------------------------\r\n        -- If there are a dozen or so symbol errors in at a rate of \r\n        -- greater than 1 in a million then advance the delay and\r\n        -- if that wraps then assert the bitslip signal\r\n        -------------------------------------------------------------\r\n        if rising_edge(clk) then\r\n            -----------------------------------\r\n            -- See if an error has been seen\r\n            --\r\n            -- Holdoff gives a few cycles for \r\n            -- bitslips and delay changes to \r\n            -- take effect.\r\n            -----------------------------------\r\n            error_seen <= '0';\r\n            if holdoff = 0 then\r\n                if invalid_symbol = '1' then\r\n                    error_seen <= '1';\r\n                end if;\r\n            else \r\n                holdoff <= holdoff-1;\r\n            end if;\r\n            ---------------------------------------------\r\n            -- Keep track of valid symbol count vs errors\r\n            -- \r\n            -- Each error increase the count by a million, \r\n            -- each valid sysmbol decreases the count by \r\n            -- one. So after 12 errors it will cause us to\r\n            -- change bitslip or delay settings, but it will\r\n            -- take 7 million cycles until the high four \r\n            -- bits are zeros (and the link considered OK)\r\n            -----------------------------------------------\r\n            bitslip <= '0';\r\n            idelay_ce <= '0';\r\n            if error_seen = '1' then\r\n                if signal_quality(27 downto 24) = x\"F\" then\r\n                    ------------------------------------------\r\n                    -- Enough errors to cause us to loose sync \r\n                    -- (if we had it!) \r\n                    ------------------------------------------\r\n                    symbol_sync_i         <= '0';\r\n                    --------------------------------------                    \r\n                    -- Hold off acting on any more errors\r\n                    -- while we adjust the delay or bitslip\r\n                    --------------------------------------                    \r\n                    holdoff <= (others => '1');                    \r\n                    -----------------------\r\n                    -- Bitslip if required\r\n                    -----------------------\r\n                    if unsigned(idelay_count) = 31 then   \r\n                        bitslip <= '1';\r\n                    end if;\r\n                    -------------------------------------------------------------------\r\n                    -- And adjust the delay setting (will wrap to 0 when bitslipping)\r\n                    -------------------------------------------------------------------\r\n                    idelay_count  <= std_logic_vector(unsigned(idelay_count)+1);\r\n                    idelay_ce <= '1';   \r\n                    -------------------------------------------------------------------\r\n                    -- It will need 4M good symbols to avoid adjusting the timing again \r\n                    -------------------------------------------------------------------\r\n                    signal_quality(27 downto 24) <= x\"4\";\r\n                else\r\n                    signal_quality <= signal_quality + x\"100000\";   -- add a million if there is a symbol error\r\n                end if;\r\n            else \r\n                -----------------------------------------------\r\n                -- Count down by one, as we are one symbol \r\n                -- closer to having a valid stream\r\n                -----------------------------------------------\r\n                if signal_quality(27 downto 24) > 0 then\r\n                    signal_quality <= signal_quality - 1;   -- add a million if there is a symvole error;\r\n                end if;        \r\n            end if;\r\n            ------------------------------------\r\n            -- if we have counted down about 3M\r\n            -- symbols without any symbol errors\r\n            -- being seen then we are in sync\r\n            ------------------------------------\r\n            if signal_quality(27 downto 24) = \"0000\" then \r\n                symbol_sync <= '1';\r\n            end if;\r\n        end if;        \r\n    end process;\r\n\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/audio_meters.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: audio_meters - Behavioral\r\n--\r\n-- Description: Insert audio level meters on a video stream. \r\n-- \r\n-- Will need to make allowances for interlaced sources!\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity audio_meters is\r\n    Port ( clk : in STD_LOGIC;\r\n           -------------------------------\r\n           -- VGA data recovered from HDMI\r\n           -------------------------------\r\n           in_blank  : in std_logic;\r\n           in_hsync  : in std_logic;\r\n           in_vsync  : in std_logic;\r\n           in_red    : in std_logic_vector(7 downto 0);\r\n           in_green  : in std_logic_vector(7 downto 0);\r\n           in_blue   : in std_logic_vector(7 downto 0);\r\n           is_interlaced   : in std_logic;\r\n           is_second_field : in std_logic;\r\n            \r\n           -----------------------------------\r\n           -- VGA data to be converted to HDMI\r\n           -----------------------------------\r\n           out_blank : out std_logic;\r\n           out_hsync : out std_logic;\r\n           out_vsync : out std_logic;\r\n           out_red   : out std_logic_vector(7 downto 0);\r\n           out_green : out std_logic_vector(7 downto 0);\r\n           out_blue  : out std_logic_vector(7 downto 0);\r\n           \r\n           -------------------------------------\r\n           -- Audio Levels\r\n           -------------------------------------\r\n           signal audio_channel : in std_logic_vector(2 downto 0);\r\n           signal audio_de      : in std_logic;\r\n           signal audio_level   : in std_logic_vector(5 downto 0)\r\n     );\r\nend audio_meters;\r\n\r\narchitecture Behavioral of audio_meters is\r\n    signal col_count  : unsigned(11 downto 0);\r\n    signal line_count : unsigned(11 downto 0);\r\n    signal last_hsync : std_logic := '0';\r\n    signal last_vsync : std_logic := '0';\r\n    signal last_blank : std_logic := '0';\r\n\r\n    signal mid_blank : std_logic;\r\n    signal mid_hsync : std_logic;\r\n    signal mid_vsync : std_logic;\r\n    signal mid_red   : std_logic_vector(7 downto 0);\r\n    signal mid_green : std_logic_vector(7 downto 0);\r\n    signal mid_blue  : std_logic_vector(7 downto 0);\r\n    signal bar_draw : std_logic;\r\n    signal bar_col  : unsigned(6 downto 0); -- 0-127\r\n    signal bar_line : unsigned(5 downto 0); -- 0-63\r\n   \r\n    type a_level is array (0 to 7) of unsigned(5 downto 0);\r\n    signal levels : a_level;\r\n\r\n    type a_peak is array (0 to 7) of unsigned(7 downto 0);\r\n    signal peaks : a_peak;\r\n\r\n    signal pending_drop : std_logic := '0';\r\n\tsignal drop_index   : unsigned(2 downto 0) := (others => '0');\r\n\r\n    signal u_sample     : unsigned(5 downto 0) := (others => '0');\r\n    signal level        : unsigned(5 downto 0);\r\n    signal peak         : unsigned(5 downto 0);\r\n\r\nbegin\r\n    \r\nlevel_proc: process(clk)\r\n    begin\r\n        if rising_edge(clk) then\r\n            -------------------------------------------------\r\n            -- Update the peak level, or if pending_drop is \r\n            -- set then drop the peak and level by 1 every\r\n\t\t\t-- frame.\r\n\t\t\t--\r\n\t\t    -- This causes 'peak' to fall at 1/4th the speed\r\n\t\t    -- of 'level', but makes for inconsistent\r\n\t\t\t-- behaviour depending on frame rate :-(\r\n            -------------------------------------------------\r\n            if audio_de = '1' then \r\n                if levels(to_integer(unsigned(audio_channel))) < unsigned(audio_level) then\r\n                    levels(to_integer(unsigned(audio_channel))) <= unsigned(audio_level);\r\n                end if;     \r\n                if peaks(to_integer(unsigned(audio_channel))) < unsigned(audio_level &\"00\") then\r\n                    peaks(to_integer(unsigned(audio_channel))) <= unsigned(audio_level & \"00\");\r\n                end if;\r\n            else\r\n                if pending_drop = '1' then\r\n                    if levels(to_integer(drop_index)) > 0 then\r\n                        levels(to_integer(drop_index)) <= levels(to_integer(drop_index))-1;\r\n                    end if;\r\n                    if peaks(to_integer(drop_index)) > 0 then\r\n                        peaks(to_integer(drop_index))  <= peaks(to_integer(drop_index))-1;\r\n                    end if;\r\n                    if drop_index = \"000\" then\r\n                       pending_drop <= '0';    \r\n                    end if;\r\n                    drop_index <= drop_index-1;\r\n                end if;\r\n            end if;\r\n\r\n            -- Signal to reduce (drop' the levels of the meters once each frame (of field for interlaced sources\r\n            if last_vsync = '0'  and in_vsync = '1' then\r\n                pending_drop <= '1';\r\n                drop_index <= (others => '1');\r\n            end if;\r\n        end if;\r\n    end process;\r\n\r\nvideo_proc: process(clk)\r\n    begin\r\n        if rising_edge(clk) then\r\n            out_blank <= mid_blank;\r\n            out_hsync <= mid_hsync;\r\n            out_vsync <= mid_vsync;\r\n            out_red   <= mid_red;\r\n            out_green <= mid_green;\r\n            out_blue  <= mid_blue;\r\n\r\n            if bar_draw = '1' then\r\n                if bar_col(3 downto 1) /= \"000\" and bar_col(3 downto 1) /= \"111\" then\r\n                    if peak > bar_line then\r\n                        if peak > 60 then\r\n                            out_red(out_red'high) <= '1';\r\n                        else\r\n                            out_green(out_green'high) <= '1';\r\n                        end if;\r\n                    end if;\r\n                    \r\n                    if level = bar_line then\r\n                        out_red   <= (others => '1');\r\n                        out_green <= (others => '1');\r\n                        out_blue  <= (others => '1');\r\n                    end if;\r\n                end if; \r\n            end if;\r\n\r\n            -----------------------------------------------------------------------------\r\n            -- the mid_* signals contain the video with the box drawn to house the meters\r\n            -----------------------------------------------------------------------------\r\n            mid_blank <= in_blank;\r\n            mid_hsync <= in_hsync;\r\n            mid_vsync <= in_vsync;\r\n            mid_red   <= in_red;\r\n            mid_green <= in_green;\r\n            mid_blue  <= in_blue;\r\n            --------------------------------------------------\r\n            -- For working out if we need to draw colour bars\r\n            --------------------------------------------------\r\n            bar_draw <= '0';\r\n            bar_col   <= unsigned(col_count(6 downto 0))-1;\r\n            bar_line  <= to_unsigned(64,6)-unsigned(line_count(5 downto 0));\r\n            \r\n            -----------------------------------------------------------------------------\r\n            -- Retreive the levels for the bar. There is an \r\n            -- off-by-one error hidden by the bar boarder.\r\n            -----------------------------------------------------------------------------\r\n            level <= levels(to_integer(col_count(6 downto 4)));\r\n            peak  <= peaks(to_integer(col_count(6 downto 4)))(7 downto 2);\r\n            \r\n            -------------------------------------------------------\r\n            -- Halve the intensity of the area where the meters are.\r\n            -------------------------------------------------------\r\n            if col_count > 0 and  col_count < 129 and line_count > 0 and line_count < 65 then\r\n                bar_draw <= '1';\r\n            end if;   \r\n\r\n            if col_count > 0 and col_count < 129 and line_count > 0 and line_count < 65 then\r\n                mid_red   <= \"0\" & in_red(in_red'high downto 1);\r\n                mid_green <= \"0\" & in_green(in_green'high downto 1);\r\n                mid_blue  <= \"0\" & in_blue(in_blue'high downto 1);\r\n            end if;\r\n\r\n            -- Draw bounding box left/right sides\r\n            if (col_count = 0 or col_count = 129) and line_count < 66 then\r\n                mid_red   <= (others => '1');\r\n                mid_green <= (others => '1');\r\n                mid_blue  <= (others => '1');\r\n            end if; \r\n            -- Draw bounding box top/bottom sides\r\n            if (line_count = 0 or line_count = 65) and col_count < 130 then\r\n                mid_red   <= (others => '1');\r\n                mid_green <= (others => '1');\r\n                mid_blue  <= (others => '1');\r\n            end if; \r\n            \r\n\r\n            -- Increment the column count on when active pixels are seen \r\n            if in_blank = '0' then\r\n                col_count <= col_count + 1;\r\n            end if;\r\n\r\n            -- The end of active video is used to increment the line count           \r\n            if last_blank = '0' and in_blank = '1' then\r\n                if is_interlaced = '1' then\r\n                    line_count <= line_count + 2;\r\n                else\r\n                    line_count <= line_count + 1;\r\n                end if;\r\n                col_count <= (others => '0');\r\n            end if; \r\n                        \r\n            -- Reset the line count on falling vsync\r\n            if last_vsync = '1'  and in_vsync = '0' then\r\n                if is_interlaced = '1' and is_second_field = '1' then\r\n                    line_count <= (0 => '1', others => '0');\r\n                else\r\n                    line_count <= (others => '0');\r\n                end if;\r\n            end if;\r\n            -- remember the hsync and vsync values\r\n            last_vsync <= in_vsync;\r\n            last_hsync <= in_hsync;\r\n            last_blank <= in_blank;\r\n        end if;\r\n    end process;\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/audio_to_db.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Module Name: audio_to_db - Behavioral\r\n--\r\n-- Description: Calcuate the approximate DB level of an audio signal, with a \r\n--              return of 63 indicating 0db, (e.g. 3 = -60fb)\r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity audio_to_db is\r\n    Port ( clk           : in  STD_LOGIC;\r\n\r\n           in_channel    : in  STD_LOGIC_VECTOR (2 downto 0);\r\n           in_de         : in  STD_LOGIC;\r\n           in_sample     : in  STD_LOGIC_VECTOR (23 downto 0);\r\n\r\n           out_channel   : out STD_LOGIC_VECTOR (2 downto 0);\r\n           out_de        : out STD_LOGIC;\r\n           out_level     : out STD_LOGIC_VECTOR (5 downto 0));\r\nend audio_to_db;\r\n\r\narchitecture Behavioral of audio_to_db is\r\n\r\n    signal s7_sample  : unsigned (23 downto 0);\r\n    signal s7_de      : STD_LOGIC;\r\n    signal s7_channel : STD_LOGIC_VECTOR (2 downto 0);\r\n    signal s7_level   : unsigned( 7 downto 0);\r\n\r\n    signal s6_sample  : unsigned (23 downto 0);\r\n    signal s6_de      : STD_LOGIC;\r\n    signal s6_channel : STD_LOGIC_VECTOR (2 downto 0);\r\n    signal s6_level   : unsigned( 7 downto 0);\r\n\r\n    signal s5_sample  : unsigned (23 downto 0);\r\n    signal s5_de      : STD_LOGIC;\r\n    signal s5_channel : STD_LOGIC_VECTOR (2 downto 0);\r\n    signal s5_level   : unsigned( 7 downto 0);\r\n\r\n    signal s4_sample  : unsigned (23 downto 0);\r\n    signal s4_de      : STD_LOGIC;\r\n    signal s4_channel : STD_LOGIC_VECTOR (2 downto 0);\r\n    signal s4_level   : unsigned( 7 downto 0);\r\n\r\n    signal s3_sample  : unsigned (23 downto 0);\r\n    signal s3_de      : STD_LOGIC;\r\n    signal s3_channel : STD_LOGIC_VECTOR (2 downto 0);\r\n    signal s3_level   : unsigned( 7 downto 0);\r\n\r\n    signal s2_sample  : unsigned (23 downto 0);\r\n    signal s2_de      : STD_LOGIC;\r\n    signal s2_channel : STD_LOGIC_VECTOR (2 downto 0);\r\n    signal s2_level   : unsigned( 7 downto 0);\r\n\r\n    signal s1_sample  : unsigned (23 downto 0);\r\n    signal s1_de      : STD_LOGIC;\r\n    signal s1_channel : STD_LOGIC_VECTOR (2 downto 0);\r\nbegin\r\n\r\nprocess(clk)\r\n    begin\r\n        if rising_edge(clk) then\r\n            out_channel <= s7_channel;\r\n            out_de      <= s7_de;\r\n            if s7_level(7 downto 6) = \"00\" then\r\n                out_level <= std_logic_vector(to_unsigned(63,6)-s7_level(5 downto 0));\r\n            else\r\n                out_level <= (others => '0');\r\n            end if;\r\n            \r\n            -- Finally the last stage to get a db level\r\n            s7_channel <= s6_channel;\r\n            s7_de      <= s6_de;\r\n            if s6_sample(22 downto 15) < 72 then\r\n                s7_level <= s6_level + 5;\r\n            elsif s6_sample(22 downto 15) < 81 then\r\n                s7_level <= s6_level + 4;\r\n            elsif s6_sample(22 downto 15) < 91 then\r\n                s7_level <= s6_level + 3;\r\n            elsif s6_sample(22 downto 15) < 102 then\r\n                s7_level <= s6_level + 2;\r\n            elsif s6_sample(22 downto 15) < 114 then\r\n                s7_level <= s6_level + 1;\r\n            else\r\n                s7_level <= s6_level + 1;\r\n            end if;\r\n                        \r\n            -- Stage 5 - shift up 2 bits if needed(bit 23 of sample will be 0)\r\n            s6_channel <= s5_channel;\r\n            s6_de      <= s5_de;\r\n            if s5_sample(23 downto 22) = \"00\" then\r\n                s6_sample <= s5_sample(22 downto 0) & \"0\";\r\n                s6_level  <= s5_level + to_unsigned(6,8);\r\n            else\r\n                s6_sample <= s5_sample;\r\n                s6_level  <= s5_level;\r\n            end if; \r\n    \r\n            -- Stage 5 - shift up 2 bits if needed(bit 23 of sample will be 0)\r\n            s5_channel <= s4_channel;\r\n            s5_de      <= s4_de;\r\n            if s4_sample(23 downto 21) = \"000\" then\r\n                s5_sample <= s4_sample(21 downto 0) & \"00\";\r\n                s5_level  <= s4_level + to_unsigned(12,8);\r\n            else\r\n                s5_sample <= s4_sample;\r\n                s5_level  <= s4_level;\r\n            end if; \r\n        \r\n            -- Stage 4 - shift up 4 bits if needed(bit 23 of sample will be 0)\r\n            s4_channel <= s3_channel;\r\n            s4_de      <= s3_de;\r\n            if s3_sample(23 downto 19) = \"00000\" then\r\n                s4_sample <= s3_sample(19 downto 0) & \"0000\";\r\n                s4_level  <= s3_level + to_unsigned(24,8);\r\n            else\r\n                s4_sample <= s3_sample;\r\n                s4_level  <= s3_level;\r\n            end if; \r\n\r\n            -- Stage 3 - shift up 4 bits if needed(bit 23 of sample will be 0)\r\n            s3_channel <= s2_channel;\r\n            s3_de      <= s2_de;\r\n            if s2_sample(23 downto 19) = \"00000\" then\r\n                s3_sample <= s2_sample(19 downto 0) & \"0000\";\r\n                s3_level  <= s2_level + to_unsigned(24,8);\r\n            else\r\n                s3_sample <= s2_sample;\r\n                s3_level  <= s2_level;\r\n            end if; \r\n\r\n            -- Stage 2 - shift up 4 bits if needed(bit 23 of sample will be 0)\r\n            s2_channel <= s1_channel;\r\n            s2_de      <= s1_de;\r\n            if s1_sample(23 downto 19) = \"00000\" then\r\n                s2_sample <= s1_sample(19 downto 0) & \"0000\";\r\n                s2_level  <= to_unsigned(24,8);\r\n            else\r\n                s2_sample <= s1_sample;\r\n                s2_level  <= to_unsigned(0,8);\r\n            end if; \r\n             \r\n            --- Stage 1 - remove any sign.\r\n            s1_channel <= in_channel;\r\n            s1_de      <= in_de;\r\n            if in_sample(23) = '1' then\r\n                s1_sample  <= to_unsigned(0,24) - unsigned(in_sample);\r\n            else\r\n                s1_sample  <= unsigned(in_sample);\r\n            end if;\r\n        end if;\r\n    end process;\r\n\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/conversion_to_RGB.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: conversion_YCbCr_to_RGB - Behavioral\r\n--\r\n-- Description: Convert from RGB, studio level RGB or YCbCr to full range RGB\r\n-- \r\n--              Designed to take the same amount of time regardless of conversion \r\n--              being performed.  \r\n----------------------------------------------------------------------------------\r\n-- When using 12-bit studio range inputs and the HD colourspace\r\n--\r\n-- R = (Y-64)*1.164 + (Cb-2048) *0.090 + (Cr-2048)*1.793\r\n-- G = (Y-64)*1.164 - (Cb-2048) *0.213 - (Cr-2048)*0.533\r\n-- B = (Y-64)*1.164 + (Cb-2048) *2.112 + (Cr-2048)*0.000\r\n--\r\n-- To avoid the problems with signed/unsigned multiplication this\r\n-- has been rearranged to \r\n--\r\n-- R = Y*1.164 + Cb*0.090 + Cr*1.793 - 64*1.164 - 2048*0.090 - 2048*1.793\r\n-- G = Y*1.164 - Cb*0.213 - Cr*0.533 - 64*1.164 + 2048*0.213 + 2048*0.533\r\n-- B = Y*1.164 + Cb*2.112 + Cr*0.000 - 64*1.164 - 2048*2.112 - 2048*0.000\r\n--\r\n-- And then all the decimals have been scaled by 4096 This then only requires   \r\n-- five multipliers (as two are zero and three others are identical.\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity conversion_to_RGB is\r\n    port ( clk      : in std_Logic;\r\n           input_is_YCbCr : in std_Logic;\r\n           input_is_sRGB  : in std_Logic;\r\n\r\n           ------------------------\r\n           in_blank : in std_logic;\r\n           in_hsync : in std_logic;\r\n           in_vsync : in std_logic;\r\n           in_U     : in std_logic_vector(11 downto 0);  -- B or Cb\r\n           in_V     : in std_logic_vector(11 downto 0);  -- G or Y\r\n           in_W     : in std_logic_vector(11 downto 0);  -- R or Cr\r\n\r\n           ------------------------\r\n           out_blank : out std_logic;\r\n           out_hsync : out std_logic;\r\n           out_vsync : out std_logic;\r\n           out_R     : out std_logic_vector(11 downto 0);\r\n           out_G     : out std_logic_vector(11 downto 0);\r\n           out_B     : out std_logic_vector(11 downto 0));\r\nend entity;\r\n\r\narchitecture Behavioral of conversion_to_RGB is\r\n    ------------------------------\r\n    -- For the pipeline \r\n    ------------------------------\r\n    signal s1_blank : std_logic;\r\n    signal s1_hsync : std_logic;\r\n    signal s1_vsync : std_logic;\r\n    signal s1_U     : std_logic_vector(12 downto 0);  -- B or Cb, plus underflow guard bit\r\n    signal s1_V     : std_logic_vector(12 downto 0);  -- G or Y, plus underflow guard bit\r\n    signal s1_W     : std_logic_vector(12 downto 0);  -- R or Cr, plus underflow guard bit\r\n\r\n    signal s2_blank : std_logic;\r\n    signal s2_hsync : std_logic;\r\n    signal s2_vsync : std_logic;\r\n    signal s2_U     : std_logic_vector(12 downto 0);  -- B or Cb, plus overflow guard bit\r\n    signal s2_V     : std_logic_vector(12 downto 0);  -- G or Y, plus overflow guard bit\r\n    signal s2_W     : std_logic_vector(12 downto 0);  -- R or Cr, plus overflow guard bit\r\n\r\n    ------------------------------\r\n    -- For Calculation\r\n    ------------------------------\r\n    signal a     : unsigned(26 downto 0) := (others => '0');\r\n    signal b     : unsigned(26 downto 0) := (others => '0');\r\n    signal c     : unsigned(26 downto 0) := (others => '0');\r\n    signal d     : unsigned(26 downto 0) := (others => '0');\r\n    signal e     : unsigned(26 downto 0) := (others => '0');\r\n    signal R_raw : unsigned(26 downto 0) := (others => '0');\r\n    signal G_raw : unsigned(26 downto 0) := (others => '0');\r\n    signal B_raw : unsigned(26 downto 0) := (others => '0');\r\nbegin\r\nclk_proc: process(clk)\r\n   begin\r\n      if rising_edge(clk) then\r\n         -----------------------------------------------\r\n         -- Step 3: clamp the result\r\n         -----------------------------------------------\r\n         out_blank <= s2_blank;\r\n         out_hsync <= s2_hsync;\r\n         out_vsync <= s2_vsync;\r\n         if input_is_YCbCr = '0' then\r\n            -- trap overflows form prior stage\r\n            if s2_U(s2_U'high) = '0' then\r\n                out_B     <= s2_U(s2_U'high-1 downto 0);\r\n            else \r\n                out_B     <= (others => '1');\r\n            end if;\r\n            \r\n            if s2_V(s2_V'high) = '0' then\r\n                out_G     <= s2_V(s2_V'high-1 downto 0); \r\n            else \r\n                out_G     <= (others => '1');\r\n            end if;\r\n            \r\n            if s2_W(s2_W'high) = '0' then\r\n                out_R     <= s2_W(s2_W'high-1 downto 0); \r\n            else \r\n                out_R     <= (others => '1');\r\n            end if;\r\n         else   \r\n            case R_raw(R_raw'high-1 downto R_raw'high-2) is\r\n                when \"00\"   => out_R <= std_logic_vector(R_raw(R_raw'high-3 downto R_raw'high-14)); -- In range\r\n                when \"01\"   => out_R <= (others => '1');                          -- Overflow\r\n                when others => out_R <= (others => '0');                          -- Underflow\r\n             end case;\r\n                \r\n            case G_raw(G_raw'high-1 downto G_raw'high-2) is\r\n                when \"00\"   => out_G <= std_logic_vector(G_raw(G_raw'high-3 downto G_raw'high-14)); -- In range\r\n                when \"01\"   => out_G <= (others => '1');                          -- Overflow\r\n                when others => out_G <= (others => '0');                          -- Underflow\r\n             end case;\r\n                \r\n            case B_raw(B_raw'high-1 downto B_raw'high-2) is\r\n                when \"00\"   => out_B <= std_logic_vector(B_raw(B_raw'high-3 downto B_raw'high-14)); -- In range\r\n                when \"01\"   => out_B <= (others => '1');                          -- Overflow\r\n                when others => out_B <= (others => '0');                          -- Underflow\r\n             end case;\r\n         end if;\r\n         -------------------------------------------------\r\n         -- Step 2: Add the partial results and remove the\r\n         -- offset introduced by the use of studio range\r\n         -------------------------------------------------\r\n         s2_blank <= s1_blank;\r\n         s2_hsync <= s1_hsync;\r\n         s2_vsync <= s1_vsync;\r\n         if input_is_sRGB = '1' then\r\n            -- Trap underflows from prior stage\r\n            if s1_U(s1_U'high) = '0' then\r\n                s2_U     <= std_logic_vector(unsigned(s1_U) + unsigned(s1_U(s1_U'high downto 5)));\r\n            else\r\n                s2_U  <= (others => '0');\r\n            end if; \r\n\r\n            if s1_V(s1_V'high) = '0' then\r\n                s2_V     <= std_logic_vector(unsigned(s1_V) + unsigned(s1_V(s1_V'high downto 5)));   \r\n            else\r\n                s2_V  <= (others => '0');\r\n            end if;\r\n             \r\n            if s1_W(s1_W'high) = '0' then\r\n                s2_W     <= std_logic_vector(unsigned(s1_W) + unsigned(s1_W(s1_W'high downto 5)));\r\n            else\r\n                s2_W  <= (others => '0');\r\n            end if; \r\n         else\r\n            s2_U <= s1_U;\r\n            s2_V <= s1_V;\r\n            s2_W <= s1_W;\r\n         end if;  \r\n         R_raw <= a + d     - to_unsigned(4767*256 +    0*2048 + 7344*2048, 27);\r\n         G_raw <= a - b - e + to_unsigned(-4767*256 +  872*2048 + 2183*2048, 27);\r\n         B_raw <= a + c     - to_unsigned(4767*256 + 8650*2048 +    0*2048, 27);\r\n  \r\n         -------------------------------------------------\r\n         -- Step 1: Multiply the incoming values by the   \r\n         -- Conversion coefficients\r\n         -------------------------------------------------\r\n         s1_blank <= in_blank;\r\n         s1_hsync <= in_hsync;\r\n         s1_vsync <= in_vsync;\r\n         if input_is_sRGB = '1' then\r\n             s1_U     <= std_logic_vector(unsigned('0' & in_U) - 256); \r\n             s1_V     <= std_logic_vector(unsigned('0' & in_V) - 256);\r\n             s1_W     <= std_logic_vector(unsigned('0' & in_W) - 256);\r\n         else\r\n             s1_U     <= '0' & in_U; \r\n             s1_V     <= '0' & in_V; \r\n             s1_W     <= '0' & in_W;\r\n         end if; \r\n         a <= unsigned(in_V) * to_unsigned(4767,15); -- 1.164 * 2^12\r\n         b <= unsigned(in_U) * to_unsigned( 872,15); -- 0.213 * 2^12\r\n         c <= unsigned(in_U) * to_unsigned(8650,15); -- 2.112 * 2^12\r\n         d <= unsigned(in_W) * to_unsigned(7344,15); -- 1.793 * 2^12\r\n         e <= unsigned(in_W) * to_unsigned(2183,15); -- 0.533 * 2^12\r\n      end if;\r\n   end process;\r\nend architecture;\r\n"
  },
  {
    "path": "src/deserialiser_1_to_10.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: deserialiser_1_to_10 - Behavioral\r\n--\r\n-- Description: A 10-to-1 deserialiser for the Artix 7   \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\nlibrary IEEE;\r\nuse IEEE.std_logic_1164.ALL;\r\n\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity deserialiser_1_to_10 is\r\n    Port ( clk_mgmt    : in  std_logic;\r\n           delay_ce    : in  std_logic;\r\n           delay_count : in  std_logic_vector (4 downto 0);\r\n           \r\n           ce          : in  STD_LOGIC;\r\n           clk         : in  std_logic;\r\n           clk_x1      : in  std_logic;\r\n           bitslip     : in  std_logic;\r\n           clk_x5      : in  std_logic;\r\n           serial      : in  std_logic;\r\n           reset       : in  std_logic;\r\n           data        : out std_logic_vector (9 downto 0));\r\nend deserialiser_1_to_10;\r\n\r\narchitecture Behavioral of deserialiser_1_to_10 is\r\n    signal delayed : std_logic := '0';\r\n    signal shift1  : std_logic := '0';\r\n    signal shift2  : std_logic := '0';\r\n    signal clkb    : std_logic := '1';\r\n    attribute IODELAY_GROUP : STRING;\r\n    attribute IODELAY_GROUP of IDELAYE2_inst: label is \"idelay_group\";\r\n\r\nbegin\r\n\r\nIDELAYE2_inst : IDELAYE2\r\n    generic map (\r\n          CINVCTRL_SEL          => \"FALSE\",\r\n          DELAY_SRC             => \"DATAIN\",\r\n          HIGH_PERFORMANCE_MODE => \"TRUE\",\r\n          IDELAY_TYPE           => \"VAR_LOAD\",\r\n          IDELAY_VALUE          => 0,\r\n          PIPE_SEL              => \"FALSE\",\r\n          REFCLK_FREQUENCY      => 200.0,\r\n          SIGNAL_PATTERN        => \"DATA\"\r\n    )\r\n    port map (\r\n          DATAIN      => serial,\r\n          IDATAIN     => '0',\r\n          DATAOUT     => delayed,\r\n          --\r\n          CNTVALUEOUT => open,\r\n          C           => clk,\r\n          CE          => delay_ce,\r\n          CINVCTRL    => '0',\r\n          CNTVALUEIN  => delay_count,\r\n          INC         => '0',\r\n          LD          => '1',\r\n          LDPIPEEN    => '0',\r\n          REGRST      => '0'\r\n    );\r\n    clkb <= not clk_x5;\r\n\r\nISERDESE2_master : ISERDESE2\r\n   generic map (\r\n      DATA_RATE         => \"DDR\",\r\n      DATA_WIDTH        => 10,\r\n      DYN_CLKDIV_INV_EN => \"FALSE\",\r\n      DYN_CLK_INV_EN    => \"FALSE\",\r\n      INIT_Q1 => '0', INIT_Q2 => '0', INIT_Q3 => '0', INIT_Q4 => '0',\r\n      INTERFACE_TYPE    => \"NETWORKING\",\r\n      IOBDELAY          => \"IFD\",\r\n      NUM_CE            => 1,\r\n      OFB_USED          => \"FALSE\",\r\n      SERDES_MODE       => \"MASTER\",\r\n      SRVAL_Q1 => '0', SRVAL_Q2 => '0', SRVAL_Q3 => '0', SRVAL_Q4 => '0' \r\n   )\r\n   port map (\r\n      O => open,\r\n      Q1 => data(9), Q2 => data(8), Q3 => data(7), Q4 => data(6),\r\n      Q5 => data(5), Q6 => data(4), Q7 => data(3), Q8 => data(2),\r\n      SHIFTOUT1 => shift1, SHIFTOUT2 => shift2,\r\n      BITSLIP   => bitslip,\r\n      CE1 => ce, CE2 => '1',\r\n      CLKDIVP      => '0',\r\n      CLK          => clk_x5,\r\n      CLKB         => clkb,\r\n      CLKDIV       => clk_x1,\r\n      OCLK         => '0', \r\n      DYNCLKDIVSEL => '0',\r\n      DYNCLKSEL    => '0',\r\n      D            => '0',\r\n      DDLY         => delayed,\r\n      OFB          => '0',\r\n      OCLKB        => '0',\r\n      RST          => reset,\r\n      SHIFTIN1     => '0',\r\n      SHIFTIN2     => '0' \r\n   );\r\n               \r\nISERDESE2_slave : ISERDESE2\r\n   generic map (\r\n      DATA_RATE         => \"DDR\",\r\n      DATA_WIDTH        => 10,\r\n      DYN_CLKDIV_INV_EN => \"FALSE\",\r\n      DYN_CLK_INV_EN    => \"FALSE\",\r\n      INIT_Q1 => '0', INIT_Q2 => '0', INIT_Q3 => '0', INIT_Q4 => '0',\r\n      INTERFACE_TYPE    => \"NETWORKING\",\r\n      IOBDELAY          => \"IFD\",\r\n      NUM_CE            => 1,\r\n      OFB_USED          => \"FALSE\",\r\n      SERDES_MODE       => \"SLAVE\",  \r\n      SRVAL_Q1 => '0', SRVAL_Q2 => '0', SRVAL_Q3 => '0', SRVAL_Q4 => '0' \r\n   )\r\n   port map (\r\n      O => open,\r\n      Q1 => open, Q2 => open, Q3 => data(1), Q4 => data(0),\r\n      Q5 => open, Q6 => open, Q7 => open,    Q8 => open,\r\n      SHIFTOUT1 => open, SHIFTOUT2 => open,\r\n      BITSLIP   => bitslip,\r\n      CE1 => ce, CE2 => '1',\r\n      CLKDIVP      => '0',\r\n      CLK          => CLK_x5,\r\n      CLKB         => clkb,\r\n      CLKDIV       => clk_x1,\r\n      OCLK         => '0', \r\n      DYNCLKDIVSEL => '0',\r\n      DYNCLKSEL    => '0',\r\n      D            => '0',\r\n      DDLY         => '0',\r\n      OFB          => '0',\r\n      OCLKB        => '0',\r\n      RST          => reset,\r\n      SHIFTIN1     => shift1,\r\n      SHIFTIN2     => shift2 \r\n   );\r\nend Behavioral;"
  },
  {
    "path": "src/detect_interlace.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: detect_interlace - Behavioral\r\n--\r\n-- Description: Detect if the source is interlaced, and report what field is \r\n--              being processed\r\n-- \r\n-- Will need to make allowances for interlaced sources!\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity detect_interlace is\r\n    Port ( clk             : in STD_LOGIC;\r\n           hsync           : in std_logic;\r\n           vsync           : in std_logic;\r\n    \t   is_interlaced   : out std_logic;\r\n\t   \t   is_second_field : out std_logic);\r\nend entity;\r\n\r\narchitecture Behavioral of detect_interlace is\r\n\tsignal last_vsync     : std_logic := '0';\r\n\tsignal last_hsync     : std_logic := '0';\r\n\tsignal first_quarter  : unsigned(11 downto 0) := (others => '0');\r\n\tsignal last_quarter   : unsigned(11 downto 0) := (others => '0');\r\n\tsignal hcount         : unsigned(11 downto 0) := (others => '0');\r\n\tsignal last_vsync_pos : unsigned(11 downto 0) := (others => '0');\r\n\tsignal second_field   : std_logic := '0';\r\nbegin\r\nclk_proc: process(clk)\r\n\tbegin\r\n\t\tif rising_edge(clk) then\r\n\t\t\tif last_vsync = '0' and vsync = '1' then\r\n\t\t\t\tis_second_field <= '0';\r\n\t\t\t\tif hcount > first_quarter and hcount < last_quarter then\r\n\t\t\t\t\t-- The second field of an interlaced \r\n                           -- frame is indicated when the vsync is\r\n\t                      -- asserted in the middle of the scan line.\r\n\t\t\t\t\t--\r\n\t\t\t\t\t-- Also add a little check for a misbehaving source\r\n\t\t\t\t\tif last_vsync_pos /= hcount then\r\n\t\t\t\t\t\tis_interlaced   <= '1';\r\n\t\t\t\t\t\tis_second_field <= '1';\r\n\t\t\t\t\t\tsecond_field    <= '1';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tis_interlaced   <= '1';\r\n\t\t\t\t\t\tis_second_field <= '1';\r\n\t\t\t\t\t\tsecond_field    <= '1';\r\n\t\t\t\t\tend if;\r\n\r\n\t\t\t\telse\r\n\t\t\t\t\t-- If we see two 'field 1's in a row we \r\n\t\t\t\t\t-- switch back to indicating an \r\n                    -- uninterlaced source\r\n\t\t\t\t\tif second_field = '0' then\r\n\t\t\t\t\t\tis_interlaced <= '0';\r\n\t\t\t\t\tend if;\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\tis_second_field <= '0';\r\n\t\t\t\t\tsecond_field    <= '0';\r\n\t\t\t\tend if;\r\n\t\t\t\tlast_vsync_pos <= hcount;\r\n\t\t\telse\r\n\t\t\tend if;\r\n\r\n\t\t\tif last_hsync = '0' and hsync = '1' then\r\n\t\t\t\thcount <= (others => '0');\r\n\t\t\t\tfirst_quarter <= \"00\" & hcount(11 downto 2);\r\n\t\t\t\tlast_quarter <= hcount+1-hcount(11 downto 2);\r\n\t\t\telse\r\n\t\t\t\thcount <= hcount +1;\r\n\t\t\tend if;\r\n\t\t\tlast_vsync <= vsync;\r\n\t\t\tlast_hsync <= hsync;\r\n\t\tend if;\r\n\tend process;\r\nend architecture;\r\n\t\t"
  },
  {
    "path": "src/dvid_output.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Module Name: DVID_output - Behavioral\r\n--\r\n-- Description: Convert a stream of pixels into a DVID output \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.std_logic_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity DVID_output is\r\n    Port ( \r\n        pixel_clk       : in std_logic;  -- Driven by BUFG\r\n        pixel_io_clk_x1 : in std_logic;  -- Driven by BUFIO\r\n        pixel_io_clk_x5 : in std_logic;  -- Driven by BUFIO\r\n        \r\n        -- VGA Signals\r\n        vga_blank    : in  std_logic;\r\n        vga_hsync    : in  std_logic;\r\n        vga_vsync    : in  std_logic;\r\n        vga_red      : in  std_logic_vector(7 downto 0);\r\n        vga_blue     : in  std_logic_vector(7 downto 0);\r\n        vga_green    : in  std_logic_vector(7 downto 0);\r\n        data_valid   : in  std_logic;\r\n        \r\n        --- DVI-D out\r\n        tmds_out_clk    : out   std_logic;\r\n        tmds_out_ch0    : out   std_logic;\r\n        tmds_out_ch1    : out   std_logic;\r\n        tmds_out_ch2    : out   std_logic\r\n    );\r\nend DVID_output;\r\n\r\narchitecture Behavioral of DVID_output is\r\n\r\n   component tmds_encoder is\r\n   Port ( clk     : in  std_logic;\r\n          data    : in  std_logic_vector (7 downto 0);\r\n          c       : in  std_logic_vector (1 downto 0);\r\n          blank   : in  std_logic;\r\n          encoded : out std_logic_vector (9 downto 0));\r\n    end component;\r\n\r\n    component serialiser_10_to_1 is\r\n    Port ( clk    : in  std_logic;\r\n           clk_x5 : in  std_logic;\r\n           reset  : in  std_logic;\r\n           data   : in  std_logic_vector (9 downto 0);\r\n           serial : out std_logic);\r\n    end component;\r\n\r\n    signal c0_tmds_symbol : std_logic_vector (9 downto 0);\r\n    signal c1_tmds_symbol : std_logic_vector (9 downto 0);\r\n    signal c2_tmds_symbol : std_logic_vector (9 downto 0);\r\n\r\n    signal reset_sr       : std_logic_vector (2 downto 0) := (others => '1');\r\n    signal reset          : std_logic := '1';\r\n    \r\nbegin\r\n    reset <= reset_sr(0);\r\n    \r\nprocess(pixel_clk, data_valid)\r\n    begin\r\n        if data_valid = '0' then\r\n           reset_sr <= (others => '1');\r\n        elsif rising_edge(pixel_clk) then\r\n            reset_sr <= '0' & reset_sr(reset_sr'high downto 1); \r\n        end if;\r\n    end process;\r\n    ---------------------\r\n    -- TMDS Encoders\r\n    ---------------------\r\nc0_tmds: tmds_encoder port map (\r\n        clk     => pixel_clk,\r\n        data    => vga_blue,\r\n        c(1)    => vga_vsync,\r\n        c(0)    => vga_hsync,\r\n        blank   => vga_blank,\r\n        encoded => c0_tmds_symbol);\r\n\r\nc1_tmds: tmds_encoder port map (\r\n        clk     => pixel_clk,\r\n        data    => vga_green,\r\n        c       => (others => '0'),\r\n        blank   => vga_blank,\r\n        encoded => c1_tmds_symbol);\r\n        \r\nc2_tmds: tmds_encoder port map (\r\n        clk     => pixel_clk,\r\n        data    => vga_red,\r\n        c       => (others => '0'),\r\n        blank   => vga_blank,\r\n        encoded => c2_tmds_symbol);\r\n    ---------------------\r\n    -- Output serializers\r\n    ---------------------\r\nser_ch0: serialiser_10_to_1 port map ( \r\n        clk    => pixel_io_clk_x1,\r\n        clk_x5 => pixel_io_clk_x5,\r\n        reset  => reset,\r\n        data   => c0_tmds_symbol,\r\n        serial => tmds_out_ch0);\r\n        \r\nser_ch1: serialiser_10_to_1 port map ( \r\n        clk    => pixel_io_clk_x1,\r\n        clk_x5 => pixel_io_clk_x5,\r\n        reset  => reset,\r\n        data   => c1_tmds_symbol,\r\n        serial => tmds_out_ch1);\r\n\r\nser_ch2: serialiser_10_to_1 port map (\r\n        clk    => pixel_io_clk_x1,\r\n        clk_x5 => pixel_io_clk_x5,\r\n        reset  => reset,\r\n        data   => c2_tmds_symbol,\r\n        serial => tmds_out_ch2);\r\n\r\nser_clk: serialiser_10_to_1 Port map (\r\n        clk    => pixel_io_clk_x1,\r\n        clk_x5 => pixel_io_clk_x5,\r\n        reset  => reset,\r\n        data   => \"0000011111\",\r\n        serial => tmds_out_clk);\r\n\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/edge_enhance.vhd",
    "content": "----------------------------------------------------------------------------------\n-- Engineer: Mike Field <hasmter@snap.net.nz> \n-- \n-- Module Name: edge_enhance - Behavioral\n--\n-- Description: Video edge enhancement \n--\n------------------------------------------------------------------------------------\n-- The MIT License (MIT)\n-- \n-- Copyright (c) 2015 Michael Alan Field\n-- \n-- Permission is hereby granted, free of charge, to any person obtaining a copy\n-- of this software and associated documentation files (the \"Software\"), to deal\n-- in the Software without restriction, including without limitation the rights\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n-- copies of the Software, and to permit persons to whom the Software is\n-- furnished to do so, subject to the following conditions:\n-- \n-- The above copyright notice and this permission notice shall be included in\n-- all copies or substantial portions of the Software.\n-- \n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n-- THE SOFTWARE.\n------------------------------------------------------------------------------------\n----- Want to say thanks? ----------------------------------------------------------\n------------------------------------------------------------------------------------\n--\n-- This design has taken many hours - with the industry metric of 30 lines\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\n-- to share it if you can make use of it. It is released under the MIT license,\n-- so you are not under any onus to say thanks, but....\n-- \n-- If you what to say thanks for this design how about trying PayPal?\n--  Educational use - Enough for a beer\n--  Hobbyist use    - Enough for a pizza\n--  Research use    - Enough to take the family out to dinner\n--  Commercial use  - A weeks pay for an engineer (I wish!)\n--\n----------------------------------------------------------------------------------\n\nlibrary IEEE;\nuse IEEE.STD_LOGIC_1164.ALL;\nuse IEEE.NUMERIC_STD.ALL;\n\nentity edge_enhance is\n    Port (  clk            : in STD_LOGIC;\n            enable_feature : in std_logic;\n            -------------------------------\n            -- VGA data recovered from HDMI\n            -------------------------------\n            in_blank  : in std_logic;\n            in_hsync  : in std_logic;\n            in_vsync  : in std_logic;\n            in_red    : in std_logic_vector(7 downto 0);\n            in_green  : in std_logic_vector(7 downto 0);\n            in_blue   : in std_logic_vector(7 downto 0);\n            \n            -----------------------------------\n            -- VGA data to be converted to HDMI\n            -----------------------------------\n            out_blank : out std_logic;\n            out_hsync : out std_logic;\n            out_vsync : out std_logic;\n            out_red   : out std_logic_vector(7 downto 0);\n            out_green : out std_logic_vector(7 downto 0);\n            out_blue  : out std_logic_vector(7 downto 0));\nend edge_enhance;\n\narchitecture Behavioral of edge_enhance is\n    component line_delay is\n    Port ( clk : in STD_LOGIC;\n           -------------------------------\n           -- VGA data recovered from HDMI\n           -------------------------------\n           in_blank  : in std_logic;\n           in_hsync  : in std_logic;\n           in_vsync  : in std_logic;\n           in_red    : in std_logic_vector(7 downto 0);\n           in_green  : in std_logic_vector(7 downto 0);\n           in_blue   : in std_logic_vector(7 downto 0);\n     \n           -----------------------------------\n           -- VGA data to be converted to HDMI\n           -----------------------------------\n           out_blank : out std_logic;\n           out_hsync : out std_logic;\n           out_vsync : out std_logic;\n           out_red   : out std_logic_vector(7 downto 0);\n           out_green : out std_logic_vector(7 downto 0);\n           out_blue  : out std_logic_vector(7 downto 0));\n    end component;\n    type a_bits is array(0 to 8) of std_logic;\n    type a_component is array(0 to 8) of std_logic_vector(7 downto 0);\n    signal blanks : a_bits;\n    signal hsyncs : a_bits;\n    signal vsyncs : a_bits;\n    signal reds   : a_component;\n    signal greens : a_component;\n    signal blues  : a_component;\n\n    signal bypass_1_blank : std_logic := '0';\n    signal bypass_1_hsync : std_logic := '0';\n    signal bypass_1_vsync : std_logic := '0';\n    signal bypass_1_red   : std_logic_vector(7 downto 0) := (others => '0');\n    signal bypass_1_blue  : std_logic_vector(7 downto 0) := (others => '0');\n    signal bypass_1_green : std_logic_vector(7 downto 0) := (others => '0');\n\n    signal bypass_2_blank : std_logic := '0';\n    signal bypass_2_hsync : std_logic := '0';\n    signal bypass_2_vsync : std_logic := '0';\n    signal bypass_2_red   : std_logic_vector(7 downto 0) := (others => '0');\n    signal bypass_2_blue  : std_logic_vector(7 downto 0) := (others => '0');\n    signal bypass_2_green : std_logic_vector(7 downto 0) := (others => '0');\n    \n    signal bypass_3_blank : std_logic := '0';\n    signal bypass_3_hsync : std_logic := '0';\n    signal bypass_3_vsync : std_logic := '0';\n    signal bypass_3_red   : std_logic_vector(7 downto 0) := (others => '0');\n    signal bypass_3_blue  : std_logic_vector(7 downto 0) := (others => '0');\n    signal bypass_3_green : std_logic_vector(7 downto 0) := (others => '0');\n\n    signal sobel_3_hsync  : std_logic := '0';\n    signal sobel_3_blank  : std_logic := '0';\n    signal sobel_3_vsync  : std_logic := '0';\n    signal sobel_3_red    : unsigned(12 downto 0) := (others => '0');\n    signal sobel_3_green  : unsigned(12 downto 0) := (others => '0');\n    signal sobel_3_blue   : unsigned(12 downto 0) := (others => '0');\n    \n    signal sobel_2_hsync   : std_logic := '0';\n    signal sobel_2_blank   : std_logic := '0';\n    signal sobel_2_vsync   : std_logic := '0';\n    signal sobel_2_red_x   : unsigned(11 downto 0) := (others => '0');\n    signal sobel_2_red_y   : unsigned(11 downto 0) := (others => '0');\n    signal sobel_2_green_x : unsigned(11 downto 0) := (others => '0');\n    signal sobel_2_green_y : unsigned(11 downto 0) := (others => '0');\n    signal sobel_2_blue_x  : unsigned(11 downto 0) := (others => '0');\n    signal sobel_2_blue_y  : unsigned(11 downto 0) := (others => '0');\n\n    signal sobel_1_hsync        : std_logic := '0';\n    signal sobel_1_blank        : std_logic := '0';\n    signal sobel_1_vsync        : std_logic := '0';\n    signal sobel_1_red_left     : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_red_right    : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_red_top      : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_red_bottom   : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_green_left   : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_green_right  : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_green_top    : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_green_bottom : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_blue_left    : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_blue_right   : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_blue_top     : unsigned(11 downto 0) := (others => '0');\n    signal sobel_1_blue_bottom  : unsigned(11 downto 0) := (others => '0');\nbegin\n    blanks(0)  <= in_blank;\n    hsyncs(0)  <= in_hsync;\n    vsyncs(0)  <= in_vsync;\n    reds(0)    <= in_red;\n    greens(0)  <= in_green;\n    blues(0)   <= in_blue;\n\ni_line_delay_1: line_delay  Port map ( \n        clk       => clk,\n        in_blank  => blanks(0),\n        in_hsync  => hsyncs(0),\n        in_vsync  => vsyncs(0),\n        in_red    => reds(0),\n        in_green  => greens(0),\n        in_blue   => blues(0),\n\n        out_blank => blanks(3), \n        out_hsync => hsyncs(3),\n        out_vsync => vsyncs(3), \n        out_red   => reds(3),\n        out_green => greens(3), \n        out_blue  => blues(3)  \n    );\n\ni_line_delay_2: line_delay  Port map ( \n        clk       => clk,\n        in_blank  => blanks(3),\n        in_hsync  => hsyncs(3),\n        in_vsync  => vsyncs(3),\n        in_red    => reds(3),\n        in_green  => greens(3),\n        in_blue   => blues(3),\n\n        out_blank => blanks(6), \n        out_hsync => hsyncs(6),\n        out_vsync => vsyncs(6), \n        out_red   => reds(6),\n        out_green => greens(6), \n        out_blue  => blues(6)  \n    );\n\nprocess(clk)\n    begin\n        if rising_edge(clk) then\n            if enable_feature = '1' then\n                out_hsync <= sobel_3_hsync;\n                out_blank <= sobel_3_blank;\n                out_vsync <= sobel_3_vsync;\n\n                if sobel_3_red(12 downto 12) = \"0\" then\n                    out_red   <= std_logic_vector(sobel_3_red(11 downto 4));\n                else\n                    out_red   <= (others => '1');\n                end if;\n\n                if sobel_3_green(12 downto 12) = \"0\" then\n                    out_green   <= std_logic_vector(sobel_3_green(11 downto 4));\n                else\n                    out_green   <= (others => '1');\n                end if;\n\n                if sobel_3_blue(12 downto 12) = \"0\" then\n                    out_blue   <= std_logic_vector(sobel_3_blue(11 downto 4));\n                else\n                    out_blue   <= (others => '1');\n                end if;\n            else\n                out_hsync <= bypass_3_hsync;\n                out_blank <= bypass_3_blank;\n                out_vsync <= bypass_3_vsync;\n                out_red   <= bypass_3_red;\n                out_blue  <= bypass_3_blue;\n                out_green <= bypass_3_green;\n            end if;\n\n            --------------------------------------\n            -- For if we eed to bypass the feature\n            --------------------------------------\n            bypass_3_blank <= bypass_2_blank;\n            bypass_3_hsync <= bypass_2_hsync;\n            bypass_3_vsync <= bypass_2_vsync;\n            bypass_3_red   <= bypass_2_red;\n            bypass_3_blue  <= bypass_2_blue;\n            bypass_3_green <= bypass_2_green;\n\n            bypass_2_blank <= bypass_1_blank;\n            bypass_2_hsync <= bypass_1_hsync;\n            bypass_2_vsync <= bypass_1_vsync;\n            bypass_2_red   <= bypass_1_red;\n            bypass_2_blue  <= bypass_1_blue;\n            bypass_2_green <= bypass_1_green;\n\n            bypass_1_blank <= blanks(4);\n            bypass_1_hsync <= hsyncs(4);\n            bypass_1_vsync <= vsyncs(4);\n            bypass_1_red   <= reds(4);\n            bypass_1_blue  <= blues(4);\n            bypass_1_green <= greens(4);\n\n            ----------------------------------\n            --- Calculating the Sobel operator\n            ----------------------------------\n            sobel_3_blank <= sobel_2_blank;\n            sobel_3_hsync <= sobel_2_hsync;\n            sobel_3_vsync <= sobel_2_vsync;\n            sobel_3_red   <= (\"0\" & sobel_2_red_x)   +  sobel_2_red_y;\n            sobel_3_green <= (\"0\" & sobel_2_green_x) +  sobel_2_green_y;\n            sobel_3_blue  <= (\"0\" & sobel_2_blue_x)  +  sobel_2_blue_y;\n             \n            -- For the red channel\n            sobel_2_blank <= sobel_1_blank;\n            sobel_2_hsync <= sobel_1_hsync;\n            sobel_2_vsync <= sobel_1_vsync;\n\n            if sobel_1_red_left > sobel_1_red_right then\n                sobel_2_red_x <= sobel_1_red_left - sobel_1_red_right;\n            else\n                sobel_2_red_x <= sobel_1_red_right - sobel_1_red_left;\n            end if;            \n            if sobel_1_red_top > sobel_1_red_bottom then\n                sobel_2_red_y <= sobel_1_red_top - sobel_1_red_bottom;\n            else\n                sobel_2_red_y <= sobel_1_red_bottom - sobel_1_red_top;\n            end if;\n            \n            -- For the green channel\n            if sobel_1_green_left > sobel_1_green_right then\n                sobel_2_green_x <= sobel_1_green_left - sobel_1_green_right;\n            else\n                sobel_2_green_x <= sobel_1_green_right - sobel_1_green_left;\n            end if;\n            if sobel_1_green_top > sobel_1_green_bottom then\n                sobel_2_green_y <= sobel_1_green_top - sobel_1_green_bottom;\n            else\n                sobel_2_green_y <= sobel_1_green_bottom - sobel_1_green_top;\n            end if;\n            \n            -- For the blue channel\n            if sobel_1_blue_left > sobel_1_blue_right then\n                sobel_2_blue_x <= sobel_1_blue_left - sobel_1_blue_right;\n            else\n                sobel_2_blue_x <= sobel_1_blue_right - sobel_1_blue_left;\n            end if;            \n            if sobel_1_blue_top > sobel_1_blue_bottom then\n                sobel_2_blue_y <= sobel_1_blue_top - sobel_1_blue_bottom;\n            else\n                sobel_2_blue_y <= sobel_1_blue_bottom - sobel_1_blue_top;\n            end if;\n\n            -- Now for the first stage;            \n            sobel_1_blank <= blanks(4);\n            sobel_1_hsync <= hsyncs(4);\n            sobel_1_vsync <= vsyncs(4);\n            -- For the red channel\n            sobel_1_red_left   <= (\"000\" & unsigned(reds(0)) & \"0\") + (\"0000\" & unsigned(reds(0))) \n                                + (\"000\" & unsigned(reds(3)) & \"0\") + (\"0\"    & unsigned(reds(3)) & \"000\")\n                                + (\"000\" & unsigned(reds(6)) & \"0\") + (\"0000\" & unsigned(reds(6)));\n\n            sobel_1_red_right  <= (\"000\" & unsigned(reds(2)) & \"0\") + (\"0000\" & unsigned(reds(2))) \n                                + (\"000\" & unsigned(reds(5)) & \"0\") + (\"0\"    & unsigned(reds(5)) & \"000\") \n                                + (\"000\" & unsigned(reds(8)) & \"0\") + (\"0000\" & unsigned(reds(8)));\n\n            sobel_1_red_top    <= (\"000\" & unsigned(reds(2)) & \"0\") + (\"0000\" & unsigned(reds(2)))       \n                                + (\"000\" & unsigned(reds(1)) & \"0\") + (\"0\"    & unsigned(reds(1)) & \"000\") \n                                + (\"000\" & unsigned(reds(0)) & \"0\") + (\"0000\" & unsigned(reds(0)));\n\n            sobel_1_red_bottom <= (\"000\" & unsigned(reds(6)) & \"0\") + (\"0000\" & unsigned(reds(6)))\n                                + (\"000\" & unsigned(reds(7)) & \"0\") + (\"0\"    & unsigned(reds(7)) & \"000\") \n                                + (\"000\" & unsigned(reds(8)) & \"0\") + (\"0000\" & unsigned(reds(8)));\n\n            -- For the green channel\n            sobel_1_green_left   <= (\"000\" & unsigned(greens(0)) & \"0\") + (\"0000\" & unsigned(greens(0))) \n                                  + (\"000\" & unsigned(greens(3)) & \"0\") + (\"0\"    & unsigned(greens(3)) & \"000\")\n                                  + (\"000\" & unsigned(greens(6)) & \"0\") + (\"0000\" & unsigned(greens(6)));\n\n            sobel_1_green_right  <= (\"000\" & unsigned(greens(2)) & \"0\") + (\"0000\" & unsigned(greens(2))) \n                                  + (\"000\" & unsigned(greens(5)) & \"0\") + (\"0\"    & unsigned(greens(5)) & \"000\") \n                                  + (\"000\" & unsigned(greens(8)) & \"0\") + (\"0000\" & unsigned(greens(8)));\n\n            sobel_1_green_top    <= (\"000\" & unsigned(greens(2)) & \"0\") + (\"0000\" & unsigned(greens(2)))       \n                                  + (\"000\" & unsigned(greens(1)) & \"0\") + (\"0\"    & unsigned(greens(1)) & \"000\") \n                                  + (\"000\" & unsigned(greens(0)) & \"0\") + (\"0000\" & unsigned(greens(0)));\n\n            sobel_1_green_bottom <= (\"000\" & unsigned(greens(6)) & \"0\") + (\"0000\" & unsigned(greens(6)))\n                                  + (\"000\" & unsigned(greens(7)) & \"0\") + (\"0\"    & unsigned(greens(7)) & \"000\") \n                                  + (\"000\" & unsigned(greens(8)) & \"0\") + (\"0000\" & unsigned(greens(8)));\n                    \n            -- For the blue channel\n            sobel_1_blue_left   <= (\"000\" & unsigned(blues(0)) & \"0\") + (\"0000\" & unsigned(blues(0))) \n                                 + (\"000\" & unsigned(blues(3)) & \"0\") + (\"0\"    & unsigned(blues(3)) & \"000\")\n                                 + (\"000\" & unsigned(blues(6)) & \"0\") + (\"0000\" & unsigned(blues(6)));\n\n            sobel_1_blue_right  <= (\"000\" & unsigned(blues(2)) & \"0\") + (\"0000\" & unsigned(blues(2))) \n                                 + (\"000\" & unsigned(blues(5)) & \"0\") + (\"0\"    & unsigned(blues(5)) & \"000\") \n                                 + (\"000\" & unsigned(blues(8)) & \"0\") + (\"0000\" & unsigned(blues(8)));\n\n            sobel_1_blue_top    <= (\"000\" & unsigned(blues(2)) & \"0\") + (\"0000\" & unsigned(blues(2)))       \n                                 + (\"000\" & unsigned(blues(1)) & \"0\") + (\"0\"    & unsigned(blues(1)) & \"000\") \n                                 + (\"000\" & unsigned(blues(0)) & \"0\") + (\"0000\" & unsigned(blues(0)));\n\n            sobel_1_blue_bottom <= (\"000\" & unsigned(blues(6)) & \"0\") + (\"0000\" & unsigned(blues(6)))\n                                 + (\"000\" & unsigned(blues(7)) & \"0\") + (\"0\"    & unsigned(blues(7)) & \"000\") \n                                 + (\"000\" & unsigned(blues(8)) & \"0\") + (\"0000\" & unsigned(blues(8)));\n                    \n            --------------------------------------------------------------------\n            -- Copy over the short chains that gives us a 3x3 matrix to work with\n            ---------------------------------------------------------------------\n            -- The bottom row\n            blanks(1) <= blanks(0);\n            hsyncs(1) <= hsyncs(0);\n            vsyncs(1) <= vsyncs(0);\n            reds(1)   <= reds(0);\n            greens(1) <= greens(0);\n            blues(1)  <= blues(0);\n        \n            blanks(2) <= blanks(1);\n            hsyncs(2) <= hsyncs(1);\n            vsyncs(2) <= vsyncs(1);\n            reds(2)   <= reds(1);\n            greens(2) <= greens(1);\n            blues(2)  <= blues(1);\n            -- The middle row\n            blanks(4) <= blanks(3);\n            hsyncs(4) <= hsyncs(3);\n            vsyncs(4) <= vsyncs(3);\n            reds(4)   <= reds(3);\n            greens(4) <= greens(3);\n            blues(4)  <= blues(3);\n        \n            blanks(5) <= blanks(4);\n            hsyncs(5) <= hsyncs(4);\n            vsyncs(5) <= vsyncs(4);\n            reds(5)   <= reds(4);\n            greens(5) <= greens(4);\n            blues(5)  <= blues(4);\n        \n            -- The top row\n            blanks(7) <= blanks(6);\n            hsyncs(7) <= hsyncs(6);\n            vsyncs(7) <= vsyncs(6);\n            reds(7)   <= reds(6);\n            greens(7) <= greens(6);\n            blues(7)  <= blues(6);\n        \n            blanks(8) <= blanks(7);\n            hsyncs(8) <= hsyncs(7);\n            vsyncs(8) <= vsyncs(7);\n            reds(8)   <= reds(7);\n            greens(8) <= greens(7);\n            blues(8)  <= blues(7);\n        end if;\n    end process;\n\nend Behavioral;\n"
  },
  {
    "path": "src/edid_rom.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n--\r\n-- Module Name: edid_rom - Behavioral\r\n--\r\n-- Description: A simple EDID ROM, configured for 1920x1080@60Hz, HDMI format.\r\n--\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\nlibrary ieee;\r\nuse ieee.std_logic_1164.all;\r\nuse ieee.numeric_std.all;\r\n\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity edid_rom is\r\n   port ( clk      : in    std_logic;\r\n          sclk_raw : in    std_logic;\r\n          sdat_raw : inout std_logic := 'Z';\r\n          edid_debug : out std_logic_vector(2 downto 0) := (others => '0')\r\n  );\r\nend entity;\r\n\r\narchitecture Behavioral of edid_rom is\r\n\r\n   type a_edid_rom is array (0 to 255) of std_logic_vector(7 downto 0);\r\n\r\n   signal edid_rom : a_edid_rom := (\r\n      ------- BASE EDID Bytes 0 to 35 -----------------------------\r\n      -- Header\r\n      x\"00\",x\"FF\",x\"FF\",x\"FF\",x\"FF\",x\"FF\",x\"FF\",x\"00\",\r\n      -- EISA ID - Manufacturer, Product,\r\n      x\"04\",x\"43\", x\"07\",x\"f2\", \r\n      -- EISA ID -Serial\r\n      x\"01\",x\"00\",x\"00\",x\"00\",\r\n      -- Model/year\r\n      x\"FF\", x\"11\",\r\n      -- EDID Version\r\n      x\"01\", x\"04\",\r\n      ------------------------------------\r\n      ------------------------------------\r\n      -- Digital Video using DVI, 8 bits\r\n      --- x\"81\",   -- Checksum 0xB6 \r\n      ------------------------------------\r\n      -- Digital Video using HDMI, 8 bits\r\n      x\"A2\", -- Checksum 0x95 \r\n      ------------------------------------\r\n      -- Aspect ratio, flag, gamma\r\n      x\"4f\", x\"00\", x\"78\", \r\n      ------------------------------------      \r\n      -- Features \r\n      x\"3E\",\r\n      -- Display x,y Chromaticity V Breaks here!\r\n      x\"EE\", x\"91\", x\"a3\", x\"54\", x\"4c\", x\"99\", x\"26\", x\"0f\", x\"50\", x\"54\",\r\n      -- Established timings\r\n      x\"20\", x\"00\", x\"00\",\r\n      -- Standard timings\r\n      x\"01\", x\"01\", x\"01\", x\"01\", x\"01\", x\"01\", x\"01\", x\"01\", \r\n      x\"01\", x\"01\", x\"01\", x\"01\", x\"01\", x\"01\", x\"01\", x\"01\", \r\n      ------- End of BASE EDID ---------------------------------\r\n\r\n      ----- 18 byte data block 1080p --------\r\n      -- Pixel clock\r\n      x\"02\",x\"3A\",\r\n      -- Horizontal 1920 with 280 blanking\r\n      x\"80\", x\"18\", x\"71\",\r\n      -- Vertical 1080 with 45 lines blanking\r\n      x\"38\", x\"2D\", x\"40\",\r\n      -- Horizontal front porch\r\n      x\"58\",x\"2C\",\r\n      -- Vertical front porch\r\n      x\"04\",x\"05\",\r\n      -- Horizontal and vertical image size\r\n      x\"0f\", x\"48\", x\"42\",\r\n      -- Horizontal and vertical boarder\r\n      x\"00\", x\"00\",\r\n      -- Options (non-interlaces, not 3D, syncs...)\r\n      x\"1E\",\r\n\r\n      ----- 18 byte data block 1080i --------\r\n      -- Pixel clock\r\n      x\"01\",x\"1D\",\r\n      -- Horizontal 1920 with 280 blanking\r\n      x\"80\", x\"18\", x\"71\",\r\n      -- Vertical 1080 with 45 lines blanking\r\n      x\"1C\", x\"16\", x\"20\",\r\n      -- Horizontal front porch\r\n      x\"58\",x\"2C\",\r\n      -- Vertical front porch -- SEEMS WRONG!\r\n      x\"25\",x\"00\",\r\n      -- Horizontal and vertical image size\r\n      x\"0f\", x\"48\", x\"42\",\r\n      -- Horizontal and vertical boarder\r\n      x\"00\", x\"00\",\r\n      -- Options (non-interlaces, not 3D, syncs...)\r\n      x\"9E\",\r\n\r\n      ----- 18 byte data block 720p --------\r\n      -- Pixel clock\r\n      x\"01\",x\"1D\",\r\n      -- Horizontal 1920 with 280 blanking\r\n      x\"00\", x\"72\", x\"51\",\r\n      -- Vertical 1080 with 45 lines blanking\r\n      x\"D0\", x\"1E\", x\"20\",\r\n      -- Horizontal front porch\r\n      x\"6E\",x\"28\",\r\n      -- Vertical front porch -- SEEMS WRONG!\r\n      x\"55\",x\"00\",\r\n      -- Horizontal and vertical image size\r\n      x\"0f\", x\"48\", x\"42\",\r\n      -- Horizontal and vertical boarder\r\n      x\"00\", x\"00\",\r\n      -- Options (non-interlaces, not 3D, syncs...)\r\n      x\"1E\",\r\n\r\n      ----- 18 byte data block 720p --------\r\n      -- Monitor name ASCII descriptor\r\n      x\"00\", x\"00\", x\"00\", x\"FC\", x\"00\",\r\n      -- ASCII name - \"ABC LCD47w[lf] \"\r\n      x\"48\", x\"61\", x\"6D\", x\"73\", x\"74\", x\"65\", x\"72\", x\"6B\",\r\n      x\"73\", x\"0A\", x\"20\", x\"20\", x\"20\",\r\n\r\n      ----- End of EDID block\r\n      -- Extension flag & checksum\r\n      x\"01\", x\"74\",\r\n      \r\n       x\"02\", x\"03\", x\"18\", x\"72\", x\"47\", x\"90\", x\"85\", x\"04\", x\"03\", x\"02\", x\"07\", x\"06\", x\"23\", x\"09\", x\"07\", x\"07\",\r\n       x\"83\", x\"01\", x\"00\", x\"00\", x\"65\", x\"03\", x\"0C\", x\"00\", x\"10\", x\"00\", x\"8E\", x\"0A\", x\"D0\", x\"8A\", x\"20\", x\"E0\",\r\n       x\"2d\", x\"10\", x\"10\", x\"3E\", x\"96\", x\"00\", x\"1F\", x\"09\", x\"00\", x\"00\", x\"00\", x\"18\", x\"8E\", x\"0A\", x\"D0\", x\"8A\",\r\n       x\"20\", x\"E0\", x\"2D\", x\"10\", x\"10\", x\"3E\", x\"96\", x\"00\", x\"04\", x\"03\", x\"00\", x\"00\", x\"00\", x\"18\", x\"8E\", x\"0A\",\r\n       x\"A0\", x\"14\", x\"51\", x\"F0\", x\"16\", x\"00\", x\"26\", x\"7C\", x\"43\", x\"00\", x\"1F\", x\"09\", x\"00\", x\"00\", x\"00\", x\"98\",\r\n       x\"8E\", x\"0A\", x\"A0\", x\"14\", x\"51\", x\"F0\", x\"16\", x\"00\", x\"26\", x\"7C\", x\"43\", x\"00\", x\"04\", x\"03\", x\"00\", x\"00\",\r\n       x\"00\", x\"98\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\",\r\n       x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"00\", x\"C9\"\r\n      \r\n      );\r\n\r\n   signal sclk_delay  : std_logic_vector(2 downto 0);\r\n   signal sdat_delay  : unsigned(6 downto 0);\r\n   \r\n   type t_state is (   state_idle, \r\n                     -- States to support writing the device's address\r\n                     state_start,\r\n                     state_dev7,\r\n                     state_dev6,\r\n                     state_dev5,\r\n                     state_dev4,\r\n                     state_dev3,\r\n                     state_dev2,\r\n                     state_dev1,\r\n                     state_dev0,\r\n                     -- States to support writing the address\r\n                     state_ack_device_write,\r\n                     state_addr7,\r\n                     state_addr6,\r\n                     state_addr5,\r\n                     state_addr4,\r\n                     state_addr3,\r\n                     state_addr2,\r\n                     state_addr1,\r\n                     state_addr0,\r\n                     state_addr_ack,\r\n                     -- States to support the selector device \r\n                     state_selector_ack_device_write,\r\n                     state_selector_addr7,\r\n                     state_selector_addr6,\r\n                     state_selector_addr5,\r\n                     state_selector_addr4,\r\n                     state_selector_addr3,\r\n                     state_selector_addr2,\r\n                     state_selector_addr1,\r\n                     state_selector_addr0,\r\n                     state_selector_addr_ack,\r\n                     -- States to support reading from the the EDID ROM\r\n                     state_ack_device_read,\r\n                     state_read7,\r\n                     state_read6,\r\n                     state_read5,\r\n                     state_read4,\r\n                     state_read3,\r\n                     state_read2,\r\n                     state_read1,\r\n                     state_read0,\r\n                     state_read_ack);\r\n\r\n   signal state           : t_state := state_idle;\r\n   signal data_out_sr     : std_logic_vector(7 downto 0) := (others => '1');\r\n   signal data_shift_reg  : std_logic_vector(7 downto 0) := (others => '0');\r\n   signal addr_reg        : unsigned(7 downto 0) := (others => '0');\r\n   signal selector_reg    : unsigned(7 downto 0) := (others => '0');\r\n   signal data_to_send    : std_logic_vector(7 downto 0) := (others => '0');\r\n   signal data_out_delay  : std_logic_vector(7 downto 0) := (others => '0');\r\n   signal PULL_LOW        : std_logic := '0';\r\n   signal sdat_input      : std_logic := '0';\r\n   signal sdat_delay_last : std_logic := '0';\r\nbegin\r\n\r\ni_IOBUF: IOBUF\r\n    generic map (\r\n       DRIVE => 12,\r\n       IOSTANDARD => \"DEFAULT\",\r\n       SLEW => \"SLOW\")\r\n    port map (\r\n       O  => sdat_input, -- Buffer output\r\n       IO => sdat_raw,   -- Buffer inout port (connect directly to top-level port)\r\n       I  => '0',        -- Buffer input\r\n       T  => data_out_sr(data_out_sr'high)      -- 3-state enable input, high=input, low=output \r\n    );\r\n    edid_debug(0) <= std_logic(sdat_delay(sdat_delay'high));\r\n    edid_debug(1) <= sclk_raw; \r\n\r\nprocess(clk)\r\n   begin   \r\n      if rising_edge(clk) then\r\n         \r\n         -- falling edge on SDAT while sclk is held high = START condition\r\n         if sclk_delay(1) = '1' and sclk_delay(0) = '1' and sdat_delay_last  = '1' and sdat_delay(sdat_delay'high) = '0' then\r\n            state <= state_start;\r\n            edid_debug(2) <= '1';\r\n         end if;\r\n         \r\n         -- rising edge on SDAT while sclk is held high = STOP condition\r\n         if sclk_delay(1) = '1' and sclk_delay(0) = '1' and sdat_delay_last = '0' and sdat_delay(sdat_delay'high) = '1' then\r\n            state <= state_idle;\r\n            selector_reg <= (others => '0');\r\n            edid_debug(2) <= '0';\r\n         end if;\r\n\r\n         -- rising edge on SCLK - usually a data bit \r\n         if sclk_delay(1) = '1' and sclk_delay(0) = '0' then\r\n            -- Move data into a shift register\r\n            data_shift_reg <= data_shift_reg(data_shift_reg'high-1 downto 0) & std_logic(sdat_delay(sdat_delay'high));\r\n         end if;\r\n         \r\n         -- falling edge on SCLK - time to change state\r\n         if sclk_delay(1) = '0' and sclk_delay(0) = '1' then\r\n            data_out_sr <= data_out_sr(data_out_sr'high-1 downto 0) & '1'; -- Add Pull up   \r\n            case state is \r\n               when state_start            => state <= state_dev7;\r\n               when state_dev7             => state <= state_dev6;\r\n               when state_dev6             => state <= state_dev5;\r\n               when state_dev5             => state <= state_dev4;\r\n               when state_dev4             => state <= state_dev3;\r\n               when state_dev3             => state <= state_dev2;\r\n               when state_dev2             => state <= state_dev1;\r\n               when state_dev1             => state <= state_dev0;\r\n               when state_dev0             => if data_shift_reg = x\"A1\" then\r\n                                                 state <= state_ack_device_read;\r\n                                                 data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK\r\n                                              elsif data_shift_reg = x\"A0\" then\r\n                                                 state <= state_ack_device_write;\r\n                                                 data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK\r\n                                              elsif data_shift_reg = x\"60\" then\r\n                                                 state <= state_selector_ack_device_write;\r\n                                                 data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK\r\n                                              else\r\n                                                 state <= state_idle;\r\n                                              end if;               \r\n               when state_ack_device_write => state <= state_addr7;\r\n               when state_addr7            => state <= state_addr6;\r\n               when state_addr6            => state <= state_addr5;\r\n               when state_addr5            => state <= state_addr4;\r\n               when state_addr4            => state <= state_addr3;\r\n               when state_addr3            => state <= state_addr2;\r\n               when state_addr2            => state <= state_addr1;\r\n               when state_addr1            => state <= state_addr0;\r\n               when state_addr0            => state <= state_addr_ack;\r\n                                              addr_reg  <= unsigned(data_shift_reg);\r\n                                              data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK\r\n               when state_addr_ack         => state <= state_idle;   -- SLave ACK and ignore any written data\r\n                ------------------------------------\r\n                -- Process the write to the selector\r\n                ------------------------------------\r\n               when state_selector_ack_device_write => state <= state_selector_addr7;\r\n               when state_selector_addr7            => state <= state_selector_addr6;\r\n               when state_selector_addr6            => state <= state_selector_addr5;\r\n               when state_selector_addr5            => state <= state_selector_addr4;\r\n               when state_selector_addr4            => state <= state_selector_addr3;\r\n               when state_selector_addr3            => state <= state_selector_addr2;\r\n               when state_selector_addr2            => state <= state_selector_addr1;\r\n               when state_selector_addr1            => state <= state_selector_addr0;\r\n               when state_selector_addr0            => state <= state_selector_addr_ack;\r\n                                              selector_reg  <= unsigned(data_shift_reg(7 downto 0));\r\n                                              data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK\r\n               when state_selector_addr_ack         => state <= state_idle;   -- SLave ACK and ignore any written data\r\n               -------------------------\r\n\r\n               when state_ack_device_read  => state <= state_read7;\r\n                                              data_out_sr <=  edid_rom(to_integer(addr_reg));\r\n               when state_read7            => state <= state_read6;\r\n               when state_read6            => state <= state_read5;\r\n               when state_read5            => state <= state_read4;\r\n               when state_read4            => state <= state_read3;\r\n               when state_read3            => state <= state_read2;\r\n               when state_read2            => state <= state_read1;\r\n               when state_read1            => state <= state_read0;\r\n               when state_read0            => state <= state_read_ack; \r\n               when state_read_ack         => if sdat_delay(sdat_delay'high) = '0' then \r\n                                                 state <= state_read7;\r\n                                                 data_out_sr <=  edid_rom(to_integer(addr_reg+1));\r\n                                              else \r\n                                                 state <= state_idle;\r\n                                              end if;                     \r\n                                              addr_reg <= addr_reg+1;\r\n               when others                 => state <= state_idle;\r\n            end case;\r\n         end if;\r\n        sdat_delay_last <= sdat_delay(sdat_delay'high);\r\n         -- Synchronisers for SCLK and SDAT\r\n         sclk_delay <= sclk_raw & sclk_delay(sclk_delay'high downto 1);\r\n         -- Resolve any 'Z' state in simulation - make it pull up. \r\n         if sdat_input = '0'  then \r\n            if sdat_delay(sdat_delay'high) = '1' then \r\n                sdat_delay <= sdat_delay - 1;\r\n            else\r\n                sdat_delay <= (others => '0');\r\n            end if; \r\n         else\r\n            if sdat_delay(sdat_delay'high) = '0' then \r\n                 sdat_delay <= sdat_delay + 1;\r\n             else\r\n                 sdat_delay <= (others => '1');\r\n             end if; \r\n         end if;\r\n      end if;\r\n   end process;\r\nend architecture;"
  },
  {
    "path": "src/expand_422_to_444.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: expand_422_to_444 - Behavioral\r\n--\r\n-- Description: Convert incoming 422 data to 444 \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity expand_422_to_444 is\r\n    Port ( clk : in STD_LOGIC;\r\n        input_is_422 : in std_logic;\r\n        ------------------\r\n        -- Incoming pixels\r\n        ------------------\r\n        in_blank  : in std_logic;\r\n        in_hsync  : in std_logic;\r\n        in_vsync  : in std_logic;\r\n        in_ch2    : in std_logic_vector(7 downto 0);\r\n        in_ch1    : in std_logic_vector(7 downto 0);\r\n        in_ch0    : in std_logic_vector(7 downto 0);\r\n    \r\n        -------------------\r\n        -- Processed pixels\r\n        -------------------\r\n        out_blank : out std_logic;\r\n        out_hsync : out std_logic;\r\n        out_vsync : out std_logic;\r\n        out_U     : out std_logic_vector(11 downto 0);  -- B or Cb\r\n        out_V     : out std_logic_vector(11 downto 0);  -- G or Y\r\n        out_W     : out std_logic_vector(11 downto 0)   -- R or Cr\r\n    );\r\nend expand_422_to_444;\r\n\r\narchitecture Behavioral of expand_422_to_444 is\r\n\r\n    signal in_blank_1 : std_logic := '0';\r\n    signal in_hsync_1 : std_logic := '0';\r\n    signal in_vsync_1 : std_logic := '0';\r\n    signal in_ch0_1   : std_logic_vector(7 downto 0) := (others => '0');\r\n    signal in_ch1_1   : std_logic_vector(7 downto 0) := (others => '0');\r\n    signal in_ch2_1   : std_logic_vector(7 downto 0) := (others => '0');\r\n\r\n    signal in_blank_2 : std_logic := '0';\r\n    signal in_hsync_2 : std_logic := '0';\r\n    signal in_vsync_2 : std_logic := '0';\r\n    signal in_ch0_2   : std_logic_vector(7 downto 0) := (others => '0');\r\n    signal in_ch1_2   : std_logic_vector(7 downto 0) := (others => '0');\r\n    signal in_ch2_2   : std_logic_vector(7 downto 0) := (others => '0');\r\n\r\n    signal first_of_pair : std_logic := '0';\r\nbegin\r\n\r\nprocess(clk) \r\n    begin\r\n        if rising_edge(clk) then\r\n            if input_is_422 = '1' then\r\n                ------------------------------------------------------\r\n                -- For 422, copy the chroma values between pixel pairs \r\n                ------------------------------------------------------                \r\n                out_blank <= in_blank_1;\r\n                out_hsync <= in_hsync_1;\r\n                out_vsync <= in_vsync_1;\r\n                if in_blank_1 = '1' then\r\n                    first_of_pair <= '1';\r\n                    out_U     <= in_ch2_1 & in_ch0_1(7 downto 4); -- Cb\r\n                    out_V     <= in_ch1_1 & in_ch0_1(3 downto 0); -- Y\r\n                    out_W     <= in_ch2_1 & in_ch0_1(7 downto 4); -- Cr\r\n                else\r\n                    if first_of_pair = '1' then\r\n                        -- Take Cr from the next pixel\r\n                        first_of_pair <= '0';\r\n                        out_U     <= in_ch2_1 & in_ch0_1(7 downto 4); -- Cb\r\n                        out_V     <= in_ch1_1 & in_ch0_1(3 downto 0); -- Y\r\n                        out_W     <= in_ch2   & in_ch0  (7 downto 4); -- Cr\r\n                    else\r\n                        -- Take Cb from the prior pixel\r\n                        first_of_pair <= '1';\r\n                        out_U     <= in_ch2_2 & in_ch0_2(7 downto 4); -- Cb\r\n                        out_V     <= in_ch1_1 & in_ch0_1(3 downto 0); -- Y\r\n                        out_W     <= in_ch2_1 & in_ch0_1(7 downto 4); -- Cr\r\n                    end if;\r\n                end if;\r\n            else\r\n                ------------------------------------------------------\r\n                -- Minimal processing for 422 (either RGB or YCbCr)\r\n                ------------------------------------------------------\r\n                out_blank <= in_blank_1;\r\n                out_hsync <= in_hsync_1;\r\n                out_vsync <= in_vsync_1;\r\n                out_U     <= in_ch0_1 & \"0000\";  -- B or Cb  \r\n                out_V     <= in_ch1_1 & \"0000\";  -- G or Y\r\n                out_W     <= in_ch2_1 & \"0000\";  -- R or Cr\r\n            end if;\r\n            \r\n            -- Remember the pixel for two cycles\r\n            in_blank_1 <= in_blank;\r\n            in_hsync_1 <= in_hsync;\r\n            in_vsync_1 <= in_vsync;\r\n            in_ch0_1   <= in_ch0;\r\n            in_ch1_1   <= in_ch1;\r\n            in_ch2_1   <= in_ch2;\r\n            \r\n            in_blank_2 <= in_blank_1;\r\n            in_hsync_2 <= in_hsync_1;\r\n            in_vsync_2 <= in_vsync_1;\r\n            in_ch0_2   <= in_ch0_1;\r\n            in_ch1_2   <= in_ch1_1;\r\n            in_ch2_2   <= in_ch2_1;\r\n        end if;    \r\n    end process;\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/extract_audio_samples.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Module Name: extract_audio_samples - Behavioral\r\n--\r\n-- Description: Extract audio data from the HDMI ADP data stream\r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity extract_audio_samples is\r\n    Port ( clk                 : in STD_LOGIC;\r\n           adp_data_valid      : in STD_LOGIC;\r\n           adp_header_bit      : in STD_LOGIC;\r\n           adp_frame_bit       : in STD_LOGIC;\r\n           adp_subpacket0_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket1_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket2_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket3_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           audio_de            : out STD_LOGIC;\r\n           audio_channel       : out STD_LOGIC_VECTOR (2 downto 0);\r\n           audio_sample        : out STD_LOGIC_VECTOR (23 downto 0)\r\n    );\r\nend extract_audio_samples;\r\n\r\narchitecture Behavioral of extract_audio_samples is\r\n    signal header_bits        : STD_LOGIC_VECTOR (31 downto 0);\r\n    signal frame_bits         : STD_LOGIC_VECTOR (31 downto 0);\r\n    signal subpacket0_bits    : STD_LOGIC_VECTOR (63 downto 0);\r\n    signal subpacket1_bits    : STD_LOGIC_VECTOR (63 downto 0);\r\n    signal subpacket2_bits    : STD_LOGIC_VECTOR (63 downto 0);\r\n    signal subpacket3_bits    : STD_LOGIC_VECTOR (63 downto 0);\r\n    signal grab_other_channel : std_logic := '0';\r\nbegin\r\n\r\nprocess(clk)\r\n    begin\r\n        if rising_edge(clk) then\r\n            -----------------------------------------------\r\n            -- Move the incoming bits into a shift register\r\n            -----------------------------------------------\r\n            header_bits     <= adp_header_bit      & header_bits(header_bits'high downto 1);\r\n            frame_bits      <= (adp_frame_bit and adp_data_valid) & frame_bits(frame_bits'high   downto 1);\r\n            subpacket0_bits <= adp_subpacket0_bits & subpacket0_bits(subpacket0_bits'high downto 2);\r\n            subpacket1_bits <= adp_subpacket1_bits & subpacket1_bits(subpacket1_bits'high downto 2);\r\n            subpacket2_bits <= adp_subpacket2_bits & subpacket2_bits(subpacket2_bits'high downto 2);\r\n            subpacket3_bits <= adp_subpacket3_bits & subpacket3_bits(subpacket3_bits'high downto 2);\r\n            \r\n            audio_de      <= '0';\r\n\r\n            if grab_other_channel = '1' then\r\n                audio_de           <= header_bits(7);\r\n                audio_channel      <= \"001\";\r\n                audio_sample       <= subpacket0_bits(45 downto 22);\r\n                grab_other_channel <= '0';\r\n            end if;\r\n            if frame_bits = x\"FFFFFFFE\" then\r\n                ------------------------------------------------\r\n                -- Check the packet type as being audio samples\r\n                ------------------------------------------------\r\n                if header_bits(7 downto 0) = x\"02\" then\r\n                    audio_de      <= header_bits(8);\r\n                    audio_channel <= \"000\";\r\n                    audio_sample  <= subpacket0_bits(23 downto 0);\r\n                    grab_other_channel <= '1';                      \r\n                end if;\r\n            end if;\r\n        end if;\r\n    end process;\r\n    \r\nend Behavioral;\r\n"
  },
  {
    "path": "src/extract_video_infopacket_data.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: extract_video_infopacket_data - Behavioral\r\n--\r\n-- Description: Extract a couple of fields from the video infopacket, allowin use\r\n--              to correctly convert the incoming pixels into RGB 444 for internal\r\n--              processing.  \r\n-- \r\n--              Bits 14:13 indicate the colour space and 444 vs 422.\r\n--              Bits 27:26 indicate if the pixels are studio level (16-240) \r\n--              or full range (0-255)  \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity extract_video_infopacket_data is\r\n    Port ( clk                 : in STD_LOGIC;\r\n           adp_data_valid      : in STD_LOGIC;\r\n           adp_header_bit      : in STD_LOGIC;\r\n           adp_frame_bit       : in STD_LOGIC;\r\n           adp_subpacket0_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket1_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket2_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket3_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           input_is_YCbCr      : out STD_LOGIC;\r\n           input_is_422        : out STD_LOGIC;\r\n           input_is_sRGB       : out STD_LOGIC);\r\nend extract_video_infopacket_data;\r\n\r\narchitecture Behavioral of extract_video_infopacket_data is\r\n    -- For this usage, we are only interested in four bits that are all in the first\r\n    -- 16 transfers of the 32-bit packets\r\n    signal header_bits     : STD_LOGIC_VECTOR (15 downto 0);\r\n    signal frame_bits      : STD_LOGIC_VECTOR (15 downto 0);\r\n    signal subpacket0_bits : STD_LOGIC_VECTOR (31 downto 0);\r\n    signal updated         : std_logic := '0';\r\nbegin\r\n\r\nprocess(clk)\r\n    begin\r\n        if rising_edge(clk) then\r\n            if adp_data_valid = '1' then\r\n                -----------------------------------------------\r\n                -- Move the incoming bits into a shift register\r\n                -----------------------------------------------\r\n                header_bits     <= adp_header_bit      & header_bits(header_bits'high downto 1);\r\n                frame_bits      <= adp_frame_bit       & frame_bits(frame_bits'high   downto 1);\r\n                subpacket0_bits <= adp_subpacket0_bits & subpacket0_bits(subpacket0_bits'high downto 2);\r\n                updated         <= '1';  \r\n            end if;\r\n\r\n            ----------------------------------------------------\r\n            -- The 0 in frame bits indicates the start of packet\r\n            ----------------------------------------------------\r\n            if updated = '1' and frame_bits = x\"FFFE\" then\r\n                -- 82 is the type of packet, 02 is the version\r\n                if header_bits = x\"0282\" then\r\n                    case subpacket0_bits(14 downto 13) is\r\n                        when \"00\"   => input_is_YCbCr <= '0'; input_is_422 <= '0';\r\n                        when \"01\"   => input_is_YCbCr <= '1'; input_is_422 <= '1';\r\n                        when \"10\"   => input_is_YCbCr <= '1'; input_is_422 <= '0';\r\n                        when others => NULL;\r\n                    end case; \r\n\r\n                    case subpacket0_bits(27 downto 26) is\r\n                        when \"01\"   => input_is_sRGB <= '1';\r\n                        when others => input_is_sRGB <= '0';\r\n                    end case; \r\n\r\n                end if;\r\n            end if; \r\n        end if;\r\n    end process;\r\n\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/guidelines.vhd",
    "content": "----------------------------------------------------------------------------------\n-- Engineer: Mike Field <hamster@snap.net.nz> \n-- \n-- Module Name: guidelines - Behavioral\n--\n-- Description: When enabled, put guidelines on the screen  \n-- \n-- The MIT License (MIT)\n-- \n-- Copyright (c) 2015 Michael Alan Field\n-- \n-- Permission is hereby granted, free of charge, to any person obtaining a copy\n-- of this software and associated documentation files (the \"Software\"), to deal\n-- in the Software without restriction, including without limitation the rights\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n-- copies of the Software, and to permit persons to whom the Software is\n-- furnished to do so, subject to the following conditions:\n-- \n-- The above copyright notice and this permission notice shall be included in\n-- all copies or substantial portions of the Software.\n-- \n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n-- THE SOFTWARE.\n------------------------------------------------------------------------------------\n----- Want to say thanks? ----------------------------------------------------------\n------------------------------------------------------------------------------------\n--\n-- This design has taken many hours - with the industry metric of 30 lines\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\n-- to share it if you can make use of it. It is released under the MIT license,\n-- so you are not under any onus to say thanks, but....\n-- \n-- If you what to say thanks for this design how about trying PayPal?\n--  Educational use - Enough for a beer\n--  Hobbyist use    - Enough for a pizza\n--  Research use    - Enough to take the family out to dinner\n--  Commercial use  - A weeks pay for an engineer (I wish!)\n--\n----------------------------------------------------------------------------------\n\nlibrary IEEE;\nuse IEEE.STD_LOGIC_1164.ALL;\nuse IEEE.NUMERIC_STD.ALL;\n\nentity guidelines is\n    Port ( clk : in STD_LOGIC;\n       enable_feature   : in std_logic;\n       -------------------------------\n       -- VGA data recovered from HDMI\n       -------------------------------\n       in_blank  : in std_logic;\n       in_hsync  : in std_logic;\n       in_vsync  : in std_logic;\n       in_red    : in std_logic_vector(7 downto 0);\n       in_green  : in std_logic_vector(7 downto 0);\n       in_blue   : in std_logic_vector(7 downto 0);\n       is_interlaced   : in std_logic;\n       is_second_field : in std_logic;\n        \n       -----------------------------------\n       -- VGA data to be converted to HDMI\n       -----------------------------------\n       out_blank : out std_logic;\n       out_hsync : out std_logic;\n       out_vsync : out std_logic;\n       out_red   : out std_logic_vector(7 downto 0);\n       out_green : out std_logic_vector(7 downto 0);\n       out_blue  : out std_logic_vector(7 downto 0));\nend guidelines;\n\narchitecture Behavioral of guidelines is\n    signal hcount : unsigned(11 downto 0) := (others => '0');\n    signal vcount : unsigned(11 downto 0) := (others => '0');\n    signal h_size : unsigned(11 downto 0) := (others => '0');\n    signal v_size : unsigned(11 downto 0) := (others => '0');\n    signal last_blank : std_logic := '0';\n    signal last_vsync : std_logic := '0';\nbegin\n\nprocess(clk)\n    begin\n        if rising_edge(clk) then\n            out_blank  <= in_blank;\n            out_hsync  <= in_hsync;\n            out_vsync  <= in_vsync;\n            out_red    <= in_red;\n            out_green  <= in_green;\n            out_blue   <= in_blue;\n\n            if enable_feature = '1' then\n                if h_size = 1280 then\n                    if hcount = 426 or hcount = 854 then\n                        out_red   <= (others => '1');\n                        out_green <= (others => '1');\n                        out_blue  <= (others => '1');\n                    end if; \n                end if; \n\n                if h_size = 1920 then\n                    if hcount = 640 or hcount = 1280 then\n                        out_red   <= (others => '1');\n                        out_green <= (others => '1');\n                        out_blue  <= (others => '1');\n                    end if; \n                end if;\n\n                if v_size = 720 then\n                    if vcount = 240 or vcount = 480 then\n                        out_red   <= (others => '1');\n                        out_green <= (others => '1');\n                        out_blue  <= (others => '1');\n                    end if;\n                end if;\n\n                if v_size = 1080 then\n                    if is_interlaced = '0' and (vcount = 360 or vcount = 720) then\n                        out_red   <= (others => '1');\n                        out_green <= (others => '1');\n                        out_blue  <= (others => '1');\n                    end if;\n                    \n                    if is_interlaced = '1' and (vcount = 180 or vcount = 360) then\n                        out_red   <= (others => '1');\n                        out_green <= (others => '1');\n                        out_blue  <= (others => '1');\n                    end if;\n                end if;\n            end if;\n                            \n            -------------------------------------------------------------\n            -- Count the number of lines in a frame (not field!!!)\n            -------------------------------------------------------------\n            if last_blank = '0' and in_blank = '1' then\n                vcount <= vcount + 1;\n            end if;\n            \n            -------------------------------------------------------------\n            -- Use the falling edge of VSYNC to to capture the number of \n            -- lines on the screen, as the rising edge is where the \n            -- interaced field is detected and can be a bit unstable.\n            -------------------------------------------------------------\n            if in_vsync = '0' and last_vsync = '1' and is_second_field = '0'then\n                vcount <= (others => '0');\n                v_size <= vcount;\n            end if;\n\n            -------------------------------------------------------------\n            -- Count the width of the frame\n            -------------------------------------------------------------\n            if in_blank = '1' then\n                if hcount /= 0 then\n                    h_size <= hcount;\n                end if;\n                hcount <= (others => '0');\n            else\n                hcount <= hcount + 1;\n            end if;\n            last_blank <= in_blank;\n            last_vsync <= in_vsync;\n            if enable_feature = '1' and in_blank = '0' then\n            end if; \n        end if;\n    end process;\nend Behavioral;\n"
  },
  {
    "path": "src/hdmi_design.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer:    Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Create Date: 22.07.2015 21:10:34\r\n-- Module Name: hdmi_design - Behavioral\r\n-- Project Name: \r\n--\r\n-- Description: Top level of a video processing design \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity hdmi_design is\r\n    Port ( \r\n        clk100    : in STD_LOGIC;\r\n        -- Control signals\r\n        led           : out   std_logic_vector(7 downto 0) :=(others => '0');\r\n        sw            : in    std_logic_vector(7 downto 0) :=(others => '0');\r\n        debug_pmod    : out   std_logic_vector(7 downto 0) :=(others => '0');\r\n\r\n        --HDMI input signals\r\n        hdmi_rx_cec   : inout std_logic;\r\n        hdmi_rx_hpa   : out   std_logic;\r\n        hdmi_rx_scl   : in    std_logic;\r\n        hdmi_rx_sda   : inout std_logic;\r\n        hdmi_rx_txen  : out   std_logic;\r\n        hdmi_rx_clk_n : in    std_logic;\r\n        hdmi_rx_clk_p : in    std_logic;\r\n        hdmi_rx_n     : in    std_logic_vector(2 downto 0);\r\n        hdmi_rx_p     : in    std_logic_vector(2 downto 0);\r\n\r\n        --- HDMI out\r\n        hdmi_tx_cec   : inout std_logic;\r\n        hdmi_tx_clk_n : out   std_logic;\r\n        hdmi_tx_clk_p : out   std_logic;\r\n        hdmi_tx_hpd   : in    std_logic;\r\n        hdmi_tx_rscl  : inout std_logic;\r\n        hdmi_tx_rsda  : inout std_logic;\r\n        hdmi_tx_p     : out   std_logic_vector(2 downto 0);\r\n        hdmi_tx_n     : out   std_logic_vector(2 downto 0);\r\n        -- For dumping symbols\r\n        rs232_tx     : out std_logic      \r\n    );\r\nend hdmi_design;\r\n\r\narchitecture Behavioral of hdmi_design is\r\n    component hdmi_io is\r\n    Port ( \r\n        clk100    : in STD_LOGIC;\r\n        -------------------------------\r\n        -- Control signals\r\n        -------------------------------\r\n        clock_locked  : out std_logic;\r\n        data_synced   : out std_logic;\r\n        debug         : out std_logic_vector(7 downto 0);        \r\n        -------------------------------\r\n        --HDMI input signals\r\n        -------------------------------\r\n        hdmi_rx_cec   : inout std_logic;\r\n        hdmi_rx_hpa   : out   std_logic;\r\n        hdmi_rx_scl   : in    std_logic;\r\n        hdmi_rx_sda   : inout std_logic;\r\n        hdmi_rx_txen  : out   std_logic;\r\n        hdmi_rx_clk_n : in    std_logic;\r\n        hdmi_rx_clk_p : in    std_logic;\r\n        hdmi_rx_n     : in    std_logic_vector(2 downto 0);\r\n        hdmi_rx_p     : in    std_logic_vector(2 downto 0);\r\n\r\n        -------------\r\n        -- HDMI out\r\n        -------------\r\n        hdmi_tx_cec   : inout std_logic;\r\n        hdmi_tx_clk_n : out   std_logic;\r\n        hdmi_tx_clk_p : out   std_logic;\r\n        hdmi_tx_hpd   : in    std_logic;\r\n        hdmi_tx_rscl  : inout std_logic;\r\n        hdmi_tx_rsda  : inout std_logic;\r\n        hdmi_tx_p     : out   std_logic_vector(2 downto 0);\r\n        hdmi_tx_n     : out   std_logic_vector(2 downto 0);\r\n\r\n        pixel_clk     : out std_logic;\r\n        -------------------------------\r\n        -- VGA data recovered from HDMI\r\n        -------------------------------\r\n        in_hdmi_detected : out std_logic;\r\n        in_blank        : out std_logic;\r\n        in_hsync        : out std_logic;\r\n        in_vsync        : out std_logic;\r\n        in_red          : out std_logic_vector(7 downto 0);\r\n        in_green        : out std_logic_vector(7 downto 0);\r\n        in_blue         : out std_logic_vector(7 downto 0);\r\n        is_interlaced   : out std_logic;\r\n        is_second_field : out std_logic;\r\n            \r\n        -------------------------------------\r\n        -- Audio Levels\r\n        -------------------------------------\r\n        audio_channel : out std_logic_vector(2 downto 0);\r\n        audio_de      : out std_logic;\r\n        audio_sample  : out std_logic_vector(23 downto 0);\r\n        \r\n        -----------------------------------\r\n        -- VGA data to be converted to HDMI\r\n        -----------------------------------\r\n        out_blank     : in  std_logic;\r\n        out_hsync     : in  std_logic;\r\n        out_vsync     : in  std_logic;\r\n        out_red       : in  std_logic_vector(7 downto 0);\r\n        out_green     : in  std_logic_vector(7 downto 0);\r\n        out_blue      : in  std_logic_vector(7 downto 0);\r\n        -----------------------------------\r\n        -- For symbol dump or retransmit\r\n        -----------------------------------\r\n        symbol_sync  : out std_logic; -- indicates a fixed reference point in the frame.\r\n        symbol_ch0   : out std_logic_vector(9 downto 0);\r\n        symbol_ch1   : out std_logic_vector(9 downto 0);\r\n        symbol_ch2   : out std_logic_vector(9 downto 0)\r\n    );\r\n    end component;\r\n    signal symbol_sync  : std_logic;\r\n    signal symbol_ch0   : std_logic_vector(9 downto 0);\r\n    signal symbol_ch1   : std_logic_vector(9 downto 0);\r\n    signal symbol_ch2   : std_logic_vector(9 downto 0);\r\n    \r\n    component pixel_processing is\r\n        Port ( clk : in STD_LOGIC;\r\n            switches  : in std_logic_vector(7 downto 0);\r\n            ------------------\r\n            -- Incoming pixels\r\n            ------------------\r\n            in_blank  : in std_logic;\r\n            in_hsync  : in std_logic;\r\n            in_vsync  : in std_logic;\r\n            in_red    : in std_logic_vector(7 downto 0);\r\n            in_green  : in std_logic_vector(7 downto 0);\r\n            in_blue   : in std_logic_vector(7 downto 0);\r\n            is_interlaced   : in  std_logic;\r\n            is_second_field : in  std_logic;\r\n        \r\n            -------------------\r\n            -- Processed pixels\r\n            -------------------\r\n            out_blank : out std_logic;\r\n            out_hsync : out std_logic;\r\n            out_vsync : out std_logic;\r\n            out_red   : out std_logic_vector(7 downto 0);\r\n            out_green : out std_logic_vector(7 downto 0);\r\n            out_blue  : out std_logic_vector(7 downto 0);\r\n                       \r\n            -------------------------------------\r\n            -- Audio samples for metering\r\n            -------------------------------------\r\n            audio_channel : in std_logic_vector(2 downto 0);\r\n            audio_de      : in std_logic;\r\n            audio_sample  : in std_logic_vector(23 downto 0)\r\n    );\r\n    end component;\r\n\r\n    component symbol_dump is\r\n        port ( \r\n            clk          : in std_logic;\r\n            clk100       : in std_logic;\r\n            symbol_sync  : in std_logic; -- indicates a fixed reference point in the frame.\r\n            symbol_ch0   : in std_logic_vector(9 downto 0);\r\n            symbol_ch1   : in std_logic_vector(9 downto 0);\r\n            symbol_ch2   : in std_logic_vector(9 downto 0);\r\n            rs232_tx     : out std_logic);        \r\n    end component;\r\n\r\n    signal pixel_clk : std_logic;\r\n    signal in_blank  : std_logic;\r\n    signal in_hsync  : std_logic;\r\n    signal in_vsync  : std_logic;\r\n    signal in_red    : std_logic_vector(7 downto 0);\r\n    signal in_green  : std_logic_vector(7 downto 0);\r\n    signal in_blue   : std_logic_vector(7 downto 0);\r\n    signal is_interlaced   : std_logic;\r\n    signal is_second_field : std_logic;\r\n    signal out_blank : std_logic;\r\n    signal out_hsync : std_logic;\r\n    signal out_vsync : std_logic;\r\n    signal out_red   : std_logic_vector(7 downto 0);\r\n    signal out_green : std_logic_vector(7 downto 0);\r\n    signal out_blue  : std_logic_vector(7 downto 0);\r\n\r\n    signal audio_channel : std_logic_vector(2 downto 0);\r\n    signal audio_de      : std_logic;\r\n    signal audio_sample  : std_logic_vector(23 downto 0);\r\n\r\n    signal debug : std_logic_vector(7 downto 0);\r\nbegin\r\n    debug_pmod <= debug;    \r\n    led        <= debug;\r\n    \r\ni_hdmi_io: hdmi_io port map ( \r\n        clk100        => clk100,\r\n        ---------------------\r\n        -- Control signals\r\n        ---------------------\r\n        clock_locked     => open,\r\n        data_synced      => open,\r\n        debug            => debug,\r\n        ---------------------\r\n        -- HDMI input signals\r\n        ---------------------\r\n        hdmi_rx_cec   => hdmi_rx_cec,\r\n        hdmi_rx_hpa   => hdmi_rx_hpa,\r\n        hdmi_rx_scl   => hdmi_rx_scl,\r\n        hdmi_rx_sda   => hdmi_rx_sda,\r\n        hdmi_rx_txen  => hdmi_rx_txen,\r\n        hdmi_rx_clk_n => hdmi_rx_clk_n,\r\n        hdmi_rx_clk_p => hdmi_rx_clk_p,\r\n        hdmi_rx_p     => hdmi_rx_p,\r\n        hdmi_rx_n     => hdmi_rx_n,\r\n\r\n        ----------------------\r\n        -- HDMI output signals\r\n        ----------------------\r\n        hdmi_tx_cec   => hdmi_tx_cec,\r\n        hdmi_tx_clk_n => hdmi_tx_clk_n,\r\n        hdmi_tx_clk_p => hdmi_tx_clk_p,\r\n        hdmi_tx_hpd   => hdmi_tx_hpd,\r\n        hdmi_tx_rscl  => hdmi_tx_rscl,\r\n        hdmi_tx_rsda  => hdmi_tx_rsda,\r\n        hdmi_tx_p     => hdmi_tx_p,\r\n        hdmi_tx_n     => hdmi_tx_n,     \r\n\r\n        \r\n        pixel_clk => pixel_clk,\r\n        -------------------------------\r\n        -- VGA data recovered from HDMI\r\n        -------------------------------\r\n        in_blank        => in_blank,\r\n        in_hsync        => in_hsync,\r\n        in_vsync        => in_vsync,\r\n        in_red          => in_red,\r\n        in_green        => in_green,\r\n        in_blue         => in_blue,\r\n        is_interlaced   => is_interlaced,\r\n        is_second_field => is_second_field,\r\n\r\n        -----------------------------------\r\n        -- For symbol dump or retransmit\r\n        -----------------------------------\r\n        audio_channel => audio_channel,\r\n        audio_de      => audio_de,\r\n        audio_sample  => audio_sample,\r\n        \r\n        -----------------------------------\r\n        -- VGA data to be converted to HDMI\r\n        -----------------------------------\r\n        out_blank => out_blank,\r\n        out_hsync => out_hsync,\r\n        out_vsync => out_vsync,\r\n        out_red   => out_red,\r\n        out_green => out_green,\r\n        out_blue  => out_blue,\r\n        \r\n        symbol_sync  => symbol_sync, \r\n        symbol_ch0   => symbol_ch0,\r\n        symbol_ch1   => symbol_ch1,\r\n        symbol_ch2   => symbol_ch2\r\n    );\r\n    \r\ni_processing: pixel_processing Port map ( \r\n        clk => pixel_clk,\r\n        switches => sw,\r\n        ------------------\r\n        -- Incoming pixels\r\n        ------------------\r\n        in_blank        => in_blank,\r\n        in_hsync        => in_hsync,\r\n        in_vsync        => in_vsync,\r\n        in_red          => in_red,\r\n        in_green        => in_green,\r\n        in_blue         => in_blue,    \r\n        is_interlaced   => is_interlaced,\r\n        is_second_field => is_second_field,\r\n        audio_channel   => audio_channel,\r\n        audio_de        => audio_de,\r\n        audio_sample    => audio_sample,\r\n        -------------------\r\n        -- Processed pixels\r\n        -------------------\r\n        out_blank => out_blank,\r\n        out_hsync => out_hsync,\r\n        out_vsync => out_vsync,\r\n        out_red   => out_red,\r\n        out_green => out_green,\r\n        out_blue  => out_blue\r\n    );\r\n\r\n    -- Swap to this if you want to capture the HDMI symbols\r\n    -- and send them up the RS232 port\r\n    --rs232_tx <= '1';\r\ni_symbol_dump: symbol_dump port map (\r\n            clk         => pixel_clk,\r\n            clk100      => clk100,\r\n            symbol_sync => symbol_sync,\r\n            symbol_ch0  => symbol_ch0,\r\n            symbol_ch1  => symbol_ch1,\r\n            symbol_ch2  => symbol_ch2, \r\n            rs232_tx    => rs232_tx);        \r\n    \r\nend Behavioral;"
  },
  {
    "path": "src/hdmi_input.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Module Name: hdmi_input - Behavioral\r\n--\r\n-- Description: Decode the video data out of an incoming HDMI data stream. \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity hdmi_input is\r\n    Port (\r\n        system_clk      : in  std_logic;\r\n\r\n        debug           : out std_logic_vector(5 downto 0);        \r\n        hdmi_detected   : out std_logic;\r\n    \r\n        pixel_clk       : out std_logic;  -- Driven by BUFG\r\n        pixel_io_clk_x1 : out std_logic;  -- Driven by BUFFIO\r\n        pixel_io_clk_x5 : out std_logic;  -- Driven by BUFFIO\r\n    \r\n        -- HDMI input signals\r\n        hdmi_in_clk   : in    std_logic;\r\n        hdmi_in_ch0   : in    std_logic;\r\n        hdmi_in_ch1   : in    std_logic;\r\n        hdmi_in_ch2   : in    std_logic;\r\n    \r\n        -- Status\r\n        pll_locked   : out std_logic;\r\n        symbol_sync  : out std_logic;\r\n    \r\n        -- Raw data signals\r\n        raw_blank : out std_logic;\r\n        raw_hsync : out std_logic;\r\n        raw_vsync : out std_logic;\r\n        raw_ch0   : out std_logic_vector(7 downto 0);\r\n        raw_ch1   : out std_logic_vector(7 downto 0);\r\n        raw_ch2   : out std_logic_vector(7 downto 0);\r\n        -- ADP data\r\n        adp_data_valid      : out std_logic;\r\n        adp_header_bit      : out std_logic;\r\n        adp_frame_bit       : out std_logic;\r\n        adp_subpacket0_bits : out std_logic_vector(1 downto 0);\r\n        adp_subpacket1_bits : out std_logic_vector(1 downto 0);\r\n        adp_subpacket2_bits : out std_logic_vector(1 downto 0);\r\n        adp_subpacket3_bits : out std_logic_vector(1 downto 0);\r\n        -- For later reuse\r\n        symbol_ch0   : out std_logic_vector(9 downto 0);\r\n        symbol_ch1   : out std_logic_vector(9 downto 0);\r\n        symbol_ch2   : out std_logic_vector(9 downto 0)\r\n        \r\n    );\r\nend hdmi_input;\r\n\r\narchitecture Behavioral of hdmi_input is\r\n\r\n    component input_channel is\r\n    Port ( clk_mgmt        : in STD_LOGIC;\r\n           clk             : in  STD_LOGIC;\r\n           clk_x1          : in  STD_LOGIC;\r\n           clk_x5          : in  STD_LOGIC;\r\n           serial          : in  STD_LOGIC;\r\n           reset           : in  STD_LOGIC;\r\n           ce              : in  STD_LOGIC;\r\n           invalid_symbol  : out std_logic;\r\n           symbol          : out std_logic_vector (9 downto 0);\r\n           ctl_valid       : out std_logic;\r\n           ctl             : out std_logic_vector (1 downto 0);\r\n           terc4_valid     : out std_logic;\r\n           terc4           : out std_logic_vector (3 downto 0);\r\n           guardband_valid : out std_logic;\r\n           guardband       : out std_logic_vector (0 downto 0);\r\n           data_valid      : out std_logic;\r\n           data            : out std_logic_vector (7 downto 0);\r\n           symbol_sync     : out STD_LOGIC);\r\n    end component;\r\n    \r\n    signal clk_pixel_raw     : std_logic;\r\n    \r\n    component alignment_detect is\r\n        Port ( clk            : in STD_LOGIC;\r\n               invalid_symbol : in STD_LOGIC;\r\n               delay_count    : out STD_LOGIC_VECTOR(4 downto 0);\r\n               delay_ce       : out STD_LOGIC;\r\n               bitslip        : out STD_LOGIC;\r\n               symbol_sync    : out STD_LOGIC);\r\n    end component;\r\n    \r\n    signal clk_pixel         : std_logic;\r\n    signal clk_pixel_x1      : std_logic;\r\n    signal clk_pixel_x5      : std_logic;\r\n    signal clk_pixel_x1_raw  : std_logic;\r\n    signal clk_pixel_x5_raw  : std_logic;\r\n    signal clk_200_raw       : std_logic;\r\n    signal clk_200           : std_logic;\r\n    signal clkfb_1           : std_logic;\r\n    signal clkfb_2           : std_logic;\r\n    signal locked            : std_logic;\r\n    signal reset             : std_logic;\r\n    signal ser_reset         : std_logic;\r\n    signal ser_ce            : std_logic;\r\n    -------------------------------------------------------------\r\n    -- The raw 10-bit received symbols\r\n    -------------------------------------------------------------\r\n    signal ch0_symbol  : std_logic_vector(9 downto 0);\r\n    signal ch1_symbol  : std_logic_vector(9 downto 0);\r\n    signal ch2_symbol  : std_logic_vector(9 downto 0);\r\n    \r\n    -------------------------------------------------------------\r\n    -- For the decoded TMDS data\r\n    -------------------------------------------------------------\r\n    signal ch0_invalid_symbol  : std_logic;\r\n    signal ch0_ctl_valid       : std_logic;\r\n    signal ch0_ctl             : std_logic_vector(1 downto 0);\r\n    signal ch0_terc4_valid     : std_logic;\r\n    signal ch0_terc4           : std_logic_vector (3 downto 0);\r\n    signal ch0_data_valid      : std_logic;\r\n    signal ch0_data            : std_logic_vector(7 downto 0);\r\n    signal ch0_guardband_valid : std_logic;\r\n    signal ch0_guardband       : std_logic_vector (0 downto 0);\r\n    signal ch0_delay_count     : std_logic_vector (4 downto 0);\r\n    signal ch0_delay_ce        : STD_LOGIC;\r\n    signal ch0_bitslip         : STD_LOGIC;\r\n    signal ch0_symbol_sync     : STD_LOGIC;\r\n\r\n    signal ch0_invalid_symbol_1  : std_logic;\r\n    signal ch0_ctl_valid_1       : std_logic;\r\n    signal ch0_ctl_1             : std_logic_vector(1 downto 0);\r\n    signal ch0_terc4_valid_1     : std_logic;\r\n    signal ch0_terc4_1           : std_logic_vector (3 downto 0);\r\n    signal ch0_data_valid_1      : std_logic;\r\n    signal ch0_data_1            : std_logic_vector(7 downto 0);\r\n    \r\n    signal ch1_invalid_symbol  : std_logic;\r\n    signal ch1_ctl_valid       : std_logic;\r\n    signal ch1_ctl             : std_logic_vector(1 downto 0);\r\n    signal ch1_terc4_valid     : std_logic;\r\n    signal ch1_terc4           : std_logic_vector (3 downto 0);\r\n    signal ch1_data_valid      : std_logic;\r\n    signal ch1_data            : std_logic_vector(7 downto 0);\r\n    signal ch1_guardband_valid : std_logic;\r\n    signal ch1_guardband       : std_logic_vector (0 downto 0);\r\n    signal ch1_delay_count     : std_logic_vector (4 downto 0);\r\n    signal ch1_delay_ce        : STD_LOGIC;\r\n    signal ch1_bitslip         : STD_LOGIC;\r\n    signal ch1_symbol_sync     : STD_LOGIC;\r\n\r\n    signal ch1_invalid_symbol_1  : std_logic;\r\n    signal ch1_ctl_valid_1       : std_logic;\r\n    signal ch1_ctl_1             : std_logic_vector(1 downto 0);\r\n    signal ch1_terc4_valid_1     : std_logic;\r\n    signal ch1_terc4_1           : std_logic_vector (3 downto 0);\r\n    signal ch1_data_valid_1      : std_logic;\r\n    signal ch1_data_1            : std_logic_vector(7 downto 0);\r\n    \r\n    signal ch2_invalid_symbol  : std_logic;\r\n    signal ch2_ctl_valid       : std_logic;\r\n    signal ch2_ctl             : std_logic_vector(1 downto 0);\r\n    signal ch2_terc4_valid     : std_logic;\r\n    signal ch2_terc4           : std_logic_vector (3 downto 0);\r\n    signal ch2_data_valid      : std_logic;\r\n    signal ch2_data            : std_logic_vector(7 downto 0);\r\n    signal ch2_guardband_valid : std_logic;\r\n    signal ch2_guardband       : std_logic_vector (0 downto 0);\r\n    signal ch2_delay_count     : std_logic_vector (4 downto 0);\r\n    signal ch2_delay_ce        : STD_LOGIC;\r\n    signal ch2_bitslip         : STD_LOGIC;\r\n    signal ch2_symbol_sync     : STD_LOGIC;\r\n\r\n    signal ch2_invalid_symbol_1  : std_logic;\r\n    signal ch2_ctl_valid_1       : std_logic;\r\n    signal ch2_ctl_1             : std_logic_vector(1 downto 0);\r\n    signal ch2_terc4_valid_1     : std_logic;\r\n    signal ch2_terc4_1           : std_logic_vector (3 downto 0);\r\n    signal ch2_data_valid_1      : std_logic;\r\n    signal ch2_data_1            : std_logic_vector(7 downto 0);\r\n    \r\n    \r\n    signal reset_counter  : unsigned(7 downto 0) := (others => '1');\r\n\r\n    signal vdp_prefix_detect    : std_logic_vector(7 downto 0) := (others => '0');\r\n    signal vdp_guardband_detect : std_logic := '0';\r\n    signal vdp_prefix_seen      : std_logic := '0';\r\n    signal in_vdp               : std_logic := '0';\r\n\r\n    signal adp_prefix_detect    : std_logic_vector(7 downto 0) := (others => '0');\r\n    signal adp_guardband_detect : std_logic := '0'; \r\n    signal adp_prefix_seen      : std_logic := '0';\r\n    signal in_adp               : std_logic := '0';\r\n    signal dvid_mode            : std_logic := '0';\r\n    signal last_was_ctl         : std_logic := '0';\r\n    \r\n    signal in_dvid              : std_logic := '0';\r\n    signal symbol_sync_i        : std_logic := '0';\r\nbegin\r\n    pll_locked  <= locked;\r\n    symbol_sync <= symbol_sync_i;\r\n    reset       <= std_logic(reset_counter(reset_counter'high));    \r\n    symbol_ch0  <= ch0_symbol;\r\n    symbol_ch1  <= ch1_symbol;\r\n    symbol_ch2  <= ch2_symbol;\r\n\r\n    \r\n    debug       <= ch2_invalid_symbol & ch1_invalid_symbol & ch0_invalid_symbol & dvid_mode & locked & symbol_sync_i;         \r\n\r\n    --------------------------------------------\r\n    -- a 200MHz clock for the IDELAY reference\r\n    --------------------------------------------\r\nclk_MMCME2_BASE_inst : MMCME2_BASE\r\n   generic map (\r\n      BANDWIDTH => \"OPTIMIZED\",      -- Jitter programming (OPTIMIZED, HIGH, LOW)\r\n      DIVCLK_DIVIDE   => 1,          -- Master division value (1-106)\r\n      CLKFBOUT_MULT_F => 8.0,        -- Multiply value for all CLKOUT (2.000-64.000).\r\n      CLKFBOUT_PHASE => 0.0,         -- Phase offset in degrees of CLKFB (-360.000-360.000).\r\n      CLKIN1_PERIOD => 10.0, -- Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).\r\n      -- CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)\r\n      CLKOUT0_DIVIDE_F => 4.0,       -- Divide amount for CLKOUT0 (1.000-128.000).\r\n      CLKOUT1_DIVIDE   => 1,\r\n      CLKOUT2_DIVIDE   => 1,\r\n      CLKOUT3_DIVIDE   => 1,\r\n      CLKOUT4_DIVIDE   => 1,\r\n      CLKOUT5_DIVIDE   => 1,\r\n      CLKOUT6_DIVIDE   => 1,\r\n      -- CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).\r\n      CLKOUT0_DUTY_CYCLE => 0.5,\r\n      CLKOUT1_DUTY_CYCLE => 0.5,\r\n      CLKOUT2_DUTY_CYCLE => 0.5,\r\n      CLKOUT3_DUTY_CYCLE => 0.5,\r\n      CLKOUT4_DUTY_CYCLE => 0.5,\r\n      CLKOUT5_DUTY_CYCLE => 0.5,\r\n      CLKOUT6_DUTY_CYCLE => 0.5,\r\n      -- CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).\r\n      CLKOUT0_PHASE => 0.0,\r\n      CLKOUT1_PHASE => 0.0,\r\n      CLKOUT2_PHASE => 0.0,\r\n      CLKOUT3_PHASE => 0.0,\r\n      CLKOUT4_PHASE => 0.0,\r\n      CLKOUT5_PHASE => 0.0,\r\n      CLKOUT6_PHASE => 0.0,\r\n      CLKOUT4_CASCADE => FALSE,  -- Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE)\r\n      REF_JITTER1 => 0.0,        -- Reference input jitter in UI (0.000-0.999).\r\n      STARTUP_WAIT => FALSE      -- Delays DONE until MMCM is locked (FALSE, TRUE)\r\n   )\r\n   port map (\r\n      -- Clock Outputs: 1-bit (each) output: User configurable clock outputs\r\n      CLKOUT0   => clk_200_raw,  -- 1-bit output: CLKOUT0\r\n      CLKOUT0B  => open,         -- 1-bit output: Inverted CLKOUT0\r\n      CLKOUT1   => open,         -- 1-bit output: CLKOUT1\r\n      CLKOUT1B  => open,         -- 1-bit output: Inverted CLKOUT1\r\n      CLKOUT2   => open,         -- 1-bit output: CLKOUT2\r\n      CLKOUT2B  => open,         -- 1-bit output: Inverted CLKOUT2\r\n      CLKOUT3   => open,         -- 1-bit output: CLKOUT3\r\n      CLKOUT3B  => open,         -- 1-bit output: Inverted CLKOUT3\r\n      CLKOUT4   => open,         -- 1-bit output: CLKOUT4\r\n      CLKOUT5   => open,         -- 1-bit output: CLKOUT5\r\n      CLKOUT6   => open,         -- 1-bit output: CLKOUT6\r\n      -- Feedback Clocks: 1-bit (each) output: Clock feedback ports\r\n      CLKFBOUT  => clkfb_1,      -- 1-bit output: Feedback clock\r\n      CLKFBOUTB => open,         -- 1-bit output: Inverted CLKFBOUT\r\n      -- Status Ports: 1-bit (each) output: MMCM status ports\r\n      LOCKED    => open,         -- 1-bit output: LOCK\r\n      -- Clock Inputs: 1-bit (each) input: Clock input\r\n      CLKIN1    => system_clk,   -- 1-bit input: Clock\r\n      -- Control Ports: 1-bit (each) input: MMCM control ports\r\n      PWRDWN    => '0',          -- 1-bit input: Power-down\r\n      RST       => '0',          -- 1-bit input: Reset\r\n      -- Feedback Clocks: 1-bit (each) input: Clock feedback ports\r\n      CLKFBIN   => clkfb_1       -- 1-bit input: Feedback clock\r\n   );\r\n\r\ni_BUFG: BUFG PORT MAP (\r\n        I => clk_200_raw,\r\n        O => clk_200\r\n    );\r\n   ------------------------------\r\n   -- Input Delay reference\r\n   --\r\n   -- These are tied to the delay instances  \r\n   -- by the IODELAY_GROUP attribute.\r\n   --------------------------------------------    \r\nIDELAYCTRL_inst : IDELAYCTRL\r\n    port map (\r\n        RDY    => open,    -- 1-bit output: Ready output\r\n        REFCLK => clk_200, -- 1-bit input:  Reference clock input\r\n        RST    => '0'      -- 1-bit input:  Active high reset input\r\n    );\r\n\r\n   --------------------------------\r\n   -- MMCM driven by the HDMI clock\r\n   --------------------------------\r\nhdmi_MMCME2_BASE_inst : MMCME2_BASE\r\n   generic map (\r\n      BANDWIDTH => \"OPTIMIZED\",      -- Jitter programming (OPTIMIZED, HIGH, LOW)\r\n      DIVCLK_DIVIDE   => 1,          -- Master division value (1-106)\r\n      CLKFBOUT_MULT_F => 5.0,        -- Multiply value for all CLKOUT (2.000-64.000).\r\n      CLKFBOUT_PHASE => 0.0,         -- Phase offset in degrees of CLKFB (-360.000-360.000).\r\n      CLKIN1_PERIOD => 12.5, --1000.0/148.5, -- Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).\r\n      -- CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)\r\n      CLKOUT0_DIVIDE_F => 5.0,       -- Divide amount for CLKOUT0 (1.000-128.000).\r\n      CLKOUT1_DIVIDE   => 5,\r\n      CLKOUT2_DIVIDE   => 1,\r\n      CLKOUT3_DIVIDE   => 1,\r\n      CLKOUT4_DIVIDE   => 1,\r\n      CLKOUT5_DIVIDE   => 1,\r\n      CLKOUT6_DIVIDE   => 1,\r\n      -- CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).\r\n      CLKOUT0_DUTY_CYCLE => 0.5,\r\n      CLKOUT1_DUTY_CYCLE => 0.5,\r\n      CLKOUT2_DUTY_CYCLE => 0.5,\r\n      CLKOUT3_DUTY_CYCLE => 0.5,\r\n      CLKOUT4_DUTY_CYCLE => 0.5,\r\n      CLKOUT5_DUTY_CYCLE => 0.5,\r\n      CLKOUT6_DUTY_CYCLE => 0.5,\r\n      -- CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).\r\n      CLKOUT0_PHASE => 0.0,\r\n      CLKOUT1_PHASE => 0.0,\r\n      CLKOUT2_PHASE => 0.0,\r\n      CLKOUT3_PHASE => 0.0,\r\n      CLKOUT4_PHASE => 0.0,\r\n      CLKOUT5_PHASE => 0.0,\r\n      CLKOUT6_PHASE => 0.0,\r\n      CLKOUT4_CASCADE => FALSE,  -- Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE)\r\n      REF_JITTER1 => 0.0,        -- Reference input jitter in UI (0.000-0.999).\r\n      STARTUP_WAIT => FALSE      -- Delays DONE until MMCM is locked (FALSE, TRUE)\r\n   )\r\n   port map (\r\n      -- Clock Outputs: 1-bit (each) output: User configurable clock outputs\r\n      CLKOUT0   => clk_pixel_raw,    -- 1-bit output: CLKOUT0\r\n      CLKOUT0B  => open,         -- 1-bit output: Inverted CLKOUT0\r\n      CLKOUT1   => clk_pixel_x1_raw, -- 1-bit output: CLKOUT1\r\n      CLKOUT1B  => open,         -- 1-bit output: Inverted CLKOUT1\r\n      CLKOUT2   => clk_pixel_x5_raw, -- 1-bit output: CLKOUT2\r\n      CLKOUT2B  => open,         -- 1-bit output: Inverted CLKOUT2\r\n      CLKOUT3   => open,         -- 1-bit output: CLKOUT3\r\n      CLKOUT3B  => open,         -- 1-bit output: Inverted CLKOUT3\r\n      CLKOUT4   => open,         -- 1-bit output: CLKOUT4\r\n      CLKOUT5   => open,         -- 1-bit output: CLKOUT5\r\n      CLKOUT6   => open,         -- 1-bit output: CLKOUT6\r\n      -- Feedback Clocks: 1-bit (each) output: Clock feedback ports\r\n      CLKFBOUT  => clkfb_2,       -- 1-bit output: Feedback clock\r\n      CLKFBOUTB => open,          -- 1-bit output: Inverted CLKFBOUT\r\n      -- Status Ports: 1-bit (each) output: MMCM status ports\r\n      LOCKED    => locked,        -- 1-bit output: LOCK\r\n      -- Clock Inputs: 1-bit (each) input: Clock input\r\n      CLKIN1    => hdmi_in_clk, -- 1-bit input: Clock\r\n      -- Control Ports: 1-bit (each) input: MMCM control ports\r\n      PWRDWN    => '0',           -- 1-bit input: Power-down\r\n      RST       => '0',           -- 1-bit input: Reset\r\n      -- Feedback Clocks: 1-bit (each) input: Clock feedback ports\r\n      CLKFBIN   => clkfb_2        -- 1-bit input: Feedback clock\r\n   );\r\n\r\n   ----------------------------------\r\n   -- Force the highest speed clock \r\n   -- through the IO clock buffer\r\n   -- (this is only rated for 600MHz!)\r\n   -----------------------------------  \r\nBUFIO_x5_inst : BUFIO\r\n   port map (\r\n      I => clk_pixel_x5_raw, -- 1-bit input: Clock input (connect to an IBUF or BUFMR).\r\n      O => clk_pixel_x5      -- 1-bit output: Clock output (connect to I/O clock loads).\r\n   );\r\n\r\nBUFIO_x1_inst : BUFG\r\n      port map (\r\n         I => clk_pixel_x1_raw, -- 1-bit input: Clock input (connect to an IBUF or BUFMR).\r\n         O => clk_pixel_x1      -- 1-bit output: Clock output (connect to I/O clock loads).\r\n      );\r\n\r\nBUFIO_inst : BUFG\r\n      port map (\r\n         I => clk_pixel_raw, -- 1-bit input: Clock input (connect to an IBUF or BUFMR).\r\n         O => clk_pixel      -- 1-bit output: Clock output (connect to I/O clock loads).\r\n      );\r\n      pixel_clk       <= clk_pixel;\r\n      pixel_io_clk_x1 <= clk_pixel_x1;\r\n      pixel_io_clk_x5 <= clk_pixel_x5;\r\n\r\nch0: input_channel Port map ( \r\n        clk_mgmt        => system_clk,\r\n        clk             => clk_pixel,\r\n        ce              => ser_ce,\r\n        clk_x1          => clk_pixel_x1,\r\n        clk_x5          => clk_pixel_x5,\r\n        serial          => hdmi_in_ch0,\r\n        invalid_symbol  => ch0_invalid_symbol,\r\n        symbol          => ch0_symbol,\r\n        ctl_valid       => ch0_ctl_valid,\r\n        ctl             => ch0_ctl,\r\n        terc4_valid     => ch0_terc4_valid,\r\n        terc4           => ch0_terc4,\r\n        guardband_valid => ch0_guardband_valid,\r\n        guardband       => ch0_guardband,\r\n        data_valid      => ch0_data_valid,\r\n        data            => ch0_data,\r\n        reset           => ser_reset,\r\n        symbol_sync     => ch0_symbol_sync);\r\n\r\nch1: input_channel Port map ( \r\n        clk_mgmt        => system_clk,\r\n        clk             => clk_pixel,\r\n        ce              => ser_ce,\r\n        clk_x1          => clk_pixel_x1,\r\n        clk_x5          => clk_pixel_x5,\r\n        serial          => hdmi_in_ch1,\r\n        symbol          => ch1_symbol,\r\n        invalid_symbol  => ch1_invalid_symbol,\r\n        ctl_valid       => ch1_ctl_valid,\r\n        ctl             => ch1_ctl,\r\n        terc4_valid     => ch1_terc4_valid,\r\n        terc4           => ch1_terc4,\r\n        guardband_valid => ch1_guardband_valid,\r\n        guardband       => ch1_guardband,\r\n        data_valid      => ch1_data_valid,\r\n        data            => ch1_data,\r\n        reset           => ser_reset,\r\n        symbol_sync     => ch1_symbol_sync);\r\n\r\nch2: input_channel Port map ( \r\n        clk_mgmt        => system_clk,\r\n        clk             => clk_pixel,\r\n        ce              => ser_ce,\r\n        clk_x1          => clk_pixel_x1,\r\n        clk_x5          => clk_pixel_x5,\r\n        serial          => hdmi_in_ch2,\r\n        invalid_symbol  => ch2_invalid_symbol,\r\n        symbol          => ch2_symbol,\r\n        ctl_valid       => ch2_ctl_valid,\r\n        ctl             => ch2_ctl,\r\n        terc4_valid     => ch2_terc4_valid,\r\n        terc4           => ch2_terc4,\r\n        guardband_valid => ch2_guardband_valid,\r\n        guardband       => ch2_guardband,\r\n        data_valid      => ch2_data_valid,\r\n        data            => ch2_data,\r\n        reset           => ser_reset,\r\n        symbol_sync     => ch2_symbol_sync);\r\n\r\n    symbol_sync_i <= ch0_symbol_sync and ch1_symbol_sync and ch2_symbol_sync;\r\n    \r\n    hdmi_detected <= not dvid_mode;\r\nhdmi_section_decode: process(clk_pixel)\r\n    begin\r\n        if rising_edge(clk_pixel) then\r\n            -------------------------------------------------------------------\r\n            -- Output the values depending on what sort of data block we are in\r\n            -------------------------------------------------------------------\r\n            if ch0_ctl_valid = '1' and ch1_ctl_valid = '1' and ch2_ctl_valid = '1' then\r\n                -------------------------------------------------------------------\r\n                -- As soon as we see avalid CTL symbols we are no longer in the   \r\n                -- video or aux data period it doesn't have any trailing guard band\r\n                -------------------------------------------------------------------\r\n                in_vdp    <= '0';\r\n                in_adp    <= '0';\r\n                in_dvid   <= '0';\r\n                raw_vsync <= ch0_ctl(1);\r\n                raw_hsync <= ch0_ctl(0);\r\n                raw_blank <= '1';            \r\n                raw_ch2   <= (others => '0');\r\n                raw_ch1   <= (others => '0');\r\n                raw_ch0   <= (others => '0');\r\n                last_was_ctl   <= '1';\r\n                adp_data_valid <= '0';\r\n            else\r\n                last_was_ctl <= '0';\r\n                adp_data_valid <= '0';\r\n                if in_vdp = '1' then\r\n                    raw_vsync <= '0';\r\n                    raw_hsync <= '0';\r\n                    raw_blank <= '0';            \r\n                    raw_ch2   <= ch2_data;\r\n                    raw_ch1   <= ch1_data;\r\n                    raw_ch0   <= ch0_data;\r\n                    if ch2_invalid_symbol = '1' or ch2_invalid_symbol = '1' or ch2_invalid_symbol = '1' then\r\n                        raw_ch2   <= x\"EF\";\r\n                        raw_ch1   <= x\"16\";\r\n                        raw_ch0   <= x\"16\";\r\n                    end if;\r\n            \r\n                elsif in_dvid = '1' then\r\n                    -- In the Video data period\r\n                    raw_vsync <= '0';\r\n                    raw_hsync <= '0';\r\n                    raw_blank <= '0';            \r\n                    raw_ch2   <= ch2_data;\r\n                    raw_ch1   <= ch1_data;\r\n                    raw_ch0   <= ch0_data;\r\n                elsif in_adp = '1' then\r\n                    -- In the Aux Data Period Period\r\n                    raw_vsync <= ch0_terc4(1);\r\n                    raw_hsync <= ch0_terc4(0);\r\n                    raw_blank <= '1';            \r\n                    raw_ch0   <= (others => '0');\r\n                    raw_ch1   <= (others => '0');\r\n                    raw_ch2   <= (others => '0');\r\n                    -- ADP data extraction\r\n                    adp_data_valid      <= '1';\r\n                    adp_header_bit      <= ch0_terc4(2);\r\n                    adp_frame_bit       <= ch0_terc4(3);\r\n                    adp_subpacket0_bits <= ch2_terc4(0) & ch1_terc4(0);\r\n                    adp_subpacket1_bits <= ch2_terc4(1) & ch1_terc4(1);\r\n                    adp_subpacket2_bits <= ch2_terc4(2) & ch1_terc4(2);\r\n                    adp_subpacket3_bits <= ch2_terc4(3) & ch1_terc4(3);\r\n                end if;\r\n            end if;\r\n               \r\n            ------------------------------------------------------------\r\n            -- We need to detect 8 ADP or VDP prefix characters in a row\r\n            ------------------------------------------------------------\r\n            vdp_prefix_detect <= vdp_prefix_detect(6 downto 0) & '0';\r\n            vdp_prefix_seen <= '0';\r\n            if ch0_ctl_valid = '1' and ch1_ctl_valid = '1' and ch1_ctl_valid = '1' then\r\n                if ch1_ctl = \"01\" and ch2_ctl = \"00\" then\r\n                    vdp_prefix_detect(0) <=  '1';\r\n                    if vdp_prefix_detect = \"01111111\" then\r\n                        vdp_prefix_seen <= '1';\r\n                    end if;\r\n                end if;\r\n            end if;\r\n                \r\n            ---------------------------------------------\r\n            -- See if we can detect the ADP guardband\r\n            --\r\n            -- The ADP guardband includes HSYNC and VSYNC\r\n            -- encoded in TERC4 coded in Ch0.\r\n            ---------------------------------------------\r\n            adp_prefix_detect <= adp_prefix_detect(6 downto 0) & '0';\r\n            adp_prefix_seen <= '0';\r\n            if ch0_ctl_valid = '1' and ch1_ctl_valid = '1' and ch1_ctl_valid = '1' then\r\n                if ch1_ctl = \"01\" and ch2_ctl = \"01\" then\r\n                    adp_prefix_detect(0) <= '1';\r\n                    if adp_prefix_detect = \"01111111\" then\r\n                        adp_prefix_seen <= '1';\r\n                    end if;\r\n                end if;\r\n            end if;\r\n            ---------------------------------------------\r\n            -- See if we can detect the ADP guardband\r\n            --\r\n            -- The ADP guardband includes HSYNC and VSYNC\r\n            -- encoded in TERC4 coded in Ch0 - annoying!\r\n            ---------------------------------------------\r\n            adp_guardband_detect <= '0';\r\n            if in_vdp = '0' and ch0_terc4_valid = '1' and ch1_guardband_valid = '1' and ch1_guardband_valid = '1' then\r\n                if ch0_terc4(3 downto 2) = \"11\" and ch1_guardband = \"0\" and ch2_guardband = \"0\" then\r\n                    raw_vsync <= ch0_terc4(1);\r\n                    raw_hsync <= ch0_terc4(0);\r\n                    adp_guardband_detect <= adp_prefix_seen;\r\n                    in_adp <= adp_guardband_detect AND (not in_adp) and (not in_vdp);\r\n                end if;\r\n            end if;\r\n            -----------------------------------------\r\n            -- See if we can detect the VDP guardband\r\n            -- This is pretty nices as the guard\r\n            -----------------------------------------\r\n            vdp_guardband_detect <= '0';                        \r\n            if ch0_guardband_valid = '1' and ch1_guardband_valid = '1' and ch2_guardband_valid = '1' then\r\n                -- TERC Coded for the VDP guard band.\r\n                if ch0_guardband = \"1\" and ch1_guardband = \"0\" and ch2_guardband = \"1\" then\r\n                   vdp_guardband_detect <= vdp_prefix_seen;\r\n                   in_vdp <= vdp_guardband_detect AND (not in_adp) and (not in_vdp);\r\n                   dvid_mode <= '0';\r\n                end if;\r\n            end if;\r\n            --------------------------------\r\n            -- Is this some DVID video data?\r\n            --------------------------------\r\n            if dvid_mode = '1' and last_was_ctl = '1' and ch0_data_valid = '1' and ch1_data_valid = '1' and ch2_data_valid = '1' then\r\n                in_dvid <= '1';\r\n            end if;\r\n            -------------------------------------------------------------\r\n            -- Is this an un-announced video data? If so we receiving \r\n            -- DVI-D data, and not HDMI \r\n            -------------------------------------------------------------\r\n            if ch0_data_valid = '1' and ch1_data_valid = '1' and ch2_data_valid = '1' \r\n                and last_was_ctl = '1' and vdp_prefix_seen = '0' and adp_prefix_seen = '0' then\r\n               dvid_mode <= '1';\r\n            end if;\r\n\r\n            ch0_invalid_symbol_1 <= ch0_invalid_symbol;\r\n            ch0_ctl_valid_1      <= ch0_ctl_valid;\r\n            ch0_ctl_1            <= ch0_ctl;\r\n            ch0_terc4_valid_1    <= ch0_terc4_valid;\r\n            ch0_terc4_1          <= ch0_terc4;\r\n            ch0_data_1           <= ch0_data;\r\n\r\n            ch1_invalid_symbol_1 <= ch1_invalid_symbol;\r\n            ch1_ctl_valid_1      <= ch1_ctl_valid;\r\n            ch1_ctl_1            <= ch1_ctl;\r\n            ch1_terc4_valid_1    <= ch1_terc4_valid;\r\n            ch1_terc4_1          <= ch1_terc4;\r\n            ch1_data_1           <= ch1_data;\r\n\r\n            ch2_invalid_symbol_1 <= ch2_invalid_symbol;\r\n            ch2_ctl_valid_1      <= ch2_ctl_valid;\r\n            ch2_ctl_1            <= ch2_ctl;\r\n            ch2_terc4_valid_1    <= ch2_terc4_valid;\r\n            ch2_terc4_1          <= ch2_terc4;\r\n            ch2_data_valid_1     <= ch2_data_valid;\r\n            ch2_data_1           <= ch2_data;\r\n        end if;\r\n    end process;\r\n    \r\n------------------------------------------\r\n-- Reset the receivers if PLL lock is lost\r\n------------------------------------------\r\nreset_proc: process(system_clk)\r\n    begin\r\n        if rising_edge(system_clk) then\r\n            if locked = '1' then\r\n                if reset_counter > 0 then\r\n                    reset_counter <= reset_counter-1;\r\n                end if;\r\n            else\r\n                reset_counter <= (others => '1');\r\n            end if;\r\n        end if;\r\n    end process;\r\n\r\nreset_proc2: process(clk_pixel)\r\n    begin\r\n        if rising_edge(clk_pixel) then\r\n            ser_reset <= reset_counter(reset_counter'high);\r\n            ser_ce    <= not ser_reset; \r\n        end if;\r\n    end process;\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/hdmi_io.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz<\r\n-- \r\n-- Module Name: hdmi_io - Behavioral\r\n--\r\n-- Description: Wrapper for input and output components of HDMI data stream\r\n--\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity hdmi_io is\r\n    port (\r\n        clk100        : in STD_LOGIC;\r\n        -------------------------------\r\n        -- Control signals\r\n        -------------------------------\r\n        clock_locked   : out std_logic;\r\n        data_synced    : out std_logic;\r\n        debug          : out std_logic_vector(7 downto 0);        \r\n        \r\n        -------------------------------\r\n        --HDMI input signals\r\n        -------------------------------\r\n        hdmi_rx_cec   : inout std_logic;\r\n        hdmi_rx_hpa   : out   std_logic;\r\n        hdmi_rx_scl   : in    std_logic;\r\n        hdmi_rx_sda   : inout std_logic;\r\n        hdmi_rx_txen  : out   std_logic;\r\n        hdmi_rx_clk_n : in    std_logic;\r\n        hdmi_rx_clk_p : in    std_logic;\r\n        hdmi_rx_n     : in    std_logic_vector(2 downto 0);\r\n        hdmi_rx_p     : in    std_logic_vector(2 downto 0);\r\n        \r\n        -------------\r\n        -- HDMI out\r\n        -------------\r\n        hdmi_tx_cec   : inout std_logic;\r\n        hdmi_tx_clk_n : out   std_logic;\r\n        hdmi_tx_clk_p : out   std_logic;\r\n        hdmi_tx_hpd   : in    std_logic;\r\n        hdmi_tx_rscl  : inout std_logic;\r\n        hdmi_tx_rsda  : inout std_logic;\r\n        hdmi_tx_p     : out   std_logic_vector(2 downto 0);\r\n        hdmi_tx_n     : out   std_logic_vector(2 downto 0);\r\n        \r\n        pixel_clk : out std_logic;\r\n        -------------------------------\r\n        -- VGA data recovered from HDMI\r\n        -------------------------------\r\n        in_hdmi_detected : out std_logic;\r\n        in_blank  : out std_logic;\r\n        in_hsync  : out std_logic;\r\n        in_vsync  : out std_logic;\r\n        in_red    : out std_logic_vector(7 downto 0);\r\n        in_green  : out std_logic_vector(7 downto 0);\r\n        in_blue   : out std_logic_vector(7 downto 0);\r\n        is_interlaced   : out std_logic;\r\n        is_second_field : out std_logic;\r\n        \r\n        -----------------------------------\r\n        -- VGA data to be converted to HDMI\r\n        -----------------------------------\r\n        out_blank : in  std_logic;\r\n        out_hsync : in  std_logic;\r\n        out_vsync : in  std_logic;\r\n        out_red   : in  std_logic_vector(7 downto 0);\r\n        out_green : in  std_logic_vector(7 downto 0);\r\n        out_blue  : in  std_logic_vector(7 downto 0);\r\n       -------------------------------------\r\n        -- Audio Levels\r\n        -------------------------------------\r\n        audio_channel : out std_logic_vector(2 downto 0);\r\n        audio_de      : out std_logic;\r\n        audio_sample  : out std_logic_vector(23 downto 0);\r\n        \r\n        -----------------------------------\r\n        -- For symbol dump or retransmit\r\n        -----------------------------------\r\n        symbol_sync  : out std_logic; -- indicates a fixed reference point in the frame.\r\n        symbol_ch0   : out std_logic_vector(9 downto 0);\r\n        symbol_ch1   : out std_logic_vector(9 downto 0);\r\n        symbol_ch2   : out std_logic_vector(9 downto 0)\r\n    );\r\nend entity;\r\n\r\narchitecture Behavioral of hdmi_io is\r\n    component edid_rom is\r\n    port ( clk      : in    std_logic;\r\n           sclk_raw : in    std_logic;\r\n           sdat_raw : inout std_logic;\r\n           edid_debug : out std_logic_vector(2 downto 0));\r\n    end component;\r\n\r\n    component hdmi_input is \r\n    port (\r\n        system_clk      : in  std_logic;\r\n\r\n        debug           : out std_logic_vector(5 downto 0);        \r\n        hdmi_detected : out std_logic;\r\n        \r\n        pixel_clk       : out std_logic;  -- Driven by BUFG\r\n        pixel_io_clk_x1 : out std_logic;  -- Driven by BUFFIO\r\n        pixel_io_clk_x5 : out std_logic;  -- Driven by BUFFIO\r\n    \r\n        -- HDMI input signals\r\n        hdmi_in_clk   : in    std_logic;\r\n        hdmi_in_ch0   : in    std_logic;\r\n        hdmi_in_ch1   : in    std_logic;\r\n        hdmi_in_ch2   : in    std_logic;\r\n    \r\n        -- Status\r\n        pll_locked   : out std_logic;\r\n        symbol_sync  : out std_logic;\r\n    \r\n        -- Raw data signals\r\n        raw_blank : out std_logic;\r\n        raw_hsync : out std_logic;\r\n        raw_vsync : out std_logic;\r\n        raw_ch0   : out std_logic_vector(7 downto 0);\r\n        raw_ch1   : out std_logic_vector(7 downto 0);\r\n        raw_ch2   : out std_logic_vector(7 downto 0);\r\n        -- ADP data\r\n        adp_data_valid      : out std_logic;\r\n        adp_header_bit      : out std_logic;\r\n        adp_frame_bit       : out std_logic;\r\n        adp_subpacket0_bits : out std_logic_vector(1 downto 0);\r\n        adp_subpacket1_bits : out std_logic_vector(1 downto 0);\r\n        adp_subpacket2_bits : out std_logic_vector(1 downto 0);\r\n        adp_subpacket3_bits : out std_logic_vector(1 downto 0);\r\n        -- For later reuse\r\n        symbol_ch0   : out std_logic_vector(9 downto 0);\r\n        symbol_ch1   : out std_logic_vector(9 downto 0);\r\n        symbol_ch2   : out std_logic_vector(9 downto 0)\r\n        \r\n    );\r\n    end component;\r\n    \r\n    -----------------------------------------------------\r\n    -- This is a half-baked solution to extracting data\r\n    -- from ADP packets - just pipe the data thorugh and \r\n    -- extract bits on the fly. A 'real' solution would\r\n    -- first verify the ECC codes and recover any errors\r\n    ------------------------------------------------------\r\n    component extract_video_infopacket_data is \r\n    port (\r\n        clk                 : in  std_logic;\r\n        -- ADP data\r\n        adp_data_valid      : in  std_logic;\r\n        adp_header_bit      : in  std_logic;\r\n        adp_frame_bit       : in  std_logic;\r\n        adp_subpacket0_bits : in  std_logic_vector(1 downto 0);\r\n        adp_subpacket1_bits : in  std_logic_vector(1 downto 0);\r\n        adp_subpacket2_bits : in  std_logic_vector(1 downto 0);\r\n        adp_subpacket3_bits : in  std_logic_vector(1 downto 0);\r\n        -- The stuff we need\r\n        input_is_YCbCr      : out std_Logic;\r\n        input_is_422        : out std_logic;\r\n        input_is_sRGB       : out std_Logic        \r\n    );\r\n    end component;\r\n    \r\n    signal adp_data_valid      : std_logic;\r\n    signal adp_header_bit      : std_logic;\r\n    signal adp_frame_bit       : std_logic;\r\n    signal adp_subpacket0_bits : std_logic_vector(1 downto 0);\r\n    signal adp_subpacket1_bits : std_logic_vector(1 downto 0);\r\n    signal adp_subpacket2_bits : std_logic_vector(1 downto 0);\r\n    signal adp_subpacket3_bits : std_logic_vector(1 downto 0);\r\n    signal is_interlaced_i     : std_logic;\r\n    signal is_second_field_i   : std_logic;\r\n\r\n    component extract_audio_samples is\r\n    Port ( clk                 : in STD_LOGIC;\r\n           adp_data_valid      : in STD_LOGIC;\r\n           adp_header_bit      : in STD_LOGIC;\r\n           adp_frame_bit       : in STD_LOGIC;\r\n           adp_subpacket0_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket1_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket2_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           adp_subpacket3_bits : in STD_LOGIC_VECTOR (1 downto 0);\r\n           audio_de            : out STD_LOGIC;\r\n           audio_channel       : out STD_LOGIC_VECTOR (2 downto 0);\r\n           audio_sample        : out STD_LOGIC_VECTOR (23 downto 0));\r\n    end component;\r\n\r\n\r\n    signal input_is_YCbCr      : std_Logic;\r\n    signal input_is_422        : std_logic;\r\n    signal input_is_sRGB       : std_Logic;\r\n\r\n    signal raw_blank : std_logic;\r\n    signal raw_hsync : std_logic;\r\n    signal raw_vsync : std_logic;\r\n    signal raw_ch2   : std_logic_vector(7 downto 0);  -- B or Cb\r\n    signal raw_ch1   : std_logic_vector(7 downto 0);  -- G or Y\r\n    signal raw_ch0   : std_logic_vector(7 downto 0);   -- R or Cr\r\n\r\n    component detect_interlace is\r\n        Port ( clk : in STD_LOGIC;\r\n               hsync           : in  std_logic;\r\n               vsync           : in  std_logic;\r\n               is_interlaced   : out std_logic;\r\n               is_second_field : out std_logic);\r\n    end component;\r\n\r\n    component expand_422_to_444 is\r\n    Port ( clk : in STD_LOGIC;\r\n        input_is_422 : in std_logic;\r\n        ------------------\r\n        -- Incoming pixels\r\n        ------------------\r\n        in_blank  : in std_logic;\r\n        in_hsync  : in std_logic;\r\n        in_vsync  : in std_logic;\r\n        in_ch2    : in std_logic_vector(7 downto 0);\r\n        in_ch1    : in std_logic_vector(7 downto 0);\r\n        in_ch0    : in std_logic_vector(7 downto 0);\r\n    \r\n        -------------------\r\n        -- Processed pixels\r\n        -------------------\r\n        out_blank : out std_logic;\r\n        out_hsync : out std_logic;\r\n        out_vsync : out std_logic;\r\n        out_U     : out std_logic_vector(11 downto 0);  -- B or Cb\r\n        out_V     : out std_logic_vector(11 downto 0);  -- G or Y\r\n        out_W     : out std_logic_vector(11 downto 0)   -- R or Cr\r\n    );\r\n    end component;\r\n\r\n    signal fourfourfour_blank : std_logic;\r\n    signal fourfourfour_hsync : std_logic;\r\n    signal fourfourfour_vsync : std_logic;\r\n    signal fourfourfour_U     : std_logic_vector(11 downto 0);  \r\n    signal fourfourfour_V     : std_logic_vector(11 downto 0);  \r\n    signal fourfourfour_W     : std_logic_vector(11 downto 0);  \r\n\r\n    component conversion_to_RGB is\r\n        port ( clk            : in std_Logic;\r\n               input_is_YCbCr : in std_Logic;\r\n               input_is_sRGB  : in std_Logic;\r\n               ------------------------\r\n               in_blank       : in std_logic;\r\n               in_hsync       : in std_logic;\r\n               in_vsync       : in std_logic;\r\n               in_U           : in std_logic_vector(11 downto 0);\r\n               in_V           : in std_logic_vector(11 downto 0);\r\n               in_W           : in std_logic_vector(11 downto 0);\r\n               ------------------------\r\n               out_blank      : out std_logic;\r\n               out_hsync      : out std_logic;\r\n               out_vsync      : out std_logic;\r\n               out_R          : out std_logic_vector(11 downto 0);\r\n               out_G          : out std_logic_vector(11 downto 0);\r\n               out_B          : out std_logic_vector(11 downto 0)\r\n          );\r\n    end component;\r\n    \r\n    signal rgb_blank : std_logic;\r\n    signal rgb_hsync : std_logic;\r\n    signal rgb_vsync : std_logic;\r\n    signal rgb_R     : std_logic_vector(11 downto 0);\r\n    signal rgb_G     : std_logic_vector(11 downto 0);  -- G or Y\r\n    signal rgb_B     : std_logic_vector(11 downto 0);   -- R or Cr\r\n\r\n    component DVID_output is\r\n    Port ( \r\n        pixel_clk       : in std_logic;  -- Driven by BUFG\r\n        pixel_io_clk_x1 : in std_logic;  -- Driven by BUFIO\r\n        pixel_io_clk_x5 : in std_logic;  -- Driven by BUFIO\r\n        \r\n        -- VGA Signals\r\n        vga_blank       : in  std_logic;\r\n        vga_hsync       : in  std_logic;\r\n        vga_vsync       : in  std_logic;\r\n        vga_red         : in  std_logic_vector(7 downto 0);\r\n        vga_blue        : in  std_logic_vector(7 downto 0);\r\n        vga_green       : in  std_logic_vector(7 downto 0);\r\n        data_valid      : in  std_logic;\r\n        \r\n        --- HDMI out\r\n        tmds_out_clk    : out   std_logic;\r\n        tmds_out_ch0    : out   std_logic;\r\n        tmds_out_ch1    : out   std_logic;\r\n        tmds_out_ch2    : out   std_logic\r\n    );\r\n    end component;\r\n   \r\n    -- Clocks for the pixel clock domain\r\n    signal pixel_clk_i     : std_logic;\r\n    signal pixel_io_clk_x1 : std_logic;\r\n    signal pixel_io_clk_x5 : std_logic;\r\n\r\n    -- The serial data\r\n    signal tmds_in_clk  : std_logic;\r\n    signal tmds_in_ch0  : std_logic;\r\n    signal tmds_in_ch1  : std_logic;\r\n    signal tmds_in_ch2  : std_logic;\r\n\r\n    signal tmds_out_clk : std_logic;\r\n    signal tmds_out_ch0 : std_logic;\r\n    signal tmds_out_ch1 : std_logic;\r\n    signal tmds_out_ch2 : std_logic;\r\n\r\n    signal detect_sr : std_logic_vector(7 downto 0) := (others => '0');\r\nbegin\r\n    pixel_clk <= pixel_clk_i;\r\n    hdmi_rx_hpa  <= '1';\r\n    hdmi_rx_txen <= '1';\r\n    hdmi_rx_cec  <= 'Z';\r\n\r\n    debug(7)          <= raw_hsync;\r\n    debug(6)          <= raw_vsync;\r\n    debug(5)          <= is_second_field_i;  \r\n    debug(4)          <= is_interlaced_i;      \r\n    debug(3 downto 0) <= (others => '0');\r\n\r\ni_edid_rom: edid_rom  port map (\r\n             clk      => clk100,\r\n             sclk_raw => hdmi_rx_scl,\r\n             sdat_raw => hdmi_rx_sda,\r\n             edid_debug => open);\r\n\r\n    ---------------------\r\n    -- Input buffers\r\n    ---------------------\r\nin_clk_buf: IBUFDS generic map ( IOSTANDARD => \"TMDS_33\")\r\n port map ( I  => hdmi_rx_clk_p, IB => hdmi_rx_clk_n, O => tmds_in_clk);\r\n \r\nin_rx0_buf: IBUFDS generic map ( IOSTANDARD => \"TMDS_33\")\r\n port map ( I  => hdmi_rx_p(0),  IB => hdmi_rx_n(0),  O  => tmds_in_ch0);\r\n\r\nin_rx1_buf: IBUFDS generic map ( IOSTANDARD => \"TMDS_33\")\r\n port map ( I  => hdmi_rx_p(1),  IB => hdmi_rx_n(1),  O  => tmds_in_ch1);\r\n\r\nin_rx2_buf: IBUFDS generic map ( IOSTANDARD => \"TMDS_33\")\r\n port map ( I  => hdmi_rx_p(2),  IB => hdmi_rx_n(2),  O  => tmds_in_ch2);\r\n\r\ni_hdmi_input : hdmi_input port map (\r\n        system_clk      => clk100,\r\n        debug           => open,\r\n        -- Pixel and serializer clocks \r\n        pixel_clk       => pixel_clk_i,\r\n        pixel_io_clk_x1 => pixel_io_clk_x1,\r\n        pixel_io_clk_x5 => pixel_io_clk_x5,    \r\n        --- HDMI input signals\r\n        hdmi_in_clk   => tmds_in_clk,\r\n        hdmi_in_ch0   => tmds_in_ch0,\r\n        hdmi_in_ch1   => tmds_in_ch1,\r\n        hdmi_in_ch2   => tmds_in_ch2,\r\n        -- are the HDMI symbols in sync? \r\n        symbol_sync   => data_synced,\r\n        pll_locked    => clock_locked, \r\n        -- VGA internal Signals\r\n        hdmi_detected => in_hdmi_detected,\r\n        raw_blank     => raw_blank,\r\n        raw_hsync     => raw_hsync,\r\n        raw_vsync     => raw_vsync,\r\n        raw_ch2       => raw_ch2,\r\n        raw_ch1       => raw_ch1,\r\n        raw_ch0       => raw_ch0,    \r\n        -- ADP data\r\n        adp_data_valid      => adp_data_valid,\r\n        adp_header_bit      => adp_header_bit,\r\n        adp_frame_bit       => adp_frame_bit,\r\n        adp_subpacket0_bits => adp_subpacket0_bits,\r\n        adp_subpacket1_bits => adp_subpacket1_bits,\r\n        adp_subpacket2_bits => adp_subpacket2_bits,\r\n        adp_subpacket3_bits => adp_subpacket3_bits,\r\n        -- For later reuse\r\n        symbol_ch0 => symbol_ch0,\r\n        symbol_ch1 => symbol_ch1,\r\n        symbol_ch2 => symbol_ch2\r\n    );\r\n\r\n    -------------------------------------\r\n    -- If the input data is in 422 format \r\n    -- then convert it to 12-bit 444 data\r\n    -------------------------------------\r\ni_expand_422_to_444: expand_422_to_444 Port map ( \r\n        clk          => pixel_clk_i,\r\n        input_is_422 => input_is_422,\r\n        ------------------\r\n        -- Incoming raw data\r\n        ------------------\r\n        in_blank  => raw_blank,\r\n        in_hsync  => raw_hsync,\r\n        in_vsync  => raw_vsync,\r\n        in_ch2    => raw_ch2,\r\n        in_ch1    => raw_ch1,\r\n        in_ch0    => raw_ch0,\r\n    \r\n        -------------------\r\n        -- Processed pixels\r\n        -------------------\r\n        out_blank => fourfourfour_blank,\r\n        out_hsync => fourfourfour_hsync,\r\n        out_vsync => fourfourfour_vsync,\r\n        out_U     => fourfourfour_U,\r\n        out_V     => fourfourfour_V,\r\n        out_W     => fourfourfour_W\r\n    );\r\n\r\n    is_interlaced   <= is_interlaced_i;\r\n    is_second_field <= is_second_field_i; \r\ni_detect_interlace: detect_interlace Port map ( \r\n    clk             => pixel_clk_i,\r\n    hsync           => raw_hsync,\r\n    vsync           => raw_vsync,\r\n    is_interlaced   => is_interlaced_i,\r\n    is_second_field => is_second_field_i);\r\n\r\ni_conversion_to_RGB: conversion_to_RGB \r\n    port map (\r\n           clk              => pixel_clk_i,\r\n           ------------------------\r\n           input_is_YCbCr   => input_is_YCbCr,\r\n           input_is_sRGB    => input_is_sRGB,\r\n           in_blank         => fourfourfour_blank,\r\n           in_hsync         => fourfourfour_hsync,\r\n           in_vsync         => fourfourfour_vsync,\r\n           in_U             => fourfourfour_U,\r\n           in_V             => fourfourfour_V,\r\n           in_W             => fourfourfour_W,\r\n           ------------------------\r\n           out_blank        => rgb_blank,\r\n           out_hsync        => rgb_hsync,\r\n           out_vsync        => rgb_vsync,\r\n           out_R            => rgb_R,\r\n           out_G            => rgb_G,\r\n           out_B            => rgb_B\r\n    );\r\n\r\n    -----------------------------------------\r\n    -- Colour space conversion yet to be done\r\n    -----------------------------------------\r\n    in_blank <= rgb_blank;\r\n    in_hsync <= rgb_hsync;\r\n    in_vsync <= rgb_vsync;\r\n    in_blue  <= rgb_B(11 downto 4);\r\n    in_green <= rgb_G(11 downto 4);\r\n    in_red   <= rgb_R(11 downto 4);\r\n\r\n    ------------------------------------------------\r\n    -- Processing the non-video data #1\r\n    -- Extracting the Video Infopacket data we need\r\n    -- to correctly convert the video data\r\n    ------------------------------------------------\r\ni_extract_video_infopacket_data: extract_video_infopacket_data port map (\r\n    clk                 => pixel_clk_i,\r\n    -- ADP data\r\n    adp_data_valid      => adp_data_valid,\r\n    adp_header_bit      => adp_header_bit,\r\n    adp_frame_bit       => adp_frame_bit,\r\n    adp_subpacket0_bits => adp_subpacket0_bits,\r\n    adp_subpacket1_bits => adp_subpacket1_bits,\r\n    adp_subpacket2_bits => adp_subpacket2_bits,\r\n    adp_subpacket3_bits => adp_subpacket3_bits,\r\n    -- The stuff we need\r\n    input_is_YCbCr      => input_is_YCbCr,\r\n    input_is_422        => input_is_422,\r\n    input_is_sRGB       => input_is_sRGB \r\n);\r\n    ------------------------------------------------\r\n    -- Processing the non-video data #2\r\n    -- Extracting the Audio samples so we can display\r\n    -- level menters on the screen\r\n    ------------------------------------------------\r\ni_extract_audio_samples: extract_audio_samples PORT MAP (\r\n       clk                 => pixel_clk_i,\r\n       -- ADP data\r\n       adp_data_valid      => adp_data_valid,\r\n       adp_header_bit      => adp_header_bit,\r\n       adp_frame_bit       => adp_frame_bit,\r\n       adp_subpacket0_bits => adp_subpacket0_bits,\r\n       adp_subpacket1_bits => adp_subpacket1_bits,\r\n       adp_subpacket2_bits => adp_subpacket2_bits,\r\n       adp_subpacket3_bits => adp_subpacket3_bits,\r\n       -- The stuff we need\r\n       audio_de            => audio_de,\r\n       audio_channel       => audio_channel,\r\n       audio_sample        => audio_sample);\r\n\r\n------------------------------------------------\r\n-- Outputting video data\r\n-----------------------------------------------\r\ni_DVID_output: DVID_output port map ( \r\n        pixel_clk       => pixel_clk_i,\r\n        pixel_io_clk_x1 => pixel_io_clk_x1,\r\n        pixel_io_clk_x5 => pixel_io_clk_x5,\r\n        \r\n        data_valid      => '1',\r\n        -- VGA Signals\r\n        vga_blank     => out_blank,\r\n        vga_hsync     => out_hsync,\r\n        vga_vsync     => out_vsync,\r\n        vga_red       => out_red,\r\n        vga_blue      => out_blue,\r\n        vga_green     => out_green,\r\n        \r\n        --- HDMI out\r\n        tmds_out_clk  => tmds_out_clk,\r\n        tmds_out_ch0  => tmds_out_ch0,\r\n        tmds_out_ch1  => tmds_out_ch1,\r\n        tmds_out_ch2  => tmds_out_ch2\r\n    );\r\n\r\n    -----------------------------\r\n    -- Other HDMI control signals\r\n    -----------------------------\r\n    hdmi_tx_rsda  <= 'Z';\r\n    hdmi_tx_cec   <= 'Z';\r\n    hdmi_tx_rscl  <= '1';\r\n\r\n    -----------------\r\n    -- Output buffers\r\n    -----------------\r\nout_clk_buf: OBUFDS generic map ( IOSTANDARD => \"TMDS_33\",  SLEW => \"FAST\")\r\n    port map ( O  => hdmi_tx_clk_p, OB => hdmi_tx_clk_n, I => tmds_out_clk);\r\n    \r\nout_tx0_buf: OBUFDS generic map ( IOSTANDARD => \"TMDS_33\",  SLEW => \"FAST\")\r\n    port map ( O  => hdmi_tx_p(0), OB => hdmi_tx_n(0), I  => tmds_out_ch0);\r\n\r\nout_tx1_buf: OBUFDS generic map ( IOSTANDARD => \"TMDS_33\",  SLEW => \"FAST\")\r\n    port map ( O  => hdmi_tx_p(1), OB => hdmi_tx_n(1), I  => tmds_out_ch1);\r\n\r\nout_tx2_buf: OBUFDS generic map ( IOSTANDARD => \"TMDS_33\",  SLEW => \"FAST\")\r\n    port map ( O  => hdmi_tx_p(2), OB => hdmi_tx_n(2), I  => tmds_out_ch2);\r\n\r\n    -- Detect when VSYNC is held high for 8 cycles, so we can synchronise the capture of symbols \r\nprocess(pixel_clk_i)\r\n    begin\r\n        if rising_edge(pixel_clk_i) then\r\n            if detect_sr = \"11111111\" and raw_vsync = '0' then\r\n                symbol_sync <= '1';\r\n            else    \r\n                symbol_sync <= '0';\r\n            end if;\r\n            detect_sr <= detect_sr(6 downto 0) & raw_vsync; \r\n        end if;\r\n    end process;\r\n\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/input_channel.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Create Date: 30.07.2015 23:11:34\r\n-- Module Name: input_channel - Behavioral\r\n--\r\n-- Description: Receiving one of the three HDMI input channels. and decoding \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity input_channel is\r\n    Port ( clk_mgmt        : in STD_LOGIC;\r\n           clk             : in  STD_LOGIC;\r\n           clk_x1          : in  STD_LOGIC;\r\n           clk_x5          : in  STD_LOGIC;\r\n           serial          : in  STD_LOGIC;\r\n           reset           : in  std_logic;\r\n           ce              : in  STD_LOGIC;\r\n           invalid_symbol  : out std_logic;\r\n           symbol          : out std_logic_vector (9 downto 0);\r\n           ctl_valid       : out std_logic;\r\n           ctl             : out std_logic_vector (1 downto 0);\r\n           terc4_valid     : out std_logic;\r\n           terc4           : out std_logic_vector (3 downto 0);\r\n           guardband_valid : out std_logic;\r\n           guardband       : out std_logic_vector (0 downto 0);\r\n           data_valid      : out std_logic;\r\n           data            : out std_logic_vector (7 downto 0);\r\n           symbol_sync     : out STD_LOGIC);\r\nend input_channel;\r\n\r\narchitecture Behavioral of input_channel is\r\n    component deserialiser_1_to_10 is\r\n    Port ( clk_mgmt    : in  std_logic;\r\n           delay_ce    : in std_logic;\r\n           delay_count : in std_logic_vector (4 downto 0);\r\n           ce          : in  STD_LOGIC;\r\n           clk         : in std_logic;\r\n           clk_x1      : in std_logic;\r\n           bitslip     : in std_logic;\r\n           clk_x5      : in std_logic;\r\n           reset       : in std_logic;\r\n           serial      : in std_logic;\r\n           data        : out std_logic_vector (9 downto 0));\r\n    end component;\r\n    \r\n    component TMDS_decoder is\r\n    Port ( clk             : in  std_logic;\r\n           symbol          : in  std_logic_vector (9 downto 0);\r\n           invalid_symbol  : out std_logic;\r\n           ctl_valid       : out std_logic;\r\n           ctl             : out std_logic_vector (1 downto 0);\r\n           terc4_valid     : out std_logic;\r\n           terc4           : out std_logic_vector (3 downto 0);\r\n           guardband_valid : out std_logic;\r\n           guardband       : out std_logic_vector (0 downto 0);\r\n           data_valid      : out std_logic;\r\n           data            : out std_logic_vector (7 downto 0));\r\n    end component;\r\n    \r\n    component alignment_detect is\r\n        Port ( clk            : in STD_LOGIC;\r\n               invalid_symbol : in STD_LOGIC;\r\n               delay_count    : out STD_LOGIC_VECTOR(4 downto 0);\r\n               delay_ce       : out STD_LOGIC;\r\n               bitslip        : out STD_LOGIC;\r\n               symbol_sync    : out STD_LOGIC);\r\n    end component;\r\n\r\n    signal delay_count     : std_logic_vector (4 downto 0);\r\n    signal delay_ce        : STD_LOGIC;\r\n    signal bitslip         : STD_LOGIC;\r\n    signal symbol_sync_i   : STD_LOGIC;\r\n    signal symbol_i        : std_logic_vector (9 downto 0);\r\n    signal invalid_symbol_i: STD_LOGIC;\r\n\r\nbegin\r\n    symbol <= symbol_i;\r\n\r\ni_deser: deserialiser_1_to_10 port map (\r\n        clk_mgmt    => clk_mgmt,\r\n        delay_ce    => delay_ce,\r\n        delay_count => delay_count,\r\n        ce          => ce,\r\n        clk         => clk,\r\n        clk_x1      => clk_x1,\r\n        bitslip     => bitslip,\r\n        clk_x5      => clk_x5,\r\n        reset       => reset,\r\n        serial      => serial,\r\n        data        => symbol_i);\r\n\r\ni_decoder: tmds_decoder port map (\r\n        clk             => clk,\r\n        symbol          => symbol_i,\r\n        invalid_symbol  => invalid_symbol_i,\r\n        ctl_valid       => ctl_valid,\r\n        ctl             => ctl,\r\n        terc4_valid     => terc4_valid,\r\n        terc4           => terc4,\r\n        guardband_valid => guardband_valid,\r\n        guardband       => guardband,\r\n        data_valid      => data_valid,\r\n        data            => data\r\n    );\r\n    \r\n    invalid_symbol <= invalid_symbol_i;\r\n     \r\ni_alignment_detect: alignment_detect port map (\r\n           clk            => clk,\r\n           invalid_symbol => invalid_symbol_i,\r\n           delay_count    => delay_count,\r\n           delay_ce       => delay_ce,\r\n           bitslip        => bitslip,\r\n           symbol_sync    => symbol_sync);\r\n\r\nend Behavioral;\r\n"
  },
  {
    "path": "src/line_delay.vhd",
    "content": "----------------------------------------------------------------------------------\n-- Engineer: Mike Field <hamster@snap.net.nz> \n-- \n-- Module Name: line_delay - Behavioral\n--\n-- Description: Delay the video signal by one line, as measured by the rising \n--              edge on hsync. This module works for line lengths of between\n--              around 510 and around 2500 (needed for 640x480 through\n--              1920x1080.  \n--               \n------------------------------------------------------------------------------------\n-- The MIT License (MIT)\n-- \n-- Copyright (c) 2015 Michael Alan Field\n-- \n-- Permission is hereby granted, free of charge, to any person obtaining a copy\n-- of this software and associated documentation files (the \"Software\"), to deal\n-- in the Software without restriction, including without limitation the rights\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n-- copies of the Software, and to permit persons to whom the Software is\n-- furnished to do so, subject to the following conditions:\n-- \n-- The above copyright notice and this permission notice shall be included in\n-- all copies or substantial portions of the Software.\n-- \n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n-- THE SOFTWARE.\n------------------------------------------------------------------------------------\n----- Want to say thanks? ----------------------------------------------------------\n------------------------------------------------------------------------------------\n--\n-- This design has taken many hours - with the industry metric of 30 lines\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\n-- to share it if you can make use of it. It is released under the MIT license,\n-- so you are not under any onus to say thanks, but....\n-- \n-- If you what to say thanks for this design how about trying PayPal?\n--  Educational use - Enough for a beer\n--  Hobbyist use    - Enough for a pizza\n--  Research use    - Enough to take the family out to dinner\n--  Commercial use  - A weeks pay for an engineer (I wish!)\n--\n----------------------------------------------------------------------------------\n\n\nlibrary IEEE;\nuse IEEE.STD_LOGIC_1164.ALL;\nuse IEEE.NUMERIC_STD.ALL;\n\nentity line_delay is\n    Port ( clk : in STD_LOGIC;\n           -------------------------------\n           -- VGA data recovered from HDMI\n           -------------------------------\n           in_blank  : in std_logic;\n           in_hsync  : in std_logic;\n           in_vsync  : in std_logic;\n           in_red    : in std_logic_vector(7 downto 0);\n           in_green  : in std_logic_vector(7 downto 0);\n           in_blue   : in std_logic_vector(7 downto 0);\n     \n           -----------------------------------\n           -- VGA data to be converted to HDMI\n           -----------------------------------\n           out_blank : out std_logic;\n           out_hsync : out std_logic;\n           out_vsync : out std_logic;\n           out_red   : out std_logic_vector(7 downto 0);\n           out_green : out std_logic_vector(7 downto 0);\n           out_blue  : out std_logic_vector(7 downto 0));\nend line_delay;\n\narchitecture Behavioral of line_delay is\n    type mem_block is array (0 to 511) of std_logic_vector(26 downto 0);\n    signal mem_0 : mem_block := (others => (others => '0'));\n    signal mem_1 : mem_block := (others => (others => '0'));\n    signal mem_2 : mem_block := (others => (others => '0'));\n    signal mem_3 : mem_block := (others => (others => '0'));\n    signal mem_4 : mem_block := (others => (others => '0'));\n    \n    signal wr_addr    : unsigned(8 downto 0) := (others =>'1');\n    signal offset_0   : unsigned(8 downto 0) := (others =>'1');\n    signal offset_1   : unsigned(8 downto 0) := (others =>'1');\n    signal offset_2   : unsigned(8 downto 0) := (others =>'1');\n    signal offset_3   : unsigned(8 downto 0) := (others =>'1');\n    signal offset_4   : unsigned(8 downto 0) := (others =>'1');\n\n    signal width      : unsigned(11 downto 0) := (others =>'0');\n    signal line_count : unsigned(11 downto 0) := (others =>'0');\n    signal last_hsync : std_logic := '0';\n    signal mid_0      : std_logic_vector(26 downto 0) := (others =>'0');\n    signal mid_1      : std_logic_vector(26 downto 0) := (others =>'0');\n    signal mid_2      : std_logic_vector(26 downto 0) := (others =>'0');\n    signal mid_3      : std_logic_vector(26 downto 0) := (others =>'0');\nbegin\n\nprocess(clk)\n    variable mem_4_out : std_logic_vector(26 downto 0);\n    variable temp      : unsigned(11 downto 0) := (others =>'1');\n    begin\n        if rising_edge(clk) then\n            ------------------------------------------------ \n            -- Retreive the value from the end of the delay\n            -- and break out the signals\n            ------------------------------------------------ \n            mem_4_out := mem_4(to_integer(wr_addr+offset_4));\n            out_red   <= mem_4_out(26 downto 19);\n            out_green <= mem_4_out(18 downto 11);\n            out_blue  <= mem_4_out(10 downto  3);\n            out_blank <= mem_4_out(2);\n            out_hsync <= mem_4_out(1);\n            out_vsync <= mem_4_out(0);\n            \n            -------------------------------------------------\n            -- Move everything through the five memory blocks\n            -------------------------------------------------\n            mem_4(to_integer(wr_addr)) <= mid_3;\n            mid_3                      <= mem_3(to_integer(wr_addr+offset_3));\n            mem_3(to_integer(wr_addr)) <= mid_2;\n            mid_2                      <= mem_2(to_integer(wr_addr+offset_2));\n            mem_2(to_integer(wr_addr)) <= mid_1;\n            mid_1                      <= mem_1(to_integer(wr_addr+offset_1));\n            mem_1(to_integer(wr_addr)) <= mid_0;\n            mid_0                      <= mem_0(to_integer(wr_addr+offset_0));\n            mem_0(to_integer(wr_addr)) <= in_red & in_green & in_blue & in_blank & in_hsync & in_vsync;\n            wr_addr <= wr_addr - 1;\n            if in_hsync = '1' and last_hsync ='0' then\n                width <= line_count;\n                line_count <= (others => '0');\n            else\n                line_count <=line_count + 1;\n            end if;\n            \n            -------------------------------------------------------------\n            -- Update the offsets every cycle, not that we really need to\n            -- This improves the timing as we have less logic\n            -------------------------------------------------------------\n            offset_0 <= to_unsigned(508,9);\n            temp := width-512+0; offset_1 <= temp(10 downto 2);\n            temp := width-512+1; offset_2 <= temp(10 downto 2);\n            temp := width-512+2; offset_3 <= temp(10 downto 2);\n            temp := width-512+3; offset_4 <= temp(10 downto 2);\n             \n            last_hsync <= in_hsync;\n        end if;\n    end process;\n\nend Behavioral;\n"
  },
  {
    "path": "src/pixel_processing.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hasmter@snap.net.nz> \r\n-- \r\n-- Module Name: pixel_processing - Behavioral\r\n--\r\n-- Description: Where you can do processing on the raw pixel data\r\n--\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity pixel_processing is\r\n    Port ( clk : in STD_LOGIC;\r\n            -------------------------------\r\n            -- VGA data recovered from HDMI\r\n            -------------------------------\r\n            in_blank  : in std_logic;\r\n            in_hsync  : in std_logic;\r\n            in_vsync  : in std_logic;\r\n            in_red    : in std_logic_vector(7 downto 0);\r\n            in_green  : in std_logic_vector(7 downto 0);\r\n            in_blue   : in std_logic_vector(7 downto 0);\r\n            is_interlaced   : in std_logic;\r\n            is_second_field : in std_logic;\r\n            -----------------------------------\r\n            -- VGA data to be converted to HDMI\r\n            -----------------------------------\r\n            out_blank : out std_logic;\r\n            out_hsync : out std_logic;\r\n            out_vsync : out std_logic;\r\n            out_red   : out std_logic_vector(7 downto 0);\r\n            out_green : out std_logic_vector(7 downto 0);\r\n            out_blue  : out std_logic_vector(7 downto 0);\r\n            ------------------------------------\r\n            -- Audio only comes in..\r\n            ------------------------------------\r\n            audio_channel : in std_logic_vector(2 downto 0);\r\n            audio_de      : in std_logic;\r\n            audio_sample  : in std_logic_vector(23 downto 0);\r\n      \r\n            ----------------------------------\r\n            -- Controls\r\n            ----------------------------------   \r\n            switches : in std_logic_vector(7 downto 0)\r\n    );\r\nend pixel_processing;\r\n\r\narchitecture Behavioral of pixel_processing is\r\n    component audio_to_db is\r\n    Port ( clk           : in STD_LOGIC;\r\n           in_channel    : in STD_LOGIC_VECTOR (2 downto 0);\r\n           in_de         : in STD_LOGIC;\r\n           in_sample     : in STD_LOGIC_VECTOR (23 downto 0);\r\n           out_channel   : out STD_LOGIC_VECTOR (2 downto 0);\r\n           out_de        : out STD_LOGIC;\r\n           out_level     : out STD_LOGIC_VECTOR (5 downto 0));\r\n    end component;\r\n\r\n    signal level_channel  : std_logic_vector(2 downto 0);\r\n    signal level_de       : std_logic;\r\n    signal level          : std_logic_vector(5 downto 0);\r\n\r\n    component audio_meters is\r\n    Port ( clk : in STD_LOGIC;\r\n           -------------------------------\r\n           -- VGA data recovered from HDMI\r\n           -------------------------------\r\n           in_blank  : in std_logic;\r\n           in_hsync  : in std_logic;\r\n           in_vsync  : in std_logic;\r\n           in_red    : in std_logic_vector(7 downto 0);\r\n           in_green  : in std_logic_vector(7 downto 0);\r\n           in_blue   : in std_logic_vector(7 downto 0);\r\n           is_interlaced   : in std_logic;\r\n           is_second_field : in std_logic;\r\n            \r\n           -----------------------------------\r\n           -- VGA data to be converted to HDMI\r\n           -----------------------------------\r\n           out_blank : out std_logic;\r\n           out_hsync : out std_logic;\r\n           out_vsync : out std_logic;\r\n           out_red   : out std_logic_vector(7 downto 0);\r\n           out_green : out std_logic_vector(7 downto 0);\r\n           out_blue  : out std_logic_vector(7 downto 0);\r\n           \r\n           -------------------------------------\r\n           -- Audio Levels\r\n           -------------------------------------\r\n           signal audio_channel : in std_logic_vector(2 downto 0);\r\n           signal audio_de      : in std_logic;\r\n           signal audio_level   : in std_logic_vector(5 downto 0)\r\n    );\r\n    end component;\r\n\r\n    component edge_enhance is\r\n    Port ( clk : in STD_LOGIC;\r\n           enable_feature   : in std_logic;\r\n           -------------------------------\r\n           -- VGA data recovered from HDMI\r\n           -------------------------------\r\n           in_blank  : in std_logic;\r\n           in_hsync  : in std_logic;\r\n           in_vsync  : in std_logic;\r\n           in_red    : in std_logic_vector(7 downto 0);\r\n           in_green  : in std_logic_vector(7 downto 0);\r\n           in_blue   : in std_logic_vector(7 downto 0);\r\n            \r\n           -----------------------------------\r\n           -- VGA data to be converted to HDMI\r\n           -----------------------------------\r\n           out_blank : out std_logic;\r\n           out_hsync : out std_logic;\r\n           out_vsync : out std_logic;\r\n           out_red   : out std_logic_vector(7 downto 0);\r\n           out_green : out std_logic_vector(7 downto 0);\r\n           out_blue  : out std_logic_vector(7 downto 0)\r\n    );\r\n    end component;\r\n\r\n    component guidelines is\r\n    Port ( clk : in STD_LOGIC;\r\n           enable_feature   : in std_logic;\r\n           -------------------------------\r\n           -- VGA data recovered from HDMI\r\n           -------------------------------\r\n           in_blank  : in std_logic;\r\n           in_hsync  : in std_logic;\r\n           in_vsync  : in std_logic;\r\n           in_red    : in std_logic_vector(7 downto 0);\r\n           in_green  : in std_logic_vector(7 downto 0);\r\n           in_blue   : in std_logic_vector(7 downto 0);\r\n           is_interlaced   : in std_logic;\r\n           is_second_field : in std_logic;\r\n            \r\n           -----------------------------------\r\n           -- VGA data to be converted to HDMI\r\n           -----------------------------------\r\n           out_blank : out std_logic;\r\n           out_hsync : out std_logic;\r\n           out_vsync : out std_logic;\r\n           out_red   : out std_logic_vector(7 downto 0);\r\n           out_green : out std_logic_vector(7 downto 0);\r\n           out_blue  : out std_logic_vector(7 downto 0)\r\n    );\r\n    end component;\r\n    \r\n    signal b_blank : std_logic;\r\n    signal b_hsync : std_logic;\r\n    signal b_vsync : std_logic;\r\n    signal b_red   : std_logic_vector(7 downto 0);\r\n    signal b_green : std_logic_vector(7 downto 0);\r\n    signal b_blue  : std_logic_vector(7 downto 0);\r\n\r\n    signal c_blank : std_logic;\r\n    signal c_hsync : std_logic;\r\n    signal c_vsync : std_logic;\r\n    signal c_red   : std_logic_vector(7 downto 0);\r\n    signal c_green : std_logic_vector(7 downto 0);\r\n    signal c_blue  : std_logic_vector(7 downto 0);\r\n\r\nbegin\r\n\r\ni_audio_to_db: audio_to_db port map (\r\n        clk            => clk,\r\n\r\n        in_channel     => audio_channel,\r\n        in_de          => audio_de,\r\n        in_sample      => audio_sample,\r\n \r\n        out_channel    => level_channel,\r\n        out_de         => level_de,\r\n        out_level      => level\r\n    );\r\n\r\ni_edge_enhance: edge_enhance Port map ( \r\n        clk       => clk,\r\n        \r\n        enable_feature => switches(0),\r\n\r\n        in_blank  => in_blank,\r\n        in_hsync  => in_hsync,\r\n        in_vsync  => in_vsync,\r\n        in_red    => in_red,\r\n        in_green  => in_green,\r\n        in_blue   => in_blue,\r\n       \r\n        out_blank => b_blank,\r\n        out_hsync => b_hsync,\r\n        out_vsync => b_vsync,\r\n        out_red   => b_red,\r\n        out_green => b_green,\r\n        out_blue  => b_blue\r\n    );\r\n\r\ni_audio_meters: audio_meters Port map ( \r\n        clk       => clk,\r\n        in_blank  => b_blank,\r\n        in_hsync  => b_hsync,\r\n        in_vsync  => b_vsync,\r\n        in_red    => b_red,\r\n        in_green  => b_green,\r\n        in_blue   => b_blue,\r\n        is_interlaced => is_interlaced,\r\n        is_second_field => is_second_field,\r\n       \r\n        out_blank => c_blank,\r\n        out_hsync => c_hsync,\r\n        out_vsync => c_vsync,\r\n        out_red   => c_red,\r\n        out_green => c_green,\r\n        out_blue  => c_blue,\r\n        \r\n        audio_channel => level_channel,\r\n        audio_de      => level_de,\r\n        audio_level   => level\r\n    );\r\n\r\n\r\ni_guidelines: guidelines Port map ( \r\n        clk       => clk,\r\n        \r\n        enable_feature => switches(1),\r\n\r\n        in_blank  => c_blank,\r\n        in_hsync  => c_hsync,\r\n        in_vsync  => c_vsync,\r\n        in_red    => c_red,\r\n        in_green  => c_green,\r\n        in_blue   => c_blue,\r\n        is_interlaced => is_interlaced,\r\n        is_second_field => is_second_field,\r\n       \r\n        out_blank => out_blank,\r\n        out_hsync => out_hsync,\r\n        out_vsync => out_vsync,\r\n        out_red   => out_red,\r\n        out_green => out_green,\r\n        out_blue  => out_blue\r\n    );\r\n\r\n end Behavioral;"
  },
  {
    "path": "src/serialiser_10_to_1.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- File: serialiser_10_to_1.vhd\r\n--\r\n-- Engineer:  Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: serialiser_10_to_1 - Behavioral\r\n--\r\n-- Description: Using the OSERDESE2 as a 10:1 serialiser, using a x1 and x5\r\n--              clocks (using DDR outputs).\r\n--\r\n-- The tricky bit is that reset needs to be asserted, and then CE asserted \r\n-- after the reset or it will not simulate correctly (outputs show as 'X') \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity serialiser_10_to_1 is\r\n    Port ( clk    : in STD_LOGIC;\r\n           clk_x5 : in STD_LOGIC;\r\n           data   : in STD_LOGIC_VECTOR (9 downto 0);\r\n           reset  : in std_logic;\r\n           serial : out STD_LOGIC);\r\nend serialiser_10_to_1;\r\n\r\narchitecture Behavioral of serialiser_10_to_1 is\r\n    signal shift1 : std_logic := '0';\r\n    signal shift2 : std_logic := '0';\r\n    signal ce_delay : std_logic_vector(7 downto 0) := (others => '0');\r\n    signal reset_delay : std_logic_vector(7 downto 0) := (others => '0');\r\nbegin\r\n\r\nmaster_serdes : OSERDESE2\r\n   generic map (\r\n      DATA_RATE_OQ => \"DDR\",   -- DDR, SDR\r\n      DATA_RATE_TQ => \"DDR\",   -- DDR, BUF, SDR\r\n      DATA_WIDTH => 10,         -- Parallel data width (2-8,10,14)\r\n      INIT_OQ => '1',          -- Initial value of OQ output (1'b0,1'b1)\r\n      INIT_TQ => '1',          -- Initial value of TQ output (1'b0,1'b1)\r\n      SERDES_MODE => \"MASTER\", -- MASTER, SLAVE\r\n      SRVAL_OQ => '0',         -- OQ output value when SR is used (1'b0,1'b1)\r\n      SRVAL_TQ => '0',         -- TQ output value when SR is used (1'b0,1'b1)\r\n      TBYTE_CTL => \"FALSE\",    -- Enable tristate byte operation (FALSE, TRUE)\r\n      TBYTE_SRC => \"FALSE\",    -- Tristate byte source (FALSE, TRUE)\r\n      TRISTATE_WIDTH => 1      -- 3-state converter width (1,4)\r\n   )\r\n   port map (\r\n      OFB       => open,             -- 1-bit output: Feedback path for data\r\n      OQ        => serial,               -- 1-bit output: Data path output\r\n      -- SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)\r\n      SHIFTOUT1 => open,\r\n      SHIFTOUT2 => open,\r\n      TBYTEOUT  => open,   -- 1-bit output: Byte group tristate\r\n      TFB       => open,             -- 1-bit output: 3-state control\r\n      TQ        => open,               -- 1-bit output: 3-state control\r\n      CLK       => clk_x5,             -- 1-bit input: High speed clock\r\n      CLKDIV    => clk,       -- 1-bit input: Divided clock\r\n      -- D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)\r\n      D1 => data(0),\r\n      D2 => data(1),\r\n      D3 => data(2),\r\n      D4 => data(3),\r\n      D5 => data(4),\r\n      D6 => data(5),\r\n      D7 => data(6),\r\n      D8 => data(7),\r\n      OCE => '1', --ce_delay(0),             -- 1-bit input: Output data clock enable\r\n      RST => reset,             -- 1-bit input: Reset\r\n      -- SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)\r\n      SHIFTIN1 => SHIFT1,\r\n      SHIFTIN2 => SHIFT2,\r\n      -- T1 - T4: 1-bit (each) input: Parallel 3-state inputs\r\n      T1 => '0',\r\n      T2 => '0',\r\n      T3 => '0',\r\n      T4 => '0',\r\n      TBYTEIN => '0', -- 1-bit input: Byte group tristate\r\n      TCE => '0'                  -- 1-bit input: 3-state clock enable\r\n   );\r\n\r\nslave_serdes : OSERDESE2\r\n   generic map (\r\n      DATA_RATE_OQ   => \"DDR\",   -- DDR, SDR\r\n      DATA_RATE_TQ   => \"DDR\",   -- DDR, BUF, SDR\r\n      DATA_WIDTH     => 10,      -- Parallel data width (2-8,10,14)\r\n      INIT_OQ        => '1',     -- Initial value of OQ output (1'b0,1'b1)\r\n      INIT_TQ        => '1',     -- Initial value of TQ output (1'b0,1'b1)\r\n      SERDES_MODE    => \"SLAVE\", -- MASTER, SLAVE\r\n      SRVAL_OQ       => '0',     -- OQ output value when SR is used (1'b0,1'b1)\r\n      SRVAL_TQ       => '0',     -- TQ output value when SR is used (1'b0,1'b1)\r\n      TBYTE_CTL      => \"FALSE\", -- Enable tristate byte operation (FALSE, TRUE)\r\n      TBYTE_SRC      => \"FALSE\", -- Tristate byte source (FALSE, TRUE)\r\n      TRISTATE_WIDTH => 1        -- 3-state converter width (1,4)\r\n   )\r\n   port map (\r\n      OFB       => open,         -- 1-bit output: Feedback path for data\r\n      OQ        => open,         -- 1-bit output: Data path output\r\n      -- SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)\r\n      SHIFTOUT1 => shift1,\r\n      SHIFTOUT2 => shift2,\r\n      \r\n      TBYTEOUT  => open,    -- 1-bit output: Byte group tristate\r\n      TFB       => open,    -- 1-bit output: 3-state control\r\n      TQ        => open,    -- 1-bit output: 3-state control\r\n      CLK       => clk_x5,  -- 1-bit input: High speed clock\r\n      CLKDIV    => clk,     -- 1-bit input: Divided clock\r\n      -- D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)\r\n      D1       => '0',\r\n      D2       => '0',\r\n      D3       => data(8),\r\n      D4       => data(9),\r\n      D5       => '0',\r\n      D6       => '0',\r\n      D7       => '0',\r\n      D8       => '0',\r\n      OCE      => '1', --ce_delay(0),     -- 1-bit input: Output data clock enable\r\n      RST      => reset,     -- 1-bit input: Reset\r\n      -- SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)\r\n      SHIFTIN1 => '0',\r\n      SHIFTIN2 => '0',\r\n      -- T1 - T4: 1-bit (each) input: Parallel 3-state inputs\r\n      T1       => '0',\r\n      T2       => '0',\r\n      T3       => '0',\r\n      T4       => '0',\r\n      TBYTEIN  => '0',     -- 1-bit input: Byte group tristate\r\n      TCE      => '0'      -- 1-bit input: 3-state clock enable\r\n   );\r\n\r\ndelay_ce: process(clk_x5)\r\n    begin\r\n        if rising_edge(clk_x5) then\r\n            ce_delay <= not reset & ce_delay(ce_delay'high downto 1);\r\n        end if;\r\n    end process;\r\nend Behavioral;"
  },
  {
    "path": "src/symbol_dump.vhd",
    "content": "----------------------------------------------------------------------------------\n-- Engineer: Mike Field <hamster@snap.net.nz> \n-- \n-- Module Name: symbol_dump - Behavioral\n--\n-- Description: Create a trace of HDMI symbols - a 1024 word memory block is filled \n--              and then transmitted over rs232. Then refilled again, but this time\n--              waiting an extra 1024 cycles from when symbol_sync is asserted.\n--              \n--             If the video source is paused, then the entire frame can be capbured\n--             (excluding ADP data periods, which might get broken on the boundary.\n--\n--             The captured data can then be analysed by hand or used to drive \n--             simulations.\n-- \n------------------------------------------------------------------------------------\n-- The MIT License (MIT)\n-- \n-- Copyright (c) 2015 Michael Alan Field\n-- \n-- Permission is hereby granted, free of charge, to any person obtaining a copy\n-- of this software and associated documentation files (the \"Software\"), to deal\n-- in the Software without restriction, including without limitation the rights\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n-- copies of the Software, and to permit persons to whom the Software is\n-- furnished to do so, subject to the following conditions:\n-- \n-- The above copyright notice and this permission notice shall be included in\n-- all copies or substantial portions of the Software.\n-- \n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n-- THE SOFTWARE.\n------------------------------------------------------------------------------------\n----- Want to say thanks? ----------------------------------------------------------\n------------------------------------------------------------------------------------\n--\n-- This design has taken many hours - with the industry metric of 30 lines\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\n-- to share it if you can make use of it. It is released under the MIT license,\n-- so you are not under any onus to say thanks, but....\n-- \n-- If you what to say thanks for this design how about trying PayPal?\n--  Educational use - Enough for a beer\n--  Hobbyist use    - Enough for a pizza\n--  Research use    - Enough to take the family out to dinner\n--  Commercial use  - A weeks pay for an engineer (I wish!)\n--\n----------------------------------------------------------------------------------\n\n\nlibrary IEEE;\nuse IEEE.STD_LOGIC_1164.ALL;\nuse IEEE.NUMERIC_STD.ALL;\n\nentity symbol_dump is\n    Port ( clk : in STD_LOGIC;\n           clk100 : in STD_LOGIC;\n           symbol_sync : in STD_LOGIC;\n           symbol_ch0 : in STD_LOGIC_VECTOR (9 downto 0);\n           symbol_ch1 : in STD_LOGIC_VECTOR (9 downto 0);\n           symbol_ch2 : in STD_LOGIC_VECTOR (9 downto 0);\n           rs232_tx : out STD_LOGIC);\nend symbol_dump;\n\narchitecture Behavioral of symbol_dump is\n    type array_hex is array(0 to 15) of std_logic_vector(9 downto 0);\n    signal hex : array_hex := (\n            \"1001100000\", \"1001100010\", \"1001100100\", \"1001100110\",\n            \"1001101000\", \"1001101010\", \"1001101100\", \"1001101110\",\n            \"1001110000\", \"1001110010\", \"1010000010\", \"1010000100\",\n            \"1010000110\", \"1010001000\", \"1010001010\", \"1010001100\");\n\n    type array_memory is array(0 to 1023) of std_logic_vector(29 downto 0);\n    signal memory : array_memory := (others => (others =>'0')); \n    signal position      : unsigned(23 downto 0) := (others => '0');\n    signal capture_point : unsigned(23 downto 0) := (others => '0');\n    signal write_address : unsigned(9 downto 0)  := (others => '0');\n    signal write_enable  : std_logic := '0';\n    signal write_data    : std_logic_vector(29 downto 0) := (others => '0');\n    \n    ---  For signaling into the 100MHz domain\n    signal ready_to_send        : std_logic := '0';\n    signal ready_to_send_meta   : std_logic := '0';\n    signal ready_to_send_synced : std_logic := '0';\n    ---  For signaling into the pixel clock domain\n    signal sending_data : std_logic := '0';\n    signal sending_data_meta   : std_logic := '0';\n    signal sending_data_synced : std_logic := '0';\n\n    signal rd_address   : unsigned(9 downto 0)  := (others => '0');\n    signal rd_data      : std_logic_vector(29 downto 0) := (others => '0');\n    signal tx_data      : std_logic_vector(89 downto 0)     := (others => '1');\n    signal tx_count     : unsigned(7 downto 0)      := (others => '0');\n    signal baud_counter : unsigned(12 downto 0)     := (others => '0');\n    signal baud_counter_max : unsigned(12 downto 0) := to_unsigned(100000000/115200,13);\nbegin\n\nprocess(clk)\n    begin\n        if rising_edge(clk) then\n            if write_enable = '1' then\n                memory(to_integer(write_address)) <= symbol_ch2 & symbol_ch1 & symbol_ch0;\n            end if;\n            -- track where we are in the frame.\n            if symbol_sync = '1' then\n                position <= (others => '0');\n            else\n                position <= position+1;\n            end if;\n            \n            -- If we are capturing remember where we have got up to\n            -- and see if we have captured our full amount.\n            if write_enable = '1' then\n                capture_point <= position;\n                write_data <= symbol_ch2 & symbol_ch1 & symbol_ch0;\n                write_data <= symbol_ch2 & symbol_ch1 & symbol_ch0;\n                if write_address = 1023 then\n                    write_enable <= '0';\n                    ready_to_send <= '1';\n                end if;\n                write_address <= write_address+1;\n            end if;\n\n            -- Do we start capturing at this point? \n            -- (write address resets itself to 0, so we don't\n            -- have to do it here) \n            if position = capture_point and ready_to_send = '0' and sending_data_synced = '0' then\n                write_enable <= '1';\n            end if;\n            \n            -- Do we need to re-arm ready for the next capture\n            if sending_data_synced = '1' then\n               ready_to_send <= '0';\n            end if;\n            \n            \n            -- Bring data_sent into this clock domain\n            sending_data_synced <= sending_data_meta; \n            sending_data_meta   <= sending_data; \n\n        end if;\n    end process;\n    \nprocess(clk100)\n    begin\n        if rising_edge(clk100) then\n            \n            if baud_counter = 0 then\n                rs232_tx <= tx_data(0);\n                tx_data <= '1' & tx_data(89 downto 1);\n                baud_counter <= baud_counter_max;\n                if(tx_count > 0) then\n                  tx_count <= tx_count-1;\n                end if;\n            else\n                baud_counter <= baud_counter -1;    \n            end if;\n            \n            if sending_data = '1' or ready_to_send_synced = '1' then            \n                if tx_count = 0 then\n                    tx_data(89 downto 80) <= hex(to_integer(unsigned(rd_data( 3 downto  0))));\n                    tx_data(79 downto 70) <= hex(to_integer(unsigned(rd_data( 7 downto  4))));\n                    tx_data(69 downto 60) <= hex(to_integer(unsigned(rd_data(11 downto  8))));\n                    tx_data(59 downto 50) <= hex(to_integer(unsigned(rd_data(15 downto 12))));\n                    tx_data(49 downto 40) <= hex(to_integer(unsigned(rd_data(19 downto 16))));\n                    tx_data(39 downto 30) <= hex(to_integer(unsigned(rd_data(23 downto 20))));\n                    tx_data(29 downto 20) <= hex(to_integer(unsigned(rd_data(27 downto 24))));\n                    tx_data(19 downto 10) <= hex(to_integer(unsigned(rd_data(29 downto 28))));\n                    tx_data( 9 downto  0) <= \"1000010100\"; -- New line\n                    tx_count <= to_unsigned(90,8);\n\n                    rd_data <= memory(to_integer(rd_address));\n                    rd_address <= rd_address+1;\n                    if rd_address = 1023 then\n                        sending_data <= '0';\n                    else\n                        sending_data <= '1';\n                    end if;\n                end if;\n            end if;\n            \n            -- Bring the ready to send signal into this clock domain    \n            ready_to_send_synced <= ready_to_send_meta; \n            ready_to_send_meta   <= ready_to_send; \n        end if;\n    end process;\nend Behavioral;\n"
  },
  {
    "path": "src/tmds_decoder.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Create Date: 10.07.2015 20:06:49\r\n-- Design Name: \r\n-- Module Name: TMDS_decoder - Behavioral\r\n--\r\n-- Description: Decoding for TMDS encoded symbols. This performs the conversion\r\n--              using a table lookup for simplicity\r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.std_logic_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity TMDS_decoder is\r\n    Port ( clk              : in  std_logic;\r\n           symbol           : in  std_logic_vector (9 downto 0);\r\n           invalid_symbol   : out std_logic;\r\n           \r\n           ctl_valid        : out std_logic;\r\n           ctl              : out std_logic_vector (1 downto 0);\r\n\r\n           terc4_valid      : out std_logic;\r\n           terc4            : out std_logic_vector (3 downto 0);\r\n\r\n           guardband_valid  : out std_logic;\r\n           guardband        : out std_logic_vector (0 downto 0);\r\n\r\n           data_valid       : out std_logic;\r\n           data             : out std_logic_vector (7 downto 0));\r\nend TMDS_decoder;\r\n\r\narchitecture Behavioral of TMDS_decoder is\r\n    signal lookup : std_logic_vector (8 downto 0);\r\nbegin\r\n\r\ndecode_ctl:  process(clk)\r\n   begin\r\n      if rising_edge(clk) then\r\n            ------------------\r\n            -- TMDS data bytes\r\n            if lookup(8) = '1' then\r\n                data_valid <= '1'; \r\n                data       <= lookup(7 downto 0);\r\n            else\r\n                data_valid <= '0';\r\n            end if;\r\n                        \r\n            ------------\r\n            -- CTL codes\r\n            if lookup(8 downto 7) = \"01\" then\r\n                ctl_valid <= '1';\r\n                ctl       <= lookup(1 downto 0);\r\n            else \r\n                ctl_valid <= '0';\r\n            end if;\r\n\r\n            ------------------------------\r\n            -- All other codes are invalid \r\n            ------------------------------\r\n            if lookup(8 downto 7) = \"00\" then\r\n                invalid_symbol <= '1';\r\n            else\r\n                invalid_symbol <= '0';\r\n            end if;\r\n\r\n            terc4_valid     <= '0';\r\n            guardband_valid <= '0';\r\n            if lookup(8) = '1' then\r\n                -------------------------\r\n                -- Decode the guard bands\r\n                -------------------------\r\n                case lookup(7 downto 0) is \r\n                    when x\"55\"  => guardband_valid <= '1'; guardband <= \"0\";\r\n                    when x\"AB\"  => guardband_valid <= '1'; guardband <= \"1\";\r\n                    when others => null;\r\n                end case;\r\n\r\n                -------------------------\r\n                -- Decode TERC4 data\r\n                -------------------------\r\n                case lookup(7 downto 0) is \r\n                    when x\"5B\"  => terc4_valid <= '1'; terc4 <= \"0000\";-- \"1010011100\" TERC4 0000\r\n                    when x\"5A\"  => terc4_valid <= '1'; terc4 <= \"0001\"; -- \"1001100011\" TERC4 0001\r\n                    when x\"D3\"  => terc4_valid <= '1'; terc4 <= \"0010\"; -- \"1011100100\" TERC4 0010\r\n                    when x\"D9\"  => terc4_valid <= '1'; terc4 <= \"0011\"; -- \"1011100010\" TERC4 0011\r\n                    when x\"93\"  => terc4_valid <= '1'; terc4 <= \"0100\"; -- \"0101110001\" TERC4 0100\r\n                    when x\"22\"  => terc4_valid <= '1'; terc4 <= \"0101\"; -- \"0100011110\" TERC4 0101\r\n                    when x\"92\"  => terc4_valid <= '1'; terc4 <= \"0110\"; -- \"0110001110\" TERC4 0110\r\n                    when x\"44\"  => terc4_valid <= '1'; terc4 <= \"0111\"; -- \"0100111100\" TERC4 0111\r\n                    when x\"AB\"  => terc4_valid <= '1'; terc4 <= \"1000\"; -- \"1011001100\" TERC4 1000 & HDMI Guard band (video C0 and Video C2) \r\n                    when x\"4B\"  => terc4_valid <= '1'; terc4 <= \"1001\"; -- \"0100111001\" TERC4 1001\r\n                    when x\"A4\"  => terc4_valid <= '1'; terc4 <= \"1010\"; -- \"0110011100\" TERC4 1010\r\n                    when x\"B5\"  => terc4_valid <= '1'; terc4 <= \"1011\"; -- \"1011000110\" TERC4 1011\r\n                    when x\"6D\"  => terc4_valid <= '1'; terc4 <= \"1100\"; -- \"1010001110\" TERC4 1100\r\n                    when x\"6C\"  => terc4_valid <= '1'; terc4 <= \"1101\"; -- \"1001110001\" TERC4 1101\r\n                    when x\"A5\"  => terc4_valid <= '1'; terc4 <= \"1110\"; -- \"0101100011\" TERC4 1110\r\n                    when x\"BA\"  => terc4_valid <= '1'; terc4 <= \"1111\"; -- \"1011000011\" TERC4 1111\r\n                    when others => null;\r\n                end case;\r\n            end if;\r\n\r\n            -------------------------------------------------------------\r\n            -- Convert the incoming signal to something we can decode\r\n            --\r\n            -- For data symbols \r\n            -- ----------------\r\n            -- bit 8    - 1 -- Data word flage\r\n            -- bits 7:0 - xxxxxxxx - Data value\r\n            --\r\n            -- For CTL symbols\r\n            -- --------------- \r\n            -- bit 8    - 0 - Data word flage\r\n            -- bit 7    - 1 - CTL Indicator\r\n            -- bits 6:2 - X - Ignored\r\n            -- bits 1:0 - xx - CTL value\r\n            --\r\n            -- For Invalid symbols\r\n            -- ------------------- \r\n            -- bit 8    - 0 - Data word flage\r\n            -- bit 7    - 0 - TERC4 Inicated\r\n            -- bit 6    - 0 - CTL Indicator\r\n            -- bit 5    - 0 - Guard band indicator\r\n            -- bits 4:0 - X - Unused \r\n            --\r\n            ------------------------------------------------------------- \r\n            case symbol is\r\n                -- DVI-D Data sybmols\r\n                -- Data 00\r\n                when \"1111111111\" => lookup <= \"100000000\";\r\n                when \"0100000000\" => lookup <= \"100000000\";\r\n                -- Data 01\r\n                when \"0111111111\" => lookup <= \"100000001\";\r\n                when \"1100000000\" => lookup <= \"100000001\";\r\n                -- Data 02\r\n                when \"0111111110\" => lookup <= \"100000010\";\r\n                when \"1100000001\" => lookup <= \"100000010\";\r\n                -- Data 03\r\n                when \"1111111110\" => lookup <= \"100000011\";\r\n                when \"0100000001\" => lookup <= \"100000011\";\r\n                -- Data 04\r\n                when \"0111111100\" => lookup <= \"100000100\";\r\n                when \"1100000011\" => lookup <= \"100000100\";\r\n                -- Data 05\r\n                when \"1111111100\" => lookup <= \"100000101\";\r\n                when \"0100000011\" => lookup <= \"100000101\";\r\n                -- Data 06\r\n                when \"1111111101\" => lookup <= \"100000110\";\r\n                when \"0100000010\" => lookup <= \"100000110\";\r\n                -- Data 07\r\n                when \"0111111101\" => lookup <= \"100000111\";\r\n                when \"1100000010\" => lookup <= \"100000111\";\r\n                -- Data 08\r\n                when \"0111111000\" => lookup <= \"100001000\";\r\n                when \"1100000111\" => lookup <= \"100001000\";\r\n                -- Data 09\r\n                when \"1111111000\" => lookup <= \"100001001\";\r\n                when \"0100000111\" => lookup <= \"100001001\";\r\n                -- Data 0a\r\n                when \"1111111001\" => lookup <= \"100001010\";\r\n                when \"0100000110\" => lookup <= \"100001010\";\r\n                -- Data 0b\r\n                when \"0111111001\" => lookup <= \"100001011\";\r\n                when \"1100000110\" => lookup <= \"100001011\";\r\n                -- Data 0c\r\n                when \"1111111011\" => lookup <= \"100001100\";\r\n                when \"0100000100\" => lookup <= \"100001100\";\r\n                -- Data 0d\r\n                when \"0111111011\" => lookup <= \"100001101\";\r\n                when \"1100000100\" => lookup <= \"100001101\";\r\n                -- Data 0e\r\n                when \"0111111010\" => lookup <= \"100001110\";\r\n                when \"1100000101\" => lookup <= \"100001110\";\r\n                -- Data 0f\r\n                when \"1111111010\" => lookup <= \"100001111\";\r\n                when \"0100000101\" => lookup <= \"100001111\";\r\n                -- Data 10\r\n                when \"0111110000\" => lookup <= \"100010000\";\r\n                -- Data 11\r\n                when \"0100001111\" => lookup <= \"100010001\";\r\n                -- Data 12\r\n                when \"1111110001\" => lookup <= \"100010010\";\r\n                when \"0100001110\" => lookup <= \"100010010\";\r\n                -- Data 13\r\n                when \"0111110001\" => lookup <= \"100010011\";\r\n                when \"1100001110\" => lookup <= \"100010011\";\r\n                -- Data 14\r\n                when \"1111110011\" => lookup <= \"100010100\";\r\n                when \"0100001100\" => lookup <= \"100010100\";\r\n                -- Data 15\r\n                when \"0111110011\" => lookup <= \"100010101\";\r\n                when \"1100001100\" => lookup <= \"100010101\";\r\n                -- Data 16\r\n                when \"0111110010\" => lookup <= \"100010110\";\r\n                when \"1100001101\" => lookup <= \"100010110\";\r\n                -- Data 17\r\n                when \"1111110010\" => lookup <= \"100010111\";\r\n                when \"0100001101\" => lookup <= \"100010111\";\r\n                -- Data 18\r\n                when \"1111110111\" => lookup <= \"100011000\";\r\n                when \"0100001000\" => lookup <= \"100011000\";\r\n                -- Data 19\r\n                when \"0111110111\" => lookup <= \"100011001\";\r\n                when \"1100001000\" => lookup <= \"100011001\";\r\n                -- Data 1a\r\n                when \"0111110110\" => lookup <= \"100011010\";\r\n                when \"1100001001\" => lookup <= \"100011010\";\r\n                -- Data 1b\r\n                when \"1111110110\" => lookup <= \"100011011\";\r\n                when \"0100001001\" => lookup <= \"100011011\";\r\n                -- Data 1c\r\n                when \"0111110100\" => lookup <= \"100011100\";\r\n                when \"1100001011\" => lookup <= \"100011100\";\r\n                -- Data 1d\r\n                when \"1111110100\" => lookup <= \"100011101\";\r\n                when \"0100001011\" => lookup <= \"100011101\";\r\n                -- Data 1e\r\n                when \"1001011111\" => lookup <= \"100011110\";\r\n                when \"0010100000\" => lookup <= \"100011110\";\r\n                -- Data 1f\r\n                when \"0001011111\" => lookup <= \"100011111\";\r\n                when \"1010100000\" => lookup <= \"100011111\";\r\n                -- Data 20\r\n                when \"1100011111\" => lookup <= \"100100000\";\r\n                when \"0111100000\" => lookup <= \"100100000\";\r\n                -- Data 21\r\n                when \"0100011111\" => lookup <= \"100100001\";\r\n                when \"1111100000\" => lookup <= \"100100001\";\r\n                -- Data 22\r\n                when \"0100011110\" => lookup <= \"100100010\"; -- TERC4 0101\r\n                -- Data 23\r\n                when \"0111100001\" => lookup <= \"100100011\";\r\n                -- Data 24\r\n                when \"1111100011\" => lookup <= \"100100100\";\r\n                when \"0100011100\" => lookup <= \"100100100\";\r\n                -- Data 25\r\n                when \"0111100011\" => lookup <= \"100100101\";\r\n                when \"1100011100\" => lookup <= \"100100101\";\r\n                -- Data 26\r\n                when \"0111100010\" => lookup <= \"100100110\";\r\n                -- Data 27\r\n                when \"0100011101\" => lookup <= \"100100111\";\r\n                -- Data 28\r\n                when \"1111100111\" => lookup <= \"100101000\";\r\n                when \"0100011000\" => lookup <= \"100101000\";\r\n                -- Data 29\r\n                when \"0111100111\" => lookup <= \"100101001\";\r\n                when \"1100011000\" => lookup <= \"100101001\";\r\n                -- Data 2a\r\n                when \"0111100110\" => lookup <= \"100101010\";\r\n                when \"1100011001\" => lookup <= \"100101010\";\r\n                -- Data 2b\r\n                when \"1111100110\" => lookup <= \"100101011\";\r\n                when \"0100011001\" => lookup <= \"100101011\";\r\n                -- Data 2c\r\n                when \"0111100100\" => lookup <= \"100101100\";\r\n                -- Data 2d\r\n                when \"0100011011\" => lookup <= \"100101101\";\r\n                -- Data 2e\r\n                when \"1001001111\" => lookup <= \"100101110\";\r\n                when \"0010110000\" => lookup <= \"100101110\";\r\n                -- Data 2f\r\n                when \"0001001111\" => lookup <= \"100101111\";\r\n                when \"1010110000\" => lookup <= \"100101111\";\r\n                -- Data 30\r\n                when \"1111101111\" => lookup <= \"100110000\";\r\n                when \"0100010000\" => lookup <= \"100110000\";\r\n                -- Data 31\r\n                when \"0111101111\" => lookup <= \"100110001\";\r\n                when \"1100010000\" => lookup <= \"100110001\";\r\n                -- Data 32\r\n                when \"0111101110\" => lookup <= \"100110010\";\r\n                when \"1100010001\" => lookup <= \"100110010\";\r\n                -- Data 33\r\n                when \"1111101110\" => lookup <= \"100110011\";\r\n                when \"0100010001\" => lookup <= \"100110011\";\r\n                -- Data 34\r\n                when \"0111101100\" => lookup <= \"100110100\";\r\n                when \"1100010011\" => lookup <= \"100110100\";\r\n                -- Data 35\r\n                when \"1111101100\" => lookup <= \"100110101\";\r\n                when \"0100010011\" => lookup <= \"100110101\";\r\n                -- Data 36\r\n                when \"1001000111\" => lookup <= \"100110110\";\r\n                -- Data 37\r\n                when \"1010111000\" => lookup <= \"100110111\";\r\n                -- Data 38\r\n                when \"0111101000\" => lookup <= \"100111000\";\r\n                -- Data 39\r\n                when \"0100010111\" => lookup <= \"100111001\";\r\n                -- Data 3a\r\n                when \"0010111100\" => lookup <= \"100111010\";\r\n                when \"1001000011\" => lookup <= \"100111010\";\r\n                -- Data 3b\r\n                when \"1010111100\" => lookup <= \"100111011\";\r\n                when \"0001000011\" => lookup <= \"100111011\";\r\n                -- Data 3c\r\n                when \"0010111110\" => lookup <= \"100111100\";\r\n                when \"1001000001\" => lookup <= \"100111100\";\r\n                -- Data 3d\r\n                when \"1010111110\" => lookup <= \"100111101\";\r\n                when \"0001000001\" => lookup <= \"100111101\";\r\n                -- Data 3e\r\n                when \"1010111111\" => lookup <= \"100111110\";\r\n                when \"0001000000\" => lookup <= \"100111110\";\r\n                -- Data 3f\r\n                when \"0010111111\" => lookup <= \"100111111\";\r\n                when \"1001000000\" => lookup <= \"100111111\";\r\n                -- Data 40\r\n                when \"1100111111\" => lookup <= \"101000000\";\r\n                when \"0111000000\" => lookup <= \"101000000\";\r\n                -- Data 41\r\n                when \"0100111111\" => lookup <= \"101000001\";\r\n                when \"1111000000\" => lookup <= \"101000001\";\r\n                -- Data 42\r\n                when \"0100111110\" => lookup <= \"101000010\";\r\n                when \"1111000001\" => lookup <= \"101000010\";\r\n                -- Data 43\r\n                when \"1100111110\" => lookup <= \"101000011\";\r\n                when \"0111000001\" => lookup <= \"101000011\";\r\n                -- Data 44\r\n                when \"0100111100\" => lookup <= \"101000100\"; -- TERC4 0111\r\n                -- Data 45\r\n                when \"0111000011\" => lookup <= \"101000101\";\r\n                -- Data 46\r\n                when \"1100111101\" => lookup <= \"101000110\";\r\n                when \"0111000010\" => lookup <= \"101000110\";\r\n                -- Data 47\r\n                when \"0100111101\" => lookup <= \"101000111\";\r\n                when \"1111000010\" => lookup <= \"101000111\";\r\n                -- Data 48\r\n                when \"1111000111\" => lookup <= \"101001000\";\r\n                when \"0100111000\" => lookup <= \"101001000\";\r\n                -- Data 49\r\n                when \"0111000111\" => lookup <= \"101001001\";\r\n                when \"1100111000\" => lookup <= \"101001001\";\r\n                -- Data 4a\r\n                when \"0111000110\" => lookup <= \"101001010\";\r\n                -- Data 4b\r\n                when \"0100111001\" => lookup <= \"101001011\";  -- TERC4 1001\r\n                -- Data 4c\r\n                when \"1100111011\" => lookup <= \"101001100\";\r\n                when \"0111000100\" => lookup <= \"101001100\";\r\n                -- Data 4d\r\n                when \"0100111011\" => lookup <= \"101001101\";\r\n                when \"1111000100\" => lookup <= \"101001101\";\r\n                -- Data 4e\r\n                when \"1001101111\" => lookup <= \"101001110\";\r\n                when \"0010010000\" => lookup <= \"101001110\";\r\n                -- Data 4f\r\n                when \"0001101111\" => lookup <= \"101001111\";\r\n                when \"1010010000\" => lookup <= \"101001111\";\r\n                -- Data 50\r\n                when \"1111001111\" => lookup <= \"101010000\";\r\n                when \"0100110000\" => lookup <= \"101010000\";\r\n                -- Data 51\r\n                when \"0111001111\" => lookup <= \"101010001\";\r\n                when \"1100110000\" => lookup <= \"101010001\";\r\n                -- Data 52\r\n                when \"0111001110\" => lookup <= \"101010010\";\r\n                when \"1100110001\" => lookup <= \"101010010\";\r\n                -- Data 53\r\n                when \"1111001110\" => lookup <= \"101010011\";\r\n                when \"0100110001\" => lookup <= \"101010011\";\r\n                -- Data 54\r\n                when \"0111001100\" => lookup <= \"101010100\";\r\n                -- Data 55\r\n                when \"0100110011\" => lookup <= \"101010101\"; -- HDMI Guard band (video C1, data C1 & C2)\r\n                -- Data 56\r\n                when \"1001100111\" => lookup <= \"101010110\";\r\n                when \"0010011000\" => lookup <= \"101010110\";\r\n                -- Data 57\r\n                when \"0001100111\" => lookup <= \"101010111\";\r\n                when \"1010011000\" => lookup <= \"101010111\";\r\n                -- Data 58\r\n                when \"1100110111\" => lookup <= \"101011000\";\r\n                when \"0111001000\" => lookup <= \"101011000\";\r\n                -- Data 59\r\n                when \"0100110111\" => lookup <= \"101011001\";\r\n                when \"1111001000\" => lookup <= \"101011001\";\r\n                -- Data 5a\r\n                when \"1001100011\" => lookup <= \"101011010\"; -- TERC4 0001\r\n                -- Data 5b\r\n                when \"1010011100\" => lookup <= \"101011011\"; -- TERC4 0000\r\n                -- Data 5c\r\n                when \"0010011110\" => lookup <= \"101011100\";\r\n                when \"1001100001\" => lookup <= \"101011100\";\r\n                -- Data 5d\r\n                when \"1010011110\" => lookup <= \"101011101\";\r\n                when \"0001100001\" => lookup <= \"101011101\";\r\n                -- Data 5e\r\n                when \"1010011111\" => lookup <= \"101011110\";\r\n                when \"0001100000\" => lookup <= \"101011110\";\r\n                -- Data 5f\r\n                when \"0010011111\" => lookup <= \"101011111\";\r\n                when \"1001100000\" => lookup <= \"101011111\";\r\n                -- Data 60\r\n                when \"1111011111\" => lookup <= \"101100000\";\r\n                when \"0100100000\" => lookup <= \"101100000\";\r\n                -- Data 61\r\n                when \"0111011111\" => lookup <= \"101100001\";\r\n                when \"1100100000\" => lookup <= \"101100001\";\r\n                -- Data 62\r\n                when \"0111011110\" => lookup <= \"101100010\";\r\n                when \"1100100001\" => lookup <= \"101100010\";\r\n                -- Data 63\r\n                when \"1111011110\" => lookup <= \"101100011\";\r\n                when \"0100100001\" => lookup <= \"101100011\";\r\n                -- Data 64\r\n                when \"0111011100\" => lookup <= \"101100100\";\r\n                when \"1100100011\" => lookup <= \"101100100\";\r\n                -- Data 65\r\n                when \"1111011100\" => lookup <= \"101100101\";\r\n                when \"0100100011\" => lookup <= \"101100101\";\r\n                -- Data 66\r\n                when \"1001110111\" => lookup <= \"101100110\";\r\n                when \"0010001000\" => lookup <= \"101100110\";\r\n                -- Data 67\r\n                when \"0001110111\" => lookup <= \"101100111\";\r\n                when \"1010001000\" => lookup <= \"101100111\";\r\n                -- Data 68\r\n                when \"0111011000\" => lookup <= \"101101000\";\r\n                -- Data 69\r\n                when \"0100100111\" => lookup <= \"101101001\";\r\n                -- Data 6a\r\n                when \"1001110011\" => lookup <= \"101101010\";\r\n                when \"0010001100\" => lookup <= \"101101010\";\r\n                -- Data 6b\r\n                when \"0001110011\" => lookup <= \"101101011\";\r\n                when \"1010001100\" => lookup <= \"101101011\";\r\n                -- Data 6c\r\n                when \"1001110001\" => lookup <= \"101101100\"; -- TERC4 1101\r\n                -- Data 6d\r\n                when \"1010001110\" => lookup <= \"101101101\"; -- TERC4 1100\r\n                -- Data 6e\r\n                when \"1010001111\" => lookup <= \"101101110\";\r\n                when \"0001110000\" => lookup <= \"101101110\";\r\n                -- Data 6f\r\n                when \"0010001111\" => lookup <= \"101101111\";\r\n                when \"1001110000\" => lookup <= \"101101111\";\r\n                -- Data 70\r\n                when \"1100101111\" => lookup <= \"101110000\";\r\n                when \"0111010000\" => lookup <= \"101110000\";\r\n                -- Data 71\r\n                when \"0100101111\" => lookup <= \"101110001\";\r\n                when \"1111010000\" => lookup <= \"101110001\";\r\n                -- Data 72\r\n                when \"1001111011\" => lookup <= \"101110010\";\r\n                when \"0010000100\" => lookup <= \"101110010\";\r\n                -- Data 73\r\n                when \"0001111011\" => lookup <= \"101110011\";\r\n                when \"1010000100\" => lookup <= \"101110011\";\r\n                -- Data 74\r\n                when \"1001111001\" => lookup <= \"101110100\";\r\n                when \"0010000110\" => lookup <= \"101110100\";\r\n                -- Data 75\r\n                when \"0001111001\" => lookup <= \"101110101\";\r\n                when \"1010000110\" => lookup <= \"101110101\";\r\n                -- Data 76\r\n                when \"1010000111\" => lookup <= \"101110110\";\r\n                -- Data 77\r\n                when \"1001111000\" => lookup <= \"101110111\";\r\n                -- Data 78\r\n                when \"1001111101\" => lookup <= \"101111000\";\r\n                when \"0010000010\" => lookup <= \"101111000\";\r\n                -- Data 79\r\n                when \"0001111101\" => lookup <= \"101111001\";\r\n                when \"1010000010\" => lookup <= \"101111001\";\r\n                -- Data 7a\r\n                when \"0001111100\" => lookup <= \"101111010\";\r\n                when \"1010000011\" => lookup <= \"101111010\";\r\n                -- Data 7b\r\n                when \"1001111100\" => lookup <= \"101111011\";\r\n                when \"0010000011\" => lookup <= \"101111011\";\r\n                -- Data 7c\r\n                when \"0001111110\" => lookup <= \"101111100\";\r\n                when \"1010000001\" => lookup <= \"101111100\";\r\n                -- Data 7d\r\n                when \"1001111110\" => lookup <= \"101111101\";\r\n                when \"0010000001\" => lookup <= \"101111101\";\r\n                -- Data 7e\r\n                when \"1001111111\" => lookup <= \"101111110\";\r\n                when \"0010000000\" => lookup <= \"101111110\";\r\n                -- Data 7f\r\n                when \"0001111111\" => lookup <= \"101111111\";\r\n                when \"1010000000\" => lookup <= \"101111111\";\r\n                -- Data 80\r\n                when \"1101111111\" => lookup <= \"110000000\";\r\n                when \"0110000000\" => lookup <= \"110000000\";\r\n                -- Data 81\r\n                when \"0101111111\" => lookup <= \"110000001\";\r\n                when \"1110000000\" => lookup <= \"110000001\";\r\n                -- Data 82\r\n                when \"0101111110\" => lookup <= \"110000010\";\r\n                when \"1110000001\" => lookup <= \"110000010\";\r\n                -- Data 83\r\n                when \"1101111110\" => lookup <= \"110000011\";\r\n                when \"0110000001\" => lookup <= \"110000011\";\r\n                -- Data 84\r\n                when \"0101111100\" => lookup <= \"110000100\";\r\n                when \"1110000011\" => lookup <= \"110000100\";\r\n                -- Data 85\r\n                when \"1101111100\" => lookup <= \"110000101\";\r\n                when \"0110000011\" => lookup <= \"110000101\";\r\n                -- Data 86\r\n                when \"1101111101\" => lookup <= \"110000110\";\r\n                when \"0110000010\" => lookup <= \"110000110\";\r\n                -- Data 87\r\n                when \"0101111101\" => lookup <= \"110000111\";\r\n                when \"1110000010\" => lookup <= \"110000111\";\r\n                -- Data 88\r\n                when \"0101111000\" => lookup <= \"110001000\";\r\n                -- Data 89\r\n                when \"0110000111\" => lookup <= \"110001001\";\r\n                -- Data 8a\r\n                when \"1101111001\" => lookup <= \"110001010\";\r\n                when \"0110000110\" => lookup <= \"110001010\";\r\n                -- Data 8b\r\n                when \"0101111001\" => lookup <= \"110001011\";\r\n                when \"1110000110\" => lookup <= \"110001011\";\r\n                -- Data 8c\r\n                when \"1101111011\" => lookup <= \"110001100\";\r\n                when \"0110000100\" => lookup <= \"110001100\";\r\n                -- Data 8d\r\n                when \"0101111011\" => lookup <= \"110001101\";\r\n                when \"1110000100\" => lookup <= \"110001101\";\r\n                -- Data 8e\r\n                when \"1000101111\" => lookup <= \"110001110\";\r\n                when \"0011010000\" => lookup <= \"110001110\";\r\n                -- Data 8f\r\n                when \"0000101111\" => lookup <= \"110001111\";\r\n                when \"1011010000\" => lookup <= \"110001111\";\r\n                -- Data 90\r\n                when \"1110001111\" => lookup <= \"110010000\";\r\n                when \"0101110000\" => lookup <= \"110010000\";\r\n                -- Data 91\r\n                when \"0110001111\" => lookup <= \"110010001\";\r\n                when \"1101110000\" => lookup <= \"110010001\";\r\n                -- Data 92\r\n                when \"0110001110\" => lookup <= \"110010010\"; -- TERC4 0110\r\n                -- Data 93\r\n                when \"0101110001\" => lookup <= \"110010011\"; -- TERC4 0100\r\n                -- Data 94\r\n                when \"1101110011\" => lookup <= \"110010100\";\r\n                when \"0110001100\" => lookup <= \"110010100\";\r\n                -- Data 95\r\n                when \"0101110011\" => lookup <= \"110010101\";\r\n                when \"1110001100\" => lookup <= \"110010101\";\r\n                -- Data 96\r\n                when \"1000100111\" => lookup <= \"110010110\";\r\n                -- Data 97\r\n                when \"1011011000\" => lookup <= \"110010111\";\r\n                -- Data 98\r\n                when \"1101110111\" => lookup <= \"110011000\";\r\n                when \"0110001000\" => lookup <= \"110011000\";\r\n                -- Data 99\r\n                when \"0101110111\" => lookup <= \"110011001\";\r\n                when \"1110001000\" => lookup <= \"110011001\";\r\n                -- Data 9a\r\n                when \"0011011100\" => lookup <= \"110011010\";\r\n                when \"1000100011\" => lookup <= \"110011010\";\r\n                -- Data 9b\r\n                when \"1011011100\" => lookup <= \"110011011\";\r\n                when \"0000100011\" => lookup <= \"110011011\";\r\n                -- Data 9c\r\n                when \"0011011110\" => lookup <= \"110011100\";\r\n                when \"1000100001\" => lookup <= \"110011100\";\r\n                -- Data 9d\r\n                when \"1011011110\" => lookup <= \"110011101\";\r\n                when \"0000100001\" => lookup <= \"110011101\";\r\n                -- Data 9e\r\n                when \"1011011111\" => lookup <= \"110011110\";\r\n                when \"0000100000\" => lookup <= \"110011110\";\r\n                -- Data 9f\r\n                when \"0011011111\" => lookup <= \"110011111\";\r\n                when \"1000100000\" => lookup <= \"110011111\";\r\n                -- Data a0\r\n                when \"1110011111\" => lookup <= \"110100000\";\r\n                when \"0101100000\" => lookup <= \"110100000\";\r\n                -- Data a1\r\n                when \"0110011111\" => lookup <= \"110100001\";\r\n                when \"1101100000\" => lookup <= \"110100001\";\r\n                -- Data a2\r\n                when \"0110011110\" => lookup <= \"110100010\";\r\n                when \"1101100001\" => lookup <= \"110100010\";\r\n                -- Data a3\r\n                when \"1110011110\" => lookup <= \"110100011\";\r\n                when \"0101100001\" => lookup <= \"110100011\";\r\n                -- Data a4\r\n                when \"0110011100\" => lookup <= \"110100100\"; -- TERC4 1010\r\n                -- Data a5\r\n                when \"0101100011\" => lookup <= \"110100101\"; -- TERC4 1110\r\n                -- Data a6\r\n                when \"1000110111\" => lookup <= \"110100110\";\r\n                when \"0011001000\" => lookup <= \"110100110\";\r\n                -- Data a7\r\n                when \"0000110111\" => lookup <= \"110100111\";\r\n                when \"1011001000\" => lookup <= \"110100111\";\r\n                -- Data a8\r\n                when \"1101100111\" => lookup <= \"110101000\";\r\n                when \"0110011000\" => lookup <= \"110101000\";\r\n                -- Data a9\r\n                when \"0101100111\" => lookup <= \"110101001\";\r\n                when \"1110011000\" => lookup <= \"110101001\";\r\n                -- Data aa\r\n                when \"1000110011\" => lookup <= \"110101010\";\r\n                -- Data ab\r\n                when \"1011001100\" => lookup <= \"110101011\"; -- TERC4 1000 & HDMI Guard band (video C0 and Video C2) \r\n                -- Data ac\r\n                when \"0011001110\" => lookup <= \"110101100\";\r\n                when \"1000110001\" => lookup <= \"110101100\";\r\n                -- Data ad\r\n                when \"1011001110\" => lookup <= \"110101101\";\r\n                when \"0000110001\" => lookup <= \"110101101\";\r\n                -- Data ae\r\n                when \"1011001111\" => lookup <= \"110101110\";\r\n                when \"0000110000\" => lookup <= \"110101110\";\r\n                -- Data af\r\n                when \"0011001111\" => lookup <= \"110101111\";\r\n                when \"1000110000\" => lookup <= \"110101111\";\r\n                -- Data b0\r\n                when \"1101101111\" => lookup <= \"110110000\";\r\n                when \"0110010000\" => lookup <= \"110110000\";\r\n                -- Data b1\r\n                when \"0101101111\" => lookup <= \"110110001\";\r\n                when \"1110010000\" => lookup <= \"110110001\";\r\n                -- Data b2\r\n                when \"1000111011\" => lookup <= \"110110010\";\r\n                when \"0011000100\" => lookup <= \"110110010\";\r\n                -- Data b3\r\n                when \"0000111011\" => lookup <= \"110110011\";\r\n                when \"1011000100\" => lookup <= \"110110011\";\r\n                -- Data b4\r\n                when \"1000111001\" => lookup <= \"110110100\";\r\n                -- Data b5\r\n                when \"1011000110\" => lookup <= \"110110101\"; -- TERC4 1011\r\n                -- Data b6\r\n                when \"1011000111\" => lookup <= \"110110110\";\r\n                when \"0000111000\" => lookup <= \"110110110\";\r\n                -- Data b7\r\n                when \"0011000111\" => lookup <= \"110110111\";\r\n                when \"1000111000\" => lookup <= \"110110111\";\r\n                -- Data b8\r\n                when \"1000111101\" => lookup <= \"110111000\";\r\n                when \"0011000010\" => lookup <= \"110111000\";\r\n                -- Data b9\r\n                when \"0000111101\" => lookup <= \"110111001\";\r\n                when \"1011000010\" => lookup <= \"110111001\";\r\n                -- Data ba\r\n                when \"1011000011\" => lookup <= \"110111010\"; -- TERC4 1111\r\n                -- Data bb\r\n                when \"1000111100\" => lookup <= \"110111011\";\r\n                -- Data bc\r\n                when \"0000111110\" => lookup <= \"110111100\";\r\n                when \"1011000001\" => lookup <= \"110111100\";\r\n                -- Data bd\r\n                when \"1000111110\" => lookup <= \"110111101\";\r\n                when \"0011000001\" => lookup <= \"110111101\";\r\n                -- Data be\r\n                when \"1000111111\" => lookup <= \"110111110\";\r\n                when \"0011000000\" => lookup <= \"110111110\";\r\n                -- Data bf\r\n                when \"0000111111\" => lookup <= \"110111111\";\r\n                when \"1011000000\" => lookup <= \"110111111\";\r\n                -- Data c0\r\n                when \"1110111111\" => lookup <= \"111000000\";\r\n                when \"0101000000\" => lookup <= \"111000000\";\r\n                -- Data c1\r\n                when \"0110111111\" => lookup <= \"111000001\";\r\n                when \"1101000000\" => lookup <= \"111000001\";\r\n                -- Data c2\r\n                when \"0110111110\" => lookup <= \"111000010\";\r\n                when \"1101000001\" => lookup <= \"111000010\";\r\n                -- Data c3\r\n                when \"1110111110\" => lookup <= \"111000011\";\r\n                when \"0101000001\" => lookup <= \"111000011\";\r\n                -- Data c4\r\n                when \"0110111100\" => lookup <= \"111000100\";\r\n                when \"1101000011\" => lookup <= \"111000100\";\r\n                -- Data c5\r\n                when \"1110111100\" => lookup <= \"111000101\";\r\n                when \"0101000011\" => lookup <= \"111000101\";\r\n                -- Data c6\r\n                when \"1000010111\" => lookup <= \"111000110\";\r\n                -- Data c7\r\n                when \"1011101000\" => lookup <= \"111000111\";\r\n                -- Data c8\r\n                when \"0110111000\" => lookup <= \"111001000\";\r\n                -- Data c9\r\n                when \"0101000111\" => lookup <= \"111001001\";\r\n                -- Data ca\r\n                when \"0011101100\" => lookup <= \"111001010\";\r\n                when \"1000010011\" => lookup <= \"111001010\";\r\n                -- Data cb\r\n                when \"1011101100\" => lookup <= \"111001011\";\r\n                when \"0000010011\" => lookup <= \"111001011\";\r\n                -- Data cc\r\n                when \"0011101110\" => lookup <= \"111001100\";\r\n                when \"1000010001\" => lookup <= \"111001100\";\r\n                -- Data cd\r\n                when \"1011101110\" => lookup <= \"111001101\";\r\n                when \"0000010001\" => lookup <= \"111001101\";\r\n                -- Data ce\r\n                when \"1011101111\" => lookup <= \"111001110\";\r\n                when \"0000010000\" => lookup <= \"111001110\";\r\n                -- Data cf\r\n                when \"0011101111\" => lookup <= \"111001111\";\r\n                when \"1000010000\" => lookup <= \"111001111\";\r\n                -- Data d0\r\n                when \"1101001111\" => lookup <= \"111010000\";\r\n                when \"0110110000\" => lookup <= \"111010000\";\r\n                -- Data d1\r\n                when \"0101001111\" => lookup <= \"111010001\";\r\n                when \"1110110000\" => lookup <= \"111010001\";\r\n                -- Data d2\r\n                when \"1000011011\" => lookup <= \"111010010\";\r\n                -- Data d3\r\n                when \"1011100100\" => lookup <= \"111010011\"; -- TERC4 0010\r\n                -- Data d4\r\n                when \"0011100110\" => lookup <= \"111010100\";\r\n                when \"1000011001\" => lookup <= \"111010100\";\r\n                -- Data d5\r\n                when \"1011100110\" => lookup <= \"111010101\";\r\n                when \"0000011001\" => lookup <= \"111010101\";\r\n                -- Data d6\r\n                when \"1011100111\" => lookup <= \"111010110\";\r\n                when \"0000011000\" => lookup <= \"111010110\";\r\n                -- Data d7\r\n                when \"0011100111\" => lookup <= \"111010111\";\r\n                when \"1000011000\" => lookup <= \"111010111\";\r\n                -- Data d8\r\n                when \"1000011101\" => lookup <= \"111011000\";\r\n                -- Data d9\r\n                when \"1011100010\" => lookup <= \"111011001\"; -- TERC4 0011\r\n                -- Data da\r\n                when \"1011100011\" => lookup <= \"111011010\";\r\n                when \"0000011100\" => lookup <= \"111011010\";\r\n                -- Data db\r\n                when \"0011100011\" => lookup <= \"111011011\";\r\n                when \"1000011100\" => lookup <= \"111011011\";\r\n                -- Data dc\r\n                when \"1011100001\" => lookup <= \"111011100\";\r\n                -- Data dd\r\n                when \"1000011110\" => lookup <= \"111011101\";\r\n                -- Data de\r\n                when \"1000011111\" => lookup <= \"111011110\";\r\n                when \"0011100000\" => lookup <= \"111011110\";\r\n                -- Data df\r\n                when \"0000011111\" => lookup <= \"111011111\";\r\n                when \"1011100000\" => lookup <= \"111011111\";\r\n                -- Data e0\r\n                when \"1101011111\" => lookup <= \"111100000\";\r\n                when \"0110100000\" => lookup <= \"111100000\";\r\n                -- Data e1\r\n                when \"0101011111\" => lookup <= \"111100001\";\r\n                when \"1110100000\" => lookup <= \"111100001\";\r\n                -- Data e2\r\n                when \"0011110100\" => lookup <= \"111100010\";\r\n                when \"1000001011\" => lookup <= \"111100010\";\r\n                -- Data e3\r\n                when \"1011110100\" => lookup <= \"111100011\";\r\n                when \"0000001011\" => lookup <= \"111100011\";\r\n                -- Data e4\r\n                when \"0011110110\" => lookup <= \"111100100\";\r\n                when \"1000001001\" => lookup <= \"111100100\";\r\n                -- Data e5\r\n                when \"1011110110\" => lookup <= \"111100101\";\r\n                when \"0000001001\" => lookup <= \"111100101\";\r\n                -- Data e6\r\n                when \"1011110111\" => lookup <= \"111100110\";\r\n                when \"0000001000\" => lookup <= \"111100110\";\r\n                -- Data e7\r\n                when \"0011110111\" => lookup <= \"111100111\";\r\n                when \"1000001000\" => lookup <= \"111100111\";\r\n                -- Data e8\r\n                when \"0011110010\" => lookup <= \"111101000\";\r\n                when \"1000001101\" => lookup <= \"111101000\";\r\n                -- Data e9\r\n                when \"1011110010\" => lookup <= \"111101001\";\r\n                when \"0000001101\" => lookup <= \"111101001\";\r\n                -- Data ea\r\n                when \"1011110011\" => lookup <= \"111101010\";\r\n                when \"0000001100\" => lookup <= \"111101010\";\r\n                -- Data eb\r\n                when \"0011110011\" => lookup <= \"111101011\";\r\n                when \"1000001100\" => lookup <= \"111101011\";\r\n                -- Data ec\r\n                when \"1011110001\" => lookup <= \"111101100\";\r\n                when \"0000001110\" => lookup <= \"111101100\";\r\n                -- Data ed\r\n                when \"0011110001\" => lookup <= \"111101101\";\r\n                when \"1000001110\" => lookup <= \"111101101\";\r\n                -- Data ee\r\n                when \"1000001111\" => lookup <= \"111101110\";\r\n                -- Data ef\r\n                when \"1011110000\" => lookup <= \"111101111\";\r\n                -- Data f0\r\n                when \"0011111010\" => lookup <= \"111110000\";\r\n                when \"1000000101\" => lookup <= \"111110000\";\r\n                -- Data f1\r\n                when \"1011111010\" => lookup <= \"111110001\";\r\n                when \"0000000101\" => lookup <= \"111110001\";\r\n                -- Data f2\r\n                when \"1011111011\" => lookup <= \"111110010\";\r\n                when \"0000000100\" => lookup <= \"111110010\";\r\n                -- Data f3\r\n                when \"0011111011\" => lookup <= \"111110011\";\r\n                when \"1000000100\" => lookup <= \"111110011\";\r\n                -- Data f4\r\n                when \"1011111001\" => lookup <= \"111110100\";\r\n                when \"0000000110\" => lookup <= \"111110100\";\r\n                -- Data f5\r\n                when \"0011111001\" => lookup <= \"111110101\";\r\n                when \"1000000110\" => lookup <= \"111110101\";\r\n                -- Data f6\r\n                when \"0011111000\" => lookup <= \"111110110\";\r\n                when \"1000000111\" => lookup <= \"111110110\";\r\n                -- Data f7\r\n                when \"1011111000\" => lookup <= \"111110111\";\r\n                when \"0000000111\" => lookup <= \"111110111\";\r\n                -- Data f8\r\n                when \"1011111101\" => lookup <= \"111111000\";\r\n                when \"0000000010\" => lookup <= \"111111000\";\r\n                -- Data f9\r\n                when \"0011111101\" => lookup <= \"111111001\";\r\n                when \"1000000010\" => lookup <= \"111111001\";\r\n                -- Data fa\r\n                when \"0011111100\" => lookup <= \"111111010\";\r\n                when \"1000000011\" => lookup <= \"111111010\";\r\n                -- Data fb\r\n                when \"1011111100\" => lookup <= \"111111011\";\r\n                when \"0000000011\" => lookup <= \"111111011\";\r\n                -- Data fc\r\n                when \"0011111110\" => lookup <= \"111111100\";\r\n                when \"1000000001\" => lookup <= \"111111100\";\r\n                -- Data fd\r\n                when \"1011111110\" => lookup <= \"111111101\";\r\n                when \"0000000001\" => lookup <= \"111111101\";\r\n                -- Data fe\r\n                when \"1011111111\" => lookup <= \"111111110\";\r\n                when \"0000000000\" => lookup <= \"111111110\";\r\n                -- Data ff\r\n                when \"0011111111\" => lookup <= \"111111111\";\r\n                when \"1000000000\" => lookup <= \"111111111\";\r\n                \r\n                -- DVI-D CTL symbols        \r\n                when \"0010101011\" => lookup <= \"01\" & \"00000\" &  \"01\";  -- CTL1\r\n                when \"0101010100\" => lookup <= \"01\" & \"00000\" &  \"10\";  -- CTL2\r\n                when \"1010101011\" => lookup <= \"01\" & \"00000\" &  \"11\";  -- CTL3\r\n                when \"1101010100\" => lookup <= \"01\" & \"00000\" &  \"00\";  -- CTL0\r\n                \r\n                -- Invalid symbols\r\n                when others       => lookup <= \"0000\" & \"00000\"; \r\n            end case;\r\n        end if;\r\n    end process;\r\nend Behavioral;\r\n\r\n-- For Guard band and TERC4 decoding (to be done later!) \r\n-- when x\"55\" => -- \"0100110011\" HDMI Guard band (video C1, data C1 & C2)\r\n-- when x\"5B\" => -- \"1010011100\" TERC4 0000\r\n-- when x\"5A\" => -- \"1001100011\" TERC4 0001\r\n-- when x\"D3\" => -- \"1011100100\" TERC4 0010\r\n-- when x\"D9\" => -- \"1011100010\" TERC4 0011\r\n-- when x\"93\" => -- \"0101110001\" TERC4 0100\r\n-- when x\"22\" => -- \"0100011110\" TERC4 0101\r\n-- when x\"92\" => -- \"0110001110\" TERC4 0110\r\n-- when x\"44\" => -- \"0100111100\" TERC4 0111\r\n-- when x\"AB\" => -- \"1011001100\" TERC4 1000 & HDMI Guard band (video C0 and Video C2) \r\n-- when x\"4B\" => -- \"0100111001\" TERC4 1001\r\n-- when x\"A4\" => -- \"0110011100\" TERC4 1010\r\n-- when x\"B5\" => -- \"1011000110\" TERC4 1011\r\n-- when x\"6D\" => -- \"1010001110\" TERC4 1100\r\n-- when x\"6C\" => -- \"1001110001\" TERC4 1101\r\n-- when x\"A5\" => -- \"0101100011\" TERC4 1110\r\n-- when x\"BA\" => -- \"1011000011\" TERC4 1111"
  },
  {
    "path": "src/tmds_encoder.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: tmds_encoder - Behavioral   \r\n--\r\n-- Description: 8b/10b TMDS encoder \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.STD_LOGIC_UNSIGNED.ALL;\r\n\r\nentity tmds_encoder is\r\n   Port ( clk     : in  std_logic;\r\n          data    : in  std_logic_vector (7 downto 0);\r\n          c       : in  std_logic_vector (1 downto 0);\r\n          blank   : in  std_logic;\r\n          encoded : out std_logic_vector (9 downto 0));\r\nend entity;\r\n\r\narchitecture Behavioral of tmds_encoder is  \r\n    signal xored  : STD_LOGIC_VECTOR (8 downto 0);\r\n    signal xnored : STD_LOGIC_VECTOR (8 downto 0);\r\n    \r\n    signal ones                : STD_LOGIC_VECTOR (3 downto 0);\r\n    signal data_word           : STD_LOGIC_VECTOR (8 downto 0);\r\n    signal data_word_inv       : STD_LOGIC_VECTOR (8 downto 0);\r\n    signal data_word_disparity : STD_LOGIC_VECTOR (3 downto 0);\r\n    signal dc_bias             : STD_LOGIC_VECTOR (3 downto 0) := (others => '0');\r\nbegin\r\n    -- Work our the two different encodings for the byte\r\n    xored(0) <= data(0);\r\n    xored(1) <= data(1) xor xored(0);\r\n    xored(2) <= data(2) xor xored(1);\r\n    xored(3) <= data(3) xor xored(2);\r\n    xored(4) <= data(4) xor xored(3);\r\n    xored(5) <= data(5) xor xored(4);\r\n    xored(6) <= data(6) xor xored(5);\r\n    xored(7) <= data(7) xor xored(6);\r\n    xored(8) <= '1';\r\n    \r\n    xnored(0) <= data(0);\r\n    xnored(1) <= data(1) xnor xnored(0);\r\n    xnored(2) <= data(2) xnor xnored(1);\r\n    xnored(3) <= data(3) xnor xnored(2);\r\n    xnored(4) <= data(4) xnor xnored(3);\r\n    xnored(5) <= data(5) xnor xnored(4);\r\n    xnored(6) <= data(6) xnor xnored(5);\r\n    xnored(7) <= data(7) xnor xnored(6);\r\n    xnored(8) <= '0';\r\n    \r\n    -- Count how many ones are set in data\r\n    ones <= \"0000\" + data(0) + data(1) + data(2) + data(3)\r\n                    + data(4) + data(5) + data(6) + data(7);\r\n\r\n-- Decide which encoding to use\r\nprocess(ones, data(0), xnored, xored)\r\nbegin\r\n   if ones > 4 or (ones = 4 and data(0) = '0') then\r\n      data_word     <= xnored;\r\n      data_word_inv <= NOT(xnored);\r\n   else\r\n      data_word     <= xored;\r\n      data_word_inv <= NOT(xored);\r\n   end if;\r\nend process;                                          \r\n\r\n-- Work out the DC bias of the dataword;\r\ndata_word_disparity  <= \"1100\" + data_word(0) + data_word(1) + data_word(2) + data_word(3) \r\n                                 + data_word(4) + data_word(5) + data_word(6) + data_word(7);\r\n\r\n-- Now work out what the output should be\r\nprocess(clk)\r\n    begin\r\n       if rising_edge(clk) then\r\n          if blank = '1' then \r\n             -- In the control periods, all values have and have balanced bit count\r\n             case c is            \r\n                when \"00\"   => encoded <= \"1101010100\";\r\n                when \"01\"   => encoded <= \"0010101011\";\r\n                when \"10\"   => encoded <= \"0101010100\";\r\n                when others => encoded <= \"1010101011\";\r\n             end case;\r\n             dc_bias <= (others => '0');\r\n          else\r\n             if dc_bias = \"00000\" or data_word_disparity = 0 then\r\n                -- dataword has no disparity\r\n                if data_word(8) = '1' then\r\n                   encoded <= \"01\" & data_word(7 downto 0);\r\n                   dc_bias <= dc_bias + data_word_disparity;\r\n                else\r\n                   encoded <= \"10\" & data_word_inv(7 downto 0);\r\n                   dc_bias <= dc_bias - data_word_disparity;\r\n                end if;\r\n             elsif (dc_bias(3) = '0' and data_word_disparity(3) = '0') or \r\n                   (dc_bias(3) = '1' and data_word_disparity(3) = '1') then\r\n                encoded <= '1' & data_word(8) & data_word_inv(7 downto 0);\r\n                dc_bias <= dc_bias + data_word(8) - data_word_disparity;\r\n             else\r\n                encoded <= '0' & data_word;\r\n                dc_bias <= dc_bias - data_word_inv(8) + data_word_disparity;\r\n             end if;\r\n          end if;\r\n       end if;\r\n    end process;      \r\nend Behavioral;"
  },
  {
    "path": "test_bench/hdmi_test_generator/hdmi_ouput_test.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Top level design for my minimal HDMI output project\r\n--\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity hdmi_output_test is\r\n    Port ( clk50         : in  STD_LOGIC;\r\n\r\n           hdmi_out_p : out  STD_LOGIC_VECTOR(3 downto 0);\r\n           hdmi_out_n : out  STD_LOGIC_VECTOR(3 downto 0);\r\n                      \r\n           leds       : out std_logic_vector(7 downto 0));\r\nend hdmi_output_test;\r\n\r\narchitecture Behavioral of hdmi_output_test is\r\n\r\n   COMPONENT vga_gen\r\n   PORT(\r\n      clk50           : IN std_logic;          \r\n      pixel_clock     : OUT std_logic;\r\n      red_p           : OUT std_logic_vector(7 downto 0);\r\n      green_p         : OUT std_logic_vector(7 downto 0);\r\n      blue_p          : OUT std_logic_vector(7 downto 0);\r\n      blank           : OUT std_logic;\r\n      hsync           : OUT std_logic;\r\n      vsync           : OUT std_logic\r\n      );\r\n   END COMPONENT;\r\n\r\n   COMPONENT Minimal_hdmi_symbols\r\n   PORT(\r\n      clk : IN std_logic;\r\n      blank : IN std_logic;\r\n      hsync : IN std_logic;\r\n      vsync : IN std_logic;\r\n      red   : IN std_logic;\r\n      green : IN std_logic;\r\n      blue  : IN std_logic;          \r\n      c0    : OUT std_logic_vector(9 downto 0);          \r\n      c1    : OUT std_logic_vector(9 downto 0);          \r\n      c2    : OUT std_logic_vector(9 downto 0)         \r\n      );\r\n   END COMPONENT;\r\n \r\n\tCOMPONENT serializers\r\n\tPORT(\r\n\t\tclk : IN std_logic;\r\n\t\tc0 : IN std_logic_vector(9 downto 0);\r\n\t\tc1 : IN std_logic_vector(9 downto 0);\r\n\t\tc2 : IN std_logic_vector(9 downto 0);          \r\n\t\thdmi_p : OUT std_logic_vector(3 downto 0);\r\n\t\thdmi_n : OUT std_logic_vector(3 downto 0)\r\n\t\t);\r\n\tEND COMPONENT;\r\n \r\n   signal pixel_clock     : std_logic;\r\n\r\n   signal red_p   : std_logic_vector(7 downto 0);\r\n   signal green_p : std_logic_vector(7 downto 0);\r\n   signal blue_p  : std_logic_vector(7 downto 0);\r\n   signal blank   : std_logic;\r\n   signal hsync   : std_logic;\r\n   signal vsync   : std_logic;          \r\n\r\n   signal c0, c1, c2 : std_logic_vector(9 downto 0);\r\nbegin\r\n   leds <= x\"AA\";\r\n   \r\n---------------------------------------\r\n-- Generate a 1280x720 VGA test pattern\r\n---------------------------------------\r\nInst_vga_gen: vga_gen PORT MAP(\r\n      clk50 => clk50,\r\n      pixel_clock     => pixel_clock,      \r\n      red_p           => red_p,\r\n      green_p         => green_p,\r\n      blue_p          => blue_p,\r\n      blank           => blank,\r\n      hsync           => hsync,\r\n      vsync           => vsync\r\n   );\r\n\r\n---------------------------------------------------\r\n-- Convert 9 bits of the VGA signals to the DVI-D/TMDS output \r\n---------------------------------------------------\r\ni_Minimal_hdmi_symbols: Minimal_hdmi_symbols PORT MAP(\r\n      clk    => pixel_clock,\r\n      blank  => blank,\r\n      hsync  => hsync,\r\n      vsync  => vsync,\r\n      red    => red_p(7),\r\n      green  => green_p(7),\r\n      blue   => blue_p(7),\r\n      c0     => c0,\r\n      c1     => c1,\r\n      c2     => c2\r\n   );\r\n\r\ni_serializers : serializers PORT MAP (\r\n      clk    => pixel_clock,\r\n      c0     => c0,\r\n      c1     => c1,\r\n      c2     => c2,\r\n      hdmi_p => hdmi_out_p,\r\n      hdmi_n => hdmi_out_n);\r\n      \r\nend Behavioral;\r\n\r\n"
  },
  {
    "path": "test_bench/hdmi_test_generator/minimal_hdmi_symbols.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz<\r\n-- \r\n-- Description: A minimal set of TMDS symbols - just enough to send a valid \r\n--              HDMI stream\r\n--\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity minimal_hdmi_symbols is\r\n    Port ( clk : in  STD_LOGIC;\r\n           hsync, vsync,  blank : in  STD_LOGIC;\r\n           red,   green,  blue  : in  STD_LOGIC;\r\n           c0,    c1,     c2    : out STD_LOGIC_VECTOR (9 downto 0));\r\nend minimal_hdmi_symbols;\r\n\r\narchitecture Behavioral of minimal_hdmi_symbols is\r\n   type a_symbol_queue is array (0 to 10) of STD_LOGIC_VECTOR (4 downto 0);\r\n   \r\n   signal symbol_queue : a_symbol_queue                  := (others => (others => '0'));\r\n   signal symbols      :  STD_LOGIC_VECTOR (29 downto 0) := (others => '0');\r\n   \r\n   signal last_blank : std_logic := '0';\r\n   signal last_vsync : std_logic := '0';\r\n   signal last_hsync : std_logic := '0';\r\n   \r\n   signal data_island_armed : std_logic := '0';\r\n   signal data_island_index : unsigned(5 downto 0) := (others => '1');\r\nbegin\r\n   c0 <= symbols(29 downto 20);\r\n   c1 <= symbols(19 downto 10);\r\n   c2 <= symbols( 9 downto  0);\r\n\r\nprocess(clk) \r\n   begin\r\n      if rising_edge(clk) then\r\n         case symbol_queue(0) is  \r\n            ---------------------------------------------------------------\r\n            -- Eight TMDS encoded colours for testing\r\n            ---------------------------------------------------------------\r\n            when \"00000\" => symbols <= \"0111110000\" & \"0111110000\" & \"0111110000\"; -- RGB 0x101010 - Black\r\n            when \"00001\" => symbols <= \"0111110000\" & \"0111110000\" & \"1011110000\"; -- RGB 0xEF1010 - Red\r\n            when \"00010\" => symbols <= \"0111110000\" & \"1011110000\" & \"0111110000\"; -- RGB 0x10EF10 - Green\r\n            when \"00011\" => symbols <= \"0111110000\" & \"1011110000\" & \"1011110000\"; -- RGB 0xEFEF10 - Cyan\r\n            when \"00100\" => symbols <= \"1011110000\" & \"0111110000\" & \"0111110000\"; -- RGB 0x1010EF - Blue\r\n            when \"00101\" => symbols <= \"1011110000\" & \"0111110000\" & \"1011110000\"; -- RGB 0xEF10EF - Magenta\r\n            when \"00110\" => symbols <= \"1011110000\" & \"1011110000\" & \"0111110000\"; -- RGB 0x10EFEF - Yellow\r\n            when \"00111\" => symbols <= \"1011110000\" & \"1011110000\" & \"1011110000\"; -- RGB 0xEFEFEF - White\r\n            ---------------------------------------------------------------\r\n            -- control symbols from 5.4.2 - part of the DVI-D standard\r\n            ---------------------------------------------------------------\r\n            when \"01000\" => symbols <= \"1101010100\" & \"1101010100\" & \"1101010100\"; -- CTL periods\r\n            when \"01001\" => symbols <= \"0010101011\" & \"1101010100\" & \"1101010100\"; -- Hsync\r\n            when \"01010\" => symbols <= \"0101010100\" & \"1101010100\" & \"1101010100\"; -- vSync\r\n            when \"01011\" => symbols <= \"1010101011\" & \"1101010100\" & \"1101010100\"; -- vSync+hSync\r\n            ---------------------------------------------------------------\r\n            -- Symbols to signal the start of a HDMI feature \r\n            ---------------------------------------------------------------\r\n            when \"01100\" => symbols <= \"0101010100\" & \"0010101011\" & \"0010101011\"; -- DataIslandPeamble, with VSYNC - 5.2.1.1\r\n            when \"01101\" => symbols <= \"0101100011\" & \"0100110011\" & \"0100110011\"; -- DataIslandGuardBand, with VSYNC - 5.2.3.3\t\r\n            when \"01110\" => symbols <= \"1101010100\" & \"0010101011\" & \"1101010100\"; -- VideoPramble 5.2.1.1\r\n            when \"01111\" => symbols <= \"1011001100\" & \"0100110011\" & \"1011001100\"; -- VideoGuardBand 5.2.2.1\r\n\r\n            ---------------------------------------------------------------\r\n            -- From TERC4 codes in 5.4.3, and data data layout from 5.2.3.1\r\n            --\r\n            -- First nibble  is used for the nFirstWordOfPacket (MSB) Header Bit, VSYNC, HSYNC (LSB).\r\n            -- The packet is sent where VSYNC = '1' and HSYNC = '0', so we are left with 4 options            \r\n            -- Second nibble is used for the odd bits the four data sub-packets\r\n            -- Third nibble  is used for the even bits the four data sub-packets\r\n            --\r\n            -- These can be used to contruct a data island with any header\r\n            -- and any data in subpacket 0, but all other subpackets \r\n            -- must be 0s.\r\n            ---------------------------------------------------------------\r\n            when \"10000\" => symbols <= \"1011100100\" & \"1010011100\" & \"1010011100\"; -- 0010 0000 0000, TERC4 coded\r\n            when \"10001\" => symbols <= \"1011100100\" & \"1010011100\" & \"1001100011\"; -- 0010 0000 0001, TERC4 coded\r\n            when \"10010\" => symbols <= \"1011100100\" & \"1001100011\" & \"1010011100\"; -- 0010 0000 0000, TERC4 coded\r\n            when \"10011\" => symbols <= \"1011100100\" & \"1001100011\" & \"1001100011\"; -- 0010 0001 0001, TERC4 coded\r\n            when \"10100\" => symbols <= \"0110001110\" & \"1010011100\" & \"1010011100\"; -- 0110 0000 0000, TERC4 coded\r\n            when \"10101\" => symbols <= \"0110001110\" & \"1010011100\" & \"1001100011\"; -- 0110 0000 0001, TERC4 coded\r\n            when \"10110\" => symbols <= \"0110001110\" & \"1001100011\" & \"1010011100\"; -- 0110 0001 0000, TERC4 coded\r\n            when \"10111\" => symbols <= \"0110001110\" & \"1001100011\" & \"1001100011\"; -- 0110 0001 0001, TERC4 coded\r\n            when \"11000\" => symbols <= \"0110011100\" & \"1010011100\" & \"1010011100\"; -- 1010 0000 0000, TERC4 coded\r\n            when \"11001\" => symbols <= \"0110011100\" & \"1010011100\" & \"1001100011\"; -- 1010 0000 0001, TERC4 coded\r\n            when \"11010\" => symbols <= \"0110011100\" & \"1001100011\" & \"1010011100\"; -- 1010 0001 0000, TERC4 coded\r\n            when \"11011\" => symbols <= \"0110011100\" & \"1001100011\" & \"1001100011\"; -- 1010 0001 0001, TERC4 coded\r\n            when \"11100\" => symbols <= \"0101100011\" & \"1010011100\" & \"1010011100\"; -- 1110 0000 0000, TERC4 coded\r\n            when \"11101\" => symbols <= \"0101100011\" & \"1010011100\" & \"1001100011\"; -- 1110 0000 0001, TERC4 coded\r\n            when \"11110\" => symbols <= \"0101100011\" & \"1001100011\" & \"1010011100\"; -- 1110 0001 0000, TERC4 coded\r\n            when \"11111\" => symbols <= \"0101100011\" & \"1001100011\" & \"1001100011\"; -- 1110 0001 0001, TERC4 coded\r\n\r\n            when others => symbols <= (others => '0');\r\n         end case;\r\n   \r\n         if blank = '0' then\r\n            -- Are we being asked to send video data? If so we need to send a peramble\r\n            if last_blank = '1' then\r\n               symbol_queue(10) <= \"00\" & blue & green & red;\r\n               symbol_queue(9) <= \"01111\";  -- Video Guard Band\r\n               symbol_queue(8) <= \"01111\"; \r\n               symbol_queue(7) <= \"01110\";  -- Video Preamble\r\n               symbol_queue(6) <= \"01110\";\r\n               symbol_queue(5) <= \"01110\";\r\n               symbol_queue(4) <= \"01110\";\r\n               symbol_queue(3) <= \"01110\";\r\n               symbol_queue(2) <= \"01110\";\r\n               symbol_queue(1) <= \"01110\";\r\n               symbol_queue(0) <= \"01110\";\r\n            else\r\n               symbol_queue(0 to 9) <= symbol_queue(1 to 10);\r\n               symbol_queue(10) <= \"00\" & blue & green & red;\r\n            end if;\r\n         else\r\n           -- Just merge in the syncs into the control period\r\n           case data_island_index is\r\n               when \"000000\" => symbol_queue(10) <= \"01100\"; -- Data island preamble\r\n               when \"000001\" => symbol_queue(10) <= \"01100\"; -- Data island preamble\r\n               when \"000010\" => symbol_queue(10) <= \"01100\"; -- Data island preamble\r\n               when \"000011\" => symbol_queue(10) <= \"01100\"; -- Data island preamble\r\n               when \"000100\" => symbol_queue(10) <= \"01100\"; -- Data island preamble\r\n               when \"000101\" => symbol_queue(10) <= \"01100\"; -- Data island preamble\r\n               when \"000110\" => symbol_queue(10) <= \"01100\"; -- Data island preamble\r\n               when \"000111\" => symbol_queue(10) <= \"01100\"; -- Data island preamble\r\n               when \"001000\" => symbol_queue(10) <= \"01101\"; -- Data island Guard Band\r\n               when \"001001\" => symbol_queue(10) <= \"01101\"; -- Data island Guard Band\r\n\r\n\r\n               -------------------------\r\n               -- For a YCC mode AVI Infoframe Data Island\r\n               -------------------------\r\n                  -- Data Island (0-7)\r\n               when \"001010\" => symbol_queue(10) <= \"10011\"; -- First word \r\n               when \"001011\" => symbol_queue(10) <= \"11111\";\r\n               when \"001100\" => symbol_queue(10) <= \"11001\";\r\n               when \"001101\" => symbol_queue(10) <= \"11000\";\r\n               when \"001110\" => symbol_queue(10) <= \"11000\";\r\n               when \"001111\" => symbol_queue(10) <= \"11000\";\r\n               when \"010000\" => symbol_queue(10) <= \"11000\";\r\n               when \"010001\" => symbol_queue(10) <= \"11110\";\r\n                  -- Data Island (8-15)\r\n               when \"010010\" => symbol_queue(10) <= \"11000\";\r\n               when \"010011\" => symbol_queue(10) <= \"11100\";\r\n               when \"010100\" => symbol_queue(10) <= \"11000\";\r\n               when \"010101\" => symbol_queue(10) <= \"11000\";\r\n               when \"010110\" => symbol_queue(10) <= \"11000\";\r\n               when \"010111\" => symbol_queue(10) <= \"11000\";\r\n               when \"011000\" => symbol_queue(10) <= \"11000\";\r\n               when \"011001\" => symbol_queue(10) <= \"11000\";\r\n                 -- Data Island (16-23)\r\n               when \"011010\" => symbol_queue(10) <= \"11100\";\r\n               when \"011011\" => symbol_queue(10) <= \"11000\";\r\n               when \"011100\" => symbol_queue(10) <= \"11100\";\r\n               when \"011101\" => symbol_queue(10) <= \"11100\";\r\n               when \"011110\" => symbol_queue(10) <= \"11000\";\r\n               when \"011111\" => symbol_queue(10) <= \"11000\";\r\n               when \"100000\" => symbol_queue(10) <= \"11000\";\r\n               when \"100001\" => symbol_queue(10) <= \"11000\";\r\n                  -- Data Island (24-31)\r\n               when \"100010\" => symbol_queue(10) <= \"11000\";\r\n               when \"100011\" => symbol_queue(10) <= \"11000\";\r\n               when \"100100\" => symbol_queue(10) <= \"11100\";\r\n               when \"100101\" => symbol_queue(10) <= \"11000\";\r\n               when \"100110\" => symbol_queue(10) <= \"11010\";\r\n               when \"100111\" => symbol_queue(10) <= \"11100\";\r\n               when \"101000\" => symbol_queue(10) <= \"11111\";\r\n               when \"101001\" => symbol_queue(10) <= \"11110\";\r\n\r\n               -------------------------\r\n               -- For a NULL Data Island\r\n               -------------------------\r\n               -- Data Island (0-7)\r\n--               when \"001010\" => symbol_queue(10) <= \"10000\"; -- First word \r\n--               when \"001011\" => symbol_queue(10) <= \"11000\";\r\n--               when \"001100\" => symbol_queue(10) <= \"11000\";\r\n--               when \"001101\" => symbol_queue(10) <= \"11000\";\r\n--               when \"001110\" => symbol_queue(10) <= \"11000\";\r\n--               when \"001111\" => symbol_queue(10) <= \"11000\";\r\n--               when \"010000\" => symbol_queue(10) <= \"11000\";\r\n--               when \"010001\" => symbol_queue(10) <= \"11000\";\r\n                  -- Data Island (8-15)\r\n--               when \"010010\" => symbol_queue(10) <= \"11000\";\r\n--               when \"010011\" => symbol_queue(10) <= \"11000\";\r\n--               when \"010100\" => symbol_queue(10) <= \"11000\";\r\n--               when \"010101\" => symbol_queue(10) <= \"11000\";\r\n--               when \"010110\" => symbol_queue(10) <= \"11000\";\r\n--               when \"010111\" => symbol_queue(10) <= \"11000\";\r\n--               when \"011000\" => symbol_queue(10) <= \"11000\";\r\n--               when \"011001\" => symbol_queue(10) <= \"11000\";\r\n                 -- Data Island (16-23)\r\n--               when \"011010\" => symbol_queue(10) <= \"11000\";\r\n--               when \"011011\" => symbol_queue(10) <= \"11000\";\r\n--               when \"011100\" => symbol_queue(10) <= \"11000\";\r\n--               when \"011101\" => symbol_queue(10) <= \"11000\";\r\n--               when \"011110\" => symbol_queue(10) <= \"11000\";\r\n--               when \"011111\" => symbol_queue(10) <= \"11000\";\r\n--               when \"100000\" => symbol_queue(10) <= \"11000\";\r\n--               when \"100001\" => symbol_queue(10) <= \"11000\";\r\n                  -- Data Island (24-31)\r\n--               when \"100010\" => symbol_queue(10) <= \"11000\";\r\n--               when \"100011\" => symbol_queue(10) <= \"11000\";\r\n--               when \"100100\" => symbol_queue(10) <= \"11000\";\r\n--               when \"100101\" => symbol_queue(10) <= \"11000\";\r\n--               when \"100110\" => symbol_queue(10) <= \"11000\";\r\n--               when \"100111\" => symbol_queue(10) <= \"11000\";\r\n--               when \"101000\" => symbol_queue(10) <= \"11000\";\r\n--               when \"101001\" => symbol_queue(10) <= \"11000\";\r\n\r\n                  -- Trailing guard band\r\n               when \"101010\" => symbol_queue(10) <= \"01101\"; -- Data island Guard Band\r\n               when \"101011\" => symbol_queue(10) <= \"01101\"; -- Data island Guard Band\r\n                  -- There has to be four CTL symbols before the next block of video our data,\r\n                  -- But that won't be a problem for us, we will have the rest of the vertical \r\n                  -- Blanking interval\r\n               when others   => symbol_queue(10) <= \"010\" & Vsync & Hsync;\r\n           end case;\r\n           \r\n           symbol_queue(0 to 9) <= symbol_queue(1 to 10);\r\n         end if;\r\n\r\n         if data_island_index /= \"111111\" then\r\n            data_island_index  <= data_island_index  + 1;\r\n         end if;\r\n         \r\n         -- If we see the rising edge of vsync we need to send \r\n         -- a data island the next time we see the hsync signal\r\n         -- drop.\r\n         if last_vsync = '0' and vsync = '1' then\r\n            data_island_armed <= '1';\r\n         end if;\r\n\r\n         if data_island_armed = '1' and last_hsync = '1' and hsync = '0' then\r\n            data_island_index <= (others => '0');\r\n            data_island_armed <= '0';\r\n         end if;\r\n         \r\n         last_blank <= blank;\r\n         last_hsync <= hsync;\r\n         last_vsync <= vsync;\r\n      end if;\r\n   end process;\r\n\r\nend Behavioral;\r\n\r\n"
  },
  {
    "path": "test_bench/hdmi_test_generator/serializers.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Convert 3x 10-bit symbols to three serial channels and the clock channel.\r\n--\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity serializers is\r\n    Port ( clk : in  STD_LOGIC;\r\n           c0 : in  STD_LOGIC_VECTOR (9 downto 0);\r\n           c1 : in  STD_LOGIC_VECTOR (9 downto 0);\r\n           c2 : in  STD_LOGIC_VECTOR (9 downto 0);\r\n           hdmi_p : out  STD_LOGIC_VECTOR (3 downto 0);\r\n           hdmi_n : out  STD_LOGIC_VECTOR (3 downto 0));\r\nend serializers;\r\n\r\narchitecture Behavioral of serializers is\r\n   -- For holding the outward bound TMDS symbols in the slow and fast domain\r\n   signal c0_high_speed   : std_logic_vector(9 downto 0) := (others => '0');\r\n   signal c1_high_speed   : std_logic_vector(9 downto 0) := (others => '0');\r\n   signal c2_high_speed   : std_logic_vector(9 downto 0) := (others => '0');   \r\n   signal clk_high_speed  : std_logic_vector(9 downto 0) := (others => '0');\r\n   signal c2_output_bits  : std_logic_vector(1 downto 0) := \"00\";\r\n   signal c1_output_bits  : std_logic_vector(1 downto 0) := \"00\";\r\n   signal c0_output_bits  : std_logic_vector(1 downto 0) := \"00\";\r\n   signal clk_output_bits : std_logic_vector(1 downto 0) := \"00\";\r\n\r\n   -- Controlling the transfers into the high speed domain\r\n   signal latch_high_speed : std_logic_vector(4 downto 0) := \"00001\";\r\n   \r\n   -- From the DDR outputs to the output buffers\r\n   signal c0_serial, c1_serial, c2_serial, clk_serial : std_logic;\r\n\r\n   -- For generating the x5 clocks\r\n   signal clk_x5,  clk_x5_n, clk_x5_unbuffered  : std_logic;\r\n   signal clk_feedback    : std_logic;\r\n\r\n   -- To glue the HSYNC and VSYNC into the control character.\r\n   signal syncs           : std_logic_vector(1 downto 0);\r\nbegin\r\n\r\nprocess(clk_x5)\r\n   begin\r\n      ---------------------------------------------------------------\r\n      -- Now take the 10-bit words and take it into the high-speed\r\n      -- clock domain once every five cycles. \r\n      -- \r\n      -- Then send out two bits every clock cycle using DDR output\r\n      -- registers.\r\n      ---------------------------------------------------------------   \r\n      if rising_edge(clk_x5) then\r\n         c0_output_bits  <= c0_high_speed(1 downto 0);\r\n         c1_output_bits  <= c1_high_speed(1 downto 0);\r\n         c2_output_bits  <= c2_high_speed(1 downto 0);\r\n         clk_output_bits <= clk_high_speed(1 downto 0);\r\n\r\n         if latch_high_speed(0) = '1' then\r\n            c0_high_speed   <= c0;\r\n            c1_high_speed   <= c1;\r\n            c2_high_speed   <= c2;\r\n            clk_high_speed  <= \"0000011111\";\r\n         else\r\n            c0_high_speed   <= \"00\" & c0_high_speed(9 downto 2);\r\n            c1_high_speed   <= \"00\" & c1_high_speed(9 downto 2);\r\n            c2_high_speed   <= \"00\" & c2_high_speed(9 downto 2);\r\n            clk_high_speed  <= \"00\" & clk_high_speed(9 downto 2);\r\n         end if;\r\n         latch_high_speed <= latch_high_speed(0) & latch_high_speed(4 downto 1);\r\n      end if;\r\n   end process;\r\n\r\n   ------------------------------------------------------------------\r\n   -- Convert the TMDS codes into a serial stream, two bits at a time\r\n   ------------------------------------------------------------------\r\n   clk_x5_n <= not clk_x5;\r\nc0_to_serial: ODDR2\r\n   generic map(DDR_ALIGNMENT => \"C0\", INIT => '0', SRTYPE => \"ASYNC\") \r\n   port map (C0 => clk_x5,  C1 => clk_x5_n, CE => '1', R => '0', S => '0',\r\n             D0 => C0_output_bits(0), D1 => C0_output_bits(1), Q => c0_serial);\r\nOBUFDS_c0  : OBUFDS port map ( O  => hdmi_p(0), OB => hdmi_n(0), I => c0_serial);\r\n\r\nc1_to_serial: ODDR2\r\n   generic map(DDR_ALIGNMENT => \"C0\", INIT => '0', SRTYPE => \"ASYNC\") \r\n   port map (C0 => clk_x5,  C1 => clk_x5_n, CE => '1', R => '0', S => '0',\r\n             D0 => C1_output_bits(0), D1 => C1_output_bits(1), Q  => c1_serial);\r\nOBUFDS_c1  : OBUFDS port map ( O  => hdmi_p(1), OB => hdmi_n(1), I => c1_serial);\r\n   \r\nc2_to_serial: ODDR2\r\n   generic map(DDR_ALIGNMENT => \"C0\", INIT => '0', SRTYPE => \"ASYNC\") \r\n   port map (C0 => clk_x5,  C1 => clk_x5_n, CE => '1', R => '0', S => '0',\r\n             D0 => C2_output_bits(0), D1 => C2_output_bits(1), Q  => c2_serial);\r\nOBUFDS_c2  : OBUFDS port map ( O  => hdmi_p(2), OB => hdmi_n(2), I => c2_serial);\r\n\r\nclk_to_serial: ODDR2\r\n   generic map(DDR_ALIGNMENT => \"C0\", INIT => '0', SRTYPE => \"ASYNC\") \r\n   port map (C0 => clk_x5,  C1 => clk_x5_n, CE => '1', R => '0', S => '0',\r\n             D0 => Clk_output_bits(0), D1 => Clk_output_bits(1), Q  => clk_serial);\r\nOBUFDS_clk : OBUFDS port map ( O  => hdmi_p(3), OB => hdmi_n(3), I => clk_serial);\r\n   \r\n   ------------------------------------------------------------------\r\n   -- Use a PLL to generate a x5 clock, which is used to drive \r\n   -- the DDR registers.This allows 10 bits to be sent for every \r\n   -- pixel clock\r\n   ------------------------------------------------------------------\r\nPLL_BASE_inst : PLL_BASE\r\n   generic map (\r\n      CLKFBOUT_MULT => 10,                  \r\n      CLKOUT0_DIVIDE => 2,       CLKOUT0_PHASE => 0.0,   -- Output 5x original frequency\r\n      CLK_FEEDBACK => \"CLKFBOUT\",\r\n      CLKIN_PERIOD => 13.33,\r\n      DIVCLK_DIVIDE => 1\r\n   )\r\n      port map (\r\n      CLKFBOUT => clk_feedback, \r\n      CLKOUT0  => clk_x5_unbuffered,\r\n      CLKFBIN  => clk_feedback,    \r\n      CLKIN    => clk, \r\n      RST      => '0'\r\n   );\r\n\r\nBUFG_pclkx5  : BUFG port map ( I => clk_x5_unbuffered,  O => clk_x5);\r\n\r\nend Behavioral;\r\n\r\n"
  },
  {
    "path": "test_bench/hdmi_test_generator/vga_clocking.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz<\r\n-- \r\n-- Description: Generate a 40Mhz Pixel clock from the 50Mhz input\r\n--\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nlibrary UNISIM;\r\nuse UNISIM.VComponents.all;\r\n\r\nentity vga_clocking is\r\n    Port ( clk50           : in  STD_LOGIC;\r\n           pixel_clock     : out STD_LOGIC);\r\nend vga_clocking;\r\n\r\narchitecture Behavioral of vga_clocking is\r\n   signal clock_x1             : std_logic;\r\n   signal clock_x1_unbuffered  : std_logic;\r\n   signal clk_feedback         : std_logic;\r\n   signal clk50_buffered       : std_logic;\r\n   signal pll_locked           : std_logic;\r\nbegin\r\n   pixel_clock     <= clock_x1;\r\n   \r\n   -- Multiply clk50m by 15, then divide by 10 for the 75 MHz pixel clock\r\n   -- Because the all come from the same PLL the will all be in phase \r\n   PLL_BASE_inst : PLL_BASE\r\n   generic map (\r\n      CLKFBOUT_MULT => 16,                  \r\n      CLKOUT0_DIVIDE => 20,       CLKOUT0_PHASE => 0.0,  -- Output pixel clock, 1.5x original frequency\r\n      CLK_FEEDBACK => \"CLKFBOUT\",                        -- Clock source to drive CLKFBIN (\"CLKFBOUT\" or \"CLKOUT0\")\r\n      CLKIN_PERIOD => 20.0,                              -- IMPORTANT! 20.00 => 50MHz\r\n      DIVCLK_DIVIDE => 1                                 -- Division value for all output clocks (1-52)\r\n   )\r\n      port map (\r\n      CLKFBOUT => clk_feedback, \r\n      CLKOUT0  => clock_x1_unbuffered,\r\n      CLKOUT1  => open,\r\n      CLKOUT2  => open,\r\n      CLKOUT3  => open,\r\n      CLKOUT4  => open,\r\n      CLKOUT5  => open,\r\n      LOCKED   => pll_locked,      \r\n      CLKFBIN  => clk_feedback,    \r\n      CLKIN    => clk50_buffered, \r\n      RST      => '0'              -- 1-bit input: Reset input\r\n   );\r\n\r\nBUFG_clk    : BUFG port map ( I => clk50,                O => clk50_buffered);\r\nBUFG_pclock : BUFG port map ( I => clock_x1_unbuffered,  O => clock_x1);\r\n\r\nend Behavioral;"
  },
  {
    "path": "test_bench/hdmi_test_generator/vga_gen.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Description: Generates a test 1280x720 signal \r\n--\r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity vga_gen is\r\n    Port ( clk50           : in  STD_LOGIC;\r\n\t\t     pixel_clock     : out std_logic;\r\n\r\n           red_p   : out STD_LOGIC_VECTOR (7 downto 0) := (others => '0');\r\n           green_p : out STD_LOGIC_VECTOR (7 downto 0) := (others => '0');\r\n           blue_p  : out STD_LOGIC_VECTOR (7 downto 0) := (others => '0');\r\n           blank   : out STD_LOGIC := '0';\r\n           hsync   : out STD_LOGIC := '0';\r\n           vsync   : out STD_LOGIC := '0');\r\nend vga_gen;\r\n\r\narchitecture Behavioral of vga_gen is\r\n\tCOMPONENT vga_clocking\r\n\tPORT( clk50           : IN  std_logic;          \r\n         pixel_clock     : OUT std_logic);\r\n\tEND COMPONENT;\r\n\r\n   constant h_rez        : natural := 800;\r\n   constant h_sync_start : natural := 800+40;\r\n   constant h_sync_end   : natural := 800+40+128;\r\n   constant h_max        : natural := 1056;\r\n   signal   h_count      : unsigned(11 downto 0) := (others => '0');\r\n   signal   h_offset     : unsigned(7 downto 0) := (others => '0');\r\n\r\n   constant v_rez        : natural := 600;\r\n   constant v_sync_start : natural := 600+1;\r\n   constant v_sync_end   : natural := 600+1+4;\r\n   constant v_max        : natural := 628;\r\n   signal   v_count      : unsigned(11 downto 0) := x\"250\";\r\n   signal   v_offset     : unsigned(7 downto 0) := (others => '0');\r\n   signal clk40 : std_logic;\r\nbegin\r\n\r\nInst_clocking: vga_clocking PORT MAP(\r\n\t\tclk50           => clk50,\r\n\t\tpixel_clock     => clk40\r\n\t);\r\n   pixel_clock <= clk40;\r\n\r\n   \r\nprocess(clk40)\r\n   begin\r\n      if rising_edge(clk40) then\r\n         if h_count < h_rez and v_count < v_rez then\r\n            red_p   <= std_logic_vector(h_count(7 downto 0)+h_offset);\r\n            green_p <= std_logic_vector(v_count(7 downto 0)+v_offset);\r\n            blue_p  <= std_logic_vector(h_count(7 downto 0)+v_count(7 downto 0));\r\n            blank   <= '0';\r\n            if h_count = 0 or h_count = h_rez-1 then\r\n               red_p   <= (others => '1');\r\n               green_p <= (others => '1');\r\n               blue_p  <= (others => '1');\r\n            end if;\r\n            if v_count = 0 or v_count = v_rez-1 then\r\n               red_p   <= (others => '1');\r\n               green_p <= (others => '0');\r\n               blue_p  <= (others => '0');\r\n            end if;\r\n         else\r\n            red_p   <= (others => '0');\r\n            green_p <= (others => '0');\r\n            blue_p  <= (others => '0');\r\n            blank   <= '1';\r\n         end if;\r\n\r\n         if h_count >= h_sync_start and h_count < h_sync_end then\r\n            hsync <= '1';\r\n         else\r\n            hsync <= '0';\r\n         end if;\r\n         \r\n         if v_count >= v_sync_start and v_count < v_sync_end then\r\n            vsync <= '1';\r\n         else\r\n            vsync <= '0';\r\n         end if;\r\n         \r\n         if h_count = h_max then\r\n            h_count <= (others => '0');\r\n            if v_count = v_max then\r\n               h_offset <= h_offset + 1;\r\n               v_offset <= v_offset + 1;\r\n               v_count <= (others => '0');\r\n            else\r\n               v_count <= v_count+1;\r\n            end if;\r\n         else\r\n            h_count <= h_count+1;\r\n         end if;\r\n\r\n      end if;\r\n   end process;\r\n\r\nend Behavioral;\r\n\r\n"
  },
  {
    "path": "test_bench/tb_audio_to_db.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: tb_audio_to_db - Behavioral\r\n--\r\n-- Description: A testbench for the audio sample to db level calculation\r\n-- \r\n----------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n----------------------------------------------------------------------------------\r\n----- Want to say thanks? --------------------------------------------------------\r\n----------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n------------------------------------------------------------------------------------\r\n\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity tb_audio_to_db is\r\nend tb_audio_to_db;\r\n\r\narchitecture Behavioral of tb_audio_to_db is\r\n    component audio_to_db is\r\n    Port ( clk           : in  STD_LOGIC;\r\n\r\n           in_channel    : in  STD_LOGIC_VECTOR (2 downto 0);\r\n           in_de         : in  STD_LOGIC;\r\n           in_sample     : in  STD_LOGIC_VECTOR (23 downto 0);\r\n\r\n           out_channel   : out STD_LOGIC_VECTOR (2 downto 0);\r\n           out_de        : out STD_LOGIC;\r\n           out_level     : out STD_LOGIC_VECTOR (5 downto 0));\r\n    end component;\r\n\r\n    signal clk           : STD_LOGIC := '0';\r\n\r\n    signal in_channel    : STD_LOGIC_VECTOR (2 downto 0)  := (others => '0');\r\n    signal in_de         : STD_LOGIC                      := '1';\r\n    signal in_sample     : STD_LOGIC_VECTOR (23 downto 0) := (others => '0');\r\n\r\n    signal out_channel   : STD_LOGIC_VECTOR (2 downto 0);\r\n    signal out_de        : STD_LOGIC;\r\n    signal out_level     : STD_LOGIC_VECTOR (5 downto 0);\r\n\r\nbegin\r\n\r\nprocess\r\n    begin\r\n        wait for 5 ns;\r\n        clk <= '1';\r\n        wait for 5 ns;\r\n        clk <= '0';\r\n    end process;\r\n\r\nprocess\r\n    begin\r\n        wait until rising_edge(clk);\r\n        in_de <= '1';\r\n        in_sample <= in_sample(in_sample'high-1 downto 0) & not in_sample(in_sample'high);\r\n        wait until rising_edge(clk);\r\n        in_de <= '0';\r\n        wait until rising_edge(clk);\r\n        wait until rising_edge(clk);\r\n        wait until rising_edge(clk);\r\n        wait until rising_edge(clk);\r\n    end process;\r\n\r\nuut: audio_to_db port map (\r\n        clk         => clk,\r\n        in_channel  => in_channel,\r\n        in_de       => in_de,\r\n        in_sample   => in_sample,\r\n\r\n        out_channel => out_channel,\r\n        out_de      => out_de,\r\n        out_level   => out_level);\r\n\r\nend Behavioral;\r\n"
  },
  {
    "path": "test_bench/tb_convert_yCbCr_to_RGB.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz>\r\n-- \r\n-- Description: A testbench for YCbCr to RGB decoding \r\n-- \r\n------------------------------------------------------------------------------------ \r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n------------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n--\r\n----------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\n-- Uncomment the following library declaration if using\r\n-- arithmetic functions with Signed or Unsigned values\r\n--use IEEE.NUMERIC_STD.ALL;\r\n\r\n-- Uncomment the following library declaration if instantiating\r\n-- any Xilinx leaf cells in this code.\r\n--library UNISIM;\r\n--use UNISIM.VComponents.all;\r\n\r\nentity tb_convert_yCbCr_to_RGB is\r\nend tb_convert_yCbCr_to_RGB;\r\n\r\narchitecture Behavioral of tb_convert_yCbCr_to_RGB is\r\n    component conversion_YCbCr_to_RGB is\r\n    port ( clk      : in std_Logic;\r\n           input_is_YCbCr : in std_Logic;\r\n\r\n           ------------------------\r\n           in_blank : in std_logic;\r\n           in_hsync : in std_logic;\r\n           in_vsync : in std_logic;\r\n           in_U     : in std_logic_vector(11 downto 0);  -- B or Cb\r\n           in_V     : in std_logic_vector(11 downto 0);  -- G or Y\r\n           in_W     : in std_logic_vector(11 downto 0);  -- R or Cr\r\n\r\n           ------------------------\r\n           out_blank : out std_logic;\r\n           out_hsync : out std_logic;\r\n           out_vsync : out std_logic;\r\n           out_R     : out std_logic_vector(11 downto 0);\r\n           out_G     : out std_logic_vector(11 downto 0);\r\n           out_B     : out std_logic_vector(11 downto 0));\r\n    end component;\r\n\r\n    signal clk            : std_Logic := '0';\r\n    signal input_is_YCbCr : std_Logic := '0';\r\n    signal in_blank       : std_logic := '0';\r\n    signal in_hsync       : std_logic := '0';\r\n    signal in_vsync       : std_logic := '0';\r\n    signal in_U           : std_logic_vector(11 downto 0) := x\"800\";  -- B or Cb\r\n    signal in_V           : std_logic_vector(11 downto 0) := x\"800\";  -- G or Y\r\n    signal in_W           : std_logic_vector(11 downto 0) := x\"800\";  -- R or Cr\r\n    signal out_blank      : std_logic := '0';\r\n    signal out_hsync      : std_logic := '0';\r\n    signal out_vsync      : std_logic := '0';\r\n    signal out_R          : std_logic_vector(11 downto 0);\r\n    signal out_G          : std_logic_vector(11 downto 0);\r\n    signal out_B          : std_logic_vector(11 downto 0);\r\n\r\nbegin\r\n\r\nprocess\r\n    begin\r\n        wait for 5 ns;\r\n        clk <= not clk;\r\n    end process;\r\n\r\nstim: process\r\n    begin\r\n        wait for 100 ns;\r\n        in_U <= x\"100\";\r\n        wait for 100 ns;\r\n        in_U <= x\"EFF\";\r\n        wait for 100 ns;\r\n        in_U <= x\"800\";\r\n\r\n        wait for 100 ns;\r\n        in_V <= x\"100\";\r\n        wait for 100 ns;\r\n        in_V <= x\"EFF\";\r\n        wait for 100 ns;\r\n        in_V <= x\"800\";\r\n\r\n        wait for 100 ns;\r\n        in_W <= x\"100\";\r\n        wait for 100 ns;\r\n        in_W <= x\"EFF\";\r\n        wait for 100 ns;\r\n        in_W <= x\"800\";\r\n\r\n    end process;\r\nuut: conversion_YCbCr_to_RGB port map (\r\n        clk => clk,\r\n        input_is_YCbCr => '1',\r\n        ------------------------\r\n        in_blank => in_blank,\r\n        in_hsync => in_hsync,\r\n        in_vsync => in_vsync, \r\n        in_U     => in_U,\r\n        in_V     => in_V,\r\n        in_W     => in_W,\r\n        ------------------------\r\n        out_blank => out_blank, \r\n        out_hsync => out_hsync,\r\n        out_vsync => out_vsync,\r\n        out_R     => out_R,\r\n        out_G     => out_G,\r\n        out_B     => out_B);\r\n\r\nend Behavioral;\r\n"
  },
  {
    "path": "test_bench/tb_hdmi_decode.vhd",
    "content": "----------------------------------------------------------------------------------\r\n-- Engineer: Mike Field <hamster@snap.net.nz> \r\n-- \r\n-- Module Name: tb_hdmi_decode - Behavioral\r\n--\r\n-- Description: A testbench for testing HDMI decoding \r\n-- \r\n------------------------------------------------------------------------------------\r\n-- The MIT License (MIT)\r\n-- \r\n-- Copyright (c) 2015 Michael Alan Field\r\n-- \r\n-- Permission is hereby granted, free of charge, to any person obtaining a copy\r\n-- of this software and associated documentation files (the \"Software\"), to deal\r\n-- in the Software without restriction, including without limitation the rights\r\n-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n-- copies of the Software, and to permit persons to whom the Software is\r\n-- furnished to do so, subject to the following conditions:\r\n-- \r\n-- The above copyright notice and this permission notice shall be included in\r\n-- all copies or substantial portions of the Software.\r\n-- \r\n-- THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n-- THE SOFTWARE.\r\n----------------------------------------------------------------------------------\r\n----- Want to say thanks? ----------------------------------------------------------\r\n------------------------------------------------------------------------------------\r\n--\r\n-- This design has taken many hours - with the industry metric of 30 lines\r\n-- per day, it is equivalent to about 6 months of work. I'm more than happy\r\n-- to share it if you can make use of it. It is released under the MIT license,\r\n-- so you are not under any onus to say thanks, but....\r\n-- \r\n-- If you what to say thanks for this design how about trying PayPal?\r\n--  Educational use - Enough for a beer\r\n--  Hobbyist use    - Enough for a pizza\r\n--  Research use    - Enough to take the family out to dinner\r\n--  Commercial use  - A weeks pay for an engineer (I wish!)\r\n------------------------------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity tb_hdmi_decode is\r\nend tb_hdmi_decode;\r\n\r\narchitecture Behavioral of tb_hdmi_decode is\r\n    component hdmi_design is\r\n    Port ( \r\n        clk100    : in STD_LOGIC;\r\n        -- Control signals\r\n        led           : out   std_logic_vector(7 downto 0);\r\n        sw            : in    std_logic_vector(7 downto 0) :=(others => '0');\r\n        debug_pmod    : out   std_logic_vector(7 downto 0) :=(others => '0');\r\n\r\n        --HDMI input signals\r\n        hdmi_rx_cec   : inout std_logic;\r\n        hdmi_rx_hpa   : out   std_logic;\r\n        hdmi_rx_scl   : in    std_logic;\r\n        hdmi_rx_sda   : inout std_logic;\r\n        hdmi_rx_txen  : out   std_logic;\r\n        hdmi_rx_clk_n : in    std_logic;\r\n        hdmi_rx_clk_p : in    std_logic;\r\n        hdmi_rx_n     : in    std_logic_vector(2 downto 0);\r\n        hdmi_rx_p     : in    std_logic_vector(2 downto 0);\r\n\r\n        --- HDMI out\r\n        hdmi_tx_cec   : inout std_logic;\r\n        hdmi_tx_clk_n : out   std_logic;\r\n        hdmi_tx_clk_p : out   std_logic;\r\n        hdmi_tx_hpd   : in    std_logic;\r\n        hdmi_tx_rscl  : inout std_logic;\r\n        hdmi_tx_rsda  : inout std_logic;\r\n        hdmi_tx_p     : out   std_logic_vector(2 downto 0);\r\n        hdmi_tx_n     : out   std_logic_vector(2 downto 0);\r\n        -- For dumping symbols\r\n        rs232_tx     : out std_logic      \r\n    );\r\n    end component;\r\n    \r\n    component hdmi_output_test is\r\n        Port ( clk50         : in  STD_LOGIC;\r\n    \r\n               hdmi_out_p : out  STD_LOGIC_VECTOR(3 downto 0);\r\n               hdmi_out_n : out  STD_LOGIC_VECTOR(3 downto 0);\r\n                          \r\n               leds       : out std_logic_vector(7 downto 0));\r\n    end component;\r\n    \r\n    \r\n    signal clk           : std_logic := '0';\r\n    signal clk50         : std_logic := '1';\r\n    signal led           : std_logic_vector(7 downto 0);\r\n    signal hdmi_rx_cec   : std_logic;\r\n    signal hdmi_rx_hpa   : std_logic;\r\n    signal hdmi_rx_scl   : std_logic;\r\n    signal hdmi_rx_sda   : std_logic;\r\n    signal hdmi_rx_txen  : std_logic;\r\n    signal hdmi_rx_clk_n : std_logic;\r\n    signal hdmi_rx_clk_p : std_logic;\r\n    signal hdmi2_rx_clk_n : std_logic := '1';\r\n    signal hdmi2_rx_clk_p : std_logic := '0';\r\n    signal hdmi_out_n    : std_logic_vector(3 downto 0);\r\n    signal hdmi_out_p    : std_logic_vector(3 downto 0);\r\n    signal hdmi_rx_n     : std_logic_vector(2 downto 0);\r\n    signal hdmi_rx_p     : std_logic_vector(2 downto 0);\r\n    signal hdmi_tx_cec   : std_logic;\r\n    signal hdmi_tx_clk_n : std_logic;\r\n    signal hdmi_tx_clk_p : std_logic;\r\n    signal hdmi_tx_hpd   : std_logic;\r\n    signal hdmi_tx_rscl  : std_logic;\r\n    signal hdmi_tx_rsda  : std_logic;\r\n    signal hdmi_tx_p     : std_logic_vector(2 downto 0);\r\n    signal hdmi_tx_n     : std_logic_vector(2 downto 0);\r\n    \r\n    signal sdat_drive : std_logic := '1';\r\n    signal rs232_tx : std_logic := '1';\r\nbegin\r\nhdmi_rx_sda <= '0' when sdat_drive = '0' else 'H';\r\n\r\n  hdmi_rx_p <= transport hdmi_out_p(2 downto 0) after 5.00 ns;\r\n  hdmi_rx_n <= transport hdmi_out_n(2 downto 0) after 5.00 ns;\r\n  hdmi_rx_clk_p <= transport hdmi_out_p(3) after 1.25 ns;\r\n  hdmi_rx_clk_n <= transport hdmi_out_n(3) after 1.25 ns;\r\n\r\nclk_proc: process\r\nbegin\r\n    wait for 7.0 ns;\r\n    while 1 = 1 loop\r\n        wait for 5.0 ns;\r\n        clk <= not clk;\r\n    end loop;\r\nend process;\r\n\r\nclk50_proc: process\r\nbegin\r\n    wait for 7.0 ns;\r\n    while 1 = 1 loop\r\n        wait for 5.0 ns;\r\n        clk50 <= not clk50;\r\n    end loop;\r\nend process;\r\n\r\ni_gen_signal: hdmi_output_test port map (\r\n    clk50         => clk50,\r\n    hdmi_out_p    => hdmi_out_p,\r\n    hdmi_out_n    => hdmi_out_n,\r\n    leds          => open);\r\n\r\nuut: hdmi_design Port map (\r\n    clk100        => clk,\r\n    led           => open,\r\n    sw            => (others => '0'),\r\n    debug_pmod    => open,\r\n    --HDMI in\r\n    hdmi_rx_cec   => hdmi_rx_cec,\r\n    hdmi_rx_hpa   => hdmi_rx_hpa, \r\n    hdmi_rx_scl   => hdmi_rx_scl,\r\n    hdmi_rx_sda   => hdmi_rx_sda,\r\n    hdmi_rx_txen  => hdmi_rx_txen, \r\n    hdmi_rx_clk_n => hdmi_rx_clk_n,\r\n    hdmi_rx_clk_p => hdmi_rx_clk_p,\r\n    hdmi_rx_n     => hdmi_rx_n,\r\n    hdmi_rx_p     => hdmi_rx_p,\r\n\r\n    --- HDMI out\r\n    hdmi_tx_cec   => hdmi_tx_cec,\r\n    hdmi_tx_clk_n => hdmi_tx_clk_n,\r\n    hdmi_tx_clk_p => hdmi_tx_clk_p,\r\n    hdmi_tx_hpd   => hdmi_tx_hpd,\r\n    hdmi_tx_rscl  => hdmi_tx_rscl,\r\n    hdmi_tx_rsda  => hdmi_tx_rsda,\r\n    hdmi_tx_p     => hdmi_tx_p,\r\n    hdmi_tx_n     => hdmi_tx_n,\r\n    \r\n    rs232_tx      => rs232_tx\r\n);\r\n\r\nedid_test_proc: process\r\nbegin\r\n       hdmi_rx_scl <= '1';\r\n   wait for 1 us;\r\n-- START condition\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- DEVICE ADDRESS FOR WRITE\r\n-- dev bit 7\r\n   sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 6\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 6\r\n   sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 4\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 3\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 2\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 1\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 0\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- Slave ACK\r\n-- Device to ack\r\n   sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- SEND WRITE ADDRESS\r\n-- addr bit 7\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- addr bit 6\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- addr bit 6\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- addr bit 4\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- addr bit 3\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- addr bit 2\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- addr bit 1\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- addr bit 0\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- Slave ACK\r\n   sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- repeated START condition\r\n   sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; \r\n   wait for 400 ns; sdat_drive  <= '0'; wait for 200 ns; hdmi_rx_scl <= '0'; wait for 200 ns; \r\n-- DEVICE ADDRESS / READ - \r\n-- dev bit 7\r\n   sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 6\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 6\r\n   sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 4\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 3\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 2\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 1\r\n   sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- dev bit 0  - READ!\r\n   sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n\r\n-- ACK????\r\n-- Device to ack\r\n   sdat_drive <= '1';\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n\r\nfor i in 1 to 127 loop\r\n-- READ First byte\r\n-- read bit 7\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 6\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 6\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 4\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 3\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 2\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 1\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 0\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n   sdat_drive <= '1';\r\n\r\n-- Host to ack\r\n   sdat_drive <= '0';\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n   sdat_drive <= '1';\r\nend loop;\r\n-- READ Second\r\n-- read bit 7\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 6\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 6\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 4\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 3\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 2\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 1\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n-- read bit 0\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n   sdat_drive <= '1';\r\n\r\n-- Master NACK\r\n   sdat_drive <= '1';\r\n       wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;\r\n   sdat_drive <= '1';\r\n\r\n-- STOP\r\n   sdat_drive <= '1';\r\n   wait for 200 ns;\r\n       hdmi_rx_scl <= '1';\r\n   wait for 200 ns;\r\n\r\n   wait;\r\nend process;\r\n\r\nend Behavioral;\r\n"
  }
]