------------------------------------------------------------------------------ -- File name : am29lv642d.vhd ------------------------------------------------------------------------------- -- Copyright (C) 2004 Free Model Foundry; http://www.FreeModelFoundry.com -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License version 2 as -- published by the Free Software Foundation. -- -- MODIFICATION HISTORY : -- -- version: | author: | mod date: | changes made: -- V1.0 M.Stojsavljevic 04 Aug 31 Initial ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: FLASH -- Technology: Flash Memory -- Part: am29lv642d -- -- Description: 128 Megabit (8 M x 16-Bit) MCP Flash Memory -- (Two am29lv640d Flash devices) -- ------------------------------------------------------------------------------- -- Known Bugs: -- ------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.VITAL_timing.ALL; USE IEEE.VITAL_primitives.ALL; USE STD.textio.ALL; LIBRARY FMF; USE FMF.gen_utils.all; USE FMF.conversions.all; ------------------------------------------------------------------------------- -- ENTITY DECLARATION FOR am29lv642d TOP MODULE ------------------------------------------------------------------------------- ENTITY am29lv642d IS GENERIC ( -- tipd delays: interconnect path delays tipd_A0 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A1 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A2 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A3 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A4 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A5 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A6 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A7 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A8 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A9 : VitalDelayType01 := VitalZeroDelay01; --address tipd_A10 : VitalDelayType01 := VitalZeroDelay01; --lines tipd_A11 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A12 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A13 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A14 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A15 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A16 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A17 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A18 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A19 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A20 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A21 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; -- data tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; -- lines tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; tipd_CENegf1 : VitalDelayType01 := VitalZeroDelay01; tipd_CENegf2 : VitalDelayType01 := VitalZeroDelay01; tipd_LBNeg : VitalDelayType01 := VitalZeroDelay01; tipd_UBNeg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; tipd_ACC : VitalDelayType01 := VitalZeroDelay01; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- memory file to be loaded mem_file_name : STRING := "none"; prot_file_name : STRING := "none"; secsi_file_name : STRING := "none"; UserPreload : BOOLEAN := TRUE; LongTimming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( A21 : IN std_ulogic := 'U'; -- A20 : IN std_ulogic := 'U'; -- A19 : IN std_ulogic := 'U'; -- A18 : IN std_ulogic := 'U'; -- A17 : IN std_ulogic := 'U'; -- A16 : IN std_ulogic := 'U'; -- A15 : IN std_ulogic := 'U'; -- A14 : IN std_ulogic := 'U'; -- A13 : IN std_ulogic := 'U'; --address A12 : IN std_ulogic := 'U'; --lines A11 : IN std_ulogic := 'U'; -- A10 : IN std_ulogic := 'U'; -- A9 : IN std_ulogic := 'U'; -- A8 : IN std_ulogic := 'U'; -- A7 : IN std_ulogic := 'U'; -- A6 : IN std_ulogic := 'U'; -- A5 : IN std_ulogic := 'U'; -- A4 : IN std_ulogic := 'U'; -- A3 : IN std_ulogic := 'U'; -- A2 : IN std_ulogic := 'U'; -- A1 : IN std_ulogic := 'U'; -- A0 : IN std_ulogic := 'U'; -- DQ15 : INOUT std_logic := 'U'; -- DQ14 : INOUT std_logic := 'U'; -- DQ13 : INOUT std_logic := 'U'; -- DQ12 : INOUT std_logic := 'U'; -- DQ11 : INOUT std_logic := 'U'; -- DQ10 : INOUT std_logic := 'U'; -- DQ9 : INOUT std_logic := 'U'; -- data DQ8 : INOUT std_logic := 'U'; -- lines DQ7 : INOUT std_logic := 'U'; -- DQ6 : INOUT std_logic := 'U'; -- DQ5 : INOUT std_logic := 'U'; -- DQ4 : INOUT std_logic := 'U'; -- DQ3 : INOUT std_logic := 'U'; -- DQ2 : INOUT std_logic := 'U'; -- DQ1 : INOUT std_logic := 'U'; -- DQ0 : INOUT std_logic := 'U'; -- CENegf1 : IN std_ulogic := 'U'; CENegf2 : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; ACC : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of am29lv642d : ENTITY IS TRUE; END am29lv642d; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.VITAL_timing.ALL; USE IEEE.VITAL_primitives.ALL; USE STD.textio.ALL; LIBRARY FMF; USE FMF.gen_utils.all; USE FMF.conversions.all; ------------------------------------------------------------------------------- -- ENTITY DECLARATION FOR am29lv640d ------------------------------------------------------------------------------- ENTITY am29lv640d IS GENERIC ( -- tipd delays: interconnect path delays tipd_A0 : VitalDelayType01 := VitalZeroDelay01; tipd_A1 : VitalDelayType01 := VitalZeroDelay01; tipd_A2 : VitalDelayType01 := VitalZeroDelay01; tipd_A3 : VitalDelayType01 := VitalZeroDelay01; tipd_A4 : VitalDelayType01 := VitalZeroDelay01; tipd_A5 : VitalDelayType01 := VitalZeroDelay01; tipd_A6 : VitalDelayType01 := VitalZeroDelay01; tipd_A7 : VitalDelayType01 := VitalZeroDelay01; tipd_A8 : VitalDelayType01 := VitalZeroDelay01; tipd_A9 : VitalDelayType01 := VitalZeroDelay01; tipd_A10 : VitalDelayType01 := VitalZeroDelay01; tipd_A11 : VitalDelayType01 := VitalZeroDelay01; tipd_A12 : VitalDelayType01 := VitalZeroDelay01; tipd_A13 : VitalDelayType01 := VitalZeroDelay01; tipd_A14 : VitalDelayType01 := VitalZeroDelay01; tipd_A15 : VitalDelayType01 := VitalZeroDelay01; tipd_A16 : VitalDelayType01 := VitalZeroDelay01; tipd_A17 : VitalDelayType01 := VitalZeroDelay01; tipd_A18 : VitalDelayType01 := VitalZeroDelay01; tipd_A19 : VitalDelayType01 := VitalZeroDelay01; tipd_A20 : VitalDelayType01 := VitalZeroDelay01; tipd_A21 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; tipd_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_ACC : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays tpd_A0_DQ0 : VitalDelayType01 := UnitDelay01; tpd_CENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; tpd_OENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; tpd_WENeg_RY : VitalDelayType01Z := UnitDelay01Z; tsetup_A0_WENeg : VitalDelayType := UnitDelay; tsetup_A0_OENeg : VitalDelayType := UnitDelay; tsetup_DQ0_WENeg : VitalDelayType := UnitDelay; tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; tsetup_OENeg_WENeg : VitalDelayType := UnitDelay; thold_A0_WENeg : VitalDelayType := UnitDelay; thold_A0_OENeg : VitalDelayType := UnitDelay; thold_DQ0_WENeg : VitalDelayType := UnitDelay; thold_OENeg_WENeg : VitalDelayType := UnitDelay; thold_WENeg_OENeg : VitalDelayType := UnitDelay; thold_CENeg_WENeg : VitalDelayType := UnitDelay; thold_WENeg_CENeg : VitalDelayType := UnitDelay; thold_CENeg_RESETNeg : VitalDelayType := UnitDelay; tpw_RESETNeg_negedge : VitalDelayType := UnitDelay; -- tRP tpw_WENeg_negedge : VitalDelayType := UnitDelay; -- tWP tpw_WENeg_posedge : VitalDelayType := UnitDelay; -- tWPH tpw_CENeg_negedge : VitalDelayType := UnitDelay; -- tCP tpw_CENeg_posedge : VitalDelayType := UnitDelay; -- tCPH tpw_OENeg_posedge : VitalDelayType := UnitDelay; -- tOEPH tpw_A0_negedge : VitalDelayType := UnitDelay; -- -- tdevice values: values for internal delays tdevice_POW : VitalDelayType := 11 us; --Sector Erase Operation tWHWH2 tdevice_SEO : VitalDelayType := 1600 ms; --erase suspend timeout - only max time specified tdevice_ESTART_T1 : VitalDelayType := 20 us; --sector erase command sequence timeout tdevice_CTMOUT : VitalDelayType := 50 us; --device ready after Hardware reset(during embeded algorithm) tdevice_READY : VitalDelayType := 20 us; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- memory file to be loaded mem_file_name : STRING := "none"; prot_file_name : STRING := "none"; secsi_file_name : STRING := "none"; UserPreload : BOOLEAN := TRUE; LongTimming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( A0 : IN std_ulogic := 'U'; A1 : IN std_ulogic := 'U'; A2 : IN std_ulogic := 'U'; A3 : IN std_ulogic := 'U'; A4 : IN std_ulogic := 'U'; A5 : IN std_ulogic := 'U'; A6 : IN std_ulogic := 'U'; A7 : IN std_ulogic := 'U'; A8 : IN std_ulogic := 'U'; A9 : IN std_ulogic := 'U'; A10 : IN std_ulogic := 'U'; A11 : IN std_ulogic := 'U'; A12 : IN std_ulogic := 'U'; A13 : IN std_ulogic := 'U'; A14 : IN std_ulogic := 'U'; A15 : IN std_ulogic := 'U'; A16 : IN std_ulogic := 'U'; A17 : IN std_ulogic := 'U'; A18 : IN std_ulogic := 'U'; A19 : IN std_ulogic := 'U'; A20 : IN std_ulogic := 'U'; A21 : IN std_ulogic := 'U'; DQ15 : INOUT std_ulogic := 'U'; DQ14 : INOUT std_ulogic := 'U'; DQ13 : INOUT std_ulogic := 'U'; DQ12 : INOUT std_ulogic := 'U'; DQ11 : INOUT std_ulogic := 'U'; DQ10 : INOUT std_ulogic := 'U'; DQ9 : INOUT std_ulogic := 'U'; DQ8 : INOUT std_ulogic := 'U'; DQ7 : INOUT std_ulogic := 'U'; DQ6 : INOUT std_ulogic := 'U'; DQ5 : INOUT std_ulogic := 'U'; DQ4 : INOUT std_ulogic := 'U'; DQ3 : INOUT std_ulogic := 'U'; DQ2 : INOUT std_ulogic := 'U'; DQ1 : INOUT std_ulogic := 'U'; DQ0 : INOUT std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; ACC : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of am29lv640d : ENTITY IS TRUE; END am29lv640d; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of am29lv640d IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "am29lv640d"; CONSTANT MaxData : NATURAL := 16#FFFF#; CONSTANT MemSize : NATURAL := 16#3FFFFF#; CONSTANT SecSize : NATURAL := 16#7FFF#; CONSTANT SecSiSize : NATURAL := 16#7F#; CONSTANT SecNum : NATURAL := 128; CONSTANT HiAddrBit : NATURAL := 21; CONSTANT LowSecAddrBit : NATURAL := 15; -- interconnect path delay signals SIGNAL A0_ipd : std_ulogic := 'U'; SIGNAL A1_ipd : std_ulogic := 'U'; SIGNAL A2_ipd : std_ulogic := 'U'; SIGNAL A3_ipd : std_ulogic := 'U'; SIGNAL A4_ipd : std_ulogic := 'U'; SIGNAL A5_ipd : std_ulogic := 'U'; SIGNAL A6_ipd : std_ulogic := 'U'; SIGNAL A7_ipd : std_ulogic := 'U'; SIGNAL A8_ipd : std_ulogic := 'U'; SIGNAL A9_ipd : std_ulogic := 'U'; SIGNAL A10_ipd : std_ulogic := 'U'; SIGNAL A11_ipd : std_ulogic := 'U'; SIGNAL A12_ipd : std_ulogic := 'U'; SIGNAL A13_ipd : std_ulogic := 'U'; SIGNAL A14_ipd : std_ulogic := 'U'; SIGNAL A15_ipd : std_ulogic := 'U'; SIGNAL A16_ipd : std_ulogic := 'U'; SIGNAL A17_ipd : std_ulogic := 'U'; SIGNAL A18_ipd : std_ulogic := 'U'; SIGNAL A19_ipd : std_ulogic := 'U'; SIGNAL A20_ipd : std_ulogic := 'U'; SIGNAL A21_ipd : std_ulogic := 'U'; SIGNAL DQ15_ipd : std_ulogic := 'U'; SIGNAL DQ14_ipd : std_ulogic := 'U'; SIGNAL DQ13_ipd : std_ulogic := 'U'; SIGNAL DQ12_ipd : std_ulogic := 'U'; SIGNAL DQ11_ipd : std_ulogic := 'U'; SIGNAL DQ10_ipd : std_ulogic := 'U'; SIGNAL DQ9_ipd : std_ulogic := 'U'; SIGNAL DQ8_ipd : std_ulogic := 'U'; SIGNAL DQ7_ipd : std_ulogic := 'U'; SIGNAL DQ6_ipd : std_ulogic := 'U'; SIGNAL DQ5_ipd : std_ulogic := 'U'; SIGNAL DQ4_ipd : std_ulogic := 'U'; SIGNAL DQ3_ipd : std_ulogic := 'U'; SIGNAL DQ2_ipd : std_ulogic := 'U'; SIGNAL DQ1_ipd : std_ulogic := 'U'; SIGNAL DQ0_ipd : std_ulogic := 'U'; SIGNAL CENeg_ipd : std_ulogic := 'U'; SIGNAL OENeg_ipd : std_ulogic := 'U'; SIGNAL WENeg_ipd : std_ulogic := 'U'; SIGNAL RESETNeg_ipd : std_ulogic := 'U'; SIGNAL ACC_ipd : std_ulogic := 'U'; --- internal delays SIGNAL POW_out : std_ulogic := '0'; SIGNAL POU_out : std_ulogic := '0'; SIGNAL SEO_out : std_ulogic := '0'; SIGNAL POW_in : std_ulogic := '0'; SIGNAL POU_in : std_ulogic := '0'; SIGNAL SEO_in : std_ulogic := '0'; SIGNAL ESTART_T1_out : std_ulogic := '0'; --Erase Start TimeOut SIGNAL ESTART_T1_in : std_ulogic := '0'; SIGNAL CTMOUT_out : std_ulogic := '0'; -- start erease timeout SIGNAL CTMOUT_in : std_ulogic := '0'; SIGNAL READY_in : std_ulogic := '0'; SIGNAL READY_out : std_ulogic := '0'; -- Device ready after reset BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays POW :VitalBuf(POW_out, POW_in, (tdevice_POW ,UnitDelay)); SEO :VitalBuf(SEO_out, SEO_in, (tdevice_SEO ,UnitDelay)); CTMOUT :VitalBuf(CTMOUT_out, CTMOUT_in, (tdevice_CTMOUT ,UnitDelay)); READY :VitalBuf(READY_out, READY_in, (tdevice_READY ,UnitDelay)); ESTART_T1 :VitalBuf(ESTART_T1_out, ESTART_T1_in, (tdevice_ESTART_T1,UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_0 : VitalWireDelay (A21_ipd, A21, tipd_A21); w_1 : VitalWireDelay (A20_ipd, A20, tipd_A20); w_2 : VitalWireDelay (A19_ipd, A19, tipd_A19); w_3 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_4 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_5 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_6 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_7 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_8 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_9 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_10 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_11 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_12 : VitalWireDelay (A9_ipd, A9, tipd_A9); w_13 : VitalWireDelay (A8_ipd, A8, tipd_A8); w_14 : VitalWireDelay (A7_ipd, A7, tipd_A7); w_15 : VitalWireDelay (A6_ipd, A6, tipd_A6); w_16 : VitalWireDelay (A5_ipd, A5, tipd_A5); w_17 : VitalWireDelay (A4_ipd, A4, tipd_A4); w_18 : VitalWireDelay (A3_ipd, A3, tipd_A3); w_19 : VitalWireDelay (A2_ipd, A2, tipd_A2); w_20 : VitalWireDelay (A1_ipd, A1, tipd_A1); w_21 : VitalWireDelay (A0_ipd, A0, tipd_A0); w_22 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_23 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_24 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_25 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_26 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_27 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_28 : VitalWireDelay (DQ9_ipd, DQ9, tipd_DQ9); w_29 : VitalWireDelay (DQ8_ipd, DQ8, tipd_DQ8); w_30 : VitalWireDelay (DQ7_ipd, DQ7, tipd_DQ7); w_31 : VitalWireDelay (DQ6_ipd, DQ6, tipd_DQ6); w_32 : VitalWireDelay (DQ5_ipd, DQ5, tipd_DQ5); w_33 : VitalWireDelay (DQ4_ipd, DQ4, tipd_DQ4); w_34 : VitalWireDelay (DQ3_ipd, DQ3, tipd_DQ3); w_35 : VitalWireDelay (DQ2_ipd, DQ2, tipd_DQ2); w_36 : VitalWireDelay (DQ1_ipd, DQ1, tipd_DQ1); w_37 : VitalWireDelay (DQ0_ipd, DQ0, tipd_DQ0); w_38 : VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg); w_39 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_40 : VitalWireDelay (RESETNeg_ipd, RESETNeg, tipd_RESETNeg); w_41 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); END BLOCK; --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK PORT ( A : IN std_logic_vector(HiAddrBit DOWNTO 0) := (OTHERS => 'U'); DIn : IN std_logic_vector(15 DOWNTO 0) := (OTHERS => 'U'); DOut : OUT std_logic_vector(15 DOWNTO 0) := (OTHERS => 'Z'); CENeg : IN std_ulogic := 'U'; ACC : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U' ); PORT MAP ( A(21) => A21_ipd, A(20) => A20_ipd, A(19) => A19_ipd, A(18) => A18_ipd, A(17) => A17_ipd, A(16) => A16_ipd, A(15) => A15_ipd, A(14) => A14_ipd, A(13) => A13_ipd, A(12) => A12_ipd, A(11) => A11_ipd, A(10) => A10_ipd, A(9) => A9_ipd, A(8) => A8_ipd, A(7) => A7_ipd, A(6) => A6_ipd, A(5) => A5_ipd, A(4) => A4_ipd, A(3) => A3_ipd, A(2) => A2_ipd, A(1) => A1_ipd, A(0) => A0_ipd, DIn(15) => DQ15_ipd, DIn(14) => DQ14_ipd, DIn(13) => DQ13_ipd, DIn(12) => DQ12_ipd, DIn(11) => DQ11_ipd, DIn(10) => DQ10_ipd, DIn(9) => DQ9_ipd, DIn(8) => DQ8_ipd, DIn(7) => DQ7_ipd, DIn(6) => DQ6_ipd, DIn(5) => DQ5_ipd, DIn(4) => DQ4_ipd, DIn(3) => DQ3_ipd, DIn(2) => DQ2_ipd, DIn(1) => DQ1_ipd, DIn(0) => DQ0_ipd, DOut(15) => DQ15, DOut(14) => DQ14, DOut(13) => DQ13, DOut(12) => DQ12, DOut(11) => DQ11, DOut(10) => DQ10, DOut(9) => DQ9, DOut(8) => DQ8, DOut(7) => DQ7, DOut(6) => DQ6, DOut(5) => DQ5, DOut(4) => DQ4, DOut(3) => DQ3, DOut(2) => DQ2, DOut(1) => DQ1, DOut(0) => DQ0, CENeg => CENeg_ipd, ACC => ACC_ipd, OENeg => OENeg_ipd, WENeg => WENeg_ipd, RESETNeg => RESETNeg_ipd, RY => RY ); -- State Machine : State_Type TYPE state_type IS ( RESET, Z001, -- unlock cycle 1 PREL_SETBWB, -- unlock cycle 2 PREL_ULBYPASS, -- unlock bypass UNLOCK_RESET, -- unlock reset state CFI, -- CFI MOD OTP, -- SECSI OTP_Z001, -- unlock 1 secsi OTP_PREL, -- unlock 2 secsi OTP_A0SEEN, -- secsi program preeliminary OTP_EXIT, -- secsi exit OTP_FP1, -- unlock read factory protect OTP_FP2, -- read factory protect AS, -- autoselect AS_CFI, -- CFI from autoselect A0SEEN, -- program preeliminary C8, -- erase preeliminary C8_Z001, -- erase unlock bypass1 C8_PREL, -- erase unlock bypass2 ERS, -- erase SERS, -- sector erase timeout ESPS, -- erase suspend timeout SERS_EXEC, -- sector erase ESP, -- erase suspend ESP_AS, -- erase suspend autoselect ESP_Z001, -- erase unlock 1 ESP_SETBWB, -- erase unlock 2 ESP_CFI, -- ersae CFI MOD ESP_AS_CFI, -- esp. cfi form autosel. ESP_A0SEEN, -- erase programing ESP_ULBYPASS, -- esp Unlock Bypass ESP_ULBYPASS_RESET, -- esp Unlock Bypass Reset PGMS ); TYPE SecType IS ARRAY (0 TO SecSize) OF INTEGER RANGE -1 TO MaxData; TYPE MemArray IS ARRAY (0 TO SecNum-1) OF SecType; TYPE SecSiType IS ARRAY ( 0 TO SecSiSize) OF INTEGER RANGE -1 TO MaxData; -- states SIGNAL current_state : state_type; SIGNAL next_state : state_type; -- powerup SIGNAL PoweredUp : std_logic := '0'; --zero delay signals SIGNAL DOut_zd : std_logic_vector(15 DOWNTO 0) := (OTHERS =>'Z'); SIGNAL RY_zd : std_logic := 'Z'; SIGNAL DOut_pass : std_logic_vector(15 DOWNTO 0) := (OTHERS =>'Z'); --FSM control signals SIGNAL ULBYPASS : std_logic := '0'; SIGNAL SERS_ACT : std_logic := '0'; --Erase Active SIGNAL ESP_ACT : std_logic := '0'; --Erase Suspend Active SIGNAL PGMS_ACT : std_logic := '0'; --Program Active SIGNAL PDONE : std_logic := '1'; --Prog. Done SIGNAL PSTART : std_logic := '0'; --Start Programming --Program location is in protected sector SIGNAL PERR : std_logic := '0'; SIGNAL EDONE : std_logic := '1'; --Ers. Done SIGNAL ESTART : std_logic := '0'; --Start Erase SIGNAL ESUSP : std_logic := '0'; --Suspend Erase SIGNAL ESTART_SUSP : std_logic := '0'; --Start and suspend Erase SIGNAL ERES : std_logic := '0'; --Resume Erase --All sectors selected for erasure are protected SIGNAL EERR : std_logic := '0'; --Sectors selected for erasure SIGNAL ERS_QUEUE : std_logic_vector(SecNum-1 DOWNTO 0) := (OTHERS => '0'); --Command Register SIGNAL write : std_logic := '0'; SIGNAL read : std_logic := '0'; --Address within sector SHARED VARIABLE Address : NATURAL RANGE 0 TO SecSize := 0; SHARED VARIABLE SA : NATURAL RANGE 0 TO SecNum := 0; SHARED VARIABLE Addr : NATURAL RANGE 0 TO 16#7FF# := 0; SIGNAL AddressLatch : std_logic_vector(HiAddrBit DOWNTO 0); SIGNAL AddressLatch_flag : BOOLEAN := FALSE; SIGNAL D_tmp : NATURAL RANGE 0 TO MaxData; SIGNAL D_tmp0 : NATURAL RANGE 0 TO MaxData; --glitch protection SIGNAL gWE_n : std_logic := '1'; SIGNAL gCE_n : std_logic := '1'; SIGNAL gOE_n : std_logic := '1'; SIGNAL RST : std_logic := '1'; SIGNAL reseted : std_logic := '0'; -- Mem(SecAddr)(Address).... SHARED VARIABLE Mem : MemArray := (OTHERS => (OTHERS => MaxData)); --protected sectors and sub sectors SHARED VARIABLE Sec_Prot : std_logic_vector(SecNum-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE SecSi : SecSiType := (OTHERS => 0); SIGNAL OTP_ACT : std_logic := '0'; -- timing check violation SIGNAL Viol : X01 := '0'; -- Factory Protect SIGNAL FactoryProt : BOOLEAN := TRUE; SIGNAL tpd_fromOE : std_logic := '0'; SIGNAL tpd_fromCE : std_logic := '0'; SHARED VARIABLE FROMOE,FROMCE, OPENLATCH : boolean; SHARED VARIABLE tpd_from_OE : BOOLEAN := FALSE; SHARED VARIABLE tpd_from_CE : BOOLEAN := FALSE; SHARED VARIABLE Open3state : BOOLEAN := FALSE; SHARED VARIABLE ERASE_START : TIME; BEGIN --------------------------------------------------------------------------- --Power Up time 100 ns; --------------------------------------------------------------------------- PoweredUp <= '1' AFTER 100 ns; RST <= RESETNeg AFTER 500 ns; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(CENeg, WENeg, OENeg, RESETNeg, A, DIn) --Setup/Hold checks variables VARIABLE Tviol_CENeg_RESETNeg : X01 := '0'; VARIABLE Tviol_OENeg_RESETNeg : X01 := '0'; VARIABLE Tviol_OENeg_WENeg : X01 := '0'; VARIABLE Tviol_DQ0_WENeg : X01 := '0'; VARIABLE Tviol_DQ0_CENeg : X01 := '0'; VARIABLE Tviol_WENeg_OENeg : X01 := '0'; VARIABLE Tviol_A0_WENeg : X01 := '0'; VARIABLE Tviol_A0_CENeg : X01 := '0'; VARIABLE Tviol_A0_OENeg_setup : X01 := '0'; VARIABLE Tviol_A0_OENeg_hold : X01 := '0'; VARIABLE Tviol_A0_CENeg_toggle : X01 := '0'; VARIABLE Tviol_WENeg_CENeg_setup : X01 := '0'; VARIABLE Tviol_WENeg_CENeg_hold : X01 := '0'; VARIABLE Tviol_CENeg_WENeg_setup : X01 := '0'; VARIABLE Tviol_CENeg_WENeg_hold : X01 := '0'; VARIABLE TD_WENeg_CENeg : VitalTimingDataType; VARIABLE TD_CENeg_RESETNeg : VitalTimingDataType; VARIABLE TD_OENeg_RESETNeg : VitalTimingDataType; VARIABLE TD_OENeg_WENeg : VitalTimingDataType; VARIABLE TD_DQ0_WENeg : VitalTimingDataType; VARIABLE TD_DQ0_CENeg : VitalTimingDataType; VARIABLE TD_WENeg_OENeg : VitalTimingDataType; VARIABLE TD_A0_WENeg : VitalTimingDataType; VARIABLE TD_A0_CENeg : VitalTimingDataType; VARIABLE TD_A0_OENeg_setup : VitalTimingDataType; VARIABLE TD_A0_OENeg_hold : VitalTimingDataType; VARIABLE TD_A0_OENeg_toggle : VitalTimingDataType; VARIABLE TD_WENeg_CENeg_setup : VitalTimingDataType; VARIABLE TD_WENeg_CENeg_hold : VitalTimingDataType; VARIABLE TD_CENeg_WENeg_setup : VitalTimingDataType; VARIABLE TD_CENeg_WENeg_hold : VitalTimingDataType; -- Pulse width cheks variables VARIABLE Pviol_CENeg : X01 := '0'; VARIABLE Pviol_WENeg : X01 := '0'; VARIABLE Pviol_OENeg : X01 := '0'; VARIABLE Pviol_RESETNeg : X01 := '0'; VARIABLE Pviol_A0 : X01 := '0'; VARIABLE PD_CENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_OENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_RESETNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A0 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01; BEGIN IF TimingChecksOn THEN -- Setup/Hold Checks Violation := '0'; VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_A0_WENeg, SetupHigh => tsetup_A0_WENeg, HoldLow => thold_A0_WENeg, HoldHigh => thold_A0_WENeg, CheckEnabled => CENeg='0' , RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_A0_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_WENeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CENeg, RefSignalName => "CENeg", SetupLow => tsetup_A0_WENeg, SetupHigh => tsetup_A0_WENeg, HoldLow => thold_A0_WENeg, HoldHigh => thold_A0_WENeg, CheckEnabled => WENeg='0' , RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_A0_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_CENeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => OENeg, RefSignalName => "OENeg", SetupLow => tsetup_A0_OENeg, SetupHigh => tsetup_A0_OENeg, CheckEnabled => CENeg='0' AND (SERS_ACT='1' OR PGMS_ACT='1'), RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_A0_OENeg_setup, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_OENeg_setup ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => OENeg, RefSignalName => "OENeg", HoldLow => thold_A0_OENeg, HoldHigh => thold_A0_OENeg, CheckEnabled => CENeg='0' AND (SERS_ACT='1' OR PGMS_ACT='1'), RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_A0_OENeg_hold, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_OENeg_hold ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CENeg, RefSignalName => "CENeg", HoldLow => thold_A0_OENeg, HoldHigh => thold_A0_OENeg, CheckEnabled => OENeg='0' AND (SERS_ACT='1' OR PGMS_ACT='1'), RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_A0_OENeg_toggle, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_CENeg_toggle ); VitalSetupHoldCheck ( TestSignal => Din, TestSignalName => "Din", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_DQ0_WENeg, SetupHigh => tsetup_DQ0_WENeg, HoldLow => thold_DQ0_WENeg, HoldHigh => thold_DQ0_WENeg, CheckEnabled => CENeg = '0', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_DQ0_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_DQ0_WENeg ); VitalSetupHoldCheck ( TestSignal => Din, TestSignalName => "Din", RefSignal => CENeg, RefSignalName => "CENeg", SetupLow => tsetup_DQ0_WENeg, SetupHigh => tsetup_DQ0_WENeg, HoldLow => thold_DQ0_WENeg, HoldHigh => thold_DQ0_WENeg, CheckEnabled => WENeg = '0', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_DQ0_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_DQ0_CENeg ); VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OENeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_OENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_OENeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_OENeg_WENeg ); VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldHigh => thold_OENeg_WENeg, CheckEnabled => PGMS_ACT = '1'AND SERS_ACT = '1', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_OENeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_OENeg_WENeg ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => RESETNeg, RefSignalName => "RESETNeg", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_RESETNeg ); VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OENeg", RefSignal => RESETNeg, RefSignalName => "RESETNeg", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_OENeg_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_OENeg_RESETNeg ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_WENeg_hold, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_WENeg_hold ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CENeg, RefSignalName => "CENeg", HoldLow => thold_WENeg_CENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_CENeg_hold, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_CENeg_hold ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CENeg, RefSignalName => "CENeg", HoldLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_CENeg_setup, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_CENeg_setup ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_WENeg_setup, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_WENeg_setup ); VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CENeg", PulseWidthHigh => tpw_CENeg_posedge, PulseWidthLow => tpw_CENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CENeg ); VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WENeg", PulseWidthHigh => tpw_WENeg_posedge, PulseWidthLow => tpw_WENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_WENeg ); VitalPeriodPulseCheck ( TestSignal => OENeg, TestSignalName => "OENeg", PulseWidthHigh => tpw_OENeg_posedge, CheckEnabled => (SERS_ACT='1' OR PGMS_ACT='1'), HeaderMsg => InstancePath & PartID, PeriodData => PD_OENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_OENeg ); VitalPeriodPulseCheck ( TestSignal => A0, TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A0, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A0 ); -- RESET pulse width will be shorter than tpw_RESETNeg_negedge during simulatio -- in order to check if device works properly. If you still want these warnings -- uncomment the following section VitalPeriodPulseCheck ( TestSignal => RESETNeg, TestSignalName => "RESETNeg", PulseWidthLow => tpw_RESETNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_RESETNeg ); Violation := Tviol_CENeg_RESETNeg OR Tviol_OENeg_RESETNeg OR Tviol_OENeg_WENeg OR Tviol_DQ0_CENeg OR Tviol_WENeg_OENeg OR Tviol_A0_WENeg OR Tviol_A0_CENeg OR Tviol_WENeg_CENeg_setup OR Tviol_WENeg_CENeg_hold OR Tviol_CENeg_WENeg_setup OR Tviol_CENeg_WENeg_hold OR Pviol_CENeg OR Pviol_WENeg OR Pviol_RESETNeg; ASSERT Violation = '0' REPORT InstancePath & partID & " simulation may be inaccurate due to timing violations" SEVERITY WARNING; viol <= violation; END IF; -- TimingChecksOn END PROCESS VITALTimingCheck; --------------------------------------------------------------------------- -- sequential process for reset control and FSM state transition --------------------------------------------------------------------------- StateTransition : PROCESS(next_state, RESETNeg, RST, READY_out, PDone, EDone, PoweredUp) VARIABLE R : std_logic := '0'; --prog or erase in progress VARIABLE E : std_logic := '0'; --reset timming error BEGIN IF PoweredUp = '1' THEN --Hardware reset timing control IF falling_edge(RESETNeg) THEN E := '0'; IF (PDONE = '0' OR EDONE = '0') THEN --IF program or erase in progress READY_in <= '1'; R := '1'; ELSE READY_in <= '0'; R := '0'; --prog or erase not in progress END IF; ELSIF rising_edge(RESETNeg) AND RST = '1' THEN --RESET# pulse < tRP READY_in <= '0'; R := '0'; E := '1'; END IF; IF RESETNeg = '1' AND ( R = '0' OR (R = '1' AND READY_out = '1')) THEN current_state <= next_state; READY_in <= '0'; E := '0'; R := '0'; reseted <= '1'; ELSIF (R = '0' AND RESETNeg = '0' AND RST = '0') OR (R = '1' AND RESETNeg = '0' AND RST = '0' AND READY_out = '0') OR (R = '1' AND RESETNeg = '1' AND RST = '0' AND READY_out = '0') OR (R = '1' AND RESETNeg = '1' AND RST = '1' AND READY_out = '0') THEN --no state transition while RESET# low current_state <= RESET; --reset start reseted <= '0'; END IF; ELSE current_state <= RESET; -- reset reseted <= '0'; E := '0'; R := '0'; END IF; END PROCESS StateTransition; --------------------------------------------------------------------------- --Glitch Protection: Inertial Delay does not propagate pulses <5ns --------------------------------------------------------------------------- gWE_n <= WENeg AFTER 5 ns; gCE_n <= CENeg AFTER 5 ns; gOE_n <= OENeg AFTER 5 ns; --latch address on rising edge and data on falling edge of write write_dc: PROCESS (gWE_n, gCE_n, gOE_n, RESETNeg, reseted) BEGIN IF RESETNeg /= '0' AND reseted = '1' THEN IF (gWE_n = '0') AND (gCE_n = '0') AND (gOE_n = '1') THEN write <= '1'; ELSIF (gWE_n = '1' OR gCE_n = '1') AND gOE_n = '1' THEN write <= '0'; ELSE write <= '0'; END IF; ELSE write <= '0'; END IF; IF reseted = '1' THEN IF ((gWE_n = '1') AND (gCE_n = '0') AND (gOE_n = '0')) THEN read <= '1'; ELSE read <= '0'; END IF; ELSE read <= '0'; END IF; END PROCESS write_dc; --------------------------------------------------------------------------- --Process that reports warning when changes on signals WE#, CE#, OE# are --discarded --------------------------------------------------------------------------- PulseWatch : PROCESS (WENeg, CENeg, OENeg, gWE_n, gCE_n, gOE_n) BEGIN IF Now > 0 ns THEN IF (WENeg'EVENT AND (WENeg = gWE_n)) OR (CENeg'EVENT AND (CENeg = gCE_n)) OR (OENeg'EVENT AND (OENeg = gOE_n)) THEN ASSERT false REPORT "Glitch detected on control signals" SEVERITY warning; END IF; END IF; END PROCESS PulseWatch; --------------------------------------------------------------------------- -- Latch address on falling edge of WE# or CE# what ever comes later -- Latches data on rising edge of WE# or CE# what ever comes first -- also Write cycle decode --------------------------------------------------------------------------- BusCycleDecode : PROCESS(A, Din, write, WENeg, CENeg, OENeg, reseted) VARIABLE AddressLatch_tmp : std_logic_vector(HiAddrBit DOWNTO 0); BEGIN IF reseted = '1' THEN IF (falling_edge(WENeg) AND CENeg='0' AND OENeg = '1' ) OR (falling_edge(CENeg) AND WENeg /= OENeg ) OR (falling_edge(OENeg) AND WENeg='1' AND CENeg = '0' ) OR (A'EVENT AND WENeg = '1' AND CENeg = '0' AND OENeg = '0') THEN AddressLatch_tmp := A; ELSIF (rising_edge(WENeg) OR rising_edge(CENeg)) AND write = '1' THEN D_tmp0 <= to_nat(Din(7 DOWNTO 0)); D_tmp <= to_nat(Din(15 DOWNTO 0)); END IF; IF rising_edge(write) OR (CENeg = '0' AND OENeg = '0') THEN Addr := to_nat(AddressLatch_tmp(10 DOWNTO 0)); Address := to_nat (AddressLatch_tmp(LowSecAddrBit-1 DOWNTO 0)); SA := to_nat (AddressLatch_tmp(HiAddrBit DOWNTO LowSecAddrBit)); AddressLatch <= AddressLatch_tmp; END IF; END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- Timing control for the Program Operations --------------------------------------------------------------------------- ProgTime : PROCESS(PSTART, reseted) VARIABLE elapsed : time; VARIABLE duration : time; VARIABLE POW : time; BEGIN IF LongTimming THEN POW := tdevice_POW; ELSE POW := tdevice_POW/2; END IF; IF rising_edge(reseted) THEN PDONE <= '1'; -- reset done, programing terminated ELSIF reseted = '1' THEN IF rising_edge(PSTART) AND PDONE = '1' THEN IF (Sec_Prot(SA) = '0' AND Ers_Queue(SA) = '0' AND OTP_ACT = '0') OR (NOT FactoryProt AND OTP_ACT = '1') THEN duration := POW; elapsed := 0 ns; PDONE <= '0', '1' AFTER duration; ELSE PERR <= '1', '0' AFTER 1 us; ASSERT FALSE REPORT "CANNOT WRITE IN SUSPEND/PROTECTED SECTOR" SEVERITY NOTE; END IF; END IF; END IF; END PROCESS ProgTime; --------------------------------------------------------------------------- -- Timing control for the Erase Operations --------------------------------------------------------------------------- ErsTime :PROCESS(ESTART, ESUSP, ESTART_SUSP, ERES, Ers_Queue, reseted) VARIABLE cnt : NATURAL; VARIABLE elapsed : time; VARIABLE duration : time; VARIABLE start : time; VARIABLE seo : time; BEGIN IF LongTimming THEN SEO := tdevice_SEO; ELSE SEO := tdevice_SEO/1000; END IF; IF rising_edge(reseted) THEN EDONE <= '1'; -- reset done, ERASE terminated ELSIF reseted = '1' THEN IF (rising_edge(ESTART) OR rising_edge(ESTART_SUSP)) AND EDONE = '1' THEN cnt := 0; FOR i IN 0 TO SecNum-1 LOOP IF Ers_Queue(i) = '1' AND Sec_Prot(i) = '0' THEN cnt := cnt + 1; END IF; END LOOP; IF cnt > 0 THEN elapsed := 0 ns; duration := cnt * seo; EDONE <= '0', '1' AFTER duration; start := NOW; ELSE EERR <= '1', '0' AFTER 100 us; END IF; END IF; IF (rising_edge(ESUSP) OR rising_edge(ESTART_SUSP)) AND EDONE = '0' THEN elapsed := NOW - start; duration := duration - elapsed; EDONE <= '0'; ELSIF rising_edge(ERES) AND EDONE = '0' THEN start := NOW; EDONE <= '0', '1' AFTER duration; END IF; END IF; END PROCESS; --------------------------------------------------------------------------- -- Main Behavior Process -- combinational process for next state generation --------------------------------------------------------------------------- StateGen :PROCESS(write, PDONE, EDONE, CTMOUT_out, ESTART_T1_out, reseted, READY_out, PERR, EERR) VARIABLE PATTERN_1 : boolean := FALSE; VARIABLE PATTERN_2 : boolean := FALSE; VARIABLE A_PAT_1 : boolean := FALSE; --DATA Low Byte VARIABLE DataLo : NATURAL RANGE 0 TO MaxData := 0; BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- IF falling_edge(write) THEN DataLo := D_tmp0; PATTERN_1 := (Addr = 16#555#) AND (DataLo = 16#AA#) ; PATTERN_2 := (Addr = 16#2AA#) AND (DataLo = 16#55#) ; A_PAT_1 := (Addr = 16#555#) ; END IF; IF reseted /= '1' THEN next_state <= current_state; ELSE CASE current_state IS WHEN RESET => IF falling_edge(write) THEN IF (PATTERN_1) THEN next_state <= Z001; ELSIF ((Addr = 16#55#) AND (DataLo = 16#98#)) THEN next_state <= CFI; ELSE next_state <= RESET; END IF; END IF; WHEN Z001 => IF falling_edge(write) THEN IF (PATTERN_2) THEN next_state <= PREL_SETBWB; ELSE next_state <= RESET; END IF; END IF; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#A0#)) THEN next_state <= A0SEEN; ELSIF (A_PAT_1 AND (DataLo = 16#20#)) THEN next_state <= PREL_ULBYPASS; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN next_state <= OTP; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN next_state <= AS; ELSIF (A_PAT_1 AND (DataLo = 16#80#)) THEN next_state <= C8; ELSE next_state <= RESET; END IF; END IF; WHEN PREL_ULBYPASS => IF falling_edge(write) THEN IF DataLo = 16#90# THEN next_state <= UNLOCK_RESET; ELSIF (DataLo = 16#A0#) THEN next_state <= A0SEEN; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; WHEN UNLOCK_RESET => IF falling_edge(write) THEN IF (DataLo = 16#00#) THEN next_state <= RESET; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; WHEN AS => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= RESET; ELSIF ((Addr = 16#55#) AND (DataLo = 16#98#)) THEN next_state <= AS_CFI; END IF; END IF; WHEN AS_CFI => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= AS; END IF; END IF; WHEN CFI => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= RESET; END IF; END IF; WHEN OTP => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= OTP_Z001; ELSIF (Address MOD 16#100# = 16#02# AND DataLo = 16#60#) THEN next_state <= OTP_FP1; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_FP1 => IF falling_edge(write) THEN IF (Address MOD 16#100# = 16#02# AND DataLo = 16#40#) THEN next_state <= OTP_FP2; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_FP2 => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= OTP; END IF; END IF; WHEN OTP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= OTP_PREL; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_PREL => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#90#))THEN next_state <= OTP_EXIT; ELSIF (A_PAT_1 AND (DataLo = 16#A0#))THEN next_state <= OTP_A0SEEN; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_EXIT => IF falling_edge(write) THEN IF (DataLo = 16#00# AND ESP_ACT='0') THEN next_state <= RESET; ELSIF (DataLo = 16#00# AND ESP_ACT='1') THEN next_state <= ESP; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_A0SEEN => IF falling_edge(write) THEN IF (SA = 0 AND Address <= SecSiSize) THEN next_state <= PGMS; ELSE next_state <= OTP; END IF; ELSE next_state <= OTP_A0SEEN; END IF; WHEN A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; ELSE next_state <= A0SEEN; END IF; WHEN C8 => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= C8_Z001; ELSE next_state <= RESET; END IF; END IF; WHEN C8_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= C8_PREL; ELSE next_state <= RESET; END IF; END IF; WHEN C8_PREL => IF falling_edge(write) THEN IF A_PAT_1 AND DataLo = 16#10# THEN next_state <= ERS; ELSIF DataLo = 16#30# THEN next_state <= SERS; ELSE next_state <= RESET; END IF; END IF; WHEN ERS => IF rising_edge(EDONE) OR falling_edge(EERR) THEN next_state <= RESET; END IF; WHEN SERS => IF (CTMOUT_out = '1') THEN next_state <= SERS_EXEC; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN next_state <= ESP; -- ESP according to datasheet ELSIF (DataLo = 16#30#) THEN next_state <= SERS; ELSE next_state <= RESET; END IF; END IF; WHEN SERS_EXEC => IF rising_edge(EDONE) OR falling_edge(EERR) THEN next_state <= RESET; ELSIF EERR /= '1' THEN IF falling_edge(write) THEN IF DataLo = 16#B0# THEN next_state <= ESPS; END IF; END IF; END IF; WHEN ESPS => IF (ESTART_T1_out = '1') THEN next_state <= ESP; END IF; WHEN ESP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN next_state <= SERS_EXEC; ELSE IF (Addr = 16#55# AND DataLo = 16#98#) THEN next_state <= ESP_CFI; ELSIF PATTERN_1 THEN next_state <= ESP_Z001; END IF; END IF; END IF; WHEN ESP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= ESP_SETBWB; ELSE next_state <= ESP; END IF; END IF; WHEN ESP_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND DataLo = 16#90#) THEN next_state <= ESP_AS; ELSIF (A_PAT_1 AND DataLo = 16#A0#) THEN next_state <= ESP_A0SEEN; ELSIF (A_PAT_1 AND DataLo = 16#20#) THEN next_state <= ESP_ULBYPASS; ELSIF (A_PAT_1 AND DataLo = 16#88#) THEN next_state <= OTP; ELSE next_state <= ESP; END IF; END IF; WHEN ESP_AS => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= ESP; ELSIF ((Addr = 16#55#) AND (DataLo = 16#98#)) THEN next_state <= ESP_AS_CFI; ELSE next_state <= ESP_AS; END IF; END IF; WHEN ESP_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= ESP; END IF; END IF; WHEN ESP_AS_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= ESP_AS; ELSE next_state <= ESP_AS_CFI; END IF; END IF; WHEN ESP_A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; END IF; WHEN ESP_ULBYPASS => IF falling_edge(write) THEN IF (DataLo=16#A0#) THEN next_state <= ESP_A0SEEN; ELSIF (DataLo=16#90#) THEN next_state <= ESP_ULBYPASS_RESET; END IF; END IF; WHEN ESP_ULBYPASS_RESET => IF falling_edge(write) THEN IF (DataLo=16#00#) THEN next_state <= ESP; ELSE next_state <= ESP_ULBYPASS; END IF; END IF; WHEN PGMS => IF rising_edge(PDONE) OR falling_edge(PERR) THEN IF ESP_ACT = '1' THEN IF ULBYPASS = '1' THEN next_state <= ESP_ULBYPASS; ELSIF OTP_ACT = '1' THEN next_state <= OTP; ELSE next_state <= ESP; END IF; ELSIF ULBYPASS = '1' THEN next_state <= PREL_ULBYPASS; ELSIF OTP_ACT = '1' THEN next_state <= OTP; ELSE next_state <= RESET; END IF; END IF; END CASE; END IF; END PROCESS StateGen; --------------------------------------------------------------------------- --FSM Output generation and general funcionality --------------------------------------------------------------------------- Functional : PROCESS(write, read, AddressLatch, PDONE, PERR, EDONE, ESTART_T1_out, CTMOUT_out, RST, reseted, READY_out, gOE_n, gCE_n, current_state, OENeg) PROCEDURE DriveOut IS BEGIN IF Mem(SA)(Address) = -1 THEN DOut_zd(15 DOWNTO 0) <= (OTHERS => 'X'); ELSE DOut_zd(15 DOWNTO 0) <= to_slv(Mem(SA)(Address),16); END IF; END PROCEDURE DriveOut; -- PROCEDURE FOR READ AUTOSELECT SECTOR PROCEDURE Read_AS IS VARIABLE AutoselAddress : NATURAL; VARIABLE AutoselData : std_logic_vector(15 DOWNTO 0); BEGIN AutoselAddress := Address MOD 16#100#; IF AutoselAddress = 0 THEN AutoselData := to_slv(1,16); ELSIF AutoselAddress = 1 THEN AutoselData := to_slv(16#22D7#,16); ELSIF AutoselAddress = 2 THEN IF (Sec_Prot(SA) = '0') THEN -- sector unlock AutoselData := to_slv(0,16); ELSE -- sector lock AutoselData := to_slv(1,16); END IF; ELSE AutoselData := (OTHERS =>'Z'); END IF; DOut_zd <= AutoselData; END PROCEDURE Read_AS; -- procedure for read from memory when erase embaded algoritam is suspend PROCEDURE Readmem_EraseSuspend( VARIABLE Status : INOUT std_logic_vector(7 DOWNTO 0) ) IS VARIABLE read_nosuspend_sect : BOOLEAN := TRUE; BEGIN read_nosuspend_sect := TRUE; IF Ers_Queue(SA) = '1' AND Sec_Prot(SA) = '0' THEN read_nosuspend_sect := FALSE; END IF; IF read_nosuspend_sect = TRUE THEN DriveOut; ELSE ----------------------------------------------------------- --read status / erase suspend timeout - stil erasing ----------------------------------------------------------- Status(7) := '1'; Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => 'Z'); END IF; END PROCEDURE Readmem_EraseSuspend; PROCEDURE Read_EraseStatus ( VARIABLE Status : INOUT std_logic_vector(7 DOWNTO 0)) IS BEGIN Status(7) := '0'; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; IF NOW - ERASE_START > 100 us THEN IF (Ers_Queue(SA) = '1' AND Sec_Prot(SA) = '0') THEN Status(2) := NOT Status(2); --toggle END IF; ELSE IF (Ers_Queue(SA) = '1') THEN Status(2) := NOT Status(2); --toggle END IF; END IF; END PROCEDURE Read_EraseStatus; --Common Flash Interface Query codes TYPE CFItype IS ARRAY (16#10# TO 16#4F#) OF INTEGER RANGE -1 TO 16#FF#; VARIABLE CFI_array : CFItype := (OTHERS => -1); VARIABLE WRData : INTEGER := 0; VARIABLE Mem_tmp : INTEGER := 0; VARIABLE WRSA : NATURAL := 0; VARIABLE WRAddress : NATURAL := 0; VARIABLE A_PAT_1 : boolean := FALSE; VARIABLE oe : boolean := FALSE; --Status reg. VARIABLE Status : std_logic_vector(7 DOWNTO 0) := (OTHERS => '0'); --DATA Full VARIABLE Data : NATURAL Range 0 TO MaxData := 0; --DATA Low Byte VARIABLE DataLo : NATURAL RANGE 0 TO MaxData := 0; VARIABLE temp : std_logic_vector(7 DOWNTO 0); VARIABLE read_nosuspend_sect : BOOLEAN; VARIABLE i_sec : NATURAL; VARIABLE i_sub : NATURAL; VARIABLE new_data : std_logic_vector(15 DOWNTO 0); VARIABLE old_data : std_logic_vector(15 DOWNTO 0); VARIABLE data_mem : natural; VARIABLE erase_active : BOOLEAN; VARIABLE erase_suspend : BOOLEAN; BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- IF falling_edge(write) THEN DataLo := D_tmp0; Data := D_tmp; A_PAT_1 := Addr = 16#555#; END IF; oe := rising_edge(read) OR (read = '1' AND (AddressLatch'EVENT)); IF reseted = '1' THEN RY_zd <= '1'; CASE current_state IS WHEN RESET => ULBYPASS <= '0'; OTP_ACT <= '0'; Ers_Queue <= (OTHERS => '0'); SERS_ACT <= '0'; ESP_ACT <= '0'; PGMS_ACT <= '0'; CTMOUT_in <= '0'; IF falling_edge(write) THEN NULL; -- ned ELSIF oe THEN DriveOut; END IF; WHEN Z001 => null; WHEN PREL_SETBWB => null; WHEN AS => IF oe THEN Read_AS; END IF; WHEN PREL_ULBYPASS | ESP_ULBYPASS => ULBYPASS <= '1'; WHEN UNLOCK_RESET | ESP_ULBYPASS_RESET => IF falling_edge(write) THEN IF (DataLo = 16#00#) THEN ULBYPASS <= '0'; END IF; END IF; WHEN CFI | AS_CFI | ESP_CFI | ESP_AS_CFI => IF oe THEN DOut_zd(15 DOWNTO 0) <= (OTHERS => '0'); IF ((to_nat(AddressLatch) >= 16#10# AND to_nat(AddressLatch) <= 16#3C#) OR (to_nat(AddressLatch) >= 16#40# AND to_nat(AddressLatch) <= 16#4F#)) THEN DOut_zd(7 DOWNTO 0) <= to_slv(CFI_array(to_nat(AddressLatch)),8); ELSE ASSERT FALSE REPORT "Invalid CFI query address" SEVERITY warning; DOut_zd <= (OTHERS =>'Z'); END IF; END IF; WHEN OTP => OTP_ACT <= '1'; IF oe THEN IF (SA = 0 AND Address <= SecSiSize) THEN IF SecSi(Address)= -1 THEN DOut_zd <= (OTHERS=>'X'); ELSE DOut_zd <= to_slv(SecSi(Address),16); END IF; ELSE DOut_zd(15 downto 0) <= (OTHERS=>'Z'); ASSERT FALSE REPORT "Invalid SecSi Address read" SEVERITY WARNING; END IF; END IF; WHEN OTP_FP1 => WHEN OTP_FP2 => IF (Address MOD 16#100# = 16#02# AND oe) THEN IF FactoryProt THEN DOut_zd <= to_slv(16#98#, 16); ELSE DOut_zd <= to_slv(16#18#, 16); END IF; END IF; WHEN OTP_Z001 => null; WHEN OTP_PREL => null; WHEN OTP_A0SEEN => IF falling_edge(write) THEN IF (SA = 0 AND Address <= SecSiSize) THEN IF FactoryProt THEN temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); PSTART <= '1', '0' AFTER 1 ns; ELSE OTP_ACT <= '1'; PSTART <= '1', '0' AFTER 1 ns; WRData := Data; WRAddress := Address; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); Mem_tmp := SecSi(WRAddress); SecSi(WRAddress) := -1; END IF; ELSE ASSERT FALSE REPORT "Can not program to invalid SecSi Address." SEVERITY WARNING; END IF; END IF; WHEN OTP_EXIT => null; WHEN A0SEEN | ESP_A0SEEN => IF falling_edge(write) THEN IF (Sec_Prot(SA) = '0' AND Ers_Queue(SA) = '0') THEN PSTART <= '1', '0' AFTER 1 ns; WRData := Data; WRSA := SA; WRAddress := Address; Mem_tmp := Mem(WRSA)(WRAddress); Mem(WRSA)(WRAddress) := -1; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); ELSE temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); PSTART <= '1', '0' AFTER 1 ns; END IF; END IF; WHEN PGMS => RY_zd <= '0'; PGMS_ACT <= '1'; IF oe THEN ----------------------------------------------------------- --read status ----------------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => 'Z'); END IF; IF falling_edge(PERR) THEN PGMS_ACT <= '0'; END IF; IF PERR /= '1' THEN IF rising_edge(PDONE) AND (NOT PERR'EVENT) THEN PGMS_ACT <= '0'; IF Mem_tmp /= -1 THEN new_data := to_slv(WRData,16); old_data := to_slv(Mem_tmp,16); data_mem := to_nat(new_data AND old_data); IF OTP_ACT = '0' THEN Mem(WRSA)(WRAddress) := data_mem; ELSE SecSi(WRAddress) := data_mem; END IF; ELSE IF OTP_ACT = '0' THEN Mem(WRSA)(WRAddress) := WRData; ELSE SecSi(WRAddress) := WRData; END IF; END IF; END IF; END IF; WHEN C8 => IF falling_edge(write) THEN null; END IF; WHEN C8_Z001 => IF falling_edge(write) THEN null; END IF; WHEN C8_PREL => IF falling_edge(write) THEN IF A_PAT_1 AND DataLo = 16#10# THEN ESTART <= '1', '0' AFTER 1 ns; ESUSP <= '0'; ERES <= '0'; Ers_Queue <= (OTHERS => '1'); Status := "00001000"; SERS_ACT <= '1'; ERASE_START := NOW; ELSIF DataLo = 16#30# THEN --put selected sector to sec. ers. queue --start timeout Ers_Queue <= (OTHERS => '0'); Ers_Queue(SA) <= '1'; CTMOUT_in <= '1'; SERS_ACT <= '1'; END IF; END IF; WHEN ERS => RY_zd <= '0'; IF oe THEN Read_EraseStatus(Status); DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => 'Z'); END IF; IF EERR /= '1' THEN FOR i IN 0 TO SecNum -1 LOOP IF Sec_Prot(i) = '0' THEN Mem(i) := (OTHERS => -1); END IF; END LOOP; IF EDONE = '1' THEN FOR i IN 0 TO SecNum -1 LOOP IF Sec_Prot(i) = '0' THEN Mem(i) := (OTHERS => MaxData); END IF; Ers_Queue <= (OTHERS => '0'); END LOOP; END IF; END IF; WHEN SERS => ESP_ACT <= '0'; IF (CTMOUT_out = '1') THEN CTMOUT_in <= '0'; ESTART_T1_in <= '0'; ESTART <= '1', '0' AFTER 1 ns; ESUSP <= '0'; ERES <= '0'; ERASE_START := NOW; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN --need to start erase process prior to suspend ESTART_SUSP <= '1', '0' AFTER 1 ns; CTMOUT_in <= '0'; ERES <= '0'; ELSIF (DataLo = 16#30#) THEN CTMOUT_in <= '0', '1' AFTER 1 NS; Ers_Queue(SA) <= '1'; ELSE CTMOUT_in <= '0'; Ers_Queue <= (OTHERS => '0'); END IF; ELSIF oe THEN ---------------------------------------------------------- --read status - sector erase timeout ---------------------------------------------------------- Status(3) := '0'; DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => 'Z'); END IF; WHEN ESPS => RY_zd <= '0'; IF (ESTART_T1_out = '1') THEN ESTART_T1_in <= '0'; ESP_ACT <= '1'; ELSIF oe THEN ---------------------------------------------------------- --read status / erase suspend timeout - stil erasing ---------------------------------------------------------- Read_EraseStatus(Status); DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => 'Z'); END IF; WHEN SERS_EXEC => RY_zd <= '0'; ESP_ACT <= '0'; IF oe THEN ----------------------------------------------------------- --read status Erase Busy ----------------------------------------------------------- Read_EraseStatus(Status); DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => 'Z'); END IF; IF EERR /= '1' THEN IF EDONE /= '1' THEN FOR i IN 0 TO SecNum -1 LOOP IF Sec_Prot(i) = '0' AND Ers_Queue(i) = '1' THEN Mem(i) := (OTHERS => -1); END IF; END LOOP; ELSE FOR i IN 0 TO SecNum-1 LOOP IF Sec_Prot(i) = '0' AND Ers_Queue(i) = '1' THEN Mem(i) := (OTHERS => MaxData); END IF; END LOOP; END IF; IF falling_edge(write) THEN IF DataLo = 16#B0# THEN ESTART_T1_in <= '1'; ESUSP <= '1', '0' AFTER 1 ns; END IF; END IF; END IF; WHEN ESP => ESP_ACT <= '1'; IF falling_edge(write) THEN IF DataLo = 16#30# THEN ERES <= '1', '0' AFTER 1 ns; END IF; ELSIF oe THEN ----------------------------------------------------------- --read memory ----------------------------------------------------------- Readmem_EraseSuspend(Status); END IF; WHEN ESP_Z001 => null; WHEN ESP_SETBWB => null; WHEN ESP_AS => IF oe THEN Read_AS; END IF; END CASE; ELSE Ers_Queue <= (OTHERS => '0'); END IF; --Output Disable Control IF (gOE_n = '1' OR gCE_n = '1') OR (RESETNeg = '0'AND RST = '0') THEN DOut_zd <= (OTHERS => 'Z'); END IF; --Preload Control ----------------------------------------------------------------------- -- File read Section ----------------------------------------------------------------------- IF NOW = 0 ns THEN ----------------------------------------------------------------------- --CFI array data ----------------------------------------------------------------------- --CFI query identification string -- !!!!!! WORD ADDRESSES (x16) - for x8 addressing double addr --CFI query identification string CFI_array(16#10#) := 16#0051#; CFI_array(16#11#) := 16#0052#; CFI_array(16#12#) := 16#0059#; CFI_array(16#13#) := 16#0002#; CFI_array(16#14#) := 16#0000#; CFI_array(16#15#) := 16#0040#; CFI_array(16#16#) := 16#0000#; CFI_array(16#17#) := 16#0000#; CFI_array(16#18#) := 16#0000#; CFI_array(16#19#) := 16#0000#; CFI_array(16#1A#) := 16#0000#; --system interface string CFI_array(16#1B#) := 16#0030#; CFI_array(16#1C#) := 16#0036#; CFI_array(16#1D#) := 16#0000#; CFI_array(16#1E#) := 16#0000#; CFI_array(16#1F#) := 16#0004#; CFI_array(16#20#) := 16#0000#; CFI_array(16#21#) := 16#000A#; CFI_array(16#22#) := 16#0000#; CFI_array(16#23#) := 16#0005#; CFI_array(16#24#) := 16#0000#; CFI_array(16#25#) := 16#0004#; CFI_array(16#26#) := 16#0000#; --device geometry definition CFI_array(16#27#) := 16#0017#; CFI_array(16#28#) := 16#0000#; CFI_array(16#29#) := 16#0000#; CFI_array(16#2A#) := 16#0000#; CFI_array(16#2B#) := 16#0000#; CFI_array(16#2C#) := 16#0001#; CFI_array(16#2D#) := 16#007F#; CFI_array(16#2E#) := 16#0000#; CFI_array(16#2F#) := 16#0000#; CFI_array(16#30#) := 16#0001#; CFI_array(16#31#) := 16#0000#; CFI_array(16#32#) := 16#0000#; CFI_array(16#33#) := 16#0000#; CFI_array(16#34#) := 16#0000#; CFI_array(16#35#) := 16#0000#; CFI_array(16#36#) := 16#0000#; CFI_array(16#37#) := 16#0000#; CFI_array(16#38#) := 16#0000#; CFI_array(16#39#) := 16#0000#; CFI_array(16#3A#) := 16#0000#; CFI_array(16#3B#) := 16#0000#; CFI_array(16#3C#) := 16#0000#; --primary vendor-specific extended query CFI_array(16#40#) := 16#0050#; CFI_array(16#41#) := 16#0052#; CFI_array(16#42#) := 16#0049#; CFI_array(16#43#) := 16#0031#; CFI_array(16#44#) := 16#0031#; CFI_array(16#45#) := 16#0001#; CFI_array(16#46#) := 16#0002#; CFI_array(16#47#) := 16#0004#; CFI_array(16#48#) := 16#0001#; CFI_array(16#49#) := 16#0004#; CFI_array(16#4A#) := 16#0000#; CFI_array(16#4B#) := 16#0000#; CFI_array(16#4C#) := 16#0000#; CFI_array(16#4D#) := 16#00B5#; CFI_array(16#4E#) := 16#00C5#; CFI_array(16#4F#) := 16#0000#; END IF; END PROCESS Functional; --------------------------------------------------------------------------- ---- File read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_f : text is mem_file_name; FILE prot_f : text is prot_file_name; FILE secsi_f : text is secsi_file_name; CONSTANT SecS : NATURAL := SecSize+1; VARIABLE addr_ind : NATURAL ; VARIABLE sec_ind : NATURAL ; VARIABLE offset : NATURAL; VARIABLE ind : NATURAL RANGE 0 TO SecNum +1; VARIABLE buf : line; VARIABLE sect : NATURAL; VARIABLE line : NATURAL :=0; VARIABLE secsi_line : NATURAL :=0; VARIABLE report_err : BOOLEAN := FALSE; BEGIN ------------------------------------------------------------------------------- -- am29lv640d memory preload file format ------------------------------------------------------------------------------- -- / - comment -- @aaaaaa - stands for address within sector -- dddd - is word to be written at Mem(aaaaaa++) -- (aaaaaa is incremented at every load) -- only first 1-7 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! ------------------------------------------------------------------------------- IF UserPreload AND (mem_file_name /= "none" ) THEN addr_ind := 0; Mem := (OTHERS => (OTHERS => MaxData)); WHILE (not ENDFILE (mem_f)) LOOP READLINE (mem_f, buf); line := line +1; IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 7)); sec_ind := addr_ind / SecS; offset := addr_ind - (sec_ind * SecS); ELSE IF addr_ind <= MemSize THEN Mem(sec_ind)(offset):= h(buf(1 to 4)); addr_ind := (addr_ind + 1); sec_ind := addr_ind / SecS; offset := addr_ind - (sec_ind * SecS); ELSE IF report_err = FALSE THEN ASSERT FALSE REPORT "Memory file: " & mem_file_name & " Address range error at line: "&to_int_Str(line) SEVERITY error; report_err := TRUE; END IF; END IF; END IF; END LOOP; END IF; ------------------------------------------------------------------------------- -- am29lv640d sector protect preload file format ------------------------------------------------------------------------------- -- / - comment -- @sec - stands for sector address -- @80 - if d = 1 SecSi is factory protected -- - if d = 0 Secsi is customer lockable -- d - is bit to be written at Sec_Prot(sec++) -- (sec is incremented at every load) -- only first 1-3 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! ------------------------------------------------------------------------------- IF UserPreload AND (prot_file_name /= "none" ) THEN ind := 0; FactoryProt <= FALSE; Sec_Prot := (OTHERS => '0'); WHILE (not ENDFILE (prot_f)) LOOP READLINE (prot_f, buf); IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN ind := h(buf(2 TO 3)); ELSE IF (buf(1) = '1') THEN IF (ind > (SecNum-1) OR (ind < 0)) THEN FactoryProt <= TRUE; ELSE Sec_Prot(ind) := '1'; END IF; END IF; IF (ind <= (SecNum) AND ind >= 0) THEN ind := ind + 1; END IF; END IF; END LOOP; FOR i IN 0 TO (SecNum/4)-1 LOOP IF Sec_Prot(4*i+3 DOWNTO 4*i) /= "0000" AND Sec_Prot(4*i+3 DOWNTO 4*i) /= "1111" THEN -- every 4-group sectors protect bit must equal REPORT "Bad preload " & to_int_str(i) & "th sector protect group" SEVERITY warning; END IF; END LOOP; END IF; ------------------------------------------------------------------------------- -- am29lv640d SecSi preload file format ------------------------------------------------------------------------------- -- / - comment -- @aa - stands for address within SecSi -- dddd - is word to be written at SecSi(aa++) -- (aaaa is incremented at every load) -- only first 1-4 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! ------------------------------------------------------------------------------- IF (secsi_file_name /= "none" AND UserPreload ) THEN SecSi := (OTHERS => MaxData); addr_ind := 0; report_err := FALSE; WHILE (not ENDFILE (secsi_f)) LOOP READLINE (secsi_f, buf); secsi_line := secsi_line +1; IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN addr_ind := h(buf(2 to 3)); --address ELSE IF addr_ind <= SecSiSize THEN SecSi(addr_ind) := h(buf(1 to 4)); addr_ind := addr_ind + 1; ELSE IF report_err = FALSE THEN ASSERT FALSE REPORT "Memory file: " & secsi_file_name & " Address range error at line: "&to_int_Str(secsi_line) SEVERITY error; report_err := TRUE; END IF; END IF; END IF; END LOOP; END IF; WAIT; END PROCESS; ----------------------------------------------------------------------- -- Path Delay Section ----------------------------------------------------------------------- DOutPassThrough : PROCESS(DOut_zd) VARIABLE tOD : time := 0 ns; VARIABLE tCD : time := 0 ns; VARIABLE tAD : time := 0 ns; BEGIN IF DOut_zd(0) /= 'Z' THEN tpd_from_OE := FALSE; tpd_from_CE := FALSE; Open3state := TRUE; tOD := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(trz1); tCD := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(trz1); tAD := -A'LAST_EVENT + tpd_A0_DQ0(tr10); IF tOD >= tCD AND tOD > 0 ns THEN tpd_from_OE := TRUE; ELSIF tCD >= tOD AND tCD > 0 ns THEN tpd_from_CE := TRUE; END IF; IF tAD > 0 ns AND ((tAD >= tOD AND tpd_from_OE = TRUE) OR (tAD >= tCD AND tpd_from_CE = TRUE)) THEN Dout_pass <= "XXXXXXXXXXXXXXXX", Dout_zd AFTER tAD; ELSE Dout_pass <= Dout_zd; END IF; ELSE tCD := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(tr0z); tOD := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(tr0z); tpd_from_OE := (tOD <= tCD) AND (tOD > 0 ns); tpd_from_CE := (tCD < tOD) AND (tCD > 0 ns); IF tpd_from_CE = TRUE THEN tpd_from_OE := FALSE; ELSIF tpd_from_OE = TRUE THEN tpd_from_CE := FALSE; ELSE tpd_from_OE := TRUE; tpd_from_CE := TRUE; END IF; Open3state := FALSE; DOut_Pass <= DOut_zd; END IF; END PROCESS DOutPassThrough; RY_OUT: PROCESS(RY_zd) VARIABLE RY_GlitchData : VitalGlitchDataType; VARIABLE RYData : std_logic; BEGIN IF RY_zd = '1' THEN RYData := 'Z'; ELSE RYData := RY_zd; END IF; VitalPathDelay01Z( OutSignal => RY, OutSignalName => "RY", OutTemp => RYData, Mode => VitalTransport, GlitchData => RY_GlitchData, Paths => ( 0 => (InputChangeTime => WENeg'LAST_EVENT, PathDelay => tpd_WENeg_RY, PathCondition => TRUE), 1 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_WENeg_RY, PathCondition => OENeg = '0')) ); END PROCESS RY_Out; --------------------------------------------------------------------------- -- Path Delay Section for DOut signal --------------------------------------------------------------------------- D_Out_PathDelay_Gen : FOR i IN 0 TO 15 GENERATE --Dout_zd'RANGE GENERATE PROCESS(DOut_pass(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_pass(i), GlitchData => D0_GlitchData, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => tpd_from_OE), 1 => (InputChangeTime => AddressLatch'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0), PathCondition => NOT (tpd_from_OE OR tpd_from_CE)), 2 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => tpd_from_CE)) ); END PROCESS; END GENERATE D_Out_PathDelay_Gen; END BLOCK behavior; END vhdl_behavioral; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.VITAL_timing.ALL; USE IEEE.VITAL_primitives.ALL; USE STD.textio.ALL; LIBRARY FMF; USE FMF.gen_utils.all; USE FMF.conversions.all; ------------------------------------------------------------------------------ -- ARCHITECTURE DECLARATION FOR TOP am29lv642d ENTITY ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of am29lv642d IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; COMPONENT am29lv640d -- tipd delays: interconnect path delays GENERIC ( tipd_A0 : VitalDelayType01 := VitalZeroDelay01; tipd_A1 : VitalDelayType01 := VitalZeroDelay01; tipd_A2 : VitalDelayType01 := VitalZeroDelay01; tipd_A3 : VitalDelayType01 := VitalZeroDelay01; tipd_A4 : VitalDelayType01 := VitalZeroDelay01; tipd_A5 : VitalDelayType01 := VitalZeroDelay01; tipd_A6 : VitalDelayType01 := VitalZeroDelay01; tipd_A7 : VitalDelayType01 := VitalZeroDelay01; tipd_A8 : VitalDelayType01 := VitalZeroDelay01; tipd_A9 : VitalDelayType01 := VitalZeroDelay01; tipd_A10 : VitalDelayType01 := VitalZeroDelay01; tipd_A11 : VitalDelayType01 := VitalZeroDelay01; tipd_A12 : VitalDelayType01 := VitalZeroDelay01; tipd_A13 : VitalDelayType01 := VitalZeroDelay01; tipd_A14 : VitalDelayType01 := VitalZeroDelay01; tipd_A15 : VitalDelayType01 := VitalZeroDelay01; tipd_A16 : VitalDelayType01 := VitalZeroDelay01; tipd_A17 : VitalDelayType01 := VitalZeroDelay01; tipd_A18 : VitalDelayType01 := VitalZeroDelay01; tipd_A19 : VitalDelayType01 := VitalZeroDelay01; tipd_A20 : VitalDelayType01 := VitalZeroDelay01; tipd_A21 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; tipd_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_ACC : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- memory file to be loaded mem_file_name : STRING := "none"; prot_file_name : STRING := "none"; secsi_file_name : STRING := "none"; UserPreload : BOOLEAN := TRUE; LongTimming : BOOLEAN := FALSE; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( A21 : IN std_ulogic := 'U'; A20 : IN std_ulogic := 'U'; A19 : IN std_ulogic := 'U'; A18 : IN std_ulogic := 'U'; A17 : IN std_ulogic := 'U'; A16 : IN std_ulogic := 'U'; A15 : IN std_ulogic := 'U'; A14 : IN std_ulogic := 'U'; A13 : IN std_ulogic := 'U'; A12 : IN std_ulogic := 'U'; A11 : IN std_ulogic := 'U'; A10 : IN std_ulogic := 'U'; A9 : IN std_ulogic := 'U'; A8 : IN std_ulogic := 'U'; A7 : IN std_ulogic := 'U'; A6 : IN std_ulogic := 'U'; A5 : IN std_ulogic := 'U'; A4 : IN std_ulogic := 'U'; A3 : IN std_ulogic := 'U'; A2 : IN std_ulogic := 'U'; A1 : IN std_ulogic := 'U'; A0 : IN std_ulogic := 'U'; DQ15 : INOUT std_ulogic := 'U'; DQ14 : INOUT std_ulogic := 'U'; DQ13 : INOUT std_ulogic := 'U'; DQ12 : INOUT std_ulogic := 'U'; DQ11 : INOUT std_ulogic := 'U'; DQ10 : INOUT std_ulogic := 'U'; DQ9 : INOUT std_ulogic := 'U'; DQ8 : INOUT std_ulogic := 'U'; DQ7 : INOUT std_ulogic := 'U'; DQ6 : INOUT std_ulogic := 'U'; DQ5 : INOUT std_ulogic := 'U'; DQ4 : INOUT std_ulogic := 'U'; DQ3 : INOUT std_ulogic := 'U'; DQ2 : INOUT std_ulogic := 'U'; DQ1 : INOUT std_ulogic := 'U'; DQ0 : INOUT std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; ACC : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U' ); END COMPONENT; SIGNAL RY1 : std_ulogic := 'U'; SIGNAL RY2 : std_ulogic := 'U'; BEGIN U_FLASH_1 : am29lv640d GENERIC MAP( -- tipd delays: interconnect path delays tipd_A0 => tipd_A0, tipd_A1 => tipd_A1, tipd_A2 => tipd_A2, tipd_A3 => tipd_A3, tipd_A4 => tipd_A4, tipd_A5 => tipd_A5, tipd_A6 => tipd_A6, tipd_A7 => tipd_A7, tipd_A8 => tipd_A8, tipd_A9 => tipd_A9, tipd_A10 => tipd_A10, tipd_A11 => tipd_A11, tipd_A12 => tipd_A12, tipd_A13 => tipd_A13, tipd_A14 => tipd_A14, tipd_A15 => tipd_A15, tipd_A16 => tipd_A16, tipd_A17 => tipd_A17, tipd_A18 => tipd_A18, tipd_A19 => tipd_A19, tipd_A20 => tipd_A20, tipd_A21 => tipd_A21, tipd_DQ0 => tipd_DQ0, tipd_DQ1 => tipd_DQ1, tipd_DQ2 => tipd_DQ2, tipd_DQ3 => tipd_DQ3, tipd_DQ4 => tipd_DQ4, tipd_DQ5 => tipd_DQ5, tipd_DQ6 => tipd_DQ6, tipd_DQ7 => tipd_DQ7, tipd_DQ8 => tipd_DQ8, tipd_DQ9 => tipd_DQ9, tipd_DQ10 => tipd_DQ10, tipd_DQ11 => tipd_DQ11, tipd_DQ12 => tipd_DQ12, tipd_DQ13 => tipd_DQ13, tipd_DQ14 => tipd_DQ14, tipd_DQ15 => tipd_DQ15, tipd_CENeg => tipd_CENegf1, tipd_OENeg => tipd_OENeg, tipd_WENeg => tipd_WENeg, tipd_RESETNeg => tipd_RESETNeg, tipd_ACC => tipd_ACC, -- generic control parameters InstancePath => InstancePath, TimingChecksOn => TimingChecksOn, MsgOn => MsgOn, XOn => XOn, -- memory file to be loaded mem_file_name => mem_file_name, prot_file_name => prot_file_name, secsi_file_name => secsi_file_name, UserPreload => UserPreload, LongTimming => LongTimming, -- For FMF SDF technology file usage TimingModel => TimingModel ) PORT MAP( A21 => A21, A20 => A20, A19 => A19, A18 => A18, A17 => A17, A16 => A16, A15 => A15, A14 => A14, A13 => A13, A12 => A12, A11 => A11, A10 => A10, A9 => A9, A8 => A8, A7 => A7, A6 => A6, A5 => A5, A4 => A4, A3 => A3, A2 => A2, A1 => A1, A0 => A0, DQ15 => DQ15, DQ14 => DQ14, DQ13 => DQ13, DQ12 => DQ12, DQ11 => DQ11, DQ10 => DQ10, DQ9 => DQ9, DQ8 => DQ8, DQ7 => DQ7, DQ6 => DQ6, DQ5 => DQ5, DQ4 => DQ4, DQ3 => DQ3, DQ2 => DQ2, DQ1 => DQ1, DQ0 => DQ0, CENeg => CENegf1, OENeg => OENeg, WENeg => WENeg, RESETNeg => RESETNeg, ACC => ACC, RY => RY1 ); U_FLASH_2 : am29lv640d GENERIC MAP( -- tipd delays: interconnect path delays tipd_A0 => tipd_A0, tipd_A1 => tipd_A1, tipd_A2 => tipd_A2, tipd_A3 => tipd_A3, tipd_A4 => tipd_A4, tipd_A5 => tipd_A5, tipd_A6 => tipd_A6, tipd_A7 => tipd_A7, tipd_A8 => tipd_A8, tipd_A9 => tipd_A9, tipd_A10 => tipd_A10, tipd_A11 => tipd_A11, tipd_A12 => tipd_A12, tipd_A13 => tipd_A13, tipd_A14 => tipd_A14, tipd_A15 => tipd_A15, tipd_A16 => tipd_A16, tipd_A17 => tipd_A17, tipd_A18 => tipd_A18, tipd_A19 => tipd_A19, tipd_A20 => tipd_A20, tipd_A21 => tipd_A21, tipd_DQ0 => tipd_DQ0, tipd_DQ1 => tipd_DQ1, tipd_DQ2 => tipd_DQ2, tipd_DQ3 => tipd_DQ3, tipd_DQ4 => tipd_DQ4, tipd_DQ5 => tipd_DQ5, tipd_DQ6 => tipd_DQ6, tipd_DQ7 => tipd_DQ7, tipd_DQ8 => tipd_DQ8, tipd_DQ9 => tipd_DQ9, tipd_DQ10 => tipd_DQ10, tipd_DQ11 => tipd_DQ11, tipd_DQ12 => tipd_DQ12, tipd_DQ13 => tipd_DQ13, tipd_DQ14 => tipd_DQ14, tipd_DQ15 => tipd_DQ15, tipd_CENeg => tipd_CENegf2, tipd_OENeg => tipd_OENeg, tipd_WENeg => tipd_WENeg, tipd_RESETNeg => tipd_RESETNeg, -- generic control parameters InstancePath => InstancePath, TimingChecksOn => TimingChecksOn, MsgOn => MsgOn, XOn => XOn, -- memory file to be loaded mem_file_name => mem_file_name, prot_file_name => prot_file_name, secsi_file_name => secsi_file_name, UserPreload => UserPreload, LongTimming => LongTimming ) PORT MAP( A21 => A21, A20 => A20, A19 => A19, A18 => A18, A17 => A17, A16 => A16, A15 => A15, A14 => A14, A13 => A13, A12 => A12, A11 => A11, A10 => A10, A9 => A9, A8 => A8, A7 => A7, A6 => A6, A5 => A5, A4 => A4, A3 => A3, A2 => A2, A1 => A1, A0 => A0, DQ15 => DQ15, DQ14 => DQ14, DQ13 => DQ13, DQ12 => DQ12, DQ11 => DQ11, DQ10 => DQ10, DQ9 => DQ9, DQ8 => DQ8, DQ7 => DQ7, DQ6 => DQ6, DQ5 => DQ5, DQ4 => DQ4, DQ3 => DQ3, DQ2 => DQ2, DQ1 => DQ1, DQ0 => DQ0, CENeg => CENegf2, OENeg => OENeg, WENeg => WENeg, RESETNeg => RESETNeg, RY => RY2 ); RY_Gen : PROCESS(RY1, RY2) BEGIN IF RY1 = '0' OR RY2 = '0' THEN RY <= '0'; ELSE RY <= 'Z'; END IF; END PROCESS; END vhdl_behavioral;