library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.VITAL_Timing.all;
use IEEE.VITAL_Primitives.all;

package dffeas_pack is

-- default generic values
    CONSTANT DefWireDelay        : VitalDelayType01      := (0 ns, 0 ns);
    CONSTANT DefPropDelay01      : VitalDelayType01      := (0 ns, 0 ns);
    CONSTANT DefPropDelay01Z     : VitalDelayType01Z     := (OTHERS => 0 ns);
    CONSTANT DefSetupHoldCnst    : TIME := 0 ns;
    CONSTANT DefPulseWdthCnst    : TIME := 0 ns;
    CONSTANT DefGlitchMode       : VitalGlitchKindType   := VitalTransport;
    CONSTANT DefGlitchMsgOn      : BOOLEAN       := FALSE;
    CONSTANT DefGlitchXOn        : BOOLEAN       := FALSE;
    CONSTANT DefMsgOnChecks      : BOOLEAN       := TRUE;
    CONSTANT DefXOnChecks        : BOOLEAN       := TRUE;

end dffeas_pack;

library ieee;
use ieee.std_logic_1164.all;
use IEEE.VITAL_Timing.all;
use work.dffeas_pack.all;

library altera;
use altera.all;

entity smack_shadow_circuit is
    generic(
        power_up : string := "DONT_CARE";
        is_wysiwyg : string := "false";
        x_on_violation : string := "on";
        lpm_type : string := "DFFEAS";
        tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        tsetup_asdata_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        tsetup_sclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        tsetup_sload_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        thold_asdata_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        thold_sclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        thold_sload_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst;
        tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01;
        tpd_clrn_q_negedge : VitalDelayType01 := DefPropDelay01;
        tpd_prn_q_negedge : VitalDelayType01 := DefPropDelay01;
        tpd_aload_q_posedge : VitalDelayType01 := DefPropDelay01;
        tpd_asdata_q: VitalDelayType01 := DefPropDelay01;
        tipd_clk : VitalDelayType01 := DefPropDelay01;
        tipd_d : VitalDelayType01 := DefPropDelay01;
        tipd_asdata : VitalDelayType01 := DefPropDelay01;
        tipd_sclr : VitalDelayType01 := DefPropDelay01; 
        tipd_sload : VitalDelayType01 := DefPropDelay01;
        tipd_clrn : VitalDelayType01 := DefPropDelay01; 
        tipd_prn : VitalDelayType01 := DefPropDelay01; 
        tipd_aload : VitalDelayType01 := DefPropDelay01; 
        tipd_ena : VitalDelayType01 := DefPropDelay01; 
        TimingChecksOn: Boolean := True;
        MsgOn: Boolean := DefGlitchMsgOn;
        XOn: Boolean := DefGlitchXOn;
        MsgOnChecks: Boolean := DefMsgOnChecks;
        XOnChecks: Boolean := DefXOnChecks;
        InstancePath: STRING := "*"      
    );
    port(
		d: in std_logic := '0';
        ena: in std_logic := '1';
        clrn: in std_logic := '1';
        aload: in std_logic := '0';
        asdata: in std_logic := '1';
        sclr: in std_logic := '0';
        sload: in std_logic := '0';
        q: in std_logic;
        smack_sclk: in std_logic;
        smack_en: in std_logic;
        smack_scanin: in std_logic;
        smack_scanout: out std_logic
    );
end entity smack_shadow_circuit;

