Merge FPGA gateware and STM32 microcontroller firmware repos
This commit is contained in:
commit
e0c5159449
63 changed files with 112230 additions and 0 deletions
551
Artix-7-HDMI-processing.xpr
Normal file
551
Artix-7-HDMI-processing.xpr
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Product Version: Vivado v2020.2 (64-bit) -->
|
||||
<!-- -->
|
||||
<!-- Copyright 1986-2020 Xilinx, Inc. All Rights Reserved. -->
|
||||
|
||||
<Project Version="7" Minor="54" Path="C:/Users/jaseg/Documents/tachibana_4k/Artix-7-HDMI-processing/Artix-7-HDMI-processing.xpr">
|
||||
<DefaultLaunch Dir="$PRUNDIR"/>
|
||||
<Configuration>
|
||||
<Option Name="Id" Val="487e6670b2224898a3f8937139078585"/>
|
||||
<Option Name="Part" Val="xc7a200tfbg484-1"/>
|
||||
<Option Name="CompiledLibDir" Val="$PCACHEDIR/compile_simlib"/>
|
||||
<Option Name="CompiledLibDirXSim" Val=""/>
|
||||
<Option Name="CompiledLibDirModelSim" Val="$PCACHEDIR/compile_simlib/modelsim"/>
|
||||
<Option Name="CompiledLibDirQuesta" Val="$PCACHEDIR/compile_simlib/questa"/>
|
||||
<Option Name="CompiledLibDirIES" Val="$PCACHEDIR/compile_simlib/ies"/>
|
||||
<Option Name="CompiledLibDirXcelium" Val="$PCACHEDIR/compile_simlib/xcelium"/>
|
||||
<Option Name="CompiledLibDirVCS" Val="$PCACHEDIR/compile_simlib/vcs"/>
|
||||
<Option Name="CompiledLibDirRiviera" Val="$PCACHEDIR/compile_simlib/riviera"/>
|
||||
<Option Name="CompiledLibDirActivehdl" Val="$PCACHEDIR/compile_simlib/activehdl"/>
|
||||
<Option Name="SimulatorInstallDirModelSim" Val=""/>
|
||||
<Option Name="SimulatorInstallDirQuesta" Val=""/>
|
||||
<Option Name="SimulatorInstallDirIES" Val=""/>
|
||||
<Option Name="SimulatorInstallDirXcelium" Val=""/>
|
||||
<Option Name="SimulatorInstallDirVCS" Val=""/>
|
||||
<Option Name="SimulatorInstallDirRiviera" Val=""/>
|
||||
<Option Name="SimulatorInstallDirActiveHdl" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirModelSim" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirQuesta" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirIES" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirXcelium" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirVCS" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirRiviera" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirActiveHdl" Val=""/>
|
||||
<Option Name="TargetLanguage" Val="VHDL"/>
|
||||
<Option Name="BoardPart" Val=""/>
|
||||
<Option Name="ActiveSimSet" Val="sim_1"/>
|
||||
<Option Name="DefaultLib" Val="xil_defaultlib"/>
|
||||
<Option Name="ProjectType" Val="Default"/>
|
||||
<Option Name="IPCachePermission" Val="disable"/>
|
||||
<Option Name="EnableCoreContainer" Val="FALSE"/>
|
||||
<Option Name="CreateRefXciForCoreContainers" Val="FALSE"/>
|
||||
<Option Name="IPUserFilesDir" Val="$PIPUSERFILESDIR"/>
|
||||
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
|
||||
<Option Name="EnableBDX" Val="FALSE"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="560"/>
|
||||
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
||||
<Option Name="WTIesLaunchSim" Val="0"/>
|
||||
<Option Name="WTVcsLaunchSim" Val="0"/>
|
||||
<Option Name="WTRivieraLaunchSim" Val="0"/>
|
||||
<Option Name="WTActivehdlLaunchSim" Val="0"/>
|
||||
<Option Name="WTXSimExportSim" Val="4"/>
|
||||
<Option Name="WTModelSimExportSim" Val="4"/>
|
||||
<Option Name="WTQuestaExportSim" Val="4"/>
|
||||
<Option Name="WTIesExportSim" Val="4"/>
|
||||
<Option Name="WTVcsExportSim" Val="4"/>
|
||||
<Option Name="WTRivieraExportSim" Val="4"/>
|
||||
<Option Name="WTActivehdlExportSim" Val="4"/>
|
||||
<Option Name="GenerateIPUpgradeLog" Val="TRUE"/>
|
||||
<Option Name="XSimRadix" Val="hex"/>
|
||||
<Option Name="XSimTimeUnit" Val="ns"/>
|
||||
<Option Name="XSimArrayDisplayLimit" Val="1024"/>
|
||||
<Option Name="XSimTraceLimit" Val="65536"/>
|
||||
<Option Name="SimTypes" Val="rtl"/>
|
||||
<Option Name="MEMEnableMemoryMapGeneration" Val="TRUE"/>
|
||||
<Option Name="DcpsUptoDate" Val="TRUE"/>
|
||||
</Configuration>
|
||||
<FileSets Version="1" Minor="31">
|
||||
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1">
|
||||
<Filter Type="Srcs"/>
|
||||
<File Path="$PPRDIR/src/edge_cleaner.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/spi_regfile.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/term_emu.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/gen/gen_font_params_default.vh">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/term_renderer.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/top.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/window_matcher.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/alignment_detect.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/conversion_to_RGB.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/deserialiser_1_to_10.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/detect_interlace.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/dvid_output.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/edid_rom.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/expand_422_to_444.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/extract_audio_samples.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/extract_video_infopacket_data.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/hdmi_input.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/hdmi_io.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/input_channel.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/serialiser_10_to_1.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/symbol_dump.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/tmds_decoder.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/tmds_encoder.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/hdmi_design.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/audio_meters.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/audio_to_db.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/edge_enhance.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/guidelines.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/line_delay.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src/pixel_processing.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopModule" Val="hdmi_design"/>
|
||||
<Option Name="TopAutoSet" Val="TRUE"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1">
|
||||
<Filter Type="Constrs"/>
|
||||
<File Path="$PPRDIR/constraints/NexysVideo.xdc">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="TargetConstrsFile" Val="$PPRDIR/constraints/NexysVideo.xdc"/>
|
||||
<Option Name="ConstrsType" Val="XDC"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1">
|
||||
<Filter Type="Srcs"/>
|
||||
<File Path="$PPRDIR/test_bench/window_matcher_tb.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/spi_regfile_tb.v">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/term_emu_tb.v">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/term_renderer_tb.v">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/hdmi_test_generator/hdmi_ouput_test.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/hdmi_test_generator/minimal_hdmi_symbols.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/hdmi_test_generator/serializers.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/hdmi_test_generator/vga_clocking.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/hdmi_test_generator/vga_gen.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/tb_hdmi_decode.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/tb_convert_yCbCr_to_RGB.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/test_bench/tb_audio_to_db.vhd">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/window_matcher_tb_behav.wcfg">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/term_renderer_tb_behav.wcfg">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/term_emu_tb_behav.wcfg">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/spi_regfile_tb_behav.wcfg">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopModule" Val="window_matcher_tb"/>
|
||||
<Option Name="TopLib" Val="xil_defaultlib"/>
|
||||
<Option Name="TransportPathDelay" Val="0"/>
|
||||
<Option Name="TransportIntDelay" Val="0"/>
|
||||
<Option Name="SelectedSimModel" Val="rtl"/>
|
||||
<Option Name="PamDesignTestbench" Val=""/>
|
||||
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
|
||||
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
|
||||
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
|
||||
<Option Name="SrcSet" Val="sources_1"/>
|
||||
<Option Name="XSimWcfgFile" Val="$PPRDIR/tb_hdmi_decode_behav.wcfg"/>
|
||||
<Option Name="XSimWcfgFile" Val="$PPRDIR/window_matcher_tb_behav.wcfg"/>
|
||||
<Option Name="XSimWcfgFile" Val="$PPRDIR/term_renderer_tb_behav.wcfg"/>
|
||||
<Option Name="XSimWcfgFile" Val="$PPRDIR/term_emu_tb_behav.wcfg"/>
|
||||
<Option Name="XSimWcfgFile" Val="$PPRDIR/spi_core_tb_behav.wcfg"/>
|
||||
<Option Name="XSimWcfgFile" Val="$PPRDIR/spi_regfile_tb_behav.wcfg"/>
|
||||
<Option Name="xsim.simulate.runtime" Val="10ms"/>
|
||||
<Option Name="NLNetlistMode" Val="funcsim"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="utils_1" Type="Utils" RelSrcDir="$PSRCDIR/utils_1">
|
||||
<Filter Type="Utils"/>
|
||||
<Config>
|
||||
<Option Name="TopAutoSet" Val="TRUE"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="ila_0" Type="BlockSrcs" RelSrcDir="$PSRCDIR/ila_0">
|
||||
<File Path="$PSRCDIR/sources_1/ip/ila_0/ila_0.xci">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="TopModule" Val="ila_0"/>
|
||||
<Option Name="UseBlackboxStub" Val="1"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
</FileSets>
|
||||
<Simulators>
|
||||
<Simulator Name="XSim">
|
||||
<Option Name="Description" Val="Vivado Simulator"/>
|
||||
<Option Name="CompiledLib" Val="0"/>
|
||||
</Simulator>
|
||||
<Simulator Name="ModelSim">
|
||||
<Option Name="Description" Val="ModelSim Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="Questa">
|
||||
<Option Name="Description" Val="Questa Advanced Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="Riviera">
|
||||
<Option Name="Description" Val="Riviera-PRO Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="ActiveHDL">
|
||||
<Option Name="Description" Val="Active-HDL Simulator"/>
|
||||
</Simulator>
|
||||
</Simulators>
|
||||
<Runs Version="1" Minor="15">
|
||||
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a200tfbg484-1" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/synth_1" IncludeInArchive="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2014"/>
|
||||
<Step Id="synth_design"/>
|
||||
</Strategy>
|
||||
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
|
||||
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2017"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="ila_0_synth_1" Type="Ft3:Synth" SrcSet="ila_0" Part="xc7a200tfbg484-1" ConstrsSet="ila_0" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/ila_0_synth_1" IncludeInArchive="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/ila_0_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2020"/>
|
||||
<Step Id="synth_design"/>
|
||||
</Strategy>
|
||||
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
|
||||
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2020"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a200tfbg484-1" ConstrsSet="constrs_1" Description="Vivado Implementation Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2014"/>
|
||||
<Step Id="init_design"/>
|
||||
<Step Id="opt_design"/>
|
||||
<Step Id="power_opt_design"/>
|
||||
<Step Id="place_design"/>
|
||||
<Step Id="post_place_power_opt_design"/>
|
||||
<Step Id="phys_opt_design"/>
|
||||
<Step Id="route_design"/>
|
||||
<Step Id="post_route_phys_opt_design"/>
|
||||
<Step Id="write_bitstream"/>
|
||||
</Strategy>
|
||||
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
|
||||
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2017"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="ila_0_impl_1" Type="Ft2:EntireDesign" Part="xc7a200tfbg484-1" ConstrsSet="ila_0" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="ila_0_synth_1" IncludeInArchive="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/ila_0_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2020"/>
|
||||
<Step Id="init_design"/>
|
||||
<Step Id="opt_design"/>
|
||||
<Step Id="power_opt_design"/>
|
||||
<Step Id="place_design"/>
|
||||
<Step Id="post_place_power_opt_design"/>
|
||||
<Step Id="phys_opt_design"/>
|
||||
<Step Id="route_design"/>
|
||||
<Step Id="post_route_phys_opt_design"/>
|
||||
<Step Id="write_bitstream"/>
|
||||
</Strategy>
|
||||
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2020"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
</Runs>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="WARNING"/>
|
||||
<MsgAttr Name="Id" Val="Common 17-55"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="1"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<Board/>
|
||||
<DashboardSummary Version="1" Minor="0">
|
||||
<Dashboards>
|
||||
<Dashboard Name="default_dashboard">
|
||||
<Gadgets>
|
||||
<Gadget Name="drc_1" Type="drc" Version="1" Row="2" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_drc_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="methodology_1" Type="methodology" Version="1" Row="2" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_methodology_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="power_1" Type="power" Version="1" Row="1" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_power_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="timing_1" Type="timing" Version="1" Row="0" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_timing_summary_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="utilization_1" Type="utilization" Version="1" Row="0" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="synth_1#synth_1_synth_report_utilization_0 "/>
|
||||
<GadgetParam Name="RUN.STEP" Type="string" Value="synth_design"/>
|
||||
<GadgetParam Name="RUN.TYPE" Type="string" Value="synthesis"/>
|
||||
</Gadget>
|
||||
<Gadget Name="utilization_2" Type="utilization" Version="1" Row="1" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_place_report_utilization_0 "/>
|
||||
</Gadget>
|
||||
</Gadgets>
|
||||
</Dashboard>
|
||||
<CurrentDashboard>default_dashboard</CurrentDashboard>
|
||||
</Dashboards>
|
||||
</DashboardSummary>
|
||||
</Project>
|
||||
94
README.txt
Normal file
94
README.txt
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
README file for Artix 7 HDMI processing
|
||||
=======================================
|
||||
Hi!
|
||||
|
||||
This is my design for receiving HDMI input, then extracting the video data, the
|
||||
Video Inforframe and audio samples, then using that to display audio db meters
|
||||
on the top corner of the screen. Currently for simplicity the output is only DVID.
|
||||
|
||||
Features
|
||||
--------
|
||||
Supports HDMI formats:
|
||||
-720p@50
|
||||
- 720p@60,
|
||||
- 1080i (with a bug)
|
||||
- 1080p@50
|
||||
- 1080p@60
|
||||
and others....
|
||||
|
||||
Colourspaces / formats:
|
||||
- RGB 444
|
||||
- YCbCr 444
|
||||
- YCbCr 422
|
||||
|
||||
New feature 10-AUG-2015!
|
||||
-----------------------
|
||||
Switch 0 will turn real-time edge detect off and on.
|
||||
|
||||
New feature 6-AUG-2015!
|
||||
-----------------------
|
||||
Switch 1 will turn guidelines off and on. Will only show in 1080p 1080i and 720p resolutions.
|
||||
|
||||
Supported Boards
|
||||
----------------
|
||||
- Digilent Nexys Video
|
||||
|
||||
Sources tested with:
|
||||
- Western Digital HD Live
|
||||
- HP Laptop
|
||||
|
||||
Sinks tested with:
|
||||
- Viewsonic Monitor
|
||||
- AOC Monitor
|
||||
- Vivo TV
|
||||
|
||||
Known issues:
|
||||
- Currently extracts only two channels of audio
|
||||
|
||||
- Does not adjust PLL settings for input clock, so the PLL is run slightly out
|
||||
of spec.
|
||||
|
||||
- Image may re-sync once after a few seconds if symbol errors are seen.
|
||||
|
||||
- There are timings errors, as generating 148.5MHz HDMI using the Artix-7 chip
|
||||
is actually out of spec. Expect seven failing paths and about 20ns of negative
|
||||
slack.
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
181
charmap_gen.ipynb
Normal file
181
charmap_gen.ipynb
Normal file
File diff suppressed because one or more lines are too long
72
constraints/NexysVideo.xdc
Normal file
72
constraints/NexysVideo.xdc
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#------------------------------------------------------------------------------------
|
||||
# HDMI and clock Constraints for the Digilent Nexys Video FPGA development board.
|
||||
#------------------------------------------------------------------------------------
|
||||
|
||||
##Clock Signal
|
||||
set_property -dict { PACKAGE_PIN R4 IOSTANDARD LVCMOS33 } [get_ports { clk100 }];
|
||||
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk100]
|
||||
|
||||
##HDMI in
|
||||
create_clock -add -name hdmi_clk -period 6.7 -waveform {0 5} [get_ports hdmi_rx_clk_p]
|
||||
|
||||
set_property -dict { PACKAGE_PIN AA5 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_cec }]; #IO_L10P_T1_34 Sch=hdmi_rx_cec
|
||||
set_property -dict { PACKAGE_PIN W4 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_clk_n }]; #IO_L12N_T1_MRCC_34 Sch=hdmi_rx_clk_n
|
||||
set_property -dict { PACKAGE_PIN V4 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_clk_p }]; #IO_L12P_T1_MRCC_34 Sch=hdmi_rx_clk_p
|
||||
set_property -dict { PACKAGE_PIN AB12 IOSTANDARD LVCMOS25 } [get_ports { hdmi_rx_hpa }]; #IO_L7N_T1_13 Sch=hdmi_rx_hpa
|
||||
set_property -dict { PACKAGE_PIN Y4 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_scl }]; #IO_L11P_T1_SRCC_34 Sch=hdmi_rx_scl
|
||||
set_property -dict { PACKAGE_PIN AB5 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_sda }]; #IO_L10N_T1_34 Sch=hdmi_rx_sda
|
||||
set_property -dict { PACKAGE_PIN R3 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_txen }]; #IO_L3P_T0_DQS_34 Sch=hdmi_rx_txen
|
||||
set_property -dict { PACKAGE_PIN AA3 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_n[0] }]; #IO_L9N_T1_DQS_34 Sch=hdmi_rx_n[0]
|
||||
set_property -dict { PACKAGE_PIN Y3 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_p[0] }]; #IO_L9P_T1_DQS_34 Sch=hdmi_rx_p[0]
|
||||
set_property -dict { PACKAGE_PIN Y2 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_n[1] }]; #IO_L4N_T0_34 Sch=hdmi_rx_n[1]
|
||||
set_property -dict { PACKAGE_PIN W2 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_p[1] }]; #IO_L4P_T0_34 Sch=hdmi_rx_p[1]
|
||||
set_property -dict { PACKAGE_PIN V2 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_n[2] }]; #IO_L2N_T0_34 Sch=hdmi_rx_n[2]
|
||||
set_property -dict { PACKAGE_PIN U2 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_p[2] }]; #IO_L2P_T0_34 Sch=hdmi_rx_p[2]
|
||||
|
||||
|
||||
##HDMI out
|
||||
set_property -dict { PACKAGE_PIN AA4 IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_cec }]; #IO_L11N_T1_SRCC_34 Sch=hdmi_tx_cec
|
||||
set_property -dict { PACKAGE_PIN U1 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_clk_n }]; #IO_L1N_T0_34 Sch=hdmi_tx_clk_n
|
||||
set_property -dict { PACKAGE_PIN T1 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_clk_p }]; #IO_L1P_T0_34 Sch=hdmi_tx_clk_p
|
||||
set_property -dict { PACKAGE_PIN AB13 IOSTANDARD LVCMOS25 } [get_ports { hdmi_tx_hpd }]; #IO_L3N_T0_DQS_13 Sch=hdmi_tx_hpd
|
||||
set_property -dict { PACKAGE_PIN U3 IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_rscl }]; #IO_L6P_T0_34 Sch=hdmi_tx_rscl
|
||||
set_property -dict { PACKAGE_PIN V3 IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_rsda }]; #IO_L6N_T0_VREF_34 Sch=hdmi_tx_rsda
|
||||
set_property -dict { PACKAGE_PIN Y1 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_n[0] }]; #IO_L5N_T0_34 Sch=hdmi_tx_n[0]
|
||||
set_property -dict { PACKAGE_PIN W1 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_p[0] }]; #IO_L5P_T0_34 Sch=hdmi_tx_p[0]
|
||||
set_property -dict { PACKAGE_PIN AB1 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_n[1] }]; #IO_L7N_T1_34 Sch=hdmi_tx_n[1]
|
||||
set_property -dict { PACKAGE_PIN AA1 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_p[1] }]; #IO_L7P_T1_34 Sch=hdmi_tx_p[1]
|
||||
set_property -dict { PACKAGE_PIN AB2 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_n[2] }]; #IO_L8N_T1_34 Sch=hdmi_tx_n[2]
|
||||
set_property -dict { PACKAGE_PIN AB3 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_p[2] }]; #IO_L8P_T1_34 Sch=hdmi_tx_p[2]
|
||||
|
||||
# DEBUG on JA
|
||||
set_property -dict { PACKAGE_PIN AB22 IOSTANDARD LVCMOS33 } [get_ports { sck }]; #IO_L10N_T1_D15_14 Sch=ja[1]
|
||||
set_property -dict { PACKAGE_PIN AB21 IOSTANDARD LVCMOS33 } [get_ports { ncs }]; #IO_L10P_T1_D14_14 Sch=ja[2]
|
||||
set_property -dict { PACKAGE_PIN AB20 IOSTANDARD LVCMOS33 } [get_ports { sdi }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=ja[3]
|
||||
set_property -dict { PACKAGE_PIN AB18 IOSTANDARD LVCMOS33 } [get_ports { sdo }]; #IO_L17N_T2_A13_D29_14 Sch=ja[4]
|
||||
set_property -dict { PACKAGE_PIN Y21 IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[0] }]; #IO_L9P_T1_DQS_14 Sch=ja[7]
|
||||
set_property -dict { PACKAGE_PIN AA21 IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[1] }]; #IO_L8N_T1_D12_14 Sch=ja[8]
|
||||
set_property -dict { PACKAGE_PIN AA20 IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[2] }]; #IO_L8P_T1_D11_14 Sch=ja[9]
|
||||
set_property -dict { PACKAGE_PIN AA18 IOSTANDARD LVCMOS33 } [get_ports { debug_pmod[3] }]; #IO_L17P_T2_A14_D30_14 Sch=ja[10
|
||||
|
||||
##Switches
|
||||
set_property -dict { PACKAGE_PIN E22 IOSTANDARD LVCMOS25 } [get_ports { sw[0] }]; #IO_L22P_T3_16 Sch=sw[0]
|
||||
set_property -dict { PACKAGE_PIN F21 IOSTANDARD LVCMOS25 } [get_ports { sw[1] }]; #IO_25_16 Sch=sw[1]
|
||||
set_property -dict { PACKAGE_PIN G21 IOSTANDARD LVCMOS25 } [get_ports { sw[2] }]; #IO_L24P_T3_16 Sch=sw[2]
|
||||
set_property -dict { PACKAGE_PIN G22 IOSTANDARD LVCMOS25 } [get_ports { sw[3] }]; #IO_L24N_T3_16 Sch=sw[3]
|
||||
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS25 } [get_ports { sw[4] }]; #IO_L6P_T0_15 Sch=sw[4]
|
||||
set_property -dict { PACKAGE_PIN J16 IOSTANDARD LVCMOS25 } [get_ports { sw[5] }]; #IO_0_15 Sch=sw[5]
|
||||
set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS25 } [get_ports { sw[6] }]; #IO_L19P_T3_A22_15 Sch=sw[6]
|
||||
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS25 } [get_ports { sw[7] }]; #IO_25_15 Sch=sw[7]
|
||||
|
||||
##LEDs
|
||||
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS25 } [get_ports { led[0] }]; #IO_L15P_T2_DQS_13 Sch=led[0]
|
||||
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS25 } [get_ports { led[1] }]; #IO_L15N_T2_DQS_13 Sch=led[1]
|
||||
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS25 } [get_ports { led[2] }]; #IO_L17P_T2_13 Sch=led[2]
|
||||
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS25 } [get_ports { led[3] }]; #IO_L17N_T2_13 Sch=led[3]
|
||||
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS25 } [get_ports { led[4] }]; #IO_L14N_T2_SRCC_13 Sch=led[4]
|
||||
set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS25 } [get_ports { led[5] }]; #IO_L16N_T2_13 Sch=led[5]
|
||||
set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS25 } [get_ports { led[6] }]; #IO_L16P_T2_13 Sch=led[6]
|
||||
set_property -dict { PACKAGE_PIN Y13 IOSTANDARD LVCMOS25 } [get_ports { led[7] }]; #IO_L5P_T0_13 Sch=led[7]
|
||||
|
||||
##UART
|
||||
set_property -dict { PACKAGE_PIN AA19 IOSTANDARD LVCMOS33 } [get_ports { rs232_tx }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=uart_rx_out
|
||||
165
spi_regfile_tb_behav.wcfg
Normal file
165
spi_regfile_tb_behav.wcfg
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="spi_regfile_tb_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="glbl" />
|
||||
<top_module name="spi_regfile_tb" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="0fs"></ZoomStartTime>
|
||||
<ZoomEndTime time="3970000fs"></ZoomEndTime>
|
||||
<Cursor1Time time="760019fs"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="175"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="154"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="29" />
|
||||
<wvobject fp_name="/spi_regfile_tb/testcase" type="array">
|
||||
<obj_property name="ElementShortName">testcase[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">testcase[31:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#DCDCDC</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/clk" type="logic">
|
||||
<obj_property name="ElementShortName">clk</obj_property>
|
||||
<obj_property name="ObjectShortName">clk</obj_property>
|
||||
<obj_property name="CustomSignalColor">#DCDCDC</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/rst" type="logic">
|
||||
<obj_property name="ElementShortName">rst</obj_property>
|
||||
<obj_property name="ObjectShortName">rst</obj_property>
|
||||
<obj_property name="CustomSignalColor">#DCDCDC</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/sck" type="logic">
|
||||
<obj_property name="ElementShortName">sck</obj_property>
|
||||
<obj_property name="ObjectShortName">sck</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/sdi" type="logic">
|
||||
<obj_property name="ElementShortName">sdi</obj_property>
|
||||
<obj_property name="ObjectShortName">sdi</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/sdo" type="logic">
|
||||
<obj_property name="ElementShortName">sdo</obj_property>
|
||||
<obj_property name="ObjectShortName">sdo</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/ncs" type="logic">
|
||||
<obj_property name="ElementShortName">ncs</obj_property>
|
||||
<obj_property name="ObjectShortName">ncs</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_data_in" type="array">
|
||||
<obj_property name="ElementShortName">spi_data_in[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">spi_data_in[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_data_out" type="array">
|
||||
<obj_property name="ElementShortName">spi_data_out[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">spi_data_out[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_status_word" type="array">
|
||||
<obj_property name="ElementShortName">spi_status_word[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">spi_status_word[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_cmd_word" type="array">
|
||||
<obj_property name="ElementShortName">spi_cmd_word[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">spi_cmd_word[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_cmd_active" type="logic">
|
||||
<obj_property name="ElementShortName">spi_cmd_active</obj_property>
|
||||
<obj_property name="ObjectShortName">spi_cmd_active</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_cmd_begin" type="logic">
|
||||
<obj_property name="ElementShortName">spi_cmd_begin</obj_property>
|
||||
<obj_property name="ObjectShortName">spi_cmd_begin</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_cmd_step" type="logic">
|
||||
<obj_property name="ElementShortName">spi_cmd_step</obj_property>
|
||||
<obj_property name="ObjectShortName">spi_cmd_step</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_cmd_idx" type="array">
|
||||
<obj_property name="ElementShortName">spi_cmd_idx[19:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">spi_cmd_idx[19:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/i" type="array">
|
||||
<obj_property name="ElementShortName">i[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">i[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/j" type="array">
|
||||
<obj_property name="ElementShortName">j[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">j[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/k" type="array">
|
||||
<obj_property name="ElementShortName">k[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">k[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/sim_rxdata" type="array">
|
||||
<obj_property name="ElementShortName">sim_rxdata[1:4][15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">sim_rxdata[1:4][15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/sim_txdata" type="array">
|
||||
<obj_property name="ElementShortName">sim_txdata[1:4][15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">sim_txdata[1:4][15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/sim_txbuf" type="array">
|
||||
<obj_property name="ElementShortName">sim_txbuf[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">sim_txbuf[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/period" type="array">
|
||||
<obj_property name="ElementShortName">period[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">period[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/WORDSIZE" type="array">
|
||||
<obj_property name="ElementShortName">WORDSIZE[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">WORDSIZE[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_regfile_dut/txbuf" type="array">
|
||||
<obj_property name="ElementShortName">txbuf[14:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">txbuf[14:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_regfile_dut/rxbuf" type="array">
|
||||
<obj_property name="ElementShortName">rxbuf[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">rxbuf[15:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_regfile_dut/is_cmd_word" type="logic">
|
||||
<obj_property name="ElementShortName">is_cmd_word</obj_property>
|
||||
<obj_property name="ObjectShortName">is_cmd_word</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_regfile_dut/last_ncs" type="logic">
|
||||
<obj_property name="ElementShortName">last_ncs</obj_property>
|
||||
<obj_property name="ObjectShortName">last_ncs</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_regfile_dut/last_sck" type="logic">
|
||||
<obj_property name="ElementShortName">last_sck</obj_property>
|
||||
<obj_property name="ObjectShortName">last_sck</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/spi_regfile_tb/spi_regfile_dut/load_data" type="logic">
|
||||
<obj_property name="ElementShortName">load_data</obj_property>
|
||||
<obj_property name="ObjectShortName">load_data</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
163
src/alignment_detect.vhd
Normal file
163
src/alignment_detect.vhd
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz<
|
||||
--
|
||||
-- Module Name: alignment_detect - Behavioral
|
||||
--
|
||||
-- Description: Manage the dealy and bitslipping of the SERDES based on invald
|
||||
-- symbols being received.
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity alignment_detect is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
invalid_symbol : in STD_LOGIC;
|
||||
delay_count : out std_logic_vector(4 downto 0);
|
||||
delay_ce : out STD_LOGIC;
|
||||
bitslip : out STD_LOGIC;
|
||||
symbol_sync : out STD_LOGIC);
|
||||
end alignment_detect;
|
||||
|
||||
architecture Behavioral of alignment_detect is
|
||||
--------------------------------------
|
||||
-- Signals for controlling the bitslip
|
||||
-- and delay so we can sync symbols
|
||||
--------------------------------------
|
||||
signal count : unsigned(19 downto 0) := (others => '0');
|
||||
signal signal_quality : unsigned(27 downto 0) := (others => '0');
|
||||
signal holdoff : unsigned(9 downto 0) := (others => '0');
|
||||
signal error_seen : std_logic := '0';
|
||||
signal idelay_ce : std_logic := '0';
|
||||
signal idelay_count : std_logic_vector(4 downto 0) := (others => '0');
|
||||
signal symbol_sync_i : std_logic := '0';
|
||||
|
||||
begin
|
||||
delay_count <= idelay_count;
|
||||
delay_ce <= idelay_ce;
|
||||
|
||||
detect_alignment_proc: process(clk)
|
||||
begin
|
||||
-------------------------------------------------------------
|
||||
-- If there are a dozen or so symbol errors in at a rate of
|
||||
-- greater than 1 in a million then advance the delay and
|
||||
-- if that wraps then assert the bitslip signal
|
||||
-------------------------------------------------------------
|
||||
if rising_edge(clk) then
|
||||
-----------------------------------
|
||||
-- See if an error has been seen
|
||||
--
|
||||
-- Holdoff gives a few cycles for
|
||||
-- bitslips and delay changes to
|
||||
-- take effect.
|
||||
-----------------------------------
|
||||
error_seen <= '0';
|
||||
if holdoff = 0 then
|
||||
if invalid_symbol = '1' then
|
||||
error_seen <= '1';
|
||||
end if;
|
||||
else
|
||||
holdoff <= holdoff-1;
|
||||
end if;
|
||||
---------------------------------------------
|
||||
-- Keep track of valid symbol count vs errors
|
||||
--
|
||||
-- Each error increase the count by a million,
|
||||
-- each valid sysmbol decreases the count by
|
||||
-- one. So after 12 errors it will cause us to
|
||||
-- change bitslip or delay settings, but it will
|
||||
-- take 7 million cycles until the high four
|
||||
-- bits are zeros (and the link considered OK)
|
||||
-----------------------------------------------
|
||||
bitslip <= '0';
|
||||
idelay_ce <= '0';
|
||||
if error_seen = '1' then
|
||||
if signal_quality(27 downto 24) = x"F" then
|
||||
------------------------------------------
|
||||
-- Enough errors to cause us to loose sync
|
||||
-- (if we had it!)
|
||||
------------------------------------------
|
||||
symbol_sync_i <= '0';
|
||||
--------------------------------------
|
||||
-- Hold off acting on any more errors
|
||||
-- while we adjust the delay or bitslip
|
||||
--------------------------------------
|
||||
holdoff <= (others => '1');
|
||||
-----------------------
|
||||
-- Bitslip if required
|
||||
-----------------------
|
||||
if unsigned(idelay_count) = 31 then
|
||||
bitslip <= '1';
|
||||
end if;
|
||||
-------------------------------------------------------------------
|
||||
-- And adjust the delay setting (will wrap to 0 when bitslipping)
|
||||
-------------------------------------------------------------------
|
||||
idelay_count <= std_logic_vector(unsigned(idelay_count)+1);
|
||||
idelay_ce <= '1';
|
||||
-------------------------------------------------------------------
|
||||
-- It will need 4M good symbols to avoid adjusting the timing again
|
||||
-------------------------------------------------------------------
|
||||
signal_quality(27 downto 24) <= x"4";
|
||||
else
|
||||
signal_quality <= signal_quality + x"100000"; -- add a million if there is a symbol error
|
||||
end if;
|
||||
else
|
||||
-----------------------------------------------
|
||||
-- Count down by one, as we are one symbol
|
||||
-- closer to having a valid stream
|
||||
-----------------------------------------------
|
||||
if signal_quality(27 downto 24) > 0 then
|
||||
signal_quality <= signal_quality - 1; -- add a million if there is a symvole error;
|
||||
end if;
|
||||
end if;
|
||||
------------------------------------
|
||||
-- if we have counted down about 3M
|
||||
-- symbols without any symbol errors
|
||||
-- being seen then we are in sync
|
||||
------------------------------------
|
||||
if signal_quality(27 downto 24) = "0000" then
|
||||
symbol_sync <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
267
src/audio_meters.vhd
Normal file
267
src/audio_meters.vhd
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: audio_meters - Behavioral
|
||||
--
|
||||
-- Description: Insert audio level meters on a video stream.
|
||||
--
|
||||
-- Will need to make allowances for interlaced sources!
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity audio_meters is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
is_interlaced : in std_logic;
|
||||
is_second_field : in std_logic;
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0);
|
||||
|
||||
-------------------------------------
|
||||
-- Audio Levels
|
||||
-------------------------------------
|
||||
signal audio_channel : in std_logic_vector(2 downto 0);
|
||||
signal audio_de : in std_logic;
|
||||
signal audio_level : in std_logic_vector(5 downto 0)
|
||||
);
|
||||
end audio_meters;
|
||||
|
||||
architecture Behavioral of audio_meters is
|
||||
signal col_count : unsigned(11 downto 0);
|
||||
signal line_count : unsigned(11 downto 0);
|
||||
signal last_hsync : std_logic := '0';
|
||||
signal last_vsync : std_logic := '0';
|
||||
signal last_blank : std_logic := '0';
|
||||
|
||||
signal mid_blank : std_logic;
|
||||
signal mid_hsync : std_logic;
|
||||
signal mid_vsync : std_logic;
|
||||
signal mid_red : std_logic_vector(7 downto 0);
|
||||
signal mid_green : std_logic_vector(7 downto 0);
|
||||
signal mid_blue : std_logic_vector(7 downto 0);
|
||||
signal bar_draw : std_logic;
|
||||
signal bar_col : unsigned(6 downto 0); -- 0-127
|
||||
signal bar_line : unsigned(5 downto 0); -- 0-63
|
||||
|
||||
type a_level is array (0 to 7) of unsigned(5 downto 0);
|
||||
signal levels : a_level;
|
||||
|
||||
type a_peak is array (0 to 7) of unsigned(7 downto 0);
|
||||
signal peaks : a_peak;
|
||||
|
||||
signal pending_drop : std_logic := '0';
|
||||
signal drop_index : unsigned(2 downto 0) := (others => '0');
|
||||
|
||||
signal u_sample : unsigned(5 downto 0) := (others => '0');
|
||||
signal level : unsigned(5 downto 0);
|
||||
signal peak : unsigned(5 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
level_proc: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
-------------------------------------------------
|
||||
-- Update the peak level, or if pending_drop is
|
||||
-- set then drop the peak and level by 1 every
|
||||
-- frame.
|
||||
--
|
||||
-- This causes 'peak' to fall at 1/4th the speed
|
||||
-- of 'level', but makes for inconsistent
|
||||
-- behaviour depending on frame rate :-(
|
||||
-------------------------------------------------
|
||||
if audio_de = '1' then
|
||||
if levels(to_integer(unsigned(audio_channel))) < unsigned(audio_level) then
|
||||
levels(to_integer(unsigned(audio_channel))) <= unsigned(audio_level);
|
||||
end if;
|
||||
if peaks(to_integer(unsigned(audio_channel))) < unsigned(audio_level &"00") then
|
||||
peaks(to_integer(unsigned(audio_channel))) <= unsigned(audio_level & "00");
|
||||
end if;
|
||||
else
|
||||
if pending_drop = '1' then
|
||||
if levels(to_integer(drop_index)) > 0 then
|
||||
levels(to_integer(drop_index)) <= levels(to_integer(drop_index))-1;
|
||||
end if;
|
||||
if peaks(to_integer(drop_index)) > 0 then
|
||||
peaks(to_integer(drop_index)) <= peaks(to_integer(drop_index))-1;
|
||||
end if;
|
||||
if drop_index = "000" then
|
||||
pending_drop <= '0';
|
||||
end if;
|
||||
drop_index <= drop_index-1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Signal to reduce (drop' the levels of the meters once each frame (of field for interlaced sources
|
||||
if last_vsync = '0' and in_vsync = '1' then
|
||||
pending_drop <= '1';
|
||||
drop_index <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
video_proc: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
out_blank <= mid_blank;
|
||||
out_hsync <= mid_hsync;
|
||||
out_vsync <= mid_vsync;
|
||||
out_red <= mid_red;
|
||||
out_green <= mid_green;
|
||||
out_blue <= mid_blue;
|
||||
|
||||
if bar_draw = '1' then
|
||||
if bar_col(3 downto 1) /= "000" and bar_col(3 downto 1) /= "111" then
|
||||
if peak > bar_line then
|
||||
if peak > 60 then
|
||||
out_red(out_red'high) <= '1';
|
||||
else
|
||||
out_green(out_green'high) <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if level = bar_line then
|
||||
out_red <= (others => '1');
|
||||
out_green <= (others => '1');
|
||||
out_blue <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- the mid_* signals contain the video with the box drawn to house the meters
|
||||
-----------------------------------------------------------------------------
|
||||
mid_blank <= in_blank;
|
||||
mid_hsync <= in_hsync;
|
||||
mid_vsync <= in_vsync;
|
||||
mid_red <= in_red;
|
||||
mid_green <= in_green;
|
||||
mid_blue <= in_blue;
|
||||
--------------------------------------------------
|
||||
-- For working out if we need to draw colour bars
|
||||
--------------------------------------------------
|
||||
bar_draw <= '0';
|
||||
bar_col <= unsigned(col_count(6 downto 0))-1;
|
||||
bar_line <= to_unsigned(64,6)-unsigned(line_count(5 downto 0));
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Retreive the levels for the bar. There is an
|
||||
-- off-by-one error hidden by the bar boarder.
|
||||
-----------------------------------------------------------------------------
|
||||
level <= levels(to_integer(col_count(6 downto 4)));
|
||||
peak <= peaks(to_integer(col_count(6 downto 4)))(7 downto 2);
|
||||
|
||||
-------------------------------------------------------
|
||||
-- Halve the intensity of the area where the meters are.
|
||||
-------------------------------------------------------
|
||||
if col_count > 0 and col_count < 129 and line_count > 0 and line_count < 65 then
|
||||
bar_draw <= '1';
|
||||
end if;
|
||||
|
||||
if col_count > 0 and col_count < 129 and line_count > 0 and line_count < 65 then
|
||||
mid_red <= "0" & in_red(in_red'high downto 1);
|
||||
mid_green <= "0" & in_green(in_green'high downto 1);
|
||||
mid_blue <= "0" & in_blue(in_blue'high downto 1);
|
||||
end if;
|
||||
|
||||
-- Draw bounding box left/right sides
|
||||
if (col_count = 0 or col_count = 129) and line_count < 66 then
|
||||
mid_red <= (others => '1');
|
||||
mid_green <= (others => '1');
|
||||
mid_blue <= (others => '1');
|
||||
end if;
|
||||
-- Draw bounding box top/bottom sides
|
||||
if (line_count = 0 or line_count = 65) and col_count < 130 then
|
||||
mid_red <= (others => '1');
|
||||
mid_green <= (others => '1');
|
||||
mid_blue <= (others => '1');
|
||||
end if;
|
||||
|
||||
|
||||
-- Increment the column count on when active pixels are seen
|
||||
if in_blank = '0' then
|
||||
col_count <= col_count + 1;
|
||||
end if;
|
||||
|
||||
-- The end of active video is used to increment the line count
|
||||
if last_blank = '0' and in_blank = '1' then
|
||||
if is_interlaced = '1' then
|
||||
line_count <= line_count + 2;
|
||||
else
|
||||
line_count <= line_count + 1;
|
||||
end if;
|
||||
col_count <= (others => '0');
|
||||
end if;
|
||||
|
||||
-- Reset the line count on falling vsync
|
||||
if last_vsync = '1' and in_vsync = '0' then
|
||||
if is_interlaced = '1' and is_second_field = '1' then
|
||||
line_count <= (0 => '1', others => '0');
|
||||
else
|
||||
line_count <= (others => '0');
|
||||
end if;
|
||||
end if;
|
||||
-- remember the hsync and vsync values
|
||||
last_vsync <= in_vsync;
|
||||
last_hsync <= in_hsync;
|
||||
last_blank <= in_blank;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
194
src/audio_to_db.vhd
Normal file
194
src/audio_to_db.vhd
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: audio_to_db - Behavioral
|
||||
--
|
||||
-- Description: Calcuate the approximate DB level of an audio signal, with a
|
||||
-- return of 63 indicating 0db, (e.g. 3 = -60fb)
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity audio_to_db is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
|
||||
in_channel : in STD_LOGIC_VECTOR (2 downto 0);
|
||||
in_de : in STD_LOGIC;
|
||||
in_sample : in STD_LOGIC_VECTOR (23 downto 0);
|
||||
|
||||
out_channel : out STD_LOGIC_VECTOR (2 downto 0);
|
||||
out_de : out STD_LOGIC;
|
||||
out_level : out STD_LOGIC_VECTOR (5 downto 0));
|
||||
end audio_to_db;
|
||||
|
||||
architecture Behavioral of audio_to_db is
|
||||
|
||||
signal s7_sample : unsigned (23 downto 0);
|
||||
signal s7_de : STD_LOGIC;
|
||||
signal s7_channel : STD_LOGIC_VECTOR (2 downto 0);
|
||||
signal s7_level : unsigned( 7 downto 0);
|
||||
|
||||
signal s6_sample : unsigned (23 downto 0);
|
||||
signal s6_de : STD_LOGIC;
|
||||
signal s6_channel : STD_LOGIC_VECTOR (2 downto 0);
|
||||
signal s6_level : unsigned( 7 downto 0);
|
||||
|
||||
signal s5_sample : unsigned (23 downto 0);
|
||||
signal s5_de : STD_LOGIC;
|
||||
signal s5_channel : STD_LOGIC_VECTOR (2 downto 0);
|
||||
signal s5_level : unsigned( 7 downto 0);
|
||||
|
||||
signal s4_sample : unsigned (23 downto 0);
|
||||
signal s4_de : STD_LOGIC;
|
||||
signal s4_channel : STD_LOGIC_VECTOR (2 downto 0);
|
||||
signal s4_level : unsigned( 7 downto 0);
|
||||
|
||||
signal s3_sample : unsigned (23 downto 0);
|
||||
signal s3_de : STD_LOGIC;
|
||||
signal s3_channel : STD_LOGIC_VECTOR (2 downto 0);
|
||||
signal s3_level : unsigned( 7 downto 0);
|
||||
|
||||
signal s2_sample : unsigned (23 downto 0);
|
||||
signal s2_de : STD_LOGIC;
|
||||
signal s2_channel : STD_LOGIC_VECTOR (2 downto 0);
|
||||
signal s2_level : unsigned( 7 downto 0);
|
||||
|
||||
signal s1_sample : unsigned (23 downto 0);
|
||||
signal s1_de : STD_LOGIC;
|
||||
signal s1_channel : STD_LOGIC_VECTOR (2 downto 0);
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
out_channel <= s7_channel;
|
||||
out_de <= s7_de;
|
||||
if s7_level(7 downto 6) = "00" then
|
||||
out_level <= std_logic_vector(to_unsigned(63,6)-s7_level(5 downto 0));
|
||||
else
|
||||
out_level <= (others => '0');
|
||||
end if;
|
||||
|
||||
-- Finally the last stage to get a db level
|
||||
s7_channel <= s6_channel;
|
||||
s7_de <= s6_de;
|
||||
if s6_sample(22 downto 15) < 72 then
|
||||
s7_level <= s6_level + 5;
|
||||
elsif s6_sample(22 downto 15) < 81 then
|
||||
s7_level <= s6_level + 4;
|
||||
elsif s6_sample(22 downto 15) < 91 then
|
||||
s7_level <= s6_level + 3;
|
||||
elsif s6_sample(22 downto 15) < 102 then
|
||||
s7_level <= s6_level + 2;
|
||||
elsif s6_sample(22 downto 15) < 114 then
|
||||
s7_level <= s6_level + 1;
|
||||
else
|
||||
s7_level <= s6_level + 1;
|
||||
end if;
|
||||
|
||||
-- Stage 5 - shift up 2 bits if needed(bit 23 of sample will be 0)
|
||||
s6_channel <= s5_channel;
|
||||
s6_de <= s5_de;
|
||||
if s5_sample(23 downto 22) = "00" then
|
||||
s6_sample <= s5_sample(22 downto 0) & "0";
|
||||
s6_level <= s5_level + to_unsigned(6,8);
|
||||
else
|
||||
s6_sample <= s5_sample;
|
||||
s6_level <= s5_level;
|
||||
end if;
|
||||
|
||||
-- Stage 5 - shift up 2 bits if needed(bit 23 of sample will be 0)
|
||||
s5_channel <= s4_channel;
|
||||
s5_de <= s4_de;
|
||||
if s4_sample(23 downto 21) = "000" then
|
||||
s5_sample <= s4_sample(21 downto 0) & "00";
|
||||
s5_level <= s4_level + to_unsigned(12,8);
|
||||
else
|
||||
s5_sample <= s4_sample;
|
||||
s5_level <= s4_level;
|
||||
end if;
|
||||
|
||||
-- Stage 4 - shift up 4 bits if needed(bit 23 of sample will be 0)
|
||||
s4_channel <= s3_channel;
|
||||
s4_de <= s3_de;
|
||||
if s3_sample(23 downto 19) = "00000" then
|
||||
s4_sample <= s3_sample(19 downto 0) & "0000";
|
||||
s4_level <= s3_level + to_unsigned(24,8);
|
||||
else
|
||||
s4_sample <= s3_sample;
|
||||
s4_level <= s3_level;
|
||||
end if;
|
||||
|
||||
-- Stage 3 - shift up 4 bits if needed(bit 23 of sample will be 0)
|
||||
s3_channel <= s2_channel;
|
||||
s3_de <= s2_de;
|
||||
if s2_sample(23 downto 19) = "00000" then
|
||||
s3_sample <= s2_sample(19 downto 0) & "0000";
|
||||
s3_level <= s2_level + to_unsigned(24,8);
|
||||
else
|
||||
s3_sample <= s2_sample;
|
||||
s3_level <= s2_level;
|
||||
end if;
|
||||
|
||||
-- Stage 2 - shift up 4 bits if needed(bit 23 of sample will be 0)
|
||||
s2_channel <= s1_channel;
|
||||
s2_de <= s1_de;
|
||||
if s1_sample(23 downto 19) = "00000" then
|
||||
s2_sample <= s1_sample(19 downto 0) & "0000";
|
||||
s2_level <= to_unsigned(24,8);
|
||||
else
|
||||
s2_sample <= s1_sample;
|
||||
s2_level <= to_unsigned(0,8);
|
||||
end if;
|
||||
|
||||
--- Stage 1 - remove any sign.
|
||||
s1_channel <= in_channel;
|
||||
s1_de <= in_de;
|
||||
if in_sample(23) = '1' then
|
||||
s1_sample <= to_unsigned(0,24) - unsigned(in_sample);
|
||||
else
|
||||
s1_sample <= unsigned(in_sample);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
226
src/conversion_to_RGB.vhd
Normal file
226
src/conversion_to_RGB.vhd
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: conversion_YCbCr_to_RGB - Behavioral
|
||||
--
|
||||
-- Description: Convert from RGB, studio level RGB or YCbCr to full range RGB
|
||||
--
|
||||
-- Designed to take the same amount of time regardless of conversion
|
||||
-- being performed.
|
||||
----------------------------------------------------------------------------------
|
||||
-- When using 12-bit studio range inputs and the HD colourspace
|
||||
--
|
||||
-- R = (Y-64)*1.164 + (Cb-2048) *0.090 + (Cr-2048)*1.793
|
||||
-- G = (Y-64)*1.164 - (Cb-2048) *0.213 - (Cr-2048)*0.533
|
||||
-- B = (Y-64)*1.164 + (Cb-2048) *2.112 + (Cr-2048)*0.000
|
||||
--
|
||||
-- To avoid the problems with signed/unsigned multiplication this
|
||||
-- has been rearranged to
|
||||
--
|
||||
-- R = Y*1.164 + Cb*0.090 + Cr*1.793 - 64*1.164 - 2048*0.090 - 2048*1.793
|
||||
-- G = Y*1.164 - Cb*0.213 - Cr*0.533 - 64*1.164 + 2048*0.213 + 2048*0.533
|
||||
-- B = Y*1.164 + Cb*2.112 + Cr*0.000 - 64*1.164 - 2048*2.112 - 2048*0.000
|
||||
--
|
||||
-- And then all the decimals have been scaled by 4096 This then only requires
|
||||
-- five multipliers (as two are zero and three others are identical.
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity conversion_to_RGB is
|
||||
port ( clk : in std_Logic;
|
||||
input_is_YCbCr : in std_Logic;
|
||||
input_is_sRGB : in std_Logic;
|
||||
|
||||
------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_U : in std_logic_vector(11 downto 0); -- B or Cb
|
||||
in_V : in std_logic_vector(11 downto 0); -- G or Y
|
||||
in_W : in std_logic_vector(11 downto 0); -- R or Cr
|
||||
|
||||
------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_R : out std_logic_vector(11 downto 0);
|
||||
out_G : out std_logic_vector(11 downto 0);
|
||||
out_B : out std_logic_vector(11 downto 0));
|
||||
end entity;
|
||||
|
||||
architecture Behavioral of conversion_to_RGB is
|
||||
------------------------------
|
||||
-- For the pipeline
|
||||
------------------------------
|
||||
signal s1_blank : std_logic;
|
||||
signal s1_hsync : std_logic;
|
||||
signal s1_vsync : std_logic;
|
||||
signal s1_U : std_logic_vector(12 downto 0); -- B or Cb, plus underflow guard bit
|
||||
signal s1_V : std_logic_vector(12 downto 0); -- G or Y, plus underflow guard bit
|
||||
signal s1_W : std_logic_vector(12 downto 0); -- R or Cr, plus underflow guard bit
|
||||
|
||||
signal s2_blank : std_logic;
|
||||
signal s2_hsync : std_logic;
|
||||
signal s2_vsync : std_logic;
|
||||
signal s2_U : std_logic_vector(12 downto 0); -- B or Cb, plus overflow guard bit
|
||||
signal s2_V : std_logic_vector(12 downto 0); -- G or Y, plus overflow guard bit
|
||||
signal s2_W : std_logic_vector(12 downto 0); -- R or Cr, plus overflow guard bit
|
||||
|
||||
------------------------------
|
||||
-- For Calculation
|
||||
------------------------------
|
||||
signal a : unsigned(26 downto 0) := (others => '0');
|
||||
signal b : unsigned(26 downto 0) := (others => '0');
|
||||
signal c : unsigned(26 downto 0) := (others => '0');
|
||||
signal d : unsigned(26 downto 0) := (others => '0');
|
||||
signal e : unsigned(26 downto 0) := (others => '0');
|
||||
signal R_raw : unsigned(26 downto 0) := (others => '0');
|
||||
signal G_raw : unsigned(26 downto 0) := (others => '0');
|
||||
signal B_raw : unsigned(26 downto 0) := (others => '0');
|
||||
begin
|
||||
clk_proc: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
-----------------------------------------------
|
||||
-- Step 3: clamp the result
|
||||
-----------------------------------------------
|
||||
out_blank <= s2_blank;
|
||||
out_hsync <= s2_hsync;
|
||||
out_vsync <= s2_vsync;
|
||||
if input_is_YCbCr = '0' then
|
||||
-- trap overflows form prior stage
|
||||
if s2_U(s2_U'high) = '0' then
|
||||
out_B <= s2_U(s2_U'high-1 downto 0);
|
||||
else
|
||||
out_B <= (others => '1');
|
||||
end if;
|
||||
|
||||
if s2_V(s2_V'high) = '0' then
|
||||
out_G <= s2_V(s2_V'high-1 downto 0);
|
||||
else
|
||||
out_G <= (others => '1');
|
||||
end if;
|
||||
|
||||
if s2_W(s2_W'high) = '0' then
|
||||
out_R <= s2_W(s2_W'high-1 downto 0);
|
||||
else
|
||||
out_R <= (others => '1');
|
||||
end if;
|
||||
else
|
||||
case R_raw(R_raw'high-1 downto R_raw'high-2) is
|
||||
when "00" => out_R <= std_logic_vector(R_raw(R_raw'high-3 downto R_raw'high-14)); -- In range
|
||||
when "01" => out_R <= (others => '1'); -- Overflow
|
||||
when others => out_R <= (others => '0'); -- Underflow
|
||||
end case;
|
||||
|
||||
case G_raw(G_raw'high-1 downto G_raw'high-2) is
|
||||
when "00" => out_G <= std_logic_vector(G_raw(G_raw'high-3 downto G_raw'high-14)); -- In range
|
||||
when "01" => out_G <= (others => '1'); -- Overflow
|
||||
when others => out_G <= (others => '0'); -- Underflow
|
||||
end case;
|
||||
|
||||
case B_raw(B_raw'high-1 downto B_raw'high-2) is
|
||||
when "00" => out_B <= std_logic_vector(B_raw(B_raw'high-3 downto B_raw'high-14)); -- In range
|
||||
when "01" => out_B <= (others => '1'); -- Overflow
|
||||
when others => out_B <= (others => '0'); -- Underflow
|
||||
end case;
|
||||
end if;
|
||||
-------------------------------------------------
|
||||
-- Step 2: Add the partial results and remove the
|
||||
-- offset introduced by the use of studio range
|
||||
-------------------------------------------------
|
||||
s2_blank <= s1_blank;
|
||||
s2_hsync <= s1_hsync;
|
||||
s2_vsync <= s1_vsync;
|
||||
if input_is_sRGB = '1' then
|
||||
-- Trap underflows from prior stage
|
||||
if s1_U(s1_U'high) = '0' then
|
||||
s2_U <= std_logic_vector(unsigned(s1_U) + unsigned(s1_U(s1_U'high downto 5)));
|
||||
else
|
||||
s2_U <= (others => '0');
|
||||
end if;
|
||||
|
||||
if s1_V(s1_V'high) = '0' then
|
||||
s2_V <= std_logic_vector(unsigned(s1_V) + unsigned(s1_V(s1_V'high downto 5)));
|
||||
else
|
||||
s2_V <= (others => '0');
|
||||
end if;
|
||||
|
||||
if s1_W(s1_W'high) = '0' then
|
||||
s2_W <= std_logic_vector(unsigned(s1_W) + unsigned(s1_W(s1_W'high downto 5)));
|
||||
else
|
||||
s2_W <= (others => '0');
|
||||
end if;
|
||||
else
|
||||
s2_U <= s1_U;
|
||||
s2_V <= s1_V;
|
||||
s2_W <= s1_W;
|
||||
end if;
|
||||
R_raw <= a + d - to_unsigned(4767*256 + 0*2048 + 7344*2048, 27);
|
||||
G_raw <= a - b - e + to_unsigned(-4767*256 + 872*2048 + 2183*2048, 27);
|
||||
B_raw <= a + c - to_unsigned(4767*256 + 8650*2048 + 0*2048, 27);
|
||||
|
||||
-------------------------------------------------
|
||||
-- Step 1: Multiply the incoming values by the
|
||||
-- Conversion coefficients
|
||||
-------------------------------------------------
|
||||
s1_blank <= in_blank;
|
||||
s1_hsync <= in_hsync;
|
||||
s1_vsync <= in_vsync;
|
||||
if input_is_sRGB = '1' then
|
||||
s1_U <= std_logic_vector(unsigned('0' & in_U) - 256);
|
||||
s1_V <= std_logic_vector(unsigned('0' & in_V) - 256);
|
||||
s1_W <= std_logic_vector(unsigned('0' & in_W) - 256);
|
||||
else
|
||||
s1_U <= '0' & in_U;
|
||||
s1_V <= '0' & in_V;
|
||||
s1_W <= '0' & in_W;
|
||||
end if;
|
||||
a <= unsigned(in_V) * to_unsigned(4767,15); -- 1.164 * 2^12
|
||||
b <= unsigned(in_U) * to_unsigned( 872,15); -- 0.213 * 2^12
|
||||
c <= unsigned(in_U) * to_unsigned(8650,15); -- 2.112 * 2^12
|
||||
d <= unsigned(in_W) * to_unsigned(7344,15); -- 1.793 * 2^12
|
||||
e <= unsigned(in_W) * to_unsigned(2183,15); -- 0.533 * 2^12
|
||||
end if;
|
||||
end process;
|
||||
end architecture;
|
||||
178
src/deserialiser_1_to_10.vhd
Normal file
178
src/deserialiser_1_to_10.vhd
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: deserialiser_1_to_10 - Behavioral
|
||||
--
|
||||
-- Description: A 10-to-1 deserialiser for the Artix 7
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.ALL;
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity deserialiser_1_to_10 is
|
||||
Port ( clk_mgmt : in std_logic;
|
||||
delay_ce : in std_logic;
|
||||
delay_count : in std_logic_vector (4 downto 0);
|
||||
|
||||
ce : in STD_LOGIC;
|
||||
clk : in std_logic;
|
||||
clk_x1 : in std_logic;
|
||||
bitslip : in std_logic;
|
||||
clk_x5 : in std_logic;
|
||||
serial : in std_logic;
|
||||
reset : in std_logic;
|
||||
data : out std_logic_vector (9 downto 0));
|
||||
end deserialiser_1_to_10;
|
||||
|
||||
architecture Behavioral of deserialiser_1_to_10 is
|
||||
signal delayed : std_logic := '0';
|
||||
signal shift1 : std_logic := '0';
|
||||
signal shift2 : std_logic := '0';
|
||||
signal clkb : std_logic := '1';
|
||||
attribute IODELAY_GROUP : STRING;
|
||||
attribute IODELAY_GROUP of IDELAYE2_inst: label is "idelay_group";
|
||||
|
||||
begin
|
||||
|
||||
IDELAYE2_inst : IDELAYE2
|
||||
generic map (
|
||||
CINVCTRL_SEL => "FALSE",
|
||||
DELAY_SRC => "DATAIN",
|
||||
HIGH_PERFORMANCE_MODE => "TRUE",
|
||||
IDELAY_TYPE => "VAR_LOAD",
|
||||
IDELAY_VALUE => 0,
|
||||
PIPE_SEL => "FALSE",
|
||||
REFCLK_FREQUENCY => 200.0,
|
||||
SIGNAL_PATTERN => "DATA"
|
||||
)
|
||||
port map (
|
||||
DATAIN => serial,
|
||||
IDATAIN => '0',
|
||||
DATAOUT => delayed,
|
||||
--
|
||||
CNTVALUEOUT => open,
|
||||
C => clk,
|
||||
CE => delay_ce,
|
||||
CINVCTRL => '0',
|
||||
CNTVALUEIN => delay_count,
|
||||
INC => '0',
|
||||
LD => '1',
|
||||
LDPIPEEN => '0',
|
||||
REGRST => '0'
|
||||
);
|
||||
clkb <= not clk_x5;
|
||||
|
||||
ISERDESE2_master : ISERDESE2
|
||||
generic map (
|
||||
DATA_RATE => "DDR",
|
||||
DATA_WIDTH => 10,
|
||||
DYN_CLKDIV_INV_EN => "FALSE",
|
||||
DYN_CLK_INV_EN => "FALSE",
|
||||
INIT_Q1 => '0', INIT_Q2 => '0', INIT_Q3 => '0', INIT_Q4 => '0',
|
||||
INTERFACE_TYPE => "NETWORKING",
|
||||
IOBDELAY => "IFD",
|
||||
NUM_CE => 1,
|
||||
OFB_USED => "FALSE",
|
||||
SERDES_MODE => "MASTER",
|
||||
SRVAL_Q1 => '0', SRVAL_Q2 => '0', SRVAL_Q3 => '0', SRVAL_Q4 => '0'
|
||||
)
|
||||
port map (
|
||||
O => open,
|
||||
Q1 => data(9), Q2 => data(8), Q3 => data(7), Q4 => data(6),
|
||||
Q5 => data(5), Q6 => data(4), Q7 => data(3), Q8 => data(2),
|
||||
SHIFTOUT1 => shift1, SHIFTOUT2 => shift2,
|
||||
BITSLIP => bitslip,
|
||||
CE1 => ce, CE2 => '1',
|
||||
CLKDIVP => '0',
|
||||
CLK => clk_x5,
|
||||
CLKB => clkb,
|
||||
CLKDIV => clk_x1,
|
||||
OCLK => '0',
|
||||
DYNCLKDIVSEL => '0',
|
||||
DYNCLKSEL => '0',
|
||||
D => '0',
|
||||
DDLY => delayed,
|
||||
OFB => '0',
|
||||
OCLKB => '0',
|
||||
RST => reset,
|
||||
SHIFTIN1 => '0',
|
||||
SHIFTIN2 => '0'
|
||||
);
|
||||
|
||||
ISERDESE2_slave : ISERDESE2
|
||||
generic map (
|
||||
DATA_RATE => "DDR",
|
||||
DATA_WIDTH => 10,
|
||||
DYN_CLKDIV_INV_EN => "FALSE",
|
||||
DYN_CLK_INV_EN => "FALSE",
|
||||
INIT_Q1 => '0', INIT_Q2 => '0', INIT_Q3 => '0', INIT_Q4 => '0',
|
||||
INTERFACE_TYPE => "NETWORKING",
|
||||
IOBDELAY => "IFD",
|
||||
NUM_CE => 1,
|
||||
OFB_USED => "FALSE",
|
||||
SERDES_MODE => "SLAVE",
|
||||
SRVAL_Q1 => '0', SRVAL_Q2 => '0', SRVAL_Q3 => '0', SRVAL_Q4 => '0'
|
||||
)
|
||||
port map (
|
||||
O => open,
|
||||
Q1 => open, Q2 => open, Q3 => data(1), Q4 => data(0),
|
||||
Q5 => open, Q6 => open, Q7 => open, Q8 => open,
|
||||
SHIFTOUT1 => open, SHIFTOUT2 => open,
|
||||
BITSLIP => bitslip,
|
||||
CE1 => ce, CE2 => '1',
|
||||
CLKDIVP => '0',
|
||||
CLK => CLK_x5,
|
||||
CLKB => clkb,
|
||||
CLKDIV => clk_x1,
|
||||
OCLK => '0',
|
||||
DYNCLKDIVSEL => '0',
|
||||
DYNCLKSEL => '0',
|
||||
D => '0',
|
||||
DDLY => '0',
|
||||
OFB => '0',
|
||||
OCLKB => '0',
|
||||
RST => reset,
|
||||
SHIFTIN1 => shift1,
|
||||
SHIFTIN2 => shift2
|
||||
);
|
||||
end Behavioral;
|
||||
118
src/detect_interlace.vhd
Normal file
118
src/detect_interlace.vhd
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: detect_interlace - Behavioral
|
||||
--
|
||||
-- Description: Detect if the source is interlaced, and report what field is
|
||||
-- being processed
|
||||
--
|
||||
-- Will need to make allowances for interlaced sources!
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity detect_interlace is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
hsync : in std_logic;
|
||||
vsync : in std_logic;
|
||||
is_interlaced : out std_logic;
|
||||
is_second_field : out std_logic);
|
||||
end entity;
|
||||
|
||||
architecture Behavioral of detect_interlace is
|
||||
signal last_vsync : std_logic := '0';
|
||||
signal last_hsync : std_logic := '0';
|
||||
signal first_quarter : unsigned(11 downto 0) := (others => '0');
|
||||
signal last_quarter : unsigned(11 downto 0) := (others => '0');
|
||||
signal hcount : unsigned(11 downto 0) := (others => '0');
|
||||
signal last_vsync_pos : unsigned(11 downto 0) := (others => '0');
|
||||
signal second_field : std_logic := '0';
|
||||
begin
|
||||
clk_proc: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if last_vsync = '0' and vsync = '1' then
|
||||
is_second_field <= '0';
|
||||
if hcount > first_quarter and hcount < last_quarter then
|
||||
-- The second field of an interlaced
|
||||
-- frame is indicated when the vsync is
|
||||
-- asserted in the middle of the scan line.
|
||||
--
|
||||
-- Also add a little check for a misbehaving source
|
||||
if last_vsync_pos /= hcount then
|
||||
is_interlaced <= '1';
|
||||
is_second_field <= '1';
|
||||
second_field <= '1';
|
||||
else
|
||||
is_interlaced <= '1';
|
||||
is_second_field <= '1';
|
||||
second_field <= '1';
|
||||
end if;
|
||||
|
||||
else
|
||||
-- If we see two 'field 1's in a row we
|
||||
-- switch back to indicating an
|
||||
-- uninterlaced source
|
||||
if second_field = '0' then
|
||||
is_interlaced <= '0';
|
||||
end if;
|
||||
is_second_field <= '0';
|
||||
second_field <= '0';
|
||||
end if;
|
||||
last_vsync_pos <= hcount;
|
||||
else
|
||||
end if;
|
||||
|
||||
if last_hsync = '0' and hsync = '1' then
|
||||
hcount <= (others => '0');
|
||||
first_quarter <= "00" & hcount(11 downto 2);
|
||||
last_quarter <= hcount+1-hcount(11 downto 2);
|
||||
else
|
||||
hcount <= hcount +1;
|
||||
end if;
|
||||
last_vsync <= vsync;
|
||||
last_hsync <= hsync;
|
||||
end if;
|
||||
end process;
|
||||
end architecture;
|
||||
|
||||
168
src/dvid_output.vhd
Normal file
168
src/dvid_output.vhd
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: DVID_output - Behavioral
|
||||
--
|
||||
-- Description: Convert a stream of pixels into a DVID output
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity DVID_output is
|
||||
Port (
|
||||
pixel_clk : in std_logic; -- Driven by BUFG
|
||||
pixel_io_clk_x1 : in std_logic; -- Driven by BUFIO
|
||||
pixel_io_clk_x5 : in std_logic; -- Driven by BUFIO
|
||||
|
||||
-- VGA Signals
|
||||
vga_blank : in std_logic;
|
||||
vga_hsync : in std_logic;
|
||||
vga_vsync : in std_logic;
|
||||
vga_red : in std_logic_vector(7 downto 0);
|
||||
vga_blue : in std_logic_vector(7 downto 0);
|
||||
vga_green : in std_logic_vector(7 downto 0);
|
||||
data_valid : in std_logic;
|
||||
|
||||
--- DVI-D out
|
||||
tmds_out_clk : out std_logic;
|
||||
tmds_out_ch0 : out std_logic;
|
||||
tmds_out_ch1 : out std_logic;
|
||||
tmds_out_ch2 : out std_logic
|
||||
);
|
||||
end DVID_output;
|
||||
|
||||
architecture Behavioral of DVID_output is
|
||||
|
||||
component tmds_encoder is
|
||||
Port ( clk : in std_logic;
|
||||
data : in std_logic_vector (7 downto 0);
|
||||
c : in std_logic_vector (1 downto 0);
|
||||
blank : in std_logic;
|
||||
encoded : out std_logic_vector (9 downto 0));
|
||||
end component;
|
||||
|
||||
component serialiser_10_to_1 is
|
||||
Port ( clk : in std_logic;
|
||||
clk_x5 : in std_logic;
|
||||
reset : in std_logic;
|
||||
data : in std_logic_vector (9 downto 0);
|
||||
serial : out std_logic);
|
||||
end component;
|
||||
|
||||
signal c0_tmds_symbol : std_logic_vector (9 downto 0);
|
||||
signal c1_tmds_symbol : std_logic_vector (9 downto 0);
|
||||
signal c2_tmds_symbol : std_logic_vector (9 downto 0);
|
||||
|
||||
signal reset_sr : std_logic_vector (2 downto 0) := (others => '1');
|
||||
signal reset : std_logic := '1';
|
||||
|
||||
begin
|
||||
reset <= reset_sr(0);
|
||||
|
||||
process(pixel_clk, data_valid)
|
||||
begin
|
||||
if data_valid = '0' then
|
||||
reset_sr <= (others => '1');
|
||||
elsif rising_edge(pixel_clk) then
|
||||
reset_sr <= '0' & reset_sr(reset_sr'high downto 1);
|
||||
end if;
|
||||
end process;
|
||||
---------------------
|
||||
-- TMDS Encoders
|
||||
---------------------
|
||||
c0_tmds: tmds_encoder port map (
|
||||
clk => pixel_clk,
|
||||
data => vga_blue,
|
||||
c(1) => vga_vsync,
|
||||
c(0) => vga_hsync,
|
||||
blank => vga_blank,
|
||||
encoded => c0_tmds_symbol);
|
||||
|
||||
c1_tmds: tmds_encoder port map (
|
||||
clk => pixel_clk,
|
||||
data => vga_green,
|
||||
c => (others => '0'),
|
||||
blank => vga_blank,
|
||||
encoded => c1_tmds_symbol);
|
||||
|
||||
c2_tmds: tmds_encoder port map (
|
||||
clk => pixel_clk,
|
||||
data => vga_red,
|
||||
c => (others => '0'),
|
||||
blank => vga_blank,
|
||||
encoded => c2_tmds_symbol);
|
||||
---------------------
|
||||
-- Output serializers
|
||||
---------------------
|
||||
ser_ch0: serialiser_10_to_1 port map (
|
||||
clk => pixel_io_clk_x1,
|
||||
clk_x5 => pixel_io_clk_x5,
|
||||
reset => reset,
|
||||
data => c0_tmds_symbol,
|
||||
serial => tmds_out_ch0);
|
||||
|
||||
ser_ch1: serialiser_10_to_1 port map (
|
||||
clk => pixel_io_clk_x1,
|
||||
clk_x5 => pixel_io_clk_x5,
|
||||
reset => reset,
|
||||
data => c1_tmds_symbol,
|
||||
serial => tmds_out_ch1);
|
||||
|
||||
ser_ch2: serialiser_10_to_1 port map (
|
||||
clk => pixel_io_clk_x1,
|
||||
clk_x5 => pixel_io_clk_x5,
|
||||
reset => reset,
|
||||
data => c2_tmds_symbol,
|
||||
serial => tmds_out_ch2);
|
||||
|
||||
ser_clk: serialiser_10_to_1 Port map (
|
||||
clk => pixel_io_clk_x1,
|
||||
clk_x5 => pixel_io_clk_x5,
|
||||
reset => reset,
|
||||
data => "0000011111",
|
||||
serial => tmds_out_clk);
|
||||
|
||||
end Behavioral;
|
||||
19
src/edge_cleaner.v
Normal file
19
src/edge_cleaner.v
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
module edge_cleaner(
|
||||
input clk,
|
||||
input in,
|
||||
output reg out
|
||||
);
|
||||
|
||||
reg [7:0] sr;
|
||||
|
||||
always @(posedge clk) begin
|
||||
sr <= {sr[6:0], in};
|
||||
|
||||
if (sr == 8'hff) begin
|
||||
out <= 1;
|
||||
end else if (sr == 8'h00) begin
|
||||
out <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
414
src/edge_enhance.vhd
Normal file
414
src/edge_enhance.vhd
Normal file
|
|
@ -0,0 +1,414 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hasmter@snap.net.nz>
|
||||
--
|
||||
-- Module Name: edge_enhance - Behavioral
|
||||
--
|
||||
-- Description: Video edge enhancement
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity edge_enhance is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
enable_feature : in std_logic;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0));
|
||||
end edge_enhance;
|
||||
|
||||
architecture Behavioral of edge_enhance is
|
||||
component line_delay is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0));
|
||||
end component;
|
||||
type a_bits is array(0 to 8) of std_logic;
|
||||
type a_component is array(0 to 8) of std_logic_vector(7 downto 0);
|
||||
signal blanks : a_bits;
|
||||
signal hsyncs : a_bits;
|
||||
signal vsyncs : a_bits;
|
||||
signal reds : a_component;
|
||||
signal greens : a_component;
|
||||
signal blues : a_component;
|
||||
|
||||
signal bypass_1_blank : std_logic := '0';
|
||||
signal bypass_1_hsync : std_logic := '0';
|
||||
signal bypass_1_vsync : std_logic := '0';
|
||||
signal bypass_1_red : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal bypass_1_blue : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal bypass_1_green : std_logic_vector(7 downto 0) := (others => '0');
|
||||
|
||||
signal bypass_2_blank : std_logic := '0';
|
||||
signal bypass_2_hsync : std_logic := '0';
|
||||
signal bypass_2_vsync : std_logic := '0';
|
||||
signal bypass_2_red : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal bypass_2_blue : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal bypass_2_green : std_logic_vector(7 downto 0) := (others => '0');
|
||||
|
||||
signal bypass_3_blank : std_logic := '0';
|
||||
signal bypass_3_hsync : std_logic := '0';
|
||||
signal bypass_3_vsync : std_logic := '0';
|
||||
signal bypass_3_red : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal bypass_3_blue : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal bypass_3_green : std_logic_vector(7 downto 0) := (others => '0');
|
||||
|
||||
signal sobel_3_hsync : std_logic := '0';
|
||||
signal sobel_3_blank : std_logic := '0';
|
||||
signal sobel_3_vsync : std_logic := '0';
|
||||
signal sobel_3_red : unsigned(12 downto 0) := (others => '0');
|
||||
signal sobel_3_green : unsigned(12 downto 0) := (others => '0');
|
||||
signal sobel_3_blue : unsigned(12 downto 0) := (others => '0');
|
||||
|
||||
signal sobel_2_hsync : std_logic := '0';
|
||||
signal sobel_2_blank : std_logic := '0';
|
||||
signal sobel_2_vsync : std_logic := '0';
|
||||
signal sobel_2_red_x : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_2_red_y : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_2_green_x : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_2_green_y : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_2_blue_x : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_2_blue_y : unsigned(11 downto 0) := (others => '0');
|
||||
|
||||
signal sobel_1_hsync : std_logic := '0';
|
||||
signal sobel_1_blank : std_logic := '0';
|
||||
signal sobel_1_vsync : std_logic := '0';
|
||||
signal sobel_1_red_left : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_red_right : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_red_top : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_red_bottom : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_green_left : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_green_right : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_green_top : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_green_bottom : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_blue_left : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_blue_right : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_blue_top : unsigned(11 downto 0) := (others => '0');
|
||||
signal sobel_1_blue_bottom : unsigned(11 downto 0) := (others => '0');
|
||||
begin
|
||||
blanks(0) <= in_blank;
|
||||
hsyncs(0) <= in_hsync;
|
||||
vsyncs(0) <= in_vsync;
|
||||
reds(0) <= in_red;
|
||||
greens(0) <= in_green;
|
||||
blues(0) <= in_blue;
|
||||
|
||||
i_line_delay_1: line_delay Port map (
|
||||
clk => clk,
|
||||
in_blank => blanks(0),
|
||||
in_hsync => hsyncs(0),
|
||||
in_vsync => vsyncs(0),
|
||||
in_red => reds(0),
|
||||
in_green => greens(0),
|
||||
in_blue => blues(0),
|
||||
|
||||
out_blank => blanks(3),
|
||||
out_hsync => hsyncs(3),
|
||||
out_vsync => vsyncs(3),
|
||||
out_red => reds(3),
|
||||
out_green => greens(3),
|
||||
out_blue => blues(3)
|
||||
);
|
||||
|
||||
i_line_delay_2: line_delay Port map (
|
||||
clk => clk,
|
||||
in_blank => blanks(3),
|
||||
in_hsync => hsyncs(3),
|
||||
in_vsync => vsyncs(3),
|
||||
in_red => reds(3),
|
||||
in_green => greens(3),
|
||||
in_blue => blues(3),
|
||||
|
||||
out_blank => blanks(6),
|
||||
out_hsync => hsyncs(6),
|
||||
out_vsync => vsyncs(6),
|
||||
out_red => reds(6),
|
||||
out_green => greens(6),
|
||||
out_blue => blues(6)
|
||||
);
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if enable_feature = '1' then
|
||||
out_hsync <= sobel_3_hsync;
|
||||
out_blank <= sobel_3_blank;
|
||||
out_vsync <= sobel_3_vsync;
|
||||
|
||||
if sobel_3_red(12 downto 12) = "0" then
|
||||
out_red <= std_logic_vector(sobel_3_red(11 downto 4));
|
||||
else
|
||||
out_red <= (others => '1');
|
||||
end if;
|
||||
|
||||
if sobel_3_green(12 downto 12) = "0" then
|
||||
out_green <= std_logic_vector(sobel_3_green(11 downto 4));
|
||||
else
|
||||
out_green <= (others => '1');
|
||||
end if;
|
||||
|
||||
if sobel_3_blue(12 downto 12) = "0" then
|
||||
out_blue <= std_logic_vector(sobel_3_blue(11 downto 4));
|
||||
else
|
||||
out_blue <= (others => '1');
|
||||
end if;
|
||||
else
|
||||
out_hsync <= bypass_3_hsync;
|
||||
out_blank <= bypass_3_blank;
|
||||
out_vsync <= bypass_3_vsync;
|
||||
out_red <= bypass_3_red;
|
||||
out_blue <= bypass_3_blue;
|
||||
out_green <= bypass_3_green;
|
||||
end if;
|
||||
|
||||
--------------------------------------
|
||||
-- For if we eed to bypass the feature
|
||||
--------------------------------------
|
||||
bypass_3_blank <= bypass_2_blank;
|
||||
bypass_3_hsync <= bypass_2_hsync;
|
||||
bypass_3_vsync <= bypass_2_vsync;
|
||||
bypass_3_red <= bypass_2_red;
|
||||
bypass_3_blue <= bypass_2_blue;
|
||||
bypass_3_green <= bypass_2_green;
|
||||
|
||||
bypass_2_blank <= bypass_1_blank;
|
||||
bypass_2_hsync <= bypass_1_hsync;
|
||||
bypass_2_vsync <= bypass_1_vsync;
|
||||
bypass_2_red <= bypass_1_red;
|
||||
bypass_2_blue <= bypass_1_blue;
|
||||
bypass_2_green <= bypass_1_green;
|
||||
|
||||
bypass_1_blank <= blanks(4);
|
||||
bypass_1_hsync <= hsyncs(4);
|
||||
bypass_1_vsync <= vsyncs(4);
|
||||
bypass_1_red <= reds(4);
|
||||
bypass_1_blue <= blues(4);
|
||||
bypass_1_green <= greens(4);
|
||||
|
||||
----------------------------------
|
||||
--- Calculating the Sobel operator
|
||||
----------------------------------
|
||||
sobel_3_blank <= sobel_2_blank;
|
||||
sobel_3_hsync <= sobel_2_hsync;
|
||||
sobel_3_vsync <= sobel_2_vsync;
|
||||
sobel_3_red <= ("0" & sobel_2_red_x) + sobel_2_red_y;
|
||||
sobel_3_green <= ("0" & sobel_2_green_x) + sobel_2_green_y;
|
||||
sobel_3_blue <= ("0" & sobel_2_blue_x) + sobel_2_blue_y;
|
||||
|
||||
-- For the red channel
|
||||
sobel_2_blank <= sobel_1_blank;
|
||||
sobel_2_hsync <= sobel_1_hsync;
|
||||
sobel_2_vsync <= sobel_1_vsync;
|
||||
|
||||
if sobel_1_red_left > sobel_1_red_right then
|
||||
sobel_2_red_x <= sobel_1_red_left - sobel_1_red_right;
|
||||
else
|
||||
sobel_2_red_x <= sobel_1_red_right - sobel_1_red_left;
|
||||
end if;
|
||||
if sobel_1_red_top > sobel_1_red_bottom then
|
||||
sobel_2_red_y <= sobel_1_red_top - sobel_1_red_bottom;
|
||||
else
|
||||
sobel_2_red_y <= sobel_1_red_bottom - sobel_1_red_top;
|
||||
end if;
|
||||
|
||||
-- For the green channel
|
||||
if sobel_1_green_left > sobel_1_green_right then
|
||||
sobel_2_green_x <= sobel_1_green_left - sobel_1_green_right;
|
||||
else
|
||||
sobel_2_green_x <= sobel_1_green_right - sobel_1_green_left;
|
||||
end if;
|
||||
if sobel_1_green_top > sobel_1_green_bottom then
|
||||
sobel_2_green_y <= sobel_1_green_top - sobel_1_green_bottom;
|
||||
else
|
||||
sobel_2_green_y <= sobel_1_green_bottom - sobel_1_green_top;
|
||||
end if;
|
||||
|
||||
-- For the blue channel
|
||||
if sobel_1_blue_left > sobel_1_blue_right then
|
||||
sobel_2_blue_x <= sobel_1_blue_left - sobel_1_blue_right;
|
||||
else
|
||||
sobel_2_blue_x <= sobel_1_blue_right - sobel_1_blue_left;
|
||||
end if;
|
||||
if sobel_1_blue_top > sobel_1_blue_bottom then
|
||||
sobel_2_blue_y <= sobel_1_blue_top - sobel_1_blue_bottom;
|
||||
else
|
||||
sobel_2_blue_y <= sobel_1_blue_bottom - sobel_1_blue_top;
|
||||
end if;
|
||||
|
||||
-- Now for the first stage;
|
||||
sobel_1_blank <= blanks(4);
|
||||
sobel_1_hsync <= hsyncs(4);
|
||||
sobel_1_vsync <= vsyncs(4);
|
||||
-- For the red channel
|
||||
sobel_1_red_left <= ("000" & unsigned(reds(0)) & "0") + ("0000" & unsigned(reds(0)))
|
||||
+ ("000" & unsigned(reds(3)) & "0") + ("0" & unsigned(reds(3)) & "000")
|
||||
+ ("000" & unsigned(reds(6)) & "0") + ("0000" & unsigned(reds(6)));
|
||||
|
||||
sobel_1_red_right <= ("000" & unsigned(reds(2)) & "0") + ("0000" & unsigned(reds(2)))
|
||||
+ ("000" & unsigned(reds(5)) & "0") + ("0" & unsigned(reds(5)) & "000")
|
||||
+ ("000" & unsigned(reds(8)) & "0") + ("0000" & unsigned(reds(8)));
|
||||
|
||||
sobel_1_red_top <= ("000" & unsigned(reds(2)) & "0") + ("0000" & unsigned(reds(2)))
|
||||
+ ("000" & unsigned(reds(1)) & "0") + ("0" & unsigned(reds(1)) & "000")
|
||||
+ ("000" & unsigned(reds(0)) & "0") + ("0000" & unsigned(reds(0)));
|
||||
|
||||
sobel_1_red_bottom <= ("000" & unsigned(reds(6)) & "0") + ("0000" & unsigned(reds(6)))
|
||||
+ ("000" & unsigned(reds(7)) & "0") + ("0" & unsigned(reds(7)) & "000")
|
||||
+ ("000" & unsigned(reds(8)) & "0") + ("0000" & unsigned(reds(8)));
|
||||
|
||||
-- For the green channel
|
||||
sobel_1_green_left <= ("000" & unsigned(greens(0)) & "0") + ("0000" & unsigned(greens(0)))
|
||||
+ ("000" & unsigned(greens(3)) & "0") + ("0" & unsigned(greens(3)) & "000")
|
||||
+ ("000" & unsigned(greens(6)) & "0") + ("0000" & unsigned(greens(6)));
|
||||
|
||||
sobel_1_green_right <= ("000" & unsigned(greens(2)) & "0") + ("0000" & unsigned(greens(2)))
|
||||
+ ("000" & unsigned(greens(5)) & "0") + ("0" & unsigned(greens(5)) & "000")
|
||||
+ ("000" & unsigned(greens(8)) & "0") + ("0000" & unsigned(greens(8)));
|
||||
|
||||
sobel_1_green_top <= ("000" & unsigned(greens(2)) & "0") + ("0000" & unsigned(greens(2)))
|
||||
+ ("000" & unsigned(greens(1)) & "0") + ("0" & unsigned(greens(1)) & "000")
|
||||
+ ("000" & unsigned(greens(0)) & "0") + ("0000" & unsigned(greens(0)));
|
||||
|
||||
sobel_1_green_bottom <= ("000" & unsigned(greens(6)) & "0") + ("0000" & unsigned(greens(6)))
|
||||
+ ("000" & unsigned(greens(7)) & "0") + ("0" & unsigned(greens(7)) & "000")
|
||||
+ ("000" & unsigned(greens(8)) & "0") + ("0000" & unsigned(greens(8)));
|
||||
|
||||
-- For the blue channel
|
||||
sobel_1_blue_left <= ("000" & unsigned(blues(0)) & "0") + ("0000" & unsigned(blues(0)))
|
||||
+ ("000" & unsigned(blues(3)) & "0") + ("0" & unsigned(blues(3)) & "000")
|
||||
+ ("000" & unsigned(blues(6)) & "0") + ("0000" & unsigned(blues(6)));
|
||||
|
||||
sobel_1_blue_right <= ("000" & unsigned(blues(2)) & "0") + ("0000" & unsigned(blues(2)))
|
||||
+ ("000" & unsigned(blues(5)) & "0") + ("0" & unsigned(blues(5)) & "000")
|
||||
+ ("000" & unsigned(blues(8)) & "0") + ("0000" & unsigned(blues(8)));
|
||||
|
||||
sobel_1_blue_top <= ("000" & unsigned(blues(2)) & "0") + ("0000" & unsigned(blues(2)))
|
||||
+ ("000" & unsigned(blues(1)) & "0") + ("0" & unsigned(blues(1)) & "000")
|
||||
+ ("000" & unsigned(blues(0)) & "0") + ("0000" & unsigned(blues(0)));
|
||||
|
||||
sobel_1_blue_bottom <= ("000" & unsigned(blues(6)) & "0") + ("0000" & unsigned(blues(6)))
|
||||
+ ("000" & unsigned(blues(7)) & "0") + ("0" & unsigned(blues(7)) & "000")
|
||||
+ ("000" & unsigned(blues(8)) & "0") + ("0000" & unsigned(blues(8)));
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- Copy over the short chains that gives us a 3x3 matrix to work with
|
||||
---------------------------------------------------------------------
|
||||
-- The bottom row
|
||||
blanks(1) <= blanks(0);
|
||||
hsyncs(1) <= hsyncs(0);
|
||||
vsyncs(1) <= vsyncs(0);
|
||||
reds(1) <= reds(0);
|
||||
greens(1) <= greens(0);
|
||||
blues(1) <= blues(0);
|
||||
|
||||
blanks(2) <= blanks(1);
|
||||
hsyncs(2) <= hsyncs(1);
|
||||
vsyncs(2) <= vsyncs(1);
|
||||
reds(2) <= reds(1);
|
||||
greens(2) <= greens(1);
|
||||
blues(2) <= blues(1);
|
||||
-- The middle row
|
||||
blanks(4) <= blanks(3);
|
||||
hsyncs(4) <= hsyncs(3);
|
||||
vsyncs(4) <= vsyncs(3);
|
||||
reds(4) <= reds(3);
|
||||
greens(4) <= greens(3);
|
||||
blues(4) <= blues(3);
|
||||
|
||||
blanks(5) <= blanks(4);
|
||||
hsyncs(5) <= hsyncs(4);
|
||||
vsyncs(5) <= vsyncs(4);
|
||||
reds(5) <= reds(4);
|
||||
greens(5) <= greens(4);
|
||||
blues(5) <= blues(4);
|
||||
|
||||
-- The top row
|
||||
blanks(7) <= blanks(6);
|
||||
hsyncs(7) <= hsyncs(6);
|
||||
vsyncs(7) <= vsyncs(6);
|
||||
reds(7) <= reds(6);
|
||||
greens(7) <= greens(6);
|
||||
blues(7) <= blues(6);
|
||||
|
||||
blanks(8) <= blanks(7);
|
||||
hsyncs(8) <= hsyncs(7);
|
||||
vsyncs(8) <= vsyncs(7);
|
||||
reds(8) <= reds(7);
|
||||
greens(8) <= greens(7);
|
||||
blues(8) <= blues(7);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
372
src/edid_rom.vhd
Normal file
372
src/edid_rom.vhd
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: edid_rom - Behavioral
|
||||
--
|
||||
-- Description: A simple EDID ROM, configured for 1920x1080@60Hz, HDMI format.
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity edid_rom is
|
||||
port ( clk : in std_logic;
|
||||
sclk_raw : in std_logic;
|
||||
sdat_raw : inout std_logic := 'Z';
|
||||
edid_debug : out std_logic_vector(2 downto 0) := (others => '0')
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture Behavioral of edid_rom is
|
||||
|
||||
type a_edid_rom is array (0 to 255) of std_logic_vector(7 downto 0);
|
||||
|
||||
signal edid_rom : a_edid_rom := (
|
||||
------- BASE EDID Bytes 0 to 35 -----------------------------
|
||||
-- Header
|
||||
x"00",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"00",
|
||||
-- EISA ID - Manufacturer, Product,
|
||||
x"04",x"43", x"07",x"f2",
|
||||
-- EISA ID -Serial
|
||||
x"01",x"00",x"00",x"00",
|
||||
-- Model/year
|
||||
x"FF", x"1f",
|
||||
-- EDID Versiondif
|
||||
x"01", x"04",
|
||||
------------------------------------
|
||||
------------------------------------
|
||||
-- Digital Video using DVI, 8 bits
|
||||
--- x"81", -- Checksum 0xB6
|
||||
------------------------------------
|
||||
-- Digital Video using HDMI, 8 bits
|
||||
x"A2", -- Checksum 0x95
|
||||
------------------------------------
|
||||
-- Aspect ratio, flag, gamma
|
||||
x"4f", x"00", x"78",
|
||||
------------------------------------
|
||||
-- Features
|
||||
x"26",
|
||||
-- Display x,y Chromaticity V Breaks here!
|
||||
x"EE", x"91", x"a3", x"54", x"4c", x"99", x"26", x"0f", x"50", x"54",
|
||||
-- Established timings
|
||||
x"20", x"00", x"00",
|
||||
-- Standard timings
|
||||
x"01", x"01", x"01", x"01", x"01", x"01", x"01", x"01",
|
||||
x"01", x"01", x"01", x"01", x"01", x"01", x"01", x"01",
|
||||
------- End of BASE EDID ---------------------------------
|
||||
|
||||
----- 18 byte data block 1080p --------
|
||||
-- Pixel clock
|
||||
x"02",x"3A",
|
||||
-- Horizontal 1920 with 280 blanking
|
||||
x"80", x"18", x"71",
|
||||
-- Vertical 1080 with 45 lines blanking
|
||||
x"38", x"2D", x"40",
|
||||
-- Horizontal front porch
|
||||
x"58",x"2C",
|
||||
-- Vertical front porch
|
||||
x"04",x"05",
|
||||
-- Horizontal and vertical image size
|
||||
x"0f", x"48", x"42",
|
||||
-- Horizontal and vertical boarder
|
||||
x"00", x"00",
|
||||
-- Options (non-interlaces, not 3D, syncs...)
|
||||
x"1E",
|
||||
|
||||
----- 18 byte data block 1080i --------
|
||||
-- Pixel clock
|
||||
x"01",x"1D",
|
||||
-- Horizontal 1920 with 280 blanking
|
||||
x"80", x"18", x"71",
|
||||
-- Vertical 1080 with 45 lines blanking
|
||||
x"1C", x"16", x"20",
|
||||
-- Horizontal front porch
|
||||
x"58",x"2C",
|
||||
-- Vertical front porch -- SEEMS WRONG!
|
||||
x"25",x"00",
|
||||
-- Horizontal and vertical image size
|
||||
x"0f", x"48", x"42",
|
||||
-- Horizontal and vertical boarder
|
||||
x"00", x"00",
|
||||
-- Options (non-interlaces, not 3D, syncs...)
|
||||
x"9E",
|
||||
|
||||
----- 18 byte data block 720p --------
|
||||
-- Pixel clock
|
||||
x"01",x"1D",
|
||||
-- Horizontal 1920 with 280 blanking
|
||||
x"00", x"72", x"51",
|
||||
-- Vertical 1080 with 45 lines blanking
|
||||
x"D0", x"1E", x"20",
|
||||
-- Horizontal front porch
|
||||
x"6E",x"28",
|
||||
-- Vertical front porch -- SEEMS WRONG!
|
||||
x"55",x"00",
|
||||
-- Horizontal and vertical image size
|
||||
x"0f", x"48", x"42",
|
||||
-- Horizontal and vertical boarder
|
||||
x"00", x"00",
|
||||
-- Options (non-interlaces, not 3D, syncs...)
|
||||
x"1E",
|
||||
|
||||
----- 18 byte data block 720p --------
|
||||
-- Monitor name ASCII descriptor
|
||||
x"00", x"00", x"00", x"FC", x"00",
|
||||
-- ASCII name - "ABC LCD47w[lf] "
|
||||
x"74", x"61", x"63", x"68", x"69", x"62", x"61", x"6e",
|
||||
x"61", x"0A", x"20", x"20", x"20",
|
||||
|
||||
----- End of EDID block
|
||||
-- Extension flag & checksum
|
||||
x"01", x"95",
|
||||
|
||||
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"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"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"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"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"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"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"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"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00"
|
||||
-- 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",
|
||||
-- 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",
|
||||
-- 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",
|
||||
-- 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",
|
||||
-- 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",
|
||||
-- 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",
|
||||
-- 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",
|
||||
-- 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"
|
||||
|
||||
);
|
||||
|
||||
signal sclk_delay : std_logic_vector(2 downto 0);
|
||||
signal sdat_delay : unsigned(6 downto 0);
|
||||
|
||||
type t_state is ( state_idle,
|
||||
-- States to support writing the device's address
|
||||
state_start,
|
||||
state_dev7,
|
||||
state_dev6,
|
||||
state_dev5,
|
||||
state_dev4,
|
||||
state_dev3,
|
||||
state_dev2,
|
||||
state_dev1,
|
||||
state_dev0,
|
||||
-- States to support writing the address
|
||||
state_ack_device_write,
|
||||
state_addr7,
|
||||
state_addr6,
|
||||
state_addr5,
|
||||
state_addr4,
|
||||
state_addr3,
|
||||
state_addr2,
|
||||
state_addr1,
|
||||
state_addr0,
|
||||
state_addr_ack,
|
||||
-- States to support the selector device
|
||||
state_selector_ack_device_write,
|
||||
state_selector_addr7,
|
||||
state_selector_addr6,
|
||||
state_selector_addr5,
|
||||
state_selector_addr4,
|
||||
state_selector_addr3,
|
||||
state_selector_addr2,
|
||||
state_selector_addr1,
|
||||
state_selector_addr0,
|
||||
state_selector_addr_ack,
|
||||
-- States to support reading from the the EDID ROM
|
||||
state_ack_device_read,
|
||||
state_read7,
|
||||
state_read6,
|
||||
state_read5,
|
||||
state_read4,
|
||||
state_read3,
|
||||
state_read2,
|
||||
state_read1,
|
||||
state_read0,
|
||||
state_read_ack);
|
||||
|
||||
signal state : t_state := state_idle;
|
||||
signal data_out_sr : std_logic_vector(7 downto 0) := (others => '1');
|
||||
signal data_shift_reg : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal addr_reg : unsigned(7 downto 0) := (others => '0');
|
||||
signal selector_reg : unsigned(7 downto 0) := (others => '0');
|
||||
signal data_to_send : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal data_out_delay : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal PULL_LOW : std_logic := '0';
|
||||
signal sdat_input : std_logic := '0';
|
||||
signal sdat_delay_last : std_logic := '0';
|
||||
begin
|
||||
|
||||
i_IOBUF: IOBUF
|
||||
generic map (
|
||||
DRIVE => 12,
|
||||
IOSTANDARD => "DEFAULT",
|
||||
SLEW => "SLOW")
|
||||
port map (
|
||||
O => sdat_input, -- Buffer output
|
||||
IO => sdat_raw, -- Buffer inout port (connect directly to top-level port)
|
||||
I => '0', -- Buffer input
|
||||
T => data_out_sr(data_out_sr'high) -- 3-state enable input, high=input, low=output
|
||||
);
|
||||
edid_debug(0) <= std_logic(sdat_delay(sdat_delay'high));
|
||||
edid_debug(1) <= sclk_raw;
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
|
||||
-- falling edge on SDAT while sclk is held high = START condition
|
||||
if sclk_delay(1) = '1' and sclk_delay(0) = '1' and sdat_delay_last = '1' and sdat_delay(sdat_delay'high) = '0' then
|
||||
state <= state_start;
|
||||
edid_debug(2) <= '1';
|
||||
end if;
|
||||
|
||||
-- rising edge on SDAT while sclk is held high = STOP condition
|
||||
if sclk_delay(1) = '1' and sclk_delay(0) = '1' and sdat_delay_last = '0' and sdat_delay(sdat_delay'high) = '1' then
|
||||
state <= state_idle;
|
||||
selector_reg <= (others => '0');
|
||||
edid_debug(2) <= '0';
|
||||
end if;
|
||||
|
||||
-- rising edge on SCLK - usually a data bit
|
||||
if sclk_delay(1) = '1' and sclk_delay(0) = '0' then
|
||||
-- Move data into a shift register
|
||||
data_shift_reg <= data_shift_reg(data_shift_reg'high-1 downto 0) & std_logic(sdat_delay(sdat_delay'high));
|
||||
end if;
|
||||
|
||||
-- falling edge on SCLK - time to change state
|
||||
if sclk_delay(1) = '0' and sclk_delay(0) = '1' then
|
||||
data_out_sr <= data_out_sr(data_out_sr'high-1 downto 0) & '1'; -- Add Pull up
|
||||
case state is
|
||||
when state_start => state <= state_dev7;
|
||||
when state_dev7 => state <= state_dev6;
|
||||
when state_dev6 => state <= state_dev5;
|
||||
when state_dev5 => state <= state_dev4;
|
||||
when state_dev4 => state <= state_dev3;
|
||||
when state_dev3 => state <= state_dev2;
|
||||
when state_dev2 => state <= state_dev1;
|
||||
when state_dev1 => state <= state_dev0;
|
||||
when state_dev0 => if data_shift_reg = x"A1" then
|
||||
state <= state_ack_device_read;
|
||||
data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK
|
||||
elsif data_shift_reg = x"A0" then
|
||||
state <= state_ack_device_write;
|
||||
data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK
|
||||
elsif data_shift_reg = x"60" then
|
||||
state <= state_selector_ack_device_write;
|
||||
data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK
|
||||
else
|
||||
state <= state_idle;
|
||||
end if;
|
||||
when state_ack_device_write => state <= state_addr7;
|
||||
when state_addr7 => state <= state_addr6;
|
||||
when state_addr6 => state <= state_addr5;
|
||||
when state_addr5 => state <= state_addr4;
|
||||
when state_addr4 => state <= state_addr3;
|
||||
when state_addr3 => state <= state_addr2;
|
||||
when state_addr2 => state <= state_addr1;
|
||||
when state_addr1 => state <= state_addr0;
|
||||
when state_addr0 => state <= state_addr_ack;
|
||||
addr_reg <= unsigned(data_shift_reg);
|
||||
data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK
|
||||
when state_addr_ack => state <= state_idle; -- SLave ACK and ignore any written data
|
||||
------------------------------------
|
||||
-- Process the write to the selector
|
||||
------------------------------------
|
||||
when state_selector_ack_device_write => state <= state_selector_addr7;
|
||||
when state_selector_addr7 => state <= state_selector_addr6;
|
||||
when state_selector_addr6 => state <= state_selector_addr5;
|
||||
when state_selector_addr5 => state <= state_selector_addr4;
|
||||
when state_selector_addr4 => state <= state_selector_addr3;
|
||||
when state_selector_addr3 => state <= state_selector_addr2;
|
||||
when state_selector_addr2 => state <= state_selector_addr1;
|
||||
when state_selector_addr1 => state <= state_selector_addr0;
|
||||
when state_selector_addr0 => state <= state_selector_addr_ack;
|
||||
selector_reg <= unsigned(data_shift_reg(7 downto 0));
|
||||
data_out_sr(data_out_sr'high) <= '0'; -- Send Slave ACK
|
||||
when state_selector_addr_ack => state <= state_idle; -- SLave ACK and ignore any written data
|
||||
-------------------------
|
||||
|
||||
when state_ack_device_read => state <= state_read7;
|
||||
data_out_sr <= edid_rom(to_integer(addr_reg));
|
||||
when state_read7 => state <= state_read6;
|
||||
when state_read6 => state <= state_read5;
|
||||
when state_read5 => state <= state_read4;
|
||||
when state_read4 => state <= state_read3;
|
||||
when state_read3 => state <= state_read2;
|
||||
when state_read2 => state <= state_read1;
|
||||
when state_read1 => state <= state_read0;
|
||||
when state_read0 => state <= state_read_ack;
|
||||
when state_read_ack => if sdat_delay(sdat_delay'high) = '0' then
|
||||
state <= state_read7;
|
||||
data_out_sr <= edid_rom(to_integer(addr_reg+1));
|
||||
else
|
||||
state <= state_idle;
|
||||
end if;
|
||||
addr_reg <= addr_reg+1;
|
||||
when others => state <= state_idle;
|
||||
end case;
|
||||
end if;
|
||||
sdat_delay_last <= sdat_delay(sdat_delay'high);
|
||||
-- Synchronisers for SCLK and SDAT
|
||||
sclk_delay <= sclk_raw & sclk_delay(sclk_delay'high downto 1);
|
||||
-- Resolve any 'Z' state in simulation - make it pull up.
|
||||
if sdat_input = '0' then
|
||||
if sdat_delay(sdat_delay'high) = '1' then
|
||||
sdat_delay <= sdat_delay - 1;
|
||||
else
|
||||
sdat_delay <= (others => '0');
|
||||
end if;
|
||||
else
|
||||
if sdat_delay(sdat_delay'high) = '0' then
|
||||
sdat_delay <= sdat_delay + 1;
|
||||
else
|
||||
sdat_delay <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end architecture;
|
||||
152
src/expand_422_to_444.vhd
Normal file
152
src/expand_422_to_444.vhd
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: expand_422_to_444 - Behavioral
|
||||
--
|
||||
-- Description: Convert incoming 422 data to 444
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity expand_422_to_444 is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
input_is_422 : in std_logic;
|
||||
------------------
|
||||
-- Incoming pixels
|
||||
------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_ch2 : in std_logic_vector(7 downto 0);
|
||||
in_ch1 : in std_logic_vector(7 downto 0);
|
||||
in_ch0 : in std_logic_vector(7 downto 0);
|
||||
|
||||
-------------------
|
||||
-- Processed pixels
|
||||
-------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_U : out std_logic_vector(11 downto 0); -- B or Cb
|
||||
out_V : out std_logic_vector(11 downto 0); -- G or Y
|
||||
out_W : out std_logic_vector(11 downto 0) -- R or Cr
|
||||
);
|
||||
end expand_422_to_444;
|
||||
|
||||
architecture Behavioral of expand_422_to_444 is
|
||||
|
||||
signal in_blank_1 : std_logic := '0';
|
||||
signal in_hsync_1 : std_logic := '0';
|
||||
signal in_vsync_1 : std_logic := '0';
|
||||
signal in_ch0_1 : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal in_ch1_1 : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal in_ch2_1 : std_logic_vector(7 downto 0) := (others => '0');
|
||||
|
||||
signal in_blank_2 : std_logic := '0';
|
||||
signal in_hsync_2 : std_logic := '0';
|
||||
signal in_vsync_2 : std_logic := '0';
|
||||
signal in_ch0_2 : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal in_ch1_2 : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal in_ch2_2 : std_logic_vector(7 downto 0) := (others => '0');
|
||||
|
||||
signal first_of_pair : std_logic := '0';
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if input_is_422 = '1' then
|
||||
------------------------------------------------------
|
||||
-- For 422, copy the chroma values between pixel pairs
|
||||
------------------------------------------------------
|
||||
out_blank <= in_blank_1;
|
||||
out_hsync <= in_hsync_1;
|
||||
out_vsync <= in_vsync_1;
|
||||
if in_blank_1 = '1' then
|
||||
first_of_pair <= '1';
|
||||
out_U <= in_ch2_1 & in_ch0_1(7 downto 4); -- Cb
|
||||
out_V <= in_ch1_1 & in_ch0_1(3 downto 0); -- Y
|
||||
out_W <= in_ch2_1 & in_ch0_1(7 downto 4); -- Cr
|
||||
else
|
||||
if first_of_pair = '1' then
|
||||
-- Take Cr from the next pixel
|
||||
first_of_pair <= '0';
|
||||
out_U <= in_ch2_1 & in_ch0_1(7 downto 4); -- Cb
|
||||
out_V <= in_ch1_1 & in_ch0_1(3 downto 0); -- Y
|
||||
out_W <= in_ch2 & in_ch0 (7 downto 4); -- Cr
|
||||
else
|
||||
-- Take Cb from the prior pixel
|
||||
first_of_pair <= '1';
|
||||
out_U <= in_ch2_2 & in_ch0_2(7 downto 4); -- Cb
|
||||
out_V <= in_ch1_1 & in_ch0_1(3 downto 0); -- Y
|
||||
out_W <= in_ch2_1 & in_ch0_1(7 downto 4); -- Cr
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
------------------------------------------------------
|
||||
-- Minimal processing for 422 (either RGB or YCbCr)
|
||||
------------------------------------------------------
|
||||
out_blank <= in_blank_1;
|
||||
out_hsync <= in_hsync_1;
|
||||
out_vsync <= in_vsync_1;
|
||||
out_U <= in_ch0_1 & "0000"; -- B or Cb
|
||||
out_V <= in_ch1_1 & "0000"; -- G or Y
|
||||
out_W <= in_ch2_1 & "0000"; -- R or Cr
|
||||
end if;
|
||||
|
||||
-- Remember the pixel for two cycles
|
||||
in_blank_1 <= in_blank;
|
||||
in_hsync_1 <= in_hsync;
|
||||
in_vsync_1 <= in_vsync;
|
||||
in_ch0_1 <= in_ch0;
|
||||
in_ch1_1 <= in_ch1;
|
||||
in_ch2_1 <= in_ch2;
|
||||
|
||||
in_blank_2 <= in_blank_1;
|
||||
in_hsync_2 <= in_hsync_1;
|
||||
in_vsync_2 <= in_vsync_1;
|
||||
in_ch0_2 <= in_ch0_1;
|
||||
in_ch1_2 <= in_ch1_1;
|
||||
in_ch2_2 <= in_ch2_1;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
111
src/extract_audio_samples.vhd
Normal file
111
src/extract_audio_samples.vhd
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: extract_audio_samples - Behavioral
|
||||
--
|
||||
-- Description: Extract audio data from the HDMI ADP data stream
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity extract_audio_samples is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
adp_data_valid : in STD_LOGIC;
|
||||
adp_header_bit : in STD_LOGIC;
|
||||
adp_frame_bit : in STD_LOGIC;
|
||||
adp_subpacket0_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket1_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket2_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket3_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
audio_de : out STD_LOGIC;
|
||||
audio_channel : out STD_LOGIC_VECTOR (2 downto 0);
|
||||
audio_sample : out STD_LOGIC_VECTOR (23 downto 0)
|
||||
);
|
||||
end extract_audio_samples;
|
||||
|
||||
architecture Behavioral of extract_audio_samples is
|
||||
signal header_bits : STD_LOGIC_VECTOR (31 downto 0);
|
||||
signal frame_bits : STD_LOGIC_VECTOR (31 downto 0);
|
||||
signal subpacket0_bits : STD_LOGIC_VECTOR (63 downto 0);
|
||||
signal subpacket1_bits : STD_LOGIC_VECTOR (63 downto 0);
|
||||
signal subpacket2_bits : STD_LOGIC_VECTOR (63 downto 0);
|
||||
signal subpacket3_bits : STD_LOGIC_VECTOR (63 downto 0);
|
||||
signal grab_other_channel : std_logic := '0';
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
-----------------------------------------------
|
||||
-- Move the incoming bits into a shift register
|
||||
-----------------------------------------------
|
||||
header_bits <= adp_header_bit & header_bits(header_bits'high downto 1);
|
||||
frame_bits <= (adp_frame_bit and adp_data_valid) & frame_bits(frame_bits'high downto 1);
|
||||
subpacket0_bits <= adp_subpacket0_bits & subpacket0_bits(subpacket0_bits'high downto 2);
|
||||
subpacket1_bits <= adp_subpacket1_bits & subpacket1_bits(subpacket1_bits'high downto 2);
|
||||
subpacket2_bits <= adp_subpacket2_bits & subpacket2_bits(subpacket2_bits'high downto 2);
|
||||
subpacket3_bits <= adp_subpacket3_bits & subpacket3_bits(subpacket3_bits'high downto 2);
|
||||
|
||||
audio_de <= '0';
|
||||
|
||||
if grab_other_channel = '1' then
|
||||
audio_de <= header_bits(7);
|
||||
audio_channel <= "001";
|
||||
audio_sample <= subpacket0_bits(45 downto 22);
|
||||
grab_other_channel <= '0';
|
||||
end if;
|
||||
if frame_bits = x"FFFFFFFE" then
|
||||
------------------------------------------------
|
||||
-- Check the packet type as being audio samples
|
||||
------------------------------------------------
|
||||
if header_bits(7 downto 0) = x"02" then
|
||||
audio_de <= header_bits(8);
|
||||
audio_channel <= "000";
|
||||
audio_sample <= subpacket0_bits(23 downto 0);
|
||||
grab_other_channel <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
115
src/extract_video_infopacket_data.vhd
Normal file
115
src/extract_video_infopacket_data.vhd
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: extract_video_infopacket_data - Behavioral
|
||||
--
|
||||
-- Description: Extract a couple of fields from the video infopacket, allowin use
|
||||
-- to correctly convert the incoming pixels into RGB 444 for internal
|
||||
-- processing.
|
||||
--
|
||||
-- Bits 14:13 indicate the colour space and 444 vs 422.
|
||||
-- Bits 27:26 indicate if the pixels are studio level (16-240)
|
||||
-- or full range (0-255)
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity extract_video_infopacket_data is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
adp_data_valid : in STD_LOGIC;
|
||||
adp_header_bit : in STD_LOGIC;
|
||||
adp_frame_bit : in STD_LOGIC;
|
||||
adp_subpacket0_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket1_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket2_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket3_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
input_is_YCbCr : out STD_LOGIC;
|
||||
input_is_422 : out STD_LOGIC;
|
||||
input_is_sRGB : out STD_LOGIC);
|
||||
end extract_video_infopacket_data;
|
||||
|
||||
architecture Behavioral of extract_video_infopacket_data is
|
||||
-- For this usage, we are only interested in four bits that are all in the first
|
||||
-- 16 transfers of the 32-bit packets
|
||||
signal header_bits : STD_LOGIC_VECTOR (15 downto 0);
|
||||
signal frame_bits : STD_LOGIC_VECTOR (15 downto 0);
|
||||
signal subpacket0_bits : STD_LOGIC_VECTOR (31 downto 0);
|
||||
signal updated : std_logic := '0';
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if adp_data_valid = '1' then
|
||||
-----------------------------------------------
|
||||
-- Move the incoming bits into a shift register
|
||||
-----------------------------------------------
|
||||
header_bits <= adp_header_bit & header_bits(header_bits'high downto 1);
|
||||
frame_bits <= adp_frame_bit & frame_bits(frame_bits'high downto 1);
|
||||
subpacket0_bits <= adp_subpacket0_bits & subpacket0_bits(subpacket0_bits'high downto 2);
|
||||
updated <= '1';
|
||||
end if;
|
||||
|
||||
----------------------------------------------------
|
||||
-- The 0 in frame bits indicates the start of packet
|
||||
----------------------------------------------------
|
||||
if updated = '1' and frame_bits = x"FFFE" then
|
||||
-- 82 is the type of packet, 02 is the version
|
||||
if header_bits = x"0282" then
|
||||
case subpacket0_bits(14 downto 13) is
|
||||
when "00" => input_is_YCbCr <= '0'; input_is_422 <= '0';
|
||||
when "01" => input_is_YCbCr <= '1'; input_is_422 <= '1';
|
||||
when "10" => input_is_YCbCr <= '1'; input_is_422 <= '0';
|
||||
when others => NULL;
|
||||
end case;
|
||||
|
||||
case subpacket0_bits(27 downto 26) is
|
||||
when "01" => input_is_sRGB <= '1';
|
||||
when others => input_is_sRGB <= '0';
|
||||
end case;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
136
src/gen/gen_charmap_is_printable_bold.v
Normal file
136
src/gen/gen_charmap_is_printable_bold.v
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
|
||||
module gen_charmap_is_printable_bold(input glyph[15:0], output reg is_printable) begin
|
||||
always @(glyph) begin
|
||||
case(glyph)
|
||||
16'h0000: is_printable <= 1;
|
||||
16'h0001: is_printable <= 1;
|
||||
16'h0002: is_printable <= 1;
|
||||
16'h0003: is_printable <= 1;
|
||||
16'h0004: is_printable <= 1;
|
||||
16'h0005: is_printable <= 1;
|
||||
16'h0006: is_printable <= 1;
|
||||
16'h0007: is_printable <= 1;
|
||||
16'h0008: is_printable <= 1;
|
||||
16'h0009: is_printable <= 1;
|
||||
16'h000a: is_printable <= 1;
|
||||
16'h000b: is_printable <= 1;
|
||||
16'h000c: is_printable <= 1;
|
||||
16'h000d: is_printable <= 1;
|
||||
16'h000e: is_printable <= 1;
|
||||
16'h000f: is_printable <= 1;
|
||||
16'h0010: is_printable <= 1;
|
||||
16'h0011: is_printable <= 1;
|
||||
16'h0012: is_printable <= 1;
|
||||
16'h0013: is_printable <= 1;
|
||||
16'h0014: is_printable <= 1;
|
||||
16'h0015: is_printable <= 1;
|
||||
16'h0016: is_printable <= 1;
|
||||
16'h0017: is_printable <= 1;
|
||||
16'h0018: is_printable <= 1;
|
||||
16'h0019: is_printable <= 1;
|
||||
16'h001a: is_printable <= 1;
|
||||
16'h001b: is_printable <= 1;
|
||||
16'h001c: is_printable <= 1;
|
||||
16'h001d: is_printable <= 1;
|
||||
16'h001e: is_printable <= 1;
|
||||
16'h001f: is_printable <= 1;
|
||||
16'h0020: is_printable <= 1;
|
||||
16'h0021: is_printable <= 1;
|
||||
16'h0022: is_printable <= 1;
|
||||
16'h0023: is_printable <= 1;
|
||||
16'h0024: is_printable <= 1;
|
||||
16'h0025: is_printable <= 1;
|
||||
16'h0026: is_printable <= 1;
|
||||
16'h0027: is_printable <= 1;
|
||||
16'h0028: is_printable <= 1;
|
||||
16'h0029: is_printable <= 1;
|
||||
16'h002a: is_printable <= 1;
|
||||
16'h002b: is_printable <= 1;
|
||||
16'h002c: is_printable <= 1;
|
||||
16'h002d: is_printable <= 1;
|
||||
16'h002e: is_printable <= 1;
|
||||
16'h002f: is_printable <= 1;
|
||||
16'h0030: is_printable <= 1;
|
||||
16'h0031: is_printable <= 1;
|
||||
16'h0032: is_printable <= 1;
|
||||
16'h0033: is_printable <= 1;
|
||||
16'h0034: is_printable <= 1;
|
||||
16'h0035: is_printable <= 1;
|
||||
16'h0036: is_printable <= 1;
|
||||
16'h0037: is_printable <= 1;
|
||||
16'h0038: is_printable <= 1;
|
||||
16'h0039: is_printable <= 1;
|
||||
16'h003a: is_printable <= 1;
|
||||
16'h003b: is_printable <= 1;
|
||||
16'h003c: is_printable <= 1;
|
||||
16'h003d: is_printable <= 1;
|
||||
16'h003e: is_printable <= 1;
|
||||
16'h003f: is_printable <= 1;
|
||||
16'h0040: is_printable <= 1;
|
||||
16'h0041: is_printable <= 1;
|
||||
16'h0042: is_printable <= 1;
|
||||
16'h0043: is_printable <= 1;
|
||||
16'h0044: is_printable <= 1;
|
||||
16'h0045: is_printable <= 1;
|
||||
16'h0046: is_printable <= 1;
|
||||
16'h0047: is_printable <= 1;
|
||||
16'h0048: is_printable <= 1;
|
||||
16'h0049: is_printable <= 1;
|
||||
16'h004a: is_printable <= 1;
|
||||
16'h004b: is_printable <= 1;
|
||||
16'h004c: is_printable <= 1;
|
||||
16'h004d: is_printable <= 1;
|
||||
16'h004e: is_printable <= 1;
|
||||
16'h004f: is_printable <= 1;
|
||||
16'h0050: is_printable <= 1;
|
||||
16'h0051: is_printable <= 1;
|
||||
16'h0052: is_printable <= 1;
|
||||
16'h0053: is_printable <= 1;
|
||||
16'h0054: is_printable <= 1;
|
||||
16'h0055: is_printable <= 1;
|
||||
16'h0056: is_printable <= 1;
|
||||
16'h0057: is_printable <= 1;
|
||||
16'h0058: is_printable <= 1;
|
||||
16'h0059: is_printable <= 1;
|
||||
16'h005a: is_printable <= 1;
|
||||
16'h005b: is_printable <= 1;
|
||||
16'h005c: is_printable <= 1;
|
||||
16'h005d: is_printable <= 1;
|
||||
16'h005e: is_printable <= 1;
|
||||
16'h005f: is_printable <= 1;
|
||||
16'h0060: is_printable <= 1;
|
||||
16'h0061: is_printable <= 1;
|
||||
16'h0062: is_printable <= 1;
|
||||
16'h0063: is_printable <= 1;
|
||||
16'h0064: is_printable <= 1;
|
||||
16'h0065: is_printable <= 1;
|
||||
16'h0066: is_printable <= 1;
|
||||
16'h0067: is_printable <= 1;
|
||||
16'h0068: is_printable <= 1;
|
||||
16'h0069: is_printable <= 1;
|
||||
16'h006a: is_printable <= 1;
|
||||
16'h006b: is_printable <= 1;
|
||||
16'h006c: is_printable <= 1;
|
||||
16'h006d: is_printable <= 1;
|
||||
16'h006e: is_printable <= 1;
|
||||
16'h006f: is_printable <= 1;
|
||||
16'h0070: is_printable <= 1;
|
||||
16'h0071: is_printable <= 1;
|
||||
16'h0072: is_printable <= 1;
|
||||
16'h0073: is_printable <= 1;
|
||||
16'h0074: is_printable <= 1;
|
||||
16'h0075: is_printable <= 1;
|
||||
16'h0076: is_printable <= 1;
|
||||
16'h0077: is_printable <= 1;
|
||||
16'h0078: is_printable <= 1;
|
||||
16'h0079: is_printable <= 1;
|
||||
16'h007a: is_printable <= 1;
|
||||
16'h007b: is_printable <= 1;
|
||||
16'h007c: is_printable <= 1;
|
||||
16'h007d: is_printable <= 1;
|
||||
16'h007e: is_printable <= 1;
|
||||
16'h007f: is_printable <= 1;
|
||||
default: is_printable <= 0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
136
src/gen/gen_charmap_is_printable_default.v
Normal file
136
src/gen/gen_charmap_is_printable_default.v
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
|
||||
module gen_charmap_is_printable_default(input glyph[15:0], output reg is_printable) begin
|
||||
always @(glyph) begin
|
||||
case(glyph)
|
||||
16'h0000: is_printable <= 1;
|
||||
16'h0001: is_printable <= 1;
|
||||
16'h0002: is_printable <= 1;
|
||||
16'h0003: is_printable <= 1;
|
||||
16'h0004: is_printable <= 1;
|
||||
16'h0005: is_printable <= 1;
|
||||
16'h0006: is_printable <= 1;
|
||||
16'h0007: is_printable <= 1;
|
||||
16'h0008: is_printable <= 1;
|
||||
16'h0009: is_printable <= 1;
|
||||
16'h000a: is_printable <= 1;
|
||||
16'h000b: is_printable <= 1;
|
||||
16'h000c: is_printable <= 1;
|
||||
16'h000d: is_printable <= 1;
|
||||
16'h000e: is_printable <= 1;
|
||||
16'h000f: is_printable <= 1;
|
||||
16'h0010: is_printable <= 1;
|
||||
16'h0011: is_printable <= 1;
|
||||
16'h0012: is_printable <= 1;
|
||||
16'h0013: is_printable <= 1;
|
||||
16'h0014: is_printable <= 1;
|
||||
16'h0015: is_printable <= 1;
|
||||
16'h0016: is_printable <= 1;
|
||||
16'h0017: is_printable <= 1;
|
||||
16'h0018: is_printable <= 1;
|
||||
16'h0019: is_printable <= 1;
|
||||
16'h001a: is_printable <= 1;
|
||||
16'h001b: is_printable <= 1;
|
||||
16'h001c: is_printable <= 1;
|
||||
16'h001d: is_printable <= 1;
|
||||
16'h001e: is_printable <= 1;
|
||||
16'h001f: is_printable <= 1;
|
||||
16'h0020: is_printable <= 1;
|
||||
16'h0021: is_printable <= 1;
|
||||
16'h0022: is_printable <= 1;
|
||||
16'h0023: is_printable <= 1;
|
||||
16'h0024: is_printable <= 1;
|
||||
16'h0025: is_printable <= 1;
|
||||
16'h0026: is_printable <= 1;
|
||||
16'h0027: is_printable <= 1;
|
||||
16'h0028: is_printable <= 1;
|
||||
16'h0029: is_printable <= 1;
|
||||
16'h002a: is_printable <= 1;
|
||||
16'h002b: is_printable <= 1;
|
||||
16'h002c: is_printable <= 1;
|
||||
16'h002d: is_printable <= 1;
|
||||
16'h002e: is_printable <= 1;
|
||||
16'h002f: is_printable <= 1;
|
||||
16'h0030: is_printable <= 1;
|
||||
16'h0031: is_printable <= 1;
|
||||
16'h0032: is_printable <= 1;
|
||||
16'h0033: is_printable <= 1;
|
||||
16'h0034: is_printable <= 1;
|
||||
16'h0035: is_printable <= 1;
|
||||
16'h0036: is_printable <= 1;
|
||||
16'h0037: is_printable <= 1;
|
||||
16'h0038: is_printable <= 1;
|
||||
16'h0039: is_printable <= 1;
|
||||
16'h003a: is_printable <= 1;
|
||||
16'h003b: is_printable <= 1;
|
||||
16'h003c: is_printable <= 1;
|
||||
16'h003d: is_printable <= 1;
|
||||
16'h003e: is_printable <= 1;
|
||||
16'h003f: is_printable <= 1;
|
||||
16'h0040: is_printable <= 1;
|
||||
16'h0041: is_printable <= 1;
|
||||
16'h0042: is_printable <= 1;
|
||||
16'h0043: is_printable <= 1;
|
||||
16'h0044: is_printable <= 1;
|
||||
16'h0045: is_printable <= 1;
|
||||
16'h0046: is_printable <= 1;
|
||||
16'h0047: is_printable <= 1;
|
||||
16'h0048: is_printable <= 1;
|
||||
16'h0049: is_printable <= 1;
|
||||
16'h004a: is_printable <= 1;
|
||||
16'h004b: is_printable <= 1;
|
||||
16'h004c: is_printable <= 1;
|
||||
16'h004d: is_printable <= 1;
|
||||
16'h004e: is_printable <= 1;
|
||||
16'h004f: is_printable <= 1;
|
||||
16'h0050: is_printable <= 1;
|
||||
16'h0051: is_printable <= 1;
|
||||
16'h0052: is_printable <= 1;
|
||||
16'h0053: is_printable <= 1;
|
||||
16'h0054: is_printable <= 1;
|
||||
16'h0055: is_printable <= 1;
|
||||
16'h0056: is_printable <= 1;
|
||||
16'h0057: is_printable <= 1;
|
||||
16'h0058: is_printable <= 1;
|
||||
16'h0059: is_printable <= 1;
|
||||
16'h005a: is_printable <= 1;
|
||||
16'h005b: is_printable <= 1;
|
||||
16'h005c: is_printable <= 1;
|
||||
16'h005d: is_printable <= 1;
|
||||
16'h005e: is_printable <= 1;
|
||||
16'h005f: is_printable <= 1;
|
||||
16'h0060: is_printable <= 1;
|
||||
16'h0061: is_printable <= 1;
|
||||
16'h0062: is_printable <= 1;
|
||||
16'h0063: is_printable <= 1;
|
||||
16'h0064: is_printable <= 1;
|
||||
16'h0065: is_printable <= 1;
|
||||
16'h0066: is_printable <= 1;
|
||||
16'h0067: is_printable <= 1;
|
||||
16'h0068: is_printable <= 1;
|
||||
16'h0069: is_printable <= 1;
|
||||
16'h006a: is_printable <= 1;
|
||||
16'h006b: is_printable <= 1;
|
||||
16'h006c: is_printable <= 1;
|
||||
16'h006d: is_printable <= 1;
|
||||
16'h006e: is_printable <= 1;
|
||||
16'h006f: is_printable <= 1;
|
||||
16'h0070: is_printable <= 1;
|
||||
16'h0071: is_printable <= 1;
|
||||
16'h0072: is_printable <= 1;
|
||||
16'h0073: is_printable <= 1;
|
||||
16'h0074: is_printable <= 1;
|
||||
16'h0075: is_printable <= 1;
|
||||
16'h0076: is_printable <= 1;
|
||||
16'h0077: is_printable <= 1;
|
||||
16'h0078: is_printable <= 1;
|
||||
16'h0079: is_printable <= 1;
|
||||
16'h007a: is_printable <= 1;
|
||||
16'h007b: is_printable <= 1;
|
||||
16'h007c: is_printable <= 1;
|
||||
16'h007d: is_printable <= 1;
|
||||
16'h007e: is_printable <= 1;
|
||||
16'h007f: is_printable <= 1;
|
||||
default: is_printable <= 0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
3
src/gen/gen_font_params_bold.vh
Normal file
3
src/gen/gen_font_params_bold.vh
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
`define GEN_FONT_GLYPH_W_bold 8
|
||||
`define GEN_FONT_GLYPH_H_bold 16
|
||||
`define GEN_FONT_GLYPH_COUNT_bold 128
|
||||
3
src/gen/gen_font_params_default.vh
Normal file
3
src/gen/gen_font_params_default.vh
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
`define GEN_FONT_GLYPH_W_default 8
|
||||
`define GEN_FONT_GLYPH_H_default 16
|
||||
`define GEN_FONT_GLYPH_COUNT_default 128
|
||||
2048
src/gen/gen_glyphtable_bold.hex
Normal file
2048
src/gen/gen_glyphtable_bold.hex
Normal file
File diff suppressed because it is too large
Load diff
2048
src/gen/gen_glyphtable_default.hex
Normal file
2048
src/gen/gen_glyphtable_default.hex
Normal file
File diff suppressed because it is too large
Load diff
32768
src/gen/glyph_buffer_init_file.hex
Normal file
32768
src/gen/glyph_buffer_init_file.hex
Normal file
File diff suppressed because it is too large
Load diff
169
src/guidelines.vhd
Normal file
169
src/guidelines.vhd
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: guidelines - Behavioral
|
||||
--
|
||||
-- Description: When enabled, put guidelines on the screen
|
||||
--
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity guidelines is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
enable_feature : in std_logic;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
is_interlaced : in std_logic;
|
||||
is_second_field : in std_logic;
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0));
|
||||
end guidelines;
|
||||
|
||||
architecture Behavioral of guidelines is
|
||||
signal hcount : unsigned(11 downto 0) := (others => '0');
|
||||
signal vcount : unsigned(11 downto 0) := (others => '0');
|
||||
signal h_size : unsigned(11 downto 0) := (others => '0');
|
||||
signal v_size : unsigned(11 downto 0) := (others => '0');
|
||||
signal last_blank : std_logic := '0';
|
||||
signal last_vsync : std_logic := '0';
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
out_blank <= in_blank;
|
||||
out_hsync <= in_hsync;
|
||||
out_vsync <= in_vsync;
|
||||
out_red <= in_red;
|
||||
out_green <= in_green;
|
||||
out_blue <= in_blue;
|
||||
|
||||
if enable_feature = '1' then
|
||||
if h_size = 1280 then
|
||||
if hcount = 426 or hcount = 854 then
|
||||
out_red <= (others => '1');
|
||||
out_green <= (others => '1');
|
||||
out_blue <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if h_size = 1920 then
|
||||
if hcount = 640 or hcount = 1280 then
|
||||
out_red <= (others => '1');
|
||||
out_green <= (others => '1');
|
||||
out_blue <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if v_size = 720 then
|
||||
if vcount = 240 or vcount = 480 then
|
||||
out_red <= (others => '1');
|
||||
out_green <= (others => '1');
|
||||
out_blue <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if v_size = 1080 then
|
||||
if is_interlaced = '0' and (vcount = 360 or vcount = 720) then
|
||||
out_red <= (others => '1');
|
||||
out_green <= (others => '1');
|
||||
out_blue <= (others => '1');
|
||||
end if;
|
||||
|
||||
if is_interlaced = '1' and (vcount = 180 or vcount = 360) then
|
||||
out_red <= (others => '1');
|
||||
out_green <= (others => '1');
|
||||
out_blue <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Count the number of lines in a frame (not field!!!)
|
||||
-------------------------------------------------------------
|
||||
if last_blank = '0' and in_blank = '1' then
|
||||
vcount <= vcount + 1;
|
||||
end if;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Use the falling edge of VSYNC to to capture the number of
|
||||
-- lines on the screen, as the rising edge is where the
|
||||
-- interaced field is detected and can be a bit unstable.
|
||||
-------------------------------------------------------------
|
||||
if in_vsync = '0' and last_vsync = '1' and is_second_field = '0'then
|
||||
vcount <= (others => '0');
|
||||
v_size <= vcount;
|
||||
end if;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Count the width of the frame
|
||||
-------------------------------------------------------------
|
||||
if in_blank = '1' then
|
||||
if hcount /= 0 then
|
||||
h_size <= hcount;
|
||||
end if;
|
||||
hcount <= (others => '0');
|
||||
else
|
||||
hcount <= hcount + 1;
|
||||
end if;
|
||||
last_blank <= in_blank;
|
||||
last_vsync <= in_vsync;
|
||||
if enable_feature = '1' and in_blank = '0' then
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
362
src/hdmi_design.vhd
Normal file
362
src/hdmi_design.vhd
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Create Date: 22.07.2015 21:10:34
|
||||
-- Module Name: hdmi_design - Behavioral
|
||||
-- Project Name:
|
||||
--
|
||||
-- Description: Top level of a video processing design
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity hdmi_design is
|
||||
Port (
|
||||
clk100 : in STD_LOGIC;
|
||||
-- Control signals
|
||||
led : out std_logic_vector(7 downto 0) :=(others => '0');
|
||||
sw : in std_logic_vector(7 downto 0) :=(others => '0');
|
||||
debug_pmod : out std_logic_vector(3 downto 0) :=(others => '0');
|
||||
|
||||
sck : in std_logic;
|
||||
ncs : in std_logic;
|
||||
sdi : in std_logic;
|
||||
sdo : out std_logic;
|
||||
|
||||
--HDMI input signals
|
||||
hdmi_rx_cec : inout std_logic;
|
||||
hdmi_rx_hpa : out std_logic;
|
||||
hdmi_rx_scl : in std_logic;
|
||||
hdmi_rx_sda : inout std_logic;
|
||||
hdmi_rx_txen : out std_logic;
|
||||
hdmi_rx_clk_n : in std_logic;
|
||||
hdmi_rx_clk_p : in std_logic;
|
||||
hdmi_rx_n : in std_logic_vector(2 downto 0);
|
||||
hdmi_rx_p : in std_logic_vector(2 downto 0);
|
||||
|
||||
--- HDMI out
|
||||
hdmi_tx_cec : inout std_logic;
|
||||
hdmi_tx_clk_n : out std_logic;
|
||||
hdmi_tx_clk_p : out std_logic;
|
||||
hdmi_tx_hpd : in std_logic;
|
||||
hdmi_tx_rscl : inout std_logic;
|
||||
hdmi_tx_rsda : inout std_logic;
|
||||
hdmi_tx_p : out std_logic_vector(2 downto 0);
|
||||
hdmi_tx_n : out std_logic_vector(2 downto 0);
|
||||
-- For dumping symbols
|
||||
rs232_tx : out std_logic
|
||||
);
|
||||
end hdmi_design;
|
||||
|
||||
architecture Behavioral of hdmi_design is
|
||||
component hdmi_io is
|
||||
Port (
|
||||
clk100 : in STD_LOGIC;
|
||||
-------------------------------
|
||||
-- Control signals
|
||||
-------------------------------
|
||||
clock_locked : out std_logic;
|
||||
data_synced : out std_logic;
|
||||
debug : out std_logic_vector(7 downto 0);
|
||||
-------------------------------
|
||||
--HDMI input signals
|
||||
-------------------------------
|
||||
hdmi_rx_cec : inout std_logic;
|
||||
hdmi_rx_hpa : out std_logic;
|
||||
hdmi_rx_scl : in std_logic;
|
||||
hdmi_rx_sda : inout std_logic;
|
||||
hdmi_rx_txen : out std_logic;
|
||||
hdmi_rx_clk_n : in std_logic;
|
||||
hdmi_rx_clk_p : in std_logic;
|
||||
hdmi_rx_n : in std_logic_vector(2 downto 0);
|
||||
hdmi_rx_p : in std_logic_vector(2 downto 0);
|
||||
|
||||
-------------
|
||||
-- HDMI out
|
||||
-------------
|
||||
hdmi_tx_cec : inout std_logic;
|
||||
hdmi_tx_clk_n : out std_logic;
|
||||
hdmi_tx_clk_p : out std_logic;
|
||||
hdmi_tx_hpd : in std_logic;
|
||||
hdmi_tx_rscl : inout std_logic;
|
||||
hdmi_tx_rsda : inout std_logic;
|
||||
hdmi_tx_p : out std_logic_vector(2 downto 0);
|
||||
hdmi_tx_n : out std_logic_vector(2 downto 0);
|
||||
|
||||
pixel_clk : out std_logic;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_hdmi_detected : out std_logic;
|
||||
in_blank : out std_logic;
|
||||
in_hsync : out std_logic;
|
||||
in_vsync : out std_logic;
|
||||
in_red : out std_logic_vector(7 downto 0);
|
||||
in_green : out std_logic_vector(7 downto 0);
|
||||
in_blue : out std_logic_vector(7 downto 0);
|
||||
is_interlaced : out std_logic;
|
||||
is_second_field : out std_logic;
|
||||
|
||||
-------------------------------------
|
||||
-- Audio Levels
|
||||
-------------------------------------
|
||||
audio_channel : out std_logic_vector(2 downto 0);
|
||||
audio_de : out std_logic;
|
||||
audio_sample : out std_logic_vector(23 downto 0);
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : in std_logic;
|
||||
out_hsync : in std_logic;
|
||||
out_vsync : in std_logic;
|
||||
out_red : in std_logic_vector(7 downto 0);
|
||||
out_green : in std_logic_vector(7 downto 0);
|
||||
out_blue : in std_logic_vector(7 downto 0);
|
||||
-----------------------------------
|
||||
-- For symbol dump or retransmit
|
||||
-----------------------------------
|
||||
symbol_sync : out std_logic; -- indicates a fixed reference point in the frame.
|
||||
symbol_ch0 : out std_logic_vector(9 downto 0);
|
||||
symbol_ch1 : out std_logic_vector(9 downto 0);
|
||||
symbol_ch2 : out std_logic_vector(9 downto 0)
|
||||
);
|
||||
end component;
|
||||
signal symbol_sync : std_logic;
|
||||
signal symbol_ch0 : std_logic_vector(9 downto 0);
|
||||
signal symbol_ch1 : std_logic_vector(9 downto 0);
|
||||
signal symbol_ch2 : std_logic_vector(9 downto 0);
|
||||
|
||||
component proc_top is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
switches : in std_logic_vector(7 downto 0);
|
||||
|
||||
sck : in std_logic;
|
||||
ncs : in std_logic;
|
||||
sdi : in std_logic;
|
||||
sdo : out std_logic;
|
||||
|
||||
------------------
|
||||
-- Incoming pixels
|
||||
------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
is_interlaced : in std_logic;
|
||||
is_second_field : in std_logic;
|
||||
|
||||
-------------------
|
||||
-- Processed pixels
|
||||
-------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0);
|
||||
|
||||
debug : out std_logic_vector(5 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component symbol_dump is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
clk100 : in std_logic;
|
||||
symbol_sync : in std_logic; -- indicates a fixed reference point in the frame.
|
||||
symbol_ch0 : in std_logic_vector(9 downto 0);
|
||||
symbol_ch1 : in std_logic_vector(9 downto 0);
|
||||
symbol_ch2 : in std_logic_vector(9 downto 0);
|
||||
rs232_tx : out std_logic);
|
||||
end component;
|
||||
|
||||
signal pixel_clk : std_logic;
|
||||
signal in_blank : std_logic;
|
||||
signal in_hsync : std_logic;
|
||||
signal in_vsync : std_logic;
|
||||
signal in_red : std_logic_vector(7 downto 0);
|
||||
signal in_green : std_logic_vector(7 downto 0);
|
||||
signal in_blue : std_logic_vector(7 downto 0);
|
||||
signal is_interlaced : std_logic;
|
||||
signal is_second_field : std_logic;
|
||||
signal out_blank : std_logic;
|
||||
signal out_hsync : std_logic;
|
||||
signal out_vsync : std_logic;
|
||||
signal out_red : std_logic_vector(7 downto 0);
|
||||
signal out_green : std_logic_vector(7 downto 0);
|
||||
signal out_blue : std_logic_vector(7 downto 0);
|
||||
|
||||
signal audio_channel : std_logic_vector(2 downto 0);
|
||||
signal audio_de : std_logic;
|
||||
signal audio_sample : std_logic_vector(23 downto 0);
|
||||
|
||||
signal debug : std_logic_vector(7 downto 0);
|
||||
signal io_debug : std_logic_vector(7 downto 0);
|
||||
signal proc_debug : std_logic_vector(5 downto 0);
|
||||
begin
|
||||
debug_pmod <= debug(3 downto 0);
|
||||
led <= debug;
|
||||
|
||||
debug(7 downto 6) <= io_debug(7 downto 6);
|
||||
debug(5 downto 0) <= proc_debug;
|
||||
|
||||
i_hdmi_io: hdmi_io port map (
|
||||
clk100 => clk100,
|
||||
---------------------
|
||||
-- Control signals
|
||||
---------------------
|
||||
clock_locked => open,
|
||||
data_synced => open,
|
||||
debug => io_debug,
|
||||
---------------------
|
||||
-- HDMI input signals
|
||||
---------------------
|
||||
hdmi_rx_cec => hdmi_rx_cec,
|
||||
hdmi_rx_hpa => hdmi_rx_hpa,
|
||||
hdmi_rx_scl => hdmi_rx_scl,
|
||||
hdmi_rx_sda => hdmi_rx_sda,
|
||||
hdmi_rx_txen => hdmi_rx_txen,
|
||||
hdmi_rx_clk_n => hdmi_rx_clk_n,
|
||||
hdmi_rx_clk_p => hdmi_rx_clk_p,
|
||||
hdmi_rx_p => hdmi_rx_p,
|
||||
hdmi_rx_n => hdmi_rx_n,
|
||||
|
||||
----------------------
|
||||
-- HDMI output signals
|
||||
----------------------
|
||||
hdmi_tx_cec => hdmi_tx_cec,
|
||||
hdmi_tx_clk_n => hdmi_tx_clk_n,
|
||||
hdmi_tx_clk_p => hdmi_tx_clk_p,
|
||||
hdmi_tx_hpd => hdmi_tx_hpd,
|
||||
hdmi_tx_rscl => hdmi_tx_rscl,
|
||||
hdmi_tx_rsda => hdmi_tx_rsda,
|
||||
hdmi_tx_p => hdmi_tx_p,
|
||||
hdmi_tx_n => hdmi_tx_n,
|
||||
|
||||
|
||||
pixel_clk => pixel_clk,
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank => in_blank,
|
||||
in_hsync => in_hsync,
|
||||
in_vsync => in_vsync,
|
||||
in_red => in_red,
|
||||
in_green => in_green,
|
||||
in_blue => in_blue,
|
||||
is_interlaced => is_interlaced,
|
||||
is_second_field => is_second_field,
|
||||
|
||||
-----------------------------------
|
||||
-- For symbol dump or retransmit
|
||||
-----------------------------------
|
||||
audio_channel => audio_channel,
|
||||
audio_de => audio_de,
|
||||
audio_sample => audio_sample,
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank => out_blank,
|
||||
out_hsync => out_hsync,
|
||||
out_vsync => out_vsync,
|
||||
out_red => out_red,
|
||||
out_green => out_green,
|
||||
out_blue => out_blue,
|
||||
|
||||
symbol_sync => symbol_sync,
|
||||
symbol_ch0 => symbol_ch0,
|
||||
symbol_ch1 => symbol_ch1,
|
||||
symbol_ch2 => symbol_ch2
|
||||
);
|
||||
|
||||
i_processing: proc_top Port map (
|
||||
clk => pixel_clk,
|
||||
switches => sw,
|
||||
|
||||
sck => sck,
|
||||
ncs => ncs,
|
||||
sdi => sdi,
|
||||
sdo => sdo,
|
||||
------------------
|
||||
-- Incoming pixels
|
||||
------------------
|
||||
in_blank => in_blank,
|
||||
in_hsync => in_hsync,
|
||||
in_vsync => in_vsync,
|
||||
in_red => in_red,
|
||||
in_green => in_green,
|
||||
in_blue => in_blue,
|
||||
is_interlaced => is_interlaced,
|
||||
is_second_field => is_second_field,
|
||||
-------------------
|
||||
-- Processed pixels
|
||||
-------------------
|
||||
out_blank => out_blank,
|
||||
out_hsync => out_hsync,
|
||||
out_vsync => out_vsync,
|
||||
out_red => out_red,
|
||||
out_green => out_green,
|
||||
out_blue => out_blue,
|
||||
|
||||
debug => proc_debug
|
||||
);
|
||||
|
||||
-- Swap to this if you want to capture the HDMI symbols
|
||||
-- and send them up the RS232 port
|
||||
--rs232_tx <= '1';
|
||||
i_symbol_dump: symbol_dump port map (
|
||||
clk => pixel_clk,
|
||||
clk100 => clk100,
|
||||
symbol_sync => symbol_sync,
|
||||
symbol_ch0 => symbol_ch0,
|
||||
symbol_ch1 => symbol_ch1,
|
||||
symbol_ch2 => symbol_ch2,
|
||||
rs232_tx => rs232_tx);
|
||||
|
||||
end Behavioral;
|
||||
670
src/hdmi_input.vhd
Normal file
670
src/hdmi_input.vhd
Normal file
|
|
@ -0,0 +1,670 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: hdmi_input - Behavioral
|
||||
--
|
||||
-- Description: Decode the video data out of an incoming HDMI data stream.
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity hdmi_input is
|
||||
Port (
|
||||
system_clk : in std_logic;
|
||||
|
||||
debug : out std_logic_vector(5 downto 0);
|
||||
hdmi_detected : out std_logic;
|
||||
|
||||
pixel_clk : out std_logic; -- Driven by BUFG
|
||||
pixel_io_clk_x1 : out std_logic; -- Driven by BUFFIO
|
||||
pixel_io_clk_x5 : out std_logic; -- Driven by BUFFIO
|
||||
|
||||
-- HDMI input signals
|
||||
hdmi_in_clk : in std_logic;
|
||||
hdmi_in_ch0 : in std_logic;
|
||||
hdmi_in_ch1 : in std_logic;
|
||||
hdmi_in_ch2 : in std_logic;
|
||||
|
||||
-- Status
|
||||
pll_locked : out std_logic;
|
||||
symbol_sync : out std_logic;
|
||||
|
||||
-- Raw data signals
|
||||
raw_blank : out std_logic;
|
||||
raw_hsync : out std_logic;
|
||||
raw_vsync : out std_logic;
|
||||
raw_ch0 : out std_logic_vector(7 downto 0);
|
||||
raw_ch1 : out std_logic_vector(7 downto 0);
|
||||
raw_ch2 : out std_logic_vector(7 downto 0);
|
||||
-- ADP data
|
||||
adp_data_valid : out std_logic;
|
||||
adp_header_bit : out std_logic;
|
||||
adp_frame_bit : out std_logic;
|
||||
adp_subpacket0_bits : out std_logic_vector(1 downto 0);
|
||||
adp_subpacket1_bits : out std_logic_vector(1 downto 0);
|
||||
adp_subpacket2_bits : out std_logic_vector(1 downto 0);
|
||||
adp_subpacket3_bits : out std_logic_vector(1 downto 0);
|
||||
-- For later reuse
|
||||
symbol_ch0 : out std_logic_vector(9 downto 0);
|
||||
symbol_ch1 : out std_logic_vector(9 downto 0);
|
||||
symbol_ch2 : out std_logic_vector(9 downto 0)
|
||||
|
||||
);
|
||||
end hdmi_input;
|
||||
|
||||
architecture Behavioral of hdmi_input is
|
||||
|
||||
component input_channel is
|
||||
Port ( clk_mgmt : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
clk_x1 : in STD_LOGIC;
|
||||
clk_x5 : in STD_LOGIC;
|
||||
serial : in STD_LOGIC;
|
||||
reset : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
invalid_symbol : out std_logic;
|
||||
symbol : out std_logic_vector (9 downto 0);
|
||||
ctl_valid : out std_logic;
|
||||
ctl : out std_logic_vector (1 downto 0);
|
||||
terc4_valid : out std_logic;
|
||||
terc4 : out std_logic_vector (3 downto 0);
|
||||
guardband_valid : out std_logic;
|
||||
guardband : out std_logic_vector (0 downto 0);
|
||||
data_valid : out std_logic;
|
||||
data : out std_logic_vector (7 downto 0);
|
||||
symbol_sync : out STD_LOGIC);
|
||||
end component;
|
||||
|
||||
signal clk_pixel_raw : std_logic;
|
||||
|
||||
component alignment_detect is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
invalid_symbol : in STD_LOGIC;
|
||||
delay_count : out STD_LOGIC_VECTOR(4 downto 0);
|
||||
delay_ce : out STD_LOGIC;
|
||||
bitslip : out STD_LOGIC;
|
||||
symbol_sync : out STD_LOGIC);
|
||||
end component;
|
||||
|
||||
signal clk_pixel : std_logic;
|
||||
signal clk_pixel_x1 : std_logic;
|
||||
signal clk_pixel_x5 : std_logic;
|
||||
signal clk_pixel_x1_raw : std_logic;
|
||||
signal clk_pixel_x5_raw : std_logic;
|
||||
signal clk_200_raw : std_logic;
|
||||
signal clk_200 : std_logic;
|
||||
signal clkfb_1 : std_logic;
|
||||
signal clkfb_2 : std_logic;
|
||||
signal locked : std_logic;
|
||||
signal reset : std_logic;
|
||||
signal ser_reset : std_logic;
|
||||
signal ser_ce : std_logic;
|
||||
-------------------------------------------------------------
|
||||
-- The raw 10-bit received symbols
|
||||
-------------------------------------------------------------
|
||||
signal ch0_symbol : std_logic_vector(9 downto 0);
|
||||
signal ch1_symbol : std_logic_vector(9 downto 0);
|
||||
signal ch2_symbol : std_logic_vector(9 downto 0);
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- For the decoded TMDS data
|
||||
-------------------------------------------------------------
|
||||
signal ch0_invalid_symbol : std_logic;
|
||||
signal ch0_ctl_valid : std_logic;
|
||||
signal ch0_ctl : std_logic_vector(1 downto 0);
|
||||
signal ch0_terc4_valid : std_logic;
|
||||
signal ch0_terc4 : std_logic_vector (3 downto 0);
|
||||
signal ch0_data_valid : std_logic;
|
||||
signal ch0_data : std_logic_vector(7 downto 0);
|
||||
signal ch0_guardband_valid : std_logic;
|
||||
signal ch0_guardband : std_logic_vector (0 downto 0);
|
||||
signal ch0_delay_count : std_logic_vector (4 downto 0);
|
||||
signal ch0_delay_ce : STD_LOGIC;
|
||||
signal ch0_bitslip : STD_LOGIC;
|
||||
signal ch0_symbol_sync : STD_LOGIC;
|
||||
|
||||
signal ch0_invalid_symbol_1 : std_logic;
|
||||
signal ch0_ctl_valid_1 : std_logic;
|
||||
signal ch0_ctl_1 : std_logic_vector(1 downto 0);
|
||||
signal ch0_terc4_valid_1 : std_logic;
|
||||
signal ch0_terc4_1 : std_logic_vector (3 downto 0);
|
||||
signal ch0_data_valid_1 : std_logic;
|
||||
signal ch0_data_1 : std_logic_vector(7 downto 0);
|
||||
|
||||
signal ch1_invalid_symbol : std_logic;
|
||||
signal ch1_ctl_valid : std_logic;
|
||||
signal ch1_ctl : std_logic_vector(1 downto 0);
|
||||
signal ch1_terc4_valid : std_logic;
|
||||
signal ch1_terc4 : std_logic_vector (3 downto 0);
|
||||
signal ch1_data_valid : std_logic;
|
||||
signal ch1_data : std_logic_vector(7 downto 0);
|
||||
signal ch1_guardband_valid : std_logic;
|
||||
signal ch1_guardband : std_logic_vector (0 downto 0);
|
||||
signal ch1_delay_count : std_logic_vector (4 downto 0);
|
||||
signal ch1_delay_ce : STD_LOGIC;
|
||||
signal ch1_bitslip : STD_LOGIC;
|
||||
signal ch1_symbol_sync : STD_LOGIC;
|
||||
|
||||
signal ch1_invalid_symbol_1 : std_logic;
|
||||
signal ch1_ctl_valid_1 : std_logic;
|
||||
signal ch1_ctl_1 : std_logic_vector(1 downto 0);
|
||||
signal ch1_terc4_valid_1 : std_logic;
|
||||
signal ch1_terc4_1 : std_logic_vector (3 downto 0);
|
||||
signal ch1_data_valid_1 : std_logic;
|
||||
signal ch1_data_1 : std_logic_vector(7 downto 0);
|
||||
|
||||
signal ch2_invalid_symbol : std_logic;
|
||||
signal ch2_ctl_valid : std_logic;
|
||||
signal ch2_ctl : std_logic_vector(1 downto 0);
|
||||
signal ch2_terc4_valid : std_logic;
|
||||
signal ch2_terc4 : std_logic_vector (3 downto 0);
|
||||
signal ch2_data_valid : std_logic;
|
||||
signal ch2_data : std_logic_vector(7 downto 0);
|
||||
signal ch2_guardband_valid : std_logic;
|
||||
signal ch2_guardband : std_logic_vector (0 downto 0);
|
||||
signal ch2_delay_count : std_logic_vector (4 downto 0);
|
||||
signal ch2_delay_ce : STD_LOGIC;
|
||||
signal ch2_bitslip : STD_LOGIC;
|
||||
signal ch2_symbol_sync : STD_LOGIC;
|
||||
|
||||
signal ch2_invalid_symbol_1 : std_logic;
|
||||
signal ch2_ctl_valid_1 : std_logic;
|
||||
signal ch2_ctl_1 : std_logic_vector(1 downto 0);
|
||||
signal ch2_terc4_valid_1 : std_logic;
|
||||
signal ch2_terc4_1 : std_logic_vector (3 downto 0);
|
||||
signal ch2_data_valid_1 : std_logic;
|
||||
signal ch2_data_1 : std_logic_vector(7 downto 0);
|
||||
|
||||
|
||||
signal reset_counter : unsigned(7 downto 0) := (others => '1');
|
||||
|
||||
signal vdp_prefix_detect : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal vdp_guardband_detect : std_logic := '0';
|
||||
signal vdp_prefix_seen : std_logic := '0';
|
||||
signal in_vdp : std_logic := '0';
|
||||
|
||||
signal adp_prefix_detect : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal adp_guardband_detect : std_logic := '0';
|
||||
signal adp_prefix_seen : std_logic := '0';
|
||||
signal in_adp : std_logic := '0';
|
||||
signal dvid_mode : std_logic := '0';
|
||||
signal last_was_ctl : std_logic := '0';
|
||||
|
||||
signal in_dvid : std_logic := '0';
|
||||
signal symbol_sync_i : std_logic := '0';
|
||||
begin
|
||||
pll_locked <= locked;
|
||||
symbol_sync <= symbol_sync_i;
|
||||
reset <= std_logic(reset_counter(reset_counter'high));
|
||||
symbol_ch0 <= ch0_symbol;
|
||||
symbol_ch1 <= ch1_symbol;
|
||||
symbol_ch2 <= ch2_symbol;
|
||||
|
||||
|
||||
debug <= ch2_invalid_symbol & ch1_invalid_symbol & ch0_invalid_symbol & dvid_mode & locked & symbol_sync_i;
|
||||
|
||||
--------------------------------------------
|
||||
-- a 200MHz clock for the IDELAY reference
|
||||
--------------------------------------------
|
||||
clk_MMCME2_BASE_inst : MMCME2_BASE
|
||||
generic map (
|
||||
BANDWIDTH => "OPTIMIZED", -- Jitter programming (OPTIMIZED, HIGH, LOW)
|
||||
DIVCLK_DIVIDE => 1, -- Master division value (1-106)
|
||||
CLKFBOUT_MULT_F => 8.0, -- Multiply value for all CLKOUT (2.000-64.000).
|
||||
CLKFBOUT_PHASE => 0.0, -- Phase offset in degrees of CLKFB (-360.000-360.000).
|
||||
CLKIN1_PERIOD => 10.0, -- Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
|
||||
-- CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)
|
||||
CLKOUT0_DIVIDE_F => 4.0, -- Divide amount for CLKOUT0 (1.000-128.000).
|
||||
CLKOUT1_DIVIDE => 1,
|
||||
CLKOUT2_DIVIDE => 1,
|
||||
CLKOUT3_DIVIDE => 1,
|
||||
CLKOUT4_DIVIDE => 1,
|
||||
CLKOUT5_DIVIDE => 1,
|
||||
CLKOUT6_DIVIDE => 1,
|
||||
-- CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).
|
||||
CLKOUT0_DUTY_CYCLE => 0.5,
|
||||
CLKOUT1_DUTY_CYCLE => 0.5,
|
||||
CLKOUT2_DUTY_CYCLE => 0.5,
|
||||
CLKOUT3_DUTY_CYCLE => 0.5,
|
||||
CLKOUT4_DUTY_CYCLE => 0.5,
|
||||
CLKOUT5_DUTY_CYCLE => 0.5,
|
||||
CLKOUT6_DUTY_CYCLE => 0.5,
|
||||
-- CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
|
||||
CLKOUT0_PHASE => 0.0,
|
||||
CLKOUT1_PHASE => 0.0,
|
||||
CLKOUT2_PHASE => 0.0,
|
||||
CLKOUT3_PHASE => 0.0,
|
||||
CLKOUT4_PHASE => 0.0,
|
||||
CLKOUT5_PHASE => 0.0,
|
||||
CLKOUT6_PHASE => 0.0,
|
||||
CLKOUT4_CASCADE => FALSE, -- Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE)
|
||||
REF_JITTER1 => 0.0, -- Reference input jitter in UI (0.000-0.999).
|
||||
STARTUP_WAIT => FALSE -- Delays DONE until MMCM is locked (FALSE, TRUE)
|
||||
)
|
||||
port map (
|
||||
-- Clock Outputs: 1-bit (each) output: User configurable clock outputs
|
||||
CLKOUT0 => clk_200_raw, -- 1-bit output: CLKOUT0
|
||||
CLKOUT0B => open, -- 1-bit output: Inverted CLKOUT0
|
||||
CLKOUT1 => open, -- 1-bit output: CLKOUT1
|
||||
CLKOUT1B => open, -- 1-bit output: Inverted CLKOUT1
|
||||
CLKOUT2 => open, -- 1-bit output: CLKOUT2
|
||||
CLKOUT2B => open, -- 1-bit output: Inverted CLKOUT2
|
||||
CLKOUT3 => open, -- 1-bit output: CLKOUT3
|
||||
CLKOUT3B => open, -- 1-bit output: Inverted CLKOUT3
|
||||
CLKOUT4 => open, -- 1-bit output: CLKOUT4
|
||||
CLKOUT5 => open, -- 1-bit output: CLKOUT5
|
||||
CLKOUT6 => open, -- 1-bit output: CLKOUT6
|
||||
-- Feedback Clocks: 1-bit (each) output: Clock feedback ports
|
||||
CLKFBOUT => clkfb_1, -- 1-bit output: Feedback clock
|
||||
CLKFBOUTB => open, -- 1-bit output: Inverted CLKFBOUT
|
||||
-- Status Ports: 1-bit (each) output: MMCM status ports
|
||||
LOCKED => open, -- 1-bit output: LOCK
|
||||
-- Clock Inputs: 1-bit (each) input: Clock input
|
||||
CLKIN1 => system_clk, -- 1-bit input: Clock
|
||||
-- Control Ports: 1-bit (each) input: MMCM control ports
|
||||
PWRDWN => '0', -- 1-bit input: Power-down
|
||||
RST => '0', -- 1-bit input: Reset
|
||||
-- Feedback Clocks: 1-bit (each) input: Clock feedback ports
|
||||
CLKFBIN => clkfb_1 -- 1-bit input: Feedback clock
|
||||
);
|
||||
|
||||
i_BUFG: BUFG PORT MAP (
|
||||
I => clk_200_raw,
|
||||
O => clk_200
|
||||
);
|
||||
------------------------------
|
||||
-- Input Delay reference
|
||||
--
|
||||
-- These are tied to the delay instances
|
||||
-- by the IODELAY_GROUP attribute.
|
||||
--------------------------------------------
|
||||
IDELAYCTRL_inst : IDELAYCTRL
|
||||
port map (
|
||||
RDY => open, -- 1-bit output: Ready output
|
||||
REFCLK => clk_200, -- 1-bit input: Reference clock input
|
||||
RST => '0' -- 1-bit input: Active high reset input
|
||||
);
|
||||
|
||||
--------------------------------
|
||||
-- MMCM driven by the HDMI clock
|
||||
--------------------------------
|
||||
hdmi_MMCME2_BASE_inst : MMCME2_BASE
|
||||
generic map (
|
||||
BANDWIDTH => "OPTIMIZED", -- Jitter programming (OPTIMIZED, HIGH, LOW)
|
||||
DIVCLK_DIVIDE => 1, -- Master division value (1-106)
|
||||
CLKFBOUT_MULT_F => 5.0, -- Multiply value for all CLKOUT (2.000-64.000).
|
||||
CLKFBOUT_PHASE => 0.0, -- Phase offset in degrees of CLKFB (-360.000-360.000).
|
||||
CLKIN1_PERIOD => 12.5, --1000.0/148.5, -- Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
|
||||
-- CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)
|
||||
CLKOUT0_DIVIDE_F => 5.0, -- Divide amount for CLKOUT0 (1.000-128.000).
|
||||
CLKOUT1_DIVIDE => 5,
|
||||
CLKOUT2_DIVIDE => 1,
|
||||
CLKOUT3_DIVIDE => 1,
|
||||
CLKOUT4_DIVIDE => 1,
|
||||
CLKOUT5_DIVIDE => 1,
|
||||
CLKOUT6_DIVIDE => 1,
|
||||
-- CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).
|
||||
CLKOUT0_DUTY_CYCLE => 0.5,
|
||||
CLKOUT1_DUTY_CYCLE => 0.5,
|
||||
CLKOUT2_DUTY_CYCLE => 0.5,
|
||||
CLKOUT3_DUTY_CYCLE => 0.5,
|
||||
CLKOUT4_DUTY_CYCLE => 0.5,
|
||||
CLKOUT5_DUTY_CYCLE => 0.5,
|
||||
CLKOUT6_DUTY_CYCLE => 0.5,
|
||||
-- CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
|
||||
CLKOUT0_PHASE => 0.0,
|
||||
CLKOUT1_PHASE => 0.0,
|
||||
CLKOUT2_PHASE => 0.0,
|
||||
CLKOUT3_PHASE => 0.0,
|
||||
CLKOUT4_PHASE => 0.0,
|
||||
CLKOUT5_PHASE => 0.0,
|
||||
CLKOUT6_PHASE => 0.0,
|
||||
CLKOUT4_CASCADE => FALSE, -- Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE)
|
||||
REF_JITTER1 => 0.0, -- Reference input jitter in UI (0.000-0.999).
|
||||
STARTUP_WAIT => FALSE -- Delays DONE until MMCM is locked (FALSE, TRUE)
|
||||
)
|
||||
port map (
|
||||
-- Clock Outputs: 1-bit (each) output: User configurable clock outputs
|
||||
CLKOUT0 => clk_pixel_raw, -- 1-bit output: CLKOUT0
|
||||
CLKOUT0B => open, -- 1-bit output: Inverted CLKOUT0
|
||||
CLKOUT1 => clk_pixel_x1_raw, -- 1-bit output: CLKOUT1
|
||||
CLKOUT1B => open, -- 1-bit output: Inverted CLKOUT1
|
||||
CLKOUT2 => clk_pixel_x5_raw, -- 1-bit output: CLKOUT2
|
||||
CLKOUT2B => open, -- 1-bit output: Inverted CLKOUT2
|
||||
CLKOUT3 => open, -- 1-bit output: CLKOUT3
|
||||
CLKOUT3B => open, -- 1-bit output: Inverted CLKOUT3
|
||||
CLKOUT4 => open, -- 1-bit output: CLKOUT4
|
||||
CLKOUT5 => open, -- 1-bit output: CLKOUT5
|
||||
CLKOUT6 => open, -- 1-bit output: CLKOUT6
|
||||
-- Feedback Clocks: 1-bit (each) output: Clock feedback ports
|
||||
CLKFBOUT => clkfb_2, -- 1-bit output: Feedback clock
|
||||
CLKFBOUTB => open, -- 1-bit output: Inverted CLKFBOUT
|
||||
-- Status Ports: 1-bit (each) output: MMCM status ports
|
||||
LOCKED => locked, -- 1-bit output: LOCK
|
||||
-- Clock Inputs: 1-bit (each) input: Clock input
|
||||
CLKIN1 => hdmi_in_clk, -- 1-bit input: Clock
|
||||
-- Control Ports: 1-bit (each) input: MMCM control ports
|
||||
PWRDWN => '0', -- 1-bit input: Power-down
|
||||
RST => '0', -- 1-bit input: Reset
|
||||
-- Feedback Clocks: 1-bit (each) input: Clock feedback ports
|
||||
CLKFBIN => clkfb_2 -- 1-bit input: Feedback clock
|
||||
);
|
||||
|
||||
----------------------------------
|
||||
-- Force the highest speed clock
|
||||
-- through the IO clock buffer
|
||||
-- (this is only rated for 600MHz!)
|
||||
-----------------------------------
|
||||
BUFIO_x5_inst : BUFIO
|
||||
port map (
|
||||
I => clk_pixel_x5_raw, -- 1-bit input: Clock input (connect to an IBUF or BUFMR).
|
||||
O => clk_pixel_x5 -- 1-bit output: Clock output (connect to I/O clock loads).
|
||||
);
|
||||
|
||||
BUFIO_x1_inst : BUFG
|
||||
port map (
|
||||
I => clk_pixel_x1_raw, -- 1-bit input: Clock input (connect to an IBUF or BUFMR).
|
||||
O => clk_pixel_x1 -- 1-bit output: Clock output (connect to I/O clock loads).
|
||||
);
|
||||
|
||||
BUFIO_inst : BUFG
|
||||
port map (
|
||||
I => clk_pixel_raw, -- 1-bit input: Clock input (connect to an IBUF or BUFMR).
|
||||
O => clk_pixel -- 1-bit output: Clock output (connect to I/O clock loads).
|
||||
);
|
||||
pixel_clk <= clk_pixel;
|
||||
pixel_io_clk_x1 <= clk_pixel_x1;
|
||||
pixel_io_clk_x5 <= clk_pixel_x5;
|
||||
|
||||
ch0: input_channel Port map (
|
||||
clk_mgmt => system_clk,
|
||||
clk => clk_pixel,
|
||||
ce => ser_ce,
|
||||
clk_x1 => clk_pixel_x1,
|
||||
clk_x5 => clk_pixel_x5,
|
||||
serial => hdmi_in_ch0,
|
||||
invalid_symbol => ch0_invalid_symbol,
|
||||
symbol => ch0_symbol,
|
||||
ctl_valid => ch0_ctl_valid,
|
||||
ctl => ch0_ctl,
|
||||
terc4_valid => ch0_terc4_valid,
|
||||
terc4 => ch0_terc4,
|
||||
guardband_valid => ch0_guardband_valid,
|
||||
guardband => ch0_guardband,
|
||||
data_valid => ch0_data_valid,
|
||||
data => ch0_data,
|
||||
reset => ser_reset,
|
||||
symbol_sync => ch0_symbol_sync);
|
||||
|
||||
ch1: input_channel Port map (
|
||||
clk_mgmt => system_clk,
|
||||
clk => clk_pixel,
|
||||
ce => ser_ce,
|
||||
clk_x1 => clk_pixel_x1,
|
||||
clk_x5 => clk_pixel_x5,
|
||||
serial => hdmi_in_ch1,
|
||||
symbol => ch1_symbol,
|
||||
invalid_symbol => ch1_invalid_symbol,
|
||||
ctl_valid => ch1_ctl_valid,
|
||||
ctl => ch1_ctl,
|
||||
terc4_valid => ch1_terc4_valid,
|
||||
terc4 => ch1_terc4,
|
||||
guardband_valid => ch1_guardband_valid,
|
||||
guardband => ch1_guardband,
|
||||
data_valid => ch1_data_valid,
|
||||
data => ch1_data,
|
||||
reset => ser_reset,
|
||||
symbol_sync => ch1_symbol_sync);
|
||||
|
||||
ch2: input_channel Port map (
|
||||
clk_mgmt => system_clk,
|
||||
clk => clk_pixel,
|
||||
ce => ser_ce,
|
||||
clk_x1 => clk_pixel_x1,
|
||||
clk_x5 => clk_pixel_x5,
|
||||
serial => hdmi_in_ch2,
|
||||
invalid_symbol => ch2_invalid_symbol,
|
||||
symbol => ch2_symbol,
|
||||
ctl_valid => ch2_ctl_valid,
|
||||
ctl => ch2_ctl,
|
||||
terc4_valid => ch2_terc4_valid,
|
||||
terc4 => ch2_terc4,
|
||||
guardband_valid => ch2_guardband_valid,
|
||||
guardband => ch2_guardband,
|
||||
data_valid => ch2_data_valid,
|
||||
data => ch2_data,
|
||||
reset => ser_reset,
|
||||
symbol_sync => ch2_symbol_sync);
|
||||
|
||||
symbol_sync_i <= ch0_symbol_sync and ch1_symbol_sync and ch2_symbol_sync;
|
||||
|
||||
hdmi_detected <= not dvid_mode;
|
||||
hdmi_section_decode: process(clk_pixel)
|
||||
begin
|
||||
if rising_edge(clk_pixel) then
|
||||
-------------------------------------------------------------------
|
||||
-- Output the values depending on what sort of data block we are in
|
||||
-------------------------------------------------------------------
|
||||
if ch0_ctl_valid = '1' and ch1_ctl_valid = '1' and ch2_ctl_valid = '1' then
|
||||
-------------------------------------------------------------------
|
||||
-- As soon as we see avalid CTL symbols we are no longer in the
|
||||
-- video or aux data period it doesn't have any trailing guard band
|
||||
-------------------------------------------------------------------
|
||||
in_vdp <= '0';
|
||||
in_adp <= '0';
|
||||
in_dvid <= '0';
|
||||
raw_vsync <= ch0_ctl(1);
|
||||
raw_hsync <= ch0_ctl(0);
|
||||
raw_blank <= '1';
|
||||
raw_ch2 <= (others => '0');
|
||||
raw_ch1 <= (others => '0');
|
||||
raw_ch0 <= (others => '0');
|
||||
last_was_ctl <= '1';
|
||||
adp_data_valid <= '0';
|
||||
else
|
||||
last_was_ctl <= '0';
|
||||
adp_data_valid <= '0';
|
||||
if in_vdp = '1' then
|
||||
raw_vsync <= '0';
|
||||
raw_hsync <= '0';
|
||||
raw_blank <= '0';
|
||||
raw_ch2 <= ch2_data;
|
||||
raw_ch1 <= ch1_data;
|
||||
raw_ch0 <= ch0_data;
|
||||
if ch2_invalid_symbol = '1' or ch2_invalid_symbol = '1' or ch2_invalid_symbol = '1' then
|
||||
raw_ch2 <= x"EF";
|
||||
raw_ch1 <= x"16";
|
||||
raw_ch0 <= x"16";
|
||||
end if;
|
||||
|
||||
elsif in_dvid = '1' then
|
||||
-- In the Video data period
|
||||
raw_vsync <= '0';
|
||||
raw_hsync <= '0';
|
||||
raw_blank <= '0';
|
||||
raw_ch2 <= ch2_data;
|
||||
raw_ch1 <= ch1_data;
|
||||
raw_ch0 <= ch0_data;
|
||||
elsif in_adp = '1' then
|
||||
-- In the Aux Data Period Period
|
||||
raw_vsync <= ch0_terc4(1);
|
||||
raw_hsync <= ch0_terc4(0);
|
||||
raw_blank <= '1';
|
||||
raw_ch0 <= (others => '0');
|
||||
raw_ch1 <= (others => '0');
|
||||
raw_ch2 <= (others => '0');
|
||||
-- ADP data extraction
|
||||
adp_data_valid <= '1';
|
||||
adp_header_bit <= ch0_terc4(2);
|
||||
adp_frame_bit <= ch0_terc4(3);
|
||||
adp_subpacket0_bits <= ch2_terc4(0) & ch1_terc4(0);
|
||||
adp_subpacket1_bits <= ch2_terc4(1) & ch1_terc4(1);
|
||||
adp_subpacket2_bits <= ch2_terc4(2) & ch1_terc4(2);
|
||||
adp_subpacket3_bits <= ch2_terc4(3) & ch1_terc4(3);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
------------------------------------------------------------
|
||||
-- We need to detect 8 ADP or VDP prefix characters in a row
|
||||
------------------------------------------------------------
|
||||
vdp_prefix_detect <= vdp_prefix_detect(6 downto 0) & '0';
|
||||
vdp_prefix_seen <= '0';
|
||||
if ch0_ctl_valid = '1' and ch1_ctl_valid = '1' and ch1_ctl_valid = '1' then
|
||||
if ch1_ctl = "01" and ch2_ctl = "00" then
|
||||
vdp_prefix_detect(0) <= '1';
|
||||
if vdp_prefix_detect = "01111111" then
|
||||
vdp_prefix_seen <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
---------------------------------------------
|
||||
-- See if we can detect the ADP guardband
|
||||
--
|
||||
-- The ADP guardband includes HSYNC and VSYNC
|
||||
-- encoded in TERC4 coded in Ch0.
|
||||
---------------------------------------------
|
||||
adp_prefix_detect <= adp_prefix_detect(6 downto 0) & '0';
|
||||
adp_prefix_seen <= '0';
|
||||
if ch0_ctl_valid = '1' and ch1_ctl_valid = '1' and ch1_ctl_valid = '1' then
|
||||
if ch1_ctl = "01" and ch2_ctl = "01" then
|
||||
adp_prefix_detect(0) <= '1';
|
||||
if adp_prefix_detect = "01111111" then
|
||||
adp_prefix_seen <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
---------------------------------------------
|
||||
-- See if we can detect the ADP guardband
|
||||
--
|
||||
-- The ADP guardband includes HSYNC and VSYNC
|
||||
-- encoded in TERC4 coded in Ch0 - annoying!
|
||||
---------------------------------------------
|
||||
adp_guardband_detect <= '0';
|
||||
if in_vdp = '0' and ch0_terc4_valid = '1' and ch1_guardband_valid = '1' and ch1_guardband_valid = '1' then
|
||||
if ch0_terc4(3 downto 2) = "11" and ch1_guardband = "0" and ch2_guardband = "0" then
|
||||
raw_vsync <= ch0_terc4(1);
|
||||
raw_hsync <= ch0_terc4(0);
|
||||
adp_guardband_detect <= adp_prefix_seen;
|
||||
in_adp <= adp_guardband_detect AND (not in_adp) and (not in_vdp);
|
||||
end if;
|
||||
end if;
|
||||
-----------------------------------------
|
||||
-- See if we can detect the VDP guardband
|
||||
-- This is pretty nices as the guard
|
||||
-----------------------------------------
|
||||
vdp_guardband_detect <= '0';
|
||||
if ch0_guardband_valid = '1' and ch1_guardband_valid = '1' and ch2_guardband_valid = '1' then
|
||||
-- TERC Coded for the VDP guard band.
|
||||
if ch0_guardband = "1" and ch1_guardband = "0" and ch2_guardband = "1" then
|
||||
vdp_guardband_detect <= vdp_prefix_seen;
|
||||
in_vdp <= vdp_guardband_detect AND (not in_adp) and (not in_vdp);
|
||||
dvid_mode <= '0';
|
||||
end if;
|
||||
end if;
|
||||
--------------------------------
|
||||
-- Is this some DVID video data?
|
||||
--------------------------------
|
||||
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
|
||||
in_dvid <= '1';
|
||||
end if;
|
||||
-------------------------------------------------------------
|
||||
-- Is this an un-announced video data? If so we receiving
|
||||
-- DVI-D data, and not HDMI
|
||||
-------------------------------------------------------------
|
||||
if ch0_data_valid = '1' and ch1_data_valid = '1' and ch2_data_valid = '1'
|
||||
and last_was_ctl = '1' and vdp_prefix_seen = '0' and adp_prefix_seen = '0' then
|
||||
dvid_mode <= '1';
|
||||
end if;
|
||||
|
||||
ch0_invalid_symbol_1 <= ch0_invalid_symbol;
|
||||
ch0_ctl_valid_1 <= ch0_ctl_valid;
|
||||
ch0_ctl_1 <= ch0_ctl;
|
||||
ch0_terc4_valid_1 <= ch0_terc4_valid;
|
||||
ch0_terc4_1 <= ch0_terc4;
|
||||
ch0_data_1 <= ch0_data;
|
||||
|
||||
ch1_invalid_symbol_1 <= ch1_invalid_symbol;
|
||||
ch1_ctl_valid_1 <= ch1_ctl_valid;
|
||||
ch1_ctl_1 <= ch1_ctl;
|
||||
ch1_terc4_valid_1 <= ch1_terc4_valid;
|
||||
ch1_terc4_1 <= ch1_terc4;
|
||||
ch1_data_1 <= ch1_data;
|
||||
|
||||
ch2_invalid_symbol_1 <= ch2_invalid_symbol;
|
||||
ch2_ctl_valid_1 <= ch2_ctl_valid;
|
||||
ch2_ctl_1 <= ch2_ctl;
|
||||
ch2_terc4_valid_1 <= ch2_terc4_valid;
|
||||
ch2_terc4_1 <= ch2_terc4;
|
||||
ch2_data_valid_1 <= ch2_data_valid;
|
||||
ch2_data_1 <= ch2_data;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------
|
||||
-- Reset the receivers if PLL lock is lost
|
||||
------------------------------------------
|
||||
reset_proc: process(system_clk)
|
||||
begin
|
||||
if rising_edge(system_clk) then
|
||||
if locked = '1' then
|
||||
if reset_counter > 0 then
|
||||
reset_counter <= reset_counter-1;
|
||||
end if;
|
||||
else
|
||||
reset_counter <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
reset_proc2: process(clk_pixel)
|
||||
begin
|
||||
if rising_edge(clk_pixel) then
|
||||
ser_reset <= reset_counter(reset_counter'high);
|
||||
ser_ce <= not ser_reset;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
587
src/hdmi_io.vhd
Normal file
587
src/hdmi_io.vhd
Normal file
|
|
@ -0,0 +1,587 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz<
|
||||
--
|
||||
-- Module Name: hdmi_io - Behavioral
|
||||
--
|
||||
-- Description: Wrapper for input and output components of HDMI data stream
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity hdmi_io is
|
||||
port (
|
||||
clk100 : in STD_LOGIC;
|
||||
-------------------------------
|
||||
-- Control signals
|
||||
-------------------------------
|
||||
clock_locked : out std_logic;
|
||||
data_synced : out std_logic;
|
||||
debug : out std_logic_vector(7 downto 0);
|
||||
|
||||
-------------------------------
|
||||
--HDMI input signals
|
||||
-------------------------------
|
||||
hdmi_rx_cec : inout std_logic;
|
||||
hdmi_rx_hpa : out std_logic;
|
||||
hdmi_rx_scl : in std_logic;
|
||||
hdmi_rx_sda : inout std_logic;
|
||||
hdmi_rx_txen : out std_logic;
|
||||
hdmi_rx_clk_n : in std_logic;
|
||||
hdmi_rx_clk_p : in std_logic;
|
||||
hdmi_rx_n : in std_logic_vector(2 downto 0);
|
||||
hdmi_rx_p : in std_logic_vector(2 downto 0);
|
||||
|
||||
-------------
|
||||
-- HDMI out
|
||||
-------------
|
||||
hdmi_tx_cec : inout std_logic;
|
||||
hdmi_tx_clk_n : out std_logic;
|
||||
hdmi_tx_clk_p : out std_logic;
|
||||
hdmi_tx_hpd : in std_logic;
|
||||
hdmi_tx_rscl : inout std_logic;
|
||||
hdmi_tx_rsda : inout std_logic;
|
||||
hdmi_tx_p : out std_logic_vector(2 downto 0);
|
||||
hdmi_tx_n : out std_logic_vector(2 downto 0);
|
||||
|
||||
pixel_clk : out std_logic;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_hdmi_detected : out std_logic;
|
||||
in_blank : out std_logic;
|
||||
in_hsync : out std_logic;
|
||||
in_vsync : out std_logic;
|
||||
in_red : out std_logic_vector(7 downto 0);
|
||||
in_green : out std_logic_vector(7 downto 0);
|
||||
in_blue : out std_logic_vector(7 downto 0);
|
||||
is_interlaced : out std_logic;
|
||||
is_second_field : out std_logic;
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : in std_logic;
|
||||
out_hsync : in std_logic;
|
||||
out_vsync : in std_logic;
|
||||
out_red : in std_logic_vector(7 downto 0);
|
||||
out_green : in std_logic_vector(7 downto 0);
|
||||
out_blue : in std_logic_vector(7 downto 0);
|
||||
-------------------------------------
|
||||
-- Audio Levels
|
||||
-------------------------------------
|
||||
audio_channel : out std_logic_vector(2 downto 0);
|
||||
audio_de : out std_logic;
|
||||
audio_sample : out std_logic_vector(23 downto 0);
|
||||
|
||||
-----------------------------------
|
||||
-- For symbol dump or retransmit
|
||||
-----------------------------------
|
||||
symbol_sync : out std_logic; -- indicates a fixed reference point in the frame.
|
||||
symbol_ch0 : out std_logic_vector(9 downto 0);
|
||||
symbol_ch1 : out std_logic_vector(9 downto 0);
|
||||
symbol_ch2 : out std_logic_vector(9 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture Behavioral of hdmi_io is
|
||||
component edid_rom is
|
||||
port ( clk : in std_logic;
|
||||
sclk_raw : in std_logic;
|
||||
sdat_raw : inout std_logic;
|
||||
edid_debug : out std_logic_vector(2 downto 0));
|
||||
end component;
|
||||
|
||||
component hdmi_input is
|
||||
port (
|
||||
system_clk : in std_logic;
|
||||
|
||||
debug : out std_logic_vector(5 downto 0);
|
||||
hdmi_detected : out std_logic;
|
||||
|
||||
pixel_clk : out std_logic; -- Driven by BUFG
|
||||
pixel_io_clk_x1 : out std_logic; -- Driven by BUFFIO
|
||||
pixel_io_clk_x5 : out std_logic; -- Driven by BUFFIO
|
||||
|
||||
-- HDMI input signals
|
||||
hdmi_in_clk : in std_logic;
|
||||
hdmi_in_ch0 : in std_logic;
|
||||
hdmi_in_ch1 : in std_logic;
|
||||
hdmi_in_ch2 : in std_logic;
|
||||
|
||||
-- Status
|
||||
pll_locked : out std_logic;
|
||||
symbol_sync : out std_logic;
|
||||
|
||||
-- Raw data signals
|
||||
raw_blank : out std_logic;
|
||||
raw_hsync : out std_logic;
|
||||
raw_vsync : out std_logic;
|
||||
raw_ch0 : out std_logic_vector(7 downto 0);
|
||||
raw_ch1 : out std_logic_vector(7 downto 0);
|
||||
raw_ch2 : out std_logic_vector(7 downto 0);
|
||||
-- ADP data
|
||||
adp_data_valid : out std_logic;
|
||||
adp_header_bit : out std_logic;
|
||||
adp_frame_bit : out std_logic;
|
||||
adp_subpacket0_bits : out std_logic_vector(1 downto 0);
|
||||
adp_subpacket1_bits : out std_logic_vector(1 downto 0);
|
||||
adp_subpacket2_bits : out std_logic_vector(1 downto 0);
|
||||
adp_subpacket3_bits : out std_logic_vector(1 downto 0);
|
||||
-- For later reuse
|
||||
symbol_ch0 : out std_logic_vector(9 downto 0);
|
||||
symbol_ch1 : out std_logic_vector(9 downto 0);
|
||||
symbol_ch2 : out std_logic_vector(9 downto 0)
|
||||
|
||||
);
|
||||
end component;
|
||||
|
||||
-----------------------------------------------------
|
||||
-- This is a half-baked solution to extracting data
|
||||
-- from ADP packets - just pipe the data thorugh and
|
||||
-- extract bits on the fly. A 'real' solution would
|
||||
-- first verify the ECC codes and recover any errors
|
||||
------------------------------------------------------
|
||||
component extract_video_infopacket_data is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
-- ADP data
|
||||
adp_data_valid : in std_logic;
|
||||
adp_header_bit : in std_logic;
|
||||
adp_frame_bit : in std_logic;
|
||||
adp_subpacket0_bits : in std_logic_vector(1 downto 0);
|
||||
adp_subpacket1_bits : in std_logic_vector(1 downto 0);
|
||||
adp_subpacket2_bits : in std_logic_vector(1 downto 0);
|
||||
adp_subpacket3_bits : in std_logic_vector(1 downto 0);
|
||||
-- The stuff we need
|
||||
input_is_YCbCr : out std_Logic;
|
||||
input_is_422 : out std_logic;
|
||||
input_is_sRGB : out std_Logic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal adp_data_valid : std_logic;
|
||||
signal adp_header_bit : std_logic;
|
||||
signal adp_frame_bit : std_logic;
|
||||
signal adp_subpacket0_bits : std_logic_vector(1 downto 0);
|
||||
signal adp_subpacket1_bits : std_logic_vector(1 downto 0);
|
||||
signal adp_subpacket2_bits : std_logic_vector(1 downto 0);
|
||||
signal adp_subpacket3_bits : std_logic_vector(1 downto 0);
|
||||
signal is_interlaced_i : std_logic;
|
||||
signal is_second_field_i : std_logic;
|
||||
|
||||
component extract_audio_samples is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
adp_data_valid : in STD_LOGIC;
|
||||
adp_header_bit : in STD_LOGIC;
|
||||
adp_frame_bit : in STD_LOGIC;
|
||||
adp_subpacket0_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket1_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket2_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
adp_subpacket3_bits : in STD_LOGIC_VECTOR (1 downto 0);
|
||||
audio_de : out STD_LOGIC;
|
||||
audio_channel : out STD_LOGIC_VECTOR (2 downto 0);
|
||||
audio_sample : out STD_LOGIC_VECTOR (23 downto 0));
|
||||
end component;
|
||||
|
||||
|
||||
signal input_is_YCbCr : std_Logic;
|
||||
signal input_is_422 : std_logic;
|
||||
signal input_is_sRGB : std_Logic;
|
||||
|
||||
signal raw_blank : std_logic;
|
||||
signal raw_hsync : std_logic;
|
||||
signal raw_vsync : std_logic;
|
||||
signal raw_ch2 : std_logic_vector(7 downto 0); -- B or Cb
|
||||
signal raw_ch1 : std_logic_vector(7 downto 0); -- G or Y
|
||||
signal raw_ch0 : std_logic_vector(7 downto 0); -- R or Cr
|
||||
|
||||
component detect_interlace is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
hsync : in std_logic;
|
||||
vsync : in std_logic;
|
||||
is_interlaced : out std_logic;
|
||||
is_second_field : out std_logic);
|
||||
end component;
|
||||
|
||||
component expand_422_to_444 is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
input_is_422 : in std_logic;
|
||||
------------------
|
||||
-- Incoming pixels
|
||||
------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_ch2 : in std_logic_vector(7 downto 0);
|
||||
in_ch1 : in std_logic_vector(7 downto 0);
|
||||
in_ch0 : in std_logic_vector(7 downto 0);
|
||||
|
||||
-------------------
|
||||
-- Processed pixels
|
||||
-------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_U : out std_logic_vector(11 downto 0); -- B or Cb
|
||||
out_V : out std_logic_vector(11 downto 0); -- G or Y
|
||||
out_W : out std_logic_vector(11 downto 0) -- R or Cr
|
||||
);
|
||||
end component;
|
||||
|
||||
signal fourfourfour_blank : std_logic;
|
||||
signal fourfourfour_hsync : std_logic;
|
||||
signal fourfourfour_vsync : std_logic;
|
||||
signal fourfourfour_U : std_logic_vector(11 downto 0);
|
||||
signal fourfourfour_V : std_logic_vector(11 downto 0);
|
||||
signal fourfourfour_W : std_logic_vector(11 downto 0);
|
||||
|
||||
component conversion_to_RGB is
|
||||
port ( clk : in std_Logic;
|
||||
input_is_YCbCr : in std_Logic;
|
||||
input_is_sRGB : in std_Logic;
|
||||
------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_U : in std_logic_vector(11 downto 0);
|
||||
in_V : in std_logic_vector(11 downto 0);
|
||||
in_W : in std_logic_vector(11 downto 0);
|
||||
------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_R : out std_logic_vector(11 downto 0);
|
||||
out_G : out std_logic_vector(11 downto 0);
|
||||
out_B : out std_logic_vector(11 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal rgb_blank : std_logic;
|
||||
signal rgb_hsync : std_logic;
|
||||
signal rgb_vsync : std_logic;
|
||||
signal rgb_R : std_logic_vector(11 downto 0);
|
||||
signal rgb_G : std_logic_vector(11 downto 0); -- G or Y
|
||||
signal rgb_B : std_logic_vector(11 downto 0); -- R or Cr
|
||||
|
||||
component DVID_output is
|
||||
Port (
|
||||
pixel_clk : in std_logic; -- Driven by BUFG
|
||||
pixel_io_clk_x1 : in std_logic; -- Driven by BUFIO
|
||||
pixel_io_clk_x5 : in std_logic; -- Driven by BUFIO
|
||||
|
||||
-- VGA Signals
|
||||
vga_blank : in std_logic;
|
||||
vga_hsync : in std_logic;
|
||||
vga_vsync : in std_logic;
|
||||
vga_red : in std_logic_vector(7 downto 0);
|
||||
vga_blue : in std_logic_vector(7 downto 0);
|
||||
vga_green : in std_logic_vector(7 downto 0);
|
||||
data_valid : in std_logic;
|
||||
|
||||
--- HDMI out
|
||||
tmds_out_clk : out std_logic;
|
||||
tmds_out_ch0 : out std_logic;
|
||||
tmds_out_ch1 : out std_logic;
|
||||
tmds_out_ch2 : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
-- Clocks for the pixel clock domain
|
||||
signal pixel_clk_i : std_logic;
|
||||
signal pixel_io_clk_x1 : std_logic;
|
||||
signal pixel_io_clk_x5 : std_logic;
|
||||
|
||||
-- The serial data
|
||||
signal tmds_in_clk : std_logic;
|
||||
signal tmds_in_ch0 : std_logic;
|
||||
signal tmds_in_ch1 : std_logic;
|
||||
signal tmds_in_ch2 : std_logic;
|
||||
|
||||
signal tmds_out_clk : std_logic;
|
||||
signal tmds_out_ch0 : std_logic;
|
||||
signal tmds_out_ch1 : std_logic;
|
||||
signal tmds_out_ch2 : std_logic;
|
||||
|
||||
signal detect_sr : std_logic_vector(7 downto 0) := (others => '0');
|
||||
begin
|
||||
pixel_clk <= pixel_clk_i;
|
||||
hdmi_rx_hpa <= '1';
|
||||
hdmi_rx_txen <= '1';
|
||||
hdmi_rx_cec <= 'Z';
|
||||
|
||||
debug(7) <= raw_hsync;
|
||||
debug(6) <= raw_vsync;
|
||||
debug(5) <= is_second_field_i;
|
||||
debug(4) <= is_interlaced_i;
|
||||
debug(3) <= out_hsync;
|
||||
debug(2) <= out_vsync;
|
||||
debug(1) <= out_blank;
|
||||
debug(0) <= '0';
|
||||
|
||||
i_edid_rom: edid_rom port map (
|
||||
clk => clk100,
|
||||
sclk_raw => hdmi_rx_scl,
|
||||
sdat_raw => hdmi_rx_sda,
|
||||
edid_debug => open);
|
||||
|
||||
---------------------
|
||||
-- Input buffers
|
||||
---------------------
|
||||
in_clk_buf: IBUFDS generic map ( IOSTANDARD => "TMDS_33")
|
||||
port map ( I => hdmi_rx_clk_p, IB => hdmi_rx_clk_n, O => tmds_in_clk);
|
||||
|
||||
in_rx0_buf: IBUFDS generic map ( IOSTANDARD => "TMDS_33")
|
||||
port map ( I => hdmi_rx_p(0), IB => hdmi_rx_n(0), O => tmds_in_ch0);
|
||||
|
||||
in_rx1_buf: IBUFDS generic map ( IOSTANDARD => "TMDS_33")
|
||||
port map ( I => hdmi_rx_p(1), IB => hdmi_rx_n(1), O => tmds_in_ch1);
|
||||
|
||||
in_rx2_buf: IBUFDS generic map ( IOSTANDARD => "TMDS_33")
|
||||
port map ( I => hdmi_rx_p(2), IB => hdmi_rx_n(2), O => tmds_in_ch2);
|
||||
|
||||
i_hdmi_input : hdmi_input port map (
|
||||
system_clk => clk100,
|
||||
debug => open,
|
||||
-- Pixel and serializer clocks
|
||||
pixel_clk => pixel_clk_i,
|
||||
pixel_io_clk_x1 => pixel_io_clk_x1,
|
||||
pixel_io_clk_x5 => pixel_io_clk_x5,
|
||||
--- HDMI input signals
|
||||
hdmi_in_clk => tmds_in_clk,
|
||||
hdmi_in_ch0 => tmds_in_ch0,
|
||||
hdmi_in_ch1 => tmds_in_ch1,
|
||||
hdmi_in_ch2 => tmds_in_ch2,
|
||||
-- are the HDMI symbols in sync?
|
||||
symbol_sync => data_synced,
|
||||
pll_locked => clock_locked,
|
||||
-- VGA internal Signals
|
||||
hdmi_detected => in_hdmi_detected,
|
||||
raw_blank => raw_blank,
|
||||
raw_hsync => raw_hsync,
|
||||
raw_vsync => raw_vsync,
|
||||
raw_ch2 => raw_ch2,
|
||||
raw_ch1 => raw_ch1,
|
||||
raw_ch0 => raw_ch0,
|
||||
-- ADP data
|
||||
adp_data_valid => adp_data_valid,
|
||||
adp_header_bit => adp_header_bit,
|
||||
adp_frame_bit => adp_frame_bit,
|
||||
adp_subpacket0_bits => adp_subpacket0_bits,
|
||||
adp_subpacket1_bits => adp_subpacket1_bits,
|
||||
adp_subpacket2_bits => adp_subpacket2_bits,
|
||||
adp_subpacket3_bits => adp_subpacket3_bits,
|
||||
-- For later reuse
|
||||
symbol_ch0 => symbol_ch0,
|
||||
symbol_ch1 => symbol_ch1,
|
||||
symbol_ch2 => symbol_ch2
|
||||
);
|
||||
|
||||
-------------------------------------
|
||||
-- If the input data is in 422 format
|
||||
-- then convert it to 12-bit 444 data
|
||||
-------------------------------------
|
||||
i_expand_422_to_444: expand_422_to_444 Port map (
|
||||
clk => pixel_clk_i,
|
||||
input_is_422 => input_is_422,
|
||||
------------------
|
||||
-- Incoming raw data
|
||||
------------------
|
||||
in_blank => raw_blank,
|
||||
in_hsync => raw_hsync,
|
||||
in_vsync => raw_vsync,
|
||||
in_ch2 => raw_ch2,
|
||||
in_ch1 => raw_ch1,
|
||||
in_ch0 => raw_ch0,
|
||||
|
||||
-------------------
|
||||
-- Processed pixels
|
||||
-------------------
|
||||
out_blank => fourfourfour_blank,
|
||||
out_hsync => fourfourfour_hsync,
|
||||
out_vsync => fourfourfour_vsync,
|
||||
out_U => fourfourfour_U,
|
||||
out_V => fourfourfour_V,
|
||||
out_W => fourfourfour_W
|
||||
);
|
||||
|
||||
is_interlaced <= is_interlaced_i;
|
||||
is_second_field <= is_second_field_i;
|
||||
i_detect_interlace: detect_interlace Port map (
|
||||
clk => pixel_clk_i,
|
||||
hsync => raw_hsync,
|
||||
vsync => raw_vsync,
|
||||
is_interlaced => is_interlaced_i,
|
||||
is_second_field => is_second_field_i);
|
||||
|
||||
i_conversion_to_RGB: conversion_to_RGB
|
||||
port map (
|
||||
clk => pixel_clk_i,
|
||||
------------------------
|
||||
input_is_YCbCr => input_is_YCbCr,
|
||||
input_is_sRGB => input_is_sRGB,
|
||||
in_blank => fourfourfour_blank,
|
||||
in_hsync => fourfourfour_hsync,
|
||||
in_vsync => fourfourfour_vsync,
|
||||
in_U => fourfourfour_U,
|
||||
in_V => fourfourfour_V,
|
||||
in_W => fourfourfour_W,
|
||||
------------------------
|
||||
out_blank => rgb_blank,
|
||||
out_hsync => rgb_hsync,
|
||||
out_vsync => rgb_vsync,
|
||||
out_R => rgb_R,
|
||||
out_G => rgb_G,
|
||||
out_B => rgb_B
|
||||
);
|
||||
|
||||
-----------------------------------------
|
||||
-- Colour space conversion yet to be done
|
||||
-----------------------------------------
|
||||
in_blank <= rgb_blank;
|
||||
in_hsync <= rgb_hsync;
|
||||
in_vsync <= rgb_vsync;
|
||||
in_blue <= rgb_B(11 downto 4);
|
||||
in_green <= rgb_G(11 downto 4);
|
||||
in_red <= rgb_R(11 downto 4);
|
||||
|
||||
------------------------------------------------
|
||||
-- Processing the non-video data #1
|
||||
-- Extracting the Video Infopacket data we need
|
||||
-- to correctly convert the video data
|
||||
------------------------------------------------
|
||||
i_extract_video_infopacket_data: extract_video_infopacket_data port map (
|
||||
clk => pixel_clk_i,
|
||||
-- ADP data
|
||||
adp_data_valid => adp_data_valid,
|
||||
adp_header_bit => adp_header_bit,
|
||||
adp_frame_bit => adp_frame_bit,
|
||||
adp_subpacket0_bits => adp_subpacket0_bits,
|
||||
adp_subpacket1_bits => adp_subpacket1_bits,
|
||||
adp_subpacket2_bits => adp_subpacket2_bits,
|
||||
adp_subpacket3_bits => adp_subpacket3_bits,
|
||||
-- The stuff we need
|
||||
input_is_YCbCr => input_is_YCbCr,
|
||||
input_is_422 => input_is_422,
|
||||
input_is_sRGB => input_is_sRGB
|
||||
);
|
||||
------------------------------------------------
|
||||
-- Processing the non-video data #2
|
||||
-- Extracting the Audio samples so we can display
|
||||
-- level menters on the screen
|
||||
------------------------------------------------
|
||||
i_extract_audio_samples: extract_audio_samples PORT MAP (
|
||||
clk => pixel_clk_i,
|
||||
-- ADP data
|
||||
adp_data_valid => adp_data_valid,
|
||||
adp_header_bit => adp_header_bit,
|
||||
adp_frame_bit => adp_frame_bit,
|
||||
adp_subpacket0_bits => adp_subpacket0_bits,
|
||||
adp_subpacket1_bits => adp_subpacket1_bits,
|
||||
adp_subpacket2_bits => adp_subpacket2_bits,
|
||||
adp_subpacket3_bits => adp_subpacket3_bits,
|
||||
-- The stuff we need
|
||||
audio_de => audio_de,
|
||||
audio_channel => audio_channel,
|
||||
audio_sample => audio_sample);
|
||||
|
||||
------------------------------------------------
|
||||
-- Outputting video data
|
||||
-----------------------------------------------
|
||||
i_DVID_output: DVID_output port map (
|
||||
pixel_clk => pixel_clk_i,
|
||||
pixel_io_clk_x1 => pixel_io_clk_x1,
|
||||
pixel_io_clk_x5 => pixel_io_clk_x5,
|
||||
|
||||
data_valid => '1',
|
||||
-- VGA Signals
|
||||
vga_blank => out_blank,
|
||||
vga_hsync => out_hsync,
|
||||
vga_vsync => out_vsync,
|
||||
vga_red => out_red,
|
||||
vga_blue => out_blue,
|
||||
vga_green => out_green,
|
||||
|
||||
--- HDMI out
|
||||
tmds_out_clk => tmds_out_clk,
|
||||
tmds_out_ch0 => tmds_out_ch0,
|
||||
tmds_out_ch1 => tmds_out_ch1,
|
||||
tmds_out_ch2 => tmds_out_ch2
|
||||
);
|
||||
|
||||
-----------------------------
|
||||
-- Other HDMI control signals
|
||||
-----------------------------
|
||||
hdmi_tx_rsda <= 'Z';
|
||||
hdmi_tx_cec <= 'Z';
|
||||
hdmi_tx_rscl <= '1';
|
||||
|
||||
-----------------
|
||||
-- Output buffers
|
||||
-----------------
|
||||
out_clk_buf: OBUFDS generic map ( IOSTANDARD => "TMDS_33", SLEW => "FAST")
|
||||
port map ( O => hdmi_tx_clk_p, OB => hdmi_tx_clk_n, I => tmds_out_clk);
|
||||
|
||||
out_tx0_buf: OBUFDS generic map ( IOSTANDARD => "TMDS_33", SLEW => "FAST")
|
||||
port map ( O => hdmi_tx_p(0), OB => hdmi_tx_n(0), I => tmds_out_ch0);
|
||||
|
||||
out_tx1_buf: OBUFDS generic map ( IOSTANDARD => "TMDS_33", SLEW => "FAST")
|
||||
port map ( O => hdmi_tx_p(1), OB => hdmi_tx_n(1), I => tmds_out_ch1);
|
||||
|
||||
out_tx2_buf: OBUFDS generic map ( IOSTANDARD => "TMDS_33", SLEW => "FAST")
|
||||
port map ( O => hdmi_tx_p(2), OB => hdmi_tx_n(2), I => tmds_out_ch2);
|
||||
|
||||
-- Detect when VSYNC is held high for 8 cycles, so we can synchronise the capture of symbols
|
||||
process(pixel_clk_i)
|
||||
begin
|
||||
if rising_edge(pixel_clk_i) then
|
||||
if detect_sr = "11111111" and raw_vsync = '0' then
|
||||
symbol_sync <= '1';
|
||||
else
|
||||
symbol_sync <= '0';
|
||||
end if;
|
||||
detect_sr <= detect_sr(6 downto 0) & raw_vsync;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
157
src/input_channel.vhd
Normal file
157
src/input_channel.vhd
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Create Date: 30.07.2015 23:11:34
|
||||
-- Module Name: input_channel - Behavioral
|
||||
--
|
||||
-- Description: Receiving one of the three HDMI input channels. and decoding
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity input_channel is
|
||||
Port ( clk_mgmt : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
clk_x1 : in STD_LOGIC;
|
||||
clk_x5 : in STD_LOGIC;
|
||||
serial : in STD_LOGIC;
|
||||
reset : in std_logic;
|
||||
ce : in STD_LOGIC;
|
||||
invalid_symbol : out std_logic;
|
||||
symbol : out std_logic_vector (9 downto 0);
|
||||
ctl_valid : out std_logic;
|
||||
ctl : out std_logic_vector (1 downto 0);
|
||||
terc4_valid : out std_logic;
|
||||
terc4 : out std_logic_vector (3 downto 0);
|
||||
guardband_valid : out std_logic;
|
||||
guardband : out std_logic_vector (0 downto 0);
|
||||
data_valid : out std_logic;
|
||||
data : out std_logic_vector (7 downto 0);
|
||||
symbol_sync : out STD_LOGIC);
|
||||
end input_channel;
|
||||
|
||||
architecture Behavioral of input_channel is
|
||||
component deserialiser_1_to_10 is
|
||||
Port ( clk_mgmt : in std_logic;
|
||||
delay_ce : in std_logic;
|
||||
delay_count : in std_logic_vector (4 downto 0);
|
||||
ce : in STD_LOGIC;
|
||||
clk : in std_logic;
|
||||
clk_x1 : in std_logic;
|
||||
bitslip : in std_logic;
|
||||
clk_x5 : in std_logic;
|
||||
reset : in std_logic;
|
||||
serial : in std_logic;
|
||||
data : out std_logic_vector (9 downto 0));
|
||||
end component;
|
||||
|
||||
component TMDS_decoder is
|
||||
Port ( clk : in std_logic;
|
||||
symbol : in std_logic_vector (9 downto 0);
|
||||
invalid_symbol : out std_logic;
|
||||
ctl_valid : out std_logic;
|
||||
ctl : out std_logic_vector (1 downto 0);
|
||||
terc4_valid : out std_logic;
|
||||
terc4 : out std_logic_vector (3 downto 0);
|
||||
guardband_valid : out std_logic;
|
||||
guardband : out std_logic_vector (0 downto 0);
|
||||
data_valid : out std_logic;
|
||||
data : out std_logic_vector (7 downto 0));
|
||||
end component;
|
||||
|
||||
component alignment_detect is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
invalid_symbol : in STD_LOGIC;
|
||||
delay_count : out STD_LOGIC_VECTOR(4 downto 0);
|
||||
delay_ce : out STD_LOGIC;
|
||||
bitslip : out STD_LOGIC;
|
||||
symbol_sync : out STD_LOGIC);
|
||||
end component;
|
||||
|
||||
signal delay_count : std_logic_vector (4 downto 0);
|
||||
signal delay_ce : STD_LOGIC;
|
||||
signal bitslip : STD_LOGIC;
|
||||
signal symbol_sync_i : STD_LOGIC;
|
||||
signal symbol_i : std_logic_vector (9 downto 0);
|
||||
signal invalid_symbol_i: STD_LOGIC;
|
||||
|
||||
begin
|
||||
symbol <= symbol_i;
|
||||
|
||||
i_deser: deserialiser_1_to_10 port map (
|
||||
clk_mgmt => clk_mgmt,
|
||||
delay_ce => delay_ce,
|
||||
delay_count => delay_count,
|
||||
ce => ce,
|
||||
clk => clk,
|
||||
clk_x1 => clk_x1,
|
||||
bitslip => bitslip,
|
||||
clk_x5 => clk_x5,
|
||||
reset => reset,
|
||||
serial => serial,
|
||||
data => symbol_i);
|
||||
|
||||
i_decoder: tmds_decoder port map (
|
||||
clk => clk,
|
||||
symbol => symbol_i,
|
||||
invalid_symbol => invalid_symbol_i,
|
||||
ctl_valid => ctl_valid,
|
||||
ctl => ctl,
|
||||
terc4_valid => terc4_valid,
|
||||
terc4 => terc4,
|
||||
guardband_valid => guardband_valid,
|
||||
guardband => guardband,
|
||||
data_valid => data_valid,
|
||||
data => data
|
||||
);
|
||||
|
||||
invalid_symbol <= invalid_symbol_i;
|
||||
|
||||
i_alignment_detect: alignment_detect port map (
|
||||
clk => clk,
|
||||
invalid_symbol => invalid_symbol_i,
|
||||
delay_count => delay_count,
|
||||
delay_ce => delay_ce,
|
||||
bitslip => bitslip,
|
||||
symbol_sync => symbol_sync);
|
||||
|
||||
end Behavioral;
|
||||
153
src/line_delay.vhd
Normal file
153
src/line_delay.vhd
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: line_delay - Behavioral
|
||||
--
|
||||
-- Description: Delay the video signal by one line, as measured by the rising
|
||||
-- edge on hsync. This module works for line lengths of between
|
||||
-- around 510 and around 2500 (needed for 640x480 through
|
||||
-- 1920x1080.
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity line_delay is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0));
|
||||
end line_delay;
|
||||
|
||||
architecture Behavioral of line_delay is
|
||||
type mem_block is array (0 to 511) of std_logic_vector(26 downto 0);
|
||||
signal mem_0 : mem_block := (others => (others => '0'));
|
||||
signal mem_1 : mem_block := (others => (others => '0'));
|
||||
signal mem_2 : mem_block := (others => (others => '0'));
|
||||
signal mem_3 : mem_block := (others => (others => '0'));
|
||||
signal mem_4 : mem_block := (others => (others => '0'));
|
||||
|
||||
signal wr_addr : unsigned(8 downto 0) := (others =>'1');
|
||||
signal offset_0 : unsigned(8 downto 0) := (others =>'1');
|
||||
signal offset_1 : unsigned(8 downto 0) := (others =>'1');
|
||||
signal offset_2 : unsigned(8 downto 0) := (others =>'1');
|
||||
signal offset_3 : unsigned(8 downto 0) := (others =>'1');
|
||||
signal offset_4 : unsigned(8 downto 0) := (others =>'1');
|
||||
|
||||
signal width : unsigned(11 downto 0) := (others =>'0');
|
||||
signal line_count : unsigned(11 downto 0) := (others =>'0');
|
||||
signal last_hsync : std_logic := '0';
|
||||
signal mid_0 : std_logic_vector(26 downto 0) := (others =>'0');
|
||||
signal mid_1 : std_logic_vector(26 downto 0) := (others =>'0');
|
||||
signal mid_2 : std_logic_vector(26 downto 0) := (others =>'0');
|
||||
signal mid_3 : std_logic_vector(26 downto 0) := (others =>'0');
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
variable mem_4_out : std_logic_vector(26 downto 0);
|
||||
variable temp : unsigned(11 downto 0) := (others =>'1');
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
------------------------------------------------
|
||||
-- Retreive the value from the end of the delay
|
||||
-- and break out the signals
|
||||
------------------------------------------------
|
||||
mem_4_out := mem_4(to_integer(wr_addr+offset_4));
|
||||
out_red <= mem_4_out(26 downto 19);
|
||||
out_green <= mem_4_out(18 downto 11);
|
||||
out_blue <= mem_4_out(10 downto 3);
|
||||
out_blank <= mem_4_out(2);
|
||||
out_hsync <= mem_4_out(1);
|
||||
out_vsync <= mem_4_out(0);
|
||||
|
||||
-------------------------------------------------
|
||||
-- Move everything through the five memory blocks
|
||||
-------------------------------------------------
|
||||
mem_4(to_integer(wr_addr)) <= mid_3;
|
||||
mid_3 <= mem_3(to_integer(wr_addr+offset_3));
|
||||
mem_3(to_integer(wr_addr)) <= mid_2;
|
||||
mid_2 <= mem_2(to_integer(wr_addr+offset_2));
|
||||
mem_2(to_integer(wr_addr)) <= mid_1;
|
||||
mid_1 <= mem_1(to_integer(wr_addr+offset_1));
|
||||
mem_1(to_integer(wr_addr)) <= mid_0;
|
||||
mid_0 <= mem_0(to_integer(wr_addr+offset_0));
|
||||
mem_0(to_integer(wr_addr)) <= in_red & in_green & in_blue & in_blank & in_hsync & in_vsync;
|
||||
wr_addr <= wr_addr - 1;
|
||||
if in_hsync = '1' and last_hsync ='0' then
|
||||
width <= line_count;
|
||||
line_count <= (others => '0');
|
||||
else
|
||||
line_count <=line_count + 1;
|
||||
end if;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Update the offsets every cycle, not that we really need to
|
||||
-- This improves the timing as we have less logic
|
||||
-------------------------------------------------------------
|
||||
offset_0 <= to_unsigned(508,9);
|
||||
temp := width-512+0; offset_1 <= temp(10 downto 2);
|
||||
temp := width-512+1; offset_2 <= temp(10 downto 2);
|
||||
temp := width-512+2; offset_3 <= temp(10 downto 2);
|
||||
temp := width-512+3; offset_4 <= temp(10 downto 2);
|
||||
|
||||
last_hsync <= in_hsync;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
281
src/pixel_processing.vhd
Normal file
281
src/pixel_processing.vhd
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hasmter@snap.net.nz>
|
||||
--
|
||||
-- Module Name: pixel_processing - Behavioral
|
||||
--
|
||||
-- Description: Where you can do processing on the raw pixel data
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity pixel_processing is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
is_interlaced : in std_logic;
|
||||
is_second_field : in std_logic;
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0);
|
||||
------------------------------------
|
||||
-- Audio only comes in..
|
||||
------------------------------------
|
||||
audio_channel : in std_logic_vector(2 downto 0);
|
||||
audio_de : in std_logic;
|
||||
audio_sample : in std_logic_vector(23 downto 0);
|
||||
|
||||
----------------------------------
|
||||
-- Controls
|
||||
----------------------------------
|
||||
switches : in std_logic_vector(7 downto 0)
|
||||
);
|
||||
end pixel_processing;
|
||||
|
||||
architecture Behavioral of pixel_processing is
|
||||
component audio_to_db is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
in_channel : in STD_LOGIC_VECTOR (2 downto 0);
|
||||
in_de : in STD_LOGIC;
|
||||
in_sample : in STD_LOGIC_VECTOR (23 downto 0);
|
||||
out_channel : out STD_LOGIC_VECTOR (2 downto 0);
|
||||
out_de : out STD_LOGIC;
|
||||
out_level : out STD_LOGIC_VECTOR (5 downto 0));
|
||||
end component;
|
||||
|
||||
signal level_channel : std_logic_vector(2 downto 0);
|
||||
signal level_de : std_logic;
|
||||
signal level : std_logic_vector(5 downto 0);
|
||||
|
||||
component audio_meters is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
is_interlaced : in std_logic;
|
||||
is_second_field : in std_logic;
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0);
|
||||
|
||||
-------------------------------------
|
||||
-- Audio Levels
|
||||
-------------------------------------
|
||||
signal audio_channel : in std_logic_vector(2 downto 0);
|
||||
signal audio_de : in std_logic;
|
||||
signal audio_level : in std_logic_vector(5 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component edge_enhance is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
enable_feature : in std_logic;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component guidelines is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
enable_feature : in std_logic;
|
||||
-------------------------------
|
||||
-- VGA data recovered from HDMI
|
||||
-------------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_red : in std_logic_vector(7 downto 0);
|
||||
in_green : in std_logic_vector(7 downto 0);
|
||||
in_blue : in std_logic_vector(7 downto 0);
|
||||
is_interlaced : in std_logic;
|
||||
is_second_field : in std_logic;
|
||||
|
||||
-----------------------------------
|
||||
-- VGA data to be converted to HDMI
|
||||
-----------------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_red : out std_logic_vector(7 downto 0);
|
||||
out_green : out std_logic_vector(7 downto 0);
|
||||
out_blue : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal b_blank : std_logic;
|
||||
signal b_hsync : std_logic;
|
||||
signal b_vsync : std_logic;
|
||||
signal b_red : std_logic_vector(7 downto 0);
|
||||
signal b_green : std_logic_vector(7 downto 0);
|
||||
signal b_blue : std_logic_vector(7 downto 0);
|
||||
|
||||
signal c_blank : std_logic;
|
||||
signal c_hsync : std_logic;
|
||||
signal c_vsync : std_logic;
|
||||
signal c_red : std_logic_vector(7 downto 0);
|
||||
signal c_green : std_logic_vector(7 downto 0);
|
||||
signal c_blue : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
i_audio_to_db: audio_to_db port map (
|
||||
clk => clk,
|
||||
|
||||
in_channel => audio_channel,
|
||||
in_de => audio_de,
|
||||
in_sample => audio_sample,
|
||||
|
||||
out_channel => level_channel,
|
||||
out_de => level_de,
|
||||
out_level => level
|
||||
);
|
||||
|
||||
i_edge_enhance: edge_enhance Port map (
|
||||
clk => clk,
|
||||
|
||||
enable_feature => switches(0),
|
||||
|
||||
in_blank => in_blank,
|
||||
in_hsync => in_hsync,
|
||||
in_vsync => in_vsync,
|
||||
in_red => in_red,
|
||||
in_green => in_green,
|
||||
in_blue => in_blue,
|
||||
|
||||
out_blank => b_blank,
|
||||
out_hsync => b_hsync,
|
||||
out_vsync => b_vsync,
|
||||
out_red => b_red,
|
||||
out_green => b_green,
|
||||
out_blue => b_blue
|
||||
);
|
||||
|
||||
i_audio_meters: audio_meters Port map (
|
||||
clk => clk,
|
||||
in_blank => b_blank,
|
||||
in_hsync => b_hsync,
|
||||
in_vsync => b_vsync,
|
||||
in_red => b_red,
|
||||
in_green => b_green,
|
||||
in_blue => b_blue,
|
||||
is_interlaced => is_interlaced,
|
||||
is_second_field => is_second_field,
|
||||
|
||||
out_blank => c_blank,
|
||||
out_hsync => c_hsync,
|
||||
out_vsync => c_vsync,
|
||||
out_red => c_red,
|
||||
out_green => c_green,
|
||||
out_blue => c_blue,
|
||||
|
||||
audio_channel => level_channel,
|
||||
audio_de => level_de,
|
||||
audio_level => level
|
||||
);
|
||||
|
||||
|
||||
i_guidelines: guidelines Port map (
|
||||
clk => clk,
|
||||
|
||||
enable_feature => switches(1),
|
||||
|
||||
in_blank => c_blank,
|
||||
in_hsync => c_hsync,
|
||||
in_vsync => c_vsync,
|
||||
in_red => c_red,
|
||||
in_green => c_green,
|
||||
in_blue => c_blue,
|
||||
is_interlaced => is_interlaced,
|
||||
is_second_field => is_second_field,
|
||||
|
||||
out_blank => out_blank,
|
||||
out_hsync => out_hsync,
|
||||
out_vsync => out_vsync,
|
||||
out_red => out_red,
|
||||
out_green => out_green,
|
||||
out_blue => out_blue
|
||||
);
|
||||
|
||||
end Behavioral;
|
||||
176
src/serialiser_10_to_1.vhd
Normal file
176
src/serialiser_10_to_1.vhd
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- File: serialiser_10_to_1.vhd
|
||||
--
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: serialiser_10_to_1 - Behavioral
|
||||
--
|
||||
-- Description: Using the OSERDESE2 as a 10:1 serialiser, using a x1 and x5
|
||||
-- clocks (using DDR outputs).
|
||||
--
|
||||
-- The tricky bit is that reset needs to be asserted, and then CE asserted
|
||||
-- after the reset or it will not simulate correctly (outputs show as 'X')
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity serialiser_10_to_1 is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
clk_x5 : in STD_LOGIC;
|
||||
data : in STD_LOGIC_VECTOR (9 downto 0);
|
||||
reset : in std_logic;
|
||||
serial : out STD_LOGIC);
|
||||
end serialiser_10_to_1;
|
||||
|
||||
architecture Behavioral of serialiser_10_to_1 is
|
||||
signal shift1 : std_logic := '0';
|
||||
signal shift2 : std_logic := '0';
|
||||
signal ce_delay : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal reset_delay : std_logic_vector(7 downto 0) := (others => '0');
|
||||
begin
|
||||
|
||||
master_serdes : OSERDESE2
|
||||
generic map (
|
||||
DATA_RATE_OQ => "DDR", -- DDR, SDR
|
||||
DATA_RATE_TQ => "DDR", -- DDR, BUF, SDR
|
||||
DATA_WIDTH => 10, -- Parallel data width (2-8,10,14)
|
||||
INIT_OQ => '1', -- Initial value of OQ output (1'b0,1'b1)
|
||||
INIT_TQ => '1', -- Initial value of TQ output (1'b0,1'b1)
|
||||
SERDES_MODE => "MASTER", -- MASTER, SLAVE
|
||||
SRVAL_OQ => '0', -- OQ output value when SR is used (1'b0,1'b1)
|
||||
SRVAL_TQ => '0', -- TQ output value when SR is used (1'b0,1'b1)
|
||||
TBYTE_CTL => "FALSE", -- Enable tristate byte operation (FALSE, TRUE)
|
||||
TBYTE_SRC => "FALSE", -- Tristate byte source (FALSE, TRUE)
|
||||
TRISTATE_WIDTH => 1 -- 3-state converter width (1,4)
|
||||
)
|
||||
port map (
|
||||
OFB => open, -- 1-bit output: Feedback path for data
|
||||
OQ => serial, -- 1-bit output: Data path output
|
||||
-- SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
|
||||
SHIFTOUT1 => open,
|
||||
SHIFTOUT2 => open,
|
||||
TBYTEOUT => open, -- 1-bit output: Byte group tristate
|
||||
TFB => open, -- 1-bit output: 3-state control
|
||||
TQ => open, -- 1-bit output: 3-state control
|
||||
CLK => clk_x5, -- 1-bit input: High speed clock
|
||||
CLKDIV => clk, -- 1-bit input: Divided clock
|
||||
-- D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
|
||||
D1 => data(0),
|
||||
D2 => data(1),
|
||||
D3 => data(2),
|
||||
D4 => data(3),
|
||||
D5 => data(4),
|
||||
D6 => data(5),
|
||||
D7 => data(6),
|
||||
D8 => data(7),
|
||||
OCE => '1', --ce_delay(0), -- 1-bit input: Output data clock enable
|
||||
RST => reset, -- 1-bit input: Reset
|
||||
-- SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
|
||||
SHIFTIN1 => SHIFT1,
|
||||
SHIFTIN2 => SHIFT2,
|
||||
-- T1 - T4: 1-bit (each) input: Parallel 3-state inputs
|
||||
T1 => '0',
|
||||
T2 => '0',
|
||||
T3 => '0',
|
||||
T4 => '0',
|
||||
TBYTEIN => '0', -- 1-bit input: Byte group tristate
|
||||
TCE => '0' -- 1-bit input: 3-state clock enable
|
||||
);
|
||||
|
||||
slave_serdes : OSERDESE2
|
||||
generic map (
|
||||
DATA_RATE_OQ => "DDR", -- DDR, SDR
|
||||
DATA_RATE_TQ => "DDR", -- DDR, BUF, SDR
|
||||
DATA_WIDTH => 10, -- Parallel data width (2-8,10,14)
|
||||
INIT_OQ => '1', -- Initial value of OQ output (1'b0,1'b1)
|
||||
INIT_TQ => '1', -- Initial value of TQ output (1'b0,1'b1)
|
||||
SERDES_MODE => "SLAVE", -- MASTER, SLAVE
|
||||
SRVAL_OQ => '0', -- OQ output value when SR is used (1'b0,1'b1)
|
||||
SRVAL_TQ => '0', -- TQ output value when SR is used (1'b0,1'b1)
|
||||
TBYTE_CTL => "FALSE", -- Enable tristate byte operation (FALSE, TRUE)
|
||||
TBYTE_SRC => "FALSE", -- Tristate byte source (FALSE, TRUE)
|
||||
TRISTATE_WIDTH => 1 -- 3-state converter width (1,4)
|
||||
)
|
||||
port map (
|
||||
OFB => open, -- 1-bit output: Feedback path for data
|
||||
OQ => open, -- 1-bit output: Data path output
|
||||
-- SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
|
||||
SHIFTOUT1 => shift1,
|
||||
SHIFTOUT2 => shift2,
|
||||
|
||||
TBYTEOUT => open, -- 1-bit output: Byte group tristate
|
||||
TFB => open, -- 1-bit output: 3-state control
|
||||
TQ => open, -- 1-bit output: 3-state control
|
||||
CLK => clk_x5, -- 1-bit input: High speed clock
|
||||
CLKDIV => clk, -- 1-bit input: Divided clock
|
||||
-- D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
|
||||
D1 => '0',
|
||||
D2 => '0',
|
||||
D3 => data(8),
|
||||
D4 => data(9),
|
||||
D5 => '0',
|
||||
D6 => '0',
|
||||
D7 => '0',
|
||||
D8 => '0',
|
||||
OCE => '1', --ce_delay(0), -- 1-bit input: Output data clock enable
|
||||
RST => reset, -- 1-bit input: Reset
|
||||
-- SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
|
||||
SHIFTIN1 => '0',
|
||||
SHIFTIN2 => '0',
|
||||
-- T1 - T4: 1-bit (each) input: Parallel 3-state inputs
|
||||
T1 => '0',
|
||||
T2 => '0',
|
||||
T3 => '0',
|
||||
T4 => '0',
|
||||
TBYTEIN => '0', -- 1-bit input: Byte group tristate
|
||||
TCE => '0' -- 1-bit input: 3-state clock enable
|
||||
);
|
||||
|
||||
delay_ce: process(clk_x5)
|
||||
begin
|
||||
if rising_edge(clk_x5) then
|
||||
ce_delay <= not reset & ce_delay(ce_delay'high downto 1);
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
97
src/spi_regfile.v
Normal file
97
src/spi_regfile.v
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module spi_regfile(
|
||||
input clk, rst,
|
||||
|
||||
input sck, sdi, ncs,
|
||||
output reg sdo,
|
||||
|
||||
input [7:0] spi_data_in,
|
||||
output reg [7:0] spi_data_out,
|
||||
|
||||
input [7:0] spi_status_word,
|
||||
output reg [7:0] spi_cmd_word,
|
||||
output reg spi_cmd_begin,
|
||||
output reg spi_cmd_active,
|
||||
output reg spi_cmd_step,
|
||||
output reg [19:0] spi_cmd_idx,
|
||||
output [7:0] rxbuf_dbg
|
||||
);
|
||||
|
||||
reg [6:0] txbuf;
|
||||
reg [7:0] rxbuf;
|
||||
reg is_cmd_word;
|
||||
reg last_ncs;
|
||||
reg last_sck;
|
||||
reg load_data;
|
||||
|
||||
assign rxbuf_dbg = rxbuf;
|
||||
|
||||
wire sck_clean, sdi_clean, ncs_clean;
|
||||
edge_cleaner sck_cleaner (.clk(clk), .in(sck), .out(sck_clean));
|
||||
edge_cleaner sdi_cleaner (.clk(clk), .in(sdi), .out(sdi_clean));
|
||||
edge_cleaner ncs_cleaner (.clk(clk), .in(ncs), .out(ncs_clean));
|
||||
|
||||
/* SPI mode 0: CPOL = 0, CPHA = 0. Initial SDO setup on falling ~CS edge */
|
||||
|
||||
always @(posedge clk) begin
|
||||
spi_cmd_begin <= 0;
|
||||
spi_cmd_step <= 0;
|
||||
last_ncs <= ncs_clean;
|
||||
last_sck <= sck_clean;
|
||||
|
||||
if (rst) begin
|
||||
is_cmd_word <= 1;
|
||||
spi_cmd_active <= 0;
|
||||
spi_cmd_idx <= 0;
|
||||
|
||||
end else begin
|
||||
if (last_ncs && !ncs_clean) begin
|
||||
txbuf <= spi_status_word[6:0];
|
||||
sdo <= spi_status_word[7];
|
||||
rxbuf <= 8'h01;
|
||||
end
|
||||
|
||||
if (!ncs_clean) begin
|
||||
if (!last_sck && sck_clean) begin /* sampling edge */
|
||||
if (!rxbuf[7]) begin
|
||||
rxbuf <= {rxbuf[6:0], sdi_clean};
|
||||
|
||||
end else begin
|
||||
rxbuf <= 8'h01;
|
||||
load_data <= 1;
|
||||
|
||||
if (is_cmd_word) begin
|
||||
spi_cmd_word <= {rxbuf[6:0], sdi_clean};
|
||||
is_cmd_word <= 0;
|
||||
spi_cmd_active <= 1;
|
||||
spi_cmd_begin <= 1;
|
||||
spi_cmd_idx <= 0;
|
||||
|
||||
end else begin
|
||||
spi_data_out <= {rxbuf[6:0], sdi_clean};
|
||||
spi_cmd_idx <= spi_cmd_idx+1;
|
||||
spi_cmd_step <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
end else if (last_sck && !sck_clean) begin /* driving edge */
|
||||
if (load_data) begin
|
||||
sdo <= spi_data_in[7];
|
||||
txbuf <= spi_data_in[6:0];
|
||||
load_data <= 0;
|
||||
|
||||
end else begin
|
||||
sdo <= txbuf[6];
|
||||
txbuf <= {txbuf[5:0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
end else begin
|
||||
spi_cmd_active <= 0;
|
||||
is_cmd_word <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
192
src/symbol_dump.vhd
Normal file
192
src/symbol_dump.vhd
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: symbol_dump - Behavioral
|
||||
--
|
||||
-- Description: Create a trace of HDMI symbols - a 1024 word memory block is filled
|
||||
-- and then transmitted over rs232. Then refilled again, but this time
|
||||
-- waiting an extra 1024 cycles from when symbol_sync is asserted.
|
||||
--
|
||||
-- If the video source is paused, then the entire frame can be capbured
|
||||
-- (excluding ADP data periods, which might get broken on the boundary.
|
||||
--
|
||||
-- The captured data can then be analysed by hand or used to drive
|
||||
-- simulations.
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity symbol_dump is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
clk100 : in STD_LOGIC;
|
||||
symbol_sync : in STD_LOGIC;
|
||||
symbol_ch0 : in STD_LOGIC_VECTOR (9 downto 0);
|
||||
symbol_ch1 : in STD_LOGIC_VECTOR (9 downto 0);
|
||||
symbol_ch2 : in STD_LOGIC_VECTOR (9 downto 0);
|
||||
rs232_tx : out STD_LOGIC);
|
||||
end symbol_dump;
|
||||
|
||||
architecture Behavioral of symbol_dump is
|
||||
type array_hex is array(0 to 15) of std_logic_vector(9 downto 0);
|
||||
signal hex : array_hex := (
|
||||
"1001100000", "1001100010", "1001100100", "1001100110",
|
||||
"1001101000", "1001101010", "1001101100", "1001101110",
|
||||
"1001110000", "1001110010", "1010000010", "1010000100",
|
||||
"1010000110", "1010001000", "1010001010", "1010001100");
|
||||
|
||||
type array_memory is array(0 to 1023) of std_logic_vector(29 downto 0);
|
||||
signal memory : array_memory := (others => (others =>'0'));
|
||||
signal position : unsigned(23 downto 0) := (others => '0');
|
||||
signal capture_point : unsigned(23 downto 0) := (others => '0');
|
||||
signal write_address : unsigned(9 downto 0) := (others => '0');
|
||||
signal write_enable : std_logic := '0';
|
||||
signal write_data : std_logic_vector(29 downto 0) := (others => '0');
|
||||
|
||||
--- For signaling into the 100MHz domain
|
||||
signal ready_to_send : std_logic := '0';
|
||||
signal ready_to_send_meta : std_logic := '0';
|
||||
signal ready_to_send_synced : std_logic := '0';
|
||||
--- For signaling into the pixel clock domain
|
||||
signal sending_data : std_logic := '0';
|
||||
signal sending_data_meta : std_logic := '0';
|
||||
signal sending_data_synced : std_logic := '0';
|
||||
|
||||
signal rd_address : unsigned(9 downto 0) := (others => '0');
|
||||
signal rd_data : std_logic_vector(29 downto 0) := (others => '0');
|
||||
signal tx_data : std_logic_vector(89 downto 0) := (others => '1');
|
||||
signal tx_count : unsigned(7 downto 0) := (others => '0');
|
||||
signal baud_counter : unsigned(12 downto 0) := (others => '0');
|
||||
signal baud_counter_max : unsigned(12 downto 0) := to_unsigned(100000000/115200,13);
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if write_enable = '1' then
|
||||
memory(to_integer(write_address)) <= symbol_ch2 & symbol_ch1 & symbol_ch0;
|
||||
end if;
|
||||
-- track where we are in the frame.
|
||||
if symbol_sync = '1' then
|
||||
position <= (others => '0');
|
||||
else
|
||||
position <= position+1;
|
||||
end if;
|
||||
|
||||
-- If we are capturing remember where we have got up to
|
||||
-- and see if we have captured our full amount.
|
||||
if write_enable = '1' then
|
||||
capture_point <= position;
|
||||
write_data <= symbol_ch2 & symbol_ch1 & symbol_ch0;
|
||||
write_data <= symbol_ch2 & symbol_ch1 & symbol_ch0;
|
||||
if write_address = 1023 then
|
||||
write_enable <= '0';
|
||||
ready_to_send <= '1';
|
||||
end if;
|
||||
write_address <= write_address+1;
|
||||
end if;
|
||||
|
||||
-- Do we start capturing at this point?
|
||||
-- (write address resets itself to 0, so we don't
|
||||
-- have to do it here)
|
||||
if position = capture_point and ready_to_send = '0' and sending_data_synced = '0' then
|
||||
write_enable <= '1';
|
||||
end if;
|
||||
|
||||
-- Do we need to re-arm ready for the next capture
|
||||
if sending_data_synced = '1' then
|
||||
ready_to_send <= '0';
|
||||
end if;
|
||||
|
||||
|
||||
-- Bring data_sent into this clock domain
|
||||
sending_data_synced <= sending_data_meta;
|
||||
sending_data_meta <= sending_data;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clk100)
|
||||
begin
|
||||
if rising_edge(clk100) then
|
||||
|
||||
if baud_counter = 0 then
|
||||
rs232_tx <= tx_data(0);
|
||||
tx_data <= '1' & tx_data(89 downto 1);
|
||||
baud_counter <= baud_counter_max;
|
||||
if(tx_count > 0) then
|
||||
tx_count <= tx_count-1;
|
||||
end if;
|
||||
else
|
||||
baud_counter <= baud_counter -1;
|
||||
end if;
|
||||
|
||||
if sending_data = '1' or ready_to_send_synced = '1' then
|
||||
if tx_count = 0 then
|
||||
tx_data(89 downto 80) <= hex(to_integer(unsigned(rd_data( 3 downto 0))));
|
||||
tx_data(79 downto 70) <= hex(to_integer(unsigned(rd_data( 7 downto 4))));
|
||||
tx_data(69 downto 60) <= hex(to_integer(unsigned(rd_data(11 downto 8))));
|
||||
tx_data(59 downto 50) <= hex(to_integer(unsigned(rd_data(15 downto 12))));
|
||||
tx_data(49 downto 40) <= hex(to_integer(unsigned(rd_data(19 downto 16))));
|
||||
tx_data(39 downto 30) <= hex(to_integer(unsigned(rd_data(23 downto 20))));
|
||||
tx_data(29 downto 20) <= hex(to_integer(unsigned(rd_data(27 downto 24))));
|
||||
tx_data(19 downto 10) <= hex(to_integer(unsigned(rd_data(29 downto 28))));
|
||||
tx_data( 9 downto 0) <= "1000010100"; -- New line
|
||||
tx_count <= to_unsigned(90,8);
|
||||
|
||||
rd_data <= memory(to_integer(rd_address));
|
||||
rd_address <= rd_address+1;
|
||||
if rd_address = 1023 then
|
||||
sending_data <= '0';
|
||||
else
|
||||
sending_data <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Bring the ready to send signal into this clock domain
|
||||
ready_to_send_synced <= ready_to_send_meta;
|
||||
ready_to_send_meta <= ready_to_send;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
324
src/term_emu.v
Normal file
324
src/term_emu.v
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module term_emu(
|
||||
input clk, rst,
|
||||
|
||||
input in_byte_valid,
|
||||
input [7:0] in_byte,
|
||||
output reg in_byte_ack,
|
||||
|
||||
output reg glyph_buffer_w_valid,
|
||||
output reg [15:0] glyph_buffer_w_addr,
|
||||
output reg [19:0] glyph_buffer_w_data
|
||||
);
|
||||
|
||||
parameter GLYPHMEM_W = 256; /* glyphs */
|
||||
parameter GLYPHMEM_H = 128; /* glyphs */
|
||||
|
||||
localparam ST_PARSE_TEXT = 9'b000000001,
|
||||
ST_PARSE_ESC = 9'b000000010,
|
||||
ST_PARSE_CSI = 9'b000000100,
|
||||
ST_PARSE_SEP = 9'b000100000,
|
||||
ST_PARSE_INVAL = 9'b010000000;
|
||||
|
||||
|
||||
wire [15:0] glyph_buffer_w_addr_comp = (GLYPHMEM_W*glyph_y) + glyph_x;
|
||||
|
||||
reg [8:0] parser_state;
|
||||
reg [3:0] cur_fg;
|
||||
reg [3:0] cur_bg;
|
||||
reg cur_bold;
|
||||
reg cur_underline;
|
||||
localparam NUM_BUF_SZ = 8;
|
||||
reg [NUM_BUF_SZ*12-1:0] num_buf;
|
||||
wire [11:0] num_buf_last;
|
||||
assign num_buf_last = num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-1-11];
|
||||
reg [7:0] parser_action;
|
||||
reg parser_valid;
|
||||
reg [4:0] num_buf_idx;
|
||||
reg [9:0] glyph_x;
|
||||
reg [9:0] glyph_y;
|
||||
reg [11:0] csi_act_ctr;
|
||||
reg cursor_movement_x_pos;
|
||||
reg cursor_movement_x_neg;
|
||||
reg cursor_movement_y_pos;
|
||||
reg cursor_movement_y_neg;
|
||||
reg esc_inval;
|
||||
reg num_start;
|
||||
|
||||
always @(posedge clk) begin
|
||||
in_byte_ack <= 0;
|
||||
glyph_buffer_w_valid <= 0;
|
||||
|
||||
if (rst) begin
|
||||
parser_state <= ST_PARSE_TEXT;
|
||||
num_buf <= 0;
|
||||
parser_valid <= 0;
|
||||
parser_action <= 0;
|
||||
glyph_x <= 0;
|
||||
glyph_y <= 0;
|
||||
num_start <= 0;
|
||||
cur_fg <= 7;
|
||||
cur_bg <= 0;
|
||||
cur_bold <= 0;
|
||||
cur_underline <= 0;
|
||||
num_buf_idx <= 0;
|
||||
csi_act_ctr <= 0;
|
||||
esc_inval <= 0;
|
||||
cursor_movement_x_pos <= 0;
|
||||
cursor_movement_x_neg <= 0;
|
||||
cursor_movement_y_pos <= 0;
|
||||
cursor_movement_y_neg <= 0;
|
||||
|
||||
end else if (!parser_valid && in_byte_valid) begin
|
||||
in_byte_ack <= 1;
|
||||
|
||||
case (parser_state)
|
||||
(ST_PARSE_TEXT): begin
|
||||
if (in_byte == 8'h1b) begin /* \e */
|
||||
parser_state <= ST_PARSE_ESC;
|
||||
|
||||
end else if (in_byte == 8'h0a) begin /* \n */
|
||||
glyph_x <= 0;
|
||||
glyph_buffer_w_valid <= 1;
|
||||
glyph_buffer_w_data <= {1'b0, 1'b0, 2'b00, cur_bg, 4'b0000, in_byte};
|
||||
glyph_buffer_w_addr <= glyph_buffer_w_addr_comp;
|
||||
|
||||
if (glyph_y != GLYPHMEM_H-1) begin
|
||||
glyph_y <= glyph_y + 1;
|
||||
end
|
||||
|
||||
end else begin
|
||||
glyph_buffer_w_valid <= 1;
|
||||
glyph_buffer_w_data <= {cur_underline, cur_bold, 2'b00, cur_bg, cur_fg, in_byte};
|
||||
glyph_buffer_w_addr <= glyph_buffer_w_addr_comp;
|
||||
if (glyph_x != GLYPHMEM_W-1) begin
|
||||
glyph_x <= glyph_x + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
(ST_PARSE_ESC): begin
|
||||
if (in_byte == 8'h5b) begin /* [ */
|
||||
parser_state <= ST_PARSE_CSI;
|
||||
num_buf <= {{0}};
|
||||
num_start <= 1;
|
||||
|
||||
end else begin
|
||||
parser_state <= ST_PARSE_INVAL;
|
||||
end
|
||||
end
|
||||
|
||||
(ST_PARSE_CSI), (ST_PARSE_SEP): begin
|
||||
if (in_byte >= 8'h30 && in_byte <= 8'h39) begin /* 0-9 */
|
||||
if (num_start) begin
|
||||
num_start <= 0;
|
||||
num_buf <= {num_buf[NUM_BUF_SZ*12-1:12], 8'hff, ~in_byte[3:0]};
|
||||
end else begin
|
||||
num_buf <= {num_buf[NUM_BUF_SZ*12-1:12], num_buf[7:0], ~in_byte[3:0]};
|
||||
end
|
||||
parser_state = ST_PARSE_CSI;
|
||||
|
||||
end else if (in_byte == 8'h3b) begin /* ; */
|
||||
num_buf <= {num_buf[NUM_BUF_SZ*12-1-12:0], 12'hfff};
|
||||
parser_state <= ST_PARSE_SEP;
|
||||
num_start <= 1;
|
||||
|
||||
end else if (in_byte >= 8'h40 && in_byte <= 8'h7e) begin
|
||||
parser_action <= in_byte;
|
||||
parser_valid <= 1;
|
||||
num_buf_idx <= 0;
|
||||
esc_inval <= 0;
|
||||
csi_act_ctr <= 0;
|
||||
cursor_movement_x_pos <= 0;
|
||||
cursor_movement_x_neg <= 0;
|
||||
cursor_movement_y_pos <= 0;
|
||||
cursor_movement_y_neg <= 0;
|
||||
parser_state <= ST_PARSE_TEXT;
|
||||
|
||||
end else begin
|
||||
parser_state <= ST_PARSE_INVAL;
|
||||
end
|
||||
end
|
||||
|
||||
(ST_PARSE_INVAL): begin
|
||||
if (in_byte >= 8'h40 && in_byte <= 8'h7e) begin
|
||||
parser_state <= ST_PARSE_TEXT;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
end else if (parser_valid) begin
|
||||
if (cursor_movement_x_pos || cursor_movement_x_neg || cursor_movement_y_pos || cursor_movement_y_neg) begin
|
||||
csi_act_ctr <= bcd12_inc(csi_act_ctr);
|
||||
|
||||
if (csi_act_ctr != ~num_buf_last) begin
|
||||
if (cursor_movement_x_pos) begin
|
||||
if (glyph_x != GLYPHMEM_W-1) glyph_x <= glyph_x + 1;
|
||||
end else if (cursor_movement_x_neg) begin
|
||||
if (glyph_x != 0) glyph_x <= glyph_x - 1;
|
||||
end else if (cursor_movement_y_pos) begin
|
||||
if (glyph_y != GLYPHMEM_H-1) glyph_y <= glyph_y + 1;
|
||||
end else if (cursor_movement_y_neg) begin
|
||||
if (glyph_y != 0) glyph_y <= glyph_y - 1;
|
||||
end
|
||||
end
|
||||
|
||||
if (num_buf_last == 0 || ~num_buf_last == 12'h001 || csi_act_ctr == ~num_buf_last) begin
|
||||
if (cursor_movement_x_pos && cursor_movement_y_pos) begin
|
||||
num_buf <= {num_buf[NUM_BUF_SZ*12-1-12:0], 12'h000};
|
||||
cursor_movement_x_pos <= 0;
|
||||
end else begin
|
||||
parser_valid <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
end else if (parser_action == 8'h41 && !esc_inval) begin /* A; Cursor up */
|
||||
cursor_movement_y_neg <= 1;
|
||||
num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0];
|
||||
|
||||
end else if (parser_action == 8'h42 && !esc_inval) begin /* B; Cursor down */
|
||||
cursor_movement_y_pos <= 1;
|
||||
num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0];
|
||||
|
||||
end else if (parser_action == 8'h43 && !esc_inval) begin /* C; Cursor forward */
|
||||
cursor_movement_x_pos <= 1;
|
||||
num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0];
|
||||
|
||||
end else if (parser_action == 8'h44 && !esc_inval) begin /* D; Cursor back */
|
||||
cursor_movement_x_neg <= 1;
|
||||
num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0];
|
||||
|
||||
end else if (parser_action == 8'h45 && !esc_inval) begin /* E; Cursor next line */
|
||||
glyph_x <= 0;
|
||||
cursor_movement_y_pos <= 1;
|
||||
num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0];
|
||||
|
||||
end else if (parser_action == 8'h46 && !esc_inval) begin /* F: Cursor previous line */
|
||||
glyph_x <= 0;
|
||||
cursor_movement_y_neg <= 1;
|
||||
num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0];
|
||||
|
||||
end else if (parser_action == 8'h47 && !esc_inval) begin /* G: Cursor horizontal absolute */
|
||||
glyph_x <= 0;
|
||||
num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0];
|
||||
if (num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] != 0) begin
|
||||
cursor_movement_x_pos <= 1;
|
||||
end else begin
|
||||
parser_valid <= 0;
|
||||
end
|
||||
|
||||
end else if (parser_action == 8'h48 && !esc_inval) begin /* H: Cursor x/y absolute */
|
||||
glyph_x <= 0;
|
||||
glyph_y <= 0;
|
||||
num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-24] <= num_buf[23:0];
|
||||
if (num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] != 0) begin
|
||||
cursor_movement_x_pos <= 1;
|
||||
cursor_movement_y_pos <= 1;
|
||||
end else begin
|
||||
parser_valid <= 0;
|
||||
end
|
||||
|
||||
end else if (parser_action == 8'h6d && !esc_inval) begin /* m; CSI SGR */
|
||||
if (num_buf_idx == NUM_BUF_SZ-1) begin
|
||||
parser_valid <= 0;
|
||||
end
|
||||
|
||||
case (~num_buf_last)
|
||||
(12'h000): begin /* reset */
|
||||
cur_fg <= 7;
|
||||
cur_bg <= 0;
|
||||
cur_bold <= 0;
|
||||
cur_underline <= 0;
|
||||
end
|
||||
(12'h001): begin /* bold */
|
||||
cur_bold <= 1;
|
||||
end
|
||||
(12'h004): begin /* underlined */
|
||||
cur_underline <= 1;
|
||||
end
|
||||
(12'h007): begin /* reverse video */
|
||||
cur_fg = cur_bg;
|
||||
cur_bg = cur_fg;
|
||||
end
|
||||
(12'h022): begin /* not bold */
|
||||
cur_bold <= 0;
|
||||
end
|
||||
(12'h024): begin /* not underlined */
|
||||
cur_underline <= 0;
|
||||
end
|
||||
|
||||
(12'h030): cur_fg <= 0;
|
||||
(12'h031): cur_fg <= 1;
|
||||
(12'h032): cur_fg <= 2;
|
||||
(12'h033): cur_fg <= 3;
|
||||
(12'h034): cur_fg <= 4;
|
||||
(12'h035): cur_fg <= 5;
|
||||
(12'h036): cur_fg <= 6;
|
||||
(12'h037): cur_fg <= 7;
|
||||
(12'h038): esc_inval <= 1;
|
||||
(12'h039): cur_fg <= 7;
|
||||
|
||||
(12'h040): cur_bg <= 0;
|
||||
(12'h041): cur_bg <= 1;
|
||||
(12'h042): cur_bg <= 2;
|
||||
(12'h043): cur_bg <= 3;
|
||||
(12'h044): cur_bg <= 4;
|
||||
(12'h045): cur_bg <= 5;
|
||||
(12'h046): cur_bg <= 6;
|
||||
(12'h047): cur_bg <= 7;
|
||||
(12'h048): esc_inval <= 1;
|
||||
(12'h049): cur_bg <= 0;
|
||||
|
||||
(12'h090): cur_fg <= 8;
|
||||
(12'h091): cur_fg <= 9;
|
||||
(12'h092): cur_fg <= 10;
|
||||
(12'h093): cur_fg <= 11;
|
||||
(12'h094): cur_fg <= 12;
|
||||
(12'h095): cur_fg <= 13;
|
||||
(12'h096): cur_fg <= 14;
|
||||
(12'h097): cur_fg <= 15;
|
||||
|
||||
(12'h100): cur_bg <= 8;
|
||||
(12'h101): cur_bg <= 9;
|
||||
(12'h102): cur_bg <= 10;
|
||||
(12'h103): cur_bg <= 11;
|
||||
(12'h104): cur_bg <= 12;
|
||||
(12'h105): cur_bg <= 13;
|
||||
(12'h106): cur_bg <= 14;
|
||||
(12'h107): cur_bg <= 15;
|
||||
/* (12'hfff): ignore! */
|
||||
endcase
|
||||
|
||||
num_buf_idx <= num_buf_idx + 1;
|
||||
num_buf <= {num_buf[NUM_BUF_SZ*12-1-12:0], 12'h000};
|
||||
|
||||
end else begin
|
||||
parser_valid <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function [11:0] bcd12_inc;
|
||||
input [11:0] in;
|
||||
begin
|
||||
bcd12_inc = in;
|
||||
if (in[3:0] != 4'h9) begin
|
||||
bcd12_inc[3:0] = in[3:0]+1;
|
||||
end else begin
|
||||
bcd12_inc[3:0] = 4'h0;
|
||||
if (in[7:4] != 4'h9) begin
|
||||
bcd12_inc[7:4] = in[7:4] + 1;
|
||||
end else begin
|
||||
bcd12_inc[7:4] = 0;
|
||||
if (in[11:8] != 4'h9) begin
|
||||
bcd12_inc[11:8] = in[11:8] + 1;
|
||||
end else begin
|
||||
bcd12_inc[11:8] = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
endmodule
|
||||
168
src/term_renderer.v
Normal file
168
src/term_renderer.v
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module term_renderer(
|
||||
input rst, clk,
|
||||
|
||||
input in_blank, in_vsync, in_hsync,
|
||||
|
||||
input [19:0] glyphmem_data,
|
||||
output [15:0] glyphmem_r_addr,
|
||||
|
||||
output out_hsync, out_vsync,
|
||||
output [7:0] out_red,
|
||||
output [7:0] out_green,
|
||||
output [7:0] out_blue
|
||||
);
|
||||
|
||||
parameter GLYPHMEM_W = 256; /* glyphs */
|
||||
parameter GLYPHMEM_H = 128; /* glyphs */
|
||||
|
||||
/* Glyph table instantiation */
|
||||
`include "gen/gen_font_params_default.vh"
|
||||
localparam FONT_GLYPH_W = `GEN_FONT_GLYPH_W_default;
|
||||
localparam FONT_GLYPH_H = `GEN_FONT_GLYPH_H_default;
|
||||
localparam FONT_GLYPH_COUNT = `GEN_FONT_GLYPH_COUNT_default;
|
||||
reg [FONT_GLYPH_W-1:0] glyph_table_default [0:FONT_GLYPH_COUNT*FONT_GLYPH_H-1];
|
||||
/* This is the dumbest thing, but it seems vivado is just *that* stupid. */
|
||||
`ifdef SYNTHESIS
|
||||
initial $readmemh("../../src/gen/gen_glyphtable_default.hex", glyph_table_default);
|
||||
`else
|
||||
initial $readmemh("../../../../src/gen/gen_glyphtable_default.hex", glyph_table_default);
|
||||
`endif
|
||||
|
||||
`include "gen/gen_font_params_bold.vh"
|
||||
/* NOTE: Bold font must have same glyph w/h, glyph count as regular font above */
|
||||
reg [FONT_GLYPH_W-1:0] glyph_table_bold [0:FONT_GLYPH_COUNT*FONT_GLYPH_H-1];
|
||||
`ifdef SYNTHESIS
|
||||
initial $readmemh("../../src/gen/gen_glyphtable_bold.hex", glyph_table_bold);
|
||||
`else
|
||||
initial $readmemh("../../../../src/gen/gen_glyphtable_bold.hex", glyph_table_bold);
|
||||
`endif
|
||||
|
||||
/* Color palette */
|
||||
function [23:0] color_palette;
|
||||
input [3:0] index;
|
||||
begin
|
||||
/* Peppermint color palette: https://noahfrederick.com/log/lion-terminal-theme-peppermint */
|
||||
case (index)
|
||||
default: color_palette = 24'h353535;
|
||||
(1): color_palette = 24'he64569;
|
||||
(2): color_palette = 24'h89d287;
|
||||
(3): color_palette = 24'hdab752;
|
||||
(4): color_palette = 24'h439ecf;
|
||||
(5): color_palette = 24'hd961dc;
|
||||
(6): color_palette = 24'h64aaaf;
|
||||
(7): color_palette = 24'hb3b3b3;
|
||||
(8): color_palette = 24'h535353;
|
||||
(9): color_palette = 24'he4859a;
|
||||
(10): color_palette = 24'ha2cca1;
|
||||
(11): color_palette = 24'he1e387;
|
||||
(12): color_palette = 24'h6fbbe2;
|
||||
(13): color_palette = 24'he586e7;
|
||||
(14): color_palette = 24'h96dcda;
|
||||
(15): color_palette = 24'hdedede;
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
|
||||
/* Glyph x/y synchronization logic */
|
||||
reg [11:0] glyph_x;
|
||||
reg [11:0] glyph_y;
|
||||
reg [FONT_GLYPH_W-1:0] glyph_sreg_out;
|
||||
reg [5:0] px_x;
|
||||
reg [5:0] px_y;
|
||||
reg in_hsync_last, in_vsync_last, in_blank_last;
|
||||
|
||||
wire [7:0] gm_data_glyph = glyphmem_data[7:0];
|
||||
wire [11:0] gm_data_style = glyphmem_data[19:8];
|
||||
reg [11:0] glyphmem_style_reg;
|
||||
wire [3:0] gm_data_fgcolor = glyphmem_style_reg[3:0];
|
||||
wire [3:0] gm_data_bgcolor = glyphmem_style_reg[7:4];
|
||||
reg [3:0] last_bgcolor;
|
||||
wire gm_data_bold = gm_data_style[10];
|
||||
wire gm_data_underline = glyphmem_style_reg[11] && !newline_found;
|
||||
reg newline_found;
|
||||
|
||||
assign out_vsync = in_vsync_last;
|
||||
assign out_hsync = in_hsync_last;
|
||||
|
||||
assign glyphmem_r_addr = (GLYPHMEM_W*glyph_y) + glyph_x;
|
||||
wire px_data = glyph_sreg_out[FONT_GLYPH_W-1] || (gm_data_underline && px_y == FONT_GLYPH_H-2);
|
||||
assign {out_red, out_green, out_blue} = color_palette(newline_found ? last_bgcolor : (px_data ? gm_data_fgcolor : gm_data_bgcolor));
|
||||
|
||||
/* Core logic */
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
glyph_x <= 0;
|
||||
glyph_y <= 0;
|
||||
px_x <= 0;
|
||||
px_y <= 0;
|
||||
in_hsync_last <= 0;
|
||||
in_vsync_last <= 0;
|
||||
in_blank_last <= 0;
|
||||
glyph_sreg_out <= 0;
|
||||
glyphmem_style_reg <= 0;
|
||||
newline_found <= 0;
|
||||
|
||||
end else begin
|
||||
in_hsync_last <= in_hsync;
|
||||
in_vsync_last <= in_vsync;
|
||||
in_blank_last <= in_blank;
|
||||
|
||||
if (!in_blank_last && in_blank) begin
|
||||
glyph_x <= 0;
|
||||
px_x <= 0;
|
||||
newline_found <= 0;
|
||||
|
||||
if (px_y != FONT_GLYPH_H-1) begin
|
||||
px_y <= px_y + 1;
|
||||
end else begin
|
||||
glyph_y <= glyph_y + 1;
|
||||
px_y <= 0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (!in_blank) begin
|
||||
if (px_x != FONT_GLYPH_W-1) begin
|
||||
px_x <= px_x + 1;
|
||||
|
||||
end else begin
|
||||
px_x <= 0;
|
||||
end
|
||||
|
||||
if (px_x == 0) begin
|
||||
if (newline_found) begin
|
||||
glyph_sreg_out <= 0;
|
||||
end else if (gm_data_bold) begin
|
||||
glyph_sreg_out <= glyph_table_bold[gm_data_glyph*FONT_GLYPH_H + px_y];
|
||||
end else begin
|
||||
glyph_sreg_out <= glyph_table_default[gm_data_glyph*FONT_GLYPH_H + px_y];
|
||||
end
|
||||
|
||||
glyphmem_style_reg <= gm_data_style;
|
||||
glyph_x <= glyph_x + 1;
|
||||
|
||||
if (!newline_found && gm_data_glyph == 8'h0a) begin /* Newline character */
|
||||
newline_found <= 1;
|
||||
last_bgcolor <= gm_data_bgcolor;
|
||||
end
|
||||
|
||||
end else begin
|
||||
glyph_sreg_out <= {glyph_sreg_out[FONT_GLYPH_W-2:0], 1'b0};
|
||||
end
|
||||
|
||||
end else if (!in_hsync_last) begin
|
||||
glyph_sreg_out <= 0;
|
||||
glyphmem_style_reg <= 0;
|
||||
end
|
||||
|
||||
if (in_vsync_last && !in_vsync) begin
|
||||
glyph_y <= 0;
|
||||
px_y <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
915
src/tmds_decoder.vhd
Normal file
915
src/tmds_decoder.vhd
Normal file
|
|
@ -0,0 +1,915 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Create Date: 10.07.2015 20:06:49
|
||||
-- Design Name:
|
||||
-- Module Name: TMDS_decoder - Behavioral
|
||||
--
|
||||
-- Description: Decoding for TMDS encoded symbols. This performs the conversion
|
||||
-- using a table lookup for simplicity
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity TMDS_decoder is
|
||||
Port ( clk : in std_logic;
|
||||
symbol : in std_logic_vector (9 downto 0);
|
||||
invalid_symbol : out std_logic;
|
||||
|
||||
ctl_valid : out std_logic;
|
||||
ctl : out std_logic_vector (1 downto 0);
|
||||
|
||||
terc4_valid : out std_logic;
|
||||
terc4 : out std_logic_vector (3 downto 0);
|
||||
|
||||
guardband_valid : out std_logic;
|
||||
guardband : out std_logic_vector (0 downto 0);
|
||||
|
||||
data_valid : out std_logic;
|
||||
data : out std_logic_vector (7 downto 0));
|
||||
end TMDS_decoder;
|
||||
|
||||
architecture Behavioral of TMDS_decoder is
|
||||
signal lookup : std_logic_vector (8 downto 0);
|
||||
begin
|
||||
|
||||
decode_ctl: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
------------------
|
||||
-- TMDS data bytes
|
||||
if lookup(8) = '1' then
|
||||
data_valid <= '1';
|
||||
data <= lookup(7 downto 0);
|
||||
else
|
||||
data_valid <= '0';
|
||||
end if;
|
||||
|
||||
------------
|
||||
-- CTL codes
|
||||
if lookup(8 downto 7) = "01" then
|
||||
ctl_valid <= '1';
|
||||
ctl <= lookup(1 downto 0);
|
||||
else
|
||||
ctl_valid <= '0';
|
||||
end if;
|
||||
|
||||
------------------------------
|
||||
-- All other codes are invalid
|
||||
------------------------------
|
||||
if lookup(8 downto 7) = "00" then
|
||||
invalid_symbol <= '1';
|
||||
else
|
||||
invalid_symbol <= '0';
|
||||
end if;
|
||||
|
||||
terc4_valid <= '0';
|
||||
guardband_valid <= '0';
|
||||
if lookup(8) = '1' then
|
||||
-------------------------
|
||||
-- Decode the guard bands
|
||||
-------------------------
|
||||
case lookup(7 downto 0) is
|
||||
when x"55" => guardband_valid <= '1'; guardband <= "0";
|
||||
when x"AB" => guardband_valid <= '1'; guardband <= "1";
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
-------------------------
|
||||
-- Decode TERC4 data
|
||||
-------------------------
|
||||
case lookup(7 downto 0) is
|
||||
when x"5B" => terc4_valid <= '1'; terc4 <= "0000";-- "1010011100" TERC4 0000
|
||||
when x"5A" => terc4_valid <= '1'; terc4 <= "0001"; -- "1001100011" TERC4 0001
|
||||
when x"D3" => terc4_valid <= '1'; terc4 <= "0010"; -- "1011100100" TERC4 0010
|
||||
when x"D9" => terc4_valid <= '1'; terc4 <= "0011"; -- "1011100010" TERC4 0011
|
||||
when x"93" => terc4_valid <= '1'; terc4 <= "0100"; -- "0101110001" TERC4 0100
|
||||
when x"22" => terc4_valid <= '1'; terc4 <= "0101"; -- "0100011110" TERC4 0101
|
||||
when x"92" => terc4_valid <= '1'; terc4 <= "0110"; -- "0110001110" TERC4 0110
|
||||
when x"44" => terc4_valid <= '1'; terc4 <= "0111"; -- "0100111100" TERC4 0111
|
||||
when x"AB" => terc4_valid <= '1'; terc4 <= "1000"; -- "1011001100" TERC4 1000 & HDMI Guard band (video C0 and Video C2)
|
||||
when x"4B" => terc4_valid <= '1'; terc4 <= "1001"; -- "0100111001" TERC4 1001
|
||||
when x"A4" => terc4_valid <= '1'; terc4 <= "1010"; -- "0110011100" TERC4 1010
|
||||
when x"B5" => terc4_valid <= '1'; terc4 <= "1011"; -- "1011000110" TERC4 1011
|
||||
when x"6D" => terc4_valid <= '1'; terc4 <= "1100"; -- "1010001110" TERC4 1100
|
||||
when x"6C" => terc4_valid <= '1'; terc4 <= "1101"; -- "1001110001" TERC4 1101
|
||||
when x"A5" => terc4_valid <= '1'; terc4 <= "1110"; -- "0101100011" TERC4 1110
|
||||
when x"BA" => terc4_valid <= '1'; terc4 <= "1111"; -- "1011000011" TERC4 1111
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Convert the incoming signal to something we can decode
|
||||
--
|
||||
-- For data symbols
|
||||
-- ----------------
|
||||
-- bit 8 - 1 -- Data word flage
|
||||
-- bits 7:0 - xxxxxxxx - Data value
|
||||
--
|
||||
-- For CTL symbols
|
||||
-- ---------------
|
||||
-- bit 8 - 0 - Data word flage
|
||||
-- bit 7 - 1 - CTL Indicator
|
||||
-- bits 6:2 - X - Ignored
|
||||
-- bits 1:0 - xx - CTL value
|
||||
--
|
||||
-- For Invalid symbols
|
||||
-- -------------------
|
||||
-- bit 8 - 0 - Data word flage
|
||||
-- bit 7 - 0 - TERC4 Inicated
|
||||
-- bit 6 - 0 - CTL Indicator
|
||||
-- bit 5 - 0 - Guard band indicator
|
||||
-- bits 4:0 - X - Unused
|
||||
--
|
||||
-------------------------------------------------------------
|
||||
case symbol is
|
||||
-- DVI-D Data sybmols
|
||||
-- Data 00
|
||||
when "1111111111" => lookup <= "100000000";
|
||||
when "0100000000" => lookup <= "100000000";
|
||||
-- Data 01
|
||||
when "0111111111" => lookup <= "100000001";
|
||||
when "1100000000" => lookup <= "100000001";
|
||||
-- Data 02
|
||||
when "0111111110" => lookup <= "100000010";
|
||||
when "1100000001" => lookup <= "100000010";
|
||||
-- Data 03
|
||||
when "1111111110" => lookup <= "100000011";
|
||||
when "0100000001" => lookup <= "100000011";
|
||||
-- Data 04
|
||||
when "0111111100" => lookup <= "100000100";
|
||||
when "1100000011" => lookup <= "100000100";
|
||||
-- Data 05
|
||||
when "1111111100" => lookup <= "100000101";
|
||||
when "0100000011" => lookup <= "100000101";
|
||||
-- Data 06
|
||||
when "1111111101" => lookup <= "100000110";
|
||||
when "0100000010" => lookup <= "100000110";
|
||||
-- Data 07
|
||||
when "0111111101" => lookup <= "100000111";
|
||||
when "1100000010" => lookup <= "100000111";
|
||||
-- Data 08
|
||||
when "0111111000" => lookup <= "100001000";
|
||||
when "1100000111" => lookup <= "100001000";
|
||||
-- Data 09
|
||||
when "1111111000" => lookup <= "100001001";
|
||||
when "0100000111" => lookup <= "100001001";
|
||||
-- Data 0a
|
||||
when "1111111001" => lookup <= "100001010";
|
||||
when "0100000110" => lookup <= "100001010";
|
||||
-- Data 0b
|
||||
when "0111111001" => lookup <= "100001011";
|
||||
when "1100000110" => lookup <= "100001011";
|
||||
-- Data 0c
|
||||
when "1111111011" => lookup <= "100001100";
|
||||
when "0100000100" => lookup <= "100001100";
|
||||
-- Data 0d
|
||||
when "0111111011" => lookup <= "100001101";
|
||||
when "1100000100" => lookup <= "100001101";
|
||||
-- Data 0e
|
||||
when "0111111010" => lookup <= "100001110";
|
||||
when "1100000101" => lookup <= "100001110";
|
||||
-- Data 0f
|
||||
when "1111111010" => lookup <= "100001111";
|
||||
when "0100000101" => lookup <= "100001111";
|
||||
-- Data 10
|
||||
when "0111110000" => lookup <= "100010000";
|
||||
-- Data 11
|
||||
when "0100001111" => lookup <= "100010001";
|
||||
-- Data 12
|
||||
when "1111110001" => lookup <= "100010010";
|
||||
when "0100001110" => lookup <= "100010010";
|
||||
-- Data 13
|
||||
when "0111110001" => lookup <= "100010011";
|
||||
when "1100001110" => lookup <= "100010011";
|
||||
-- Data 14
|
||||
when "1111110011" => lookup <= "100010100";
|
||||
when "0100001100" => lookup <= "100010100";
|
||||
-- Data 15
|
||||
when "0111110011" => lookup <= "100010101";
|
||||
when "1100001100" => lookup <= "100010101";
|
||||
-- Data 16
|
||||
when "0111110010" => lookup <= "100010110";
|
||||
when "1100001101" => lookup <= "100010110";
|
||||
-- Data 17
|
||||
when "1111110010" => lookup <= "100010111";
|
||||
when "0100001101" => lookup <= "100010111";
|
||||
-- Data 18
|
||||
when "1111110111" => lookup <= "100011000";
|
||||
when "0100001000" => lookup <= "100011000";
|
||||
-- Data 19
|
||||
when "0111110111" => lookup <= "100011001";
|
||||
when "1100001000" => lookup <= "100011001";
|
||||
-- Data 1a
|
||||
when "0111110110" => lookup <= "100011010";
|
||||
when "1100001001" => lookup <= "100011010";
|
||||
-- Data 1b
|
||||
when "1111110110" => lookup <= "100011011";
|
||||
when "0100001001" => lookup <= "100011011";
|
||||
-- Data 1c
|
||||
when "0111110100" => lookup <= "100011100";
|
||||
when "1100001011" => lookup <= "100011100";
|
||||
-- Data 1d
|
||||
when "1111110100" => lookup <= "100011101";
|
||||
when "0100001011" => lookup <= "100011101";
|
||||
-- Data 1e
|
||||
when "1001011111" => lookup <= "100011110";
|
||||
when "0010100000" => lookup <= "100011110";
|
||||
-- Data 1f
|
||||
when "0001011111" => lookup <= "100011111";
|
||||
when "1010100000" => lookup <= "100011111";
|
||||
-- Data 20
|
||||
when "1100011111" => lookup <= "100100000";
|
||||
when "0111100000" => lookup <= "100100000";
|
||||
-- Data 21
|
||||
when "0100011111" => lookup <= "100100001";
|
||||
when "1111100000" => lookup <= "100100001";
|
||||
-- Data 22
|
||||
when "0100011110" => lookup <= "100100010"; -- TERC4 0101
|
||||
-- Data 23
|
||||
when "0111100001" => lookup <= "100100011";
|
||||
-- Data 24
|
||||
when "1111100011" => lookup <= "100100100";
|
||||
when "0100011100" => lookup <= "100100100";
|
||||
-- Data 25
|
||||
when "0111100011" => lookup <= "100100101";
|
||||
when "1100011100" => lookup <= "100100101";
|
||||
-- Data 26
|
||||
when "0111100010" => lookup <= "100100110";
|
||||
-- Data 27
|
||||
when "0100011101" => lookup <= "100100111";
|
||||
-- Data 28
|
||||
when "1111100111" => lookup <= "100101000";
|
||||
when "0100011000" => lookup <= "100101000";
|
||||
-- Data 29
|
||||
when "0111100111" => lookup <= "100101001";
|
||||
when "1100011000" => lookup <= "100101001";
|
||||
-- Data 2a
|
||||
when "0111100110" => lookup <= "100101010";
|
||||
when "1100011001" => lookup <= "100101010";
|
||||
-- Data 2b
|
||||
when "1111100110" => lookup <= "100101011";
|
||||
when "0100011001" => lookup <= "100101011";
|
||||
-- Data 2c
|
||||
when "0111100100" => lookup <= "100101100";
|
||||
-- Data 2d
|
||||
when "0100011011" => lookup <= "100101101";
|
||||
-- Data 2e
|
||||
when "1001001111" => lookup <= "100101110";
|
||||
when "0010110000" => lookup <= "100101110";
|
||||
-- Data 2f
|
||||
when "0001001111" => lookup <= "100101111";
|
||||
when "1010110000" => lookup <= "100101111";
|
||||
-- Data 30
|
||||
when "1111101111" => lookup <= "100110000";
|
||||
when "0100010000" => lookup <= "100110000";
|
||||
-- Data 31
|
||||
when "0111101111" => lookup <= "100110001";
|
||||
when "1100010000" => lookup <= "100110001";
|
||||
-- Data 32
|
||||
when "0111101110" => lookup <= "100110010";
|
||||
when "1100010001" => lookup <= "100110010";
|
||||
-- Data 33
|
||||
when "1111101110" => lookup <= "100110011";
|
||||
when "0100010001" => lookup <= "100110011";
|
||||
-- Data 34
|
||||
when "0111101100" => lookup <= "100110100";
|
||||
when "1100010011" => lookup <= "100110100";
|
||||
-- Data 35
|
||||
when "1111101100" => lookup <= "100110101";
|
||||
when "0100010011" => lookup <= "100110101";
|
||||
-- Data 36
|
||||
when "1001000111" => lookup <= "100110110";
|
||||
-- Data 37
|
||||
when "1010111000" => lookup <= "100110111";
|
||||
-- Data 38
|
||||
when "0111101000" => lookup <= "100111000";
|
||||
-- Data 39
|
||||
when "0100010111" => lookup <= "100111001";
|
||||
-- Data 3a
|
||||
when "0010111100" => lookup <= "100111010";
|
||||
when "1001000011" => lookup <= "100111010";
|
||||
-- Data 3b
|
||||
when "1010111100" => lookup <= "100111011";
|
||||
when "0001000011" => lookup <= "100111011";
|
||||
-- Data 3c
|
||||
when "0010111110" => lookup <= "100111100";
|
||||
when "1001000001" => lookup <= "100111100";
|
||||
-- Data 3d
|
||||
when "1010111110" => lookup <= "100111101";
|
||||
when "0001000001" => lookup <= "100111101";
|
||||
-- Data 3e
|
||||
when "1010111111" => lookup <= "100111110";
|
||||
when "0001000000" => lookup <= "100111110";
|
||||
-- Data 3f
|
||||
when "0010111111" => lookup <= "100111111";
|
||||
when "1001000000" => lookup <= "100111111";
|
||||
-- Data 40
|
||||
when "1100111111" => lookup <= "101000000";
|
||||
when "0111000000" => lookup <= "101000000";
|
||||
-- Data 41
|
||||
when "0100111111" => lookup <= "101000001";
|
||||
when "1111000000" => lookup <= "101000001";
|
||||
-- Data 42
|
||||
when "0100111110" => lookup <= "101000010";
|
||||
when "1111000001" => lookup <= "101000010";
|
||||
-- Data 43
|
||||
when "1100111110" => lookup <= "101000011";
|
||||
when "0111000001" => lookup <= "101000011";
|
||||
-- Data 44
|
||||
when "0100111100" => lookup <= "101000100"; -- TERC4 0111
|
||||
-- Data 45
|
||||
when "0111000011" => lookup <= "101000101";
|
||||
-- Data 46
|
||||
when "1100111101" => lookup <= "101000110";
|
||||
when "0111000010" => lookup <= "101000110";
|
||||
-- Data 47
|
||||
when "0100111101" => lookup <= "101000111";
|
||||
when "1111000010" => lookup <= "101000111";
|
||||
-- Data 48
|
||||
when "1111000111" => lookup <= "101001000";
|
||||
when "0100111000" => lookup <= "101001000";
|
||||
-- Data 49
|
||||
when "0111000111" => lookup <= "101001001";
|
||||
when "1100111000" => lookup <= "101001001";
|
||||
-- Data 4a
|
||||
when "0111000110" => lookup <= "101001010";
|
||||
-- Data 4b
|
||||
when "0100111001" => lookup <= "101001011"; -- TERC4 1001
|
||||
-- Data 4c
|
||||
when "1100111011" => lookup <= "101001100";
|
||||
when "0111000100" => lookup <= "101001100";
|
||||
-- Data 4d
|
||||
when "0100111011" => lookup <= "101001101";
|
||||
when "1111000100" => lookup <= "101001101";
|
||||
-- Data 4e
|
||||
when "1001101111" => lookup <= "101001110";
|
||||
when "0010010000" => lookup <= "101001110";
|
||||
-- Data 4f
|
||||
when "0001101111" => lookup <= "101001111";
|
||||
when "1010010000" => lookup <= "101001111";
|
||||
-- Data 50
|
||||
when "1111001111" => lookup <= "101010000";
|
||||
when "0100110000" => lookup <= "101010000";
|
||||
-- Data 51
|
||||
when "0111001111" => lookup <= "101010001";
|
||||
when "1100110000" => lookup <= "101010001";
|
||||
-- Data 52
|
||||
when "0111001110" => lookup <= "101010010";
|
||||
when "1100110001" => lookup <= "101010010";
|
||||
-- Data 53
|
||||
when "1111001110" => lookup <= "101010011";
|
||||
when "0100110001" => lookup <= "101010011";
|
||||
-- Data 54
|
||||
when "0111001100" => lookup <= "101010100";
|
||||
-- Data 55
|
||||
when "0100110011" => lookup <= "101010101"; -- HDMI Guard band (video C1, data C1 & C2)
|
||||
-- Data 56
|
||||
when "1001100111" => lookup <= "101010110";
|
||||
when "0010011000" => lookup <= "101010110";
|
||||
-- Data 57
|
||||
when "0001100111" => lookup <= "101010111";
|
||||
when "1010011000" => lookup <= "101010111";
|
||||
-- Data 58
|
||||
when "1100110111" => lookup <= "101011000";
|
||||
when "0111001000" => lookup <= "101011000";
|
||||
-- Data 59
|
||||
when "0100110111" => lookup <= "101011001";
|
||||
when "1111001000" => lookup <= "101011001";
|
||||
-- Data 5a
|
||||
when "1001100011" => lookup <= "101011010"; -- TERC4 0001
|
||||
-- Data 5b
|
||||
when "1010011100" => lookup <= "101011011"; -- TERC4 0000
|
||||
-- Data 5c
|
||||
when "0010011110" => lookup <= "101011100";
|
||||
when "1001100001" => lookup <= "101011100";
|
||||
-- Data 5d
|
||||
when "1010011110" => lookup <= "101011101";
|
||||
when "0001100001" => lookup <= "101011101";
|
||||
-- Data 5e
|
||||
when "1010011111" => lookup <= "101011110";
|
||||
when "0001100000" => lookup <= "101011110";
|
||||
-- Data 5f
|
||||
when "0010011111" => lookup <= "101011111";
|
||||
when "1001100000" => lookup <= "101011111";
|
||||
-- Data 60
|
||||
when "1111011111" => lookup <= "101100000";
|
||||
when "0100100000" => lookup <= "101100000";
|
||||
-- Data 61
|
||||
when "0111011111" => lookup <= "101100001";
|
||||
when "1100100000" => lookup <= "101100001";
|
||||
-- Data 62
|
||||
when "0111011110" => lookup <= "101100010";
|
||||
when "1100100001" => lookup <= "101100010";
|
||||
-- Data 63
|
||||
when "1111011110" => lookup <= "101100011";
|
||||
when "0100100001" => lookup <= "101100011";
|
||||
-- Data 64
|
||||
when "0111011100" => lookup <= "101100100";
|
||||
when "1100100011" => lookup <= "101100100";
|
||||
-- Data 65
|
||||
when "1111011100" => lookup <= "101100101";
|
||||
when "0100100011" => lookup <= "101100101";
|
||||
-- Data 66
|
||||
when "1001110111" => lookup <= "101100110";
|
||||
when "0010001000" => lookup <= "101100110";
|
||||
-- Data 67
|
||||
when "0001110111" => lookup <= "101100111";
|
||||
when "1010001000" => lookup <= "101100111";
|
||||
-- Data 68
|
||||
when "0111011000" => lookup <= "101101000";
|
||||
-- Data 69
|
||||
when "0100100111" => lookup <= "101101001";
|
||||
-- Data 6a
|
||||
when "1001110011" => lookup <= "101101010";
|
||||
when "0010001100" => lookup <= "101101010";
|
||||
-- Data 6b
|
||||
when "0001110011" => lookup <= "101101011";
|
||||
when "1010001100" => lookup <= "101101011";
|
||||
-- Data 6c
|
||||
when "1001110001" => lookup <= "101101100"; -- TERC4 1101
|
||||
-- Data 6d
|
||||
when "1010001110" => lookup <= "101101101"; -- TERC4 1100
|
||||
-- Data 6e
|
||||
when "1010001111" => lookup <= "101101110";
|
||||
when "0001110000" => lookup <= "101101110";
|
||||
-- Data 6f
|
||||
when "0010001111" => lookup <= "101101111";
|
||||
when "1001110000" => lookup <= "101101111";
|
||||
-- Data 70
|
||||
when "1100101111" => lookup <= "101110000";
|
||||
when "0111010000" => lookup <= "101110000";
|
||||
-- Data 71
|
||||
when "0100101111" => lookup <= "101110001";
|
||||
when "1111010000" => lookup <= "101110001";
|
||||
-- Data 72
|
||||
when "1001111011" => lookup <= "101110010";
|
||||
when "0010000100" => lookup <= "101110010";
|
||||
-- Data 73
|
||||
when "0001111011" => lookup <= "101110011";
|
||||
when "1010000100" => lookup <= "101110011";
|
||||
-- Data 74
|
||||
when "1001111001" => lookup <= "101110100";
|
||||
when "0010000110" => lookup <= "101110100";
|
||||
-- Data 75
|
||||
when "0001111001" => lookup <= "101110101";
|
||||
when "1010000110" => lookup <= "101110101";
|
||||
-- Data 76
|
||||
when "1010000111" => lookup <= "101110110";
|
||||
-- Data 77
|
||||
when "1001111000" => lookup <= "101110111";
|
||||
-- Data 78
|
||||
when "1001111101" => lookup <= "101111000";
|
||||
when "0010000010" => lookup <= "101111000";
|
||||
-- Data 79
|
||||
when "0001111101" => lookup <= "101111001";
|
||||
when "1010000010" => lookup <= "101111001";
|
||||
-- Data 7a
|
||||
when "0001111100" => lookup <= "101111010";
|
||||
when "1010000011" => lookup <= "101111010";
|
||||
-- Data 7b
|
||||
when "1001111100" => lookup <= "101111011";
|
||||
when "0010000011" => lookup <= "101111011";
|
||||
-- Data 7c
|
||||
when "0001111110" => lookup <= "101111100";
|
||||
when "1010000001" => lookup <= "101111100";
|
||||
-- Data 7d
|
||||
when "1001111110" => lookup <= "101111101";
|
||||
when "0010000001" => lookup <= "101111101";
|
||||
-- Data 7e
|
||||
when "1001111111" => lookup <= "101111110";
|
||||
when "0010000000" => lookup <= "101111110";
|
||||
-- Data 7f
|
||||
when "0001111111" => lookup <= "101111111";
|
||||
when "1010000000" => lookup <= "101111111";
|
||||
-- Data 80
|
||||
when "1101111111" => lookup <= "110000000";
|
||||
when "0110000000" => lookup <= "110000000";
|
||||
-- Data 81
|
||||
when "0101111111" => lookup <= "110000001";
|
||||
when "1110000000" => lookup <= "110000001";
|
||||
-- Data 82
|
||||
when "0101111110" => lookup <= "110000010";
|
||||
when "1110000001" => lookup <= "110000010";
|
||||
-- Data 83
|
||||
when "1101111110" => lookup <= "110000011";
|
||||
when "0110000001" => lookup <= "110000011";
|
||||
-- Data 84
|
||||
when "0101111100" => lookup <= "110000100";
|
||||
when "1110000011" => lookup <= "110000100";
|
||||
-- Data 85
|
||||
when "1101111100" => lookup <= "110000101";
|
||||
when "0110000011" => lookup <= "110000101";
|
||||
-- Data 86
|
||||
when "1101111101" => lookup <= "110000110";
|
||||
when "0110000010" => lookup <= "110000110";
|
||||
-- Data 87
|
||||
when "0101111101" => lookup <= "110000111";
|
||||
when "1110000010" => lookup <= "110000111";
|
||||
-- Data 88
|
||||
when "0101111000" => lookup <= "110001000";
|
||||
-- Data 89
|
||||
when "0110000111" => lookup <= "110001001";
|
||||
-- Data 8a
|
||||
when "1101111001" => lookup <= "110001010";
|
||||
when "0110000110" => lookup <= "110001010";
|
||||
-- Data 8b
|
||||
when "0101111001" => lookup <= "110001011";
|
||||
when "1110000110" => lookup <= "110001011";
|
||||
-- Data 8c
|
||||
when "1101111011" => lookup <= "110001100";
|
||||
when "0110000100" => lookup <= "110001100";
|
||||
-- Data 8d
|
||||
when "0101111011" => lookup <= "110001101";
|
||||
when "1110000100" => lookup <= "110001101";
|
||||
-- Data 8e
|
||||
when "1000101111" => lookup <= "110001110";
|
||||
when "0011010000" => lookup <= "110001110";
|
||||
-- Data 8f
|
||||
when "0000101111" => lookup <= "110001111";
|
||||
when "1011010000" => lookup <= "110001111";
|
||||
-- Data 90
|
||||
when "1110001111" => lookup <= "110010000";
|
||||
when "0101110000" => lookup <= "110010000";
|
||||
-- Data 91
|
||||
when "0110001111" => lookup <= "110010001";
|
||||
when "1101110000" => lookup <= "110010001";
|
||||
-- Data 92
|
||||
when "0110001110" => lookup <= "110010010"; -- TERC4 0110
|
||||
-- Data 93
|
||||
when "0101110001" => lookup <= "110010011"; -- TERC4 0100
|
||||
-- Data 94
|
||||
when "1101110011" => lookup <= "110010100";
|
||||
when "0110001100" => lookup <= "110010100";
|
||||
-- Data 95
|
||||
when "0101110011" => lookup <= "110010101";
|
||||
when "1110001100" => lookup <= "110010101";
|
||||
-- Data 96
|
||||
when "1000100111" => lookup <= "110010110";
|
||||
-- Data 97
|
||||
when "1011011000" => lookup <= "110010111";
|
||||
-- Data 98
|
||||
when "1101110111" => lookup <= "110011000";
|
||||
when "0110001000" => lookup <= "110011000";
|
||||
-- Data 99
|
||||
when "0101110111" => lookup <= "110011001";
|
||||
when "1110001000" => lookup <= "110011001";
|
||||
-- Data 9a
|
||||
when "0011011100" => lookup <= "110011010";
|
||||
when "1000100011" => lookup <= "110011010";
|
||||
-- Data 9b
|
||||
when "1011011100" => lookup <= "110011011";
|
||||
when "0000100011" => lookup <= "110011011";
|
||||
-- Data 9c
|
||||
when "0011011110" => lookup <= "110011100";
|
||||
when "1000100001" => lookup <= "110011100";
|
||||
-- Data 9d
|
||||
when "1011011110" => lookup <= "110011101";
|
||||
when "0000100001" => lookup <= "110011101";
|
||||
-- Data 9e
|
||||
when "1011011111" => lookup <= "110011110";
|
||||
when "0000100000" => lookup <= "110011110";
|
||||
-- Data 9f
|
||||
when "0011011111" => lookup <= "110011111";
|
||||
when "1000100000" => lookup <= "110011111";
|
||||
-- Data a0
|
||||
when "1110011111" => lookup <= "110100000";
|
||||
when "0101100000" => lookup <= "110100000";
|
||||
-- Data a1
|
||||
when "0110011111" => lookup <= "110100001";
|
||||
when "1101100000" => lookup <= "110100001";
|
||||
-- Data a2
|
||||
when "0110011110" => lookup <= "110100010";
|
||||
when "1101100001" => lookup <= "110100010";
|
||||
-- Data a3
|
||||
when "1110011110" => lookup <= "110100011";
|
||||
when "0101100001" => lookup <= "110100011";
|
||||
-- Data a4
|
||||
when "0110011100" => lookup <= "110100100"; -- TERC4 1010
|
||||
-- Data a5
|
||||
when "0101100011" => lookup <= "110100101"; -- TERC4 1110
|
||||
-- Data a6
|
||||
when "1000110111" => lookup <= "110100110";
|
||||
when "0011001000" => lookup <= "110100110";
|
||||
-- Data a7
|
||||
when "0000110111" => lookup <= "110100111";
|
||||
when "1011001000" => lookup <= "110100111";
|
||||
-- Data a8
|
||||
when "1101100111" => lookup <= "110101000";
|
||||
when "0110011000" => lookup <= "110101000";
|
||||
-- Data a9
|
||||
when "0101100111" => lookup <= "110101001";
|
||||
when "1110011000" => lookup <= "110101001";
|
||||
-- Data aa
|
||||
when "1000110011" => lookup <= "110101010";
|
||||
-- Data ab
|
||||
when "1011001100" => lookup <= "110101011"; -- TERC4 1000 & HDMI Guard band (video C0 and Video C2)
|
||||
-- Data ac
|
||||
when "0011001110" => lookup <= "110101100";
|
||||
when "1000110001" => lookup <= "110101100";
|
||||
-- Data ad
|
||||
when "1011001110" => lookup <= "110101101";
|
||||
when "0000110001" => lookup <= "110101101";
|
||||
-- Data ae
|
||||
when "1011001111" => lookup <= "110101110";
|
||||
when "0000110000" => lookup <= "110101110";
|
||||
-- Data af
|
||||
when "0011001111" => lookup <= "110101111";
|
||||
when "1000110000" => lookup <= "110101111";
|
||||
-- Data b0
|
||||
when "1101101111" => lookup <= "110110000";
|
||||
when "0110010000" => lookup <= "110110000";
|
||||
-- Data b1
|
||||
when "0101101111" => lookup <= "110110001";
|
||||
when "1110010000" => lookup <= "110110001";
|
||||
-- Data b2
|
||||
when "1000111011" => lookup <= "110110010";
|
||||
when "0011000100" => lookup <= "110110010";
|
||||
-- Data b3
|
||||
when "0000111011" => lookup <= "110110011";
|
||||
when "1011000100" => lookup <= "110110011";
|
||||
-- Data b4
|
||||
when "1000111001" => lookup <= "110110100";
|
||||
-- Data b5
|
||||
when "1011000110" => lookup <= "110110101"; -- TERC4 1011
|
||||
-- Data b6
|
||||
when "1011000111" => lookup <= "110110110";
|
||||
when "0000111000" => lookup <= "110110110";
|
||||
-- Data b7
|
||||
when "0011000111" => lookup <= "110110111";
|
||||
when "1000111000" => lookup <= "110110111";
|
||||
-- Data b8
|
||||
when "1000111101" => lookup <= "110111000";
|
||||
when "0011000010" => lookup <= "110111000";
|
||||
-- Data b9
|
||||
when "0000111101" => lookup <= "110111001";
|
||||
when "1011000010" => lookup <= "110111001";
|
||||
-- Data ba
|
||||
when "1011000011" => lookup <= "110111010"; -- TERC4 1111
|
||||
-- Data bb
|
||||
when "1000111100" => lookup <= "110111011";
|
||||
-- Data bc
|
||||
when "0000111110" => lookup <= "110111100";
|
||||
when "1011000001" => lookup <= "110111100";
|
||||
-- Data bd
|
||||
when "1000111110" => lookup <= "110111101";
|
||||
when "0011000001" => lookup <= "110111101";
|
||||
-- Data be
|
||||
when "1000111111" => lookup <= "110111110";
|
||||
when "0011000000" => lookup <= "110111110";
|
||||
-- Data bf
|
||||
when "0000111111" => lookup <= "110111111";
|
||||
when "1011000000" => lookup <= "110111111";
|
||||
-- Data c0
|
||||
when "1110111111" => lookup <= "111000000";
|
||||
when "0101000000" => lookup <= "111000000";
|
||||
-- Data c1
|
||||
when "0110111111" => lookup <= "111000001";
|
||||
when "1101000000" => lookup <= "111000001";
|
||||
-- Data c2
|
||||
when "0110111110" => lookup <= "111000010";
|
||||
when "1101000001" => lookup <= "111000010";
|
||||
-- Data c3
|
||||
when "1110111110" => lookup <= "111000011";
|
||||
when "0101000001" => lookup <= "111000011";
|
||||
-- Data c4
|
||||
when "0110111100" => lookup <= "111000100";
|
||||
when "1101000011" => lookup <= "111000100";
|
||||
-- Data c5
|
||||
when "1110111100" => lookup <= "111000101";
|
||||
when "0101000011" => lookup <= "111000101";
|
||||
-- Data c6
|
||||
when "1000010111" => lookup <= "111000110";
|
||||
-- Data c7
|
||||
when "1011101000" => lookup <= "111000111";
|
||||
-- Data c8
|
||||
when "0110111000" => lookup <= "111001000";
|
||||
-- Data c9
|
||||
when "0101000111" => lookup <= "111001001";
|
||||
-- Data ca
|
||||
when "0011101100" => lookup <= "111001010";
|
||||
when "1000010011" => lookup <= "111001010";
|
||||
-- Data cb
|
||||
when "1011101100" => lookup <= "111001011";
|
||||
when "0000010011" => lookup <= "111001011";
|
||||
-- Data cc
|
||||
when "0011101110" => lookup <= "111001100";
|
||||
when "1000010001" => lookup <= "111001100";
|
||||
-- Data cd
|
||||
when "1011101110" => lookup <= "111001101";
|
||||
when "0000010001" => lookup <= "111001101";
|
||||
-- Data ce
|
||||
when "1011101111" => lookup <= "111001110";
|
||||
when "0000010000" => lookup <= "111001110";
|
||||
-- Data cf
|
||||
when "0011101111" => lookup <= "111001111";
|
||||
when "1000010000" => lookup <= "111001111";
|
||||
-- Data d0
|
||||
when "1101001111" => lookup <= "111010000";
|
||||
when "0110110000" => lookup <= "111010000";
|
||||
-- Data d1
|
||||
when "0101001111" => lookup <= "111010001";
|
||||
when "1110110000" => lookup <= "111010001";
|
||||
-- Data d2
|
||||
when "1000011011" => lookup <= "111010010";
|
||||
-- Data d3
|
||||
when "1011100100" => lookup <= "111010011"; -- TERC4 0010
|
||||
-- Data d4
|
||||
when "0011100110" => lookup <= "111010100";
|
||||
when "1000011001" => lookup <= "111010100";
|
||||
-- Data d5
|
||||
when "1011100110" => lookup <= "111010101";
|
||||
when "0000011001" => lookup <= "111010101";
|
||||
-- Data d6
|
||||
when "1011100111" => lookup <= "111010110";
|
||||
when "0000011000" => lookup <= "111010110";
|
||||
-- Data d7
|
||||
when "0011100111" => lookup <= "111010111";
|
||||
when "1000011000" => lookup <= "111010111";
|
||||
-- Data d8
|
||||
when "1000011101" => lookup <= "111011000";
|
||||
-- Data d9
|
||||
when "1011100010" => lookup <= "111011001"; -- TERC4 0011
|
||||
-- Data da
|
||||
when "1011100011" => lookup <= "111011010";
|
||||
when "0000011100" => lookup <= "111011010";
|
||||
-- Data db
|
||||
when "0011100011" => lookup <= "111011011";
|
||||
when "1000011100" => lookup <= "111011011";
|
||||
-- Data dc
|
||||
when "1011100001" => lookup <= "111011100";
|
||||
-- Data dd
|
||||
when "1000011110" => lookup <= "111011101";
|
||||
-- Data de
|
||||
when "1000011111" => lookup <= "111011110";
|
||||
when "0011100000" => lookup <= "111011110";
|
||||
-- Data df
|
||||
when "0000011111" => lookup <= "111011111";
|
||||
when "1011100000" => lookup <= "111011111";
|
||||
-- Data e0
|
||||
when "1101011111" => lookup <= "111100000";
|
||||
when "0110100000" => lookup <= "111100000";
|
||||
-- Data e1
|
||||
when "0101011111" => lookup <= "111100001";
|
||||
when "1110100000" => lookup <= "111100001";
|
||||
-- Data e2
|
||||
when "0011110100" => lookup <= "111100010";
|
||||
when "1000001011" => lookup <= "111100010";
|
||||
-- Data e3
|
||||
when "1011110100" => lookup <= "111100011";
|
||||
when "0000001011" => lookup <= "111100011";
|
||||
-- Data e4
|
||||
when "0011110110" => lookup <= "111100100";
|
||||
when "1000001001" => lookup <= "111100100";
|
||||
-- Data e5
|
||||
when "1011110110" => lookup <= "111100101";
|
||||
when "0000001001" => lookup <= "111100101";
|
||||
-- Data e6
|
||||
when "1011110111" => lookup <= "111100110";
|
||||
when "0000001000" => lookup <= "111100110";
|
||||
-- Data e7
|
||||
when "0011110111" => lookup <= "111100111";
|
||||
when "1000001000" => lookup <= "111100111";
|
||||
-- Data e8
|
||||
when "0011110010" => lookup <= "111101000";
|
||||
when "1000001101" => lookup <= "111101000";
|
||||
-- Data e9
|
||||
when "1011110010" => lookup <= "111101001";
|
||||
when "0000001101" => lookup <= "111101001";
|
||||
-- Data ea
|
||||
when "1011110011" => lookup <= "111101010";
|
||||
when "0000001100" => lookup <= "111101010";
|
||||
-- Data eb
|
||||
when "0011110011" => lookup <= "111101011";
|
||||
when "1000001100" => lookup <= "111101011";
|
||||
-- Data ec
|
||||
when "1011110001" => lookup <= "111101100";
|
||||
when "0000001110" => lookup <= "111101100";
|
||||
-- Data ed
|
||||
when "0011110001" => lookup <= "111101101";
|
||||
when "1000001110" => lookup <= "111101101";
|
||||
-- Data ee
|
||||
when "1000001111" => lookup <= "111101110";
|
||||
-- Data ef
|
||||
when "1011110000" => lookup <= "111101111";
|
||||
-- Data f0
|
||||
when "0011111010" => lookup <= "111110000";
|
||||
when "1000000101" => lookup <= "111110000";
|
||||
-- Data f1
|
||||
when "1011111010" => lookup <= "111110001";
|
||||
when "0000000101" => lookup <= "111110001";
|
||||
-- Data f2
|
||||
when "1011111011" => lookup <= "111110010";
|
||||
when "0000000100" => lookup <= "111110010";
|
||||
-- Data f3
|
||||
when "0011111011" => lookup <= "111110011";
|
||||
when "1000000100" => lookup <= "111110011";
|
||||
-- Data f4
|
||||
when "1011111001" => lookup <= "111110100";
|
||||
when "0000000110" => lookup <= "111110100";
|
||||
-- Data f5
|
||||
when "0011111001" => lookup <= "111110101";
|
||||
when "1000000110" => lookup <= "111110101";
|
||||
-- Data f6
|
||||
when "0011111000" => lookup <= "111110110";
|
||||
when "1000000111" => lookup <= "111110110";
|
||||
-- Data f7
|
||||
when "1011111000" => lookup <= "111110111";
|
||||
when "0000000111" => lookup <= "111110111";
|
||||
-- Data f8
|
||||
when "1011111101" => lookup <= "111111000";
|
||||
when "0000000010" => lookup <= "111111000";
|
||||
-- Data f9
|
||||
when "0011111101" => lookup <= "111111001";
|
||||
when "1000000010" => lookup <= "111111001";
|
||||
-- Data fa
|
||||
when "0011111100" => lookup <= "111111010";
|
||||
when "1000000011" => lookup <= "111111010";
|
||||
-- Data fb
|
||||
when "1011111100" => lookup <= "111111011";
|
||||
when "0000000011" => lookup <= "111111011";
|
||||
-- Data fc
|
||||
when "0011111110" => lookup <= "111111100";
|
||||
when "1000000001" => lookup <= "111111100";
|
||||
-- Data fd
|
||||
when "1011111110" => lookup <= "111111101";
|
||||
when "0000000001" => lookup <= "111111101";
|
||||
-- Data fe
|
||||
when "1011111111" => lookup <= "111111110";
|
||||
when "0000000000" => lookup <= "111111110";
|
||||
-- Data ff
|
||||
when "0011111111" => lookup <= "111111111";
|
||||
when "1000000000" => lookup <= "111111111";
|
||||
|
||||
-- DVI-D CTL symbols
|
||||
when "0010101011" => lookup <= "01" & "00000" & "01"; -- CTL1
|
||||
when "0101010100" => lookup <= "01" & "00000" & "10"; -- CTL2
|
||||
when "1010101011" => lookup <= "01" & "00000" & "11"; -- CTL3
|
||||
when "1101010100" => lookup <= "01" & "00000" & "00"; -- CTL0
|
||||
|
||||
-- Invalid symbols
|
||||
when others => lookup <= "0000" & "00000";
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
|
||||
-- For Guard band and TERC4 decoding (to be done later!)
|
||||
-- when x"55" => -- "0100110011" HDMI Guard band (video C1, data C1 & C2)
|
||||
-- when x"5B" => -- "1010011100" TERC4 0000
|
||||
-- when x"5A" => -- "1001100011" TERC4 0001
|
||||
-- when x"D3" => -- "1011100100" TERC4 0010
|
||||
-- when x"D9" => -- "1011100010" TERC4 0011
|
||||
-- when x"93" => -- "0101110001" TERC4 0100
|
||||
-- when x"22" => -- "0100011110" TERC4 0101
|
||||
-- when x"92" => -- "0110001110" TERC4 0110
|
||||
-- when x"44" => -- "0100111100" TERC4 0111
|
||||
-- when x"AB" => -- "1011001100" TERC4 1000 & HDMI Guard band (video C0 and Video C2)
|
||||
-- when x"4B" => -- "0100111001" TERC4 1001
|
||||
-- when x"A4" => -- "0110011100" TERC4 1010
|
||||
-- when x"B5" => -- "1011000110" TERC4 1011
|
||||
-- when x"6D" => -- "1010001110" TERC4 1100
|
||||
-- when x"6C" => -- "1001110001" TERC4 1101
|
||||
-- when x"A5" => -- "0101100011" TERC4 1110
|
||||
-- when x"BA" => -- "1011000011" TERC4 1111
|
||||
144
src/tmds_encoder.vhd
Normal file
144
src/tmds_encoder.vhd
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: tmds_encoder - Behavioral
|
||||
--
|
||||
-- Description: 8b/10b TMDS encoder
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity tmds_encoder is
|
||||
Port ( clk : in std_logic;
|
||||
data : in std_logic_vector (7 downto 0);
|
||||
c : in std_logic_vector (1 downto 0);
|
||||
blank : in std_logic;
|
||||
encoded : out std_logic_vector (9 downto 0));
|
||||
end entity;
|
||||
|
||||
architecture Behavioral of tmds_encoder is
|
||||
signal xored : STD_LOGIC_VECTOR (8 downto 0);
|
||||
signal xnored : STD_LOGIC_VECTOR (8 downto 0);
|
||||
|
||||
signal ones : STD_LOGIC_VECTOR (3 downto 0);
|
||||
signal data_word : STD_LOGIC_VECTOR (8 downto 0);
|
||||
signal data_word_inv : STD_LOGIC_VECTOR (8 downto 0);
|
||||
signal data_word_disparity : STD_LOGIC_VECTOR (3 downto 0);
|
||||
signal dc_bias : STD_LOGIC_VECTOR (3 downto 0) := (others => '0');
|
||||
begin
|
||||
-- Work our the two different encodings for the byte
|
||||
xored(0) <= data(0);
|
||||
xored(1) <= data(1) xor xored(0);
|
||||
xored(2) <= data(2) xor xored(1);
|
||||
xored(3) <= data(3) xor xored(2);
|
||||
xored(4) <= data(4) xor xored(3);
|
||||
xored(5) <= data(5) xor xored(4);
|
||||
xored(6) <= data(6) xor xored(5);
|
||||
xored(7) <= data(7) xor xored(6);
|
||||
xored(8) <= '1';
|
||||
|
||||
xnored(0) <= data(0);
|
||||
xnored(1) <= data(1) xnor xnored(0);
|
||||
xnored(2) <= data(2) xnor xnored(1);
|
||||
xnored(3) <= data(3) xnor xnored(2);
|
||||
xnored(4) <= data(4) xnor xnored(3);
|
||||
xnored(5) <= data(5) xnor xnored(4);
|
||||
xnored(6) <= data(6) xnor xnored(5);
|
||||
xnored(7) <= data(7) xnor xnored(6);
|
||||
xnored(8) <= '0';
|
||||
|
||||
-- Count how many ones are set in data
|
||||
ones <= "0000" + data(0) + data(1) + data(2) + data(3)
|
||||
+ data(4) + data(5) + data(6) + data(7);
|
||||
|
||||
-- Decide which encoding to use
|
||||
process(ones, data(0), xnored, xored)
|
||||
begin
|
||||
if ones > 4 or (ones = 4 and data(0) = '0') then
|
||||
data_word <= xnored;
|
||||
data_word_inv <= NOT(xnored);
|
||||
else
|
||||
data_word <= xored;
|
||||
data_word_inv <= NOT(xored);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Work out the DC bias of the dataword;
|
||||
data_word_disparity <= "1100" + data_word(0) + data_word(1) + data_word(2) + data_word(3)
|
||||
+ data_word(4) + data_word(5) + data_word(6) + data_word(7);
|
||||
|
||||
-- Now work out what the output should be
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if blank = '1' then
|
||||
-- In the control periods, all values have and have balanced bit count
|
||||
case c is
|
||||
when "00" => encoded <= "1101010100";
|
||||
when "01" => encoded <= "0010101011";
|
||||
when "10" => encoded <= "0101010100";
|
||||
when others => encoded <= "1010101011";
|
||||
end case;
|
||||
dc_bias <= (others => '0');
|
||||
else
|
||||
if dc_bias = "00000" or data_word_disparity = 0 then
|
||||
-- dataword has no disparity
|
||||
if data_word(8) = '1' then
|
||||
encoded <= "01" & data_word(7 downto 0);
|
||||
dc_bias <= dc_bias + data_word_disparity;
|
||||
else
|
||||
encoded <= "10" & data_word_inv(7 downto 0);
|
||||
dc_bias <= dc_bias - data_word_disparity;
|
||||
end if;
|
||||
elsif (dc_bias(3) = '0' and data_word_disparity(3) = '0') or
|
||||
(dc_bias(3) = '1' and data_word_disparity(3) = '1') then
|
||||
encoded <= '1' & data_word(8) & data_word_inv(7 downto 0);
|
||||
dc_bias <= dc_bias + data_word(8) - data_word_disparity;
|
||||
else
|
||||
encoded <= '0' & data_word;
|
||||
dc_bias <= dc_bias - data_word_inv(8) + data_word_disparity;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
396
src/top.v
Normal file
396
src/top.v
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
|
||||
module proc_top(
|
||||
input clk,
|
||||
|
||||
input sck, sdi, ncs,
|
||||
output sdo,
|
||||
|
||||
input in_blank, in_hsync, in_vsync,
|
||||
input [7:0] in_red,
|
||||
input [7:0] in_green,
|
||||
input [7:0] in_blue,
|
||||
input is_interlaced, is_second_field,
|
||||
|
||||
output out_blank, out_hsync, out_vsync,
|
||||
output [7:0] out_red,
|
||||
output [7:0] out_green,
|
||||
output [7:0] out_blue,
|
||||
|
||||
output [5:0] debug,
|
||||
|
||||
input [7:0] switches
|
||||
);
|
||||
|
||||
/* ================= */
|
||||
/* DEBUG DEBUG DEBUG */
|
||||
/* ================= */
|
||||
|
||||
/* Color bar generator */
|
||||
/*
|
||||
parameter CB_HRES = 1280;
|
||||
parameter CB_VRES = 720;
|
||||
parameter CB_H_FP = 68;
|
||||
parameter CB_H_BP = 300;
|
||||
parameter CB_V_FP = 25;
|
||||
parameter CB_V_BP = 5;
|
||||
|
||||
reg [11:0] cb_x = 0;
|
||||
reg [11:0] cb_y = 0;
|
||||
reg [11:0] cb_cnt = 0;
|
||||
reg [5:0] cb_bar = 0;
|
||||
|
||||
reg cb_hsync = 0, cb_vsync = 0, cb_blank = 1, cb_vactive = 0;
|
||||
reg [7:0] cb_red;
|
||||
reg [7:0] cb_green;
|
||||
reg [7:0] cb_blue;
|
||||
|
||||
assign out_hsync = cb_hsync;
|
||||
assign out_vsync = cb_vsync;
|
||||
assign out_blank = cb_blank;
|
||||
assign out_red = cb_red;
|
||||
assign out_green = cb_green;
|
||||
assign out_blue = cb_blue;
|
||||
|
||||
always @(posedge clk) begin
|
||||
//cb_hsync <= in_hsync;
|
||||
//cb_vsync <= in_vsync;
|
||||
//cb_blank <= in_blank;
|
||||
//cb_red <= in_red;
|
||||
//cb_green <= in_green;
|
||||
//cb_blue <= in_blue;
|
||||
|
||||
cb_x <= cb_x + 1;
|
||||
|
||||
cb_hsync <= cb_x >= 8 && cb_x <= 15;
|
||||
cb_vsync <= cb_y >= 4 && cb_y <= 7;
|
||||
|
||||
if (cb_x == CB_H_FP + CB_HRES + CB_H_BP - 1) begin
|
||||
cb_x <= 0;
|
||||
cb_y <= cb_y + 1;
|
||||
|
||||
|
||||
if (cb_y == CB_V_FP - 1) begin
|
||||
cb_vactive <= 1;
|
||||
|
||||
end else if (cb_y == CB_V_FP + CB_VRES - 1) begin
|
||||
cb_vactive <= 0;
|
||||
|
||||
end else if (cb_y == CB_V_FP + CB_VRES + CB_V_BP - 1) begin
|
||||
cb_y <= 0;
|
||||
end
|
||||
|
||||
end else if (cb_vactive && (cb_x == CB_H_FP - 1)) begin
|
||||
cb_red <= 0;
|
||||
cb_green <= 0;
|
||||
cb_blue <= 0;
|
||||
cb_blank <= 0;
|
||||
|
||||
end else if (cb_vactive && (cb_x == CB_H_FP + CB_HRES - 1)) begin
|
||||
cb_blank <= 1;
|
||||
cb_cnt <= 0;
|
||||
cb_bar <= 0;
|
||||
|
||||
end
|
||||
|
||||
if (!cb_blank) begin
|
||||
cb_cnt <= cb_cnt + 1;
|
||||
|
||||
if (cb_cnt == 127) begin
|
||||
cb_cnt <= 0;
|
||||
cb_bar <= cb_bar + 1;
|
||||
|
||||
if (cb_bar == 7) begin
|
||||
cb_bar <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (cb_y < CB_V_FP + 30 || cb_y > CB_V_FP + CB_VRES - 30) begin
|
||||
cb_red <= {8{cb_bar[0]}};
|
||||
cb_green <= {8{cb_bar[1]}};
|
||||
cb_blue <= {8{cb_bar[2]}};
|
||||
|
||||
end else begin
|
||||
cb_red <= in_red;
|
||||
cb_green <= in_green;
|
||||
cb_blue <= in_blue;
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
/* ================= */
|
||||
/* END DEBUG END */
|
||||
/* ================= */
|
||||
|
||||
parameter GLYPHMEM_W = 256; /* glyphs */
|
||||
parameter GLYPHMEM_H = 128; /* glyphs */
|
||||
parameter PAYLOAD_BUF_SIZE = 16384;
|
||||
|
||||
reg rst = 0;
|
||||
reg [3:0] rst_cnt = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst_cnt != 0) begin
|
||||
rst <= 1;
|
||||
end
|
||||
|
||||
if (rst_cnt != 4'hf) begin
|
||||
rst_cnt <= rst_cnt + 1;
|
||||
end else begin
|
||||
rst <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
reg input_idle = 0;
|
||||
reg [19:0] idle_cnt = 0;
|
||||
always @(posedge clk) begin
|
||||
if (in_vsync) begin
|
||||
idle_cnt <= 0;
|
||||
input_idle <= 0;
|
||||
|
||||
end else begin
|
||||
if (idle_cnt == 20'hfffff) begin
|
||||
input_idle <= 1;
|
||||
|
||||
end else begin
|
||||
idle_cnt <= idle_cnt + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/* Switches */
|
||||
wire bypass = switches[0];
|
||||
|
||||
/* spi interface */
|
||||
reg [7:0] spi_data_in;
|
||||
wire [7:0] spi_data_out;
|
||||
wire win_locked;
|
||||
wire [7:0] spi_status_word = {5'h00, bypass, win_locked, input_idle};
|
||||
wire [7:0] spi_cmd_word;
|
||||
wire spi_cmd_begin, spi_cmd_active, spi_cmd_step;
|
||||
wire [19:0] spi_cmd_idx;
|
||||
|
||||
/* term emu */
|
||||
wire temu_in_valid = (spi_cmd_word == 8'h23) && spi_cmd_step;
|
||||
wire glyph_buffer_w_valid;
|
||||
wire [15:0] glyph_buffer_w_addr;
|
||||
wire [19:0] glyph_buffer_w_data;
|
||||
|
||||
/* matcher */
|
||||
wire win_blank;
|
||||
wire [11:0] win_w;
|
||||
wire [11:0] win_h;
|
||||
wire out_data_en;
|
||||
wire out_data_valid;
|
||||
wire [7:0] matcher_debug;
|
||||
|
||||
assign debug = {matcher_debug[3:2], win_blank, win_locked, out_data_en, out_data_valid};
|
||||
|
||||
/* term renderer */
|
||||
wire [7:0] win_red;
|
||||
wire [7:0] win_green;
|
||||
wire [7:0] win_blue;
|
||||
|
||||
/* spi read index logic */
|
||||
reg [15:0] spi_payload_r_idx;
|
||||
reg [1:0] spi_payload_byte;
|
||||
always @(posedge clk) begin
|
||||
if (spi_cmd_begin) begin
|
||||
spi_payload_r_idx <= 0;
|
||||
spi_payload_byte <= 0;
|
||||
end else if (spi_cmd_step) begin
|
||||
if (spi_payload_byte == 2) begin
|
||||
spi_payload_r_idx <= spi_payload_r_idx + 1;
|
||||
spi_payload_byte <= 0;
|
||||
|
||||
end else begin
|
||||
spi_payload_byte <= spi_payload_byte + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/* payload buffer access logic */
|
||||
reg [23:0] payload_buf [0:PAYLOAD_BUF_SIZE-1];
|
||||
reg out_data_en_last;
|
||||
reg [15:0] payload_w_idx;
|
||||
reg [23:0] payload_r_data;
|
||||
always @(posedge clk) begin
|
||||
out_data_en_last <= out_data_en;
|
||||
|
||||
if (!out_data_en) begin
|
||||
payload_w_idx <= 0;
|
||||
end
|
||||
|
||||
if (out_data_valid) begin
|
||||
if (payload_w_idx != PAYLOAD_BUF_SIZE) begin
|
||||
payload_buf[payload_w_idx] <= {in_red, in_green, in_blue};
|
||||
payload_w_idx <= payload_w_idx + 1;
|
||||
end
|
||||
end
|
||||
|
||||
payload_r_data <= payload_buf[spi_payload_r_idx];
|
||||
end
|
||||
|
||||
/* SPI read payload memory access logic */
|
||||
always @(posedge clk) begin
|
||||
if (spi_cmd_active && (spi_cmd_word == 8'h22)) begin
|
||||
case (spi_payload_byte)
|
||||
0: spi_data_in <= payload_r_data[23:16];
|
||||
1: spi_data_in <= payload_r_data[15:8];
|
||||
default: spi_data_in <= payload_r_data[7:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
/* glyph memory logic */
|
||||
reg [19:0] glyphmem [0:GLYPHMEM_W*GLYPHMEM_H-1];
|
||||
/* This is the dumbest thing, but it seems vivado is just *that* stupid. */
|
||||
`ifdef SYNTHESIS
|
||||
initial $readmemh("../../src/gen/glyph_buffer_init_file.hex", glyphmem);
|
||||
`else
|
||||
initial $readmemh("../../../../src/gen/glyph_buffer_init_file.hex", glyphmem);
|
||||
`endif
|
||||
|
||||
reg [19:0] glyphmem_r_data;
|
||||
wire [15:0] glyphmem_r_addr;
|
||||
always @(posedge clk) begin
|
||||
if (glyph_buffer_w_valid) begin
|
||||
glyphmem[glyph_buffer_w_addr] <= glyph_buffer_w_data;
|
||||
end
|
||||
|
||||
glyphmem_r_data <= glyphmem[glyphmem_r_addr];
|
||||
end
|
||||
|
||||
wire [7:0] rxbuf_dbg;
|
||||
|
||||
spi_regfile spi_regfile_dut (
|
||||
.clk(clk), .rst(rst),
|
||||
|
||||
.sck(sck), .sdi(sdi), .sdo(sdo), .ncs(ncs),
|
||||
|
||||
.spi_data_in(spi_data_in),
|
||||
.spi_data_out(spi_data_out),
|
||||
|
||||
.spi_status_word(spi_status_word),
|
||||
.spi_cmd_word(spi_cmd_word),
|
||||
.spi_cmd_begin(spi_cmd_begin),
|
||||
.spi_cmd_active(spi_cmd_active),
|
||||
.spi_cmd_step(spi_cmd_step),
|
||||
.spi_cmd_idx(spi_cmd_idx),
|
||||
|
||||
.rxbuf_dbg(rxbuf_dbg)
|
||||
);
|
||||
|
||||
term_emu #(
|
||||
.GLYPHMEM_W(GLYPHMEM_W),
|
||||
.GLYPHMEM_H(GLYPHMEM_H)
|
||||
) term_emu_i (
|
||||
.clk(clk), .rst(rst),
|
||||
|
||||
.in_byte_valid(temu_in_valid),
|
||||
.in_byte(spi_data_out),
|
||||
.in_byte_ack(),
|
||||
|
||||
.glyph_buffer_w_valid(glyph_buffer_w_valid),
|
||||
.glyph_buffer_w_addr(glyph_buffer_w_addr),
|
||||
.glyph_buffer_w_data(glyph_buffer_w_data)
|
||||
);
|
||||
|
||||
term_renderer #(
|
||||
.GLYPHMEM_W(GLYPHMEM_W),
|
||||
.GLYPHMEM_H(GLYPHMEM_H)
|
||||
) term_renderer_i (
|
||||
.rst(rst),
|
||||
.clk(clk),
|
||||
|
||||
.in_blank(win_blank),
|
||||
.in_vsync(in_vsync),
|
||||
.in_hsync(in_hsync),
|
||||
|
||||
.out_hsync(),
|
||||
.out_vsync(),
|
||||
|
||||
.glyphmem_data(glyphmem_r_data),
|
||||
.glyphmem_r_addr(glyphmem_r_addr),
|
||||
|
||||
.out_red(win_red),
|
||||
.out_green(win_green),
|
||||
.out_blue(win_blue)
|
||||
);
|
||||
|
||||
wire [11:0] win_x_dbg;
|
||||
wire [11:0] win_y_dbg;
|
||||
wire [11:0] win_w_dbg;
|
||||
wire [11:0] win_h_dbg;
|
||||
wire [11:0] scan_x_dbg;
|
||||
wire [11:0] scan_y_dbg;
|
||||
wire [8:0] match_dbg;
|
||||
|
||||
window_matcher window_matcher_i (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.bypass(bypass),
|
||||
.debug(matcher_debug),
|
||||
.scan_x_dbg(scan_x_dbg),
|
||||
.scan_y_dbg(scan_y_dbg),
|
||||
.match_dbg(match_dbg),
|
||||
|
||||
.in_blank(in_blank),
|
||||
.in_hsync(in_hsync),
|
||||
.in_vsync(in_vsync),
|
||||
.in_red(in_red),
|
||||
.in_green(in_green),
|
||||
.in_blue(in_blue),
|
||||
|
||||
.win_blank(win_blank),
|
||||
.win_locked(win_locked),
|
||||
.win_w(win_w),
|
||||
.win_h(win_h),
|
||||
|
||||
.win_x_dbg(win_x_dbg),
|
||||
.win_y_dbg(win_y_dbg),
|
||||
.win_w_dbg(win_w_dbg),
|
||||
.win_h_dbg(win_h_dbg),
|
||||
|
||||
.out_data_en(out_data_en),
|
||||
.out_data_valid(out_data_valid),
|
||||
|
||||
.win_red(win_red),
|
||||
.win_green(win_green),
|
||||
.win_blue(win_blue),
|
||||
|
||||
.out_blank(out_blank),
|
||||
.out_hsync(out_hsync),
|
||||
.out_vsync(out_vsync),
|
||||
.out_red(out_red),
|
||||
.out_green(out_green),
|
||||
.out_blue(out_blue)
|
||||
);
|
||||
|
||||
ila_0 i_ila_0 (
|
||||
.clk(clk),
|
||||
|
||||
.probe0(payload_w_idx[11:0]),
|
||||
.probe1(spi_payload_r_idx[11:0]),
|
||||
.probe2(scan_x_dbg),
|
||||
.probe3(scan_y_dbg),
|
||||
.probe4(payload_r_data),
|
||||
.probe5(in_blank),
|
||||
.probe6(spi_cmd_step),
|
||||
.probe7(in_vsync),
|
||||
.probe8(spi_data_in),
|
||||
.probe9(temu_in_valid),
|
||||
.probe10(spi_cmd_begin),
|
||||
.probe11(spi_cmd_active),
|
||||
.probe12(spi_payload_byte[0]),
|
||||
.probe13(spi_payload_byte[1]),
|
||||
.probe14(out_data_en),
|
||||
.probe15(out_data_valid),
|
||||
.probe16(sck),
|
||||
.probe17(sdi),
|
||||
.probe18(sdo),
|
||||
.probe19(ncs)
|
||||
);
|
||||
|
||||
endmodule
|
||||
410
src/window_matcher.v
Normal file
410
src/window_matcher.v
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 06/14/2021 05:44:00 PM
|
||||
// Design Name:
|
||||
// Module Name: window_matcher
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module window_matcher(
|
||||
/* Pixel clock and synchronous, active-high reset */
|
||||
input clk, rst,
|
||||
|
||||
input bypass,
|
||||
|
||||
/* Input pixel bus */
|
||||
input in_blank, in_hsync, in_vsync,
|
||||
input [7:0] in_red, [7:0] in_green, [7:0] in_blue,
|
||||
|
||||
/* Output pixel bus */
|
||||
output out_blank,
|
||||
output out_hsync, out_vsync,
|
||||
output [7:0] out_red, [7:0] out_green, [7:0] out_blue,
|
||||
|
||||
/* Overlay data IO */
|
||||
output reg win_blank,
|
||||
output [11:0] win_x_dbg,
|
||||
output [11:0] win_y_dbg,
|
||||
output [11:0] win_w_dbg,
|
||||
output [11:0] win_h_dbg,
|
||||
output reg [11:0] win_w,
|
||||
output reg [11:0] win_h,
|
||||
output reg win_locked,
|
||||
input [7:0] win_red, [7:0] win_green, [7:0] win_blue,
|
||||
|
||||
/* Extracted data output */
|
||||
output reg out_data_en,
|
||||
output reg out_data_valid,
|
||||
|
||||
output [7:0] debug,
|
||||
output [7:0] match_dbg,
|
||||
output [11:0] scan_x_dbg,
|
||||
output [11:0] scan_y_dbg
|
||||
);
|
||||
|
||||
wire [23:0] in_pxd = {in_red, in_green, in_blue};
|
||||
wire [23:0] win_pxd = {win_red, win_green, win_blue};
|
||||
wire [23:0] out_pxd;
|
||||
assign {out_red, out_green, out_blue} = out_pxd;
|
||||
|
||||
assign debug = {in_pxd_match_dbg, win_blank, win_hactive, win_locked, 1'b0};
|
||||
|
||||
/* Pattern matching */
|
||||
localparam [23:0] MARKER_0 = 24'h001020;
|
||||
localparam [23:0] MARKER_1 = 24'h304050;
|
||||
localparam [23:0] MARKER_2 = 24'h607080;
|
||||
localparam [23:0] MARKER_3 = 24'h90a0b0;
|
||||
localparam [23:0] MARKER_4 = 24'hc0d0e0;
|
||||
localparam [23:0] MARKER_5 = 24'hf04020;
|
||||
localparam [23:0] MARKER_6 = 24'h504030;
|
||||
localparam [23:0] MARKER_7 = 24'h201000;
|
||||
|
||||
/* In captures, we rarely observe that a channel value like 8'h50 gets changed to 8'h4f. I have no idea why this is, and pröperly debugging it is a major To-Do. For now, however, we simply dump the four LSBs and adjust the upper nibble to round.
|
||||
*/
|
||||
function [7:0] unfuck;
|
||||
input [7:0] in_ch;
|
||||
begin
|
||||
unfuck[3:0] = 4'h0;
|
||||
|
||||
if (in_ch[3:0] < 8) begin
|
||||
unfuck[7:4] = in_ch[7:4];
|
||||
end else begin
|
||||
unfuck[7:4] = in_ch[7:4] + 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
wire [7:0] in_red_unfucked = unfuck(in_red);
|
||||
wire [7:0] in_green_unfucked = unfuck(in_green);
|
||||
wire [7:0] in_blue_unfucked = unfuck(in_blue);
|
||||
wire [23:0] in_pxd_unfucked = {in_red_unfucked, in_green_unfucked, in_blue_unfucked};
|
||||
|
||||
wire [7:0] in_pxd_match = {
|
||||
in_pxd_unfucked == MARKER_7,
|
||||
in_pxd_unfucked == MARKER_6,
|
||||
in_pxd_unfucked == MARKER_5,
|
||||
in_pxd_unfucked == MARKER_4,
|
||||
in_pxd_unfucked == MARKER_3,
|
||||
in_pxd_unfucked == MARKER_2,
|
||||
in_pxd_unfucked == MARKER_1,
|
||||
in_pxd_unfucked == MARKER_0
|
||||
};
|
||||
assign match_dbg = in_pxd_match;
|
||||
|
||||
reg [3:0] in_pxd_match_dbg;
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
in_pxd_match_dbg <= 0;
|
||||
end else begin
|
||||
if (!in_blank) begin
|
||||
in_pxd_match_dbg <= in_pxd_match_dbg | in_pxd_match[7:4];
|
||||
end else begin
|
||||
in_pxd_match_dbg <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [7:0] in_pxd_match_sr [6:0];
|
||||
wire in_pxd_pattern_match =
|
||||
in_pxd_match_sr[6][0]
|
||||
&& in_pxd_match_sr[5][1]
|
||||
&& in_pxd_match_sr[4][2]
|
||||
&& in_pxd_match_sr[3][3]
|
||||
&& in_pxd_match_sr[2][4]
|
||||
&& in_pxd_match_sr[1][5]
|
||||
&& in_pxd_match_sr[0][6]
|
||||
&& in_pxd_match[7]
|
||||
&& !in_blank;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst == 1) begin
|
||||
in_pxd_match_sr[0] <= 0;
|
||||
in_pxd_match_sr[1] <= 0;
|
||||
in_pxd_match_sr[2] <= 0;
|
||||
in_pxd_match_sr[3] <= 0;
|
||||
in_pxd_match_sr[4] <= 0;
|
||||
in_pxd_match_sr[5] <= 0;
|
||||
in_pxd_match_sr[6] <= 0;
|
||||
end else begin
|
||||
in_pxd_match_sr[0] <= in_pxd_match;
|
||||
in_pxd_match_sr[1] <= in_pxd_match_sr[0];
|
||||
in_pxd_match_sr[2] <= in_pxd_match_sr[1];
|
||||
in_pxd_match_sr[3] <= in_pxd_match_sr[2];
|
||||
in_pxd_match_sr[4] <= in_pxd_match_sr[3];
|
||||
in_pxd_match_sr[5] <= in_pxd_match_sr[4];
|
||||
in_pxd_match_sr[6] <= in_pxd_match_sr[5];
|
||||
end
|
||||
end
|
||||
|
||||
/* Pixel scan state machine */
|
||||
reg [11:0] scan_x;
|
||||
reg [11:0] scan_y;
|
||||
assign scan_x_dbg = scan_x;
|
||||
assign scan_y_dbg = scan_y;
|
||||
|
||||
reg [11:0] scan_x_reg [7:0];
|
||||
reg in_hsync_reg;
|
||||
reg in_vsync_reg;
|
||||
reg in_blank_reg;
|
||||
reg [23:0] in_pxd_reg;
|
||||
|
||||
assign out_hsync = in_hsync_reg;
|
||||
assign out_vsync = in_vsync_reg;
|
||||
assign out_blank = in_blank_reg;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst == 1) begin
|
||||
scan_x <= 0;
|
||||
scan_x_reg[0] <= 0;
|
||||
scan_x_reg[1] <= 0;
|
||||
scan_x_reg[2] <= 0;
|
||||
scan_x_reg[3] <= 0;
|
||||
scan_x_reg[4] <= 0;
|
||||
scan_x_reg[5] <= 0;
|
||||
scan_x_reg[6] <= 0;
|
||||
scan_x_reg[7] <= 0;
|
||||
scan_y <= 0;
|
||||
in_hsync_reg <= 0;
|
||||
in_vsync_reg <= 0;
|
||||
in_blank_reg <= 0;
|
||||
in_pxd_reg <= 0;
|
||||
|
||||
end else begin
|
||||
in_hsync_reg <= in_hsync;
|
||||
in_vsync_reg <= in_vsync;
|
||||
in_blank_reg <= in_blank;
|
||||
in_pxd_reg <= in_pxd;
|
||||
scan_x_reg[0] <= scan_x;
|
||||
scan_x_reg[1] <= scan_x_reg[0];
|
||||
scan_x_reg[2] <= scan_x_reg[1];
|
||||
scan_x_reg[3] <= scan_x_reg[2];
|
||||
scan_x_reg[4] <= scan_x_reg[3];
|
||||
scan_x_reg[5] <= scan_x_reg[4];
|
||||
scan_x_reg[6] <= scan_x_reg[5];
|
||||
scan_x_reg[7] <= scan_x_reg[6];
|
||||
|
||||
if (!in_blank) begin
|
||||
scan_x <= scan_x + 1;
|
||||
end
|
||||
|
||||
if (!in_blank_reg && in_blank) begin
|
||||
scan_y <= scan_y + 1;
|
||||
scan_x_reg[0] <= 0;
|
||||
scan_x_reg[1] <= 0;
|
||||
scan_x_reg[2] <= 0;
|
||||
scan_x_reg[3] <= 0;
|
||||
scan_x_reg[4] <= 0;
|
||||
scan_x_reg[5] <= 0;
|
||||
scan_x_reg[6] <= 0;
|
||||
scan_x_reg[7] <= 0;
|
||||
scan_x <= 0;
|
||||
end
|
||||
|
||||
if (in_vsync_reg && !in_vsync) begin
|
||||
scan_y <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/* Window matching state machine */
|
||||
reg [11:0] win_x_int;
|
||||
reg [11:0] win_y_int;
|
||||
reg [11:0] win_w_int;
|
||||
reg [11:0] win_h_int;
|
||||
|
||||
assign win_x_dbg = win_x_int;
|
||||
assign win_y_dbg = win_y_int;
|
||||
assign win_w_dbg = win_w_int;
|
||||
assign win_h_dbg = win_h_int;
|
||||
|
||||
localparam ST_MAT_WAITING = 5'b00000,
|
||||
ST_MAT_RX0 = 5'b00001,
|
||||
ST_MAT_RX1 = 5'b00010,
|
||||
ST_MAT_RX2 = 5'b00100,
|
||||
ST_MAT_RX3 = 5'b01000,
|
||||
ST_MAT_DATA = 5'b10000;
|
||||
reg [4:0] matcher_state;
|
||||
wire matched = matcher_state[4];
|
||||
|
||||
reg [11:0] dval_x_reg;
|
||||
reg [11:0] dval_y_reg;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst == 1) begin
|
||||
out_data_valid <= 0;
|
||||
out_data_en <= 0;
|
||||
end
|
||||
|
||||
if (rst || in_vsync) begin
|
||||
matcher_state <= ST_MAT_WAITING;
|
||||
win_x_int <= 0;
|
||||
win_y_int <= 0;
|
||||
win_w_int <= 0;
|
||||
win_h_int <= 0;
|
||||
dval_x_reg <= 0;
|
||||
dval_y_reg <= 0;
|
||||
end
|
||||
|
||||
if (!rst) begin
|
||||
if (in_blank) begin
|
||||
/* Reset state if the header is only partially contained in this frame */
|
||||
if (matcher_state != ST_MAT_DATA) begin
|
||||
matcher_state <= ST_MAT_WAITING;
|
||||
end
|
||||
|
||||
end else begin
|
||||
case (matcher_state)
|
||||
ST_MAT_WAITING: begin
|
||||
if (in_pxd_pattern_match) begin
|
||||
matcher_state <= ST_MAT_RX0;
|
||||
win_x_int <= scan_x_reg[7];
|
||||
win_y_int <= scan_y;
|
||||
end
|
||||
end
|
||||
ST_MAT_RX0: begin
|
||||
matcher_state <= ST_MAT_RX1;
|
||||
end
|
||||
ST_MAT_RX1: begin
|
||||
matcher_state <= ST_MAT_RX2;
|
||||
end
|
||||
ST_MAT_RX2: begin
|
||||
matcher_state <= ST_MAT_RX3;
|
||||
win_w_int <= in_pxd;
|
||||
end
|
||||
ST_MAT_RX3: begin
|
||||
matcher_state <= ST_MAT_DATA;
|
||||
win_h_int <= in_pxd;
|
||||
out_data_valid <= 1;
|
||||
out_data_en <= 1;
|
||||
dval_x_reg <= 13;
|
||||
dval_y_reg <= 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (matcher_state == ST_MAT_DATA) begin
|
||||
/* blank */
|
||||
if (scan_x == win_x_int && out_data_en) begin
|
||||
out_data_valid <= 1;
|
||||
dval_x_reg <= 1;
|
||||
|
||||
end else if (out_data_en) begin
|
||||
dval_x_reg <= dval_x_reg + 1;
|
||||
end
|
||||
|
||||
if (dval_x_reg == win_w_int || in_blank) begin
|
||||
out_data_valid <= 0;
|
||||
end
|
||||
|
||||
if (!in_blank_reg && in_blank) begin
|
||||
dval_y_reg <= dval_y_reg + 1;
|
||||
end
|
||||
|
||||
if (dval_y_reg == win_h_int) begin
|
||||
out_data_en <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/* Match locking process */
|
||||
reg [11:0] win_x;
|
||||
reg [11:0] win_y;
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
win_locked <= 0;
|
||||
win_w <= 0;
|
||||
win_h <= 0;
|
||||
win_x <= 0;
|
||||
win_y <= 0;
|
||||
|
||||
end else begin
|
||||
if (in_vsync_reg == 0 && in_vsync == 1) begin
|
||||
win_locked <= matched;
|
||||
|
||||
if (matched) begin
|
||||
win_w <= win_w_int;
|
||||
win_h <= win_h_int;
|
||||
win_x <= win_x_int;
|
||||
win_y <= win_y_int;
|
||||
end else begin
|
||||
win_w <= 0;
|
||||
win_h <= 0;
|
||||
win_x <= 0;
|
||||
win_y <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/* Window H/VSYNC outputs */
|
||||
reg [11:0] win_blank_ctr;
|
||||
reg [11:0] win_hsync_ctr;
|
||||
reg win_hactive;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
win_blank <= 1;
|
||||
win_hactive <= 0;
|
||||
win_blank_ctr <= 0;
|
||||
win_hsync_ctr <= 0;
|
||||
|
||||
end else begin
|
||||
if (win_locked) begin
|
||||
/* hsync */
|
||||
if (scan_x == win_x && win_hactive) begin
|
||||
win_blank <= 0;
|
||||
win_blank_ctr <= 1;
|
||||
end
|
||||
|
||||
if (win_blank == 0) begin
|
||||
win_blank_ctr <= win_blank_ctr + 1;
|
||||
end
|
||||
|
||||
if (win_blank_ctr == win_w || in_blank) begin
|
||||
win_blank <= 1;
|
||||
win_blank_ctr <= 0;
|
||||
end
|
||||
|
||||
if (win_hactive && in_blank_reg && !in_blank) begin
|
||||
win_hsync_ctr <= win_hsync_ctr + 1;
|
||||
end
|
||||
|
||||
if (scan_y == win_y) begin
|
||||
win_hactive <= 1;
|
||||
end
|
||||
|
||||
if (win_hsync_ctr == win_h && !in_blank_reg && in_blank) begin
|
||||
win_hactive <= 0;
|
||||
end
|
||||
|
||||
if (in_vsync_reg == 1 && in_vsync == 0) begin
|
||||
win_hsync_ctr <= 0;
|
||||
win_hactive <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/* Payload extractor */
|
||||
reg [23:0] in_pxd_last;
|
||||
always @(posedge clk) in_pxd_last <= rst ? 0 : in_pxd;
|
||||
|
||||
/* Compositor */
|
||||
assign out_pxd = (!win_blank && !bypass) ? win_pxd : in_pxd_reg;
|
||||
endmodule
|
||||
147
term_emu_tb_behav.wcfg
Normal file
147
term_emu_tb_behav.wcfg
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="term_emu_tb_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="glbl" />
|
||||
<top_module name="term_emu_tb" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="8950000fs"></ZoomStartTime>
|
||||
<ZoomEndTime time="9370001fs"></ZoomEndTime>
|
||||
<Cursor1Time time="9236000fs"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="175"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="154"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="28" />
|
||||
<wvobject fp_name="/term_emu_tb/testcase_id" type="array">
|
||||
<obj_property name="ElementShortName">testcase_id[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">testcase_id[31:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/clk" type="logic">
|
||||
<obj_property name="ElementShortName">clk</obj_property>
|
||||
<obj_property name="ObjectShortName">clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/rst" type="logic">
|
||||
<obj_property name="ElementShortName">rst</obj_property>
|
||||
<obj_property name="ObjectShortName">rst</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/read_pos" type="array">
|
||||
<obj_property name="ElementShortName">read_pos[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">read_pos[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/in_byte_valid" type="logic">
|
||||
<obj_property name="ElementShortName">in_byte_valid</obj_property>
|
||||
<obj_property name="ObjectShortName">in_byte_valid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/in_byte" type="array">
|
||||
<obj_property name="ElementShortName">in_byte[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">in_byte[7:0]</obj_property>
|
||||
<obj_property name="Radix">ASCIIRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/in_byte_ack" type="logic">
|
||||
<obj_property name="ElementShortName">in_byte_ack</obj_property>
|
||||
<obj_property name="ObjectShortName">in_byte_ack</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/parser_state" type="array">
|
||||
<obj_property name="ElementShortName">parser_state[8:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">parser_state[8:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/cur_fg" type="array">
|
||||
<obj_property name="ElementShortName">cur_fg[3:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">cur_fg[3:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/cur_bg" type="array">
|
||||
<obj_property name="ElementShortName">cur_bg[3:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">cur_bg[3:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/cur_bold" type="logic">
|
||||
<obj_property name="ElementShortName">cur_bold</obj_property>
|
||||
<obj_property name="ObjectShortName">cur_bold</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/cur_underline" type="logic">
|
||||
<obj_property name="ElementShortName">cur_underline</obj_property>
|
||||
<obj_property name="ObjectShortName">cur_underline</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/num_buf" type="array">
|
||||
<obj_property name="ElementShortName">num_buf[95:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">num_buf[95:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/num_buf_last" type="array">
|
||||
<obj_property name="ElementShortName">num_buf_last[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">num_buf_last[11:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/parser_action" type="array">
|
||||
<obj_property name="ElementShortName">parser_action[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">parser_action[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/parser_valid" type="logic">
|
||||
<obj_property name="ElementShortName">parser_valid</obj_property>
|
||||
<obj_property name="ObjectShortName">parser_valid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/num_buf_idx" type="array">
|
||||
<obj_property name="ElementShortName">num_buf_idx[4:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">num_buf_idx[4:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/csi_act_ctr" type="array">
|
||||
<obj_property name="ElementShortName">csi_act_ctr[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">csi_act_ctr[11:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/cursor_movement_x_pos" type="logic">
|
||||
<obj_property name="ElementShortName">cursor_movement_x_pos</obj_property>
|
||||
<obj_property name="ObjectShortName">cursor_movement_x_pos</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/cursor_movement_x_neg" type="logic">
|
||||
<obj_property name="ElementShortName">cursor_movement_x_neg</obj_property>
|
||||
<obj_property name="ObjectShortName">cursor_movement_x_neg</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/cursor_movement_y_pos" type="logic">
|
||||
<obj_property name="ElementShortName">cursor_movement_y_pos</obj_property>
|
||||
<obj_property name="ObjectShortName">cursor_movement_y_pos</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/cursor_movement_y_neg" type="logic">
|
||||
<obj_property name="ElementShortName">cursor_movement_y_neg</obj_property>
|
||||
<obj_property name="ObjectShortName">cursor_movement_y_neg</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/esc_inval" type="logic">
|
||||
<obj_property name="ElementShortName">esc_inval</obj_property>
|
||||
<obj_property name="ObjectShortName">esc_inval</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/glyph_y" type="array">
|
||||
<obj_property name="ElementShortName">glyph_y[9:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyph_y[9:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/glyph_x" type="array">
|
||||
<obj_property name="ElementShortName">glyph_x[9:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyph_x[9:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/glyph_buffer_w_valid" type="logic">
|
||||
<obj_property name="ElementShortName">glyph_buffer_w_valid</obj_property>
|
||||
<obj_property name="ObjectShortName">glyph_buffer_w_valid</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/glyph_buffer_w_addr" type="array">
|
||||
<obj_property name="ElementShortName">glyph_buffer_w_addr[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyph_buffer_w_addr[15:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_emu_tb/term_emu_dut/glyph_buffer_w_data" type="array">
|
||||
<obj_property name="ElementShortName">glyph_buffer_w_data[19:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyph_buffer_w_data[19:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
142
term_renderer_tb_behav.wcfg
Normal file
142
term_renderer_tb_behav.wcfg
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="term_renderer_tb_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="glbl" />
|
||||
<top_module name="term_renderer_tb" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="233513333fs"></ZoomStartTime>
|
||||
<ZoomEndTime time="1634593334fs"></ZoomEndTime>
|
||||
<Cursor1Time time="1401080000fs"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="175"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="158"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="26" />
|
||||
<wvobject fp_name="/term_renderer_tb/testcase_id" type="array">
|
||||
<obj_property name="ElementShortName">testcase_id[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">testcase_id[31:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#008000</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/rst" type="logic">
|
||||
<obj_property name="ElementShortName">rst</obj_property>
|
||||
<obj_property name="ObjectShortName">rst</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/clk" type="logic">
|
||||
<obj_property name="ElementShortName">clk</obj_property>
|
||||
<obj_property name="ObjectShortName">clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/in_vsync" type="logic">
|
||||
<obj_property name="ElementShortName">in_vsync</obj_property>
|
||||
<obj_property name="ObjectShortName">in_vsync</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/in_hsync" type="logic">
|
||||
<obj_property name="ElementShortName">in_hsync</obj_property>
|
||||
<obj_property name="ObjectShortName">in_hsync</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/glyphmem_data" type="array">
|
||||
<obj_property name="ElementShortName">glyphmem_data[19:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyphmem_data[19:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/glyphmem_r_addr" type="array">
|
||||
<obj_property name="ElementShortName">glyphmem_r_addr[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyphmem_r_addr[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/out_red" type="array">
|
||||
<obj_property name="ElementShortName">out_red[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">out_red[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/out_green" type="array">
|
||||
<obj_property name="ElementShortName">out_green[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">out_green[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/out_blue" type="array">
|
||||
<obj_property name="ElementShortName">out_blue[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">out_blue[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/glyph_sreg_out" type="array">
|
||||
<obj_property name="ElementShortName">glyph_sreg_out[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyph_sreg_out[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/glyph_x" type="array">
|
||||
<obj_property name="ElementShortName">glyph_x[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyph_x[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/glyph_y" type="array">
|
||||
<obj_property name="ElementShortName">glyph_y[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">glyph_y[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/px_x" type="array">
|
||||
<obj_property name="ElementShortName">px_x[5:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">px_x[5:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/px_y" type="array">
|
||||
<obj_property name="ElementShortName">px_y[5:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">px_y[5:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/in_hsync_last" type="logic">
|
||||
<obj_property name="ElementShortName">in_hsync_last</obj_property>
|
||||
<obj_property name="ObjectShortName">in_hsync_last</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/in_vsync_last" type="logic">
|
||||
<obj_property name="ElementShortName">in_vsync_last</obj_property>
|
||||
<obj_property name="ObjectShortName">in_vsync_last</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/GLYPHMEM_W" type="array">
|
||||
<obj_property name="ElementShortName">GLYPHMEM_W[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">GLYPHMEM_W[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/GLYPHMEM_H" type="array">
|
||||
<obj_property name="ElementShortName">GLYPHMEM_H[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">GLYPHMEM_H[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/FONT_GLYPH_W" type="array">
|
||||
<obj_property name="ElementShortName">FONT_GLYPH_W[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">FONT_GLYPH_W[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/FONT_GLYPH_H" type="array">
|
||||
<obj_property name="ElementShortName">FONT_GLYPH_H[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">FONT_GLYPH_H[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/FONT_GLYPH_COUNT" type="array">
|
||||
<obj_property name="ElementShortName">FONT_GLYPH_COUNT[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">FONT_GLYPH_COUNT[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/gm_data_fgcolor" type="array">
|
||||
<obj_property name="ElementShortName">gm_data_fgcolor[3:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">gm_data_fgcolor[3:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/gm_data_bgcolor" type="array">
|
||||
<obj_property name="ElementShortName">gm_data_bgcolor[3:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">gm_data_bgcolor[3:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/gm_data_bold" type="logic">
|
||||
<obj_property name="ElementShortName">gm_data_bold</obj_property>
|
||||
<obj_property name="ObjectShortName">gm_data_bold</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/term_renderer_tb/term_renderer_dut/gm_data_underline" type="logic">
|
||||
<obj_property name="ElementShortName">gm_data_underline</obj_property>
|
||||
<obj_property name="ObjectShortName">gm_data_underline</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
31216
terminus-font-4.49.1/ter-u16b.bdf
Normal file
31216
terminus-font-4.49.1/ter-u16b.bdf
Normal file
File diff suppressed because it is too large
Load diff
31216
terminus-font-4.49.1/ter-u16n.bdf
Normal file
31216
terminus-font-4.49.1/ter-u16n.bdf
Normal file
File diff suppressed because it is too large
Load diff
149
test_bench/hdmi_test_generator/hdmi_ouput_test.vhd
Normal file
149
test_bench/hdmi_test_generator/hdmi_ouput_test.vhd
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Top level design for my minimal HDMI output project
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity hdmi_output_test is
|
||||
Port ( clk50 : in STD_LOGIC;
|
||||
|
||||
hdmi_out_p : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
hdmi_out_n : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
|
||||
leds : out std_logic_vector(7 downto 0));
|
||||
end hdmi_output_test;
|
||||
|
||||
architecture Behavioral of hdmi_output_test is
|
||||
|
||||
COMPONENT vga_gen
|
||||
PORT(
|
||||
clk50 : IN std_logic;
|
||||
pixel_clock : OUT std_logic;
|
||||
red_p : OUT std_logic_vector(7 downto 0);
|
||||
green_p : OUT std_logic_vector(7 downto 0);
|
||||
blue_p : OUT std_logic_vector(7 downto 0);
|
||||
blank : OUT std_logic;
|
||||
hsync : OUT std_logic;
|
||||
vsync : OUT std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT Minimal_hdmi_symbols
|
||||
PORT(
|
||||
clk : IN std_logic;
|
||||
blank : IN std_logic;
|
||||
hsync : IN std_logic;
|
||||
vsync : IN std_logic;
|
||||
red : IN std_logic;
|
||||
green : IN std_logic;
|
||||
blue : IN std_logic;
|
||||
c0 : OUT std_logic_vector(9 downto 0);
|
||||
c1 : OUT std_logic_vector(9 downto 0);
|
||||
c2 : OUT std_logic_vector(9 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT serializers
|
||||
PORT(
|
||||
clk : IN std_logic;
|
||||
c0 : IN std_logic_vector(9 downto 0);
|
||||
c1 : IN std_logic_vector(9 downto 0);
|
||||
c2 : IN std_logic_vector(9 downto 0);
|
||||
hdmi_p : OUT std_logic_vector(3 downto 0);
|
||||
hdmi_n : OUT std_logic_vector(3 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
signal pixel_clock : std_logic;
|
||||
|
||||
signal red_p : std_logic_vector(7 downto 0);
|
||||
signal green_p : std_logic_vector(7 downto 0);
|
||||
signal blue_p : std_logic_vector(7 downto 0);
|
||||
signal blank : std_logic;
|
||||
signal hsync : std_logic;
|
||||
signal vsync : std_logic;
|
||||
|
||||
signal c0, c1, c2 : std_logic_vector(9 downto 0);
|
||||
begin
|
||||
leds <= x"AA";
|
||||
|
||||
---------------------------------------
|
||||
-- Generate a 1280x720 VGA test pattern
|
||||
---------------------------------------
|
||||
Inst_vga_gen: vga_gen PORT MAP(
|
||||
clk50 => clk50,
|
||||
pixel_clock => pixel_clock,
|
||||
red_p => red_p,
|
||||
green_p => green_p,
|
||||
blue_p => blue_p,
|
||||
blank => blank,
|
||||
hsync => hsync,
|
||||
vsync => vsync
|
||||
);
|
||||
|
||||
---------------------------------------------------
|
||||
-- Convert 9 bits of the VGA signals to the DVI-D/TMDS output
|
||||
---------------------------------------------------
|
||||
i_Minimal_hdmi_symbols: Minimal_hdmi_symbols PORT MAP(
|
||||
clk => pixel_clock,
|
||||
blank => blank,
|
||||
hsync => hsync,
|
||||
vsync => vsync,
|
||||
red => red_p(7),
|
||||
green => green_p(7),
|
||||
blue => blue_p(7),
|
||||
c0 => c0,
|
||||
c1 => c1,
|
||||
c2 => c2
|
||||
);
|
||||
|
||||
i_serializers : serializers PORT MAP (
|
||||
clk => pixel_clock,
|
||||
c0 => c0,
|
||||
c1 => c1,
|
||||
c2 => c2,
|
||||
hdmi_p => hdmi_out_p,
|
||||
hdmi_n => hdmi_out_n);
|
||||
|
||||
end Behavioral;
|
||||
|
||||
283
test_bench/hdmi_test_generator/minimal_hdmi_symbols.vhd
Normal file
283
test_bench/hdmi_test_generator/minimal_hdmi_symbols.vhd
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz<
|
||||
--
|
||||
-- Description: A minimal set of TMDS symbols - just enough to send a valid
|
||||
-- HDMI stream
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity minimal_hdmi_symbols is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
hsync, vsync, blank : in STD_LOGIC;
|
||||
red, green, blue : in STD_LOGIC;
|
||||
c0, c1, c2 : out STD_LOGIC_VECTOR (9 downto 0));
|
||||
end minimal_hdmi_symbols;
|
||||
|
||||
architecture Behavioral of minimal_hdmi_symbols is
|
||||
type a_symbol_queue is array (0 to 10) of STD_LOGIC_VECTOR (4 downto 0);
|
||||
|
||||
signal symbol_queue : a_symbol_queue := (others => (others => '0'));
|
||||
signal symbols : STD_LOGIC_VECTOR (29 downto 0) := (others => '0');
|
||||
|
||||
signal last_blank : std_logic := '0';
|
||||
signal last_vsync : std_logic := '0';
|
||||
signal last_hsync : std_logic := '0';
|
||||
|
||||
signal data_island_armed : std_logic := '0';
|
||||
signal data_island_index : unsigned(5 downto 0) := (others => '1');
|
||||
begin
|
||||
c0 <= symbols(29 downto 20);
|
||||
c1 <= symbols(19 downto 10);
|
||||
c2 <= symbols( 9 downto 0);
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
case symbol_queue(0) is
|
||||
---------------------------------------------------------------
|
||||
-- Eight TMDS encoded colours for testing
|
||||
---------------------------------------------------------------
|
||||
when "00000" => symbols <= "0111110000" & "0111110000" & "0111110000"; -- RGB 0x101010 - Black
|
||||
when "00001" => symbols <= "0111110000" & "0111110000" & "1011110000"; -- RGB 0xEF1010 - Red
|
||||
when "00010" => symbols <= "0111110000" & "1011110000" & "0111110000"; -- RGB 0x10EF10 - Green
|
||||
when "00011" => symbols <= "0111110000" & "1011110000" & "1011110000"; -- RGB 0xEFEF10 - Cyan
|
||||
when "00100" => symbols <= "1011110000" & "0111110000" & "0111110000"; -- RGB 0x1010EF - Blue
|
||||
when "00101" => symbols <= "1011110000" & "0111110000" & "1011110000"; -- RGB 0xEF10EF - Magenta
|
||||
when "00110" => symbols <= "1011110000" & "1011110000" & "0111110000"; -- RGB 0x10EFEF - Yellow
|
||||
when "00111" => symbols <= "1011110000" & "1011110000" & "1011110000"; -- RGB 0xEFEFEF - White
|
||||
---------------------------------------------------------------
|
||||
-- control symbols from 5.4.2 - part of the DVI-D standard
|
||||
---------------------------------------------------------------
|
||||
when "01000" => symbols <= "1101010100" & "1101010100" & "1101010100"; -- CTL periods
|
||||
when "01001" => symbols <= "0010101011" & "1101010100" & "1101010100"; -- Hsync
|
||||
when "01010" => symbols <= "0101010100" & "1101010100" & "1101010100"; -- vSync
|
||||
when "01011" => symbols <= "1010101011" & "1101010100" & "1101010100"; -- vSync+hSync
|
||||
---------------------------------------------------------------
|
||||
-- Symbols to signal the start of a HDMI feature
|
||||
---------------------------------------------------------------
|
||||
when "01100" => symbols <= "0101010100" & "0010101011" & "0010101011"; -- DataIslandPeamble, with VSYNC - 5.2.1.1
|
||||
when "01101" => symbols <= "0101100011" & "0100110011" & "0100110011"; -- DataIslandGuardBand, with VSYNC - 5.2.3.3
|
||||
when "01110" => symbols <= "1101010100" & "0010101011" & "1101010100"; -- VideoPramble 5.2.1.1
|
||||
when "01111" => symbols <= "1011001100" & "0100110011" & "1011001100"; -- VideoGuardBand 5.2.2.1
|
||||
|
||||
---------------------------------------------------------------
|
||||
-- From TERC4 codes in 5.4.3, and data data layout from 5.2.3.1
|
||||
--
|
||||
-- First nibble is used for the nFirstWordOfPacket (MSB) Header Bit, VSYNC, HSYNC (LSB).
|
||||
-- The packet is sent where VSYNC = '1' and HSYNC = '0', so we are left with 4 options
|
||||
-- Second nibble is used for the odd bits the four data sub-packets
|
||||
-- Third nibble is used for the even bits the four data sub-packets
|
||||
--
|
||||
-- These can be used to contruct a data island with any header
|
||||
-- and any data in subpacket 0, but all other subpackets
|
||||
-- must be 0s.
|
||||
---------------------------------------------------------------
|
||||
when "10000" => symbols <= "1011100100" & "1010011100" & "1010011100"; -- 0010 0000 0000, TERC4 coded
|
||||
when "10001" => symbols <= "1011100100" & "1010011100" & "1001100011"; -- 0010 0000 0001, TERC4 coded
|
||||
when "10010" => symbols <= "1011100100" & "1001100011" & "1010011100"; -- 0010 0000 0000, TERC4 coded
|
||||
when "10011" => symbols <= "1011100100" & "1001100011" & "1001100011"; -- 0010 0001 0001, TERC4 coded
|
||||
when "10100" => symbols <= "0110001110" & "1010011100" & "1010011100"; -- 0110 0000 0000, TERC4 coded
|
||||
when "10101" => symbols <= "0110001110" & "1010011100" & "1001100011"; -- 0110 0000 0001, TERC4 coded
|
||||
when "10110" => symbols <= "0110001110" & "1001100011" & "1010011100"; -- 0110 0001 0000, TERC4 coded
|
||||
when "10111" => symbols <= "0110001110" & "1001100011" & "1001100011"; -- 0110 0001 0001, TERC4 coded
|
||||
when "11000" => symbols <= "0110011100" & "1010011100" & "1010011100"; -- 1010 0000 0000, TERC4 coded
|
||||
when "11001" => symbols <= "0110011100" & "1010011100" & "1001100011"; -- 1010 0000 0001, TERC4 coded
|
||||
when "11010" => symbols <= "0110011100" & "1001100011" & "1010011100"; -- 1010 0001 0000, TERC4 coded
|
||||
when "11011" => symbols <= "0110011100" & "1001100011" & "1001100011"; -- 1010 0001 0001, TERC4 coded
|
||||
when "11100" => symbols <= "0101100011" & "1010011100" & "1010011100"; -- 1110 0000 0000, TERC4 coded
|
||||
when "11101" => symbols <= "0101100011" & "1010011100" & "1001100011"; -- 1110 0000 0001, TERC4 coded
|
||||
when "11110" => symbols <= "0101100011" & "1001100011" & "1010011100"; -- 1110 0001 0000, TERC4 coded
|
||||
when "11111" => symbols <= "0101100011" & "1001100011" & "1001100011"; -- 1110 0001 0001, TERC4 coded
|
||||
|
||||
when others => symbols <= (others => '0');
|
||||
end case;
|
||||
|
||||
if blank = '0' then
|
||||
-- Are we being asked to send video data? If so we need to send a peramble
|
||||
if last_blank = '1' then
|
||||
symbol_queue(10) <= "00" & blue & green & red;
|
||||
symbol_queue(9) <= "01111"; -- Video Guard Band
|
||||
symbol_queue(8) <= "01111";
|
||||
symbol_queue(7) <= "01110"; -- Video Preamble
|
||||
symbol_queue(6) <= "01110";
|
||||
symbol_queue(5) <= "01110";
|
||||
symbol_queue(4) <= "01110";
|
||||
symbol_queue(3) <= "01110";
|
||||
symbol_queue(2) <= "01110";
|
||||
symbol_queue(1) <= "01110";
|
||||
symbol_queue(0) <= "01110";
|
||||
else
|
||||
symbol_queue(0 to 9) <= symbol_queue(1 to 10);
|
||||
symbol_queue(10) <= "00" & blue & green & red;
|
||||
end if;
|
||||
else
|
||||
-- Just merge in the syncs into the control period
|
||||
case data_island_index is
|
||||
when "000000" => symbol_queue(10) <= "01100"; -- Data island preamble
|
||||
when "000001" => symbol_queue(10) <= "01100"; -- Data island preamble
|
||||
when "000010" => symbol_queue(10) <= "01100"; -- Data island preamble
|
||||
when "000011" => symbol_queue(10) <= "01100"; -- Data island preamble
|
||||
when "000100" => symbol_queue(10) <= "01100"; -- Data island preamble
|
||||
when "000101" => symbol_queue(10) <= "01100"; -- Data island preamble
|
||||
when "000110" => symbol_queue(10) <= "01100"; -- Data island preamble
|
||||
when "000111" => symbol_queue(10) <= "01100"; -- Data island preamble
|
||||
when "001000" => symbol_queue(10) <= "01101"; -- Data island Guard Band
|
||||
when "001001" => symbol_queue(10) <= "01101"; -- Data island Guard Band
|
||||
|
||||
|
||||
-------------------------
|
||||
-- For a YCC mode AVI Infoframe Data Island
|
||||
-------------------------
|
||||
-- Data Island (0-7)
|
||||
when "001010" => symbol_queue(10) <= "10011"; -- First word
|
||||
when "001011" => symbol_queue(10) <= "11111";
|
||||
when "001100" => symbol_queue(10) <= "11001";
|
||||
when "001101" => symbol_queue(10) <= "11000";
|
||||
when "001110" => symbol_queue(10) <= "11000";
|
||||
when "001111" => symbol_queue(10) <= "11000";
|
||||
when "010000" => symbol_queue(10) <= "11000";
|
||||
when "010001" => symbol_queue(10) <= "11110";
|
||||
-- Data Island (8-15)
|
||||
when "010010" => symbol_queue(10) <= "11000";
|
||||
when "010011" => symbol_queue(10) <= "11100";
|
||||
when "010100" => symbol_queue(10) <= "11000";
|
||||
when "010101" => symbol_queue(10) <= "11000";
|
||||
when "010110" => symbol_queue(10) <= "11000";
|
||||
when "010111" => symbol_queue(10) <= "11000";
|
||||
when "011000" => symbol_queue(10) <= "11000";
|
||||
when "011001" => symbol_queue(10) <= "11000";
|
||||
-- Data Island (16-23)
|
||||
when "011010" => symbol_queue(10) <= "11100";
|
||||
when "011011" => symbol_queue(10) <= "11000";
|
||||
when "011100" => symbol_queue(10) <= "11100";
|
||||
when "011101" => symbol_queue(10) <= "11100";
|
||||
when "011110" => symbol_queue(10) <= "11000";
|
||||
when "011111" => symbol_queue(10) <= "11000";
|
||||
when "100000" => symbol_queue(10) <= "11000";
|
||||
when "100001" => symbol_queue(10) <= "11000";
|
||||
-- Data Island (24-31)
|
||||
when "100010" => symbol_queue(10) <= "11000";
|
||||
when "100011" => symbol_queue(10) <= "11000";
|
||||
when "100100" => symbol_queue(10) <= "11100";
|
||||
when "100101" => symbol_queue(10) <= "11000";
|
||||
when "100110" => symbol_queue(10) <= "11010";
|
||||
when "100111" => symbol_queue(10) <= "11100";
|
||||
when "101000" => symbol_queue(10) <= "11111";
|
||||
when "101001" => symbol_queue(10) <= "11110";
|
||||
|
||||
-------------------------
|
||||
-- For a NULL Data Island
|
||||
-------------------------
|
||||
-- Data Island (0-7)
|
||||
-- when "001010" => symbol_queue(10) <= "10000"; -- First word
|
||||
-- when "001011" => symbol_queue(10) <= "11000";
|
||||
-- when "001100" => symbol_queue(10) <= "11000";
|
||||
-- when "001101" => symbol_queue(10) <= "11000";
|
||||
-- when "001110" => symbol_queue(10) <= "11000";
|
||||
-- when "001111" => symbol_queue(10) <= "11000";
|
||||
-- when "010000" => symbol_queue(10) <= "11000";
|
||||
-- when "010001" => symbol_queue(10) <= "11000";
|
||||
-- Data Island (8-15)
|
||||
-- when "010010" => symbol_queue(10) <= "11000";
|
||||
-- when "010011" => symbol_queue(10) <= "11000";
|
||||
-- when "010100" => symbol_queue(10) <= "11000";
|
||||
-- when "010101" => symbol_queue(10) <= "11000";
|
||||
-- when "010110" => symbol_queue(10) <= "11000";
|
||||
-- when "010111" => symbol_queue(10) <= "11000";
|
||||
-- when "011000" => symbol_queue(10) <= "11000";
|
||||
-- when "011001" => symbol_queue(10) <= "11000";
|
||||
-- Data Island (16-23)
|
||||
-- when "011010" => symbol_queue(10) <= "11000";
|
||||
-- when "011011" => symbol_queue(10) <= "11000";
|
||||
-- when "011100" => symbol_queue(10) <= "11000";
|
||||
-- when "011101" => symbol_queue(10) <= "11000";
|
||||
-- when "011110" => symbol_queue(10) <= "11000";
|
||||
-- when "011111" => symbol_queue(10) <= "11000";
|
||||
-- when "100000" => symbol_queue(10) <= "11000";
|
||||
-- when "100001" => symbol_queue(10) <= "11000";
|
||||
-- Data Island (24-31)
|
||||
-- when "100010" => symbol_queue(10) <= "11000";
|
||||
-- when "100011" => symbol_queue(10) <= "11000";
|
||||
-- when "100100" => symbol_queue(10) <= "11000";
|
||||
-- when "100101" => symbol_queue(10) <= "11000";
|
||||
-- when "100110" => symbol_queue(10) <= "11000";
|
||||
-- when "100111" => symbol_queue(10) <= "11000";
|
||||
-- when "101000" => symbol_queue(10) <= "11000";
|
||||
-- when "101001" => symbol_queue(10) <= "11000";
|
||||
|
||||
-- Trailing guard band
|
||||
when "101010" => symbol_queue(10) <= "01101"; -- Data island Guard Band
|
||||
when "101011" => symbol_queue(10) <= "01101"; -- Data island Guard Band
|
||||
-- There has to be four CTL symbols before the next block of video our data,
|
||||
-- But that won't be a problem for us, we will have the rest of the vertical
|
||||
-- Blanking interval
|
||||
when others => symbol_queue(10) <= "010" & Vsync & Hsync;
|
||||
end case;
|
||||
|
||||
symbol_queue(0 to 9) <= symbol_queue(1 to 10);
|
||||
end if;
|
||||
|
||||
if data_island_index /= "111111" then
|
||||
data_island_index <= data_island_index + 1;
|
||||
end if;
|
||||
|
||||
-- If we see the rising edge of vsync we need to send
|
||||
-- a data island the next time we see the hsync signal
|
||||
-- drop.
|
||||
if last_vsync = '0' and vsync = '1' then
|
||||
data_island_armed <= '1';
|
||||
end if;
|
||||
|
||||
if data_island_armed = '1' and last_hsync = '1' and hsync = '0' then
|
||||
data_island_index <= (others => '0');
|
||||
data_island_armed <= '0';
|
||||
end if;
|
||||
|
||||
last_blank <= blank;
|
||||
last_hsync <= hsync;
|
||||
last_vsync <= vsync;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
|
||||
165
test_bench/hdmi_test_generator/serializers.vhd
Normal file
165
test_bench/hdmi_test_generator/serializers.vhd
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Convert 3x 10-bit symbols to three serial channels and the clock channel.
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity serializers is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
c0 : in STD_LOGIC_VECTOR (9 downto 0);
|
||||
c1 : in STD_LOGIC_VECTOR (9 downto 0);
|
||||
c2 : in STD_LOGIC_VECTOR (9 downto 0);
|
||||
hdmi_p : out STD_LOGIC_VECTOR (3 downto 0);
|
||||
hdmi_n : out STD_LOGIC_VECTOR (3 downto 0));
|
||||
end serializers;
|
||||
|
||||
architecture Behavioral of serializers is
|
||||
-- For holding the outward bound TMDS symbols in the slow and fast domain
|
||||
signal c0_high_speed : std_logic_vector(9 downto 0) := (others => '0');
|
||||
signal c1_high_speed : std_logic_vector(9 downto 0) := (others => '0');
|
||||
signal c2_high_speed : std_logic_vector(9 downto 0) := (others => '0');
|
||||
signal clk_high_speed : std_logic_vector(9 downto 0) := (others => '0');
|
||||
signal c2_output_bits : std_logic_vector(1 downto 0) := "00";
|
||||
signal c1_output_bits : std_logic_vector(1 downto 0) := "00";
|
||||
signal c0_output_bits : std_logic_vector(1 downto 0) := "00";
|
||||
signal clk_output_bits : std_logic_vector(1 downto 0) := "00";
|
||||
|
||||
-- Controlling the transfers into the high speed domain
|
||||
signal latch_high_speed : std_logic_vector(4 downto 0) := "00001";
|
||||
|
||||
-- From the DDR outputs to the output buffers
|
||||
signal c0_serial, c1_serial, c2_serial, clk_serial : std_logic;
|
||||
|
||||
-- For generating the x5 clocks
|
||||
signal clk_x5, clk_x5_n, clk_x5_unbuffered : std_logic;
|
||||
signal clk_feedback : std_logic;
|
||||
|
||||
-- To glue the HSYNC and VSYNC into the control character.
|
||||
signal syncs : std_logic_vector(1 downto 0);
|
||||
begin
|
||||
|
||||
process(clk_x5)
|
||||
begin
|
||||
---------------------------------------------------------------
|
||||
-- Now take the 10-bit words and take it into the high-speed
|
||||
-- clock domain once every five cycles.
|
||||
--
|
||||
-- Then send out two bits every clock cycle using DDR output
|
||||
-- registers.
|
||||
---------------------------------------------------------------
|
||||
if rising_edge(clk_x5) then
|
||||
c0_output_bits <= c0_high_speed(1 downto 0);
|
||||
c1_output_bits <= c1_high_speed(1 downto 0);
|
||||
c2_output_bits <= c2_high_speed(1 downto 0);
|
||||
clk_output_bits <= clk_high_speed(1 downto 0);
|
||||
|
||||
if latch_high_speed(0) = '1' then
|
||||
c0_high_speed <= c0;
|
||||
c1_high_speed <= c1;
|
||||
c2_high_speed <= c2;
|
||||
clk_high_speed <= "0000011111";
|
||||
else
|
||||
c0_high_speed <= "00" & c0_high_speed(9 downto 2);
|
||||
c1_high_speed <= "00" & c1_high_speed(9 downto 2);
|
||||
c2_high_speed <= "00" & c2_high_speed(9 downto 2);
|
||||
clk_high_speed <= "00" & clk_high_speed(9 downto 2);
|
||||
end if;
|
||||
latch_high_speed <= latch_high_speed(0) & latch_high_speed(4 downto 1);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Convert the TMDS codes into a serial stream, two bits at a time
|
||||
------------------------------------------------------------------
|
||||
clk_x5_n <= not clk_x5;
|
||||
c0_to_serial: ODDR2
|
||||
generic map(DDR_ALIGNMENT => "C0", INIT => '0', SRTYPE => "ASYNC")
|
||||
port map (C0 => clk_x5, C1 => clk_x5_n, CE => '1', R => '0', S => '0',
|
||||
D0 => C0_output_bits(0), D1 => C0_output_bits(1), Q => c0_serial);
|
||||
OBUFDS_c0 : OBUFDS port map ( O => hdmi_p(0), OB => hdmi_n(0), I => c0_serial);
|
||||
|
||||
c1_to_serial: ODDR2
|
||||
generic map(DDR_ALIGNMENT => "C0", INIT => '0', SRTYPE => "ASYNC")
|
||||
port map (C0 => clk_x5, C1 => clk_x5_n, CE => '1', R => '0', S => '0',
|
||||
D0 => C1_output_bits(0), D1 => C1_output_bits(1), Q => c1_serial);
|
||||
OBUFDS_c1 : OBUFDS port map ( O => hdmi_p(1), OB => hdmi_n(1), I => c1_serial);
|
||||
|
||||
c2_to_serial: ODDR2
|
||||
generic map(DDR_ALIGNMENT => "C0", INIT => '0', SRTYPE => "ASYNC")
|
||||
port map (C0 => clk_x5, C1 => clk_x5_n, CE => '1', R => '0', S => '0',
|
||||
D0 => C2_output_bits(0), D1 => C2_output_bits(1), Q => c2_serial);
|
||||
OBUFDS_c2 : OBUFDS port map ( O => hdmi_p(2), OB => hdmi_n(2), I => c2_serial);
|
||||
|
||||
clk_to_serial: ODDR2
|
||||
generic map(DDR_ALIGNMENT => "C0", INIT => '0', SRTYPE => "ASYNC")
|
||||
port map (C0 => clk_x5, C1 => clk_x5_n, CE => '1', R => '0', S => '0',
|
||||
D0 => Clk_output_bits(0), D1 => Clk_output_bits(1), Q => clk_serial);
|
||||
OBUFDS_clk : OBUFDS port map ( O => hdmi_p(3), OB => hdmi_n(3), I => clk_serial);
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Use a PLL to generate a x5 clock, which is used to drive
|
||||
-- the DDR registers.This allows 10 bits to be sent for every
|
||||
-- pixel clock
|
||||
------------------------------------------------------------------
|
||||
PLL_BASE_inst : PLL_BASE
|
||||
generic map (
|
||||
CLKFBOUT_MULT => 10,
|
||||
CLKOUT0_DIVIDE => 2, CLKOUT0_PHASE => 0.0, -- Output 5x original frequency
|
||||
CLK_FEEDBACK => "CLKFBOUT",
|
||||
CLKIN_PERIOD => 13.33,
|
||||
DIVCLK_DIVIDE => 1
|
||||
)
|
||||
port map (
|
||||
CLKFBOUT => clk_feedback,
|
||||
CLKOUT0 => clk_x5_unbuffered,
|
||||
CLKFBIN => clk_feedback,
|
||||
CLKIN => clk,
|
||||
RST => '0'
|
||||
);
|
||||
|
||||
BUFG_pclkx5 : BUFG port map ( I => clk_x5_unbuffered, O => clk_x5);
|
||||
|
||||
end Behavioral;
|
||||
|
||||
90
test_bench/hdmi_test_generator/vga_clocking.vhd
Normal file
90
test_bench/hdmi_test_generator/vga_clocking.vhd
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz<
|
||||
--
|
||||
-- Description: Generate a 40Mhz Pixel clock from the 50Mhz input
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity vga_clocking is
|
||||
Port ( clk50 : in STD_LOGIC;
|
||||
pixel_clock : out STD_LOGIC);
|
||||
end vga_clocking;
|
||||
|
||||
architecture Behavioral of vga_clocking is
|
||||
signal clock_x1 : std_logic;
|
||||
signal clock_x1_unbuffered : std_logic;
|
||||
signal clk_feedback : std_logic;
|
||||
signal clk50_buffered : std_logic;
|
||||
signal pll_locked : std_logic;
|
||||
begin
|
||||
pixel_clock <= clock_x1;
|
||||
|
||||
-- Multiply clk50m by 15, then divide by 10 for the 75 MHz pixel clock
|
||||
-- Because the all come from the same PLL the will all be in phase
|
||||
PLL_BASE_inst : PLL_BASE
|
||||
generic map (
|
||||
CLKFBOUT_MULT => 16,
|
||||
CLKOUT0_DIVIDE => 20, CLKOUT0_PHASE => 0.0, -- Output pixel clock, 1.5x original frequency
|
||||
CLK_FEEDBACK => "CLKFBOUT", -- Clock source to drive CLKFBIN ("CLKFBOUT" or "CLKOUT0")
|
||||
CLKIN_PERIOD => 20.0, -- IMPORTANT! 20.00 => 50MHz
|
||||
DIVCLK_DIVIDE => 1 -- Division value for all output clocks (1-52)
|
||||
)
|
||||
port map (
|
||||
CLKFBOUT => clk_feedback,
|
||||
CLKOUT0 => clock_x1_unbuffered,
|
||||
CLKOUT1 => open,
|
||||
CLKOUT2 => open,
|
||||
CLKOUT3 => open,
|
||||
CLKOUT4 => open,
|
||||
CLKOUT5 => open,
|
||||
LOCKED => pll_locked,
|
||||
CLKFBIN => clk_feedback,
|
||||
CLKIN => clk50_buffered,
|
||||
RST => '0' -- 1-bit input: Reset input
|
||||
);
|
||||
|
||||
BUFG_clk : BUFG port map ( I => clk50, O => clk50_buffered);
|
||||
BUFG_pclock : BUFG port map ( I => clock_x1_unbuffered, O => clock_x1);
|
||||
|
||||
end Behavioral;
|
||||
143
test_bench/hdmi_test_generator/vga_gen.vhd
Normal file
143
test_bench/hdmi_test_generator/vga_gen.vhd
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Description: Generates a test 1280x720 signal
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity vga_gen is
|
||||
Port ( clk50 : in STD_LOGIC;
|
||||
pixel_clock : out std_logic;
|
||||
|
||||
red_p : out STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
|
||||
green_p : out STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
|
||||
blue_p : out STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
|
||||
blank : out STD_LOGIC := '0';
|
||||
hsync : out STD_LOGIC := '0';
|
||||
vsync : out STD_LOGIC := '0');
|
||||
end vga_gen;
|
||||
|
||||
architecture Behavioral of vga_gen is
|
||||
COMPONENT vga_clocking
|
||||
PORT( clk50 : IN std_logic;
|
||||
pixel_clock : OUT std_logic);
|
||||
END COMPONENT;
|
||||
|
||||
constant h_rez : natural := 800;
|
||||
constant h_sync_start : natural := 800+40;
|
||||
constant h_sync_end : natural := 800+40+128;
|
||||
constant h_max : natural := 1056;
|
||||
signal h_count : unsigned(11 downto 0) := (others => '0');
|
||||
signal h_offset : unsigned(7 downto 0) := (others => '0');
|
||||
|
||||
constant v_rez : natural := 600;
|
||||
constant v_sync_start : natural := 600+1;
|
||||
constant v_sync_end : natural := 600+1+4;
|
||||
constant v_max : natural := 628;
|
||||
signal v_count : unsigned(11 downto 0) := x"250";
|
||||
signal v_offset : unsigned(7 downto 0) := (others => '0');
|
||||
signal clk40 : std_logic;
|
||||
begin
|
||||
|
||||
Inst_clocking: vga_clocking PORT MAP(
|
||||
clk50 => clk50,
|
||||
pixel_clock => clk40
|
||||
);
|
||||
pixel_clock <= clk40;
|
||||
|
||||
|
||||
process(clk40)
|
||||
begin
|
||||
if rising_edge(clk40) then
|
||||
if h_count < h_rez and v_count < v_rez then
|
||||
red_p <= std_logic_vector(h_count(7 downto 0)+h_offset);
|
||||
green_p <= std_logic_vector(v_count(7 downto 0)+v_offset);
|
||||
blue_p <= std_logic_vector(h_count(7 downto 0)+v_count(7 downto 0));
|
||||
blank <= '0';
|
||||
if h_count = 0 or h_count = h_rez-1 then
|
||||
red_p <= (others => '1');
|
||||
green_p <= (others => '1');
|
||||
blue_p <= (others => '1');
|
||||
end if;
|
||||
if v_count = 0 or v_count = v_rez-1 then
|
||||
red_p <= (others => '1');
|
||||
green_p <= (others => '0');
|
||||
blue_p <= (others => '0');
|
||||
end if;
|
||||
else
|
||||
red_p <= (others => '0');
|
||||
green_p <= (others => '0');
|
||||
blue_p <= (others => '0');
|
||||
blank <= '1';
|
||||
end if;
|
||||
|
||||
if h_count >= h_sync_start and h_count < h_sync_end then
|
||||
hsync <= '1';
|
||||
else
|
||||
hsync <= '0';
|
||||
end if;
|
||||
|
||||
if v_count >= v_sync_start and v_count < v_sync_end then
|
||||
vsync <= '1';
|
||||
else
|
||||
vsync <= '0';
|
||||
end if;
|
||||
|
||||
if h_count = h_max then
|
||||
h_count <= (others => '0');
|
||||
if v_count = v_max then
|
||||
h_offset <= h_offset + 1;
|
||||
v_offset <= v_offset + 1;
|
||||
v_count <= (others => '0');
|
||||
else
|
||||
v_count <= v_count+1;
|
||||
end if;
|
||||
else
|
||||
h_count <= h_count+1;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
|
||||
128
test_bench/spi_regfile_tb.v
Normal file
128
test_bench/spi_regfile_tb.v
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module spi_regfile_tb();
|
||||
|
||||
localparam period = 10;
|
||||
parameter WORDSIZE = 8;
|
||||
reg clk, rst;
|
||||
|
||||
reg sck, sdi, ncs;
|
||||
wire sdo;
|
||||
|
||||
reg [15:0] spi_data_in;
|
||||
wire [15:0] spi_data_out;
|
||||
wire [15:0] spi_status_word = 16'h3141;
|
||||
wire [15:0] spi_cmd_word;
|
||||
wire spi_cmd_begin, spi_cmd_active, spi_cmd_step;
|
||||
wire [19:0] spi_cmd_idx;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
/* rst set below */
|
||||
sck = 0;
|
||||
sdi = 0;
|
||||
ncs = 1;
|
||||
forever #period clk = ~clk;
|
||||
end
|
||||
|
||||
integer i;
|
||||
integer j;
|
||||
integer k;
|
||||
integer testcase;
|
||||
reg [WORDSIZE-1:0] sim_rxdata [1:4];
|
||||
reg [WORDSIZE-1:0] sim_txdata [1:4];
|
||||
reg [WORDSIZE-1:0] sim_txbuf;
|
||||
initial begin
|
||||
sim_rxdata[1] = 16'h523a;
|
||||
sim_rxdata[2] = 16'hbeef;
|
||||
sim_rxdata[3] = 16'h7721;
|
||||
sim_rxdata[4] = 16'h0108;
|
||||
|
||||
sim_txdata[1] = 16'h1234;
|
||||
sim_txdata[2] = 16'h5678;
|
||||
sim_txdata[3] = 16'h9abc;
|
||||
sim_txdata[4] = 16'hdef9;
|
||||
|
||||
for (j=1; j<=4; j=j+1) begin
|
||||
$display("TC-%d: rx/tx %d word", j, j);
|
||||
testcase = j;
|
||||
|
||||
rst = 1;
|
||||
repeat(2) @(posedge clk);
|
||||
rst = 0;
|
||||
@(posedge clk);
|
||||
|
||||
spi_data_in = sim_txdata[1];
|
||||
@(posedge clk);
|
||||
|
||||
ncs = 0;
|
||||
@(posedge clk);
|
||||
if (spi_cmd_begin) $finish;
|
||||
if (spi_cmd_active) $finish;
|
||||
if (spi_cmd_step) $finish;
|
||||
|
||||
for (k=1; k<=j; k=k+1) begin
|
||||
sim_txbuf = 0;
|
||||
|
||||
for (i=1; i<=WORDSIZE; i=i+1) begin
|
||||
sdi = sim_rxdata[k][WORDSIZE-i];
|
||||
sck = 0;
|
||||
|
||||
@(posedge clk);
|
||||
|
||||
sck = 1;
|
||||
sim_txbuf[WORDSIZE-i] = sdo;
|
||||
|
||||
if (i == WORDSIZE) begin
|
||||
spi_data_in = sim_txdata[k+1];
|
||||
end
|
||||
|
||||
if (spi_cmd_step) $finish;
|
||||
|
||||
@(posedge clk);
|
||||
end
|
||||
|
||||
if (!spi_cmd_active) $finish;
|
||||
if (k == 1 && !spi_cmd_begin) $finish;
|
||||
if (k > 1 && spi_cmd_begin) $finish;
|
||||
if (k == 1 && spi_cmd_step) $finish;
|
||||
if (k > 1 && !spi_cmd_step) $finish;
|
||||
if (spi_cmd_word != sim_rxdata[1]) $finish;
|
||||
if (k > 1 && spi_data_out != sim_rxdata[k]) $finish;
|
||||
if (k == 1 && sim_txbuf != 16'h3141) $finish;
|
||||
if (k > 1 && sim_txbuf != sim_txdata[k]) $finish;
|
||||
if (spi_cmd_idx != k-1) $finish;
|
||||
end
|
||||
|
||||
sck = 0;
|
||||
@(posedge clk);
|
||||
ncs = 1;
|
||||
@(posedge clk);
|
||||
|
||||
if (spi_cmd_active) $finish;
|
||||
if (spi_cmd_step) $finish;
|
||||
if (spi_cmd_begin) $finish;
|
||||
|
||||
repeat(10) @(posedge clk);
|
||||
end
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
spi_regfile spi_regfile_dut (
|
||||
.clk(clk), .rst(rst),
|
||||
|
||||
.sck(sck), .sdi(sdi), .sdo(sdo), .ncs(ncs),
|
||||
|
||||
.spi_data_in(spi_data_in),
|
||||
.spi_data_out(spi_data_out),
|
||||
|
||||
.spi_status_word(spi_status_word),
|
||||
.spi_cmd_word(spi_cmd_word),
|
||||
.spi_cmd_begin(spi_cmd_begin),
|
||||
.spi_cmd_active(spi_cmd_active),
|
||||
.spi_cmd_step(spi_cmd_step),
|
||||
.spi_cmd_idx(spi_cmd_idx)
|
||||
);
|
||||
|
||||
endmodule
|
||||
110
test_bench/tb_audio_to_db.vhd
Normal file
110
test_bench/tb_audio_to_db.vhd
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: tb_audio_to_db - Behavioral
|
||||
--
|
||||
-- Description: A testbench for the audio sample to db level calculation
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
----------------------------------------------------------------------------------
|
||||
----- Want to say thanks? --------------------------------------------------------
|
||||
----------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity tb_audio_to_db is
|
||||
end tb_audio_to_db;
|
||||
|
||||
architecture Behavioral of tb_audio_to_db is
|
||||
component audio_to_db is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
|
||||
in_channel : in STD_LOGIC_VECTOR (2 downto 0);
|
||||
in_de : in STD_LOGIC;
|
||||
in_sample : in STD_LOGIC_VECTOR (23 downto 0);
|
||||
|
||||
out_channel : out STD_LOGIC_VECTOR (2 downto 0);
|
||||
out_de : out STD_LOGIC;
|
||||
out_level : out STD_LOGIC_VECTOR (5 downto 0));
|
||||
end component;
|
||||
|
||||
signal clk : STD_LOGIC := '0';
|
||||
|
||||
signal in_channel : STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
|
||||
signal in_de : STD_LOGIC := '1';
|
||||
signal in_sample : STD_LOGIC_VECTOR (23 downto 0) := (others => '0');
|
||||
|
||||
signal out_channel : STD_LOGIC_VECTOR (2 downto 0);
|
||||
signal out_de : STD_LOGIC;
|
||||
signal out_level : STD_LOGIC_VECTOR (5 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
process
|
||||
begin
|
||||
wait for 5 ns;
|
||||
clk <= '1';
|
||||
wait for 5 ns;
|
||||
clk <= '0';
|
||||
end process;
|
||||
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
in_de <= '1';
|
||||
in_sample <= in_sample(in_sample'high-1 downto 0) & not in_sample(in_sample'high);
|
||||
wait until rising_edge(clk);
|
||||
in_de <= '0';
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
end process;
|
||||
|
||||
uut: audio_to_db port map (
|
||||
clk => clk,
|
||||
in_channel => in_channel,
|
||||
in_de => in_de,
|
||||
in_sample => in_sample,
|
||||
|
||||
out_channel => out_channel,
|
||||
out_de => out_de,
|
||||
out_level => out_level);
|
||||
|
||||
end Behavioral;
|
||||
147
test_bench/tb_convert_yCbCr_to_RGB.vhd
Normal file
147
test_bench/tb_convert_yCbCr_to_RGB.vhd
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Description: A testbench for YCbCr to RGB decoding
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if using
|
||||
-- arithmetic functions with Signed or Unsigned values
|
||||
--use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if instantiating
|
||||
-- any Xilinx leaf cells in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity tb_convert_yCbCr_to_RGB is
|
||||
end tb_convert_yCbCr_to_RGB;
|
||||
|
||||
architecture Behavioral of tb_convert_yCbCr_to_RGB is
|
||||
component conversion_YCbCr_to_RGB is
|
||||
port ( clk : in std_Logic;
|
||||
input_is_YCbCr : in std_Logic;
|
||||
|
||||
------------------------
|
||||
in_blank : in std_logic;
|
||||
in_hsync : in std_logic;
|
||||
in_vsync : in std_logic;
|
||||
in_U : in std_logic_vector(11 downto 0); -- B or Cb
|
||||
in_V : in std_logic_vector(11 downto 0); -- G or Y
|
||||
in_W : in std_logic_vector(11 downto 0); -- R or Cr
|
||||
|
||||
------------------------
|
||||
out_blank : out std_logic;
|
||||
out_hsync : out std_logic;
|
||||
out_vsync : out std_logic;
|
||||
out_R : out std_logic_vector(11 downto 0);
|
||||
out_G : out std_logic_vector(11 downto 0);
|
||||
out_B : out std_logic_vector(11 downto 0));
|
||||
end component;
|
||||
|
||||
signal clk : std_Logic := '0';
|
||||
signal input_is_YCbCr : std_Logic := '0';
|
||||
signal in_blank : std_logic := '0';
|
||||
signal in_hsync : std_logic := '0';
|
||||
signal in_vsync : std_logic := '0';
|
||||
signal in_U : std_logic_vector(11 downto 0) := x"800"; -- B or Cb
|
||||
signal in_V : std_logic_vector(11 downto 0) := x"800"; -- G or Y
|
||||
signal in_W : std_logic_vector(11 downto 0) := x"800"; -- R or Cr
|
||||
signal out_blank : std_logic := '0';
|
||||
signal out_hsync : std_logic := '0';
|
||||
signal out_vsync : std_logic := '0';
|
||||
signal out_R : std_logic_vector(11 downto 0);
|
||||
signal out_G : std_logic_vector(11 downto 0);
|
||||
signal out_B : std_logic_vector(11 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
process
|
||||
begin
|
||||
wait for 5 ns;
|
||||
clk <= not clk;
|
||||
end process;
|
||||
|
||||
stim: process
|
||||
begin
|
||||
wait for 100 ns;
|
||||
in_U <= x"100";
|
||||
wait for 100 ns;
|
||||
in_U <= x"EFF";
|
||||
wait for 100 ns;
|
||||
in_U <= x"800";
|
||||
|
||||
wait for 100 ns;
|
||||
in_V <= x"100";
|
||||
wait for 100 ns;
|
||||
in_V <= x"EFF";
|
||||
wait for 100 ns;
|
||||
in_V <= x"800";
|
||||
|
||||
wait for 100 ns;
|
||||
in_W <= x"100";
|
||||
wait for 100 ns;
|
||||
in_W <= x"EFF";
|
||||
wait for 100 ns;
|
||||
in_W <= x"800";
|
||||
|
||||
end process;
|
||||
uut: conversion_YCbCr_to_RGB port map (
|
||||
clk => clk,
|
||||
input_is_YCbCr => '1',
|
||||
------------------------
|
||||
in_blank => in_blank,
|
||||
in_hsync => in_hsync,
|
||||
in_vsync => in_vsync,
|
||||
in_U => in_U,
|
||||
in_V => in_V,
|
||||
in_W => in_W,
|
||||
------------------------
|
||||
out_blank => out_blank,
|
||||
out_hsync => out_hsync,
|
||||
out_vsync => out_vsync,
|
||||
out_R => out_R,
|
||||
out_G => out_G,
|
||||
out_B => out_B);
|
||||
|
||||
end Behavioral;
|
||||
313
test_bench/tb_hdmi_decode.vhd
Normal file
313
test_bench/tb_hdmi_decode.vhd
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Engineer: Mike Field <hamster@snap.net.nz>
|
||||
--
|
||||
-- Module Name: tb_hdmi_decode - Behavioral
|
||||
--
|
||||
-- Description: A testbench for testing HDMI decoding
|
||||
--
|
||||
------------------------------------------------------------------------------------
|
||||
-- The MIT License (MIT)
|
||||
--
|
||||
-- Copyright (c) 2015 Michael Alan Field
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
----------------------------------------------------------------------------------
|
||||
----- Want to say thanks? ----------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
--
|
||||
-- This design has taken many hours - with the industry metric of 30 lines
|
||||
-- per day, it is equivalent to about 6 months of work. I'm more than happy
|
||||
-- to share it if you can make use of it. It is released under the MIT license,
|
||||
-- so you are not under any onus to say thanks, but....
|
||||
--
|
||||
-- If you what to say thanks for this design how about trying PayPal?
|
||||
-- Educational use - Enough for a beer
|
||||
-- Hobbyist use - Enough for a pizza
|
||||
-- Research use - Enough to take the family out to dinner
|
||||
-- Commercial use - A weeks pay for an engineer (I wish!)
|
||||
------------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity tb_hdmi_decode is
|
||||
end tb_hdmi_decode;
|
||||
|
||||
architecture Behavioral of tb_hdmi_decode is
|
||||
component hdmi_design is
|
||||
Port (
|
||||
clk100 : in STD_LOGIC;
|
||||
-- Control signals
|
||||
led : out std_logic_vector(7 downto 0);
|
||||
sw : in std_logic_vector(7 downto 0) :=(others => '0');
|
||||
debug_pmod : out std_logic_vector(7 downto 0) :=(others => '0');
|
||||
|
||||
--HDMI input signals
|
||||
hdmi_rx_cec : inout std_logic;
|
||||
hdmi_rx_hpa : out std_logic;
|
||||
hdmi_rx_scl : in std_logic;
|
||||
hdmi_rx_sda : inout std_logic;
|
||||
hdmi_rx_txen : out std_logic;
|
||||
hdmi_rx_clk_n : in std_logic;
|
||||
hdmi_rx_clk_p : in std_logic;
|
||||
hdmi_rx_n : in std_logic_vector(2 downto 0);
|
||||
hdmi_rx_p : in std_logic_vector(2 downto 0);
|
||||
|
||||
--- HDMI out
|
||||
hdmi_tx_cec : inout std_logic;
|
||||
hdmi_tx_clk_n : out std_logic;
|
||||
hdmi_tx_clk_p : out std_logic;
|
||||
hdmi_tx_hpd : in std_logic;
|
||||
hdmi_tx_rscl : inout std_logic;
|
||||
hdmi_tx_rsda : inout std_logic;
|
||||
hdmi_tx_p : out std_logic_vector(2 downto 0);
|
||||
hdmi_tx_n : out std_logic_vector(2 downto 0);
|
||||
-- For dumping symbols
|
||||
rs232_tx : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component hdmi_output_test is
|
||||
Port ( clk50 : in STD_LOGIC;
|
||||
|
||||
hdmi_out_p : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
hdmi_out_n : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
|
||||
leds : out std_logic_vector(7 downto 0));
|
||||
end component;
|
||||
|
||||
|
||||
signal clk : std_logic := '0';
|
||||
signal clk50 : std_logic := '1';
|
||||
signal led : std_logic_vector(7 downto 0);
|
||||
signal hdmi_rx_cec : std_logic;
|
||||
signal hdmi_rx_hpa : std_logic;
|
||||
signal hdmi_rx_scl : std_logic;
|
||||
signal hdmi_rx_sda : std_logic;
|
||||
signal hdmi_rx_txen : std_logic;
|
||||
signal hdmi_rx_clk_n : std_logic;
|
||||
signal hdmi_rx_clk_p : std_logic;
|
||||
signal hdmi2_rx_clk_n : std_logic := '1';
|
||||
signal hdmi2_rx_clk_p : std_logic := '0';
|
||||
signal hdmi_out_n : std_logic_vector(3 downto 0);
|
||||
signal hdmi_out_p : std_logic_vector(3 downto 0);
|
||||
signal hdmi_rx_n : std_logic_vector(2 downto 0);
|
||||
signal hdmi_rx_p : std_logic_vector(2 downto 0);
|
||||
signal hdmi_tx_cec : std_logic;
|
||||
signal hdmi_tx_clk_n : std_logic;
|
||||
signal hdmi_tx_clk_p : std_logic;
|
||||
signal hdmi_tx_hpd : std_logic;
|
||||
signal hdmi_tx_rscl : std_logic;
|
||||
signal hdmi_tx_rsda : std_logic;
|
||||
signal hdmi_tx_p : std_logic_vector(2 downto 0);
|
||||
signal hdmi_tx_n : std_logic_vector(2 downto 0);
|
||||
|
||||
signal sdat_drive : std_logic := '1';
|
||||
signal rs232_tx : std_logic := '1';
|
||||
begin
|
||||
hdmi_rx_sda <= '0' when sdat_drive = '0' else 'H';
|
||||
|
||||
hdmi_rx_p <= transport hdmi_out_p(2 downto 0) after 5.00 ns;
|
||||
hdmi_rx_n <= transport hdmi_out_n(2 downto 0) after 5.00 ns;
|
||||
hdmi_rx_clk_p <= transport hdmi_out_p(3) after 1.25 ns;
|
||||
hdmi_rx_clk_n <= transport hdmi_out_n(3) after 1.25 ns;
|
||||
|
||||
clk_proc: process
|
||||
begin
|
||||
wait for 7.0 ns;
|
||||
while 1 = 1 loop
|
||||
wait for 5.0 ns;
|
||||
clk <= not clk;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
clk50_proc: process
|
||||
begin
|
||||
wait for 7.0 ns;
|
||||
while 1 = 1 loop
|
||||
wait for 5.0 ns;
|
||||
clk50 <= not clk50;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
i_gen_signal: hdmi_output_test port map (
|
||||
clk50 => clk50,
|
||||
hdmi_out_p => hdmi_out_p,
|
||||
hdmi_out_n => hdmi_out_n,
|
||||
leds => open);
|
||||
|
||||
uut: hdmi_design Port map (
|
||||
clk100 => clk,
|
||||
led => open,
|
||||
sw => (others => '0'),
|
||||
debug_pmod => open,
|
||||
--HDMI in
|
||||
hdmi_rx_cec => hdmi_rx_cec,
|
||||
hdmi_rx_hpa => hdmi_rx_hpa,
|
||||
hdmi_rx_scl => hdmi_rx_scl,
|
||||
hdmi_rx_sda => hdmi_rx_sda,
|
||||
hdmi_rx_txen => hdmi_rx_txen,
|
||||
hdmi_rx_clk_n => hdmi_rx_clk_n,
|
||||
hdmi_rx_clk_p => hdmi_rx_clk_p,
|
||||
hdmi_rx_n => hdmi_rx_n,
|
||||
hdmi_rx_p => hdmi_rx_p,
|
||||
|
||||
--- HDMI out
|
||||
hdmi_tx_cec => hdmi_tx_cec,
|
||||
hdmi_tx_clk_n => hdmi_tx_clk_n,
|
||||
hdmi_tx_clk_p => hdmi_tx_clk_p,
|
||||
hdmi_tx_hpd => hdmi_tx_hpd,
|
||||
hdmi_tx_rscl => hdmi_tx_rscl,
|
||||
hdmi_tx_rsda => hdmi_tx_rsda,
|
||||
hdmi_tx_p => hdmi_tx_p,
|
||||
hdmi_tx_n => hdmi_tx_n,
|
||||
|
||||
rs232_tx => rs232_tx
|
||||
);
|
||||
|
||||
edid_test_proc: process
|
||||
begin
|
||||
hdmi_rx_scl <= '1';
|
||||
wait for 1 us;
|
||||
-- START condition
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- DEVICE ADDRESS FOR WRITE
|
||||
-- dev bit 7
|
||||
sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 6
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 6
|
||||
sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 4
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 3
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 2
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 1
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 0
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- Slave ACK
|
||||
-- Device to ack
|
||||
sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- SEND WRITE ADDRESS
|
||||
-- addr bit 7
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- addr bit 6
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- addr bit 6
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- addr bit 4
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- addr bit 3
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- addr bit 2
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- addr bit 1
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- addr bit 0
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- Slave ACK
|
||||
sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- repeated START condition
|
||||
sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1';
|
||||
wait for 400 ns; sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- DEVICE ADDRESS / READ -
|
||||
-- dev bit 7
|
||||
sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 6
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 6
|
||||
sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 4
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 3
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 2
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 1
|
||||
sdat_drive <= '0'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- dev bit 0 - READ!
|
||||
sdat_drive <= '1'; wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
|
||||
-- ACK????
|
||||
-- Device to ack
|
||||
sdat_drive <= '1';
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
|
||||
for i in 1 to 127 loop
|
||||
-- READ First byte
|
||||
-- read bit 7
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 6
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 6
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 4
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 3
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 2
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 1
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 0
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
sdat_drive <= '1';
|
||||
|
||||
-- Host to ack
|
||||
sdat_drive <= '0';
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
sdat_drive <= '1';
|
||||
end loop;
|
||||
-- READ Second
|
||||
-- read bit 7
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 6
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 6
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 4
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 3
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 2
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 1
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
-- read bit 0
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
sdat_drive <= '1';
|
||||
|
||||
-- Master NACK
|
||||
sdat_drive <= '1';
|
||||
wait for 200 ns; hdmi_rx_scl <= '1'; wait for 400 ns; hdmi_rx_scl <= '0'; wait for 200 ns;
|
||||
sdat_drive <= '1';
|
||||
|
||||
-- STOP
|
||||
sdat_drive <= '1';
|
||||
wait for 200 ns;
|
||||
hdmi_rx_scl <= '1';
|
||||
wait for 200 ns;
|
||||
|
||||
wait;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
77
test_bench/term_emu_tb.v
Normal file
77
test_bench/term_emu_tb.v
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module term_emu_tb();
|
||||
|
||||
parameter GLYPHMEM_W = 256; /* glyphs */
|
||||
parameter GLYPHMEM_H = 128; /* glyphs */
|
||||
|
||||
localparam period = 4;
|
||||
|
||||
reg clk, rst;
|
||||
reg in_byte_valid;
|
||||
reg [7:0] in_byte;
|
||||
|
||||
wire in_byte_ack;
|
||||
wire glyph_buffer_w_valid;
|
||||
wire [15:0] glyph_buffer_w_addr;
|
||||
wire [19:0] glyph_buffer_w_data;
|
||||
|
||||
reg [19:0] glyph_buffer;
|
||||
|
||||
initial begin
|
||||
rst = 1;
|
||||
clk = 0;
|
||||
repeat(2) #period clk = ~clk;
|
||||
rst = 0;
|
||||
forever #period clk = ~clk;
|
||||
end
|
||||
|
||||
|
||||
`include "test_data/00TEMU_TEST_STR_LOADERS.v"
|
||||
|
||||
integer testcase_id;
|
||||
integer read_pos;
|
||||
initial begin
|
||||
`include "test_data/00TEMU_TEST_STR_RUNNERS.v"
|
||||
$finish;
|
||||
end
|
||||
|
||||
|
||||
reg [19:0] glyphmem [0:GLYPHMEM_W*GLYPHMEM_H-1];
|
||||
reg last_rst;
|
||||
always @(posedge clk) begin
|
||||
last_rst <= rst;
|
||||
|
||||
if (~last_rst && rst) begin
|
||||
for (integer i=0; i<GLYPHMEM_W*GLYPHMEM_H; i=i+1) begin
|
||||
glyphmem[i] = 20'h00000;
|
||||
end
|
||||
|
||||
end else begin
|
||||
if (glyph_buffer_w_valid) begin
|
||||
if (glyph_buffer_w_addr < GLYPHMEM_W*GLYPHMEM_H) begin
|
||||
glyphmem[glyph_buffer_w_addr] <= glyph_buffer_w_data;
|
||||
|
||||
end else begin
|
||||
$display("Glyph memory write access out of bounds");
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
term_emu #(
|
||||
.GLYPHMEM_W(GLYPHMEM_W),
|
||||
.GLYPHMEM_H(GLYPHMEM_H)
|
||||
) term_emu_dut (
|
||||
.clk(clk), .rst(rst),
|
||||
|
||||
.in_byte_valid(in_byte_valid),
|
||||
.in_byte(in_byte),
|
||||
.in_byte_ack(in_byte_ack),
|
||||
|
||||
.glyph_buffer_w_valid(glyph_buffer_w_valid),
|
||||
.glyph_buffer_w_addr(glyph_buffer_w_addr),
|
||||
.glyph_buffer_w_data(glyph_buffer_w_data)
|
||||
);
|
||||
endmodule
|
||||
482
test_bench/term_emu_tb_gen.ipynb
Normal file
482
test_bench/term_emu_tb_gen.ipynb
Normal file
|
|
@ -0,0 +1,482 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 356,
|
||||
"id": "corrected-briefs",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from enum import Enum\n",
|
||||
"from functools import wraps\n",
|
||||
"from itertools import product\n",
|
||||
"from pathlib import Path\n",
|
||||
"from contextlib import redirect_stdout\n",
|
||||
"import math\n",
|
||||
"import sys\n",
|
||||
"import string\n",
|
||||
"import re\n",
|
||||
"\n",
|
||||
"import jinja2\n",
|
||||
"import numpy as np\n",
|
||||
"from matplotlib import pyplot as plt\n",
|
||||
"%matplotlib inline"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 357,
|
||||
"id": "relative-curve",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"test_data_dir = Path('test_data')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 358,
|
||||
"id": "abroad-wound",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"TESTCASES = {\n",
|
||||
" 'empty_str': '',\n",
|
||||
" 'one_char': 'a',\n",
|
||||
" 'simple_str': 'Foobar',\n",
|
||||
" 'newline': 'Foobar\\baz',\n",
|
||||
"# 'long_str': 'foo'*100*4,\n",
|
||||
"# 'long_lines': 'foo'*100*4 + '\\n' + 'bar'*100*4 + '\\n' + 'narf',\n",
|
||||
" 'bold': 'Foo \\033[1mtest\\033[22m bar',\n",
|
||||
" 'underline': 'Foo \\033[4mtest\\033[24m bar',\n",
|
||||
" 'basic_fg': 'Foobar\\033[33mbaz\\033[0m this is a test', # yellow fg\n",
|
||||
" 'basic_bg': 'Foobar\\033[43mbaz\\033[0m this is a test', # yellow bg\n",
|
||||
" 'separate': 'Foobar\\033[43m\\033[35mbaz\\033[0m this is a test', # yellow bg, magenta fg\n",
|
||||
" 'combined': 'Foobar\\033[43;35mbaz\\033[0m this is a test', # yellow bg, magenta fg\n",
|
||||
" 'complex': 'Foobar\\033[43;35mbaz\\033[49m this is a test', # yellow bg, magenta fg\n",
|
||||
" 'reset': 'Foobar\\033[43;0;35mbaz\\033[49m this is a test', # magenta fg\n",
|
||||
" 'fg_newline': 'Foobar\\033[35mbaz\\nthis \\033[1mis\\033[22m a test', # magenta fg\n",
|
||||
" 'color_palette': ''.join(f'\\033[{c}m//' for c in range(30, 38)) + ' ' + ''.join(f'\\033[{c}m//' for c in range(90, 98)) + '\\n'\n",
|
||||
" +''.join(f'\\033[{c}m//' for c in range(40, 48)) + '\\033[0m ' + ''.join(f'\\033[{c}m//' for c in range(100, 108)) + '\\n',\n",
|
||||
" 'cur_u': 'Foobar\\nbaz>\\033[91m\\033[Atest',\n",
|
||||
" 'cur_d': 'Foobar\\nbaz>\\033[91m\\033[Btest',\n",
|
||||
" 'cur_l': 'Foobar\\nbaz>\\033[91m\\033[Dtest',\n",
|
||||
" 'cur_r': 'Foobar\\nbaz>\\033[91m\\033[Ctest',\n",
|
||||
" 'cur_n': 'Foobar\\nbaz>\\033[91m\\033[Etest',\n",
|
||||
" 'cur_p': 'Foobar\\nbaz>\\033[91m\\033[Ftest',\n",
|
||||
" 'cur_hh': 'Foobar\\nbaz>\\033[91m\\033[Gtest',\n",
|
||||
" 'cur_h': 'Foobar\\nbaz>\\033[91m\\033[Htest',\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 359,
|
||||
"id": "ambient-assault",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'0xf6f'"
|
||||
]
|
||||
},
|
||||
"execution_count": 359,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"hex((~0x90)&0xfff)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 360,
|
||||
"id": "competent-monster",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def gen_loaders(testcases=TESTCASES):\n",
|
||||
" with open(test_data_dir / '00TEMU_TEST_STR_LOADERS.v', 'w') as f, redirect_stdout(f):\n",
|
||||
" print()\n",
|
||||
" for name, le_str in testcases.items():\n",
|
||||
" print(f'reg [31:0] test_temu_{name} [0:{len(le_str)}];')\n",
|
||||
"\n",
|
||||
" print()\n",
|
||||
" print('initial begin')\n",
|
||||
" for name, le_str in testcases.items():\n",
|
||||
" print(f'$readmemh(\"../../../../test_bench/{test_data_dir / name}.hex\", test_temu_{name});')\n",
|
||||
" print('end')\n",
|
||||
"\n",
|
||||
"gen_loaders()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 361,
|
||||
"id": "regional-handle",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def write_hexfiles(testcases=TESTCASES):\n",
|
||||
" for name, le_str in testcases.items():\n",
|
||||
" with open(test_data_dir / f'{name}.hex', 'w') as f, redirect_stdout(f):\n",
|
||||
" for c in le_str + ' ': # pad at the end to take 1-cycle pipeline delay into account\n",
|
||||
" print(f'{ord(c):02x}')\n",
|
||||
"write_hexfiles()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 362,
|
||||
"id": "understanding-things",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Testcase 0: empty_str\n",
|
||||
"Testcase 1: one_char\n",
|
||||
"Testcase 2: simple_str\n",
|
||||
"Testcase 3: newline\n",
|
||||
"Testcase 4: bold\n",
|
||||
"Testcase 5: underline\n",
|
||||
"Testcase 6: basic_fg\n",
|
||||
"Testcase 7: basic_bg\n",
|
||||
"Testcase 8: separate\n",
|
||||
"Testcase 9: combined\n",
|
||||
"Testcase 10: complex\n",
|
||||
"Testcase 11: reset\n",
|
||||
"Testcase 12: fg_newline\n",
|
||||
"Testcase 13: color_palette\n",
|
||||
"Testcase 14: cur_u\n",
|
||||
"Testcase 15: cur_d\n",
|
||||
"Testcase 16: cur_l\n",
|
||||
"Testcase 17: cur_r\n",
|
||||
"Testcase 18: cur_n\n",
|
||||
"Testcase 19: cur_p\n",
|
||||
"Testcase 20: cur_hh\n",
|
||||
"Testcase 21: cur_h\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"RUNNER_TPL = '''\n",
|
||||
"/* Start of generated test case {{name}} */\n",
|
||||
"\n",
|
||||
"testcase_id = {{testcase_id}};\n",
|
||||
"rst = 1;\n",
|
||||
"repeat(2) @(posedge clk);\n",
|
||||
"rst = 0;\n",
|
||||
"repeat(8) @(posedge clk);\n",
|
||||
"\n",
|
||||
"$display(\"Running {{name}}\");\n",
|
||||
"for (read_pos=0; read_pos<{{str_len}}; read_pos=read_pos+1) begin\n",
|
||||
" in_byte = {{mem}}[read_pos];\n",
|
||||
" in_byte_valid = 1;\n",
|
||||
" @(posedge clk);\n",
|
||||
" while (!in_byte_ack) begin\n",
|
||||
" @(posedge clk);\n",
|
||||
" end\n",
|
||||
" in_byte_valid = 0;\n",
|
||||
"end\n",
|
||||
"\n",
|
||||
"$writememh(\"test_term_emu_dump_{{name}}.hex\", glyphmem);\n",
|
||||
"\n",
|
||||
"/* End of generated test case {{name}} */\n",
|
||||
"'''\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def gen_runners(testcases=TESTCASES):\n",
|
||||
" with open(test_data_dir / '00TEMU_TEST_STR_RUNNERS.v', 'w') as f, redirect_stdout(f):\n",
|
||||
" tpl = jinja2.Environment().from_string(RUNNER_TPL, globals=globals())\n",
|
||||
" for i, (name, le_str) in enumerate(testcases.items()):\n",
|
||||
" print(tpl.render(name=name, str_len=len(le_str) + 1, mem=f'test_temu_{name}', testcase_id=i))\n",
|
||||
" print(f'Testcase {i:>3}: {name}', file=sys.stderr)\n",
|
||||
" \n",
|
||||
"gen_runners()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 363,
|
||||
"id": "southeast-proportion",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def read_hexfile(filename):\n",
|
||||
" with open(filename) as f:\n",
|
||||
" gen = ((int(line, 16) if re.match(r'^[0-9a-f]+$', line) else 0) for line in f if line.strip())\n",
|
||||
" return list(gen)\n",
|
||||
"\n",
|
||||
"def show_tc(tc_id, w=100, h=5, glyphmem_w=256, glyphmem_h=128):\n",
|
||||
" data = read_hexfile(f'../Artix-7-HDMI-processing.sim/sim_1/behav/xsim/test_term_emu_dump_{tc_id}.hex')\n",
|
||||
" data = data[1:]\n",
|
||||
" for y in range(h):\n",
|
||||
" for x in range(w):\n",
|
||||
" entry = data[y*glyphmem_w + x]\n",
|
||||
" char = chr(entry&0xff)\n",
|
||||
"\n",
|
||||
" style = (entry>>8)&0xfff\n",
|
||||
" bold = 1 if style&(1<<10) else 22\n",
|
||||
" underline = 4 if style&(1<<11) else 24\n",
|
||||
" bg = (style>>4) & 0xf\n",
|
||||
" bg = 40 + bg if bg < 8 else 100 + bg - 8\n",
|
||||
" fg = style & 0xf\n",
|
||||
" fg = 30 + fg if fg < 8 else 90 + fg - 8\n",
|
||||
" print(f'\\033[{bold};{underline};{bg};{fg}m', end='')\n",
|
||||
"\n",
|
||||
" if char == '\\n':\n",
|
||||
" print('↵', end='')\n",
|
||||
" elif char in string.printable:\n",
|
||||
" print(char, end='')\n",
|
||||
" elif char in ' \\0':\n",
|
||||
" print(' ', end='')\n",
|
||||
" else:\n",
|
||||
" print('\\033[40;37m?', end='')\n",
|
||||
" print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 364,
|
||||
"id": "confidential-exhibition",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;30m/\u001b[22;24;40;30m/\u001b[22;24;40;31m/\u001b[22;24;40;31m/\u001b[22;24;40;32m/\u001b[22;24;40;32m/\u001b[22;24;40;33m/\u001b[22;24;40;33m/\u001b[22;24;40;34m/\u001b[22;24;40;34m/\u001b[22;24;40;35m/\u001b[22;24;40;35m/\u001b[22;24;40;36m/\u001b[22;24;40;36m/\u001b[22;24;40;37m/\u001b[22;24;40;37m/\u001b[22;24;40;37m \u001b[22;24;40;37m \u001b[22;24;40;90m/\u001b[22;24;40;90m/\u001b[22;24;40;91m/\u001b[22;24;40;91m/\u001b[22;24;40;92m/\u001b[22;24;40;92m/\u001b[22;24;40;93m/\u001b[22;24;40;93m/\u001b[22;24;40;94m/\u001b[22;24;40;94m/\u001b[22;24;40;95m/\u001b[22;24;40;95m/\u001b[22;24;40;96m/\u001b[22;24;40;96m/\u001b[22;24;40;97m/\u001b[22;24;40;97m/\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;97m/\u001b[22;24;40;97m/\u001b[22;24;41;97m/\u001b[22;24;41;97m/\u001b[22;24;42;97m/\u001b[22;24;42;97m/\u001b[22;24;43;97m/\u001b[22;24;43;97m/\u001b[22;24;44;97m/\u001b[22;24;44;97m/\u001b[22;24;45;97m/\u001b[22;24;45;97m/\u001b[22;24;46;97m/\u001b[22;24;46;97m/\u001b[22;24;47;97m/\u001b[22;24;47;97m/\u001b[22;24;40;37m \u001b[22;24;40;37m \u001b[22;24;100;37m/\u001b[22;24;100;37m/\u001b[22;24;101;37m/\u001b[22;24;101;37m/\u001b[22;24;102;37m/\u001b[22;24;102;37m/\u001b[22;24;103;37m/\u001b[22;24;103;37m/\u001b[22;24;104;37m/\u001b[22;24;104;37m/\u001b[22;24;105;37m/\u001b[22;24;105;37m/\u001b[22;24;106;37m/\u001b[22;24;106;37m/\u001b[22;24;107;37m/\u001b[22;24;107;37m/\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('color_palette')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 365,
|
||||
"id": "compressed-operator",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#show_tc('long_str')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 366,
|
||||
"id": "becoming-growth",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;37mF\u001b[22;24;40;37mo\u001b[22;24;40;37mo\u001b[22;24;40;37mb\u001b[22;24;40;37ma\u001b[22;24;40;37mr\u001b[22;24;40;37m\u001b[40;37m?\u001b[22;24;40;37ma\u001b[22;24;40;37mz\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('newline')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 367,
|
||||
"id": "sticky-novel",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#show_tc('long_lines')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 368,
|
||||
"id": "endless-lecture",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;37mF\u001b[22;24;40;37mo\u001b[22;24;40;37mo\u001b[22;24;40;37m \u001b[1;24;40;37mt\u001b[1;24;40;37me\u001b[1;24;40;37ms\u001b[1;24;40;37mt\u001b[22;24;40;37m \u001b[22;24;40;37mb\u001b[22;24;40;37ma\u001b[22;24;40;37mr\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('bold')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 369,
|
||||
"id": "latter-blowing",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;37mF\u001b[22;24;40;37mo\u001b[22;24;40;37mo\u001b[22;24;40;37m \u001b[22;4;40;37mt\u001b[22;4;40;37me\u001b[22;4;40;37ms\u001b[22;4;40;37mt\u001b[22;24;40;37m \u001b[22;24;40;37mb\u001b[22;24;40;37ma\u001b[22;24;40;37mr\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('underline')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 370,
|
||||
"id": "criminal-documentation",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;37mF\u001b[22;24;40;37mo\u001b[22;24;40;37mo\u001b[22;24;40;37mb\u001b[22;24;40;37ma\u001b[22;24;40;37mr\u001b[22;24;40;33mb\u001b[22;24;40;33ma\u001b[22;24;40;33mz\u001b[22;24;40;37m \u001b[22;24;40;37mt\u001b[22;24;40;37mh\u001b[22;24;40;37mi\u001b[22;24;40;37ms\u001b[22;24;40;37m \u001b[22;24;40;37mi\u001b[22;24;40;37ms\u001b[22;24;40;37m \u001b[22;24;40;37ma\u001b[22;24;40;37m \u001b[22;24;40;37mt\u001b[22;24;40;37me\u001b[22;24;40;37ms\u001b[22;24;40;37mt\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('basic_fg')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 371,
|
||||
"id": "colored-assumption",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;37mF\u001b[22;24;40;37mo\u001b[22;24;40;37mo\u001b[22;24;40;37mb\u001b[22;24;40;37ma\u001b[22;24;40;37mr\u001b[22;24;43;37mb\u001b[22;24;43;37ma\u001b[22;24;43;37mz\u001b[22;24;40;37m \u001b[22;24;40;37mt\u001b[22;24;40;37mh\u001b[22;24;40;37mi\u001b[22;24;40;37ms\u001b[22;24;40;37m \u001b[22;24;40;37mi\u001b[22;24;40;37ms\u001b[22;24;40;37m \u001b[22;24;40;37ma\u001b[22;24;40;37m \u001b[22;24;40;37mt\u001b[22;24;40;37me\u001b[22;24;40;37ms\u001b[22;24;40;37mt\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('basic_bg')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 372,
|
||||
"id": "quiet-mailing",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;37mF\u001b[22;24;40;37mo\u001b[22;24;40;37mo\u001b[22;24;40;37mb\u001b[22;24;40;37ma\u001b[22;24;40;37mr\u001b[22;24;43;35mb\u001b[22;24;43;35ma\u001b[22;24;43;35mz\u001b[22;24;40;37m \u001b[22;24;40;37mt\u001b[22;24;40;37mh\u001b[22;24;40;37mi\u001b[22;24;40;37ms\u001b[22;24;40;37m \u001b[22;24;40;37mi\u001b[22;24;40;37ms\u001b[22;24;40;37m \u001b[22;24;40;37ma\u001b[22;24;40;37m \u001b[22;24;40;37mt\u001b[22;24;40;37me\u001b[22;24;40;37ms\u001b[22;24;40;37mt\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('separate')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 373,
|
||||
"id": "proved-madagascar",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;37mF\u001b[22;24;40;37mo\u001b[22;24;40;37mo\u001b[22;24;40;37mb\u001b[22;24;40;37ma\u001b[22;24;40;37mr\u001b[22;24;43;35mb\u001b[22;24;43;35ma\u001b[22;24;43;35mz\u001b[22;24;40;37m \u001b[22;24;40;37mt\u001b[22;24;40;37mh\u001b[22;24;40;37mi\u001b[22;24;40;37ms\u001b[22;24;40;37m \u001b[22;24;40;37mi\u001b[22;24;40;37ms\u001b[22;24;40;37m \u001b[22;24;40;37ma\u001b[22;24;40;37m \u001b[22;24;40;37mt\u001b[22;24;40;37me\u001b[22;24;40;37ms\u001b[22;24;40;37mt\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('combined')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 374,
|
||||
"id": "original-zimbabwe",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[22;24;40;37mF\u001b[22;24;40;37mo\u001b[22;24;40;37mo\u001b[22;24;40;37mb\u001b[22;24;40;37ma\u001b[22;24;40;37mr\u001b[22;24;43;35mb\u001b[22;24;43;35ma\u001b[22;24;43;35mz\u001b[22;24;40;35m \u001b[22;24;40;35mt\u001b[22;24;40;35mh\u001b[22;24;40;35mi\u001b[22;24;40;35ms\u001b[22;24;40;35m \u001b[22;24;40;35mi\u001b[22;24;40;35ms\u001b[22;24;40;35m \u001b[22;24;40;35ma\u001b[22;24;40;35m \u001b[22;24;40;35mt\u001b[22;24;40;35me\u001b[22;24;40;35ms\u001b[22;24;40;35mt\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n",
|
||||
"\u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \u001b[22;24;40;30m \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show_tc('complex')"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
61
test_bench/term_emu_tb_show.py
Normal file
61
test_bench/term_emu_tb_show.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import re
|
||||
import string
|
||||
|
||||
def read_hexfile(filename):
|
||||
with open(filename) as f:
|
||||
gen = ((int(line, 16) if re.match(r'^[0-9a-f]+$', line) else 0) for line in f if line.strip())
|
||||
return list(gen)
|
||||
|
||||
def show_tc(tc_id, w=100, h=5, glyphmem_w=256, glyphmem_h=128):
|
||||
data = read_hexfile(f'../Artix-7-HDMI-processing.sim/sim_1/behav/xsim/test_term_emu_dump_{tc_id}.hex')
|
||||
data = data[1:]
|
||||
for y in range(h):
|
||||
for x in range(w):
|
||||
entry = data[y*glyphmem_w + x]
|
||||
char = chr(entry&0xff)
|
||||
|
||||
style = (entry>>8)&0xfff
|
||||
bold = 1 if style&(1<<10) else 22
|
||||
underline = 4 if style&(1<<11) else 24
|
||||
bg = (style>>4) & 0xf
|
||||
bg = 40 + bg if bg < 8 else 100 + bg - 8
|
||||
fg = style & 0xf
|
||||
fg = 30 + fg if fg < 8 else 90 + fg - 8
|
||||
print(f'\033[{bold};{underline};{bg};{fg}m', end='')
|
||||
|
||||
if char == '\n':
|
||||
print('↵', end='')
|
||||
elif char in string.printable:
|
||||
print(char, end='')
|
||||
elif char in ' \0':
|
||||
print(' ', end='')
|
||||
else:
|
||||
print('\033[40;37m?', end='')
|
||||
print()
|
||||
|
||||
if __name__ == '__main__':
|
||||
for tc in [
|
||||
'bold',
|
||||
'underline',
|
||||
'basic_fg',
|
||||
'basic_bg',
|
||||
'separate',
|
||||
'combined',
|
||||
'complex',
|
||||
'reset',
|
||||
'fg_newline',
|
||||
'color_palette',
|
||||
'cur_u',
|
||||
'cur_d',
|
||||
'cur_l',
|
||||
'cur_r',
|
||||
'cur_n',
|
||||
'cur_p',
|
||||
'cur_hh',
|
||||
'cur_h',
|
||||
]:
|
||||
print()
|
||||
print(f'\033[0m=== Testcase {tc} ===')
|
||||
show_tc(tc)
|
||||
267
test_bench/term_renderer_analysis.ipynb
Normal file
267
test_bench/term_renderer_analysis.ipynb
Normal file
File diff suppressed because one or more lines are too long
107
test_bench/term_renderer_tb.v
Normal file
107
test_bench/term_renderer_tb.v
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 06/15/2021 10:49:32 AM
|
||||
// Design Name:
|
||||
// Module Name: window_matcher_tb
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module term_renderer_tb();
|
||||
|
||||
parameter GLYPHMEM_W = 256; /* glyphs */
|
||||
parameter GLYPHMEM_H = 128; /* glyphs */
|
||||
|
||||
localparam period = 4;
|
||||
localparam REC_MAXLEN = 200000;
|
||||
|
||||
reg rst, clk;
|
||||
reg vsync, hsync;
|
||||
reg [19:0] glyphmem_data;
|
||||
wire [15:0] glyphmem_r_addr;
|
||||
wire [7:0] out_red;
|
||||
wire [7:0] out_green;
|
||||
wire [7:0] out_blue;
|
||||
|
||||
initial begin
|
||||
rst = 1;
|
||||
clk = 0;
|
||||
repeat(2) #period clk = ~clk;
|
||||
rst = 0;
|
||||
forever #period clk = ~clk;
|
||||
end
|
||||
|
||||
reg [23:0] data_recording [0:REC_MAXLEN];
|
||||
integer testcase_id;
|
||||
integer rec_pos;
|
||||
initial begin
|
||||
`include "test_data/00TERM_RENDERER_TC_IDX.v"
|
||||
$finish();
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
rec_pos <= 0;
|
||||
for (integer i=0; i<REC_MAXLEN; i=i+1) begin
|
||||
data_recording[i] <= 0;
|
||||
end
|
||||
|
||||
end else begin
|
||||
if (rec_pos != REC_MAXLEN-1) begin
|
||||
data_recording[rec_pos] = {out_red, out_green, out_blue};
|
||||
rec_pos = rec_pos + 1;
|
||||
|
||||
end else begin
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [19:0] glyphmem [0:GLYPHMEM_W*GLYPHMEM_H-1];
|
||||
initial $readmemh("../../../../test_bench/test_data/test_glyphmem_data.hex", glyphmem);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
glyphmem_data <= 0;
|
||||
|
||||
end else begin
|
||||
if (glyphmem_r_addr < GLYPHMEM_W*GLYPHMEM_H) begin
|
||||
glyphmem_data <= glyphmem[glyphmem_r_addr];
|
||||
end else begin
|
||||
glyphmem_data <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
term_renderer #(
|
||||
.GLYPHMEM_W(GLYPHMEM_W),
|
||||
.GLYPHMEM_H(GLYPHMEM_H)
|
||||
) term_renderer_dut (
|
||||
.rst(rst),
|
||||
.clk(clk),
|
||||
|
||||
.in_vsync(vsync),
|
||||
.in_hsync(hsync),
|
||||
|
||||
.glyphmem_data(glyphmem_data),
|
||||
.glyphmem_r_addr(glyphmem_r_addr),
|
||||
|
||||
.out_red(out_red),
|
||||
.out_green(out_green),
|
||||
.out_blue(out_blue)
|
||||
);
|
||||
|
||||
endmodule
|
||||
BIN
test_bench/test.png
Normal file
BIN
test_bench/test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 689 B |
102
test_bench/window_matcher_tb.v
Normal file
102
test_bench/window_matcher_tb.v
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 06/15/2021 10:49:32 AM
|
||||
// Design Name:
|
||||
// Module Name: window_matcher_tb
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module window_matcher_tb();
|
||||
|
||||
reg clk;
|
||||
reg rst;
|
||||
|
||||
reg in_blank;
|
||||
reg in_hsync;
|
||||
reg in_vsync;
|
||||
reg [7:0] in_red;
|
||||
reg [7:0] in_green;
|
||||
reg [7:0] in_blue;
|
||||
|
||||
wire win_blank;
|
||||
wire win_hsync;
|
||||
|
||||
wire win_locked;
|
||||
wire [11:0] win_w;
|
||||
wire [11:0] win_h;
|
||||
|
||||
wire out_data_en;
|
||||
wire out_data_valid;
|
||||
|
||||
localparam period = 4;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
in_blank = 1;
|
||||
in_hsync = 0;
|
||||
in_vsync = 0;
|
||||
in_red = 0;
|
||||
in_green = 0;
|
||||
in_blue = 0;
|
||||
|
||||
repeat(2) #period clk = ~clk;
|
||||
rst = 0;
|
||||
forever #period clk = ~clk;
|
||||
end
|
||||
|
||||
`include "test_data/00WM_TEST_POS_LOADERS.v"
|
||||
|
||||
integer read_pos;
|
||||
reg [23:0] expected_data;
|
||||
reg [23:0] expected_data_last;
|
||||
integer testcase_id;
|
||||
reg win_blank_exp, win_header;
|
||||
reg win_blank_exp_last, win_header_last;
|
||||
reg in_vsync_last;
|
||||
initial begin
|
||||
`include "test_data/00WM_TEST_POS_RUNNERS.v"
|
||||
$finish;
|
||||
end
|
||||
|
||||
window_matcher window_matcher_i (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.bypass(1'b0),
|
||||
|
||||
.in_blank(in_blank),
|
||||
.in_hsync(in_hsync),
|
||||
.in_vsync(in_vsync),
|
||||
.in_red(in_red),
|
||||
.in_green(in_green),
|
||||
.in_blue(in_blue),
|
||||
|
||||
.win_blank(win_blank),
|
||||
.win_locked(win_locked),
|
||||
.win_w(win_w),
|
||||
.win_h(win_h),
|
||||
|
||||
.out_data_en(out_data_en),
|
||||
.out_data_valid(out_data_valid),
|
||||
|
||||
.win_red(8'haa),
|
||||
.win_green(8'haa),
|
||||
.win_blue(8'haa)
|
||||
);
|
||||
|
||||
endmodule
|
||||
735
test_bench/window_matcher_tb_gen.ipynb
Normal file
735
test_bench/window_matcher_tb_gen.ipynb
Normal file
File diff suppressed because one or more lines are too long
247
window_matcher_tb_behav.wcfg
Normal file
247
window_matcher_tb_behav.wcfg
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="window_matcher_tb_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="glbl" />
|
||||
<top_module name="window_matcher_tb" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="5377246000fs"></ZoomStartTime>
|
||||
<ZoomEndTime time="5758210001fs"></ZoomEndTime>
|
||||
<Cursor1Time time="5694716000fs"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="175"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="158"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="49" />
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/clk" type="logic">
|
||||
<obj_property name="ElementShortName">clk</obj_property>
|
||||
<obj_property name="ObjectShortName">clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/rst" type="logic">
|
||||
<obj_property name="ElementShortName">rst</obj_property>
|
||||
<obj_property name="ObjectShortName">rst</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_blank" type="logic">
|
||||
<obj_property name="ElementShortName">in_blank</obj_property>
|
||||
<obj_property name="ObjectShortName">in_blank</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_hsync" type="logic">
|
||||
<obj_property name="ElementShortName">in_hsync</obj_property>
|
||||
<obj_property name="ObjectShortName">in_hsync</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_vsync" type="logic">
|
||||
<obj_property name="ElementShortName">in_vsync</obj_property>
|
||||
<obj_property name="ObjectShortName">in_vsync</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_red" type="array">
|
||||
<obj_property name="ElementShortName">in_red[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">in_red[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_green" type="array">
|
||||
<obj_property name="ElementShortName">in_green[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">in_green[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_blue" type="array">
|
||||
<obj_property name="ElementShortName">in_blue[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">in_blue[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/out_hsync" type="logic">
|
||||
<obj_property name="ElementShortName">out_hsync</obj_property>
|
||||
<obj_property name="ObjectShortName">out_hsync</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/out_vsync" type="logic">
|
||||
<obj_property name="ElementShortName">out_vsync</obj_property>
|
||||
<obj_property name="ObjectShortName">out_vsync</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/out_red" type="array">
|
||||
<obj_property name="ElementShortName">out_red[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">out_red[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/out_green" type="array">
|
||||
<obj_property name="ElementShortName">out_green[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">out_green[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/out_blue" type="array">
|
||||
<obj_property name="ElementShortName">out_blue[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">out_blue[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/win_blank" type="logic">
|
||||
<obj_property name="ElementShortName">win_blank</obj_property>
|
||||
<obj_property name="ObjectShortName">win_blank</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_hactive" type="logic">
|
||||
<obj_property name="ElementShortName">win_hactive</obj_property>
|
||||
<obj_property name="ObjectShortName">win_hactive</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/win_locked" type="logic">
|
||||
<obj_property name="ElementShortName">win_locked</obj_property>
|
||||
<obj_property name="ObjectShortName">win_locked</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/win_blank_exp" type="logic">
|
||||
<obj_property name="ElementShortName">win_blank_exp</obj_property>
|
||||
<obj_property name="ObjectShortName">win_blank_exp</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/out_data_en" type="logic">
|
||||
<obj_property name="ElementShortName">out_data_en</obj_property>
|
||||
<obj_property name="ObjectShortName">out_data_en</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/out_data_valid" type="logic">
|
||||
<obj_property name="ElementShortName">out_data_valid</obj_property>
|
||||
<obj_property name="ObjectShortName">out_data_valid</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_pxd" type="array">
|
||||
<obj_property name="ElementShortName">in_pxd[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">in_pxd[23:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_pxd" type="array">
|
||||
<obj_property name="ElementShortName">win_pxd[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_pxd[23:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/out_pxd" type="array">
|
||||
<obj_property name="ElementShortName">out_pxd[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">out_pxd[23:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_pxd_match" type="array">
|
||||
<obj_property name="ElementShortName">in_pxd_match[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">in_pxd_match[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_pxd_match_sr" type="array">
|
||||
<obj_property name="ElementShortName">in_pxd_match_sr[6:0][7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">in_pxd_match_sr[6:0][7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_pxd_pattern_match" type="logic">
|
||||
<obj_property name="ElementShortName">in_pxd_pattern_match</obj_property>
|
||||
<obj_property name="ObjectShortName">in_pxd_pattern_match</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/scan_x" type="array">
|
||||
<obj_property name="ElementShortName">scan_x[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">scan_x[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/scan_y" type="array">
|
||||
<obj_property name="ElementShortName">scan_y[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">scan_y[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_x" type="array">
|
||||
<obj_property name="ElementShortName">win_x[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_x[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_y" type="array">
|
||||
<obj_property name="ElementShortName">win_y[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_y[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_x_int" type="array">
|
||||
<obj_property name="ElementShortName">win_x_int[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_x_int[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_y_int" type="array">
|
||||
<obj_property name="ElementShortName">win_y_int[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_y_int[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/dval_x_reg" type="array">
|
||||
<obj_property name="ElementShortName">dval_x_reg[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">dval_x_reg[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/dval_y_reg" type="array">
|
||||
<obj_property name="ElementShortName">dval_y_reg[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">dval_y_reg[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_w_int" type="array">
|
||||
<obj_property name="ElementShortName">win_w_int[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_w_int[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_h_int" type="array">
|
||||
<obj_property name="ElementShortName">win_h_int[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_h_int[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_w" type="array">
|
||||
<obj_property name="ElementShortName">win_w[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_w[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_h" type="array">
|
||||
<obj_property name="ElementShortName">win_h[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_h[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/win_hsync_ctr" type="array">
|
||||
<obj_property name="ElementShortName">win_hsync_ctr[11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">win_hsync_ctr[11:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/matcher_state" type="array">
|
||||
<obj_property name="ElementShortName">matcher_state[4:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">matcher_state[4:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/matched" type="logic">
|
||||
<obj_property name="ElementShortName">matched</obj_property>
|
||||
<obj_property name="ObjectShortName">matched</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/scan_x_reg" type="array">
|
||||
<obj_property name="ElementShortName">scan_x_reg[7:0][11:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">scan_x_reg[7:0][11:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_hsync_reg" type="logic">
|
||||
<obj_property name="ElementShortName">in_hsync_reg</obj_property>
|
||||
<obj_property name="ObjectShortName">in_hsync_reg</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_vsync_reg" type="logic">
|
||||
<obj_property name="ElementShortName">in_vsync_reg</obj_property>
|
||||
<obj_property name="ObjectShortName">in_vsync_reg</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/window_matcher_i/in_pxd_reg" type="array">
|
||||
<obj_property name="ElementShortName">in_pxd_reg[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">in_pxd_reg[23:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/testcase_id" type="array">
|
||||
<obj_property name="ElementShortName">testcase_id[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">testcase_id[31:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/expected_data" type="array">
|
||||
<obj_property name="ElementShortName">expected_data[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">expected_data[23:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/expected_data_last" type="array">
|
||||
<obj_property name="ElementShortName">expected_data_last[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">expected_data_last[23:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/read_pos" type="array">
|
||||
<obj_property name="ElementShortName">read_pos[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">read_pos[31:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="/window_matcher_tb/win_header" type="logic">
|
||||
<obj_property name="ElementShortName">win_header</obj_property>
|
||||
<obj_property name="ObjectShortName">win_header</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
Loading…
Add table
Add a link
Reference in a new issue