-- ----------------------------------------------------------------------------- -- Copyright (c) 2013 Benjamin Krill -- -- 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. -- ----------------------------------------------------------------------------- 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 convert_30to15_fifo is port ( rst : in std_logic; clk : in std_logic; clkx2 : in std_logic; data_i : in std_logic_vector(29 downto 0); -- input data for 2:1 serialisation data_o : out std_logic_vector(14 downto 0) -- 5-bit data out ); end convert_30to15_fifo; architecture convert_30to15_fifo of convert_30to15_fifo is signal wa : std_logic_vector( 3 downto 0); signal wa_q : std_logic_vector( 3 downto 0); signal ra : std_logic_vector( 3 downto 0); signal ra_q : std_logic_vector( 3 downto 0); signal data_int : std_logic_vector(29 downto 0); signal rstsync_q : std_logic; signal rstsync : std_logic; signal rstp : std_logic; signal sync : std_logic; signal syncn : std_logic; signal db : std_logic_vector(29 downto 0); signal mux : std_logic_vector(14 downto 0); constant ADDR0 : std_logic_vector( 3 downto 0) := "0000"; constant ADDR1 : std_logic_vector( 3 downto 0) := "0001"; constant ADDR2 : std_logic_vector( 3 downto 0) := "0010"; constant ADDR3 : std_logic_vector( 3 downto 0) := "0011"; constant ADDR4 : std_logic_vector( 3 downto 0) := "0100"; constant ADDR5 : std_logic_vector( 3 downto 0) := "0101"; constant ADDR6 : std_logic_vector( 3 downto 0) := "0110"; constant ADDR7 : std_logic_vector( 3 downto 0) := "0111"; constant ADDR8 : std_logic_vector( 3 downto 0) := "1000"; constant ADDR9 : std_logic_vector( 3 downto 0) := "1001"; constant ADDR10 : std_logic_vector( 3 downto 0) := "1010"; constant ADDR11 : std_logic_vector( 3 downto 0) := "1011"; constant ADDR12 : std_logic_vector( 3 downto 0) := "1100"; constant ADDR13 : std_logic_vector( 3 downto 0) := "1101"; constant ADDR14 : std_logic_vector( 3 downto 0) := "1110"; constant ADDR15 : std_logic_vector( 3 downto 0) := "1111"; begin -- -------------------------------------------------- -- Here we instantiate a 16x10 Dual Port RAM -- and fill first it with data aligned to -- clk domain -- -------------------------------------------------- fdc_wa0: FDC port map (C => clk, D => wa_q(0), CLR => rst, Q => wa(0)); fdc_wa1: FDC port map (C => clk, D => wa_q(1), CLR => rst, Q => wa(1)); fdc_wa2: FDC port map (C => clk, D => wa_q(2), CLR => rst, Q => wa(2)); fdc_wa3: FDC port map (C => clk, D => wa_q(3), CLR => rst, Q => wa(3)); process (wa) begin case wa is when ADDR0 => wa_q <= ADDR1; when ADDR1 => wa_q <= ADDR2; when ADDR2 => wa_q <= ADDR3; when ADDR3 => wa_q <= ADDR4; when ADDR4 => wa_q <= ADDR5; when ADDR5 => wa_q <= ADDR6; when ADDR6 => wa_q <= ADDR7; when ADDR7 => wa_q <= ADDR8; when ADDR8 => wa_q <= ADDR9; when ADDR9 => wa_q <= ADDR10; when ADDR10 => wa_q <= ADDR11; when ADDR11 => wa_q <= ADDR12; when ADDR12 => wa_q <= ADDR13; when ADDR13 => wa_q <= ADDR14; when ADDR14 => wa_q <= ADDR15; when others => wa_q <= ADDR0; end case; end process; fifo_u: entity work.DRAM16XN generic map (data_width => 30) port map ( DATA_IN => data_i, ADDRESS => wa, ADDRESS_DP => ra, WRITE_EN => '1', CLK => clk, O_DATA_OUT => open, O_DATA_OUT_DP => data_int ); -- -------------------------------------------------- -- Here starts clk2x domain for fifo read out -- FIFO read is set to be once every 2 cycles of clk2x in order -- to keep up pace with the fifo write speed -- Also FIFO read reset is delayed a bit in order to avoid -- underflow. -- -------------------------------------------------- fdc_ra0: FDRE port map (C => clkx2, D => ra_q(0), R => rstp, CE => sync, Q => ra(0)); fdc_ra1: FDRE port map (C => clkx2, D => ra_q(1), R => rstp, CE => sync, Q => ra(1)); fdc_ra2: FDRE port map (C => clkx2, D => ra_q(2), R => rstp, CE => sync, Q => ra(2)); fdc_ra3: FDRE port map (C => clkx2, D => ra_q(3), R => rstp, CE => sync, Q => ra(3)); process (ra) begin case ra is when ADDR0 => ra_q <= ADDR1; when ADDR1 => ra_q <= ADDR2; when ADDR2 => ra_q <= ADDR3; when ADDR3 => ra_q <= ADDR4; when ADDR4 => ra_q <= ADDR5; when ADDR5 => ra_q <= ADDR6; when ADDR6 => ra_q <= ADDR7; when ADDR7 => ra_q <= ADDR8; when ADDR8 => ra_q <= ADDR9; when ADDR9 => ra_q <= ADDR10; when ADDR10 => ra_q <= ADDR11; when ADDR11 => ra_q <= ADDR12; when ADDR12 => ra_q <= ADDR13; when ADDR13 => ra_q <= ADDR14; when ADDR14 => ra_q <= ADDR15; when others => ra_q <= ADDR0; end case; end process; fdp_rst: FDP port map (C => clkx2, D => rst, PRE => rst, Q => rstsync); fd_rstsync: FD port map (C => clkx2, D => rstsync, Q => rstsync_q); fd_rstp: FD port map (C => clkx2, D => rstsync_q, Q => rstp); sync_gen: FDR port map (Q => sync, C => clkx2, R => rstp, D => syncn); syncn <= not sync; fd_db: for I in 0 to 29 generate fd_db_I: FDE port map (C => clkx2, D => data_int(I), CE => sync, Q => db(I)); end generate; mux <= db(14 downto 0) when sync = '0' else db(29 downto 15); fd_out: for I in 0 to 14 generate fd_outI: FD port map (C => clkx2, D => mux(I), Q => data_o(I)); end generate; end convert_30to15_fifo;