diff --git a/README.md b/README.md index b65d9c9..30a5bd7 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,6 @@ Most free and open source HDMI source (computer/gaming console) implementations - [ ] Support other video id codes - [ ] Interlaced video - [ ] Pixel repetition -- [ ] Special I/O features - - [x] Double Data Rate I/O (DDRIO) ### Pixel Clock @@ -77,7 +75,7 @@ You'll need to set up a PLL for producing the two HDMI clocks. The pixel clock f |1280x720|19|50Hz|74.25MHz| |3840x2160|97, 107|60Hz|594MHz| -The second clock is a clock 10 times as fast as the pixel clock. Even if your FPGA only has a single PLL, the Altera MegaWizard (or the Xilinx equivalent) should still be able to produce both. You can avoid using two different multiplication factors, with the DDRIO feature, which only requires the second clock to be 5 times as fast. +The second clock is a clock 5 times as fast as the pixel clock. Even if your FPGA only has a single PLL, the Altera MegaWizard (or the Xilinx equivalent) should still be able to produce both. ### L-PCM Audio Bitrate / Sampling Frequency @@ -120,8 +118,7 @@ This code is sent in the Source Product Description InfoFrame via `SOURCE_DEVICE ### Things to be aware of / Troubleshooting * Limited resolution: some FPGAs don't support I/O at speeds high enough to achieve 720p/1080p - * Workaround: use DDR/other special I/O features like I/O serializers - * Workaround: Altera FPGA users can try to specify speed grade C6 and see if it works, though yours may be C7 or C8. If it doesn't work, try enabling DDRIO. + * Workaround: Altera FPGA users can try to specify speed grade C6 and see if it works, though yours may be C7 or C8. Beware that this might introduce some system instability. * FPGA does not support TMDS: many FPGAs without a dedicated HDMI output don't support TMDS * You should be able to directly use LVDS (3.3v) instead, tested up to 720x480 * This might not work if your video has a high number of transitions or you plan to use higher resolutions diff --git a/README_fr.md b/README_fr.md index cb7ecca..2b993b2 100644 --- a/README_fr.md +++ b/README_fr.md @@ -12,7 +12,7 @@ La plupart des implementations open source d'un source HDMI transmettre en réal ### Démo: Mode texte VGA-compatible, 720x480p sur un Moniteur Dell Ultrasharp 1080p -![GIF showing VGA-compatible text mode on a monitor](demo.gif) +![GIF qui montre mode texte VGA-compatible sur un moniteur](demo.gif) ## Usage @@ -23,118 +23,5 @@ La plupart des implementations open source d'un source HDMI transmettre en réal 1. Read through the parameters in `hdmi.sv` and tailor any instantiations to your situation. 1. Please create an issue if you run into a problem or have any questions. Make sure you have consulted the troubleshooting section first. -### Platform Support -S'il vous plaît regarder le readme principal pour l'information à jour. - -### Liste de choses à faire - -S'il vous plaît regarder le readme principal pour l'information à jour. - -### Horloge Pixel - -Vous devrez configurer un PLL pour produire 2 horloges HDMI. S'il vous plaît regarder le readme principal pour la configuration de l'horloge première (l'horloge pixel). - -La deuxième est une horloge 10 fois plus rapide que l'horloge pixel. Même si ton FPGA a un seul PLL, le MegaWizard Altera (ou le équivalent Xilinx) devrait pouvour les deux. Vous pouvez éviter d'utiliser deux facteurs de multiplication différents avec la fonction DDRIO, ce qui nécessite une horloge deuxième seulement 5 fois plus rapide. - -### Débit Binaire Audio L-PCM / Fréquence d'échantillonnage - -Débit binaire audio et fréquence sont spécifiés comme paramètres du module HDMI. Débit binaire peut être n'importe quelle valeur de 16 à 24. S'il vous plaît regarder le readme principal pour une cartographie simple de la fréquence d'échantillonnage aux paramètres appropriés. - -### Source Device Information Code - -This code is sent in the Source Product Description InfoFrame via `SOURCE_DEVICE_INFORMATION` to give HDMI sinks an idea of what capabilities an HDMI source might have. It may be used for displaying a relevant icon in an input list (i.e. DVD logo for a DVD player). - -### Things to be aware of / Troubleshooting - -* Limited resolution: some FPGAs don't support I/O at speeds high enough to achieve 720p/1080p - * Workaround: use DDR/other special I/O features like I/O serializers - * Workaround: Altera FPGA users can try to specify speed grade C6 and see if it works, though yours may be C7 or C8. If it doesn't work, try enabling DDRIO. -* FPGA does not support TMDS: many FPGAs without a dedicated HDMI output don't support TMDS - * You should be able to directly use LVDS (3.3v) instead, tested up to 720x480 - * This might not work if your video has a high number of transitions or you plan to use higher resolutions - * Solution: AC-couple the 3.3v LVDS wires to by adding 100nF capacitors in series, as close to the transmitter as possible - * Why? TMDS is current mode logic, and driving a CML receiver with LVDS is detailed in [Figure 9 of Interfacing LVDS with other differential-I/O types](https://m.eet.com/media/1135468/330072.pdf) - * Resistors are not needed since Vcc = 3.3v for both the transmitter and receiver - * Example: See `J13`, on the [Arduino MKR Vivado 4000 schematic](https://content.arduino.cc/assets/vidor_c10_sch.zip), where LVDS IO Standard pins on a Cyclone 10 FPGA have 100nF series capacitors -* Poor wiring: if you're using a breakout board or long lengths of untwisted wire, there might be a few pixels that jitter due to interference - * Make sure you have all the necessary pins connected (GND pins, etc.) - * Try switching your HDMI cable; some cheap cables like [these I got from Amazon](https://www.amazon.com/gp/product/B01JO9PB7E/) have poor shielding -* Hot-Plug unaware: all modules are unaware of hotplug - * This shouldn't affect anything in the long term; the only stateful value is `hdmi.tmds_channel[2:0].acc` - * You should decide hotplug behavior (i.e. pause/resume on disconnect/connect, or ignore it) -* EDID not implemented: it is assumed you know what format you want at synthesis time, so there is no dynamic decision on video format - * To be implemented in a display protocol independent manner -* SCL/SCA voltage level: though unused by this implementation...it is I2C on a 5V logic level, as confirmed in the [TPD12S016 datasheet](https://www.ti.com/lit/ds/symlink/tpd12s016.pdf), which is unsupported by most FPGAs - * Solution: use a bidirectional logic level shifter compatible with I2C to convert 3.3v LVTTL to 5v - * Solution: use 3.3-V LVTTL I/O standard with 6.65k pull-up resistors to 3.3v (as done in `J13` on the [Arduino MKR Vivado 4000 schematic](https://content.arduino.cc/assets/vidor_c10_sch.zip)) - * Emailed Arduino support: safe to use as long as the HDMI slave does not have pull-ups - -## Licensing - -Dual-licensed under Apache License 2.0 and MIT License. - -### Adoption HDMI - -Moi je ne suis pas un avocat -- l'avis ci dessous est donné sur la base de discussion sur [une publication Hacker News](https://news.ycombinator.com/item?id=22279308) et ma recherche. - -HDMI itself is not a royalty free technology, unfortunately. You are free to use it for testing, development, etc. but to receive the HDMI LA's (licensing administration) blessing to create and sell end-user products: - - -> The manufacturer of the finished end-user product MUST be a licensed HDMI Adopter, and -> The finished end-user product MUST satisfy all requirements as defined in the Adopter Agreement including but not limited to passing compliance testing either at an HDMI ATC or through self-testing. - - -Becoming an adopter means you have to pay a flat annual fee (~ $1k-$2k) and a per device royalty (~ $0.05). If you are selling an end-user device and DO NOT want to become an adopter, you can turn on the `DVI_OUTPUT` parameter, which will disable any HDMI-only logic, like audio. - -Please consult your lawyer if you have any concerns. Here are a few noteworthy cases that may help you make a decision: - -* Arduino LLC is not an adopter, yet sells the [Arduino MKR Vidor 4000](https://store.arduino.cc/usa/mkr-vidor-4000) FPGA - * It has a micro-HDMI connector - * [Having an HDMI connector does not require a license](https://electronics.stackexchange.com/questions/28202/legality-of-using-hdmi-connectors-in-non-hdmi-product) - * Official examples provided by Arduino on GitHub only perform DVI output - * It is a user's choice to program the FPGA for HDMI output - * Therefore: the device isn't an end-user product under the purview of HDMI LA -* Unlicensed DisplayPort to HDMI cables (2011) - * [Articles suggests that the HDMI LA can recall illegal products](https://www.pcmag.com/archive/displayport-to-hdmi-cables-illegal-could-be-recalled-266671?amp=1). - * But these cables [are still sold on Amazon](https://www.amazon.com/s?k=hdmi+to+displayport+cable) - * Therefore: the power of HDMI LA to enforce licensing is unclear -* [Terminated Adopters](https://hdmi.org/adopter/terminated) - * There are currently 1,043 terminated adopters - * Includes noteworthy companies like Xilinx, Lattice Semiconductor, Cypress Semiconductor, EVGA (!), etc. - * No conclusion -* Raspberry Pi Trading Ltd is licensed - * They include the HDMI logo for products - * Therefore: Raspberry Pi products are legal, licensed end-user products - -## Alternative Implementations - -- [HDMI Intel FPGA IP Core](https://www.intel.com/content/www/us/en/programmable/products/intellectual-property/ip/interface-protocols/m-alt-hdmi-megacore.html): Stratix/Arria/Cyclone -- [Xilinx HDMI solutions](https://www.xilinx.com/products/intellectual-property/hdmi.html#overview): Virtex/Kintex/Zynq/Artix -- [Artix 7 HDMI Processing](https://github.com/hamsternz/Artix-7-HDMI-processing): VHDL, decode & encode -- [SimpleVOut](https://github.com/cliffordwolf/SimpleVOut): many formats, no auxiliary data - -If you know of another good alternative, open an issue and it will be added. - -## Reference Documents - -*These documents are not hosted here! They are available on Library Genesis and at other locations.* - -* [HDMI Specification v1.4b](https://b-ok.cc/book/5499564/fe35f4) -* [HDMI Specification v2.0](https://b-ok.cc/book/5464885/1f0b4c) -* [EIA-CEA861-D.pdf](https://libgen.is/book/index.php?md5=CEE424CA0F098096B6B4EC32C32F80AA) -* [CTA-861-G.pdf](https://b-ok.cc/book/5463292/52859e) -* [DVI Specification v1.0](https://www.cs.unc.edu/~stc/FAQs/Video/dvi_spec-V1_0.pdf) -* [IEC 60958-1](https://ia803003.us.archive.org/30/items/gov.in.is.iec.60958.1.2004/is.iec.60958.1.2004.pdf) -* [IEC 60958-3](https://ia800905.us.archive.org/22/items/gov.in.is.iec.60958.3.2003/is.iec.60958.3.2003.pdf) -* [E-DDC v1.2](https://glenwing.github.io/docs/) - -## Special Thanks - -* Mike Field's (@hamsternz) demos of DVI and HDMI output for helping me better understand HDMI - * http://www.hamsterworks.co.nz/mediawiki/index.php/Dvid_test - * http://www.hamsterworks.co.nz/mediawiki/index.php/Minimal_DVI-D -* Jean P. Nicolle (fpga4fun.com) for sparking my interest in HDMI - * https://www.fpga4fun.com/HDMI.html -* Bureau of Indian Standards for free equivalents of non-free IEC standards 60958-1, 60958-3, etc. -* @glenwing for [links to many VESA standard documents](https://glenwing.github.io/docs/) +S'il vous plaît regarder le readme anglais pour l'information à jour. diff --git a/src/Manifest.py b/src/Manifest.py index df2bde5..a6a7af3 100644 --- a/src/Manifest.py +++ b/src/Manifest.py @@ -3,8 +3,7 @@ "tmds_channel.sv", "packet_assembler.sv", "packet_picker.sv", - "OBUFDS.v", - "altera_gpio_lite.sv", + "serializer.sv", "auxiliary_video_information_info_frame.sv", "source_product_description_info_frame.sv", "audio_clock_regeneration_packet.sv", diff --git a/src/OBUFDS.v b/src/OBUFDS.v deleted file mode 100644 index cafe4a1..0000000 --- a/src/OBUFDS.v +++ /dev/null @@ -1,135 +0,0 @@ -// megafunction wizard: %GPIO Lite Intel FPGA IP v19.1% -// GENERATION: XML -// OBUFDS.v - -// Generated using ACDS version 19.1 670 - -`ifdef MODEL_TECH -// For purposes of simulation, OBUFDS just outputs the input signal along with an inverted copy. -// Check other simulators using https://gist.github.com/amuramatsu/be54c5548a0ece78c95897d570915a0e. -module OBUFDS ( - input wire [3:0] din, // din.export - output reg [3:0] pad_out, // pad_out.export - output reg [3:0] pad_out_b // pad_out_b.export - ); -always @* pad_out <= din; -always @* pad_out_b <= ~din; -endmodule -`else -module OBUFDS ( - input wire [3:0] din, // din.export - output wire [3:0] pad_out, // pad_out.export - output wire [3:0] pad_out_b // pad_out_b.export - ); - - altera_gpio_lite #( - .PIN_TYPE ("output"), - .SIZE (4), - .REGISTER_MODE ("bypass"), - .BUFFER_TYPE ("true_differential"), - .ASYNC_MODE ("none"), - .SYNC_MODE ("none"), - .BUS_HOLD ("false"), - .OPEN_DRAIN_OUTPUT ("false"), - .ENABLE_OE_PORT ("false"), - .ENABLE_NSLEEP_PORT ("false"), - .ENABLE_CLOCK_ENA_PORT ("false"), - .SET_REGISTER_OUTPUTS_HIGH ("false"), - .INVERT_OUTPUT ("false"), - .INVERT_INPUT_CLOCK ("false"), - .USE_ONE_REG_TO_DRIVE_OE ("false"), - .USE_DDIO_REG_TO_DRIVE_OE ("false"), - .USE_ADVANCED_DDR_FEATURES ("false"), - .USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY ("false"), - .ENABLE_OE_HALF_CYCLE_DELAY ("true"), - .INVERT_CLKDIV_INPUT_CLOCK ("false"), - .ENABLE_PHASE_INVERT_CTRL_PORT ("false"), - .ENABLE_HR_CLOCK ("false"), - .INVERT_OUTPUT_CLOCK ("false"), - .INVERT_OE_INCLOCK ("false"), - .ENABLE_PHASE_DETECTOR_FOR_CK ("false") - ) obufds_inst ( - .din (din), // din.export - .pad_out (pad_out), // pad_out.export - .pad_out_b (pad_out_b), // pad_out_b.export - .outclocken (1'b1), // (terminated) - .inclock (1'b0), // (terminated) - .inclocken (1'b0), // (terminated) - .fr_clock (), // (terminated) - .hr_clock (), // (terminated) - .invert_hr_clock (1'b0), // (terminated) - .outclock (1'b0), // (terminated) - .phy_mem_clock (1'b0), // (terminated) - .mimic_clock (), // (terminated) - .dout (), // (terminated) - .pad_io (), // (terminated) - .pad_io_b (), // (terminated) - .pad_in (4'b0000), // (terminated) - .pad_in_b (4'b0000), // (terminated) - .aset (1'b0), // (terminated) - .aclr (1'b0), // (terminated) - .sclr (1'b0), // (terminated) - .nsleep (4'b0000), // (terminated) - .oe (4'b0000) // (terminated) - ); - -endmodule -`endif -// Retrieval info: -// -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// IPFS_FILES : OBUFDS.vo -// RELATED_FILES: OBUFDS.v, altera_gpio_lite.sv diff --git a/src/altera_gpio_lite.sv b/src/altera_gpio_lite.sv deleted file mode 100644 index e3fde01..0000000 --- a/src/altera_gpio_lite.sv +++ /dev/null @@ -1,1200 +0,0 @@ -// (C) 2001-2019 Intel Corporation. All rights reserved. -// Your use of Intel Corporation's design tools, logic functions and other -// software and tools, and its AMPP partner logic functions, and any output -// files from any of the foregoing (including device programming or simulation -// files), and any associated documentation or information are expressly subject -// to the terms and conditions of the Intel Program License Subscription -// Agreement, Intel FPGA IP License Agreement, or other applicable -// license agreement, including, without limitation, that your use is for the -// sole purpose of programming logic devices manufactured by Intel and sold by -// Intel or its authorized distributors. Please refer to the applicable -// agreement for further details. - - -`timescale 1 ps / 1 ps - -module altgpio_one_bit( - inclock, - outclock, - phy_mem_clock, - inclocken, - outclocken, - oe, - din, - dout, - pad, - pad_b, - aset, - sclr, - hr_clock, - fr_clock, - mimic_clock, - nsleep -); - - parameter PIN_TYPE = "output"; - parameter BUFFER_TYPE = "single-ended"; - parameter REGISTER_MODE = "bypass"; - parameter ASYNC_MODE = "none"; - parameter SYNC_MODE = "none"; - parameter BUS_HOLD = "false"; - parameter SET_REGISTER_OUTPUTS_HIGH = "false"; - parameter USE_ENHANCED_DDR_HIO_REGISTER = "false"; - parameter BYPASS_THREE_QUARTER_REGISTER = "true"; - parameter INVERT_OUTPUT = "false"; - parameter INVERT_INPUT_CLOCK = "false"; - parameter INVERT_OUTPUT_CLOCK = "false"; - parameter INVERT_OE_INCLOCK = "false"; - parameter USE_ONE_REG_TO_DRIVE_OE = "false"; - parameter USE_DDIO_REG_TO_DRIVE_OE = "false"; - parameter OPEN_DRAIN_OUTPUT = "false"; - parameter ENABLE_OE_HALF_CYCLE_DELAY = "true"; - parameter USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY = "false"; - parameter ENABLE_CLOCK_ENA_PORT = "false"; - parameter ENABLE_HR_CLOCK = "false"; - parameter ENABLE_PHASE_DETECTOR_FOR_CK = "false"; - parameter ENABLE_NSLEEP_PORT = "false"; - - localparam DATA_SIZE = (REGISTER_MODE == "ddr") ? 2:1; - localparam DDIO_REG_POWER_UP = (ASYNC_MODE == "preset" || SET_REGISTER_OUTPUTS_HIGH == "true") ? "high" : "low"; - - input inclock; - input outclock; - input inclocken; - input outclocken; - input oe; - input nsleep; - input [DATA_SIZE - 1:0] din; - output [DATA_SIZE - 1:0] dout; - inout pad; - inout pad_b; - input aset; - input sclr; - input phy_mem_clock; - input hr_clock; - (* altera_attribute = "-name GLOBAL_SIGNAL\"OFF\"" *) output fr_clock; - output mimic_clock; - - wire din_ddr; - wire buf_in; - - wire oe_out; - wire nsleep_in; - - generate - if (PIN_TYPE == "output" || PIN_TYPE == "bidir") - begin - wire [1:0] din_fr; - if (INVERT_OUTPUT == "false") - begin - assign din_fr = din; - end - else - begin - assign din_fr = ~din; - end - - wire outclock_wire; - if (REGISTER_MODE != "bypass") - begin - if (INVERT_OUTPUT_CLOCK == "false") - begin: normal_input_clock - assign outclock_wire = outclock; - end - else - begin: inverted_output_clock - assign outclock_wire = ~outclock; - end - end - - wire outclocken_wire; - assign outclocken_wire = (ENABLE_CLOCK_ENA_PORT == "true") ? outclocken : 1'b1; - - if (REGISTER_MODE == "ddr" && USE_ENHANCED_DDR_HIO_REGISTER == "true") - begin - if (ASYNC_MODE != "none") - begin: async_mode_out_path_enhanced_ddr - fiftyfivenm_ddio_out - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), - .power_up(DDIO_REG_POWER_UP), - .use_new_clocking_model("true") - ) fr_out_data_ddio ( - .datainhi(din_fr[0]), - .datainlo(din_fr[1]), - .dataout(din_ddr), - .clkhi(outclock_wire), - .clklo(outclock_wire), - .muxsel(outclock_wire), - .areset(aset), - .ena(outclocken_wire), - .phymemclock(phy_mem_clock) - `ifndef ALTERA_RESERVED_QIS - , - .clk (outclock_wire), - .sreset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else if (SYNC_MODE != "none") - begin: sync_mode_out_path_enhanced_ddr - fiftyfivenm_ddio_out - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), - .power_up(DDIO_REG_POWER_UP), - .use_new_clocking_model("true") - ) fr_out_data_ddio ( - .datainhi(din_fr[0]), - .datainlo(din_fr[1]), - .dataout(din_ddr), - .clkhi(outclock_wire), - .clklo(outclock_wire), - .muxsel(outclock_wire), - .sreset(sclr), - .ena(outclocken_wire), - .phymemclock(phy_mem_clock) - `ifndef ALTERA_RESERVED_QIS - , - .clk (outclock_wire), - .areset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else - begin: out_path_enhanced_ddr - fiftyfivenm_ddio_out - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), - .power_up(DDIO_REG_POWER_UP), - .use_new_clocking_model("true") - ) fr_out_data_ddio ( - .datainhi(din_fr[0]), - .datainlo(din_fr[1]), - .dataout(din_ddr), - .clkhi(outclock_wire), - .clklo(outclock_wire), - .muxsel(outclock_wire), - .ena(outclocken_wire), - .phymemclock(phy_mem_clock) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .clk(1'b0), - .sreset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - end - else if (REGISTER_MODE == "ddr" && USE_ENHANCED_DDR_HIO_REGISTER == "false") - begin - if (ASYNC_MODE != "none") - begin: async_mode_out_path_ddr - fiftyfivenm_ddio_out - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .use_new_clocking_model("true"), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) - ) fr_out_data_ddio ( - .datainhi(din_fr[0]), - .datainlo(din_fr[1]), - .dataout(din_ddr), - .clkhi(outclock_wire), - .clklo(outclock_wire), - .muxsel(outclock_wire), - .areset(aset), - .ena(outclocken_wire) - `ifndef ALTERA_RESERVED_QIS - , - .clk(1'b0), - .phymemclock(1'b0), - .sreset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else if (SYNC_MODE != "none") - begin: sync_mode_out_path_ddr - fiftyfivenm_ddio_out - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .use_new_clocking_model("true"), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) - ) fr_out_data_ddio ( - .datainhi(din_fr[0]), - .datainlo(din_fr[1]), - .dataout(din_ddr), - .clkhi(outclock_wire), - .clklo(outclock_wire), - .muxsel(outclock_wire), - .sreset(sclr), - .ena(outclocken_wire) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .clk(1'b0), - .phymemclock(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else - begin: out_path_ddr - fiftyfivenm_ddio_out - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .use_new_clocking_model("true"), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) - ) fr_out_data_ddio ( - .datainhi(din_fr[0]), - .datainlo(din_fr[1]), - .dataout(din_ddr), - .clkhi(outclock_wire), - .clklo(outclock_wire), - .muxsel(outclock_wire), - .ena(outclocken_wire) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .clk(1'b0), - .phymemclock(1'b0), - .sreset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - end - else if (REGISTER_MODE == "single-register") - begin: out_path_sdr - reg reg_data_out /* synthesis altera_attribute="FAST_OUTPUT_REGISTER=on" */; - always @(posedge outclock_wire) - reg_data_out <= din_fr[0]; - - assign din_ddr = reg_data_out; - end - else - begin: out_path_reg_none - assign din_ddr = din_fr[0]; - end - end - endgenerate - - generate - - if (PIN_TYPE == "bidir" || PIN_TYPE == "output") - begin - wire oe_inclk_wire; - if (USE_ONE_REG_TO_DRIVE_OE == "true" || USE_DDIO_REG_TO_DRIVE_OE == "true") - begin - if (INVERT_OE_INCLOCK == "false") - begin: normal_oe_inclock - assign oe_inclk_wire = outclock; - end - else - begin: inverted_oe_inclock - assign oe_inclk_wire = ~outclock; - end - end - - wire oe_outclocken_wire; - assign oe_outclocken_wire = (ENABLE_CLOCK_ENA_PORT == "true") ? outclocken : 1'b1; - - if (USE_DDIO_REG_TO_DRIVE_OE == "true") - begin - if (REGISTER_MODE == "ddr" && USE_ENHANCED_DDR_HIO_REGISTER == "true") - begin - if (ASYNC_MODE != "none") - begin: async_mode_oe_path_enhanced_ddr - fiftyfivenm_ddio_oe - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), - .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), - .power_up(DDIO_REG_POWER_UP) - ) fr_oe_data_ddio ( - .oe(~oe), - .dataout(oe_out), - .clk(oe_inclk_wire), - .areset(aset), - .ena(oe_outclocken_wire), - .phymemclock(phy_mem_clock) - `ifndef ALTERA_RESERVED_QIS - , - .sreset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else if (SYNC_MODE != "none") - begin: sync_mode_oe_path_enhanced_ddr - fiftyfivenm_ddio_oe - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), - .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), - .power_up(DDIO_REG_POWER_UP) - ) fr_oe_data_ddio ( - .oe(~oe), - .dataout(oe_out), - .clk(oe_inclk_wire), - .sreset(sclr), - .ena(oe_outclocken_wire), - .phymemclock(phy_mem_clock) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else - begin: oe_path_enhanced_ddr - fiftyfivenm_ddio_oe - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), - .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), - .power_up(DDIO_REG_POWER_UP) - ) fr_oe_data_ddio ( - .oe(~oe), - .dataout(oe_out), - .clk(oe_inclk_wire), - .ena(oe_outclocken_wire), - .phymemclock(phy_mem_clock) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .sreset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - end - else if (REGISTER_MODE == "ddr" && USE_ENHANCED_DDR_HIO_REGISTER == "false") - begin - if (ASYNC_MODE != "none") - begin: async_mode_oe_path_ddr - fiftyfivenm_ddio_oe - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), - .power_up(DDIO_REG_POWER_UP), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) - ) fr_oe_data_ddio ( - .oe(~oe), - .dataout(oe_out), - .clk(oe_inclk_wire), - .areset(aset), - .ena(oe_outclocken_wire) - `ifndef ALTERA_RESERVED_QIS - , - .phymemclock(1'b0), - .sreset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else if (SYNC_MODE != "none") - begin: sync_mode_oe_path_ddr - fiftyfivenm_ddio_oe - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), - .power_up(DDIO_REG_POWER_UP), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) - ) fr_oe_data_ddio ( - .oe(~oe), - .dataout(oe_out), - .clk(oe_inclk_wire), - .sreset(sclr), - .ena(oe_outclocken_wire) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .phymemclock(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else - begin: oe_path_ddr - fiftyfivenm_ddio_oe - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), - .power_up(DDIO_REG_POWER_UP), - .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) - ) fr_oe_data_ddio ( - .oe(~oe), - .dataout(oe_out), - .clk(oe_inclk_wire), - .ena(oe_outclocken_wire) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .phymemclock(1'b0), - .sreset(1'b0), - .dfflo(), - .dffhi(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - end - end - else if (USE_ONE_REG_TO_DRIVE_OE == "true") - begin: oe_path_sdr - fiftyfivenm_ff oe_reg ( - .clk(oe_inclk_wire), - .d(~oe), - .clrn(1'b1), - .ena(1'b1), - .q(oe_out) - ); - end - else if (USE_ONE_REG_TO_DRIVE_OE == "false" && USE_DDIO_REG_TO_DRIVE_OE == "false") - begin: oe_path_reg_none - assign oe_out = ~oe; - end - end - endgenerate - - generate - if (PIN_TYPE == "input" || PIN_TYPE == "bidir") - begin - wire [1:0] ddr_input; - wire inclock_wire; - - if (REGISTER_MODE != "bypass") - begin - if (INVERT_INPUT_CLOCK == "false") - begin: normal_input_clock - assign inclock_wire = inclock; - end - else - begin: inverted_input_clock - assign inclock_wire = ~inclock; - end - end - - wire inclocken_wire; - assign inclocken_wire = (ENABLE_CLOCK_ENA_PORT == "true") ? inclocken : 1'b1; - - if (REGISTER_MODE == "ddr") - begin - if (USE_ENHANCED_DDR_HIO_REGISTER == "true" || USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY == "true") - begin - if (ENABLE_HR_CLOCK == "true") - begin - if (ASYNC_MODE != "none") - begin: async_mode_in_path_enhanced_ddr_with_halfrateresyncclk - fiftyfivenm_ddio_in - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .invert_input_clock(INVERT_INPUT_CLOCK) - ) fr_in_ddio ( - .datain(buf_in), - .clk(inclock_wire), - .ena(inclocken_wire), - .halfrateresyncclk(hr_clock), - .regouthi(ddr_input[1]), - .regoutlo(ddr_input[0]), - .clkout(fr_clock), - .areset(aset) - `ifndef ALTERA_RESERVED_QIS - , - .sreset(1'b0), - .dfflo(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else if (SYNC_MODE != "none") - begin:sync_mode_in_path_enhanced_ddr_with_halfrateresyncclk - fiftyfivenm_ddio_in - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .invert_input_clock(INVERT_INPUT_CLOCK) - ) fr_in_ddio ( - .datain(buf_in), - .clk (inclock_wire), - .ena(inclocken_wire), - .sreset(sclr), - .halfrateresyncclk(hr_clock), - .regouthi(ddr_input[1]), - .regoutlo(ddr_input[0]), - .clkout(fr_clock) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .dfflo(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - else - begin:in_path_enhanced_ddr_with_halfrateresyncclk - fiftyfivenm_ddio_in - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .invert_input_clock(INVERT_INPUT_CLOCK) - ) fr_in_ddio ( - .datain(buf_in), - .clk (inclock_wire), - .ena(inclocken_wire), - .halfrateresyncclk(hr_clock), - .regouthi(ddr_input[1]), - .regoutlo(ddr_input[0]), - .clkout(fr_clock) - `ifndef ALTERA_RESERVED_QIS - , - .sreset(1'b0), - .areset(1'b0), - .dfflo(), - .devpor(1'b1), - .devclrn(1'b1) - `endif - ); - end - end - else - begin - if (ASYNC_MODE != "none") - begin: async_mode_in_path_enhanced_ddr - fiftyfivenm_ddio_in - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .invert_input_clock(INVERT_INPUT_CLOCK) - ) fr_in_ddio ( - .datain(buf_in), - .clk(inclock_wire), - .ena(inclocken_wire), - .regouthi(ddr_input[1]), - .regoutlo(ddr_input[0]), - .clkout(fr_clock), - .areset(aset) - `ifndef ALTERA_RESERVED_QIS - , - .sreset(1'b0), - .dfflo(), - .devpor(1'b1), - .devclrn(1'b1), - .halfrateresyncclk(1'b0) - `endif - ); - end - else if (SYNC_MODE != "none") - begin:sync_mode_in_path_enhanced_ddr - fiftyfivenm_ddio_in - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .invert_input_clock(INVERT_INPUT_CLOCK) - ) fr_in_ddio ( - .datain(buf_in), - .clk (inclock_wire), - .ena(inclocken_wire), - .sreset(sclr), - .regouthi(ddr_input[1]), - .regoutlo(ddr_input[0]), - .clkout(fr_clock) - `ifndef ALTERA_RESERVED_QIS - , - .areset(1'b0), - .dfflo(), - .devpor(1'b1), - .devclrn(1'b1), - .halfrateresyncclk(1'b0) - `endif - ); - end - else - begin:in_path_enhanced_ddr - fiftyfivenm_ddio_in - #( - .async_mode(ASYNC_MODE), - .sync_mode(SYNC_MODE), - .power_up(DDIO_REG_POWER_UP), - .invert_input_clock(INVERT_INPUT_CLOCK) - ) fr_in_ddio ( - .datain(buf_in), - .clk (inclock_wire), - .ena(inclocken_wire), - .regouthi(ddr_input[1]), - .regoutlo(ddr_input[0]), - .clkout(fr_clock) - `ifndef ALTERA_RESERVED_QIS - , - .sreset(1'b0), - .areset(1'b0), - .dfflo(), - .devpor(1'b1), - .devclrn(1'b1), - .halfrateresyncclk(1'b0) - `endif - ); - end - end - end - else if (ENABLE_PHASE_DETECTOR_FOR_CK == "true") - begin - assign mimic_clock = buf_in; - end - else - begin: in_path_ddr - wire input_cell_l_q; - wire input_aset; - - assign input_aset = ( ASYNC_MODE == "clear") ? !aset : aset; - - fiftyfivenm_ff input_cell_l ( - .clk(inclock_wire), - .d(buf_in), - .clrn(input_aset), - .ena(inclocken_wire), - .q(input_cell_l_q) - ); - - fiftyfivenm_ff input_latch_l ( - .clk(~inclock_wire), - .d(input_cell_l_q), - .clrn(input_aset), - .ena(inclocken_wire), - .q(ddr_input[0]) - ); - - fiftyfivenm_ff input_cell_h ( - .clk(~inclock_wire), - .d(buf_in), - .clrn(input_aset), - .ena(inclocken_wire), - .q(ddr_input[1]) - ); - - end - end - else if (REGISTER_MODE == "single-register") - begin: in_path_sdr - reg reg_data_in /* synthesis altera_attribute="FAST_INPUT_REGISTER=on" */; - always @(posedge inclock_wire) begin - reg_data_in <= buf_in; - end - assign ddr_input[0] = reg_data_in; - end - else - begin: in_path_reg_none - assign ddr_input[0] = buf_in; - end - - assign dout[DATA_SIZE - 1:0] = ddr_input[DATA_SIZE - 1:0]; - - end - endgenerate - - generate - if (PIN_TYPE == "output" || PIN_TYPE == "bidir") - begin - if(BUFFER_TYPE == "pseudo_differential") - begin: pseudo_diff_output_buf - - wire wire_pseudo_diff_o; - wire wire_pseudo_diff_o_bar; - - fiftyfivenm_io_obuf - #( - .bus_hold(BUS_HOLD), - .open_drain_output(OPEN_DRAIN_OUTPUT) - ) obuf_a ( - .i(wire_pseudo_diff_o), - .oe(~oe_out), - .o(pad), - .obar() - `ifndef ALTERA_RESERVED_QIS - , - .seriesterminationcontrol(16'b0), - .devoe(1'b1) - `endif - ); - - fiftyfivenm_io_obuf - #( - .bus_hold(BUS_HOLD), - .open_drain_output(OPEN_DRAIN_OUTPUT) - ) obuf_a_bar ( - .i(wire_pseudo_diff_o_bar), - .oe(~oe_out), - .o(pad_b), - .obar() - `ifndef ALTERA_RESERVED_QIS - , - .seriesterminationcontrol(16'b0), - .devoe(1'b1) - `endif - ); - - fiftyfivenm_pseudo_diff_out pseudo_diff_a - ( - .i(din_ddr), - .o(wire_pseudo_diff_o), - .obar(wire_pseudo_diff_o_bar) - ); - - - - end - else if (BUFFER_TYPE == "true_differential") - begin: true_diff_output_buf - fiftyfivenm_io_obuf - #( - .bus_hold(BUS_HOLD), - .open_drain_output(OPEN_DRAIN_OUTPUT) - ) obuf ( - .i(din_ddr), - .oe(~oe_out), - .o(pad), - .obar(pad_b) - `ifndef ALTERA_RESERVED_QIS - , - .seriesterminationcontrol(16'b0), - .devoe(1'b1) - `endif - ); - end - else - begin: output_buf - fiftyfivenm_io_obuf - #( - .bus_hold(BUS_HOLD), - .open_drain_output(OPEN_DRAIN_OUTPUT) - ) obuf ( - .i(din_ddr), - .oe(~oe_out), - .o(pad), - .obar() - `ifndef ALTERA_RESERVED_QIS - , - .seriesterminationcontrol(16'b0), - .devoe(1'b1) - `endif - ); - end - end - endgenerate - - assign nsleep_in = (ENABLE_NSLEEP_PORT == "true") ? nsleep : 1'b1; - - generate - if (PIN_TYPE == "input" || PIN_TYPE == "bidir") - begin - if(BUFFER_TYPE == "true_differential" || BUFFER_TYPE == "pseudo_differential") - begin: diff_input_buf - if (ENABLE_NSLEEP_PORT == "true") - begin: diff_input_buf_with_nsleep - fiftyfivenm_io_ibuf - #( - .bus_hold(BUS_HOLD) - ) ibuf ( - .i(pad), - .ibar(pad_b), - .o(buf_in), - .nsleep(nsleep_in) - ); - end - else - begin: diff_input_buf_without_nsleep - fiftyfivenm_io_ibuf - #( - .bus_hold(BUS_HOLD) - ) ibuf ( - .i(pad), - .ibar(pad_b), - .o(buf_in) - ); - end - end - else - begin:input_buf - if (ENABLE_NSLEEP_PORT == "true") - begin: input_buf_with_nsleep - fiftyfivenm_io_ibuf - #( - .bus_hold(BUS_HOLD) - ) ibuf ( - .i(pad), - .o(buf_in), - .nsleep(nsleep_in) - `ifndef ALTERA_RESERVED_QIS - , - .ibar(1'b0) - `endif - ); - end - else - begin: input_buf_without_nsleep - fiftyfivenm_io_ibuf - #( - .bus_hold(BUS_HOLD) - ) ibuf ( - .i(pad), - .o(buf_in) - `ifndef ALTERA_RESERVED_QIS - , - .ibar(1'b0) - `endif - ); - end - end - end - endgenerate - - generate - if (PIN_TYPE == "output") - begin - assign dout = {DATA_SIZE{1'b0}}; - end - - if (PIN_TYPE == "output" || REGISTER_MODE != "ddr" || USE_ENHANCED_DDR_HIO_REGISTER == "false") - begin - assign fr_clock = 1'b0; - end - - if (PIN_TYPE == "input" || PIN_TYPE == "output" || REGISTER_MODE != "ddr" || ENABLE_PHASE_DETECTOR_FOR_CK == "false") - begin - assign mimic_clock = 1'b0; - end - endgenerate - -endmodule - -module altera_gpio_lite( - inclock, - outclock, - inclocken, - outclocken, - oe, - din, - dout, - pad_io, - pad_io_b, - pad_in, - pad_in_b, - pad_out, - pad_out_b, - aset, - aclr, - phy_mem_clock, - sclr, - hr_clock, - fr_clock, - invert_hr_clock, - mimic_clock, - nsleep -); - - parameter PIN_TYPE = "output"; - parameter BUFFER_TYPE = "single-ended"; - parameter REGISTER_MODE = "bypass"; - parameter SIZE = 4; - parameter ASYNC_MODE = "none"; - parameter SYNC_MODE = "none"; - parameter BUS_HOLD = "false"; - parameter SET_REGISTER_OUTPUTS_HIGH = "false"; - parameter INVERT_OUTPUT = "false"; - parameter INVERT_INPUT_CLOCK = "false"; - parameter INVERT_OUTPUT_CLOCK = "false"; - parameter INVERT_OE_INCLOCK = "false"; - parameter USE_ONE_REG_TO_DRIVE_OE = "false"; - parameter USE_DDIO_REG_TO_DRIVE_OE = "false"; - parameter OPEN_DRAIN_OUTPUT = "false"; - parameter USE_ADVANCED_DDR_FEATURES = "false"; - parameter USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY = "false"; - parameter INVERT_CLKDIV_INPUT_CLOCK = "false"; - parameter ENABLE_HR_CLOCK = "false"; - parameter ENABLE_OE_HALF_CYCLE_DELAY = "true"; - parameter ENABLE_OE_PORT = "false"; - parameter ENABLE_CLOCK_ENA_PORT = "false"; - parameter ENABLE_PHASE_INVERT_CTRL_PORT = "false"; - parameter ENABLE_PHASE_DETECTOR_FOR_CK = "false"; - parameter ENABLE_NSLEEP_PORT = "false"; - - localparam USE_ENHANCED_DDR_HIO_REGISTER = USE_ADVANCED_DDR_FEATURES; - localparam BYPASS_THREE_QUARTER_REGISTER = (USE_ADVANCED_DDR_FEATURES == "true") ? "false" : "true"; - localparam DATA_SIZE = (REGISTER_MODE == "ddr") ? 2 : 1; - - input inclock; - input outclock; - input inclocken; - input outclocken; - input [SIZE - 1:0] oe; - input [SIZE - 1:0] nsleep; - input [SIZE * DATA_SIZE - 1:0] din; - output [SIZE * DATA_SIZE - 1:0] dout; - inout [SIZE - 1:0] pad_io; - inout [SIZE - 1:0] pad_io_b; - input [SIZE - 1:0] pad_in; - input [SIZE - 1:0] pad_in_b; - output [SIZE - 1:0] pad_out; - output [SIZE - 1:0] pad_out_b; - input aset; - input aclr; - input sclr; - input phy_mem_clock; - input invert_hr_clock; - output [SIZE - 1:0] fr_clock; - output wire hr_clock; - output [SIZE - 1:0] mimic_clock; - - wire [SIZE * DATA_SIZE - 1:0] din_reordered; - wire [SIZE * DATA_SIZE - 1:0] dout_reordered; - wire aclr_aset_wire; - wire sclr_wire; - wire [SIZE - 1:0] pad_io; - wire [SIZE - 1:0] pad_io_b; - - - assign aclr_aset_wire = (ASYNC_MODE == "clear") ? aclr : (ASYNC_MODE == "preset") ? aset : 1'b1; - assign sclr_wire = (SYNC_MODE == "clear") ? sclr : 1'b0; - - generate - if (PIN_TYPE == "input") - begin - assign pad_io = pad_in; - assign pad_io_b = pad_in_b; - assign pad_out = {SIZE{1'b0}}; - assign pad_out_b = {SIZE{1'b0}}; - end - else if (PIN_TYPE == "output") - begin - assign pad_out = pad_io; - assign pad_out_b = pad_io_b; - end - else begin - assign pad_out = {SIZE{1'b0}}; - assign pad_out_b = {SIZE{1'b0}}; - end - endgenerate - - genvar j, k; - generate - begin : reorder - for(j = 0; j < SIZE ; j = j + 1) begin : j_loop - for(k = 0; k < DATA_SIZE; k = k + 1) begin : k_d_loop - assign din_reordered[j * DATA_SIZE + k] = din[j + k * SIZE]; - assign dout[j + k * SIZE] = dout_reordered[j * DATA_SIZE + k]; - end - end - end - endgenerate - - genvar i; - generate - begin : gpio_one_bit - for(i = 0 ; i < SIZE ; i = i + 1) begin : i_loop - wire oe_wire; - wire nsleep_wire; - - - assign oe_wire = (PIN_TYPE == "output" && ENABLE_OE_PORT == "false") ? 1'b1 : - (PIN_TYPE == "input") ? 1'b0 : oe[i]; - - - assign nsleep_wire = (PIN_TYPE == "input" && ENABLE_NSLEEP_PORT == "false") ? 1'b1 : - (PIN_TYPE == "output") ? 1'b0 : nsleep[i]; - - altgpio_one_bit #( - .PIN_TYPE(PIN_TYPE), - .BUFFER_TYPE(BUFFER_TYPE), - .REGISTER_MODE(REGISTER_MODE), - .ASYNC_MODE(ASYNC_MODE), - .SYNC_MODE(SYNC_MODE), - .BUS_HOLD(BUS_HOLD), - .SET_REGISTER_OUTPUTS_HIGH(SET_REGISTER_OUTPUTS_HIGH), - .USE_ENHANCED_DDR_HIO_REGISTER(USE_ENHANCED_DDR_HIO_REGISTER), - .USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY(USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY), - .BYPASS_THREE_QUARTER_REGISTER(BYPASS_THREE_QUARTER_REGISTER), - .INVERT_OUTPUT(INVERT_OUTPUT), - .INVERT_INPUT_CLOCK(INVERT_INPUT_CLOCK), - .INVERT_OUTPUT_CLOCK(INVERT_OUTPUT_CLOCK), - .INVERT_OE_INCLOCK(INVERT_OE_INCLOCK), - .USE_ONE_REG_TO_DRIVE_OE(USE_ONE_REG_TO_DRIVE_OE), - .USE_DDIO_REG_TO_DRIVE_OE(USE_DDIO_REG_TO_DRIVE_OE), - .OPEN_DRAIN_OUTPUT(OPEN_DRAIN_OUTPUT), - .ENABLE_OE_HALF_CYCLE_DELAY(ENABLE_OE_HALF_CYCLE_DELAY), - .ENABLE_CLOCK_ENA_PORT(ENABLE_CLOCK_ENA_PORT), - .ENABLE_HR_CLOCK(ENABLE_HR_CLOCK), - .ENABLE_PHASE_DETECTOR_FOR_CK(ENABLE_PHASE_DETECTOR_FOR_CK), - .ENABLE_NSLEEP_PORT(ENABLE_NSLEEP_PORT) - ) altgpio_bit_i ( - .inclock(inclock), - .outclock(outclock), - .phy_mem_clock(phy_mem_clock), - .inclocken(inclocken), - .outclocken(outclocken), - .oe(oe_wire), - .din(din_reordered[(i + 1) * DATA_SIZE - 1 : i * DATA_SIZE]), - .dout(dout_reordered[(i + 1) * DATA_SIZE - 1 : i * DATA_SIZE]), - .pad(pad_io[i]), - .pad_b(pad_io_b[i]), - .aset(aclr_aset_wire), - .sclr(sclr_wire), - .fr_clock(fr_clock[i]), - .hr_clock(hr_clock), - .mimic_clock(mimic_clock[i]), - .nsleep(nsleep_wire) - ); - end - end - endgenerate - - generate - if ((PIN_TYPE == "input" || PIN_TYPE == "bidir") && (ENABLE_HR_CLOCK == "true")) - begin - if (ENABLE_PHASE_INVERT_CTRL_PORT == "true") - begin - if (SYNC_MODE == "clear") - begin : clock_divider_sync_mode_invert_hr_clock - fiftyfivenm_io_clock_divider - #( - .invert_input_clock_phase(INVERT_CLKDIV_INPUT_CLOCK), - .use_phasectrlin(ENABLE_PHASE_INVERT_CTRL_PORT), - .sync_mode(SYNC_MODE) - ) io_clkdiv ( - .clk(inclock), - .phaseinvertctrl(invert_hr_clock), - .sreset(sclr_wire), - .clkout(hr_clock) - ); - end - else - begin : clock_divider_invert_hr_clock - fiftyfivenm_io_clock_divider - #( - .invert_input_clock_phase(INVERT_CLKDIV_INPUT_CLOCK), - .use_phasectrlin(ENABLE_PHASE_INVERT_CTRL_PORT), - .sync_mode(SYNC_MODE) - ) io_clkdiv ( - .clk(inclock), - .phaseinvertctrl(invert_hr_clock), - .clkout(hr_clock) - `ifndef ALTERA_RESERVED_QIS - , - .sreset(1'b0) - `endif - ); - end - end - else - begin - if (SYNC_MODE == "clear") - begin : clock_divider_sync_mode - fiftyfivenm_io_clock_divider - #( - .invert_input_clock_phase(INVERT_CLKDIV_INPUT_CLOCK), - .use_phasectrlin(ENABLE_PHASE_INVERT_CTRL_PORT), - .sync_mode(SYNC_MODE) - ) io_clkdiv ( - .clk(inclock), - .sreset(sclr_wire), - .clkout(hr_clock) - `ifndef ALTERA_RESERVED_QIS - , - .phaseinvertctrl(1'b0) - `endif - ); - end - else - begin : clock_divider - fiftyfivenm_io_clock_divider - #( - .invert_input_clock_phase(INVERT_CLKDIV_INPUT_CLOCK), - .use_phasectrlin(ENABLE_PHASE_INVERT_CTRL_PORT), - .sync_mode(SYNC_MODE) - ) io_clkdiv ( - .clk(inclock), - .clkout(hr_clock) - `ifndef ALTERA_RESERVED_QIS - , - .sreset(1'b0), - .phaseinvertctrl(1'b0) - `endif - ); - end - end - end - else begin - assign hr_clock = 1'b0; - end - endgenerate - -endmodule diff --git a/src/hdmi.sv b/src/hdmi.sv index f9827a8..c8a611a 100644 --- a/src/hdmi.sv +++ b/src/hdmi.sv @@ -18,9 +18,6 @@ module hdmi // Enable this flag if the output should be a DVI signal. You might want to do this to reduce resource usage or if you're only outputting video. parameter bit DVI_OUTPUT = 1'b0, - // When enabled, DDRIO (Double Data Rate I/O) is used and clk_pixel_x10 only needs to be five times as fast as clk_pixel. - parameter bit DDRIO = 1'b0, - // **All parameters below matter ONLY IF you plan on sending auxiliary data (DVI_OUTPUT == 1'b0)** // Specify the refresh rate in Hz you are using for audio calculations @@ -41,17 +38,15 @@ module hdmi parameter bit [7:0] SOURCE_DEVICE_INFORMATION = 8'h00 // See README.md or CTA-861-G for the list of valid codes ) ( - input logic clk_pixel_x10, + input logic clk_pixel_x5, input logic clk_pixel, input logic clk_audio, input logic [23:0] rgb, input logic [AUDIO_BIT_WIDTH-1:0] audio_sample_word [1:0], // These outputs go to your HDMI port - output logic [2:0] tmds_p, - output logic tmds_clock_p, - output logic [2:0] tmds_n, - output logic tmds_clock_n, + output logic [2:0] tmds, + output logic tmds_clock, // All outputs below this line stay inside the FPGA // They are used (by you) to pick the color each pixel should have @@ -145,6 +140,16 @@ generate assign screen_start_y = frame_height - screen_height; endgenerate +localparam real VIDEO_RATE = (VIDEO_ID_CODE == 1 ? 25.2E6 + : VIDEO_ID_CODE == 2 || VIDEO_ID_CODE == 3 ? 27.027E6 + : VIDEO_ID_CODE == 4 ? 74.25E6 + : VIDEO_ID_CODE == 16 ? 148.5E6 + : VIDEO_ID_CODE == 17 || VIDEO_ID_CODE == 18 ? 27E6 + : VIDEO_ID_CODE == 19 ? 74.25E6 + : VIDEO_ID_CODE == 34 ? 74.25E6 + : VIDEO_ID_CODE == 97 || VIDEO_ID_CODE == 107 ? 594E6 + : 0) * (VIDEO_REFRESH_RATE == 59.94 || VIDEO_REFRESH_RATE == 29.97 ? 1000.0/1001.0 : 1); // https://groups.google.com/forum/#!topic/sci.engr.advanced-tv/DQcGk5R_zsM + // Wrap-around pixel position counters indicating the pixel to be generated by the user in THIS clock and sent out in the NEXT clock. always_ff @(posedge clk_pixel) begin @@ -206,15 +211,6 @@ generate logic video_field_end; assign video_field_end = cx == frame_width - 1'b1 && cy == frame_height - 1'b1; logic [4:0] packet_pixel_counter; - localparam real VIDEO_RATE = (VIDEO_ID_CODE == 1 ? 25.2E6 - : VIDEO_ID_CODE == 2 || VIDEO_ID_CODE == 3 ? 27.027E6 - : VIDEO_ID_CODE == 4 ? 74.25E6 - : VIDEO_ID_CODE == 16 ? 148.5E6 - : VIDEO_ID_CODE == 17 || VIDEO_ID_CODE == 18 ? 27E6 - : VIDEO_ID_CODE == 19 ? 74.25E6 - : VIDEO_ID_CODE == 34 ? 74.25E6 - : VIDEO_ID_CODE == 97 || VIDEO_ID_CODE == 107 ? 594E6 - : 0) * (VIDEO_REFRESH_RATE == 59.94 || VIDEO_REFRESH_RATE == 29.97 ? 1000.0/1001.0 : 1); // https://groups.google.com/forum/#!topic/sci.engr.advanced-tv/DQcGk5R_zsM packet_picker #( .VIDEO_ID_CODE(VIDEO_ID_CODE), .VIDEO_RATE(VIDEO_RATE), @@ -251,89 +247,16 @@ generate endgenerate // All logic below relates to the production and output of the 10-bit TMDS code. -logic [9:0] tmds [NUM_CHANNELS-1:0] /* verilator public_flat */ ; +logic [9:0] tmds_internal [NUM_CHANNELS-1:0] /* verilator public_flat */ ; genvar i; generate // TMDS code production. for (i = 0; i < NUM_CHANNELS; i++) begin: tmds_gen - tmds_channel #(.CN(i)) tmds_channel (.clk_pixel(clk_pixel), .video_data(video_data[i*8+7:i*8]), .data_island_data(data_island_data[i*4+3:i*4]), .control_data(control_data[i*2+1:i*2]), .mode(mode), .tmds(tmds[i])); + tmds_channel #(.CN(i)) tmds_channel (.clk_pixel(clk_pixel), .video_data(video_data[i*8+7:i*8]), .data_island_data(data_island_data[i*4+3:i*4]), .control_data(control_data[i*2+1:i*2]), .mode(mode), .tmds(tmds_internal[i])); end - - // Shift registers are loaded with a set of values from tmds_channels every ten clk_pixel_x10. They are shifted out by the time the next set is loaded. - // They are initialized to the 0,0 control signal from Section 5.4.2. - // This gives time for the first pixel to be generated by the first clock. - logic [9:0] tmds_shift [NUM_CHANNELS-1:0] = '{10'b1101010100, 10'b1101010100, 10'b1101010100}; - - logic tmds_control = 1'd0; - always_ff @(posedge clk_pixel) - tmds_control <= !tmds_control; - logic [3:0] tmds_control_synchronizer_chain = 2'd0; - always_ff @(posedge clk_pixel_x10) - tmds_control_synchronizer_chain <= {tmds_control, tmds_control_synchronizer_chain[3:1]}; - - logic [9:0] tmds_mux [NUM_CHANNELS-1:0]; - always_comb - begin - if (tmds_control_synchronizer_chain[1] ^ tmds_control_synchronizer_chain[0]) - tmds_mux = tmds; - else - tmds_mux = tmds_shift; - end - - // See Section 5.4.1 - for (i = 0; i < NUM_CHANNELS; i++) - begin: tmds_shifting - always_ff @(posedge clk_pixel_x10) - tmds_shift[i] <= tmds_control_synchronizer_chain[1] ^ tmds_control_synchronizer_chain[0] ? tmds_mux[i] : tmds_shift[i] >> (DDRIO ? 2 : 1); - end - - logic [9:0] tmds_shift_clk_pixel = 10'b0000011111; - always_ff @(posedge clk_pixel_x10) - tmds_shift_clk_pixel <= tmds_control_synchronizer_chain[1] ^ tmds_control_synchronizer_chain[0] ? 10'b0000011111 : {tmds_shift_clk_pixel[(DDRIO ? 1 : 0):0], tmds_shift_clk_pixel[9:(DDRIO ? 2 : 1)]}; - - // Double data rate support - logic [NUM_CHANNELS-1:0] tmds_current; - logic tmds_current_clk; - - if (DDRIO) - begin - `ifdef SYNTHESIS // TODO: Is this really Vivado? https://forums.xilinx.com/t5/Simulation-and-Verification/Predefined-constant-for-simulation/td-p/986901 - `ifndef ALTERA_RESERVED_QIS - for (i = 0; i < NUM_CHANNELS; i++) - begin: oddr2_gen - ODDR2 #(.DDR_ALIGNMENT("NONE"), .INIT(1'b0), .SRTYPE("SYNC")) clock_forward_inst (.Q(tmds_current[i]), .C0(clk_pixel_x10), .C1(!clk_pixel_x10), .CE(1'b1), .D0(tmds_shift[i][0]), .D1(tmds_shift[i][1]), .R(1'b0), .S(1'b0)); - end - ODDR2 #(.DDR_ALIGNMENT("NONE"), .INIT(1'b0), .SRTYPE("SYNC")) clock_forward_inst (.Q(tmds_current_clk), .C0(clk_pixel_x10), .C1(!clk_pixel_x10), .CE(1'b1), .D0(tmds_shift_clk_pixel[0]), .D1(tmds_shift_clk_pixel[1]), .R(1'b0), .S(1'b0)); - `endif - `else - altDDIO_out DDRIO (.dataout({tmds_current, tmds_current_clk}), .outclock(clk_pixel_x10), .datain_h({tmds_shift[2][0], tmds_shift[1][0], tmds_shift[0][0], tmds_shift_clk_pixel[0]}), .datain_l({tmds_shift[2][1], tmds_shift[1][1], tmds_shift[0][1], tmds_shift_clk_pixel[1]}), .aclr(1'b0), .aset(1'b0), .outclocken(1'b1), .sclr(1'b0), .sset(1'b0)); - defparam DDRIO.inverted_input_clocks = "OFF", DDRIO.lpm_hint = "UNUSED", DDRIO.lpm_type = "altDDIO_out", DDRIO.power_up_high = "OFF", DDRIO.width = NUM_CHANNELS + 1; - `endif - end - else - begin - assign tmds_current = {tmds_shift[2][0], tmds_shift[1][0], tmds_shift[0][0]}; - assign tmds_current_clk = tmds_shift_clk_pixel[0]; - end - -`ifndef VERILATOR - // Differential signal output - `ifdef SYNTHESIS // TODO: Is this really Vivado? https://forums.xilinx.com/t5/Simulation-and-Verification/Predefined-constant-for-simulation/td-p/986901 - `ifndef ALTERA_RESERVED_QIS - for (i = 0; i < NUM_CHANNELS; i++) - begin: obufds_gen - OBUFDS obufds (.I(tmds_current[i]), .O(tmds_p[i]), .OB(tmds_n[i])); - end - OBUFDS OBUFDS_clock(.I(tmds_current_clk), .O(tmds_clock_p), .OB(tmds_clock_n)); - `endif - `else - // If Altera synthesis, a true differential buffer is built with altera_gpio_lite from the Intel IP Catalog. - // If simulation, a mocked signal inversion is used. - OBUFDS obufds(.din({tmds_current, tmds_current_clk}), .pad_out({tmds_p, tmds_clock_p}), .pad_out_b({tmds_n, tmds_clock_n})); - `endif -`endif - endgenerate +serializer #(.NUM_CHANNELS(NUM_CHANNELS), .VIDEO_RATE(VIDEO_RATE)) serializer(.clk_pixel(clk_pixel), .clk_pixel_x5(clk_pixel_x5), .tmds_internal(tmds_internal), .tmds(tmds), .tmds_clock(tmds_clock)); + endmodule diff --git a/src/serializer.sv b/src/serializer.sv new file mode 100644 index 0000000..12d5926 --- /dev/null +++ b/src/serializer.sv @@ -0,0 +1,165 @@ +module serializer +#( + parameter int NUM_CHANNELS = 3, + parameter real VIDEO_RATE +) +( + input logic clk_pixel, + input logic clk_pixel_x5, + input logic [9:0] tmds_internal [NUM_CHANNELS-1:0], + output logic [2:0] tmds, + output logic tmds_clock +); + +`ifndef VERILATOR + `ifdef SYNTHESIS + `ifndef ALTERA_RESERVED_QIS + // Based on VHDL implementation by Furkan Cayci, 2010 + logic [9:0] tmds_internal_plus_clock [NUM_CHANNELS:0]; + assign tmds_internal_plus_clock =tmds_internal_plus_clock '{10'b0000011111, tmds_internal[2], tmds_internal[1], tmds_internal[0]}; + logic [1:0] cascade [NUM_CHANNELS:0]; + genvar i; + generate + for (i = 0; i <= NUM_CHANNELS; i++) + begin: xilinx_serialize + OSERDES2 #(.DATA_RATE_OQ("DDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(10), .SERDES_MODE("MASTER"), .TRISTATE_WIDTH(1)) + primary ( + .OQ(i == NUM_CHANNELS ? tmds_clock : tmds[i]), + .OFB(), + .TQ(), + .TFB(), + .SHIFTOUT1(), + .SHIFTOUT2(), + .TBYTEOUT(), + .CLK(clk_pixel_x5), + .CLKDIV(clk_pixel), + .D1(tmds_internal_plus_clock[i][0]), + .D2(tmds_internal_plus_clock[i][1]), + .D3(tmds_internal_plus_clock[i][2]), + .D4(tmds_internal_plus_clock[i][3]), + .D5(tmds_internal_plus_clock[i][4]), + .D6(tmds_internal_plus_clock[i][5]), + .D7(tmds_internal_plus_clock[i][6]), + .D8(tmds_internal_plus_clock[i][7]), + .TCE(1'b0), + .OCE(1'b1), + .TBYTEIN(1'b0), + .RST(), + .SHIFTIN1(cascade[i][0]), + .SHIFTIN2(cascade[i][1]), + .T1(1'b0), + .T2(1'b0), + .T3(1'b0), + .T4(1'b0) + ); + OSERDES2 #(.DATA_RATE_OQ("DDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(10), .SERDES_MODE("SLAVE"), .TRISTATE_WIDTH(1)) + secondary ( + .OQ(), + .OFB(), + .TQ(), + .TFB(), + .SHIFTOUT1(cascade[i][0]), + .SHIFTOUT2(cascade[i][1]), + .TBYTEOUT(), + .CLK(clk_pixel_x5), + .CLKDIV(clk_pixel), + .D1(1'b0), + .D2(1'b0), + .D3(tmds_internal_plus_clock[i][8]), + .D4(tmds_internal_plus_clock[i][9]), + .D5(1'b0), + .D6(1'b0), + .D7(1'b0), + .D8(1'b0), + .TCE(1'b0), + .OCE(1'b1), + .TBYTEIN(1'b0), + .RST(), + .SHIFTIN1(1'b0), + .SHIFTIN2(1'b0), + .T1(1'b0), + .T2(1'b0), + .T3(1'b0), + .T4(1'b0) + ); + end + endgenerate + `endif + `else + logic [9:0] tmds_reversed [NUM_CHANNELS-1:0]; + genvar i, j; + generate + for (i = 0; i < NUM_CHANNELS; i++) + begin: tmds_rev + for (j = 0; j < 10; j++) + begin: tmds_rev_channel + assign tmds_reversed[i][j] = tmds_internal[i][9-j]; + end + end + endgenerate + `ifdef MODEL_TECH + logic [3:0] position = 4'd0; + always_ff @(posedge clk_pixel_x5) + begin + tmds <= {tmds_reversed[2][position], tmds_reversed[1][position], tmds_reversed[0][position]}; + tmds_clock <= position >= 4'd5; + position <= position == 4'd9 ? 4'd0 : position + 1'd1; + end + always_ff @(negedge clk_pixel_x5) + begin + tmds <= {tmds_reversed[2][position], tmds_reversed[1][position], tmds_reversed[0][position]}; + tmds_clock <= position >= 4'd5; + position <= position == 4'd9 ? 4'd0 : position + 1'd1; + end + `else + altlvds_tx ALTLVDS_TX_component ( + .tx_in ({10'b1111100000, tmds_reversed[2], tmds_reversed[1], tmds_reversed[0]}), + .tx_inclock (clk_pixel_x5), + .tx_out ({tmds_clock, tmds[2], tmds[1], tmds[0]}), + .tx_outclock (), + .pll_areset (1'b0), + .sync_inclock (1'b0), + .tx_coreclock (), + .tx_data_reset (1'b0), + .tx_enable (1'b1), + .tx_locked (), + .tx_pll_enable (1'b1), + .tx_syncclock (clk_pixel)); + defparam + ALTLVDS_TX_component.center_align_msb = "UNUSED", + ALTLVDS_TX_component.common_rx_tx_pll = "OFF", + ALTLVDS_TX_component.coreclock_divide_by = 1, + // ALTLVDS_TX_component.data_rate = "800.0 Mbps", + ALTLVDS_TX_component.deserialization_factor = 10, + ALTLVDS_TX_component.differential_drive = 0, + ALTLVDS_TX_component.enable_clock_pin_mode = "UNUSED", + ALTLVDS_TX_component.implement_in_les = "OFF", + ALTLVDS_TX_component.inclock_boost = 0, + ALTLVDS_TX_component.inclock_data_alignment = "EDGE_ALIGNED", + ALTLVDS_TX_component.inclock_period = int'(10000000.0 / (VIDEO_RATE * 10.0)), + ALTLVDS_TX_component.inclock_phase_shift = 0, + // ALTLVDS_TX_component.intended_device_family = "Cyclone V", + ALTLVDS_TX_component.lpm_hint = "CBX_MODULE_PREFIX=altlvds_tx_inst", + ALTLVDS_TX_component.lpm_type = "altlvds_tx", + ALTLVDS_TX_component.multi_clock = "OFF", + ALTLVDS_TX_component.number_of_channels = 4, + // ALTLVDS_TX_component.outclock_alignment = "EDGE_ALIGNED", + // ALTLVDS_TX_component.outclock_divide_by = 1, + // ALTLVDS_TX_component.outclock_duty_cycle = 50, + // ALTLVDS_TX_component.outclock_multiply_by = 1, + // ALTLVDS_TX_component.outclock_phase_shift = 0, + // ALTLVDS_TX_component.outclock_resource = "Dual-Regional clock", + ALTLVDS_TX_component.output_data_rate = int'(VIDEO_RATE * 10.0), + ALTLVDS_TX_component.pll_compensation_mode = "AUTO", + ALTLVDS_TX_component.pll_self_reset_on_loss_lock = "OFF", + ALTLVDS_TX_component.preemphasis_setting = 0, + // ALTLVDS_TX_component.refclk_frequency = "20.000000 MHz", + ALTLVDS_TX_component.registered_input = "OFF", + ALTLVDS_TX_component.use_external_pll = "ON", + ALTLVDS_TX_component.use_no_phase_shift = "ON", + ALTLVDS_TX_component.vod_setting = 0, + ALTLVDS_TX_component.clk_src_is_pll = "off"; + `endif + `endif +`endif +endmodule \ No newline at end of file diff --git a/test/top_tb/pll.sv b/test/top_tb/pll.sv index a56ff4e..ac1ad4e 100644 --- a/test/top_tb/pll.sv +++ b/test/top_tb/pll.sv @@ -10,8 +10,8 @@ module pll ( ); always begin - #3969ps c0 = 1; - #3969ps c0 = 0; + #7937ps c0 = 1; + #7937ps c0 = 0; end always diff --git a/test/top_tb/top_tb.sv b/test/top_tb/top_tb.sv index b8adb2a..fe33696 100644 --- a/test/top_tb/top_tb.sv +++ b/test/top_tb/top_tb.sv @@ -51,9 +51,9 @@ endgenerate always @(posedge top.clk_pixel) begin - tmds_values[0] <= top.hdmi.tmds[0]; - tmds_values[1] <= top.hdmi.tmds[1]; - tmds_values[2] <= top.hdmi.tmds[2]; + tmds_values[0] <= top.hdmi.tmds_internal[0]; + tmds_values[1] <= top.hdmi.tmds_internal[1]; + tmds_values[2] <= top.hdmi.tmds_internal[2]; end logic [4:0] data_counter = 0; diff --git a/top/top.sv b/top/top.sv index 887690c..e344f81 100644 --- a/top/top.sv +++ b/top/top.sv @@ -1,14 +1,12 @@ module top (); -logic [2:0] tmds_p; -logic tmds_clock_p; -logic [2:0] tmds_n; -logic tmds_clock_n; +logic [2:0] tmds; +logic tmds_clock; logic clk_pixel; -logic clk_pixel_x10; +logic clk_pixel_x5; logic clk_audio; -pll pll(.c0(clk_pixel_x10), .c1(clk_pixel), .c2(clk_audio)); +pll pll(.c0(clk_pixel_x5), .c1(clk_pixel), .c2(clk_audio)); logic [15:0] audio_sample_word [1:0] = '{16'd0, 16'd0}; always @(posedge clk_audio) @@ -22,15 +20,13 @@ always @(posedge clk_pixel) // 640x480 @ 59.94Hz hdmi #(.VIDEO_ID_CODE(1), .VIDEO_REFRESH_RATE(59.94), .AUDIO_RATE(48000), .AUDIO_BIT_WIDTH(16)) hdmi( - .clk_pixel_x10(clk_pixel_x10), + .clk_pixel_x5(clk_pixel_x5), .clk_pixel(clk_pixel), .clk_audio(clk_audio), .rgb(rgb), .audio_sample_word(audio_sample_word), - .tmds_p(tmds_p), - .tmds_clock_p(tmds_clock_p), - .tmds_n(tmds_n), - .tmds_clock_n(tmds_clock_n), + .tmds(tmds), + .tmds_clock(tmds_clock), .cx(cx), .cy(cy), .screen_start_x(screen_start_x),