2013-10-07 09:07:08 +02:00
|
|
|
-- -----------------------------------------------------------------------------
|
|
|
|
-- Copyright (c) 2013 Benjamin Krill <benjamin@krll.de>
|
2013-10-07 09:34:06 +02:00
|
|
|
--
|
2013-10-07 09:07:08 +02:00
|
|
|
-- 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:
|
2013-10-07 09:34:06 +02:00
|
|
|
--
|
2013-10-07 09:07:08 +02:00
|
|
|
-- The above copyright notice and this permission notice shall be included in
|
|
|
|
-- all copies or substantial portions of the Software.
|
2013-10-07 09:34:06 +02:00
|
|
|
--
|
2013-10-07 09:07:08 +02:00
|
|
|
-- 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.
|
|
|
|
-- -----------------------------------------------------------------------------
|
2013-09-23 10:20:49 +02:00
|
|
|
library ieee;
|
|
|
|
use ieee.std_logic_1164.all;
|
|
|
|
use ieee.numeric_std.all;
|
|
|
|
use work.dvi_package.all;
|
|
|
|
|
|
|
|
library UNISIM;
|
|
|
|
use UNISIM.Vcomponents.all;
|
|
|
|
|
|
|
|
entity encoder is
|
|
|
|
port (
|
|
|
|
clk : in std_logic;
|
|
|
|
rst_n : in std_logic;
|
|
|
|
data_i : in std_logic_vector(7 downto 0);
|
|
|
|
c0 : in std_logic;
|
|
|
|
c1 : in std_logic;
|
|
|
|
de : in std_logic;
|
|
|
|
data_o : out std_logic_vector(9 downto 0)
|
|
|
|
);
|
|
|
|
end encoder;
|
|
|
|
|
|
|
|
architecture encoder of encoder is
|
|
|
|
signal n1d : unsigned(3 downto 0);
|
|
|
|
signal data_iq : std_logic_vector(7 downto 0);
|
|
|
|
signal decision1 : std_logic;
|
|
|
|
signal q_m : std_logic_vector(8 downto 0);
|
|
|
|
signal n0q_m : unsigned(3 downto 0); -- number of 1s and 0s for q_m
|
|
|
|
signal n1q_m : unsigned(3 downto 0); -- number of 1s and 0s for q_m
|
|
|
|
signal n1q_i : unsigned(3 downto 0); -- number of 1s and 0s for q_m
|
|
|
|
signal cnt : unsigned(4 downto 0); -- disparity counter, MSB is the sign bit
|
|
|
|
signal decision2 : std_logic;
|
|
|
|
signal decision3 : std_logic;
|
|
|
|
type usigned_t is array(natural range <>) of unsigned(3 downto 0);
|
|
|
|
signal data_iu : usigned_t(7 downto 0);
|
|
|
|
signal q_mu : usigned_t(8 downto 0);
|
|
|
|
|
|
|
|
signal de_q, de_reg : std_logic;
|
|
|
|
signal c0_q, c1_q : std_logic;
|
|
|
|
signal c0_reg, c1_reg : std_logic;
|
|
|
|
signal c1c0 : std_logic_vector(1 downto 0);
|
|
|
|
signal q_m_reg : std_logic_vector(8 downto 0);
|
|
|
|
signal data_oq : std_logic_vector(9 downto 0);
|
|
|
|
begin
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- Counting number of 1s and 0s for each incoming pixel
|
|
|
|
-- component. Pipe line the result.
|
|
|
|
-- Register Data Input so it matches the pipe lined adder
|
|
|
|
-- output
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
tounsigned0: for I in 0 to 7 generate
|
|
|
|
data_iu(I)(3 downto 1) <= "000";
|
|
|
|
data_iu(I)(0 downto 0) <= unsigned(data_i(I downto I));
|
|
|
|
end generate;
|
|
|
|
process (clk, rst_n)
|
|
|
|
begin
|
|
|
|
if rst_n = '0' then
|
|
|
|
n1d <= (others => '0');
|
|
|
|
data_iq <= (others => '0');
|
|
|
|
elsif rising_edge(clk) then
|
|
|
|
n1d <= data_iu(0) + data_iu(1) + data_iu(2) + data_iu(3)
|
|
|
|
+ data_iu(4) + data_iu(5) + data_iu(6) + data_iu(7);
|
|
|
|
data_iq <= data_i;
|
|
|
|
end if;
|
|
|
|
end process;
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- Stage 1: 8 bit -> 9 bit
|
|
|
|
-- Refer to DVI 1.0 Specification, page 29, Figure 3-5
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
decision1 <= '1' when n1d > x"4" or (n1d = x"4" and data_iq(0) = '0') else '0';
|
|
|
|
q_m(0) <= data_iq(0);
|
|
|
|
q_m(1) <= (q_m(0) xnor data_iq(1)) when decision1 = '1' else q_m(0) xor data_iq(1);
|
|
|
|
q_m(2) <= (q_m(1) xnor data_iq(2)) when decision1 = '1' else q_m(1) xor data_iq(2);
|
|
|
|
q_m(3) <= (q_m(2) xnor data_iq(3)) when decision1 = '1' else q_m(2) xor data_iq(3);
|
|
|
|
q_m(4) <= (q_m(3) xnor data_iq(4)) when decision1 = '1' else q_m(3) xor data_iq(4);
|
|
|
|
q_m(5) <= (q_m(4) xnor data_iq(5)) when decision1 = '1' else q_m(4) xor data_iq(5);
|
|
|
|
q_m(6) <= (q_m(5) xnor data_iq(6)) when decision1 = '1' else q_m(5) xor data_iq(6);
|
|
|
|
q_m(7) <= (q_m(6) xnor data_iq(7)) when decision1 = '1' else q_m(6) xor data_iq(7);
|
|
|
|
q_m(8) <= '0' when decision1 = '1' else '1';
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- Stage 2: 9 bit -> 10 bit
|
|
|
|
-- Refer to DVI 1.0 Specification, page 29, Figure 3-5
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
tounsigned1: for I in 0 to 8 generate
|
|
|
|
q_mu(I)(3 downto 1) <= "000";
|
|
|
|
q_mu(I)(0 downto 0) <= unsigned(q_m(I downto I));
|
|
|
|
end generate;
|
|
|
|
n1q_i <= q_mu(0) + q_mu(1) + q_mu(2) + q_mu(3) + q_mu(4) + q_mu(5) + q_mu(6) + q_mu(7);
|
|
|
|
process (clk, rst_n)
|
|
|
|
begin
|
|
|
|
if rst_n = '0' then
|
|
|
|
n1q_m <= (others => '0');
|
|
|
|
n0q_m <= (others => '0');
|
|
|
|
elsif rising_edge(clk) then
|
|
|
|
n1q_m <= n1q_i;
|
|
|
|
n0q_m <= x"8" - n1q_i;
|
|
|
|
end if;
|
|
|
|
end process;
|
|
|
|
|
|
|
|
decision2 <= '1' when cnt = "00000" or n1q_m = n0q_m else '0';
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
decision3 <= '1' when (cnt(4) = '0' and n1q_m > n0q_m) or (cnt(4) = '1' and n0q_m > n1q_m) else '0';
|
|
|
|
|
|
|
|
-- --------------------------
|
|
|
|
-- pipe line alignment
|
|
|
|
-- --------------------------
|
|
|
|
process (clk, rst_n)
|
|
|
|
begin
|
|
|
|
if rst_n = '0' then
|
|
|
|
de_q <= '0';
|
|
|
|
de_reg <= '0';
|
|
|
|
c0_q <= '0';
|
|
|
|
c0_reg <= '0';
|
|
|
|
c1_q <= '0';
|
|
|
|
c1_reg <= '0';
|
|
|
|
q_m_reg <= (others => '0');
|
|
|
|
elsif rising_edge(clk) then
|
|
|
|
de_q <= de;
|
|
|
|
de_reg <= de_q;
|
|
|
|
|
|
|
|
c0_q <= c0;
|
|
|
|
c0_reg <= c0_q;
|
|
|
|
c1_q <= c1;
|
|
|
|
c1_reg <= c1_q;
|
|
|
|
|
|
|
|
q_m_reg <= q_m;
|
|
|
|
end if;
|
|
|
|
end process;
|
|
|
|
|
|
|
|
-- --------------------------
|
|
|
|
-- 10-bit out
|
|
|
|
-- disparity counter
|
|
|
|
-- --------------------------
|
|
|
|
process (clk, rst_n)
|
|
|
|
begin
|
|
|
|
if rst_n = '0' then
|
|
|
|
data_oq <= (others => '0');
|
|
|
|
cnt <= (others => '0');
|
|
|
|
elsif rising_edge(clk) then
|
|
|
|
if de_reg = '1' then
|
|
|
|
if decision2 = '1' then
|
|
|
|
data_oq(9) <= not q_m_reg(8);
|
|
|
|
data_oq(8) <= q_m_reg(8);
|
|
|
|
if q_m_reg(8) = '1' then
|
|
|
|
data_oq(7 downto 0) <= q_m_reg(7 downto 0);
|
|
|
|
cnt <= cnt + n1q_m - n0q_m;
|
|
|
|
else
|
|
|
|
data_oq(7 downto 0) <= not q_m_reg(7 downto 0);
|
|
|
|
cnt <= cnt + n0q_m - n1q_m;
|
|
|
|
end if;
|
|
|
|
elsif decision3 = '1' then
|
|
|
|
data_oq(9) <= '1';
|
|
|
|
data_oq(8) <= q_m_reg(8);
|
|
|
|
data_oq(7 downto 0) <= not q_m_reg(7 downto 0);
|
|
|
|
cnt <= cnt + (q_m_reg(8) & '0') + (n0q_m - n1q_m);
|
|
|
|
else
|
|
|
|
data_oq(9) <= '0';
|
|
|
|
data_oq(8) <= q_m_reg(8);
|
|
|
|
data_oq(7 downto 0) <= q_m_reg(7 downto 0);
|
|
|
|
cnt <= cnt - (not q_m_reg(8) & '0') + (n1q_m - n0q_m);
|
|
|
|
end if;
|
|
|
|
else
|
|
|
|
case c1c0 is
|
|
|
|
when "00" => data_oq <= CTRLTOKEN0;
|
|
|
|
when "01" => data_oq <= CTRLTOKEN1;
|
|
|
|
when "10" => data_oq <= CTRLTOKEN2;
|
|
|
|
when others => data_oq <= CTRLTOKEN3;
|
|
|
|
end case;
|
|
|
|
cnt <= (others => '0');
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
end process;
|
|
|
|
c1c0 <= c1_reg & c0_reg;
|
|
|
|
|
|
|
|
data_o <= data_oq;
|
|
|
|
|
|
|
|
end encoder;
|