HDMI/DVI Encoder/Decoder
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
5.6 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. -- -----------------------------------------------------------------------------
  2. -- Copyright (c) 2013 Benjamin Krill <benjamin@krll.de>
  3. --
  4. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  5. -- of this software and associated documentation files (the "Software"), to deal
  6. -- in the Software without restriction, including without limitation the rights
  7. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. -- copies of the Software, and to permit persons to whom the Software is
  9. -- furnished to do so, subject to the following conditions:
  10. --
  11. -- The above copyright notice and this permission notice shall be included in
  12. -- all copies or substantial portions of the Software.
  13. --
  14. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. -- THE SOFTWARE.
  21. -- -----------------------------------------------------------------------------
  22. library ieee;
  23. use ieee.std_logic_1164.all;
  24. use ieee.numeric_std.all;
  25. use work.dvi_package.all;
  26. library UNISIM;
  27. use UNISIM.Vcomponents.all;
  28. entity chnlbond is
  29. port (
  30. clk : in std_logic;
  31. rst_n : in std_logic;
  32. rawdata_i : in std_logic_vector(9 downto 0);
  33. psaligned_i : in std_logic;
  34. other_valid_i : in std_logic_vector(1 downto 0);
  35. other_ready_i : in std_logic_vector(1 downto 0);
  36. ready_o : out std_logic;
  37. sdata_o : out std_logic_vector(9 downto 0)
  38. );
  39. end chnlbond;
  40. architecture chnlbond of chnlbond is
  41. signal rawdata_vld : std_logic;
  42. signal we : std_logic;
  43. signal wa, ra : unsigned(3 downto 0);
  44. signal dpfo_dout : std_logic_vector(9 downto 0);
  45. signal sdata : std_logic_vector(9 downto 0);
  46. signal rcvd_ctkn : std_logic;
  47. signal rcvd_ctkn_q : std_logic;
  48. signal blnkbgn : std_logic;
  49. signal skip_line : std_logic;
  50. signal next_blnkbgn : std_logic;
  51. signal ready : std_logic;
  52. signal rawdata_vld_q : std_logic;
  53. signal rawdata_vld_s : std_logic;
  54. signal ra_en : std_logic;
  55. begin
  56. sdata_o <= sdata;
  57. ready_o <= ready;
  58. rawdata_vld <= other_valid_i(0) and other_valid_i(1) and psaligned_i;
  59. -- ----------------------------------------------------------
  60. -- FIFO Write Control Logic
  61. -- ----------------------------------------------------------
  62. process (clk, rst_n)
  63. begin
  64. if rst_n = '0' then
  65. we <= '0';
  66. sdata <= (others => '0');
  67. wa <= (others => '0');
  68. elsif rising_edge(clk) then
  69. we <= rawdata_vld;
  70. if rawdata_vld = '1' then
  71. wa <= wa + "1";
  72. else
  73. wa <= (others => '0');
  74. end if;
  75. sdata <= dpfo_dout;
  76. end if;
  77. end process;
  78. -- ----------------------------------------------------------
  79. -- FIFO
  80. -- ----------------------------------------------------------
  81. cbfifo_i: entity work.DRAM16XN
  82. generic map ( data_width => 10 )
  83. port map (
  84. DATA_IN => rawdata_i,
  85. ADDRESS => std_logic_vector(wa),
  86. ADDRESS_DP => std_logic_vector(ra),
  87. WRITE_EN => we,
  88. CLK => clk,
  89. O_DATA_OUT => open,
  90. O_DATA_OUT_DP => dpfo_dout
  91. );
  92. -- ----------------------------------------------------------
  93. -- FIFO read Control Logic
  94. -- ----------------------------------------------------------
  95. next_blnkbgn <= skip_line and blnkbgn;
  96. process (clk, rst_n)
  97. begin
  98. if rst_n = '0' then
  99. rcvd_ctkn <= '0';
  100. rcvd_ctkn_q <= '0';
  101. ready <= '0';
  102. skip_line <= '0';
  103. rawdata_vld_q <= '0';
  104. rawdata_vld_s <= '0';
  105. elsif rising_edge(clk) then
  106. -- ---------------------------
  107. -- Use blank period beginning
  108. -- as a speical marker to
  109. -- align all channel together
  110. -- ---------------------------
  111. rcvd_ctkn <= '0';
  112. if sdata = CTRLTOKEN0 or sdata = CTRLTOKEN1
  113. or sdata = CTRLTOKEN2 or sdata = CTRLTOKEN3 then
  114. rcvd_ctkn <= '1';
  115. end if;
  116. rcvd_ctkn_q <= rcvd_ctkn;
  117. blnkbgn <= rcvd_ctkn and not rcvd_ctkn_q;
  118. -- ---------------------------
  119. -- skip the current line
  120. -- ---------------------------
  121. if rawdata_vld = '0' then
  122. skip_line <= '0';
  123. elsif blnkbgn = '1' then
  124. skip_line <= '1';
  125. end if;
  126. -- ---------------------------
  127. -- Declare my own readiness
  128. -- ---------------------------
  129. if rawdata_vld = '0' then
  130. ready <= '0';
  131. elsif next_blnkbgn = '1' then
  132. ready <= '1';
  133. end if;
  134. rawdata_vld_q <= rawdata_vld;
  135. rawdata_vld_s <= rawdata_vld and not rawdata_vld_q;
  136. end if;
  137. end process;
  138. -- ----------------------------------------------------------
  139. -- 1. FIFO flow through first when all channels are found valid(phase aligned)
  140. -- 2. When the speical marker on my channel is found, the fifo read is hold
  141. -- 3. Until the same markers are found across all three channels, the fifo read resumes
  142. -- ----------------------------------------------------------
  143. process (clk, rst_n)
  144. begin
  145. if rst_n = '0' then
  146. ra_en <= '0';
  147. ra <= (others => '0');
  148. elsif rising_edge(clk) then
  149. if rawdata_vld_s = '1' or (other_ready_i(0) = '1' and other_ready_i(1) = '1' and ready = '1') then
  150. ra_en <= '1';
  151. elsif next_blnkbgn = '1' and not (other_ready_i(0) = '1' and other_ready_i(1) = '1' and ready = '1') then
  152. ra_en <= '0';
  153. end if;
  154. -- ---------------------------
  155. -- FIFO Read Address Counter
  156. -- ---------------------------
  157. if rawdata_vld = '0' then
  158. ra <= (others => '0');
  159. elsif ra_en = '1' then
  160. ra <= ra + "1";
  161. end if;
  162. end if;
  163. end process;
  164. end chnlbond;