------------------------------------------------------------------------------- -- File name : am29lv2562m.vhd ------------------------------------------------------------------------------- -- Copyright (C) 2004-2005 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.Radmanovic 04 Oct 19 Initial release -- V1.1 M.Radmanovic 05 Apr 04 Changed variable cnt in ErsTime -- process -- V1.2 O.Jankovic 05 Aug 05 Dynamic memory allocation ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: FLASH -- Technology: Flash Memory -- Part: am29lv2562m -- -- Description: 512 Mbit(16Mb x 32-Bit/32Mb x 16-Bit) -- Uniform Sector Flash Memory -- ------------------------------------------------------------------------------- -- 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 am29lv2562m TOP MODULE ------------------------------------------------------------------------------- ENTITY am29lv2562m 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_A22 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A23 : 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_DQ16 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ17 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ18 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ19 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ20 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ21 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ22 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ23 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ24 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ25 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ26 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ27 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ28 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ29 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ30 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ31 : VitalDelayType01 := VitalZeroDelay01; -- tipd_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WORDNeg : VitalDelayType01 := VitalZeroDelay01; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- memory file to be loaded mem_file_name1 : STRING := "am29lv2562m.mem"; secsi_file_name1 : STRING := "am29lv2562m_secsi.mem"; mem_file_name2 : STRING := "am29lv2562m.mem"; prot_file_name : STRING := "am29lv2562m_prot.mem"; secsi_file_name2 : STRING := "am29lv2562m_secsi.mem"; UserPreload : BOOLEAN := TRUE; LongTimming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( A23 : IN std_ulogic := 'U'; -- A22 : IN std_ulogic := 'U'; -- 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'; -- DQ31 : INOUT std_ulogic := 'U'; -- DQ31/A-1 DQ30 : INOUT std_ulogic := 'U'; -- DQ29 : INOUT std_ulogic := 'U'; -- DQ28 : INOUT std_ulogic := 'U'; -- DQ27 : INOUT std_ulogic := 'U'; -- DQ26 : INOUT std_ulogic := 'U'; -- DQ25 : INOUT std_ulogic := 'U'; -- data DQ24 : INOUT std_ulogic := 'U'; -- lines DQ23 : INOUT std_ulogic := 'U'; -- DQ22 : INOUT std_ulogic := 'U'; -- DQ21 : INOUT std_ulogic := 'U'; -- DQ20 : INOUT std_ulogic := 'U'; -- DQ19 : INOUT std_ulogic := 'U'; -- DQ18 : INOUT std_ulogic := 'U'; -- DQ17 : INOUT std_ulogic := 'U'; -- DQ16 : INOUT 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'; -- data DQ8 : INOUT std_ulogic := 'U'; -- lines 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'; WPNeg : IN std_ulogic := 'U'; WORDNeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; RY : OUT std_logic := 'U' --RY/BY# ); ATTRIBUTE VITAL_LEVEL0 of am29lv2562m : ENTITY IS TRUE; END am29lv2562m; 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 ------------------------------------------------------------------------------- ENTITY am29lv2562m_flash 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_A22 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A23 : 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_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WORDNeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays tpd_RESETNeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; tpd_A0_DQ0_rdPage_eq_0 : VitalDelayType01 := UnitDelay01;--tACC tpd_A0_DQ0_rdPage_eq_1 : VitalDelayType01 := UnitDelay01;--tPACC tpd_CENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; --(tCE,tCE,tDF,-,tDF,-) tpd_OENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; --(tOE,tOE,tDF,-,tDF,-) tpd_WENeg_RY : VitalDelayType01Z := UnitDelay01Z;--tBUSY --tsetup values tsetup_A0_CENeg : VitalDelayType := UnitDelay; --tAS edge \ tsetup_A0_OENeg : VitalDelayType := UnitDelay; tsetup_DQ0_CENeg : VitalDelayType := UnitDelay; --tDS edge / tsetup_OENeg_WENeg : VitalDelayType := UnitDelay; --0,edge / tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; --0 ns / --thold values thold_A0_CENeg : VitalDelayType := UnitDelay; --tAH edge \ thold_DQ0_CENeg : VitalDelayType := UnitDelay; --tDH edge / thold_OENeg_WENeg : VitalDelayType := UnitDelay; --10,toeh,edge / thold_CENeg_WENeg : VitalDelayType := UnitDelay; --tGHVL edge / thold_CENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH edge / --tpw values: pulse width 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_A0_negedge : VitalDelayType := UnitDelay; --tWC tRC(90-70) -- tdevice values: values for internal delays --Effective Write Buffer Program Operation tWHWH1 tdevice_WBPB : VitalDelayType := 7500 ns; --Program Operation --word write tdevice_POW : VitalDelayType := 60 us; --unlock bypass write tdevice_POU : VitalDelayType := 54 us; --Sector Erase Operation tWHWH2 tdevice_SEO : VitalDelayType := 500 ms; --Timing Limit Exceeded tdevice_HANG : VitalDelayType := 2000 ms; --erase suspend timeout tdevice_STARTE : VitalDelayType := 20 us; --program suspend timeout tdevice_STARTP : VitalDelayType := 15 us; --sector erase command sequence timeout tdevice_CTMOUTP : VitalDelayType := 50 us; --device ready after Hardware reset(during embeded algorithm) tdevice_READYP : VitalDelayType := 20 us; --tReady -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- memory file to be loaded mem_file_name : STRING := "am29lv2562m.mem"; prot_file_name : STRING := "am29lv2562m_prot.mem"; secsi_file_name : STRING := "am29lv2562m_secsi.mem"; UserPreload : BOOLEAN := TRUE; LongTimming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( A23 : IN std_ulogic := 'U'; -- A22 : IN std_ulogic := 'U'; -- 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_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'; -- data DQ8 : INOUT std_ulogic := 'U'; -- lines 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'; WPNeg : IN std_ulogic := 'U'; WORDNeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U' --RY/BY# ); ATTRIBUTE VITAL_LEVEL0 of am29lv2562m_flash : ENTITY IS TRUE; END am29lv2562m_flash; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral_dynamic_flash of am29lv2562m_flash IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral_dynamic_flash : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "am29lv2562m"; CONSTANT MaxData : NATURAL := 16#FF#; CONSTANT SecSize : NATURAL := 16#FFFF#; --65535 bytes CONSTANT SecNum : NATURAL := 511; CONSTANT SecSiSize : NATURAL := 255; CONSTANT HiAddrBit : NATURAL := 23; -- interconnect path delay signals SIGNAL A23_ipd : std_ulogic := 'U'; SIGNAL A22_ipd : std_ulogic := 'U'; SIGNAL A21_ipd : std_ulogic := 'U'; SIGNAL A20_ipd : std_ulogic := 'U'; SIGNAL A19_ipd : std_ulogic := 'U'; SIGNAL A18_ipd : std_ulogic := 'U'; SIGNAL A17_ipd : std_ulogic := 'U'; SIGNAL A16_ipd : std_ulogic := 'U'; SIGNAL A15_ipd : std_ulogic := 'U'; SIGNAL A14_ipd : std_ulogic := 'U'; SIGNAL A13_ipd : std_ulogic := 'U'; SIGNAL A12_ipd : std_ulogic := 'U'; SIGNAL A11_ipd : std_ulogic := 'U'; SIGNAL A10_ipd : std_ulogic := 'U'; SIGNAL A9_ipd : std_ulogic := 'U'; SIGNAL A8_ipd : std_ulogic := 'U'; SIGNAL A7_ipd : std_ulogic := 'U'; SIGNAL A6_ipd : std_ulogic := 'U'; SIGNAL A5_ipd : std_ulogic := 'U'; SIGNAL A4_ipd : std_ulogic := 'U'; SIGNAL A3_ipd : std_ulogic := 'U'; SIGNAL A2_ipd : std_ulogic := 'U'; SIGNAL A1_ipd : std_ulogic := 'U'; SIGNAL A0_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 WORDNeg_ipd : std_ulogic := 'U'; SIGNAL WPNeg_ipd : std_ulogic := 'U'; --- internal delays SIGNAL WBPO_in : std_ulogic := '0'; SIGNAL WBPO_out : std_ulogic := '0'; SIGNAL POW_in : std_ulogic := '0'; SIGNAL POW_out : std_ulogic := '0'; SIGNAL POU_in : std_ulogic := '0'; SIGNAL POU_out : std_ulogic := '0'; SIGNAL SEO_in : std_ulogic := '0'; SIGNAL SEO_out : std_ulogic := '0'; SIGNAL HANG_out : std_ulogic := '0'; --Program/Erase Timing Limit SIGNAL HANG_in : std_ulogic := '0'; SIGNAL START_P : std_ulogic := '0'; --Start TimeOut; Program Suspend SIGNAL START_P_in : std_ulogic := '0'; SIGNAL START_E : std_ulogic := '0'; --Start TimeOut; Erase Suspend SIGNAL START_E_in : std_ulogic := '0'; SIGNAL CTMOUT : std_ulogic := '0'; --Sector Erase TimeOut SIGNAL CTMOUT_in : std_ulogic := '0'; SIGNAL READY_in : std_ulogic := '0'; SIGNAL READY : std_ulogic := '0'; -- Device ready after reset BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays WBPB :VitalBuf(WBPO_out,WBPO_in, (tdevice_WBPB ,UnitDelay)); POW :VitalBuf(POW_out, POW_in, (tdevice_POW ,UnitDelay)); POU :VitalBuf(POU_out, POU_in, (tdevice_POU ,UnitDelay)); SEO :VitalBuf(SEO_out, SEO_in, (tdevice_SEO ,UnitDelay)); HANG :VitalBuf(HANG_out,HANG_in, (tdevice_HANG ,UnitDelay)); STARTE :VitalBuf(START_E,START_E_in,(tdevice_STARTE ,UnitDelay)); STARTP :VitalBuf(START_P,START_P_in,(tdevice_STARTP ,UnitDelay)); CTMOUTP :VitalBuf(CTMOUT, CTMOUT_in, (tdevice_CTMOUTP - 5 ns,UnitDelay)); READYP :VitalBuf(READY, READY_in, (tdevice_READYP ,UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (A23_ipd, A23, tipd_A23); w_2 : VitalWireDelay (A22_ipd, A22, tipd_A22); w_3 : VitalWireDelay (A21_ipd, A21, tipd_A21); w_4 : VitalWireDelay (A20_ipd, A20, tipd_A20); w_5 : VitalWireDelay (A19_ipd, A19, tipd_A19); w_6 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_7 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_8 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_9 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_10 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_11 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_12 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_13 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_14 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_15 : VitalWireDelay (A9_ipd, A9, tipd_A9); w_16 : VitalWireDelay (A8_ipd, A8, tipd_A8); w_17 : VitalWireDelay (A7_ipd, A7, tipd_A7); w_18 : VitalWireDelay (A6_ipd, A6, tipd_A6); w_19 : VitalWireDelay (A5_ipd, A5, tipd_A5); w_20 : VitalWireDelay (A4_ipd, A4, tipd_A4); w_21 : VitalWireDelay (A3_ipd, A3, tipd_A3); w_22 : VitalWireDelay (A2_ipd, A2, tipd_A2); w_23 : VitalWireDelay (A1_ipd, A1, tipd_A1); w_24 : VitalWireDelay (A0_ipd, A0, tipd_A0); w_25 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_26 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_27 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_28 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_29 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_30 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_31 : VitalWireDelay (DQ9_ipd , DQ9 , tipd_DQ9); w_32 : VitalWireDelay (DQ8_ipd , DQ8 , tipd_DQ8); w_33 : VitalWireDelay (DQ7_ipd , DQ7 , tipd_DQ7); w_34 : VitalWireDelay (DQ6_ipd , DQ6 , tipd_DQ6); w_35 : VitalWireDelay (DQ5_ipd , DQ5 , tipd_DQ5); w_36 : VitalWireDelay (DQ4_ipd , DQ4 , tipd_DQ4); w_37 : VitalWireDelay (DQ3_ipd , DQ3 , tipd_DQ3); w_38 : VitalWireDelay (DQ2_ipd , DQ2 , tipd_DQ2); w_39 : VitalWireDelay (DQ1_ipd , DQ1 , tipd_DQ1); w_40 : VitalWireDelay (DQ0_ipd , DQ0 , tipd_DQ0); w_41 : VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg); w_42 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_43 : VitalWireDelay (RESETNeg_ipd, RESETNeg, tipd_RESETNeg); w_44 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); w_45 : VitalWireDelay (WORDNeg_ipd, WORDNeg, tipd_WORDNeg); w_46 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg); 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_ulogic_vector(15 downto 0) := (OTHERS => 'Z'); CENeg : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; WORDNeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U' ); PORT MAP ( A(23) => A23_ipd, A(22) => A22_ipd, 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, OENeg => OENeg_ipd, WENeg => WENeg_ipd, RESETNeg => RESETNeg_ipd, WORDNeg => WORDNeg_ipd, RY => RY , WPNeg => WPNeg_ipd ); -- State Machine : State_Type TYPE state_type IS ( RESET, Z001, PREL_SETBWB, PREL_ULBYPASS, ESP_ULBYPASS, PREL_ULBYPASS_RESET, ESP_ULBYPASS_RESET, CFI, -- CFI MOD AS, -- autoselect AS_CFI, -- CFI from autoselect A0SEEN, OTP, OTP_Z001, OTP_PREL, OTP_EXIT, OTP_A0SEEN, C8, C8_Z001, C8_PREL, ERS, SERS, ESPS, SERS_EXEC, ESP, ESP_SETBWB, PSP_SETBWB, ESP_Z001, PSP_Z001, ESP_A0SEEN, ESP_AS, PSP_AS, ESP_CFI, PSP_CFI, ESP_AS_CFI, PSP_AS_CFI, PGMS, PSPS, PSP, WBPGMS_WBCNT, WBPGMS_WBLSTA, WBPGMS_WBLOAD, WBPGMS_CONFB, WBPGMS_WBABORT, WBPGMS_Z001, WBPGMS_PREL ); --Flash Memory Array TYPE SecType IS ARRAY (0 TO SecSize) OF INTEGER RANGE -1 TO MaxData; TYPE MemArray IS ARRAY (0 TO SecNum) OF SecType; --SecSi Sector TYPE SecSiType IS ARRAY ( 0 TO SecSiSize) OF INTEGER RANGE -1 TO MaxData; --Common Flash Interface Query codes TYPE CFItype IS ARRAY (16#10# TO 16#50#) OF NATURAL; -- 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 DOut_Pass : std_logic_vector(15 downto 0):=(OTHERS=>'Z'); SIGNAL RY_zd : std_logic := 'Z'; --FSM control signals SIGNAL ULBYPASS : std_logic := '0'; --Unlock Bypass Active SIGNAL ESP_ACT : std_logic := '0'; --Erase Suspend SIGNAL PSP_ACT : std_logic := '0'; --Program Suspend SIGNAL OTP_ACT : std_logic := '0'; --SecSi access SIGNAL WB_ACT : std_logic := '0'; --Write to buffer access SHARED VARIABLE DOut_zd_var : std_logic_vector(15 downto 0) :=(OTHERS=>'Z'); SIGNAL LCNT : NATURAL RANGE 0 TO 31:= 0; --Load Counter --number of location to be writen in Write Buffer: 0-31 bytes. --if 32 word/byte programming SIGNAL PCNT : NATURAL RANGE 0 TO 32:= 0; --Model should never hang!!!!!!!!!!!!!!! SIGNAL HANG : std_logic := '0'; 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 ERES : std_logic := '0'; --Resume Erase SIGNAL PSUSP : std_logic := '0'; --Suspend Program SIGNAL PRES : std_logic := '0'; --Resume Program --All sectors selected for erasure are protected SIGNAL EERR : std_logic := '0'; --Sectors selected for erasure SIGNAL ERS_QUEUE : std_logic_vector(SecNum downto 0) := (OTHERS => '0'); --Command Register SIGNAL write : std_logic := '0'; SIGNAL read : std_logic := '0'; SHARED VARIABLE wr_cnt : INTEGER; -- Access time variables SHARED VARIABLE OPENLATCH : BOOLEAN; SHARED VARIABLE FROMCE : BOOLEAN; SHARED VARIABLE FROMOE : BOOLEAN; SHARED VARIABLE page_read : BOOLEAN; SHARED VARIABLE Corrupt_Sec : std_logic_vector(SecNum downto 0) := (OTHERS => '0'); SHARED VARIABLE RData : INTEGER; -- --------------------------------------------------------------------- -- Data types required to implement link list structure -- --------------------------------------------------------------------- TYPE mem_data_t; TYPE mem_data_pointer_t IS ACCESS mem_data_t; TYPE mem_data_t IS RECORD key_address : INTEGER; val_data : INTEGER; successor : mem_data_pointer_t; END RECORD; -- --------------------------------------------------------------------- -- Array of linked lists. -- Support memory region partitioning for faster access. -- --------------------------------------------------------------------- TYPE mem_data_pointer_array_t IS ARRAY(NATURAL RANGE <>) OF mem_data_pointer_t; -- Access dynamically allocated space SHARED VARIABLE linked_list : mem_data_pointer_array_t(0 TO SecNum) := (OTHERS => null); -- --------------------------------------------------------------------- -- -- Function Name: erase_mem -- -- Description: erase_mem is used to perform memory data ERASE -- operation above memory block or memory page region. -- -- Routine is built-in addressing performance -- parameters. -- Routine performs N successive erase operations. -- For N successive erase operations instead of : -- N x find + N x erase --> -- erase_mem provides the posiibility of : -- 1 x find + N x iterate + N x erase -- Reducing the number of find element calls, operation -- execution time is significantly affected. -- -- [address_low, adress_high] must belong to the same -- memory parition, handled by a single list. -- -- Arguments: -- -- IN Type Description -- address_low integer Starting address of the -- memory -- region to be erased. -- address_high integer The last address of the -- memory -- region to be erased. -- -- INOUT -- linked_list mem_data_pointer_t Linked list holding memory -- region -- to be erased. -- -- OUT -- none -- -- Returns -- none -- -- --------------------------------------------------------------------- PROCEDURE erase_mem( address_low : IN INTEGER; address_high : IN INTEGER; linked_list : INOUT mem_data_pointer_t); -- --------------------------------------------------------------------- -- -- Function Name: read_mem -- -- Description: Memory READ operation performed above dynamically -- allocated space. -- -- Iterates through a linked list data structure -- holding -- memory data. Performs a search for an address match. -- -- If matched successfully, data kept by a linked list -- element will be returned. -- -- In case no match occurred, no allocation has been -- performed for the search address. -- Memory data is never written, set to initial value. -- Initial data value returned. -- -- Arguments: -- -- IN Type Description -- address integer Data address to be read. -- -- INOUT -- linked_list mem_data_pointer_t Linked list holding memory -- region -- to be read. Depends on DUT -- specific partition scheme. -- data integer Read operation result. -- -- OUT -- none -- -- Returns -- none -- -- --------------------------------------------------------------------- PROCEDURE read_mem( linked_list : INOUT mem_data_pointer_t; data : INOUT INTEGER; address : IN INTEGER); -- --------------------------------------------------------------------- -- -- Function Name: write_mem -- -- Description: Memory WRITE operation performed above dynamically -- allocated space. -- -- Iterates through a linked list data structure -- holding -- memory data. Performs a search for an address match. -- -- If matched successfully, data kept by a linked list -- element will be aligned with data argument value. -- -- In case no match occurred, no allocation has been -- performed for the search address. -- Memory space for a new element is allocated, linked -- into a list and set to data argument value. -- -- If data argument value is recognized as initial, -- memory space will be de-allocated for the addressed -- location. -- -- Arguments: -- -- IN Type Description -- address integer Address to be written. -- data integer Data to be written. -- -- INOUT -- linked_list mem_data_pointer_t Linked list holding memory -- region -- to be written. Depends on DUT -- specific partition scheme. -- -- OUT -- none -- -- Returns -- none -- -- --------------------------------------------------------------------- PROCEDURE write_mem( linked_list : INOUT mem_data_pointer_t; address : IN INTEGER; data : IN INTEGER); -- --------------------------------------------------------------------- -- Create linked listed -- --------------------------------------------------------------------- PROCEDURE create_list( key_address : IN INTEGER; val_data : IN INTEGER; root : INOUT mem_data_pointer_t) IS BEGIN root := NEW mem_data_t; root.successor := NULL; root.key_address := key_address; root.val_data := val_data; END PROCEDURE create_list; -- --------------------------------------------------------------------- -- Iterate through linked listed comapring key values -- Stop when key value greater or equal -- --------------------------------------------------------------------- PROCEDURE position_list( key_address : IN INTEGER; root : INOUT mem_data_pointer_t; found : INOUT mem_data_pointer_t; prev : INOUT mem_data_pointer_t) IS BEGIN found := root; prev := NULL; WHILE ((found /= NULL) AND (found.key_address < key_address)) LOOP prev := found; found := found.successor; END LOOP; END PROCEDURE position_list; -- --------------------------------------------------------------------- -- Add new element to a linked list -- --------------------------------------------------------------------- PROCEDURE insert_list( key_address : IN INTEGER; val_data : IN INTEGER; root : INOUT mem_data_pointer_t) IS VARIABLE new_element : mem_data_pointer_t; VARIABLE found : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; BEGIN position_list(key_address, root, found, prev); -- Insert at list tail IF (found = NULL) THEN prev.successor := NEW mem_data_t; prev.successor.key_address := key_address; prev.successor.val_data := val_data; prev.successor.successor := NULL; ELSE -- Element exists, update memory data value IF (found.key_address = key_address) THEN found.val_data := val_data; ELSE -- No element found, allocate and link new_element := NEW mem_data_t; new_element.key_address := key_address; new_element.val_data := val_data; new_element.successor := found; -- Possible root position IF (prev /= NULL) THEN prev.successor := new_element; ELSE root := new_element; END IF; END IF; END IF; END PROCEDURE insert_list; -- --------------------------------------------------------------------- -- Remove element from a linked list -- --------------------------------------------------------------------- PROCEDURE remove_list( key_address : IN INTEGER; root : INOUT mem_data_pointer_t) IS VARIABLE found : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; BEGIN position_list(key_address, root, found, prev); IF (found /= NULL) THEN -- Key value match IF (found.key_address = key_address) THEN -- Handle root position removal IF (prev /= NULL) THEN prev.successor := found.successor; ELSE root := found.successor; END IF; DEALLOCATE(found); END IF; END IF; END PROCEDURE remove_list; -- --------------------------------------------------------------------- -- Remove range of elements from a linked list -- Higher performance than one-by-one removal -- --------------------------------------------------------------------- PROCEDURE remove_list_range( address_low : IN INTEGER; address_high : IN INTEGER; root : INOUT mem_data_pointer_t) IS VARIABLE iter : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; VARIABLE link_element : mem_data_pointer_t; BEGIN iter := root; prev := NULL; -- Find first linked list element belonging to -- a specified address range [address_low, address_high] WHILE ((iter /= NULL) AND NOT ( (iter.key_address >= address_low) AND (iter.key_address <= address_high))) LOOP prev := iter; iter := iter.successor; END LOOP; -- Continue until address_high reached -- Deallocate linked list elements pointed by iterator IF (iter /= NULL) THEN WHILE ((iter /= NULL) AND (iter.key_address >= address_low) AND (iter.key_address <= address_high)) LOOP link_element := iter.successor; DEALLOCATE(iter); iter := link_element; END LOOP; -- Handle possible root value change IF prev /= NULL THEN prev.successor := link_element; ELSE root := link_element; END IF; END IF; END PROCEDURE remove_list_range; -- --------------------------------------------------------------------- -- Address range to be erased -- --------------------------------------------------------------------- PROCEDURE erase_mem( address_low : IN INTEGER; address_high : IN INTEGER; linked_list : INOUT mem_data_pointer_t) IS BEGIN remove_list_range( address_low, address_high, linked_list ); END PROCEDURE erase_mem; -- --------------------------------------------------------------------- -- Memory READ operation performed above dynamically allocated space -- --------------------------------------------------------------------- PROCEDURE read_mem( linked_list : INOUT mem_data_pointer_t; data : INOUT INTEGER; address : IN INTEGER) IS VARIABLE found : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; VARIABLE mem_data : INTEGER; BEGIN IF (linked_list = NULL) THEN -- Not allocated, not written, initial value mem_data := MaxData ; ELSE position_list(address, linked_list, found, prev); IF (found /= NULL) THEN IF found.key_address = address THEN -- Allocated, val_data stored mem_data := found.val_data; ELSE -- Not allocated, not written, initial value mem_data := MaxData ; END IF; ELSE -- Not allocated, not written, initial value mem_data := MaxData ; END IF; END IF; data := mem_data; END PROCEDURE read_mem; -- --------------------------------------------------------------------- -- Memory WRITE operation performed above dynamically allocated space -- --------------------------------------------------------------------- PROCEDURE write_mem( linked_list : INOUT mem_data_pointer_t; address : IN INTEGER; data : IN INTEGER) IS BEGIN IF (data /= MaxData ) THEN -- Handle possible root value update IF (linked_list /= NULL) THEN insert_list(address, data, linked_list); ELSE create_list(address, data, linked_list); END IF; ELSE -- Deallocate if initial value written -- No linked list, NOP, initial value implicit IF (linked_list /= NULL) THEN remove_list(address, linked_list); END IF; END IF; END PROCEDURE write_mem; PROCEDURE READ_DATA( sectoraddr : IN NATURAL RANGE 0 TO Secnum; addressinsec : IN NATURAL RANGE 0 TO Secsize; ReadData : INOUT INTEGER) IS BEGIN read_mem(linked_list(sectoraddr), ReadData, addressinsec ); IF (ReadData = MaxData AND Corrupt_Sec(sectoraddr) = '1') THEN ReadData := -1; ELSIF (ReadData = MaxData+1) AND Corrupt_Sec(sectoraddr) = '1' THEN ReadData := MaxData; END IF; END READ_DATA; PROCEDURE WRITE_DATA( sectoraddr : IN NATURAL RANGE 0 TO Secnum; addressinsec : IN NATURAL RANGE 0 TO Secsize; WriteData : IN INTEGER) IS BEGIN IF (WriteData = MaxData AND Corrupt_Sec(sectoraddr) = '1') THEN write_mem(linked_list(sectoraddr), addressinsec, WriteData+1 ); ELSE write_mem(linked_list(sectoraddr), addressinsec, WriteData ); END IF; END WRITE_DATA; FUNCTION READMEM_RESET(Data : INTEGER RANGE -1 TO MaxData) RETURN STD_LOGIC_VECTOR IS VARIABLE ReadData : STD_LOGIC_VECTOR(15 downto 0); BEGIN IF Data = -1 THEN ReadData := (OTHERS=>'X'); ELSE ReadData := to_slv(Data,16); END IF; RETURN ReadData; END READMEM_RESET; --Sector Address SIGNAL SecAddr : NATURAL RANGE 0 TO SecNum := 0; SIGNAL SA : NATURAL RANGE 0 TO SecNum := 0; SIGNAL WBPage : NATURAL; --Address within sector SIGNAL Address : NATURAL RANGE 0 TO SecSize := 0; SIGNAL SubAddr : NATURAL RANGE 0 TO SecSize := 0; SHARED VARIABLE CFI_array : CFItype := (OTHERS => 0); SIGNAL D_tmp0 : NATURAL RANGE 0 TO MaxData; SIGNAL D_tmp1 : NATURAL RANGE 0 TO MaxData; --A23:A11 Don't Care SIGNAL Addr : NATURAL RANGE 0 TO 16#7FFF# := 0; SIGNAL WPage : NATURAL RANGE 0 TO 16#7FFF# := 0; --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 Sec_Prot : std_logic_vector(511 downto 0) := (OTHERS => '0'); SHARED VARIABLE SecSi : SecSiType := (OTHERS => 0); --SecSi ProtectionStatus SIGNAL FactoryProt : std_logic := '1'; -- Addresses of the Protected Sector SIGNAL ProtSecNum : INTEGER := -1; SIGNAL ProtSec : INTEGER := -1; -- timing check violation SIGNAL Viol : X01 := '0'; PROCEDURE generate_out ( DOut_zd : OUT std_logic_vector(15 downto 0); SecAddr : IN NATURAL; WORDNeg : IN std_logic; SecSi_acc : IN NATURAL; Address : IN NATURAL ) IS BEGIN IF SecSi_acc = 0 THEN READ_DATA(SecAddr,Address,RData); IF RData = -1 THEN DOut_zd(7 downto 0) := (OTHERS=>'X'); ELSE DOut_zd(7 downto 0) := to_slv(RData,8); END IF; IF WORDNeg = '1' THEN READ_DATA(SecAddr,Address+1,RData); IF RData = -1 THEN DOut_zd(15 downto 8) := (OTHERS=>'X'); ELSE DOut_zd(15 downto 8):=to_slv(RData,8); END IF; END IF; ELSE DOut_zd(7 downto 0) := (OTHERS=>'X'); IF SecSi(Address)/=-1 THEN DOut_zd(7 downto 0) := to_slv(SecSi(Address),8); END IF; IF WORDNeg='1' THEN DOut_zd(15 downto 8) := (OTHERS=>'X'); IF SecSi(Address) /= -1 THEN DOut_zd(15 downto 8) := to_slv(SecSi(Address+1),8); END IF; END IF; END IF; END PROCEDURE generate_out; BEGIN --------------------------------------------------------------------------- --protected sector --------------------------------------------------------------------------- ProtSecNum <= SecNum WHEN TimingModel(12)= 'H' OR TimingModel(12)= 'h' ELSE 0 ; ProtSec <= 1 WHEN TimingModel(12)= 'H' OR TimingModel(12)= 'h' ELSE 0 ; PoweredUp <= '1' AFTER 100 ns; RST <= RESETNeg AFTER 500 ns; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(WORDNeg, A, Din, CENeg, OENeg, WENeg, RESETNeg) -- Timing Check Variables VARIABLE Tviol_A0_CENeg : X01 := '0'; VARIABLE TD_A0_CENeg : VitalTimingDataType; VARIABLE Tviol_A0_WENeg : X01 := '0'; VARIABLE TD_A0_WENeg : VitalTimingDataType; VARIABLE Tviol_A0_OENeg : X01 := '0'; VARIABLE TD_A0_OENeg : VitalTimingDataType; VARIABLE Tviol_DQ0_CENeg : X01 := '0'; VARIABLE TD_DQ0_CENeg : VitalTimingDataType; VARIABLE Tviol_DQ0_WENeg : X01 := '0'; VARIABLE TD_DQ0_WENeg : VitalTimingDataType; VARIABLE Tviol_CENeg_RESETNeg : X01 := '0'; VARIABLE TD_CENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_OENeg_RESETNeg : X01 := '0'; VARIABLE TD_OENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_WENeg_RESETNeg : X01 := '0'; VARIABLE TD_WENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_F : X01 := '0'; VARIABLE TD_CENeg_WENeg_F : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_R : X01 := '0'; VARIABLE TD_CENeg_WENeg_R : VitalTimingDataType; VARIABLE Tviol_OENeg_WENeg_F : X01 := '0'; VARIABLE TD_OENeg_WENeg_F : VitalTimingDataType; VARIABLE Tviol_OENeg_WENeg_R : X01 := '0'; VARIABLE TD_OENeg_WENeg_R : VitalTimingDataType; VARIABLE Tviol_WENeg_CENeg_F : X01 := '0'; VARIABLE TD_WENeg_CENeg_F : VitalTimingDataType; VARIABLE Tviol_WENeg_CENeg_R : X01 := '0'; VARIABLE TD_WENeg_CENeg_R : VitalTimingDataType; VARIABLE Tviol_CENeg_OENeg : X01 := '0'; VARIABLE TD_CENeg_OENeg : VitalTimingDataType; VARIABLE Tviol_WORDNeg_CENeg : X01 := '0'; VARIABLE TD_WORDNeg_CENeg : VitalTimingDataType; VARIABLE Pviol_RESETNeg : X01 := '0'; VARIABLE PD_RESETNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CENeg : X01 := '0'; VARIABLE PD_CENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_WENeg : X01 := '0'; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A0 : X01 := '0'; VARIABLE PD_A0 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01 := '0'; BEGIN --------------------------------------------------------------------------- -- Timing Check Section --------------------------------------------------------------------------- IF (TimingChecksOn) THEN -- Setup/Hold Check between A and CENeg VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CENeg, RefSignalName => "CE#", SetupHigh => tsetup_A0_CENeg, SetupLow => tsetup_A0_CENeg, HoldHigh => thold_A0_CENeg, HoldLow => thold_A0_CENeg, CheckEnabled => WENeg = '0' AND OENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_CENeg, Violation => Tviol_A0_CENeg ); -- Setup/Hold Check between A and WENeg VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_A0_CENeg, SetupLow => tsetup_A0_CENeg, HoldHigh => thold_A0_CENeg, HoldLow => thold_A0_CENeg, CheckEnabled => CENeg = '0' AND OENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_WENeg, Violation => Tviol_A0_WENeg ); -- Setup Check between A and OENeg VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => OENeg, RefSignalName => "OE#", SetupHigh => tsetup_A0_OENeg, SetupLow => tsetup_A0_OENeg, CheckEnabled => CENeg = '0' AND WENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_OENeg, Violation => Tviol_A0_OENeg ); -- Setup/Hold Check between DQ and CENeg VitalSetupHoldCheck ( TestSignal => DQ0, TestSignalName => "DQ", RefSignal => CENeg, RefSignalName => "CE#", SetupHigh => tsetup_DQ0_CENeg, SetupLow => tsetup_DQ0_CENeg, HoldHigh => thold_DQ0_CENeg, HoldLow => thold_DQ0_CENeg, CheckEnabled => WENeg = '0' AND OENeg = '1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_DQ0_CENeg, Violation => Tviol_DQ0_CENeg ); -- Setup/Hold Check between DQ and WENeg VitalSetupHoldCheck ( TestSignal => DQ0, TestSignalName => "DQ", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_DQ0_CENeg, SetupLow => tsetup_DQ0_CENeg, HoldHigh => thold_DQ0_CENeg, HoldLow => thold_DQ0_CENeg, CheckEnabled => CENeg = '0' AND OENeg = '1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_DQ0_WENeg, Violation => Tviol_DQ0_WENeg ); -- Hold Check between CENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_RESETNeg, Violation => Tviol_CENeg_RESETNeg ); -- Hold Check between OENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_RESETNeg, Violation => Tviol_OENeg_RESETNeg ); -- Hold Check between WENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_RESETNeg, Violation => Tviol_WENeg_RESETNeg ); -- Hold Check between OENeg and WENeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => WENeg, RefSignalName => "WE#", HoldHigh => thold_OENeg_WENeg, CheckEnabled => PDONE = '0' OR EDONE = '0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_WENeg_R, Violation => Tviol_OENeg_WENeg_R ); -- Hold Check between OENeg and WENeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_OENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_WENeg_F, Violation => Tviol_OENeg_WENeg_F ); -- Hold Check between CENeg and OENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => OENeg, RefSignalName => "OE#", HoldHigh => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_OENeg, Violation => Tviol_CENeg_OENeg ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => CENeg, RefSignalName => "CE#", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CENeg_F, Violation => Tviol_WENeg_CENeg_F ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => CENeg, RefSignalName => "CE#", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CENeg_R, Violation => Tviol_WENeg_CENeg_R ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_F, Violation => Tviol_CENeg_WENeg_F ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_R, Violation => Tviol_CENeg_WENeg_R ); -- PulseWidth Check for RESETNeg VitalPeriodPulseCheck ( TestSignal => RESETNeg, TestSignalName => "RESET#", PulseWidthLow => tpw_RESETNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RESETNeg, Violation => Pviol_RESETNeg ); -- PulseWidth Check for WENeg VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WE#", PulseWidthHigh => tpw_WENeg_posedge, PulseWidthLow => tpw_WENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, Violation => Pviol_WENeg ); -- PulseWidth Check for CENeg VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CE#", PulseWidthHigh => tpw_CENeg_posedge, PulseWidthLow => tpw_CENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg, Violation => Pviol_CENeg ); -- PulseWidth Check for A VitalPeriodPulseCheck ( TestSignal => A(0), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A0, Violation => Pviol_A0 ); Violation := Tviol_A0_CENeg OR Tviol_A0_WENeg OR Tviol_A0_OENeg OR Tviol_WORDNeg_CENeg OR Tviol_DQ0_CENeg OR Tviol_DQ0_WENeg OR Tviol_CENeg_RESETNeg OR Tviol_OENeg_RESETNeg OR Tviol_WENeg_RESETNeg OR Tviol_OENeg_WENeg_F OR Tviol_OENeg_WENeg_R OR Tviol_WORDNeg_CENeg OR Tviol_CENeg_OENeg OR Tviol_WENeg_CENeg_F OR Tviol_WENeg_CENeg_R OR Tviol_CENeg_WENeg_F OR Tviol_CENeg_WENeg_R OR Pviol_RESETNeg OR Pviol_WENeg OR Pviol_CENeg OR Pviol_A0 ; Viol <= Violation; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY WARNING; END IF; END PROCESS VITALTimingCheck; ---------------------------------------------------------------------------- -- sequential process for reset control and FSM state transition ---------------------------------------------------------------------------- StateTransition : PROCESS(next_state, RESETNeg, RST, READY, 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='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='0')OR (R='1' AND RESETNeg='1' AND RST='0' AND READY='0')OR (R='1' AND RESETNeg='1' AND RST='1' AND READY='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 <= 'X'; END IF; END IF; IF ((gWE_n = '1') AND (gCE_n = '0') AND (gOE_n = '0') )THEN read <= '1'; 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)) THEN ASSERT false REPORT "Glitch detected on WE# control signals" SEVERITY warning; END IF; IF (CENeg'EVENT AND (CENeg = gCE_n)) THEN ASSERT false REPORT "Glitch detected on CE# control signals" SEVERITY warning; END IF; IF (OENeg'EVENT AND (OENeg = gOE_n)) THEN ASSERT false REPORT "Glitch detected on OE# 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, read, WORDNeg) VARIABLE A_tmp : NATURAL RANGE 0 TO 16#7FF#; VARIABLE A_tmp2 : NATURAL RANGE 0 TO SecSize; VARIABLE SA_tmp : NATURAL RANGE 0 TO SecNum; VARIABLE A_tmp1 : NATURAL RANGE 0 TO SecSize; VARIABLE i : NATURAL; 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 OR (Din(15)'EVENT AND WORDNeg='0') OR WORDNeg'EVENT) OR ( A'EVENT AND WENeg = '1' AND CENeg = '0' AND OENeg = '0') THEN A_tmp := to_nat( A(10 downto 0) ); A_tmp2 := to_nat( A(8 downto 0) ); SA_tmp := to_nat( A(HiAddrBit downto 15)); IF (WORDNeg = '0') THEN IF Din(15) = '1' THEN A_tmp1 := to_nat( A(14 downto 0) & '1' ); ELSE A_tmp1 := to_nat( A(14 downto 0) & '0' ); END IF; ELSE A_tmp1 := to_nat( A(14 downto 0) & '0' ); END IF; ELSIF (rising_edge(WENeg) OR rising_edge(CENeg)) AND write = '1' THEN D_tmp0 <= to_nat(Din(7 downto 0)); IF WORDNeg = '1' THEN D_tmp1 <= to_nat(Din(15 downto 8)); END IF; END IF; IF rising_edge(write) OR falling_edge(OENeg) OR falling_edge(CENeg) OR ((A'EVENT OR (Din(15)'EVENT AND WORDNeg = '0') OR WORDNeg'EVENT) AND WENeg = '1' AND CENeg = '0' AND OENeg = '0') THEN SecAddr <= SA_tmp; Address <= A_tmp1; WPage <= A_tmp1 / 32; SubAddr <=A_tmp2; Addr <= A_tmp; END IF; END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- Timing control for the Program Operations --------------------------------------------------------------------------- ProgTime :PROCESS(OTP_ACT,PSTART, ESP_ACT, PSUSP, PRES, reseted) VARIABLE cnt : NATURAL RANGE 0 TO SecNum + 1 := 0; VARIABLE duration : time; VARIABLE elapsed : time; VARIABLE pow, pou, wbpb : time; VARIABLE start : time; BEGIN pow := tdevice_POW / 2; pou := tdevice_POU / 2; wbpb := tdevice_WBPB /2; IF LongTimming THEN pow := tdevice_POW; pou := tdevice_POU; wbpb := tdevice_WBPB; 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' OR ESP_ACT = '0')) AND (OTP_ACT = '0')) OR (FactoryProt = '0' AND OTP_ACT = '1')THEN IF PCNT < 32 THEN --buffer IF WORDNeg = '1' THEN cnt := PCNT + 2; ELSE cnt := PCNT + 1; END IF; duration := cnt * wbpb; ELSE IF ULBYPASS = '1' THEN duration := pou;--tdevice_POU; ELSE duration := pow;--tdevice_POW; END IF; END IF; elapsed := 0 ns; start := NOW; PDONE <= '0', '1' AFTER duration; ELSE PERR <= '1', '0' AFTER 1 us; END IF; END IF; IF rising_edge(PSUSP) AND PDONE = '0' THEN elapsed := NOW - start; duration := duration - elapsed; PDONE <= '0'; ELSIF rising_edge(PRES) AND PDONE = '0' THEN start := NOW; PDONE <= '0', '1' AFTER duration; END IF; END IF; END PROCESS ProgTime; --------------------------------------------------------------------------- -- Timing control for the Erase Operations --------------------------------------------------------------------------- ErsTime :PROCESS(ESTART, ESUSP, ERES, Ers_Queue, reseted) VARIABLE cnt : NATURAL RANGE 0 TO SecNum + 1 := 0; VARIABLE elapsed : time; VARIABLE duration : time; VARIABLE start : time; VARIABLE seo : time; BEGIN seo := tdevice_SEO/1000; IF LongTimming THEN seo := tdevice_SEO; END IF; IF rising_edge(reseted) THEN EDONE <= '1'; -- reset done, ERASE terminated ELSIF reseted = '1' THEN IF rising_edge(ESTART) AND EDONE = '1' THEN cnt := 0; FOR i IN Ers_Queue'RANGE LOOP IF Ers_Queue(i) = '1' AND Sec_Prot(i) /= '1' 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; ELSIF rising_edge(ESUSP) 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, Addr, D_tmp0,D_tmp1, ULBYPASS, PDONE, EDONE, HANG, CTMOUT, SecAddr, START_P, START_E, reseted, READY, PERR, EERR) VARIABLE PATTERN_1 : boolean := FALSE; VARIABLE PATTERN_2 : boolean := FALSE; VARIABLE A_PAT_1 : boolean := FALSE; --DATA High WORD VARIABLE DataHi : NATURAL RANGE 0 TO MaxData := 0; --DATA Low WORD 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#) AND (ULBYPASS = '0')) OR (ULBYPASS = '1'); 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 CFI => IF falling_edge(write) THEN IF (DataLo=16#F0#) THEN next_state <= RESET; ELSE next_state <= CFI; END IF; END IF; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#20#)) THEN next_state <= PREL_ULBYPASS; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN next_state <= AS; ELSIF (A_PAT_1 AND (DataLo = 16#A0#)) THEN next_state <= A0SEEN; ELSIF (A_PAT_1 AND (DataLo = 16#80#)) THEN next_state <= C8; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN next_state <= OTP; ELSIF DataLo = 16#25# THEN next_state <= WBPGMS_WBCNT; ELSE next_state <= RESET; END IF; END IF; WHEN WBPGMS_WBCNT => IF falling_edge(write) THEN IF (SecAddr = SA) AND ((WORDNeg = '0'AND DataLo < 32) OR (WORDNeg = '1'AND DataLo < 16)) THEN next_state <= WBPGMS_WBLSTA; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_WBLSTA => IF falling_edge(write) THEN IF (SecAddr = SA) THEN IF (LCNT > 0) THEN next_state <= WBPGMS_WBLOAD; ELSE next_state <= WBPGMS_CONFB; END IF; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_WBLOAD => IF falling_edge(write) THEN IF (WPage = WBPage) THEN IF (LCNT > 0) THEN next_state <= WBPGMS_WBLOAD; ELSE next_state <= WBPGMS_CONFB; END IF; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_CONFB => IF falling_edge(write) THEN IF (SecAddr = SA) AND (DataLo = 16#29#) THEN next_state <= PGMS; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_WBABORT => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= WBPGMS_Z001; END IF; END IF; WHEN WBPGMS_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= WBPGMS_PREL; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_PREL => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN IF ESP_ACT ='1' THEN next_state <= ESP; ELSIF OTP_ACT ='1' THEN next_state <= OTP; ELSE next_state <= RESET; END IF; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN PREL_ULBYPASS => IF falling_edge(write) THEN IF (DataLo = 16#90#) THEN next_state <= PREL_ULBYPASS_RESET; ELSIF (A_PAT_1 AND (DataLo = 16#A0#)) THEN next_state <= A0SEEN; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; WHEN PREL_ULBYPASS_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; ELSE next_state <= AS; END IF; END IF; WHEN AS_CFI => IF falling_edge(write) THEN IF (DataLo=16#F0#) THEN next_state <= AS; ELSE next_state <= AS_CFI; END IF; END IF; WHEN A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; ELSE next_state <= A0SEEN; END IF; WHEN OTP => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= OTP_Z001; ELSE 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# AND PSP_ACT /= '1')THEN next_state <= OTP_A0SEEN; ELSIF DataLo = 16#25# THEN next_state <= WBPGMS_WBCNT; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_EXIT => IF falling_edge(write) THEN IF DataLo=16#00# THEN IF PSP_ACT = '1' THEN next_state <= PSP; ELSIF ESP_ACT = '1' THEN next_state <= ESP; ELSE next_state <= RESET; END IF; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; 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 = '1' THEN next_state <= SERS_EXEC; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN next_state <= ESP; ELSIF (DataLo = 16#30#) THEN next_state <= SERS; ELSE next_state <= RESET; END IF; END IF; WHEN ESPS => IF (START_E = '1') THEN next_state <= ESP; END IF; WHEN PSPS => IF (START_P = '1') THEN next_state <= PSP; 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 ESP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN next_state <= SERS_EXEC; ELSE IF PATTERN_1 THEN next_state <= ESP_Z001; ELSIF Addr = 16#55# AND DataLo = 16#98# THEN next_state <= ESP_CFI; END IF; END IF; END IF; WHEN PSP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN next_state <= PGMS; ELSE IF PATTERN_1 THEN next_state <= PSP_Z001; ELSIF Addr = 16#55# AND DataLo = 16#98# THEN next_state <= PSP_CFI; END IF; END IF; 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 ESP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= ESP_SETBWB; ELSE next_state <= ESP; END IF; END IF; WHEN PSP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= PSP_SETBWB; ELSE next_state <= PSP; END IF; END IF; WHEN ESP_SETBWB => IF falling_edge(write) THEN IF A_PAT_1 AND DataLo = 16#A0# THEN next_state <= ESP_A0SEEN; ELSIF A_PAT_1 AND DataLo = 16#90# THEN next_state <= ESP_AS; ELSIF (A_PAT_1 AND DataLo = 16#20#) THEN next_state <= ESP_ULBYPASS; ELSIF DataLo = 16#25# THEN next_state <= WBPGMS_WBCNT; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN next_state <= OTP; ELSE next_state <= ESP; END IF; END IF; WHEN PSP_SETBWB => IF falling_edge(write) THEN IF A_PAT_1 AND DataLo = 16#90# THEN next_state <= PSP_AS; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN next_state <= OTP; ELSE next_state <= PSP; 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 PSP_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= PSP; END IF; END IF; WHEN ESP_A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; 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; END IF; END IF; WHEN PSP_AS => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= PSP; ELSIF ((Addr=16#55#) AND (DataLo=16#98#)) THEN next_state <= PSP_AS_CFI; END IF; END IF; WHEN ESP_AS_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= ESP_AS; END IF; END IF; WHEN PSP_AS_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= PSP_AS; 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; ELSE IF OTP_ACT = '1' THEN next_state <= OTP; ELSE next_state <= ESP; END IF; END IF; ELSIF ULBYPASS = '1' THEN next_state <= PREL_ULBYPASS; ELSIF OTP_ACT = '1' THEN next_state <= OTP; ELSE next_state <= RESET; END IF; ELSIF falling_edge(write) THEN IF DataLo = 16#B0# AND OTP_ACT /= '1' AND ERS_QUEUE(SecAddr) /= '1' THEN next_state <= PSPS; END IF; END IF; END CASE; END IF; END PROCESS StateGen; WP_CTRL: PROCESS(WPNeg) VARIABLE Sec_Prot_reg : std_logic := '0'; BEGIN --Hardware Write Protection IF falling_edge(WPNeg) THEN Sec_Prot_reg := Sec_Prot(ProtSecNum); Sec_Prot(ProtSecNum) := '1'; ELSIF rising_edge(WPNeg) THEN Sec_Prot(ProtSecNum) := Sec_Prot_reg; END IF; END PROCESS WP_CTRL; --------------------------------------------------------------------------- --FSM Output generation and general funcionality --------------------------------------------------------------------------- Functional : PROCESS(write, read, Addr, D_tmp0,D_tmp1, Address, SecAddr, PDONE, EDONE, HANG, START_E, START_P, CTMOUT, RST, reseted, WORDNeg, READY, gOE_n, current_state) --WriteBuffer TYPE WBDataType IS ARRAY ( 0 TO 31) OF INTEGER RANGE -1 TO MaxData; TYPE WBAddrType IS ARRAY ( 0 TO 31) OF INTEGER RANGE -1 TO 31; VARIABLE WBData : WBDataType:=(OTHERS=>0); VARIABLE WBAddr : WBAddrType:=(OTHERS=>-1); VARIABLE BaseLoc : NATURAL RANGE 0 TO SecSize := 0; VARIABLE cnt : NATURAL RANGE 0 TO 31 := 0; VARIABLE PATTERN_1 : boolean := FALSE; VARIABLE PATTERN_2 : boolean := FALSE; VARIABLE A_PAT_1 : boolean := FALSE; VARIABLE oe : boolean := FALSE; --Status reg. VARIABLE Status : std_logic_vector(7 downto 0) := (OTHERS=>'0'); VARIABLE old_bit : std_logic_vector(7 downto 0); VARIABLE new_bit : std_logic_vector(7 downto 0); VARIABLE old_int : INTEGER RANGE -1 to MaxData; VARIABLE new_int : INTEGER RANGE -1 to MaxData; --DATA High WORD VARIABLE DataHi : NATURAL RANGE 0 TO MaxData := 0; --DATA Low WORD VARIABLE DataLo : NATURAL RANGE 0 TO MaxData := 0; VARIABLE temp : std_logic_vector(7 downto 0); VARIABLE i : INTEGER; VARIABLE SecSiAddr : NATURAL RANGE 0 TO SecSiSize := 0; BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- IF falling_edge(write) THEN DataLo := D_tmp0; DataHi := D_tmp1; PATTERN_1 := (Addr = 16#555#) AND (DataLo = 16#AA#) ; PATTERN_2 := (Addr = 16#2AA#) AND (DataLo = 16#55#) ; A_PAT_1 := ((Addr = 16#555#)AND (ULBYPASS = '0')) OR (ULBYPASS = '1'); END IF; oe:= rising_edge(read)OR(read = '1'AND(Address'EVENT or SecAddr'EVENT)); IF reseted = '1' THEN CASE current_state IS WHEN RESET => OTP_ACT <= '0'; ESP_ACT <= '0'; PSP_ACT <= '0'; ULBYPASS <= '0'; CTMOUT_in <= '0'; Status := (OTHERS => '0'); Ers_queue <= (OTHERS => '0'); IF oe THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, WORDNeg => WORDNeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; RY_zd <= '1'; WHEN Z001 => null; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#20#)) THEN ULBYPASS <= '1'; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN ULBYPASS <= '0'; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN OTP_ACT <= '1'; ELSIF DataLo = 16#25# THEN SA <= SecAddr; END IF; END IF; WHEN PREL_ULBYPASS => --ready signal active RY_zd <= '1'; WHEN ESP_ULBYPASS => --ready signal active RY_zd <= '1'; WHEN PREL_ULBYPASS_RESET | ESP_ULBYPASS_RESET=> IF falling_edge(write) AND (DataLo = 16#00# ) THEN ULBYPASS <= '0'; END IF; WHEN OTP => OTP_ACT <= '1'; IF oe THEN --read SecSi Sector Region SecSiAddr := Address MOD (SecSiSize +1); generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => SecSiAddr, WORDNeg => WORDNeg, SecSi_Acc => 1); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; --ready signal active RY_zd <= '1'; WHEN OTP_Z001 => null; WHEN OTP_PREL => IF falling_edge(write) THEN IF DataLo = 16#25# THEN SA <= 0; ASSERT SecAddr=0 REPORT "Invalid sector address in SecSi mode" SEVERITY warning; --activate OTP OTP_ACT <= '1'; END IF; END IF; WHEN OTP_A0SEEN | A0SEEN | ESP_A0SEEN => IF falling_edge(write) THEN PSTART <= '1', '0' AFTER 1 ns; PCNT <= 32; WBData(0) := -1; WBData(1) := -1; IF Viol = '0' THEN WBData(0) := DataLo; WBData(1) := DataHi; END IF; IF OTP_ACT /= '1' THEN WBPage <= WPage; ELSE WBPage <= WPage MOD 8; END IF; WBAddr(0) := Address MOD 32; SA <= SecAddr; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); IF OTP_ACT = '1' THEN ASSERT SecAddr = 0 REPORT "Invalid sector Address in SecSi" SEVERITY warning; ASSERT Addr > 15 REPORT "Invalid program address(ESN region)in SecSi"& " region. Address= " & to_int_str(Addr) SEVERITY warning; ASSERT Addr < 256 REPORT "Invalid program address in SecSi region. " & "Address= " & to_int_str(Addr) SEVERITY warning; END IF; IF WORDNeg = '1' THEN WBAddr(1) := WBAddr(0) + 1; ELSE WBAddr(1) := -1; END IF; END IF; WHEN CFI | AS_CFI | ESP_CFI | ESP_AS_CFI| PSP_CFI | PSP_AS_CFI => IF oe THEN IF ((Addr >= 16#10# AND Addr <= 16#3C#) OR (Addr >= 16#40# AND Addr <= 16#50#)) THEN IF (CFI_array(Addr) /= -1) THEN DOut_zd(15 downto 0) <= to_slv(CFI_array(Addr),16); IF WORDNeg = '0' THEN DOut_zd(15 downto 8) <= (OTHERS=> 'Z'); END IF; IF WORDNeg = '0' AND NOT((Address mod 2) = 0)THEN DOut_zd(7 downto 0) <= (OTHERS=> 'Z'); END IF; END IF; ELSE ASSERT FALSE REPORT "Invalid CFI query address" SEVERITY warning; DOut_zd <= (OTHERS =>'Z'); 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 --Start Chip Erase ESTART <= '1', '0' AFTER 1 ns; ESUSP <= '0'; ERES <= '0'; Ers_Queue <= (OTHERS => '1'); Status := (OTHERS => '0'); ELSIF DataLo = 16#30# THEN --put selected sector to sec. ers. queue --start timeout Ers_Queue <= (OTHERS => '0'); Ers_Queue(SecAddr) <= '1'; CTMOUT_in <= '1'; END IF; END IF; WHEN ERS => IF oe THEN ----------------------------------------------------------- -- read status / embeded erase algorithm - Chip Erase ----------------------------------------------------------- Status(7) := '0'; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; Status(2) := NOT Status(2); --toggle DOut_zd(7 downto 0) <= Status(7 downto 0); END IF; FOR i IN 0 TO SecNum LOOP IF Sec_Prot(i) /= '1' AND EERR /= '1' THEN Corrupt_Sec(i) := '1'; erase_mem( 0, SecSize, linked_list(i) ); END IF; END LOOP; IF EDONE = '1' AND EERR /= '1' THEN FOR i IN 0 TO SecNum LOOP IF Sec_Prot(i) /= '1' THEN Corrupt_Sec(i) := '0'; erase_mem( 0, SecSize, linked_list(i) ); END IF; END LOOP; END IF; -- busy signal active RY_zd <= '0'; WHEN SERS => IF CTMOUT = '1' THEN CTMOUT_in <= '0'; START_E_in <= '0'; ESTART <= '1', '0' AFTER 1 ns; ESUSP <= '0'; ERES <= '0'; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN --need to start erase process prior to suspend ESTART <= '1', '0' AFTER 1 ns; ERES <= '0'; -- CTMOUT reset CTMOUT_in <= '0'; --suspend timeout (should be 0 according to datasheet) ESUSP <= '1' AFTER 1 ns, '0' AFTER 2 ns; ELSIF (DataLo = 16#30#) THEN CTMOUT_in <= '0', '1' AFTER 1 ns; Ers_Queue(SecAddr) <= '1'; ELSE CTMOUT_in <= '0'; END IF; ELSIF oe THEN ----------------------------------------------------------- --read status - sector erase timeout ----------------------------------------------------------- Status(3) := '0'; Status(6) := NOT Status(6); DOut_zd(7 downto 0) <=Status(7 downto 0); END IF; WHEN ESPS => IF (START_E = '1') THEN ESP_ACT <= '1'; START_E_in <= '0'; ELSIF oe THEN ----------------------------------------------------------- --read status / erase suspend timeout - stil erasing ----------------------------------------------------------- IF (Ers_Queue(SecAddr)='1') THEN Status(7) := '0'; Status(2) := NOT Status(2); --toggle ELSE Status(7) := '1'; END IF; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; DOut_zd(7 downto 0) <=Status(7 downto 0); END IF; WHEN WBPGMS_WBCNT => IF falling_edge(write) THEN IF (SecAddr = SA) AND ((WORDNeg = '0' AND DataLo < 32) OR (WORDNeg = '1'AND DataLo < 16)) THEN cnt := DataLo; IF WORDNeg = '1' THEN cnt := cnt * 2; END IF; PCNT <= cnt; LCNT <= cnt; END IF; END IF; WHEN WBPGMS_WBLSTA => IF falling_edge(write) THEN IF (SecAddr = SA) THEN WBData(cnt) := -1; IF Viol = '0' THEN WBData(cnt) := DataLo; END IF; WBAddr(cnt) := Address MOD 32; IF WORDNeg = '1' THEN WBData(cnt + 1) := -1; IF Viol = '0' THEN WBData(cnt + 1) := DataHi; END IF; WBAddr(cnt + 1) := (Address MOD 32) +1; IF cnt > 0 THEN cnt := cnt -1; END IF; END IF; IF cnt > 0 THEN cnt := cnt -1; END IF; --save last loaded data for data polling temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); IF OTP_ACT = '1' THEN WBPage <= WPage MOD 8; ELSE WBPage <= WPage; END IF; ASSERT WPage<8 REPORT "Invalid Write Buffer Page selected in "& " SecSi" SEVERITY warning; END IF; LCNT <= cnt; END IF; WHEN WBPGMS_WBLOAD => IF falling_edge(write) THEN IF (WPage = WBPage)THEN WBData(cnt) := -1; IF Viol = '0' THEN WBData(cnt) := DataLo; END IF; WBAddr(cnt) := Address MOD 32; IF WORDNeg = '1' THEN WBData(cnt + 1) := -1; IF Viol = '0' THEN WBData(cnt + 1) := DataHi; END IF; WBAddr(cnt + 1) := (Address MOD 32) + 1; IF cnt > 0 THEN cnt := cnt - 1; END IF; END IF; IF cnt > 0 THEN cnt := cnt - 1; END IF; --save last loaded data for data polling temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); END IF; LCNT <= cnt; END IF; WHEN WBPGMS_CONFB => IF falling_edge(write) THEN IF (SecAddr = SA) AND (DataLo = 16#29#) THEN PSTART <= '1', '0' AFTER 1 ns; PSUSP <= '0'; PRES <= '0'; END IF; END IF; WHEN WBPGMS_WBABORT => IF oe THEN --------------------------------------------------------------- --read status / write buffer abort --------------------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(1) := '1'; DOut_zd(7 downto 0) <=Status(7 downto 0); END IF; --busy signal active RY_zd <= '0'; WHEN WBPGMS_Z001 => null; WHEN WBPGMS_PREL => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN PSP_ACT <= '0'; END IF; END IF; WHEN PSPS => IF (START_P = '1') THEN PSP_ACT <= '1'; START_P_in <= '0'; ELSIF oe THEN ----------------------------------------------------------- --read status ----------------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(1) := '0'; Status(1) := '0'; DOut_zd(7 downto 0) <=Status(7 downto 0); IF SecAddr = SA THEN DOut_zd(7) <= Status(7); ELSE DOut_zd(7) <= NOT Status(7); END IF; END IF; WHEN SERS_EXEC => IF oe THEN ----------------------------------------------------------- --read status Erase Busy ----------------------------------------------------------- IF (Ers_Queue(SecAddr) = '1') THEN Status(7) := '0'; Status(2) := NOT Status(2); --toggle ELSE Status(7) := '1'; END IF; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; DOut_zd(7 downto 0) <=Status(7 downto 0); END IF; IF EERR /= '1' THEN FOR i IN Ers_Queue'RANGE LOOP IF Ers_Queue(i) = '1' AND Sec_Prot(i) /= '1' THEN Corrupt_Sec(i) := '1'; erase_mem( 0, SecSize, linked_list(i) ); END IF; END LOOP; IF EDONE = '1' THEN FOR i IN Ers_Queue'RANGE LOOP IF Ers_Queue(i) = '1' AND Sec_Prot(i) /= '1' THEN Corrupt_Sec(i) := '0'; erase_mem( 0, SecSize, linked_list(i) ); END IF; END LOOP; ELSIF falling_edge(write) THEN IF DataLo = 16#B0# THEN START_E_in <= '1'; ESUSP <= '1', '0' AFTER 1 ns; END IF; END IF; END IF; --busy signal active RY_zd <= '0'; WHEN ESP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN --resume erase ERES <= '1', '0' AFTER 1 ns; END IF; ELSIF oe THEN ----------------------------------------------------------- --read ----------------------------------------------------------- IF Ers_Queue(SecAddr) /= '1' THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, WORDNeg => WORDNeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; ELSE ------------------------------------------------------- --read status ------------------------------------------------------- Status(7) := '1'; Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd(7 downto 0) <= Status(7 downto 0); END IF; END IF; --ready signal active RY_zd <= '1'; WHEN PSP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN --resume erase PRES <= '1', '0' AFTER 1 ns; PSP_ACT <= '0'; END IF; ELSIF oe THEN ----------------------------------------------------------- --read ----------------------------------------------------------- IF Ers_Queue(SecAddr) /= '1' AND SecAddr /= SA THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, WORDNeg => WORDNeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; ELSIF Ers_Queue(SecAddr) = '1' THEN ------------------------------------------------------- --read erase suspend status ------------------------------------------------------- Status(7) := '1'; Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd(7 downto 0) <= Status(7 downto 0); END IF; END IF; --ready signal active RY_zd <= '1'; WHEN ESP_Z001 | PSP_Z001 | PSP_SETBWB => null; WHEN ESP_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#20#)) THEN ULBYPASS <= '1'; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN ULBYPASS <= '0'; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN OTP_ACT <= '1'; ELSIF DataLo = 16#25# THEN SA <= SecAddr; END IF; END IF; WHEN OTP_EXIT => IF DataLo = 16#00# THEN OTP_ACT <='0'; END IF; WHEN AS | ESP_AS | PSP_AS => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN OTP_ACT <='0'; END IF; ELSIF oe THEN IF SubAddr = 0 THEN DOut_zd(15 downto 0) <= to_slv(16#0001#,16); ELSIF SubAddr = 1 THEN DOut_zd(15 downto 0) <= to_slv(16#227E#,16); ELSIF SubAddr = 16#E# THEN DOut_zd(15 downto 0) <= to_slv(16#2212#,16); ELSIF SubAddr = 16#F# THEN DOut_zd(15 downto 0) <= to_slv(16#2201#,16); ELSIF SubAddr = 3 THEN DOut_zd(15 downto 8 ) <= to_slv(16#00#,8); DOut_zd(3 downto 0 ) <= to_slv(16#8#,4); DOut_zd(7 downto 4 ) <= FactoryProt&'0'&'0'&to_slv(ProtSec, 1); ELSIF SubAddr = 2 THEN DOut_zd(15 downto 0) <= to_slv(16#0000#,16); DOut_zd(0) <= Sec_Prot(SecAddr); ELSE DOut_zd(15 downto 0) <= to_slv(16#0000#,16); END IF; IF WORDNeg = '0' THEN DOut_zd(15 downto 8) <= (OTHERS=>'X'); END IF; END IF; WHEN PGMS => IF oe THEN ----------------------------------------------------------- --read status ----------------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(1) := '0'; Status(1) := '0'; DOut_zd(7 downto 0) <=Status(7 downto 0); IF SecAddr = SA THEN DOut_zd(7) <= Status(7); ELSE DOut_zd(7) <= NOT Status(7); END IF; END IF; IF falling_edge(write) THEN IF DataLo=16#B0# AND OTP_ACT = '0' THEN START_P_in <= '1'; PSUSP <= '1', '0' AFTER 1 ns; END IF; END IF; IF PERR/='1' THEN BaseLoc := WBPage * 32; IF PCNT < 32 THEN --buffer wr_cnt := PCNT; IF WORDNeg = '1' THEN wr_cnt := wr_cnt + 1; END IF; ELSE --DWord/Word program wr_cnt := 0; IF WORDNeg = '1' THEN wr_cnt := 1; END IF; END IF; FOR i IN wr_cnt downto 0 LOOP new_int:= WBData(i); old_int := -1; IF WBAddr(i) >= 0 THEN IF OTP_ACT /= '1' THEN --mem write READ_DATA(SA,BaseLoc + WBAddr(i),RData); old_int := RData; ELSE old_int := SecSi(BaseLoc+WBAddr(i)); END IF; END IF; WBData(i):= -1; IF new_int>-1 THEN new_bit:=to_slv(new_int,8); IF old_int>-1 THEN old_bit:=to_slv(old_int,8); FOR j IN 0 TO 7 LOOP IF old_bit(j) = '0' THEN new_bit(j):='0'; END IF; END LOOP; new_int:=to_nat(new_bit); END IF; WBData(i):= new_int; END IF; END LOOP; FOR i IN wr_cnt downto 0 LOOP IF WBAddr(i) < 0 THEN REPORT "write buffer violation" SEVERITY warning; ELSIF OTP_ACT /= '1' THEN --mem write WRITE_DATA(SA,BaseLoc + WBAddr(i),-1); ELSE SecSi(BaseLoc + WBAddr(i)) := -1; END IF; END LOOP; IF HANG /= '1' AND PDONE = '1' AND (NOT PERR'EVENT) THEN FOR i IN wr_cnt downto 0 LOOP IF WBAddr(i) > -1 THEN IF OTP_ACT /= '1' THEN --mem write WRITE_DATA(SA,BaseLoc + WBAddr(i),WBData(i)); ELSE --SecSi write SecSi(BaseLoc+WBAddr(i)) := WBData(i); END IF; ELSE ASSERT false REPORT "WriteBuffer Address error" SEVERITY warning; END IF; WBData(i) := -1; END LOOP; END IF; END IF; --busy signal active RY_zd <= '0'; END CASE; END IF; --Output Disable Control IF (gOE_n = '1') OR (gCE_n = '1') OR (RESETNeg = '0' AND RST = '0') THEN DOut_zd <= (OTHERS=>'Z'); ELSE IF (WORDNeg = '0') THEN DOut_zd(15 downto 8) <= (OTHERS =>'Z'); END IF; END IF; END PROCESS Functional; --------------------------------------------------------------------------- ---- File Read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_file : text is mem_file_name; FILE prot_file : text is prot_file_name; FILE secsi_file : text is secsi_file_name; VARIABLE S_ind : NATURAL := 0; VARIABLE ind : NATURAL RANGE 0 TO SecSize:= 0; VARIABLE buf : line; CONSTANT SecS : NATURAL := 16#10000#; CONSTANT MemSize : NATURAL := 16#1FFFFFF#;--bytes VARIABLE Sec_prot_tmp :std_logic_vector (134 downto 0); VARIABLE addr_ind : NATURAL ; VARIABLE sec_ind : NATURAL ; VARIABLE offset : NATURAL ; VARIABLE overload : boolean :=FALSE; VARIABLE line : NATURAL :=0; VARIABLE preloaded : boolean :=FALSE; BEGIN WAIT ON ProtSecNum; ----------------------------------------------------------------------- --CFI array data ----------------------------------------------------------------------- --CFI query identification string -- !!!!!! WORD ADDRESSES (x16) - for x8 addressing double addr 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#0027#; CFI_array(16#1C#) := 16#0036#; CFI_array(16#1D#) := 16#0000#; CFI_array(16#1E#) := 16#0000#; CFI_array(16#1F#) := 16#0007#; CFI_array(16#20#) := 16#0007#; CFI_array(16#21#) := 16#000A#; CFI_array(16#22#) := 16#0000#; CFI_array(16#23#) := 16#0001#; CFI_array(16#24#) := 16#0005#; CFI_array(16#25#) := 16#0004#; CFI_array(16#26#) := 16#0000#; --device geometry definition CFI_array(16#27#) := 16#0019#; CFI_array(16#28#) := 16#0002#; CFI_array(16#29#) := 16#0000#; CFI_array(16#2A#) := 16#0005#; CFI_array(16#2B#) := 16#0000#; CFI_array(16#2C#) := 16#0001#; CFI_array(16#2D#) := 16#01FF#; CFI_array(16#2E#) := 16#0001#; 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#0033#; CFI_array(16#45#) := 16#0008#; CFI_array(16#46#) := 16#0002#; CFI_array(16#47#) := 16#0001#; 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#0001#; CFI_array(16#4D#) := 16#00B5#; CFI_array(16#4E#) := 16#00C5#; CFI_array(16#4F#) := 16#0000# + (16#0001# * (4+ProtSec)); CFI_array(16#50#) := 16#0001#; IF (mem_file_name /= "none" AND UserPreload ) THEN -------------------------------------------------------------------- -----am29lv2562m memory preload file format ------------------------ -------------------------------------------------------------------- -- / - comment -- @aaaaaaa - stands for address within Memory -- dd -
is byte to be written at Mem(aaaaaaa++) -- (aaaaaaa is incremented at every load) -- only first 1-8 columns are loaded. NO empty lines !!!!!!!!!!!!! -------------------------------------------------------------------- addr_ind := 0; WHILE (not ENDFILE (mem_file)) LOOP READLINE (mem_file, buf); line := line +1; IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 8)); sec_ind := addr_ind / SecS; offset := addr_ind - ( sec_ind * SecS ); ELSE IF addr_ind <= MemSize THEN WRITE_DATA(sec_ind,offset,h(buf(1 to 2))); addr_ind := (addr_ind + 1); sec_ind := addr_ind / SecS; offset := addr_ind - ( sec_ind * SecS ); ELSE ASSERT overload /= FALSE REPORT "file: "&mem_file_name&" has size larger than " &to_int_str(MemSize)&" at line "&to_int_str(line) SEVERITY Note; overload := TRUE; END IF; END IF; END LOOP; END IF; IF (prot_file_name /= "none" AND UserPreload ) THEN -------------------------------------------------------------------- -----am29lv2562m sector protect preload file format ---------------- -------------------------------------------------------------------- -- / - comment -- @sss - stands for sector number -- d - is bit to be written at SecProt(sss++) -- (sec is incremented at every load) -- (At last(134) position is Factory protection) -- only first 1-4 columns are loaded. NO empty lines !!!!!!!!!!!!! -------------------------------------------------------------------- -------------------------------------------------------------------- ind := 0; Sec_Prot := (OTHERS => '0'); Sec_prot_tmp := (OTHERS => '0'); WHILE (not ENDFILE (prot_file)) LOOP READLINE (prot_file, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 4)); ELSE IF addr_ind <= 134 THEN IF buf(1) = '1' THEN Sec_prot_tmp (addr_ind) := '1'; ELSE Sec_prot_tmp (addr_ind) := '0'; END IF; addr_ind := addr_ind + 1; END IF; END IF; END LOOP; Sec_Prot(0) := Sec_prot_tmp(0); Sec_Prot(1) := Sec_prot_tmp(1); Sec_Prot(2) := Sec_prot_tmp(2); Sec_Prot(3) := Sec_prot_tmp(3); Sec_Prot(508):= Sec_prot_tmp(130); Sec_Prot(509):= Sec_prot_tmp(131); Sec_Prot(510):= Sec_prot_tmp(132); Sec_Prot(511):= Sec_prot_tmp(133); FactoryProt <= Sec_prot_tmp(134); FOR i IN 4 TO 507 LOOP Sec_Prot(i) := Sec_prot_tmp((i/4)+3); END LOOP; END IF; -------------------------------------------------------------- -- am29lv2562m SecSi preload file format --------------------------------------------------------------- -- / - comment -- @aa - stands for address within SecSi -- dd -
is byte to be written at SecSi(aa++) -- (aa is incremented at every load) -- only first 1-3 columns are loaded. NO empty lines !!!!!!!! --------------------------------------------------------------- IF (SecSi_file_name /= "none" AND UserPreload ) THEN SecSi := (OTHERS => MaxData); ind := 0; WHILE (not ENDFILE (SecSi_file)) LOOP READLINE (SecSi_file, buf); IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN ind := h(buf(2 TO 3)); ELSE IF ind <= SecSiSize THEN SecSi(ind) := h(buf(1 TO 2)); ind := ind + 1; END IF; END IF; END LOOP; END IF; END PROCESS MemPreload; DOutPassThrough : PROCESS(DOut_zd) VARIABLE ValidData : std_logic_vector(15 downto 0); VARIABLE CEDQ_t : TIME; VARIABLE OEDQ_t : TIME; VARIABLE ADDRDQ_t : TIME; BEGIN IF DOut_zd(0) /= 'Z' THEN OPENLATCH := TRUE; CEDQ_t := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(trz0); OEDQ_t := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(trz0); ADDRDQ_t := -A'LAST_EVENT + tpd_A0_DQ0_rdPage_eq_0(tr01); IF ( WORDNeg = '0' ) AND (DIn(15)'LAST_EVENT < A'LAST_EVENT) THEN ADDRDQ_t := -DIn(15)'LAST_EVENT + tpd_A0_DQ0_rdPage_eq_0(tr01); END IF; FROMOE := (OEDQ_t >= CEDQ_t) AND (OEDQ_t > 0 ns); FROMCE := (CEDQ_t > OEDQ_t) AND (CEDQ_t > 0 ns); IF WORDNeg = '0' THEN ValidData := "ZZZZZZZZXXXXXXXX"; ELSE ValidData := "XXXXXXXXXXXXXXXX"; END IF; IF ((ADDRDQ_t > 0 ns) AND (((ADDRDQ_t > CEDQ_t) AND FROMCE) OR ((ADDRDQ_t > OEDQ_t) AND FROMOE))) THEN DOut_Pass <= ValidData, DOut_zd AFTER ADDRDQ_t; ELSE DOut_Pass <= DOut_zd; END IF; ELSE CEDQ_t := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(tr0z); OEDQ_t := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(tr0z); FROMOE := (OEDQ_t <= CEDQ_t) AND (OEDQ_t > 0 ns); FROMCE := (CEDQ_t < OEDQ_t) AND (CEDQ_t > 0 ns); DOut_Pass <= DOut_zd; OPENLATCH := FALSE; DOut_Pass <= DOut_zd; END IF; END PROCESS DOutPassThrough; -- read page process PD_PAGE : PROCESS (read, A, DIn(15)) VARIABLE Address_page : std_logic_vector(HiAddrBit-2 DOWNTO 0); BEGIN IF rising_edge(read) THEN Address_page := A(HiAddrBit DOWNTO 2); ELSIF (A'event OR(DIn(15)'event AND WORDNeg = '0')) AND read = '1' AND reseted = '1' THEN IF A(HiAddrBit DOWNTO 2) = Address_page THEN page_read := TRUE; ELSE page_read := FALSE; Address_page := A(HiAddrBit DOWNTO 2); END IF; ELSE page_read := FALSE; END IF; END PROCESS PD_PAGE; ----------------------------------------------------------------------- -- Path Delay Section ----------------------------------------------------------------------- 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 7 GENERATE PROCESS(DOut_Pass(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_Pass(i), GlitchData => D0_GlitchData, IgnoreDefaultDelay => TRUE, Mode => VitalTransport, RejectFastPath => FALSE, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMOE) OR (OPENLATCH AND FROMCE)), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMCE) OR (OPENLATCH AND FROMOE)), 2 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_1), PathCondition => NOT FROMOE AND NOT FROMCE AND page_read), 3 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_0), PathCondition => NOT FROMOE AND NOT FROMCE AND NOT page_read), 4 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_1), PathCondition => WORDNeg = '0' AND DOut_pass(i) /= 'X' AND page_read), 5 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_0), PathCondition => WORDNeg = '0' AND DOut_pass(i) /= 'X' AND NOT page_read), 6 => (InputChangeTime => RESETNeg'LAST_EVENT, PathDelay => tpd_RESETNeg_DQ0, PathCondition => RESETNeg='0') ) ); END PROCESS; END GENERATE D_Out_PathDelay_Gen; --------------------------------------------------------------------------- -- Path Delay Section for DOut signal --------------------------------------------------------------------------- D_Out_15_8_PathDelay_Gen : FOR i IN 8 TO 15 GENERATE PROCESS(DOut_Pass(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_Pass(i), GlitchData => D0_GlitchData, IgnoreDefaultDelay => TRUE, Mode => VitalTransport, RejectFastPath => FALSE, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMOE) OR (OPENLATCH AND FROMCE)), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMCE) OR (OPENLATCH AND FROMOE)), 2 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_1), PathCondition => NOT FROMOE AND NOT FROMCE AND page_read), 3 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_0), PathCondition => NOT FROMOE AND NOT FROMCE AND NOT page_read), 4 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_1), PathCondition => WORDNeg = '0' AND DOut_pass(i) /= 'X' AND page_read), 5 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_0), PathCondition => WORDNeg = '0' AND DOut_pass(i) /= 'X' AND NOT page_read), 6 => (InputChangeTime => RESETNeg'LAST_EVENT, PathDelay => tpd_RESETNeg_DQ0, PathCondition => RESETNeg='0') ) ); END PROCESS; END GENERATE D_Out_15_8_PathDelay_Gen; END BLOCK behavior; END vhdl_behavioral_dynamic_flash; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral_static_falsh of am29lv2562m_flash IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral_static_falsh : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "am29lv2562m"; CONSTANT MaxData : NATURAL := 16#FF#; CONSTANT SecSize : NATURAL := 16#FFFF#; --65535 bytes CONSTANT SecNum : NATURAL := 511; CONSTANT SecSiSize : NATURAL := 255; CONSTANT HiAddrBit : NATURAL := 23; -- interconnect path delay signals SIGNAL A23_ipd : std_ulogic := 'U'; SIGNAL A22_ipd : std_ulogic := 'U'; SIGNAL A21_ipd : std_ulogic := 'U'; SIGNAL A20_ipd : std_ulogic := 'U'; SIGNAL A19_ipd : std_ulogic := 'U'; SIGNAL A18_ipd : std_ulogic := 'U'; SIGNAL A17_ipd : std_ulogic := 'U'; SIGNAL A16_ipd : std_ulogic := 'U'; SIGNAL A15_ipd : std_ulogic := 'U'; SIGNAL A14_ipd : std_ulogic := 'U'; SIGNAL A13_ipd : std_ulogic := 'U'; SIGNAL A12_ipd : std_ulogic := 'U'; SIGNAL A11_ipd : std_ulogic := 'U'; SIGNAL A10_ipd : std_ulogic := 'U'; SIGNAL A9_ipd : std_ulogic := 'U'; SIGNAL A8_ipd : std_ulogic := 'U'; SIGNAL A7_ipd : std_ulogic := 'U'; SIGNAL A6_ipd : std_ulogic := 'U'; SIGNAL A5_ipd : std_ulogic := 'U'; SIGNAL A4_ipd : std_ulogic := 'U'; SIGNAL A3_ipd : std_ulogic := 'U'; SIGNAL A2_ipd : std_ulogic := 'U'; SIGNAL A1_ipd : std_ulogic := 'U'; SIGNAL A0_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 WORDNeg_ipd : std_ulogic := 'U'; SIGNAL WPNeg_ipd : std_ulogic := 'U'; --- internal delays SIGNAL WBPO_in : std_ulogic := '0'; SIGNAL WBPO_out : std_ulogic := '0'; SIGNAL POW_in : std_ulogic := '0'; SIGNAL POW_out : std_ulogic := '0'; SIGNAL POU_in : std_ulogic := '0'; SIGNAL POU_out : std_ulogic := '0'; SIGNAL SEO_in : std_ulogic := '0'; SIGNAL SEO_out : std_ulogic := '0'; SIGNAL HANG_out : std_ulogic := '0'; --Program/Erase Timing Limit SIGNAL HANG_in : std_ulogic := '0'; SIGNAL START_P : std_ulogic := '0'; --Start TimeOut; Program Suspend SIGNAL START_P_in : std_ulogic := '0'; SIGNAL START_E : std_ulogic := '0'; --Start TimeOut; Erase Suspend SIGNAL START_E_in : std_ulogic := '0'; SIGNAL CTMOUT : std_ulogic := '0'; --Sector Erase TimeOut SIGNAL CTMOUT_in : std_ulogic := '0'; SIGNAL READY_in : std_ulogic := '0'; SIGNAL READY : std_ulogic := '0'; -- Device ready after reset BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays WBPB :VitalBuf(WBPO_out,WBPO_in, (tdevice_WBPB ,UnitDelay)); POW :VitalBuf(POW_out, POW_in, (tdevice_POW ,UnitDelay)); POU :VitalBuf(POU_out, POU_in, (tdevice_POU ,UnitDelay)); SEO :VitalBuf(SEO_out, SEO_in, (tdevice_SEO ,UnitDelay)); HANG :VitalBuf(HANG_out,HANG_in, (tdevice_HANG ,UnitDelay)); STARTE :VitalBuf(START_E,START_E_in,(tdevice_STARTE ,UnitDelay)); STARTP :VitalBuf(START_P,START_P_in,(tdevice_STARTP ,UnitDelay)); CTMOUTP :VitalBuf(CTMOUT, CTMOUT_in, (tdevice_CTMOUTP - 5 ns,UnitDelay)); READYP :VitalBuf(READY, READY_in, (tdevice_READYP ,UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (A23_ipd, A23, tipd_A23); w_2 : VitalWireDelay (A22_ipd, A22, tipd_A22); w_3 : VitalWireDelay (A21_ipd, A21, tipd_A21); w_4 : VitalWireDelay (A20_ipd, A20, tipd_A20); w_5 : VitalWireDelay (A19_ipd, A19, tipd_A19); w_6 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_7 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_8 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_9 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_10 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_11 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_12 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_13 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_14 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_15 : VitalWireDelay (A9_ipd, A9, tipd_A9); w_16 : VitalWireDelay (A8_ipd, A8, tipd_A8); w_17 : VitalWireDelay (A7_ipd, A7, tipd_A7); w_18 : VitalWireDelay (A6_ipd, A6, tipd_A6); w_19 : VitalWireDelay (A5_ipd, A5, tipd_A5); w_20 : VitalWireDelay (A4_ipd, A4, tipd_A4); w_21 : VitalWireDelay (A3_ipd, A3, tipd_A3); w_22 : VitalWireDelay (A2_ipd, A2, tipd_A2); w_23 : VitalWireDelay (A1_ipd, A1, tipd_A1); w_24 : VitalWireDelay (A0_ipd, A0, tipd_A0); w_25 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_26 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_27 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_28 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_29 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_30 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_31 : VitalWireDelay (DQ9_ipd , DQ9 , tipd_DQ9); w_32 : VitalWireDelay (DQ8_ipd , DQ8 , tipd_DQ8); w_33 : VitalWireDelay (DQ7_ipd , DQ7 , tipd_DQ7); w_34 : VitalWireDelay (DQ6_ipd , DQ6 , tipd_DQ6); w_35 : VitalWireDelay (DQ5_ipd , DQ5 , tipd_DQ5); w_36 : VitalWireDelay (DQ4_ipd , DQ4 , tipd_DQ4); w_37 : VitalWireDelay (DQ3_ipd , DQ3 , tipd_DQ3); w_38 : VitalWireDelay (DQ2_ipd , DQ2 , tipd_DQ2); w_39 : VitalWireDelay (DQ1_ipd , DQ1 , tipd_DQ1); w_40 : VitalWireDelay (DQ0_ipd , DQ0 , tipd_DQ0); w_41 : VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg); w_42 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_43 : VitalWireDelay (RESETNeg_ipd, RESETNeg, tipd_RESETNeg); w_44 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); w_45 : VitalWireDelay (WORDNeg_ipd, WORDNeg, tipd_WORDNeg); w_46 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg); 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_ulogic_vector(15 downto 0) := (OTHERS => 'Z'); CENeg : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; WORDNeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U' ); PORT MAP ( A(23) => A23_ipd, A(22) => A22_ipd, 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, OENeg => OENeg_ipd, WENeg => WENeg_ipd, RESETNeg => RESETNeg_ipd, WORDNeg => WORDNeg_ipd, RY => RY , WPNeg => WPNeg_ipd ); -- State Machine : State_Type TYPE state_type IS ( RESET, Z001, PREL_SETBWB, PREL_ULBYPASS, ESP_ULBYPASS, PREL_ULBYPASS_RESET, ESP_ULBYPASS_RESET, CFI, -- CFI MOD AS, -- autoselect AS_CFI, -- CFI from autoselect A0SEEN, OTP, OTP_Z001, OTP_PREL, OTP_EXIT, OTP_A0SEEN, C8, C8_Z001, C8_PREL, ERS, SERS, ESPS, SERS_EXEC, ESP, ESP_SETBWB, PSP_SETBWB, ESP_Z001, PSP_Z001, ESP_A0SEEN, ESP_AS, PSP_AS, ESP_CFI, PSP_CFI, ESP_AS_CFI, PSP_AS_CFI, PGMS, PSPS, PSP, WBPGMS_WBCNT, WBPGMS_WBLSTA, WBPGMS_WBLOAD, WBPGMS_CONFB, WBPGMS_WBABORT, WBPGMS_Z001, WBPGMS_PREL ); --Flash Memory Array TYPE SecType IS ARRAY (0 TO SecSize) OF INTEGER RANGE -1 TO MaxData; TYPE MemArray IS ARRAY (0 TO SecNum) OF SecType; --SecSi Sector TYPE SecSiType IS ARRAY ( 0 TO SecSiSize) OF INTEGER RANGE -1 TO MaxData; --Common Flash Interface Query codes TYPE CFItype IS ARRAY (16#10# TO 16#50#) OF NATURAL; -- 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 DOut_Pass : std_logic_vector(15 downto 0):=(OTHERS=>'Z'); SIGNAL RY_zd : std_logic := 'Z'; --FSM control signals SIGNAL ULBYPASS : std_logic := '0'; --Unlock Bypass Active SIGNAL ESP_ACT : std_logic := '0'; --Erase Suspend SIGNAL PSP_ACT : std_logic := '0'; --Program Suspend SIGNAL OTP_ACT : std_logic := '0'; --SecSi access SIGNAL WB_ACT : std_logic := '0'; --Write to buffer access SHARED VARIABLE DOut_zd_var : std_logic_vector(15 downto 0) :=(OTHERS=>'Z'); SIGNAL LCNT : NATURAL RANGE 0 TO 31:= 0; --Load Counter --number of location to be writen in Write Buffer: 0-31 bytes. --if 32 word/byte programming SIGNAL PCNT : NATURAL RANGE 0 TO 32:= 0; --Model should never hang!!!!!!!!!!!!!!! SIGNAL HANG : std_logic := '0'; 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 ERES : std_logic := '0'; --Resume Erase SIGNAL PSUSP : std_logic := '0'; --Suspend Program SIGNAL PRES : std_logic := '0'; --Resume Program --All sectors selected for erasure are protected SIGNAL EERR : std_logic := '0'; --Sectors selected for erasure SIGNAL ERS_QUEUE : std_logic_vector(SecNum downto 0) := (OTHERS => '0'); --Command Register SIGNAL write : std_logic := '0'; SIGNAL read : std_logic := '0'; SHARED VARIABLE wr_cnt : INTEGER; -- Access time variables SHARED VARIABLE OPENLATCH : BOOLEAN; SHARED VARIABLE FROMCE : BOOLEAN; SHARED VARIABLE FROMOE : BOOLEAN; SHARED VARIABLE page_read : BOOLEAN; --Sector Address SIGNAL SecAddr : NATURAL RANGE 0 TO SecNum := 0; SIGNAL SA : NATURAL RANGE 0 TO SecNum := 0; SIGNAL WBPage : NATURAL; --Address within sector SIGNAL Address : NATURAL RANGE 0 TO SecSize := 0; SIGNAL SubAddr : NATURAL RANGE 0 TO SecSize := 0; SHARED VARIABLE CFI_array : CFItype := (OTHERS => 0); SIGNAL D_tmp0 : NATURAL RANGE 0 TO MaxData; SIGNAL D_tmp1 : NATURAL RANGE 0 TO MaxData; --A23:A11 Don't Care SIGNAL Addr : NATURAL RANGE 0 TO 16#7FFF# := 0; SIGNAL WPage : NATURAL RANGE 0 TO 16#7FFF# := 0; --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)); SHARED VARIABLE Sec_Prot : std_logic_vector(511 downto 0) := (OTHERS => '0'); SHARED VARIABLE SecSi : SecSiType := (OTHERS => 0); --SecSi ProtectionStatus SIGNAL FactoryProt : std_logic := '1'; -- Addresses of the Protected Sector SIGNAL ProtSecNum : INTEGER := -1; SIGNAL ProtSec : INTEGER := -1; -- timing check violation SIGNAL Viol : X01 := '0'; PROCEDURE generate_out ( DOut_zd : OUT std_logic_vector(15 downto 0); SecAddr : IN NATURAL; WORDNeg : IN std_logic; SecSi_acc : IN NATURAL; Address : IN NATURAL ) IS BEGIN IF SecSi_acc = 0 THEN IF Mem(SecAddr)(Address) = -1 THEN DOut_zd(7 downto 0) := (OTHERS=>'X'); ELSE DOut_zd(7 downto 0) := to_slv(Mem(SecAddr)(Address),8); END IF; IF WORDNeg = '1' THEN IF Mem(SecAddr)(Address+1) = -1 THEN DOut_zd(15 downto 8) := (OTHERS=>'X'); ELSE DOut_zd(15 downto 8):=to_slv(Mem(SecAddr)(Address+1),8); END IF; END IF; ELSE DOut_zd(7 downto 0) := (OTHERS=>'X'); IF SecSi(Address)/=-1 THEN DOut_zd(7 downto 0) := to_slv(SecSi(Address),8); END IF; IF WORDNeg='1' THEN DOut_zd(15 downto 8) := (OTHERS=>'X'); IF SecSi(Address) /= -1 THEN DOut_zd(15 downto 8) := to_slv(SecSi(Address+1),8); END IF; END IF; END IF; END PROCEDURE generate_out; BEGIN --------------------------------------------------------------------------- --protected sector --------------------------------------------------------------------------- ProtSecNum <= SecNum WHEN TimingModel(12)= 'H' OR TimingModel(12)= 'h' ELSE 0 ; ProtSec <= 1 WHEN TimingModel(12)= 'H' OR TimingModel(12)= 'h' ELSE 0 ; PoweredUp <= '1' AFTER 100 ns; RST <= RESETNeg AFTER 500 ns; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(WORDNeg, A, Din, CENeg, OENeg, WENeg, RESETNeg) -- Timing Check Variables VARIABLE Tviol_A0_CENeg : X01 := '0'; VARIABLE TD_A0_CENeg : VitalTimingDataType; VARIABLE Tviol_A0_WENeg : X01 := '0'; VARIABLE TD_A0_WENeg : VitalTimingDataType; VARIABLE Tviol_A0_OENeg : X01 := '0'; VARIABLE TD_A0_OENeg : VitalTimingDataType; VARIABLE Tviol_DQ0_CENeg : X01 := '0'; VARIABLE TD_DQ0_CENeg : VitalTimingDataType; VARIABLE Tviol_DQ0_WENeg : X01 := '0'; VARIABLE TD_DQ0_WENeg : VitalTimingDataType; VARIABLE Tviol_CENeg_RESETNeg : X01 := '0'; VARIABLE TD_CENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_OENeg_RESETNeg : X01 := '0'; VARIABLE TD_OENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_WENeg_RESETNeg : X01 := '0'; VARIABLE TD_WENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_F : X01 := '0'; VARIABLE TD_CENeg_WENeg_F : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_R : X01 := '0'; VARIABLE TD_CENeg_WENeg_R : VitalTimingDataType; VARIABLE Tviol_OENeg_WENeg_F : X01 := '0'; VARIABLE TD_OENeg_WENeg_F : VitalTimingDataType; VARIABLE Tviol_OENeg_WENeg_R : X01 := '0'; VARIABLE TD_OENeg_WENeg_R : VitalTimingDataType; VARIABLE Tviol_WENeg_CENeg_F : X01 := '0'; VARIABLE TD_WENeg_CENeg_F : VitalTimingDataType; VARIABLE Tviol_WENeg_CENeg_R : X01 := '0'; VARIABLE TD_WENeg_CENeg_R : VitalTimingDataType; VARIABLE Tviol_CENeg_OENeg : X01 := '0'; VARIABLE TD_CENeg_OENeg : VitalTimingDataType; VARIABLE Tviol_WORDNeg_CENeg : X01 := '0'; VARIABLE TD_WORDNeg_CENeg : VitalTimingDataType; VARIABLE Pviol_RESETNeg : X01 := '0'; VARIABLE PD_RESETNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CENeg : X01 := '0'; VARIABLE PD_CENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_WENeg : X01 := '0'; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A0 : X01 := '0'; VARIABLE PD_A0 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01 := '0'; BEGIN --------------------------------------------------------------------------- -- Timing Check Section --------------------------------------------------------------------------- IF (TimingChecksOn) THEN -- Setup/Hold Check between A and CENeg VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CENeg, RefSignalName => "CE#", SetupHigh => tsetup_A0_CENeg, SetupLow => tsetup_A0_CENeg, HoldHigh => thold_A0_CENeg, HoldLow => thold_A0_CENeg, CheckEnabled => WENeg = '0' AND OENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_CENeg, Violation => Tviol_A0_CENeg ); -- Setup/Hold Check between A and WENeg VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_A0_CENeg, SetupLow => tsetup_A0_CENeg, HoldHigh => thold_A0_CENeg, HoldLow => thold_A0_CENeg, CheckEnabled => CENeg = '0' AND OENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_WENeg, Violation => Tviol_A0_WENeg ); -- Setup Check between A and OENeg VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => OENeg, RefSignalName => "OE#", SetupHigh => tsetup_A0_OENeg, SetupLow => tsetup_A0_OENeg, CheckEnabled => CENeg = '0' AND WENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_OENeg, Violation => Tviol_A0_OENeg ); -- Setup/Hold Check between DQ and CENeg VitalSetupHoldCheck ( TestSignal => DQ0, TestSignalName => "DQ", RefSignal => CENeg, RefSignalName => "CE#", SetupHigh => tsetup_DQ0_CENeg, SetupLow => tsetup_DQ0_CENeg, HoldHigh => thold_DQ0_CENeg, HoldLow => thold_DQ0_CENeg, CheckEnabled => WENeg = '0' AND OENeg = '1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_DQ0_CENeg, Violation => Tviol_DQ0_CENeg ); -- Setup/Hold Check between DQ and WENeg VitalSetupHoldCheck ( TestSignal => DQ0, TestSignalName => "DQ", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_DQ0_CENeg, SetupLow => tsetup_DQ0_CENeg, HoldHigh => thold_DQ0_CENeg, HoldLow => thold_DQ0_CENeg, CheckEnabled => CENeg = '0' AND OENeg = '1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_DQ0_WENeg, Violation => Tviol_DQ0_WENeg ); -- Hold Check between CENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_RESETNeg, Violation => Tviol_CENeg_RESETNeg ); -- Hold Check between OENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_RESETNeg, Violation => Tviol_OENeg_RESETNeg ); -- Hold Check between WENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_RESETNeg, Violation => Tviol_WENeg_RESETNeg ); -- Hold Check between OENeg and WENeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => WENeg, RefSignalName => "WE#", HoldHigh => thold_OENeg_WENeg, CheckEnabled => PDONE = '0' OR EDONE = '0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_WENeg_R, Violation => Tviol_OENeg_WENeg_R ); -- Hold Check between OENeg and WENeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_OENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_WENeg_F, Violation => Tviol_OENeg_WENeg_F ); -- Hold Check between CENeg and OENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => OENeg, RefSignalName => "OE#", HoldHigh => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_OENeg, Violation => Tviol_CENeg_OENeg ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => CENeg, RefSignalName => "CE#", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CENeg_F, Violation => Tviol_WENeg_CENeg_F ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => CENeg, RefSignalName => "CE#", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CENeg_R, Violation => Tviol_WENeg_CENeg_R ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_F, Violation => Tviol_CENeg_WENeg_F ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_R, Violation => Tviol_CENeg_WENeg_R ); -- PulseWidth Check for RESETNeg VitalPeriodPulseCheck ( TestSignal => RESETNeg, TestSignalName => "RESET#", PulseWidthLow => tpw_RESETNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RESETNeg, Violation => Pviol_RESETNeg ); -- PulseWidth Check for WENeg VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WE#", PulseWidthHigh => tpw_WENeg_posedge, PulseWidthLow => tpw_WENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, Violation => Pviol_WENeg ); -- PulseWidth Check for CENeg VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CE#", PulseWidthHigh => tpw_CENeg_posedge, PulseWidthLow => tpw_CENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg, Violation => Pviol_CENeg ); -- PulseWidth Check for A VitalPeriodPulseCheck ( TestSignal => A(0), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A0, Violation => Pviol_A0 ); Violation := Tviol_A0_CENeg OR Tviol_A0_WENeg OR Tviol_A0_OENeg OR Tviol_WORDNeg_CENeg OR Tviol_DQ0_CENeg OR Tviol_DQ0_WENeg OR Tviol_CENeg_RESETNeg OR Tviol_OENeg_RESETNeg OR Tviol_WENeg_RESETNeg OR Tviol_OENeg_WENeg_F OR Tviol_OENeg_WENeg_R OR Tviol_WORDNeg_CENeg OR Tviol_CENeg_OENeg OR Tviol_WENeg_CENeg_F OR Tviol_WENeg_CENeg_R OR Tviol_CENeg_WENeg_F OR Tviol_CENeg_WENeg_R OR Pviol_RESETNeg OR Pviol_WENeg OR Pviol_CENeg OR Pviol_A0 ; Viol <= Violation; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY WARNING; END IF; END PROCESS VITALTimingCheck; ---------------------------------------------------------------------------- -- sequential process for reset control and FSM state transition ---------------------------------------------------------------------------- StateTransition : PROCESS(next_state, RESETNeg, RST, READY, 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='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='0')OR (R='1' AND RESETNeg='1' AND RST='0' AND READY='0')OR (R='1' AND RESETNeg='1' AND RST='1' AND READY='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 <= 'X'; END IF; END IF; IF ((gWE_n = '1') AND (gCE_n = '0') AND (gOE_n = '0') )THEN read <= '1'; 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)) THEN ASSERT false REPORT "Glitch detected on WE# control signals" SEVERITY warning; END IF; IF (CENeg'EVENT AND (CENeg = gCE_n)) THEN ASSERT false REPORT "Glitch detected on CE# control signals" SEVERITY warning; END IF; IF (OENeg'EVENT AND (OENeg = gOE_n)) THEN ASSERT false REPORT "Glitch detected on OE# 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, read, WORDNeg) VARIABLE A_tmp : NATURAL RANGE 0 TO 16#7FF#; VARIABLE A_tmp2 : NATURAL RANGE 0 TO SecSize; VARIABLE SA_tmp : NATURAL RANGE 0 TO SecNum; VARIABLE A_tmp1 : NATURAL RANGE 0 TO SecSize; VARIABLE i : NATURAL; 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 OR (Din(15)'EVENT AND WORDNeg='0') OR WORDNeg'EVENT) OR ( A'EVENT AND WENeg = '1' AND CENeg = '0' AND OENeg = '0') THEN A_tmp := to_nat( A(10 downto 0) ); A_tmp2 := to_nat( A(8 downto 0) ); SA_tmp := to_nat( A(HiAddrBit downto 15)); IF (WORDNeg = '0') THEN IF Din(15) = '1' THEN A_tmp1 := to_nat( A(14 downto 0) & '1' ); ELSE A_tmp1 := to_nat( A(14 downto 0) & '0' ); END IF; ELSE A_tmp1 := to_nat( A(14 downto 0) & '0' ); END IF; ELSIF (rising_edge(WENeg) OR rising_edge(CENeg)) AND write = '1' THEN D_tmp0 <= to_nat(Din(7 downto 0)); IF WORDNeg = '1' THEN D_tmp1 <= to_nat(Din(15 downto 8)); END IF; END IF; IF rising_edge(write) OR falling_edge(OENeg) OR falling_edge(CENeg) OR ((A'EVENT OR (Din(15)'EVENT AND WORDNeg = '0') OR WORDNeg'EVENT) AND WENeg = '1' AND CENeg = '0' AND OENeg = '0') THEN SecAddr <= SA_tmp; Address <= A_tmp1; WPage <= A_tmp1 / 32; SubAddr <=A_tmp2; Addr <= A_tmp; END IF; END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- Timing control for the Program Operations --------------------------------------------------------------------------- ProgTime :PROCESS(OTP_ACT,PSTART, ESP_ACT, PSUSP, PRES, reseted) VARIABLE cnt : NATURAL RANGE 0 TO SecNum + 1 := 0; VARIABLE duration : time; VARIABLE elapsed : time; VARIABLE pow, pou, wbpb : time; VARIABLE start : time; BEGIN pow := tdevice_POW / 2; pou := tdevice_POU / 2; wbpb := tdevice_WBPB /2; IF LongTimming THEN pow := tdevice_POW; pou := tdevice_POU; wbpb := tdevice_WBPB; 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' OR ESP_ACT = '0')) AND (OTP_ACT = '0')) OR (FactoryProt = '0' AND OTP_ACT = '1')THEN IF PCNT < 32 THEN --buffer IF WORDNeg = '1' THEN cnt := PCNT + 2; ELSE cnt := PCNT + 1; END IF; duration := cnt * wbpb; ELSE IF ULBYPASS = '1' THEN duration := pou;--tdevice_POU; ELSE duration := pow;--tdevice_POW; END IF; END IF; elapsed := 0 ns; start := NOW; PDONE <= '0', '1' AFTER duration; ELSE PERR <= '1', '0' AFTER 1 us; END IF; END IF; IF rising_edge(PSUSP) AND PDONE = '0' THEN elapsed := NOW - start; duration := duration - elapsed; PDONE <= '0'; ELSIF rising_edge(PRES) AND PDONE = '0' THEN start := NOW; PDONE <= '0', '1' AFTER duration; END IF; END IF; END PROCESS ProgTime; --------------------------------------------------------------------------- -- Timing control for the Erase Operations --------------------------------------------------------------------------- ErsTime :PROCESS(ESTART, ESUSP, ERES, Ers_Queue, reseted) VARIABLE cnt : NATURAL RANGE 0 TO SecNum + 1 := 0; VARIABLE elapsed : time; VARIABLE duration : time; VARIABLE start : time; VARIABLE seo : time; BEGIN seo := tdevice_SEO/1000; IF LongTimming THEN seo := tdevice_SEO; END IF; IF rising_edge(reseted) THEN EDONE <= '1'; -- reset done, ERASE terminated ELSIF reseted = '1' THEN IF rising_edge(ESTART) AND EDONE = '1' THEN cnt := 0; FOR i IN Ers_Queue'RANGE LOOP IF Ers_Queue(i) = '1' AND Sec_Prot(i) /= '1' 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; ELSIF rising_edge(ESUSP) 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, Addr, D_tmp0,D_tmp1, ULBYPASS, PDONE, EDONE, HANG, CTMOUT, SecAddr, START_P, START_E, reseted, READY, PERR, EERR) VARIABLE PATTERN_1 : boolean := FALSE; VARIABLE PATTERN_2 : boolean := FALSE; VARIABLE A_PAT_1 : boolean := FALSE; --DATA High WORD VARIABLE DataHi : NATURAL RANGE 0 TO MaxData := 0; --DATA Low WORD 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#) AND (ULBYPASS = '0')) OR (ULBYPASS = '1'); 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 CFI => IF falling_edge(write) THEN IF (DataLo=16#F0#) THEN next_state <= RESET; ELSE next_state <= CFI; END IF; END IF; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#20#)) THEN next_state <= PREL_ULBYPASS; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN next_state <= AS; ELSIF (A_PAT_1 AND (DataLo = 16#A0#)) THEN next_state <= A0SEEN; ELSIF (A_PAT_1 AND (DataLo = 16#80#)) THEN next_state <= C8; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN next_state <= OTP; ELSIF DataLo = 16#25# THEN next_state <= WBPGMS_WBCNT; ELSE next_state <= RESET; END IF; END IF; WHEN WBPGMS_WBCNT => IF falling_edge(write) THEN IF (SecAddr = SA) AND ((WORDNeg = '0'AND DataLo < 32) OR (WORDNeg = '1'AND DataLo < 16)) THEN next_state <= WBPGMS_WBLSTA; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_WBLSTA => IF falling_edge(write) THEN IF (SecAddr = SA) THEN IF (LCNT > 0) THEN next_state <= WBPGMS_WBLOAD; ELSE next_state <= WBPGMS_CONFB; END IF; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_WBLOAD => IF falling_edge(write) THEN IF (WPage = WBPage) THEN IF (LCNT > 0) THEN next_state <= WBPGMS_WBLOAD; ELSE next_state <= WBPGMS_CONFB; END IF; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_CONFB => IF falling_edge(write) THEN IF (SecAddr = SA) AND (DataLo = 16#29#) THEN next_state <= PGMS; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_WBABORT => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= WBPGMS_Z001; END IF; END IF; WHEN WBPGMS_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= WBPGMS_PREL; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN WBPGMS_PREL => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN IF ESP_ACT ='1' THEN next_state <= ESP; ELSIF OTP_ACT ='1' THEN next_state <= OTP; ELSE next_state <= RESET; END IF; ELSE next_state <= WBPGMS_WBABORT; END IF; END IF; WHEN PREL_ULBYPASS => IF falling_edge(write) THEN IF (DataLo = 16#90#) THEN next_state <= PREL_ULBYPASS_RESET; ELSIF (A_PAT_1 AND (DataLo = 16#A0#)) THEN next_state <= A0SEEN; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; WHEN PREL_ULBYPASS_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; ELSE next_state <= AS; END IF; END IF; WHEN AS_CFI => IF falling_edge(write) THEN IF (DataLo=16#F0#) THEN next_state <= AS; ELSE next_state <= AS_CFI; END IF; END IF; WHEN A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; ELSE next_state <= A0SEEN; END IF; WHEN OTP => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= OTP_Z001; ELSE 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# AND PSP_ACT /= '1')THEN next_state <= OTP_A0SEEN; ELSIF DataLo = 16#25# THEN next_state <= WBPGMS_WBCNT; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_EXIT => IF falling_edge(write) THEN IF DataLo=16#00# THEN IF PSP_ACT = '1' THEN next_state <= PSP; ELSIF ESP_ACT = '1' THEN next_state <= ESP; ELSE next_state <= RESET; END IF; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; 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 = '1' THEN next_state <= SERS_EXEC; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN next_state <= ESP; ELSIF (DataLo = 16#30#) THEN next_state <= SERS; ELSE next_state <= RESET; END IF; END IF; WHEN ESPS => IF (START_E = '1') THEN next_state <= ESP; END IF; WHEN PSPS => IF (START_P = '1') THEN next_state <= PSP; 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 ESP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN next_state <= SERS_EXEC; ELSE IF PATTERN_1 THEN next_state <= ESP_Z001; ELSIF Addr = 16#55# AND DataLo = 16#98# THEN next_state <= ESP_CFI; END IF; END IF; END IF; WHEN PSP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN next_state <= PGMS; ELSE IF PATTERN_1 THEN next_state <= PSP_Z001; ELSIF Addr = 16#55# AND DataLo = 16#98# THEN next_state <= PSP_CFI; END IF; END IF; 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 ESP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= ESP_SETBWB; ELSE next_state <= ESP; END IF; END IF; WHEN PSP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= PSP_SETBWB; ELSE next_state <= PSP; END IF; END IF; WHEN ESP_SETBWB => IF falling_edge(write) THEN IF A_PAT_1 AND DataLo = 16#A0# THEN next_state <= ESP_A0SEEN; ELSIF A_PAT_1 AND DataLo = 16#90# THEN next_state <= ESP_AS; ELSIF (A_PAT_1 AND DataLo = 16#20#) THEN next_state <= ESP_ULBYPASS; ELSIF DataLo = 16#25# THEN next_state <= WBPGMS_WBCNT; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN next_state <= OTP; ELSE next_state <= ESP; END IF; END IF; WHEN PSP_SETBWB => IF falling_edge(write) THEN IF A_PAT_1 AND DataLo = 16#90# THEN next_state <= PSP_AS; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN next_state <= OTP; ELSE next_state <= PSP; 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 PSP_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= PSP; END IF; END IF; WHEN ESP_A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; 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; END IF; END IF; WHEN PSP_AS => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= PSP; ELSIF ((Addr=16#55#) AND (DataLo=16#98#)) THEN next_state <= PSP_AS_CFI; END IF; END IF; WHEN ESP_AS_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= ESP_AS; END IF; END IF; WHEN PSP_AS_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= PSP_AS; 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; ELSE IF OTP_ACT = '1' THEN next_state <= OTP; ELSE next_state <= ESP; END IF; END IF; ELSIF ULBYPASS = '1' THEN next_state <= PREL_ULBYPASS; ELSIF OTP_ACT = '1' THEN next_state <= OTP; ELSE next_state <= RESET; END IF; ELSIF falling_edge(write) THEN IF DataLo = 16#B0# AND OTP_ACT /= '1' AND ERS_QUEUE(SecAddr) /= '1' THEN next_state <= PSPS; END IF; END IF; END CASE; END IF; END PROCESS StateGen; WP_CTRL: PROCESS(WPNeg) VARIABLE Sec_Prot_reg : std_logic := '0'; BEGIN --Hardware Write Protection IF falling_edge(WPNeg) THEN Sec_Prot_reg := Sec_Prot(ProtSecNum); Sec_Prot(ProtSecNum) := '1'; ELSIF rising_edge(WPNeg) THEN Sec_Prot(ProtSecNum) := Sec_Prot_reg; END IF; END PROCESS WP_CTRL; --------------------------------------------------------------------------- --FSM Output generation and general funcionality --------------------------------------------------------------------------- Functional : PROCESS(write, read, Addr, D_tmp0,D_tmp1, Address, SecAddr, PDONE, EDONE, HANG, START_E, START_P, CTMOUT, RST, reseted, WORDNeg, READY, gOE_n, current_state) --WriteBuffer TYPE WBDataType IS ARRAY ( 0 TO 31) OF INTEGER RANGE -1 TO MaxData; TYPE WBAddrType IS ARRAY ( 0 TO 31) OF INTEGER RANGE -1 TO 31; VARIABLE WBData : WBDataType:=(OTHERS=>0); VARIABLE WBAddr : WBAddrType:=(OTHERS=>-1); VARIABLE BaseLoc : NATURAL RANGE 0 TO SecSize := 0; VARIABLE cnt : NATURAL RANGE 0 TO 31 := 0; VARIABLE PATTERN_1 : boolean := FALSE; VARIABLE PATTERN_2 : boolean := FALSE; VARIABLE A_PAT_1 : boolean := FALSE; VARIABLE oe : boolean := FALSE; --Status reg. VARIABLE Status : std_logic_vector(7 downto 0) := (OTHERS=>'0'); VARIABLE old_bit : std_logic_vector(7 downto 0); VARIABLE new_bit : std_logic_vector(7 downto 0); VARIABLE old_int : INTEGER RANGE -1 to MaxData; VARIABLE new_int : INTEGER RANGE -1 to MaxData; --DATA High WORD VARIABLE DataHi : NATURAL RANGE 0 TO MaxData := 0; --DATA Low WORD VARIABLE DataLo : NATURAL RANGE 0 TO MaxData := 0; VARIABLE temp : std_logic_vector(7 downto 0); VARIABLE i : INTEGER; VARIABLE SecSiAddr : NATURAL RANGE 0 TO SecSiSize := 0; BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- IF falling_edge(write) THEN DataLo := D_tmp0; DataHi := D_tmp1; PATTERN_1 := (Addr = 16#555#) AND (DataLo = 16#AA#) ; PATTERN_2 := (Addr = 16#2AA#) AND (DataLo = 16#55#) ; A_PAT_1 := ((Addr = 16#555#)AND (ULBYPASS = '0')) OR (ULBYPASS = '1'); END IF; oe:= rising_edge(read)OR(read = '1'AND(Address'EVENT or SecAddr'EVENT)); IF reseted = '1' THEN CASE current_state IS WHEN RESET => OTP_ACT <= '0'; ESP_ACT <= '0'; PSP_ACT <= '0'; ULBYPASS <= '0'; CTMOUT_in <= '0'; Status := (OTHERS => '0'); Ers_queue <= (OTHERS => '0'); IF oe THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, WORDNeg => WORDNeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; RY_zd <= '1'; WHEN Z001 => null; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#20#)) THEN ULBYPASS <= '1'; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN ULBYPASS <= '0'; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN OTP_ACT <= '1'; ELSIF DataLo = 16#25# THEN SA <= SecAddr; END IF; END IF; WHEN PREL_ULBYPASS => --ready signal active RY_zd <= '1'; WHEN ESP_ULBYPASS => --ready signal active RY_zd <= '1'; WHEN PREL_ULBYPASS_RESET | ESP_ULBYPASS_RESET=> IF falling_edge(write) AND (DataLo = 16#00# ) THEN ULBYPASS <= '0'; END IF; WHEN OTP => OTP_ACT <= '1'; IF oe THEN --read SecSi Sector Region SecSiAddr := Address MOD (SecSiSize +1); generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => SecSiAddr, WORDNeg => WORDNeg, SecSi_Acc => 1); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; --ready signal active RY_zd <= '1'; WHEN OTP_Z001 => null; WHEN OTP_PREL => IF falling_edge(write) THEN IF DataLo = 16#25# THEN SA <= 0; ASSERT SecAddr=0 REPORT "Invalid sector address in SecSi mode" SEVERITY warning; --activate OTP OTP_ACT <= '1'; END IF; END IF; WHEN OTP_A0SEEN | A0SEEN | ESP_A0SEEN => IF falling_edge(write) THEN PSTART <= '1', '0' AFTER 1 ns; PCNT <= 32; WBData(0) := -1; WBData(1) := -1; IF Viol = '0' THEN WBData(0) := DataLo; WBData(1) := DataHi; END IF; IF OTP_ACT /= '1' THEN WBPage <= WPage; ELSE WBPage <= WPage MOD 8; END IF; WBAddr(0) := Address MOD 32; SA <= SecAddr; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); IF OTP_ACT = '1' THEN ASSERT SecAddr = 0 REPORT "Invalid sector Address in SecSi" SEVERITY warning; ASSERT Addr > 15 REPORT "Invalid program address(ESN region)in SecSi"& " region. Address= " & to_int_str(Addr) SEVERITY warning; ASSERT Addr < 256 REPORT "Invalid program address in SecSi region. " & "Address= " & to_int_str(Addr) SEVERITY warning; END IF; IF WORDNeg = '1' THEN WBAddr(1) := WBAddr(0) + 1; ELSE WBAddr(1) := -1; END IF; END IF; WHEN CFI | AS_CFI | ESP_CFI | ESP_AS_CFI| PSP_CFI | PSP_AS_CFI => IF oe THEN IF ((Addr >= 16#10# AND Addr <= 16#3C#) OR (Addr >= 16#40# AND Addr <= 16#50#)) THEN IF (CFI_array(Addr) /= -1) THEN DOut_zd(15 downto 0) <= to_slv(CFI_array(Addr),16); IF WORDNeg = '0' THEN DOut_zd(15 downto 8) <= (OTHERS=> 'Z'); END IF; IF WORDNeg = '0' AND NOT((Address mod 2) = 0)THEN DOut_zd(7 downto 0) <= (OTHERS=> 'Z'); END IF; END IF; ELSE ASSERT FALSE REPORT "Invalid CFI query address" SEVERITY warning; DOut_zd <= (OTHERS =>'Z'); 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 --Start Chip Erase ESTART <= '1', '0' AFTER 1 ns; ESUSP <= '0'; ERES <= '0'; Ers_Queue <= (OTHERS => '1'); Status := (OTHERS => '0'); ELSIF DataLo = 16#30# THEN --put selected sector to sec. ers. queue --start timeout Ers_Queue <= (OTHERS => '0'); Ers_Queue(SecAddr) <= '1'; CTMOUT_in <= '1'; END IF; END IF; WHEN ERS => IF oe THEN ----------------------------------------------------------- -- read status / embeded erase algorithm - Chip Erase ----------------------------------------------------------- Status(7) := '0'; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; Status(2) := NOT Status(2); --toggle DOut_zd(7 downto 0) <= Status(7 downto 0); END IF; FOR i IN 0 TO SecNum LOOP IF Sec_Prot(i) /= '1' AND EERR /= '1' THEN Mem(i):= (OTHERS => -1); END IF; END LOOP; IF EDONE = '1' AND EERR /= '1' THEN FOR i IN 0 TO SecNum LOOP IF Sec_Prot(i) /= '1' THEN Mem(i):= (OTHERS => MaxData); END IF; END LOOP; END IF; -- busy signal active RY_zd <= '0'; WHEN SERS => IF CTMOUT = '1' THEN CTMOUT_in <= '0'; START_E_in <= '0'; ESTART <= '1', '0' AFTER 1 ns; ESUSP <= '0'; ERES <= '0'; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN --need to start erase process prior to suspend ESTART <= '1', '0' AFTER 1 ns; ERES <= '0'; -- CTMOUT reset CTMOUT_in <= '0'; --suspend timeout (should be 0 according to datasheet) ESUSP <= '1' AFTER 1 ns, '0' AFTER 2 ns; ELSIF (DataLo = 16#30#) THEN CTMOUT_in <= '0', '1' AFTER 1 ns; Ers_Queue(SecAddr) <= '1'; ELSE CTMOUT_in <= '0'; END IF; ELSIF oe THEN ----------------------------------------------------------- --read status - sector erase timeout ----------------------------------------------------------- Status(3) := '0'; Status(6) := NOT Status(6); DOut_zd(7 downto 0) <=Status(7 downto 0); END IF; WHEN ESPS => IF (START_E = '1') THEN ESP_ACT <= '1'; START_E_in <= '0'; ELSIF oe THEN ----------------------------------------------------------- --read status / erase suspend timeout - stil erasing ----------------------------------------------------------- IF (Ers_Queue(SecAddr)='1') THEN Status(7) := '0'; Status(2) := NOT Status(2); --toggle ELSE Status(7) := '1'; END IF; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; DOut_zd(7 downto 0) <=Status(7 downto 0); END IF; WHEN WBPGMS_WBCNT => IF falling_edge(write) THEN IF (SecAddr = SA) AND ((WORDNeg = '0' AND DataLo < 32) OR (WORDNeg = '1'AND DataLo < 16)) THEN cnt := DataLo; IF WORDNeg = '1' THEN cnt := cnt * 2; END IF; PCNT <= cnt; LCNT <= cnt; END IF; END IF; WHEN WBPGMS_WBLSTA => IF falling_edge(write) THEN IF (SecAddr = SA) THEN WBData(cnt) := -1; IF Viol = '0' THEN WBData(cnt) := DataLo; END IF; WBAddr(cnt) := Address MOD 32; IF WORDNeg = '1' THEN WBData(cnt + 1) := -1; IF Viol = '0' THEN WBData(cnt + 1) := DataHi; END IF; WBAddr(cnt + 1) := (Address MOD 32) +1; IF cnt > 0 THEN cnt := cnt -1; END IF; END IF; IF cnt > 0 THEN cnt := cnt -1; END IF; --save last loaded data for data polling temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); IF OTP_ACT = '1' THEN WBPage <= WPage MOD 8; ELSE WBPage <= WPage; END IF; ASSERT WPage<8 REPORT "Invalid Write Buffer Page selected in "& " SecSi" SEVERITY warning; END IF; LCNT <= cnt; END IF; WHEN WBPGMS_WBLOAD => IF falling_edge(write) THEN IF (WPage = WBPage)THEN WBData(cnt) := -1; IF Viol = '0' THEN WBData(cnt) := DataLo; END IF; WBAddr(cnt) := Address MOD 32; IF WORDNeg = '1' THEN WBData(cnt + 1) := -1; IF Viol = '0' THEN WBData(cnt + 1) := DataHi; END IF; WBAddr(cnt + 1) := (Address MOD 32) + 1; IF cnt > 0 THEN cnt := cnt - 1; END IF; END IF; IF cnt > 0 THEN cnt := cnt - 1; END IF; --save last loaded data for data polling temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); END IF; LCNT <= cnt; END IF; WHEN WBPGMS_CONFB => IF falling_edge(write) THEN IF (SecAddr = SA) AND (DataLo = 16#29#) THEN PSTART <= '1', '0' AFTER 1 ns; PSUSP <= '0'; PRES <= '0'; END IF; END IF; WHEN WBPGMS_WBABORT => IF oe THEN --------------------------------------------------------------- --read status / write buffer abort --------------------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(1) := '1'; DOut_zd(7 downto 0) <=Status(7 downto 0); END IF; --busy signal active RY_zd <= '0'; WHEN WBPGMS_Z001 => null; WHEN WBPGMS_PREL => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN PSP_ACT <= '0'; END IF; END IF; WHEN PSPS => IF (START_P = '1') THEN PSP_ACT <= '1'; START_P_in <= '0'; ELSIF oe THEN ----------------------------------------------------------- --read status ----------------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(1) := '0'; Status(1) := '0'; DOut_zd(7 downto 0) <=Status(7 downto 0); IF SecAddr = SA THEN DOut_zd(7) <= Status(7); ELSE DOut_zd(7) <= NOT Status(7); END IF; END IF; WHEN SERS_EXEC => IF oe THEN ----------------------------------------------------------- --read status Erase Busy ----------------------------------------------------------- IF (Ers_Queue(SecAddr) = '1') THEN Status(7) := '0'; Status(2) := NOT Status(2); --toggle ELSE Status(7) := '1'; END IF; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; DOut_zd(7 downto 0) <=Status(7 downto 0); END IF; IF EERR /= '1' THEN FOR i IN Ers_Queue'RANGE LOOP IF Ers_Queue(i) = '1' AND Sec_Prot(i) /= '1' THEN Mem(i) := (OTHERS => -1); END IF; END LOOP; IF EDONE = '1' THEN FOR i IN Ers_Queue'RANGE LOOP IF Ers_Queue(i) = '1' AND Sec_Prot(i) /= '1' THEN Mem(i) := (OTHERS => MaxData); END IF; END LOOP; ELSIF falling_edge(write) THEN IF DataLo = 16#B0# THEN START_E_in <= '1'; ESUSP <= '1', '0' AFTER 1 ns; END IF; END IF; END IF; --busy signal active RY_zd <= '0'; WHEN ESP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN --resume erase ERES <= '1', '0' AFTER 1 ns; END IF; ELSIF oe THEN ----------------------------------------------------------- --read ----------------------------------------------------------- IF Ers_Queue(SecAddr) /= '1' THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, WORDNeg => WORDNeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; ELSE ------------------------------------------------------- --read status ------------------------------------------------------- Status(7) := '1'; Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd(7 downto 0) <= Status(7 downto 0); END IF; END IF; --ready signal active RY_zd <= '1'; WHEN PSP => IF falling_edge(write) THEN IF DataLo = 16#30# THEN --resume erase PRES <= '1', '0' AFTER 1 ns; PSP_ACT <= '0'; END IF; ELSIF oe THEN ----------------------------------------------------------- --read ----------------------------------------------------------- IF Ers_Queue(SecAddr) /= '1' AND SecAddr /= SA THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, WORDNeg => WORDNeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; ELSIF Ers_Queue(SecAddr) = '1' THEN ------------------------------------------------------- --read erase suspend status ------------------------------------------------------- Status(7) := '1'; Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd(7 downto 0) <= Status(7 downto 0); END IF; END IF; --ready signal active RY_zd <= '1'; WHEN ESP_Z001 | PSP_Z001 | PSP_SETBWB => null; WHEN ESP_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#20#)) THEN ULBYPASS <= '1'; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN ULBYPASS <= '0'; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN OTP_ACT <= '1'; ELSIF DataLo = 16#25# THEN SA <= SecAddr; END IF; END IF; WHEN OTP_EXIT => IF DataLo = 16#00# THEN OTP_ACT <='0'; END IF; WHEN AS | ESP_AS | PSP_AS => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN OTP_ACT <='0'; END IF; ELSIF oe THEN IF SubAddr = 0 THEN DOut_zd(15 downto 0) <= to_slv(16#0001#,16); ELSIF SubAddr = 1 THEN DOut_zd(15 downto 0) <= to_slv(16#227E#,16); ELSIF SubAddr = 16#E# THEN DOut_zd(15 downto 0) <= to_slv(16#2212#,16); ELSIF SubAddr = 16#F# THEN DOut_zd(15 downto 0) <= to_slv(16#2201#,16); ELSIF SubAddr = 3 THEN DOut_zd(15 downto 8 ) <= to_slv(16#00#,8); DOut_zd(3 downto 0 ) <= to_slv(16#8#,4); DOut_zd(7 downto 4 ) <= FactoryProt&'0'&'0'&to_slv(ProtSec, 1); ELSIF SubAddr = 2 THEN DOut_zd(15 downto 0) <= to_slv(16#0000#,16); DOut_zd(0) <= Sec_Prot(SecAddr); ELSE DOut_zd(15 downto 0) <= to_slv(16#0000#,16); END IF; IF WORDNeg = '0' THEN DOut_zd(15 downto 8) <= (OTHERS=>'X'); END IF; END IF; WHEN PGMS => IF oe THEN ----------------------------------------------------------- --read status ----------------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(1) := '0'; Status(1) := '0'; DOut_zd(7 downto 0) <=Status(7 downto 0); IF SecAddr = SA THEN DOut_zd(7) <= Status(7); ELSE DOut_zd(7) <= NOT Status(7); END IF; END IF; IF falling_edge(write) THEN IF DataLo=16#B0# AND OTP_ACT = '0' THEN START_P_in <= '1'; PSUSP <= '1', '0' AFTER 1 ns; END IF; END IF; IF PERR/='1' THEN BaseLoc := WBPage * 32; IF PCNT < 32 THEN --buffer wr_cnt := PCNT; IF WORDNeg = '1' THEN wr_cnt := wr_cnt + 1; END IF; ELSE --DWord/Word program wr_cnt := 0; IF WORDNeg = '1' THEN wr_cnt := 1; END IF; END IF; FOR i IN wr_cnt downto 0 LOOP new_int:= WBData(i); old_int := -1; IF WBAddr(i) >= 0 THEN IF OTP_ACT /= '1' THEN --mem write old_int := Mem(SA)(BaseLoc+WBAddr(i)); ELSE old_int := SecSi(BaseLoc+WBAddr(i)); END IF; END IF; WBData(i):= -1; IF new_int>-1 THEN new_bit:=to_slv(new_int,8); IF old_int>-1 THEN old_bit:=to_slv(old_int,8); FOR j IN 0 TO 7 LOOP IF old_bit(j) = '0' THEN new_bit(j):='0'; END IF; END LOOP; new_int:=to_nat(new_bit); END IF; WBData(i):= new_int; END IF; END LOOP; FOR i IN wr_cnt downto 0 LOOP IF WBAddr(i) < 0 THEN REPORT "write buffer violation" SEVERITY warning; ELSIF OTP_ACT /= '1' THEN --mem write Mem(SA)(BaseLoc + WBAddr(i)) := -1; ELSE SecSi(BaseLoc + WBAddr(i)) := -1; END IF; END LOOP; IF HANG /= '1' AND PDONE = '1' AND (NOT PERR'EVENT) THEN FOR i IN wr_cnt downto 0 LOOP IF WBAddr(i) > -1 THEN IF OTP_ACT /= '1' THEN --mem write Mem(SA)(BaseLoc + WBAddr(i)) := WBData(i); ELSE --SecSi write SecSi(BaseLoc+WBAddr(i)) := WBData(i); END IF; ELSE ASSERT false REPORT "WriteBuffer Address error" SEVERITY warning; END IF; WBData(i) := -1; END LOOP; END IF; END IF; --busy signal active RY_zd <= '0'; END CASE; END IF; --Output Disable Control IF (gOE_n = '1') OR (gCE_n = '1') OR (RESETNeg = '0' AND RST = '0') THEN DOut_zd <= (OTHERS=>'Z'); ELSE IF (WORDNeg = '0') THEN DOut_zd(15 downto 8) <= (OTHERS =>'Z'); END IF; END IF; END PROCESS Functional; --------------------------------------------------------------------------- ---- File Read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_file : text is mem_file_name; FILE prot_file : text is prot_file_name; FILE secsi_file : text is secsi_file_name; VARIABLE S_ind : NATURAL := 0; VARIABLE ind : NATURAL RANGE 0 TO SecSize:= 0; VARIABLE buf : line; CONSTANT SecS : NATURAL := 16#10000#; CONSTANT MemSize : NATURAL := 16#1FFFFFF#;--bytes VARIABLE Sec_prot_tmp :std_logic_vector (134 downto 0); VARIABLE addr_ind : NATURAL ; VARIABLE sec_ind : NATURAL ; VARIABLE offset : NATURAL ; VARIABLE overload : boolean :=FALSE; VARIABLE line : NATURAL :=0; VARIABLE preloaded : boolean :=FALSE; BEGIN WAIT ON ProtSecNum; ----------------------------------------------------------------------- --CFI array data ----------------------------------------------------------------------- --CFI query identification string -- !!!!!! WORD ADDRESSES (x16) - for x8 addressing double addr 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#0027#; CFI_array(16#1C#) := 16#0036#; CFI_array(16#1D#) := 16#0000#; CFI_array(16#1E#) := 16#0000#; CFI_array(16#1F#) := 16#0007#; CFI_array(16#20#) := 16#0007#; CFI_array(16#21#) := 16#000A#; CFI_array(16#22#) := 16#0000#; CFI_array(16#23#) := 16#0001#; CFI_array(16#24#) := 16#0005#; CFI_array(16#25#) := 16#0004#; CFI_array(16#26#) := 16#0000#; --device geometry definition CFI_array(16#27#) := 16#0019#; CFI_array(16#28#) := 16#0002#; CFI_array(16#29#) := 16#0000#; CFI_array(16#2A#) := 16#0005#; CFI_array(16#2B#) := 16#0000#; CFI_array(16#2C#) := 16#0001#; CFI_array(16#2D#) := 16#01FF#; CFI_array(16#2E#) := 16#0001#; 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#0033#; CFI_array(16#45#) := 16#0008#; CFI_array(16#46#) := 16#0002#; CFI_array(16#47#) := 16#0001#; 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#0001#; CFI_array(16#4D#) := 16#00B5#; CFI_array(16#4E#) := 16#00C5#; CFI_array(16#4F#) := 16#0000# + (16#0001# * (4+ProtSec)); CFI_array(16#50#) := 16#0001#; IF (mem_file_name /= "none" AND UserPreload ) THEN -------------------------------------------------------------------- -----am29lv2562m memory preload file format ------------------------ -------------------------------------------------------------------- -- / - comment -- @aaaaaaa - stands for address within Memory -- dd -
is byte to be written at Mem(aaaaaaa++) -- (aaaaaaa is incremented at every load) -- only first 1-8 columns are loaded. NO empty lines !!!!!!!!!!!!! -------------------------------------------------------------------- addr_ind := 0; Mem := (OTHERS => (OTHERS => MaxData)); WHILE (not ENDFILE (mem_file)) LOOP READLINE (mem_file, buf); line := line +1; IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 8)); 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 2)); addr_ind := (addr_ind + 1); sec_ind := addr_ind / SecS; offset := addr_ind - ( sec_ind * SecS ); ELSE ASSERT overload /= FALSE REPORT "file: "&mem_file_name&" has size larger than " &to_int_str(MemSize)&" at line "&to_int_str(line) SEVERITY Note; overload := TRUE; END IF; END IF; END LOOP; END IF; IF (prot_file_name /= "none" AND UserPreload ) THEN -------------------------------------------------------------------- -----am29lv2562m sector protect preload file format ---------------- -------------------------------------------------------------------- -- / - comment -- @sss - stands for sector number -- d - is bit to be written at SecProt(sss++) -- (sec is incremented at every load) -- (At last(134) position is Factory protection) -- only first 1-4 columns are loaded. NO empty lines !!!!!!!!!!!!! -------------------------------------------------------------------- -------------------------------------------------------------------- ind := 0; Sec_Prot := (OTHERS => '0'); Sec_prot_tmp := (OTHERS => '0'); WHILE (not ENDFILE (prot_file)) LOOP READLINE (prot_file, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 4)); ELSE IF addr_ind <= 134 THEN IF buf(1) = '1' THEN Sec_prot_tmp (addr_ind) := '1'; ELSE Sec_prot_tmp (addr_ind) := '0'; END IF; addr_ind := addr_ind + 1; END IF; END IF; END LOOP; Sec_Prot(0) := Sec_prot_tmp(0); Sec_Prot(1) := Sec_prot_tmp(1); Sec_Prot(2) := Sec_prot_tmp(2); Sec_Prot(3) := Sec_prot_tmp(3); Sec_Prot(508):= Sec_prot_tmp(130); Sec_Prot(509):= Sec_prot_tmp(131); Sec_Prot(510):= Sec_prot_tmp(132); Sec_Prot(511):= Sec_prot_tmp(133); FactoryProt <= Sec_prot_tmp(134); FOR i IN 4 TO 507 LOOP Sec_Prot(i) := Sec_prot_tmp((i/4)+3); END LOOP; END IF; -------------------------------------------------------------- -- am29lv2562m SecSi preload file format --------------------------------------------------------------- -- / - comment -- @aa - stands for address within SecSi -- dd -
is byte to be written at SecSi(aa++) -- (aa is incremented at every load) -- only first 1-3 columns are loaded. NO empty lines !!!!!!!! --------------------------------------------------------------- IF (SecSi_file_name /= "none" AND UserPreload ) THEN SecSi := (OTHERS => MaxData); ind := 0; WHILE (not ENDFILE (SecSi_file)) LOOP READLINE (SecSi_file, buf); IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN ind := h(buf(2 TO 3)); ELSE IF ind <= SecSiSize THEN SecSi(ind) := h(buf(1 TO 2)); ind := ind + 1; END IF; END IF; END LOOP; END IF; END PROCESS MemPreload; DOutPassThrough : PROCESS(DOut_zd) VARIABLE ValidData : std_logic_vector(15 downto 0); VARIABLE CEDQ_t : TIME; VARIABLE OEDQ_t : TIME; VARIABLE ADDRDQ_t : TIME; BEGIN IF DOut_zd(0) /= 'Z' THEN OPENLATCH := TRUE; CEDQ_t := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(trz0); OEDQ_t := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(trz0); ADDRDQ_t := -A'LAST_EVENT + tpd_A0_DQ0_rdPage_eq_0(tr01); IF ( WORDNeg = '0' ) AND (DIn(15)'LAST_EVENT < A'LAST_EVENT) THEN ADDRDQ_t := -DIn(15)'LAST_EVENT + tpd_A0_DQ0_rdPage_eq_0(tr01); END IF; FROMOE := (OEDQ_t >= CEDQ_t) AND (OEDQ_t > 0 ns); FROMCE := (CEDQ_t > OEDQ_t) AND (CEDQ_t > 0 ns); IF WORDNeg = '0' THEN ValidData := "ZZZZZZZZXXXXXXXX"; ELSE ValidData := "XXXXXXXXXXXXXXXX"; END IF; IF ((ADDRDQ_t > 0 ns) AND (((ADDRDQ_t > CEDQ_t) AND FROMCE) OR ((ADDRDQ_t > OEDQ_t) AND FROMOE))) THEN DOut_Pass <= ValidData, DOut_zd AFTER ADDRDQ_t; ELSE DOut_Pass <= DOut_zd; END IF; ELSE CEDQ_t := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(tr0z); OEDQ_t := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(tr0z); FROMOE := (OEDQ_t <= CEDQ_t) AND (OEDQ_t > 0 ns); FROMCE := (CEDQ_t < OEDQ_t) AND (CEDQ_t > 0 ns); DOut_Pass <= DOut_zd; OPENLATCH := FALSE; DOut_Pass <= DOut_zd; END IF; END PROCESS DOutPassThrough; -- read page process PD_PAGE : PROCESS (read, A, DIn(15)) VARIABLE Address_page : std_logic_vector(HiAddrBit-2 DOWNTO 0); BEGIN IF rising_edge(read) THEN Address_page := A(HiAddrBit DOWNTO 2); ELSIF (A'event OR(DIn(15)'event AND WORDNeg = '0')) AND read = '1' AND reseted = '1' THEN IF A(HiAddrBit DOWNTO 2) = Address_page THEN page_read := TRUE; ELSE page_read := FALSE; Address_page := A(HiAddrBit DOWNTO 2); END IF; ELSE page_read := FALSE; END IF; END PROCESS PD_PAGE; ----------------------------------------------------------------------- -- Path Delay Section ----------------------------------------------------------------------- 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 7 GENERATE PROCESS(DOut_Pass(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_Pass(i), GlitchData => D0_GlitchData, IgnoreDefaultDelay => TRUE, Mode => VitalTransport, RejectFastPath => FALSE, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMOE) OR (OPENLATCH AND FROMCE)), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMCE) OR (OPENLATCH AND FROMOE)), 2 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_1), PathCondition => NOT FROMOE AND NOT FROMCE AND page_read), 3 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_0), PathCondition => NOT FROMOE AND NOT FROMCE AND NOT page_read), 4 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_1), PathCondition => WORDNeg = '0' AND DOut_pass(i) /= 'X' AND page_read), 5 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_0), PathCondition => WORDNeg = '0' AND DOut_pass(i) /= 'X' AND NOT page_read), 6 => (InputChangeTime => RESETNeg'LAST_EVENT, PathDelay => tpd_RESETNeg_DQ0, PathCondition => RESETNeg='0') ) ); END PROCESS; END GENERATE D_Out_PathDelay_Gen; --------------------------------------------------------------------------- -- Path Delay Section for DOut signal --------------------------------------------------------------------------- D_Out_15_8_PathDelay_Gen : FOR i IN 8 TO 15 GENERATE PROCESS(DOut_Pass(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_Pass(i), GlitchData => D0_GlitchData, IgnoreDefaultDelay => TRUE, Mode => VitalTransport, RejectFastPath => FALSE, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMOE) OR (OPENLATCH AND FROMCE)), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMCE) OR (OPENLATCH AND FROMOE)), 2 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_1), PathCondition => NOT FROMOE AND NOT FROMCE AND page_read), 3 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_0), PathCondition => NOT FROMOE AND NOT FROMCE AND NOT page_read), 4 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_1), PathCondition => WORDNeg = '0' AND DOut_pass(i) /= 'X' AND page_read), 5 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_rdPage_eq_0), PathCondition => WORDNeg = '0' AND DOut_pass(i) /= 'X' AND NOT page_read), 6 => (InputChangeTime => RESETNeg'LAST_EVENT, PathDelay => tpd_RESETNeg_DQ0, PathCondition => RESETNeg='0') ) ); END PROCESS; END GENERATE D_Out_15_8_PathDelay_Gen; END BLOCK behavior; END vhdl_behavioral_static_falsh; ------------------------------------------------------------------------------ -- ARCHITECTURE DECLARATION FOR TOP am29lv2562m ENTITY ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral_dynamic_memory_allocation of am29lv2562m IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral_dynamic_memory_allocation : ARCHITECTURE IS TRUE; COMPONENT am29lv2562m_flash -- tipd delays: interconnect path delays 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_A22 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A23 : 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_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WORDNeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays tpd_RESETNeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; tpd_A0_DQ0_rdPage_eq_0 : VitalDelayType01 := UnitDelay01;--tACC tpd_A0_DQ0_rdPage_eq_1 : VitalDelayType01 := UnitDelay01;--tPACC tpd_CENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; --(tCE,tCE,tDF,-,tDF,-) tpd_OENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; --(tOE,tOE,tDF,-,tDF,-) tpd_WENeg_RY : VitalDelayType01Z := UnitDelay01Z;--tBUSY --tsetup values tsetup_A0_CENeg : VitalDelayType := UnitDelay; --tAS edge \ tsetup_A0_OENeg : VitalDelayType := UnitDelay; tsetup_DQ0_CENeg : VitalDelayType := UnitDelay; --tDS edge / tsetup_OENeg_WENeg : VitalDelayType := UnitDelay; --0,edge / tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; --0 ns / --thold values thold_A0_CENeg : VitalDelayType := UnitDelay; --tAH edge \ thold_DQ0_CENeg : VitalDelayType := UnitDelay; --tDH edge / thold_OENeg_WENeg : VitalDelayType := UnitDelay; --10,toeh,edge / thold_CENeg_WENeg : VitalDelayType := UnitDelay; --tGHVL edge / thold_CENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH edge / --tpw values: pulse width 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_A0_negedge : VitalDelayType := UnitDelay; --tWC tRC(90-70) -- tdevice values: values for internal delays --Effective Write Buffer Program Operation tWHWH1 tdevice_WBPB : VitalDelayType := UnitDelay; --Program Operation --word write tdevice_POW : VitalDelayType := UnitDelay; --unlock bypass write tdevice_POU : VitalDelayType := UnitDelay; --Sector Erase Operation tWHWH2 tdevice_SEO : VitalDelayType := UnitDelay; --Timing Limit Exceeded tdevice_HANG : VitalDelayType := UnitDelay; --erase suspend timeout tdevice_STARTE : VitalDelayType := UnitDelay; --program suspend timeout tdevice_STARTP : VitalDelayType := UnitDelay; --sector erase command sequence timeout tdevice_CTMOUTP : VitalDelayType := UnitDelay; --device ready after Hardware reset(during embeded algorithm) tdevice_READYP : VitalDelayType := UnitDelay; --tReady -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- memory file to be loaded mem_file_name : STRING := "am29lv2562m.mem"; prot_file_name : STRING := "am29lv2562m_prot.mem"; secsi_file_name : STRING := "am29lv2562m_secsi.mem"; UserPreload : BOOLEAN := TRUE; LongTimming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( A23 : IN std_ulogic := 'U'; -- A22 : IN std_ulogic := 'U'; -- 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_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'; -- data DQ8 : INOUT std_ulogic := 'U'; -- lines 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'; WPNeg : IN std_ulogic := 'U'; WORDNeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U' --RY/BY# ); END COMPONENT; FOR FLASH_1: am29lv2562m_flash USE ENTITY WORK.am29lv2562m_flash(vhdl_behavioral_dynamic_flash); FOR FLASH_2: am29lv2562m_flash USE ENTITY WORK.am29lv2562m_flash(vhdl_behavioral_dynamic_flash); BEGIN FLASH_1 : am29lv2562m_flash 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_A22 => tipd_A22, tipd_A23 => tipd_A23, 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_DQ16, tipd_DQ9 => tipd_DQ17, tipd_DQ10 => tipd_DQ18, tipd_DQ11 => tipd_DQ19, tipd_DQ12 => tipd_DQ20, tipd_DQ13 => tipd_DQ21, tipd_DQ14 => tipd_DQ22, tipd_DQ15 => tipd_DQ23, tipd_CENeg => tipd_CENeg, tipd_OENeg => tipd_OENeg, tipd_WENeg => tipd_WENeg, tipd_RESETNeg => tipd_RESETNeg, tipd_WPNeg => tipd_WPNeg, tipd_WORDNeg => tipd_WORDNeg, -- generic control parameters InstancePath => InstancePath, TimingChecksOn => TimingChecksOn, MsgOn => MsgOn, XOn => XOn, -- memory file to be loaded mem_file_name => mem_file_name1, prot_file_name => prot_file_name, secsi_file_name => secsi_file_name1, UserPreload => UserPreload, LongTimming => LongTimming, -- For FMF SDF technology file usage TimingModel => TimingModel ) PORT MAP( A23 => A23, A22 => A22, 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 => DQ23, DQ14 => DQ22, DQ13 => DQ21, DQ12 => DQ20, DQ11 => DQ19, DQ10 => DQ18, DQ9 => DQ17, DQ8 => DQ16, DQ7 => DQ7, DQ6 => DQ6, DQ5 => DQ5, DQ4 => DQ4, DQ3 => DQ3, DQ2 => DQ2, DQ1 => DQ1, DQ0 => DQ0, CENeg => CENeg, OENeg => OENeg, WENeg => WENeg, RESETNeg => RESETNeg, WPNeg => WPNeg, RY => RY, WORDNeg => WORDNeg ); FLASH_2 : am29lv2562m_flash 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_A22 => tipd_A22, tipd_A23 => tipd_A23, tipd_DQ0 => tipd_DQ8, tipd_DQ1 => tipd_DQ9, tipd_DQ2 => tipd_DQ10, tipd_DQ3 => tipd_DQ11, tipd_DQ4 => tipd_DQ12, tipd_DQ5 => tipd_DQ13, tipd_DQ6 => tipd_DQ14, tipd_DQ7 => tipd_DQ15, tipd_DQ8 => tipd_DQ24, tipd_DQ9 => tipd_DQ25, tipd_DQ10 => tipd_DQ26, tipd_DQ11 => tipd_DQ27, tipd_DQ12 => tipd_DQ28, tipd_DQ13 => tipd_DQ29, tipd_DQ14 => tipd_DQ30, tipd_DQ15 => tipd_DQ31, tipd_CENeg => tipd_CENeg, tipd_OENeg => tipd_OENeg, tipd_WENeg => tipd_WENeg, tipd_RESETNeg => tipd_RESETNeg, tipd_WPNeg => tipd_WPNeg, tipd_WORDNeg => tipd_WORDNeg, -- generic control parameters InstancePath => InstancePath, TimingChecksOn => TimingChecksOn, MsgOn => MsgOn, XOn => XOn, -- memory file to be loaded mem_file_name => mem_file_name2, prot_file_name => prot_file_name, secsi_file_name => secsi_file_name2, UserPreload => UserPreload, LongTimming => LongTimming, -- For FMF SDF technology file usage TimingModel => TimingModel ) PORT MAP( A23 => A23, A22 => A22, 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 => DQ31, DQ14 => DQ30, DQ13 => DQ29, DQ12 => DQ28, DQ11 => DQ27, DQ10 => DQ26, DQ9 => DQ25, DQ8 => DQ24, DQ7 => DQ15, DQ6 => DQ14, DQ5 => DQ13, DQ4 => DQ12, DQ3 => DQ11, DQ2 => DQ10, DQ1 => DQ9, DQ0 => DQ8, CENeg => CENeg, OENeg => OENeg, WENeg => WENeg, RESETNeg => RESETNeg, WPNeg => WPNeg, RY => RY, WORDNeg => WORDNeg ); END vhdl_behavioral_dynamic_memory_allocation; ------------------------------------------------------------------------------ -- ARCHITECTURE DECLARATION FOR TOP am29lv2562m ENTITY ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral_static_memory_allocation of am29lv2562m IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral_static_memory_allocation : ARCHITECTURE IS TRUE; COMPONENT am29lv2562m_flash -- tipd delays: interconnect path delays 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_A22 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A23 : 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_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WORDNeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays tpd_RESETNeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; tpd_A0_DQ0_rdPage_eq_0 : VitalDelayType01 := UnitDelay01;--tACC tpd_A0_DQ0_rdPage_eq_1 : VitalDelayType01 := UnitDelay01;--tPACC tpd_CENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; --(tCE,tCE,tDF,-,tDF,-) tpd_OENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; --(tOE,tOE,tDF,-,tDF,-) tpd_WENeg_RY : VitalDelayType01Z := UnitDelay01Z;--tBUSY --tsetup values tsetup_A0_CENeg : VitalDelayType := UnitDelay; --tAS edge \ tsetup_A0_OENeg : VitalDelayType := UnitDelay; tsetup_DQ0_CENeg : VitalDelayType := UnitDelay; --tDS edge / tsetup_OENeg_WENeg : VitalDelayType := UnitDelay; --0,edge / tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; --0 ns / --thold values thold_A0_CENeg : VitalDelayType := UnitDelay; --tAH edge \ thold_DQ0_CENeg : VitalDelayType := UnitDelay; --tDH edge / thold_OENeg_WENeg : VitalDelayType := UnitDelay; --10,toeh,edge / thold_CENeg_WENeg : VitalDelayType := UnitDelay; --tGHVL edge / thold_CENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH edge / --tpw values: pulse width 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_A0_negedge : VitalDelayType := UnitDelay; --tWC tRC(90-70) -- tdevice values: values for internal delays --Effective Write Buffer Program Operation tWHWH1 tdevice_WBPB : VitalDelayType := UnitDelay; --Program Operation --word write tdevice_POW : VitalDelayType := UnitDelay; --unlock bypass write tdevice_POU : VitalDelayType := UnitDelay; --Sector Erase Operation tWHWH2 tdevice_SEO : VitalDelayType := UnitDelay; --Timing Limit Exceeded tdevice_HANG : VitalDelayType := UnitDelay; --erase suspend timeout tdevice_STARTE : VitalDelayType := UnitDelay; --program suspend timeout tdevice_STARTP : VitalDelayType := UnitDelay; --sector erase command sequence timeout tdevice_CTMOUTP : VitalDelayType := UnitDelay; --device ready after Hardware reset(during embeded algorithm) tdevice_READYP : VitalDelayType := UnitDelay; --tReady -- 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";--"am29lv2562m.mem"; prot_file_name : STRING := "none";--"am29lv2562m_prot.mem"; secsi_file_name : STRING := "none";--"am29lv2562m_secsi.mem"; UserPreload : BOOLEAN := FALSE; LongTimming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( A23 : IN std_ulogic := 'U'; -- A22 : IN std_ulogic := 'U'; -- 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_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'; -- data DQ8 : INOUT std_ulogic := 'U'; -- lines 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'; WPNeg : IN std_ulogic := 'U'; WORDNeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U' --RY/BY# ); END COMPONENT; FOR FLASH_1: am29lv2562m_flash USE ENTITY WORK.am29lv2562m_flash(vhdl_behavioral_static_falsh); FOR FLASH_2: am29lv2562m_flash USE ENTITY WORK.am29lv2562m_flash(vhdl_behavioral_static_falsh); BEGIN FLASH_1 : am29lv2562m_flash 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_A22 => tipd_A22, tipd_A23 => tipd_A23, 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_DQ16, tipd_DQ9 => tipd_DQ17, tipd_DQ10 => tipd_DQ18, tipd_DQ11 => tipd_DQ19, tipd_DQ12 => tipd_DQ20, tipd_DQ13 => tipd_DQ21, tipd_DQ14 => tipd_DQ22, tipd_DQ15 => tipd_DQ23, tipd_CENeg => tipd_CENeg, tipd_OENeg => tipd_OENeg, tipd_WENeg => tipd_WENeg, tipd_RESETNeg => tipd_RESETNeg, tipd_WPNeg => tipd_WPNeg, tipd_WORDNeg => tipd_WORDNeg, -- generic control parameters InstancePath => InstancePath, TimingChecksOn => TimingChecksOn, MsgOn => MsgOn, XOn => XOn, -- memory file to be loaded mem_file_name => mem_file_name1, prot_file_name => prot_file_name, secsi_file_name => secsi_file_name1, UserPreload => UserPreload, LongTimming => LongTimming, -- For FMF SDF technology file usage TimingModel => TimingModel ) PORT MAP( A23 => A23, A22 => A22, 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 => DQ23, DQ14 => DQ22, DQ13 => DQ21, DQ12 => DQ20, DQ11 => DQ19, DQ10 => DQ18, DQ9 => DQ17, DQ8 => DQ16, DQ7 => DQ7, DQ6 => DQ6, DQ5 => DQ5, DQ4 => DQ4, DQ3 => DQ3, DQ2 => DQ2, DQ1 => DQ1, DQ0 => DQ0, CENeg => CENeg, OENeg => OENeg, WENeg => WENeg, RESETNeg => RESETNeg, WPNeg => WPNeg, RY => RY, WORDNeg => WORDNeg ); FLASH_2 : am29lv2562m_flash 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_A22 => tipd_A22, tipd_A23 => tipd_A23, tipd_DQ0 => tipd_DQ8, tipd_DQ1 => tipd_DQ9, tipd_DQ2 => tipd_DQ10, tipd_DQ3 => tipd_DQ11, tipd_DQ4 => tipd_DQ12, tipd_DQ5 => tipd_DQ13, tipd_DQ6 => tipd_DQ14, tipd_DQ7 => tipd_DQ15, tipd_DQ8 => tipd_DQ24, tipd_DQ9 => tipd_DQ25, tipd_DQ10 => tipd_DQ26, tipd_DQ11 => tipd_DQ27, tipd_DQ12 => tipd_DQ28, tipd_DQ13 => tipd_DQ29, tipd_DQ14 => tipd_DQ30, tipd_DQ15 => tipd_DQ31, tipd_CENeg => tipd_CENeg, tipd_OENeg => tipd_OENeg, tipd_WENeg => tipd_WENeg, tipd_RESETNeg => tipd_RESETNeg, tipd_WPNeg => tipd_WPNeg, tipd_WORDNeg => tipd_WORDNeg, -- generic control parameters InstancePath => InstancePath, TimingChecksOn => TimingChecksOn, MsgOn => MsgOn, XOn => XOn, -- memory file to be loaded mem_file_name => mem_file_name2, prot_file_name => prot_file_name, secsi_file_name => secsi_file_name2, UserPreload => UserPreload, LongTimming => LongTimming, -- For FMF SDF technology file usage TimingModel => TimingModel ) PORT MAP( A23 => A23, A22 => A22, 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 => DQ31, DQ14 => DQ30, DQ13 => DQ29, DQ12 => DQ28, DQ11 => DQ27, DQ10 => DQ26, DQ9 => DQ25, DQ8 => DQ24, DQ7 => DQ15, DQ6 => DQ14, DQ5 => DQ13, DQ4 => DQ12, DQ3 => DQ11, DQ2 => DQ10, DQ1 => DQ9, DQ0 => DQ8, CENeg => CENeg, OENeg => OENeg, WENeg => WENeg, RESETNeg => RESETNeg, WPNeg => WPNeg, RY => RY, WORDNeg => WORDNeg ); END vhdl_behavioral_static_memory_allocation;