architecture rtl of smack_shadow_circuit is

    component dffeas
        generic(
            power_up : string;
            is_wysiwyg : string;
            dont_touch : string;
            x_on_violation : string;
            lpm_type : string;
            tsetup_d_clk_noedge_posedge : VitalDelayType;
            tsetup_asdata_clk_noedge_posedge : VitalDelayType;
            tsetup_sclr_clk_noedge_posedge : VitalDelayType;
            tsetup_sload_clk_noedge_posedge : VitalDelayType;
            tsetup_ena_clk_noedge_posedge : VitalDelayType;
            thold_d_clk_noedge_posedge : VitalDelayType;
            thold_asdata_clk_noedge_posedge : VitalDelayType;
            thold_sclr_clk_noedge_posedge : VitalDelayType;
            thold_sload_clk_noedge_posedge : VitalDelayType;
            thold_ena_clk_noedge_posedge : VitalDelayType;
            tpd_clk_q_posedge : VitalDelayType01;
            tpd_clrn_q_negedge : VitalDelayType01;
            tpd_prn_q_negedge : VitalDelayType01;
            tpd_aload_q_posedge : VitalDelayType01;
            tpd_asdata_q: VitalDelayType01;
            tipd_clk : VitalDelayType01;
            tipd_d : VitalDelayType01;
            tipd_asdata : VitalDelayType01;
            tipd_sclr : VitalDelayType01; 
            tipd_sload : VitalDelayType01;
            tipd_clrn : VitalDelayType01; 
            tipd_prn : VitalDelayType01; 
            tipd_aload : VitalDelayType01; 
            tipd_ena : VitalDelayType01; 
            TimingChecksOn: Boolean;
            MsgOn: Boolean;
            XOn: Boolean;
            MsgOnChecks: Boolean;
            XOnChecks: Boolean;
            InstancePath: STRING        
        );
        port(
            d         : in std_logic;
            clk       : in std_logic;
            ena       : in std_logic;
            clrn      : in std_logic;
            aload     : in std_logic;
            asdata    : in std_logic;
            sclr      : in std_logic;
            sload     : in std_logic;
            q         : out std_logic
            );
    end component dffeas;

    signal sflop_q: std_logic;
    signal scanout_buff: std_logic;

begin

    smack_flop: dffeas
    generic map(
        power_up => power_up,
        is_wysiwyg => is_wysiwyg,
        dont_touch => "true",
        x_on_violation => x_on_violation,
        lpm_type => lpm_type,
        tsetup_d_clk_noedge_posedge => tsetup_d_clk_noedge_posedge,
        tsetup_asdata_clk_noedge_posedge => tsetup_asdata_clk_noedge_posedge,
        tsetup_sclr_clk_noedge_posedge => tsetup_sclr_clk_noedge_posedge,
        tsetup_sload_clk_noedge_posedge => tsetup_sload_clk_noedge_posedge,
        tsetup_ena_clk_noedge_posedge => tsetup_ena_clk_noedge_posedge,
        thold_d_clk_noedge_posedge => thold_d_clk_noedge_posedge,
        thold_asdata_clk_noedge_posedge => thold_asdata_clk_noedge_posedge,
        thold_sclr_clk_noedge_posedge => thold_sclr_clk_noedge_posedge,
        thold_sload_clk_noedge_posedge => thold_sload_clk_noedge_posedge,
        thold_ena_clk_noedge_posedge => thold_ena_clk_noedge_posedge,
        tpd_clk_q_posedge => tpd_clk_q_posedge,
        tpd_clrn_q_negedge => tpd_clrn_q_negedge,
        tpd_prn_q_negedge => tpd_prn_q_negedge,
        tpd_aload_q_posedge => tpd_aload_q_posedge,
        tpd_asdata_q => tpd_asdata_q,
        tipd_clk => tipd_clk,
        tipd_d => tipd_d,
        tipd_asdata => tipd_asdata,
        tipd_sclr => tipd_sclr,
        tipd_sload => tipd_sload,
        tipd_clrn => tipd_clrn,
        tipd_prn => tipd_prn,
        tipd_aload => tipd_aload,
        tipd_ena => tipd_ena,
        TimingChecksOn => TimingChecksOn,
        MsgOn => MsgOn,
        XOn => XOn,
        MsgOnChecks => MsgOnChecks,
        XOnChecks => XOnChecks,
        InstancePath => InstancePath
    )
    port map(
        d       => d,
        clk     => smack_sclk,
        ena     => ena,
        clrn    => clrn,
        aload   => aload,
        asdata  => asdata,
        sclr    => sclr,
        sload   => sload,
        q       => sflop_q
    );

    smack_scanout <= scanout_buff; 

    smack_seq_proc: process
    begin
        wait until smack_sclk'event and smack_sclk = '1';
        if smack_en = '0' then
            scanout_buff <= smack_scanin;
        else
            scanout_buff <= scanout_buff or (q xor sflop_q);
        end if;
    end process smack_seq_proc;

end architecture rtl;
