--******************************************************************************
--* @short      Double Data Rate Output Block
--*
--*             receives two muons and puts them out at 80 MHz one after each other
--*             the first muon is put out at the riging edge, the second one at
--*             the falling edge (as inverted GTLp signals)
--******************************************************************************
--* @author  SAKULIN Hannes  <hsakulin@dsy-srv3.cern.ch>
--* @date    $Date: 2006/05/29 10:30:22 $
--* @version $Revision: 1.5 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_std.all;
use WORK.GMTTypes.all;
-- pragma translate_off
library UNISIM;
use UNISIM.VCOMPONENTS.all;
--pragma translate_on

entity SFDDROutput is
  port (iMuon1 : in  TGMTMu;
        iMuon2 : in  TGMTMu;
        oMuon  : out TGMTMu_flat;

        -- Clock and control
        clk   : in std_logic);
end;


architecture behavioral of SFDDROutput is
  attribute syn_useioff               : boolean;
  attribute syn_useioff of behavioral : architecture is true;

  signal sMuon1_reg      : TGMTMu;
  signal sMuon1_reg_flat : TGMTMu_flat;
  signal sMuon2_flat     : TGMTMu_flat;
  signal nclk            : std_logic;

  signal my_ce, my_rst, my_set : std_logic;

  component FDDRRSE
-- synthesis translate_off
    generic (INIT :     bit := '1' );
-- synthesis translate_on
    port (Q       : out std_ulogic;
          C0      : in  std_ulogic;
          C1      : in  std_ulogic;
          CE      : in  std_ulogic;
          D0      : in  std_ulogic;
          D1      : in  std_ulogic;
          R       : in  std_ulogic;
          S       : in  std_ulogic);
  end component;

begin  -- architecture behavioral

  -- register muon 1
  -- in order to meet timing constraints (sorting logic needs 22ns)
  reg_1 : process (clk) is
  begin
    if clk'event and clk = '1' then
      sMuon1_reg <= iMuon1;
    end if;
  end process reg_1;

  sMuon1_reg_flat     <= not GMTMu_to_flat(sMuon1_reg);  --send inverted GTLp signals
  sMuon2_flat <= not GMTMu_to_flat(iMuon2);

  nclk <= not clk;

  my_ce <= '1';
  my_rst <= '0';
  my_set <= '0';

  -- instantiate dual data rate FF for each bit
  gen_ddr_ffs: for i in sMuon2_flat'range generate
  begin  -- generate i
    U0 : FDDRRSE
      port map (
        Q  => oMuon(i),
        D0 => sMuon1_reg_flat(i),
        D1 => sMuon2_flat(i),
        C0 => nclk,  -- exchanged clock edges to correctly receive muons in FDL
        C1 => clk,
        CE => my_ce,
        R  => my_rst,
        S  => my_set
        );
  end generate gen_ddr_ffs;

end architecture behavioral;