165 lines
6.4 KiB
VHDL
165 lines
6.4 KiB
VHDL
-- -----------------------------------------------------------------------------
|
|
-- Copyright (c) 2013 Benjamin Krill <benjamin@krll.de>
|
|
--
|
|
-- 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;
|