------------------------------------------------------------------------------- -- File name : am29bdd320g.vhd ------------------------------------------------------------------------------- -- Copyright (C) 2003-2004 Free Model Foundry; http://www.FreeModelFoundry.com -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License version 2 as -- published by the Free Software Foundation. -- -- MODIFICATION HISTORY : -- -- version: | author: | mod date: | changes made: -- V1.0 A.Savic 03 Sep 12 Initial release -- V1.1 A.Savic 04 Jan 16 SM illegal commands fix -- WP# pin erase protection fix -- tdevice_CERASE removed -- RDY is an open drain output -- No bank restriction for Sector Erase -- Suspended/Resumed for all banks. -- VitalBUF primitives section changed for -- VHDL NC Sim SDF annotation -- Preload section update - sector -- contents independent preload -- ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: AMD -- Technology: Flash Memory -- Part: AM29BDD320G -- -- Description: 32Mbit (1M x32-Bit/2M x16-Bit) -- Burst Mode, Dual Boot, Simultaneous Read -- ------------------------------------------------------------------------------- -- 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 ------------------------------------------------------------------------------- ENTITY AM29BDD320G IS GENERIC ( -- tipd delays: interconnect path delays tipd_Am1 : VitalDelayType01 := VitalZeroDelay01; tipd_A0 : VitalDelayType01 := VitalZeroDelay01; tipd_A1 : VitalDelayType01 := VitalZeroDelay01; tipd_A2 : VitalDelayType01 := VitalZeroDelay01; tipd_A3 : VitalDelayType01 := VitalZeroDelay01; tipd_A4 : VitalDelayType01 := VitalZeroDelay01; tipd_A5 : VitalDelayType01 := VitalZeroDelay01; tipd_A6 : VitalDelayType01 := VitalZeroDelay01; tipd_A7 : VitalDelayType01 := VitalZeroDelay01; tipd_A8 : VitalDelayType01 := VitalZeroDelay01; tipd_A9 : VitalDelayType01 := VitalZeroDelay01; tipd_A10 : VitalDelayType01 := VitalZeroDelay01; tipd_A11 : VitalDelayType01 := VitalZeroDelay01; tipd_A12 : VitalDelayType01 := VitalZeroDelay01; tipd_A13 : VitalDelayType01 := VitalZeroDelay01; tipd_A14 : VitalDelayType01 := VitalZeroDelay01; tipd_A15 : VitalDelayType01 := VitalZeroDelay01; tipd_A16 : VitalDelayType01 := VitalZeroDelay01; tipd_A17 : VitalDelayType01 := VitalZeroDelay01; tipd_A18 : VitalDelayType01 := VitalZeroDelay01; tipd_A19 : VitalDelayType01 := VitalZeroDelay01; tipd_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; tipd_ADVNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WORDNeg : VitalDelayType01 := VitalZeroDelay01; tipd_CLK : 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; -- -- tpd delays -- Asynchronous Read tpd_A0_DQ0 : VitalDelayType01 := VitalZeroDelay01; -- tACC tpd_CENeg_DQ0 : VitalDelayType01Z:= VitalZeroDelay01Z; -- tCE,tDF,tCEZ tpd_OENeg_DQ0 : VitalDelayType01Z:= VitalZeroDelay01Z; -- tOE,tDF,tOEZ -- Burst Mode tpd_CLK_DQ0 : VitalDelayType01:= VitalZeroDelay01; -- tBACC tpd_CLK_INDNeg : VitalDelayType01:= VitalZeroDelay01; -- tDIND -- Program operation tpd_WENeg_RY : VitalDelayType01Z := VitalZeroDelay01Z; -- tBUSY tpd_CENeg_RY : VitalDelayType01Z := VitalZeroDelay01Z; -- tBUSY -- tsetup values -- Burst Mode tsetup_CENeg_CLK : VitalDelayType := UnitDelay; --tCES, CE LOW , CLK / tsetup_ADVNeg_CLK : VitalDelayType := UnitDelay; --tADVCS, ADVNeg LOW, CLK / tsetup_A0_CLK : VitalDelayType := UnitDelay; --tACS , ,CLK / -- Asynchronous Write tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; --tCS, CENeg LOW, WENeg \ tsetup_A0_WENeg : VitalDelayType := UnitDelay; --tAS, , WENeg \ tsetup_DQ0_WENeg : VitalDelayType := UnitDelay; --tDS, , WENeg / -- Synchronous Write tsetup_WENeg_CLK : VitalDelayType := UnitDelay; --tWCKS , WENeg HIGH, CLK / tsetup_WENeg_ADVNeg : VitalDelayType := UnitDelay; --tWADVS, WENeg HIGH, ADV \ -- Write Protect tsetup_WPNeg_WENeg : VitalDelayType := UnitDelay; --tWPWS, , WENeg / -- CE Controlled Write tsetup_WENeg_CENeg : VitalDelayType := UnitDelay; --tWS , WENeg LOW , CENeg \ --thold values -- Burst Mode thold_ADVNeg_CLK : VitalDelayType := UnitDelay; -- tADVCH, ADVNeg LOW, CLK / thold_A0_CLK : VitalDelayType := UnitDelay; -- tACH, , CLK / -- Asynchronous Write thold_CENeg_WENeg : VitalDelayType := UnitDelay; -- tCH, CENeg LOW, WENeg / thold_A0_WENeg : VitalDelayType := UnitDelay; -- tAH, , WENeg \ thold_DQ0_WENeg : VitalDelayType := UnitDelay; -- tDH, , WENeg / -- Sync Write thold_WENeg_ADVNeg : VitalDelayType := UnitDelay; -- tWADVH, WENeg HIGH, ADVNeg \ -- Reset thold_CENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH , CENeg HIGH, RESET / thold_OENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH , OENeg HIGH, RESET / thold_WENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH,WENeg HIGH, RESET / -- Write Protect -- Back to Back thold_OENeg_WENeg : VitalDelayType := UnitDelay; --tOEH,OENeg HIGH,WENeg \ -- CENeg Controlled Write thold_WENeg_CENeg : VitalDelayType := UnitDelay; --tWH ,WENeg LOW ,CENeg / thold_WENeg_OENeg : VitalDelayType := UnitDelay; --tOEH,WENeg HIGH,OENeg \ --tpw values: pulse width -- Burst Mode tpw_ADVNeg_negedge : VitalDelayType := UnitDelay; -- tADVP -- Reset tpw_RESETNeg_negedge : VitalDelayType := UnitDelay; -- tRP -- Sync Write tpw_WENeg_negedge : VitalDelayType := UnitDelay; -- tWP -- Program Operation tpw_WENeg_posedge : VitalDelayType := UnitDelay; -- tWPH -- Back to Back tpw_CENeg_negedge : VitalDelayType := UnitDelay; -- tCP tpw_CENeg_posedge : VitalDelayType := UnitDelay; -- tCPH tpw_CLK_posedge : VitalDelayType := UnitDelay; -- tCH tpw_CLK_negedge : VitalDelayType := UnitDelay; -- tCL -- trecovery values : recovery times -- Back to Back ( Read recovery before Write ) trecovery_OENeg_WENeg : VitalDelayType := UnitDelay; --tGHWL,WENeg HIGH,OENeg / -- CE Controlled Write trecovery_OENeg_CENeg : VitalDelayType := UnitDelay; --tGHEL,CENeg HIGH,OENeg / tperiod_CLK : VitalDelayType := UnitDelay; -- tdevice values: values for internal delays tdevice_WPProg : VitalDelayType := UnitDelay; tdevice_PErase : VitalDelayType := UnitDelay; tdevice_SUSPEND : VitalDelayType := UnitDelay; tdevice_SAWIN : VitalDelayType := UnitDelay; tdevice_UNLOCK : VitalDelayType := UnitDelay; tdevice_SE : VitalDelayType := UnitDelay; tdevice_EPA16 : VitalDelayType := UnitDelay; tdevice_EPA32 : VitalDelayType := UnitDelay; tdevice_RESEMB : VItalDelayType := UnitDelay; tdevice_NVPROG : VItalDelayType := UnitDelay; tdevice_NVErs : VItalDelayType := UnitDelay; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; mem_file_name : STRING := "none"; secsi_file_name : STRING := "none"; prot_file_name : STRING := "none"; UserPreload : BOOLEAN := FALSE; TimingModel : STRING := DefaultTimingModel ); PORT ( A19 : IN std_ulogic := 'U'; -- A18 : IN std_ulogic := 'U'; -- A17 : IN std_ulogic := 'U'; -- A16 : IN std_ulogic := 'U'; -- A15 : IN std_ulogic := 'U'; -- A14 : IN std_ulogic := 'U'; -- A13 : IN std_ulogic := 'U'; -- A12 : IN std_ulogic := 'U'; -- A11 : IN std_ulogic := 'U'; -- A10 : IN std_ulogic := 'U'; -- A9 : IN std_ulogic := 'U'; --address A8 : IN std_ulogic := 'U'; --lines 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'; -- Am1 : IN std_ulogic := 'U'; -- CENeg : IN std_ulogic := 'U'; -- Chip Enable OENeg : IN std_ulogic := 'U'; -- Output Enable WENeg : IN std_ulogic := 'U'; -- Write Enable RESETNeg : IN std_ulogic := 'U'; ADVNeg : IN std_ulogic := 'U'; -- Address Valid WPNeg : IN std_ulogic := 'U'; -- Write Protect WORDNeg : IN std_ulogic := 'U'; -- 16/32 - bit mode CLK : IN std_ulogic := 'U'; DQ31 : INOUT std_ulogic := 'U'; -- 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'; -- DQ24 : INOUT std_ulogic := 'U'; -- 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'; -- INDNeg : OUT std_ulogic := 'U'; -- Burst finished RY : OUT std_ulogic := 'U' -- Ready/Busy ); ATTRIBUTE VITAL_LEVEL0 of AM29BDD320G : ENTITY IS TRUE; END AM29BDD320G; ARCHITECTURE vhdl_behavioral of AM29BDD320G IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "AM29BDD320G" ; CONSTANT HiAddrBit : NATURAL := 19; CONSTANT DBWidth : NATURAL := 31; CONSTANT ADDRRange : NATURAL := 16#1FFFFF#; CONSTANT SecNum : NATURAL := 77; CONSTANT GroupNum : NATURAL := 31; CONSTANT SecSiSize : NATURAL := 128; -- 0..127 word CONSTANT MaxData : NATURAL := 16#FFFF#; CONSTANT OW0 : STD_LOGIC_VECTOR ( 5 downto 0 ) := "011010"; CONSTANT OW1 : STD_LOGIC_VECTOR ( 5 downto 0 ) := "011110"; CONSTANT PL0 : STD_LOGIC_VECTOR ( 5 downto 0 ) := "001010"; CONSTANT PL1 : STD_LOGIC_VECTOR ( 5 downto 0 ) := "001110"; CONSTANT SL0 : STD_LOGIC_VECTOR ( 5 downto 0 ) := "010010"; CONSTANT SL1 : STD_LOGIC_VECTOR ( 5 downto 0 ) := "010110"; CONSTANT WP0 : STD_LOGIC_VECTOR ( 5 downto 0 ) := "111010"; CONSTANT WP1 : STD_LOGIC_VECTOR ( 5 downto 0 ) := "111110"; CONSTANT tcomm : TIME := 1 ns; CONSTANT ttran : TIME := 10 ns; CONSTANT ZZZ : std_logic_vector(15 downto 0) := "ZZZZZZZZZZZZZZZZ"; CONSTANT Zero : std_logic_vector(15 downto 0) := "0000000000000000"; CONSTANT FFF : std_logic_vector(15 downto 0) := "1111111111111111"; -- interconnect path delay signals 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 Am1_ipd : std_ulogic := 'U'; SIGNAL DQ31_ipd : std_ulogic := 'U'; SIGNAL DQ30_ipd : std_ulogic := 'U'; SIGNAL DQ29_ipd : std_ulogic := 'U'; SIGNAL DQ28_ipd : std_ulogic := 'U'; SIGNAL DQ27_ipd : std_ulogic := 'U'; SIGNAL DQ26_ipd : std_ulogic := 'U'; SIGNAL DQ25_ipd : std_ulogic := 'U'; SIGNAL DQ24_ipd : std_ulogic := 'U'; SIGNAL DQ23_ipd : std_ulogic := 'U'; SIGNAL DQ22_ipd : std_ulogic := 'U'; SIGNAL DQ21_ipd : std_ulogic := 'U'; SIGNAL DQ20_ipd : std_ulogic := 'U'; SIGNAL DQ19_ipd : std_ulogic := 'U'; SIGNAL DQ18_ipd : std_ulogic := 'U'; SIGNAL DQ17_ipd : std_ulogic := 'U'; SIGNAL DQ16_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 WPNeg_ipd : std_ulogic := 'U'; SIGNAL ADVNeg_ipd : std_ulogic := 'U'; SIGNAL WORDNeg_ipd : std_ulogic := 'U'; SIGNAL CLK_ipd : std_ulogic := 'U'; SIGNAL WPProg_in : std_ulogic := '0'; SIGNAL WPPRog_out : std_ulogic := '0'; SIGNAL PErase_in : std_ulogic := '0'; SIGNAL PErase_out : std_ulogic := '0'; SIGNAL SUS_in : std_ulogic := '0'; SIGNAL SUS_out : std_ulogic := '0'; SIGNAL CErase_in : std_ulogic := '0'; SIGNAL CErase_out : std_ulogic := '0'; SIGNAL SAWindow_in : std_ulogic := '0'; SIGNAL SAWindow_out : std_ulogic := '0'; SIGNAL RESInterval_in : std_ulogic := '0'; SIGNAL RESInterval_out : std_ulogic := '0'; SIGNAL NVProg_in : std_ulogic := '0'; SIGNAL NVProg_out : std_ulogic := '0'; SIGNAL NVErs_in : std_ulogic := '0'; SIGNAL NVErs_out : std_ulogic := '0'; -- Annotate SIGNAL P1_in : std_ulogic := '0'; SIGNAL P1_out : std_ulogic := '0'; SIGNAL P2_in : std_ulogic := '0'; SIGNAL P2_out : std_ulogic := '0'; SIGNAL P3_in : std_ulogic := '0'; SIGNAL P3_out : std_ulogic := '0'; SIGNAL P4_in : std_ulogic := '0'; SIGNAL P4_out : std_ulogic := '0'; BEGIN WPPROG : VITALbuf(WPPRog_out,WPProg_in,(tdevice_WPProg,UnitDelay)); PERASE : VITALbuf(PErase_out,PErase_in,(tdevice_PErase,UnitDelay)); SUSPEND : VITALbuf(SUS_out, SUS_in, (tdevice_SUSPEND,UnitDelay)); SAWIN : VITALbuf(SAWindow_out, SAWindow_in, (tdevice_SAWIN,UnitDelay)); RESEMB : VITALbuf(RESInterval_out, RESInterval_in, (tdevice_RESEMB,UnitDelay)); NVPROG : VITALbuf(NVProg_out, NVProg_in, (tdevice_NVPROG,UnitDelay)); NVERS : VITALbuf(NVErs_out, NVErs_in, (tdevice_NVERS,UnitDelay)); -- Annotate UNLOCK : VITALbuf(P1_out,P1_in, (tdevice_UNLOCK ,UnitDelay)); SE : VITALbuf(P2_out,P2_in, (tdevice_SE ,UnitDelay)); EPA16 : VITALbuf(P3_out,P3_in, (tdevice_EPA16 ,UnitDelay)); EPA32 : VITALbuf(P4_out,P4_in, (tdevice_EPA32 ,UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_2 : VitalWireDelay (Am1_ipd, Am1, tipd_Am1); w_3 : VitalWireDelay (A19_ipd, A19, tipd_A19); w_4 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_5 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_6 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_7 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_8 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_9 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_10 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_11 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_12 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_13 : VitalWireDelay (A9_ipd , A9 , tipd_A9); w_14 : VitalWireDelay (A8_ipd , A8 , tipd_A8); w_15 : VitalWireDelay (A7_ipd , A7 , tipd_A7); w_16 : VitalWireDelay (A6_ipd , A6 , tipd_A6); w_17 : VitalWireDelay (A5_ipd , A5 , tipd_A5); w_18 : VitalWireDelay (A4_ipd , A4 , tipd_A4); w_19 : VitalWireDelay (A3_ipd , A3 , tipd_A3); w_20 : VitalWireDelay (A2_ipd , A2 , tipd_A2); w_21 : VitalWireDelay (A1_ipd , A1 , tipd_A1); w_22 : VitalWireDelay (A0_ipd , A0 , tipd_A0); w_23 : VitalWireDelay (DQ31_ipd, DQ31, tipd_DQ31); w_24 : VitalWireDelay (DQ30_ipd, DQ30, tipd_DQ30); w_25 : VitalWireDelay (DQ29_ipd, DQ29, tipd_DQ29); w_26 : VitalWireDelay (DQ28_ipd, DQ28, tipd_DQ28); w_27 : VitalWireDelay (DQ27_ipd, DQ27, tipd_DQ27); w_28 : VitalWireDelay (DQ26_ipd, DQ26, tipd_DQ26); w_29 : VitalWireDelay (DQ25_ipd, DQ25, tipd_DQ25); w_30 : VitalWireDelay (DQ24_ipd, DQ24, tipd_DQ24); w_31 : VitalWireDelay (DQ23_ipd, DQ23, tipd_DQ23); w_32 : VitalWireDelay (DQ22_ipd, DQ22, tipd_DQ22); w_33 : VitalWireDelay (DQ21_ipd, DQ21, tipd_DQ21); w_34 : VitalWireDelay (DQ20_ipd, DQ20, tipd_DQ20); w_35 : VitalWireDelay (DQ19_ipd, DQ19, tipd_DQ19); w_36 : VitalWireDelay (DQ18_ipd, DQ18, tipd_DQ18); w_37 : VitalWireDelay (DQ17_ipd, DQ17, tipd_DQ17); w_38 : VitalWireDelay (DQ16_ipd, DQ16, tipd_DQ16); w_39 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_40 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_41 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_42 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_43 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_44 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_45 : VitalWireDelay (DQ9_ipd, DQ9, tipd_DQ9); w_46 : VitalWireDelay (DQ8_ipd, DQ8, tipd_DQ8); w_47 : VitalWireDelay (DQ7_ipd, DQ7, tipd_DQ7); w_48 : VitalWireDelay (DQ6_ipd, DQ6, tipd_DQ6); w_49 : VitalWireDelay (DQ5_ipd, DQ5, tipd_DQ5); w_50 : VitalWireDelay (DQ4_ipd, DQ4, tipd_DQ4); w_51 : VitalWireDelay (DQ3_ipd, DQ3, tipd_DQ3); w_52 : VitalWireDelay (DQ2_ipd, DQ2, tipd_DQ2); w_53 : VitalWireDelay (DQ1_ipd, DQ1, tipd_DQ1); w_54 : VitalWireDelay (DQ0_ipd, DQ0, tipd_DQ0); w_55 : VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg); w_56 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_57 : VitalWireDelay (RESETNeg_ipd, RESETNeg, tipd_RESETNeg); w_58 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg); w_59 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); w_60 : VitalWireDelay (ADVNeg_ipd, ADVNeg, tipd_ADVNeg); w_61 : VitalWireDelay (WORDNeg_ipd, WORDNeg, tipd_WORDNeg); w_62 : VitalWireDelay (CLK_ipd, CLK, tipd_CLK); END BLOCK; --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK PORT ( A : IN std_logic_vector(HiAddrBit downto 0) := (OTHERS => 'U'); Am1 : IN std_ulogic := 'U'; DIn : IN std_logic_vector(DBWidth downto 0) := (OTHERS => 'U'); CENeg : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; ADVNeg : IN std_ulogic := 'U'; WORDNeg : IN std_ulogic := 'U'; CLK : IN std_ulogic := 'U'; DOut : OUT std_ulogic_vector(DBWidth downto 0) := (OTHERS => 'Z'); RY : OUT std_ulogic := 'U'; INDNeg : OUT std_ulogic := 'U' ); PORT MAP ( 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, Am1 => Am1_ipd, DIn(31) => DQ31_ipd, DIn(30) => DQ30_ipd, DIn(29) => DQ29_ipd, DIn(28) => DQ28_ipd, DIn(27) => DQ27_ipd, DIn(26) => DQ26_ipd, DIn(25) => DQ25_ipd, DIn(24) => DQ24_ipd, DIn(23) => DQ23_ipd, DIn(22) => DQ22_ipd, DIn(21) => DQ21_ipd, DIn(20) => DQ20_ipd, DIn(19) => DQ19_ipd, DIn(18) => DQ18_ipd, DIn(17) => DQ17_ipd, DIn(16) => DQ16_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, CENeg => CENeg_ipd, OENeg => OENeg_ipd, WENeg => WENeg_ipd, RESETNeg => RESETNeg_ipd, WPNeg => WPNeg_ipd, ADVNeg => ADVNeg_ipd, WORDNeg => WORDNeg_ipd, CLK => CLK_ipd, DOut(31) => DQ31, DOut(30) => DQ30, DOut(29) => DQ29, DOut(28) => DQ28, DOut(27) => DQ27, DOut(26) => DQ26, DOut(25) => DQ25, DOut(24) => DQ24, DOut(23) => DQ23, DOut(22) => DQ22, DOut(21) => DQ21, DOut(20) => DQ20, DOut(19) => DQ19, DOut(18) => DQ18, DOut(17) => DQ17, DOut(16) => DQ16, 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, RY => RY, INDNeg => INDNeg ); TYPE STATES IS ( DUMMY, READ_ASYNC, READ_SYNC, CANNOTREAD, PROGCYC, CRVERIFY, CRWRITE, BITSTATUS, DYB_WE, DYBPPBSTATUS, WRITESTATUS, ASEL, READ_CFI, CESTATUS, SESTATUS, PPB_STATUS, PPB_ALL_STATUS, READ_ESP, WRITESTATUS_ESP, READ_PSP, PROGCYC_E, READ_PSP_E, WRITESTATUS_E, PASS_PROGRAM_STATUS, PASS_UNLOCK_STATUS, PASS_VERIFY, READ_BURST, STATUS_SYNC, NV_STATUS, PPB_VERIFY ); TYPE COMMAND_STATES IS ( DUMMY, INIT, IRREG, WRITECYC, RESET_OR_IGNORE, TWO_UNLOCK, CERASESEQ, CERASESEQ_UBP, CE, BITOP, SecEXIT, PROGRAM, PROGRAM_UBP, PROGRAM_E, PROGRAM_PASS, PROGRAM_NV, PASS_PROGRAM, PASS_UNLOCK, UBP, UBPRESET, SETIMEOUT, SE, ESP, ESP_CFI, ESP_ASEL, PSP, PSP_E, PSP_CFI, PSP_E_CFI, PSP_ASEL, PSP_E_ASEL ); TYPE COMMANDS IS ( PPBLOCK_SET, PPB_PROG, PPB_ERASE, SecSi_ENTRY, SecSi_EXIT, SPMLB_PROG, PPMLB_PROG, UBPASS, SecSiPB_PROG, UBPASSRES ); -- Commands detected TYPE TRANSITION_TYPE IS ( NONE_T, DUMMY_T, SYNCSTATUS_T, SYNCBACK_T, SYNC_T, EPA_T, ESP_T, WPPROG_T, INIT_T ); TYPE BANK IS ( SMALL, LARGE ); TYPE ERASEFLAGS IS ARRAY (0 TO SecNum) OF BOOLEAN; TYPE FlashMem IS ARRAY (0 TO ADDRRange) OF NATURAL RANGE 0 TO MaxData; TYPE CFI_TYPE IS ARRAY (0 TO 16#C5#) OF NATURAL; TYPE ASEL_TYPE IS ARRAY (0 TO 16#0F#) OF NATURAL; TYPE SecSi_TYPE IS ARRAY ( 0 to 127 ) OF NATURAL RANGE 0 TO MaxData; TYPE PASSTYPE IS ARRAY ( 0 to 3 ) OF std_logic_vector ( 15 downto 0 ); -- for burts sequence address storage TYPE AddrArrayTYPE IS ARRAY(0 to 32) OF NATURAL RANGE 0 TO ADDRRange; -- dual boot parameters SHARED VARIABLE SecSiSector : NATURAL RANGE 0 TO SecNum; SHARED VARIABLE HWProtect1 : NATURAL RANGE 0 TO SecNum; SHARED VARIABLE HWProtect2 : NATURAL RANGE 0 TO SecNum; -- command and functionality state machine SIGNAL CurrentState : STATES; SIGNAL CurrentBack : STATES; SIGNAL CommandCurrentState : COMMAND_STATES; SIGNAL CommandBack : COMMAND_STATES; SIGNAL Transition : TRANSITION_TYPE; -- detecting command cycles SIGNAL CommandRegAddr : NATURAL RANGE 0 to ADDRRange; SIGNAL CommandRegData : NATURAL RANGE 0 to 16#FF#; SIGNAL CommandDataLatched : BOOLEAN := FALSE; SIGNAL ReadAddrLatched : BOOLEAN := FALSE; SIGNAL DetectedCommand : COMMANDS; SIGNAL CommandCompleted : std_logic := '0'; SIGNAL LatchAddr : std_logic_vector(HiAddrBit downto 0); SIGNAL LatchAddrLSB : std_logic; SIGNAL LatchData : std_logic_vector( DBWidth downto 0 ); SIGNAL SectorID : NATURAL RANGE 0 to SecNum; SIGNAL GroupID : NATURAL RANGE 0 to GroupNum; -- device mode parameters and protection bits SIGNAL SYNC : BOOLEAN := FALSE; SIGNAL SecSiENABLED : BOOLEAN := FALSE; SIGNAL UNLOCKBYPASS : BOOLEAN := FALSE; SIGNAL PersistentMODELock : std_logic; SIGNAL PasswordMODELock : std_logic; SIGNAL SecSiPB : std_logic; SIGNAL DYB : std_logic_vector( SecNum downto 0 ); SHARED VARIABLE ConfReg : std_logic_vector( 15 downto 0 ); SHARED VARIABLE StatusReg : std_logic_vector( 31 downto 0 ); SHARED VARIABLE PPBLockBit : std_logic; SHARED VARIABLE PPB : std_logic_vector ( GroupNum downto 0 ) := ( OTHERS => '0'); SIGNAL SecSiRegion : SecSi_TYPE := (OTHERS => MaxData); SIGNAL PasswordRegion : PASSTYPE := (OTHERS => "1111111111111111"); SIGNAL EraseSecFlag : ERASEFLAGS; SIGNAL SETime : TIME; SIGNAL DOut_zd : std_logic_vector(DBWidth downto 0); SIGNAL RY_zd : std_logic; SIGNAL INDNeg_zd : std_logic; SIGNAL RYTransition : std_logic := '0'; SIGNAL PassWindow : std_logic := '1'; SIGNAL RY_Ready : std_logic := '0'; SIGNAL RY_Busy : std_logic := '0'; SIGNAL ProgStart : std_logic := '0'; SIGNAL ProgResume : std_logic := '0'; SIGNAL ProgSuspend : std_logic := '0'; SIGNAL ProgDone : std_logic := '0'; SIGNAL PassProgDone : std_logic := '1'; SIGNAL SEStart : std_logic := '0'; SIGNAL SEStartSuspend : std_logic := '0'; SIGNAL SEDone : std_logic := '0'; SIGNAL SEResume : std_logic := '0'; SIGNAL SESuspend : std_logic := '0'; SHARED VARIABLE PPBSequenceProg : NATURAL RANGE 0 to 2; SHARED VARIABLE PPBSequenceErase : NATURAL RANGE 0 to 2; SHARED VARIABLE SSBSequence : NATURAL RANGE 0 to 2; SHARED VARIABLE PPMLBSequence : NATURAL RANGE 0 to 2; SHARED VARIABLE SPMLBSequence : NATURAL RANGE 0 to 2; SHARED VARIABLE CESeq : NATURAL RANGE 0 to 2; SHARED VARIABLE CESeqUBP : NATURAL RANGE 0 to 2; SHARED VARIABLE RESSeqUBP : NATURAL RANGE 0 to 2; SHARED VARIABLE SecSiPBSequence : NATURAL RANGE 0 to 2; SHARED VARIABLE PassProgSequence : NATURAL RANGE 0 to 3; SHARED VARIABLE PassUnlockSequence : NATURAL RANGE 0 to 3; SHARED VARIABLE EraseBankSMALL : BOOLEAN; SHARED VARIABLE EraseBankLARGE : BOOLEAN; SIGNAL CRVerifySmallBank : BOOLEAN; SIGNAL BankProg : BANK; --SIGNAL BankErase : BANK; SIGNAL BankASEL : BANK; SIGNAL BankDYBPPB : BANK; SHARED VARIABLE AddrLOW : NATURAL RANGE 0 to ADDRRange; SHARED VARIABLE AddrHIGH : NATURAL RANGE 0 to ADDRRange; SHARED VARIABLE AselFlag : BOOLEAN; SHARED VARIABLE RESFlag : BOOLEAN := FALSE; SIGNAL RESET_D : STD_LOGIC := '1'; SIGNAL OE_burst : STD_LOGIC := '1'; -- glitch protection signals SIGNAL OENeg_gl : STD_LOGIC ; SIGNAL CENeg_gl : STD_LOGIC; SIGNAL WENeg_gl : STD_LOGIC; SIGNAL PoweredUp : STD_LOGIC := '0'; ----------------------------------------------------------------------------- ------- Functions & Procedures Section ------- ----------------------------------------------------------------------------- FUNCTION ReturnSectorID(ADDR : std_logic_vector(19 downto 0)) RETURN NATURAL IS VARIABLE result : NATURAL; VARIABLE conv : NATURAL; VARIABLE adrconv : NATURAL; VARIABLE addrsel : std_logic_vector(8 downto 0); BEGIN result := 0; addrsel(8 downto 0) := ADDR(19 downto 11); conv := to_nat(addrsel); IF ( conv <= 16#07# ) THEN result := conv; END IF; IF ( conv >= 16#08# ) AND ( conv <= 16#1F0# ) THEN result := 7 + ( conv / 16#08# ); END IF; IF ( conv >= 16#1F8# ) THEN result := 70 + ( conv - 16#1F8# ); END IF; RETURN result; END ReturnSectorID; FUNCTION ReturnGroupID(conv : NATURAL ) RETURN NATURAL IS VARIABLE result : NATURAL; BEGIN result := 0; IF ( conv <= 7 ) THEN result := conv; END IF; IF ( conv >= 8 ) AND ( conv <= 10 ) THEN result := 8; END IF; IF ( conv >= 11) AND ( conv <= 66 ) THEN result := 9 + ( ( conv - 11 ) / 4 ); END IF; IF ( conv >= 67 ) AND ( conv <= 69 ) THEN result := 23; END IF; IF ( conv >= 70 ) AND ( conv <= 77 ) THEN result := conv - 46; END IF; RETURN result; END ReturnGroupID; FUNCTION ReturnBank(ADDR : std_logic_vector) RETURN BANK IS VARIABLE result : BANK; BEGIN result := LARGE; IF TimingModel(12) = 'T' THEN-- = "AM29BDD320GTXXX" IF ( to_nat(ADDR(19 downto 11)) <= 16#078# ) THEN result := SMALL; END IF; ELSE IF ( to_nat(ADDR(19 downto 11)) >= 16#180# ) THEN result := SMALL; END IF; END IF; RETURN result; END ReturnBank; FUNCTION BusyBankE ( EraseBankSMALL : BOOLEAN; EraseBankLARGE : BOOLEAN; ADDR : std_logic_vector ) RETURN BOOLEAN IS VARIABLE result : BOOLEAN; BEGIN result := ((ReturnBank(ADDR) = SMALL) AND EraseBankSMALL) OR ((ReturnBank(ADDR) = LARGE) AND EraseBankLARGE); RETURN result; END BusyBankE; FUNCTION ReturnCFIIndex ( SIGNAL WORDNeg : IN std_logic; A : std_logic_vector; Am1 : std_logic) RETURN NATURAL IS VARIABLE CFIResult : NATURAL; BEGIN CFIResult := to_nat(A(7 downto 0)); IF NOT (((( CFIResult >= 16#10# ) AND ( CFIResult <= 16#51# )) OR (( CFIResult >= 16#57# ) AND ( CFIResult <= 16#5B# )))) OR (( WORDNeg = '0' ) AND ( Am1 = '1')) THEN CFIResult := 16#77#; END IF; RETURN CFIResult; END ReturnCFIIndex; FUNCTION ASELID( LatchAddr : STD_LOGIC_VECTOR; LatchAddrLSB : STD_LOGIC; WORDNeg : STD_LOGIC ) RETURN BOOLEAN IS VARIABLE IndexOK : BOOLEAN; BEGIN IndexOK := FALSE; IF ( (LatchAddr(7 downto 0) = "00000000") OR (LatchAddr(7 downto 0) = "00000001") OR (LatchAddr(7 downto 0) = "00001110") OR (LatchAddr(7 downto 0) = "00001111") ) AND ( WORDNeg = '1' OR ( WORDNeg = '0' AND LatchAddrLSB = '0' )) THEN IndexOK := TRUE; END IF; RETURN IndexOK; END ASELID; FUNCTION STATE( SYNC : BOOLEAN ) RETURN STATES IS VARIABLE NewState : STATES; BEGIN IF ( SYNC ) THEN NewState := READ_SYNC; ELSE NewState := READ_ASYNC; END IF; RETURN NewState; END STATE; FUNCTION CheckAllPPBs( PPB : std_logic_vector ) RETURN BOOLEAN IS VARIABLE FullyErased : BOOLEAN; BEGIN FullyErased := TRUE; FOR i IN 0 to GroupNum LOOP FullyErased := FullyErased AND ( PPB(i) = '0' ); END LOOP; RETURN FullyErased; END CheckAllPPBs; PROCEDURE BankE( VARIABLE EraseBankSMALL : INOUT BOOLEAN; VARIABLE EraseBankLARGE : INOUT BOOLEAN; SetBankVars : BOOLEAN ) IS BEGIN IF ( SetBankVars ) THEN IF ReturnBank(LatchAddr) = LARGE THEN EraseBankLARGE := TRUE; ELSE EraseBankSMALL := TRUE; END IF; ELSE EraseBankLARGE := FALSE; EraseBankSMALL := FALSE; END IF; END; PROCEDURE EraseAllPPBs( VARIABLE PPB : INOUT std_logic_vector(GroupNum downto 0); VARIABLE PPBLockBit : IN std_logic) IS VARIABLE i : NATURAL; BEGIN IF ( PPBLockBit = '0' ) THEN PPB := (OTHERS => '0'); END IF; END; PROCEDURE AddrBORDERS( VARIABLE AddrLOW : INOUT NATURAL RANGE 0 to ADDRRange; VARIABLE AddrHIGH : INOUT NATURAL RANGE 0 to ADDRRange; VARIABLE SectorID : NATURAL ) IS BEGIN IF (SectorID <= 7) THEN AddrLOW := SectorID*16#01000#; AddrHIGH := SectorID*16#01000# + 16#00FFF#; ELSIF (SectorID > 7) AND (SectorID <= 69) THEN AddrLOW := (SectorID-7)*16#08000#; AddrHIGH := (SectorID-7)*16#08000#+16#07FFF#; ELSE AddrLOW := 16#1F8000# + (SectorID-70)*16#01000#; AddrHIGH := 16#1F8000# + (SectorID-70)*16#01000# + 16#00FFF#; END IF; END AddrBORDERS; PROCEDURE LINEARACCESS_INIT( SIGNAL WORDNeg : IN std_logic; SIGNAL LatchAddr : IN std_logic_vector(19 downto 0); SIGNAL LatchAddrLSB : IN std_logic; VARIABLE CONF : INOUT std_logic_vector(15 downto 0); VARIABLE BurstAddr : INOUT AddrArrayTYPE; VARIABLE BurstBorder : INOUT NATURAL RANGE 0 to 32; VARIABLE BurstCount : INOUT NATURAL RANGE 0 to 32; VARIABLE BurstDelay : INOUT NATURAL RANGE 0 to 32; VARIABLE BurstInd : INOUT NATURAL RANGE 0 to 32 ) IS VARIABLE AddrIter : NATURAL RANGE 0 TO ADDRRange; BEGIN BurstDelay := to_nat(ConfReg(13 downto 10))+2; IF WORDNeg = '0' THEN CASE CONF(2 downto 0) IS WHEN "001" => -- four words AddrIter := to_nat(LatchAddr(19 downto 1)&"00"); BurstCount := to_nat(LatchAddr(0) & LatchAddrLSB); BurstBorder := 4; WHEN "010" => -- eight words AddrIter := to_nat(LatchAddr(19 downto 2)&"000"); BurstCount := to_nat(LatchAddr(1) & LatchAddr(0) & LatchAddrLSB); BurstBorder := 8; WHEN "011" => -- sixteen words AddrIter := to_nat(LatchAddr(19 downto 3)&"0000"); BurstCount := to_nat(LatchAddr(2 downto 0) & LatchAddrLSB); BurstBorder := 16; WHEN "100" => -- thirty two words AddrIter := to_nat(LatchAddr(19 downto 4)&"00000"); BurstCount := to_nat(LatchAddr(3 downto 0) & LatchAddrLSB); BurstBorder := 32; WHEN OTHERS => NULL; END CASE; ELSE CASE CONF (2 downto 0) IS WHEN "001" => -- two dwords AddrIter := to_nat(LatchAddr(19 downto 1)&"00"); BurstCount := to_nat(LatchAddr(0) & '0'); -- 2dwords~4words BurstBorder := 4; WHEN "010" => -- four dwords AddrIter := to_nat(LatchAddr(19 downto 2)&"000"); BurstCount := to_nat(LatchAddr(1) & LatchAddr(0) & '0'); -- eight words BurstBorder := 8; WHEN "011" => -- eight dwords AddrIter := to_nat(LatchAddr(19 downto 3)&"0000"); BurstCount := to_nat(LatchAddr(2 downto 0) & '0'); -- 16 words BurstBorder := 16; WHEN OTHERS => NULL; END CASE; END IF; FOR I IN 0 TO BurstBorder-1 LOOP BurstAddr(I) := AddrIter; AddrIter := AddrIter + 1; END LOOP; BurstInd := BurstCount; END LINEARACCESS_INIT; FUNCTION WrapArround( CR8 : std_logic; SIGNAL WORDNeg : IN std_logic; BurstCount : NATURAL RANGE 0 TO 32; BurstInd : NATURAL RANGE 0 TO 32; BurstBorder : NATURAL RANGE 0 TO 32) RETURN BOOLEAN IS VARIABLE Wrap : BOOLEAN; BEGIN IF CR8 = '0' THEN IF ( BurstInd /= 0 ) THEN Wrap := (BurstCount = BurstInd - 1 AND WORDNeg = '0')-- OR (BurstCount = BurstInd - 2 AND WORDNeg = '1');-- ELSE Wrap := (BurstCount = BurstBorder - 1 AND WORDNeg = '0')-- OR (BurstCount = BurstBorder - 2 AND WORDNeg = '1');-- END IF; ELSE IF (( BurstInd > 1 ) AND WORDNeg = '0' ) OR (( BurstInd > 2 ) AND WORDNeg = '1' ) THEN Wrap := (BurstCount = BurstInd - 2 AND WORDNeg = '0')-- OR (BurstCount = BurstInd - 4 AND WORDNeg = '1');-- ELSE Wrap := (BurstCount = BurstBorder - 2 + BurstInd AND WORDNeg = '0') OR (BurstCount = BurstBorder - 4 + BurstInd AND WORDNeg = '1'); END IF; END IF; RETURN Wrap; END WrapArround; PROCEDURE READPROC( SIGNAL DOut_zd : INOUT std_logic_vector; VARIABLE Am1 : std_logic; VARIABLE FlashData : std_logic_vector; SIGNAL WORDNeg : IN std_logic; SIGNAL SecSiENABLED : BOOLEAN; VARIABLE A : std_logic_vector ) IS VARIABLE ADDR : NATURAL; BEGIN IF WORDNeg = '1' THEN ADDR := to_nat(A&'0'); ELSE ADDR := to_nat(A&Am1); END IF; IF WordNeg = '0' THEN IF SecSiENABLED AND ReturnSectorID(A) = SecSiSector THEN IF TimingModel(12) = 'T' THEN--TimingModel = "AM29BDD320GTXXX" Dout_zd(15 downto 0) <= to_slv(SecSiRegion(ADDR mod SecSiSize),16); ELSE Dout_zd(15 downto 0) <= to_slv(SecSiRegion((ADDR- 16#1FF000#) mod SecSiSize),16); END IF; ELSE IF Am1 = '0' THEN Dout_zd(15 downto 0) <= FlashData(15 downto 0); ELSE Dout_zd(15 downto 0) <= FlashData(31 downto 16); END IF; END IF; ELSE IF SecSiENABLED AND ReturnSectorID(A) = SecSiSector THEN IF TimingModel(12) = 'T' THEN--TimingModel = "AM29BDD320GTXXX" Dout_zd <= to_slv(SecSiRegion((ADDR+1) mod SecSiSize),16) & to_slv(SecSiRegion( ADDR mod SecSiSize),16); ELSE Dout_zd <= to_slv(SecSiRegion((ADDR+1-16#1FF000#) mod SecSiSize),16) & to_slv(SecSiRegion((ADDR - 16#1FF000#) mod SecSiSize),16); END IF; ELSE Dout_zd <= FlashData; END IF; END IF; END READPROC; PROCEDURE UPDATESTATES( VARIABLE SecSiEE : INOUT NATURAL RANGE 0 TO 3; VARIABLE ASELFlag : INOUT BOOLEAN; SIGNAL CommandCurrentState : INOUT COMMAND_STATES; SIGNAL CommandBack : INOUT COMMAND_STATES) IS BEGIN ASELFlag := TRUE; SecSiEE := 0; CASE CommandCurrentState IS WHEN PSP => CommandCurrentState <= PSP_ASEL; CommandBack <= PSP_ASEL; WHEN PSP_E => CommandCurrentState <= PSP_E_ASEL; CommandBack <= PSP_E_ASEL; WHEN ESP => CommandCurrentState <= ESP_ASEL; CommandBack <= ESP_ASEL; WHEN OTHERS => CommandCurrentState <= RESET_OR_IGNORE; CommandBack <= RESET_OR_IGNORE; END CASE; END UPDATESTATES; BEGIN PoweredUp <= '1' AFTER 100 ns; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(CENeg,CLK,ADVNeg,WENeg,WPNeg,RESETNeg,OENeg,DIn,A) --Setup/Hold checks variables VARIABLE Tviol_CENeg_CLK : X01 := '0'; VARIABLE Tviol_ADVNeg_CLK : X01 := '0'; VARIABLE Tviol_CENeg_WENegr : X01 := '0'; VARIABLE Tviol_CENeg_WENegf : X01 := '0'; VARIABLE Tviol_WENeg_ADVNeg : X01 := '0'; VARIABLE Tviol_WPNeg_WENeg : X01 := '0'; VARIABLE Tviol_WENeg_CENeg : X01 := '0'; VARIABLE Tviol_CENeg_RESETNeg : X01 := '0'; VARIABLE Tviol_OENeg_RESETNeg : X01 := '0'; VARIABLE Tviol_WENeg_RESETNeg : X01 := '0'; VARIABLE Tviol_OENeg_WENeg : X01 := '0'; VARIABLE Tviol_WENeg_CLK : X01 := '0'; VARIABLE Tviol_A_CLK : X01 := '0'; VARIABLE Tviol_A_WENeg : X01 := '0'; VARIABLE Tviol_A_CENeg : X01 := '0'; VARIABLE Tviol_DQ_WENeg : X01 := '0'; VARIABLE Tviol_DQ_CENeg : X01 := '0'; VARIABLE Tviol_WENeg_OENeg : X01 := '0'; VARIABLE TD_ADVNeg_CLK : VitalTimingDataType; VARIABLE TD_CENeg_CLK : VitalTimingDataType; VARIABLE TD_CENeg_WENegr : VitalTimingDataType; VARIABLE TD_CENeg_WENegf : VitalTimingDataType; VARIABLE TD_WENeg_ADVNeg : VitalTimingDataType; VARIABLE TD_WPNeg_WENeg : VitalTimingDataType; VARIABLE TD_WENeg_CENeg : VitalTimingDataType; VARIABLE TD_CENeg_RESETNeg : VitalTimingDataType; VARIABLE TD_OENeg_RESETNeg : VitalTimingDataType; VARIABLE TD_WENeg_RESETNeg : VitalTimingDataType; VARIABLE TD_OENeg_WENeg : VitalTimingDataType; VARIABLE TD_WENeg_CLK : VitalTimingDataType; VARIABLE TD_A_CLK : VitalTimingDataType; VARIABLE TD_A_WENeg : VitalTimingDataType; VARIABLE TD_A_CENeg : VitalTimingDataType; VARIABLE TD_DQ_WENeg : VitalTimingDataType; VARIABLE TD_DQ_CENeg : VitalTimingDataType; VARIABLE TD_WENeg_OENeg : VitalTimingDataType; -- Pulse width cheks variables VARIABLE Pviol_CLK : X01 := '0'; VARIABLE Pviol_CENeg : X01 := '0'; VARIABLE Pviol_WENeg : X01 := '0'; VARIABLE Pviol_ADVNeg : X01 := '0'; VARIABLE Pviol_RESETNeg : X01 := '0'; VARIABLE PD_CLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_CENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_ADVNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_RESETNeg : VitalPeriodDataType := VitalPeriodDataInit; -- Recovery time checks variables VARIABLE Rviol_RY_CENeg : X01 := '0'; VARIABLE Rviol_OENeg_CENeg : X01 := '0'; VARIABLE Rviol_OENeg_WENeg : X01 := '0'; VARIABLE RD_RY_CENeg : VitalTimingDataType; VARIABLE RD_OENeg_CENeg : VitalTimingDataType; VARIABLE RD_OENeg_WENeg : VitalTimingDataType; VARIABLE Violation : X01; BEGIN IF TimingChecksOn THEN Violation := '0'; VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_CENeg_CLK, CheckEnabled => SYNC, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_CLK ); -- tADVCS,tADVCH -- ADVNeg LOW near CLK rising edge VitalSetupHoldCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_ADVNeg_CLK, HoldLow => thold_ADVNeg_CLK, CheckEnabled => SYNC, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_ADVNeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_ADVNeg_CLK ); -- WENeg HIGH near CLK rising edge VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_WENeg_CLK, CheckEnabled => SYNC, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_CLK ); -- tCL,tCH -- CLK LOW and HIGH pulse width check VitalPeriodPulseCheck ( TestSignal => CLK, TestSignalName => "CLK", PulseWidthHigh => tpw_CLK_posedge, PulseWidthLow => tpw_CLK_negedge, Period => tperiod_CLK, CheckEnabled => SYNC, HeaderMsg => InstancePath & PartID, PeriodData => PD_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CLK ); -- tACS, tACH -- Address lines setup and hold near CLK rising edge VitalSetupHoldCheck ( TestSignal => A(0), TestSignalName => "A(0)", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_A0_CLK, SetupHigh => tsetup_A0_CLK, HoldLow => thold_A0_CLK, HoldHigh => thold_A0_CLK, CheckEnabled => SYNC, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_A_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A_CLK ); -- tAS, tAH -- Address lines setup and hold near WENeg falling edge VitalSetupHoldCheck ( TestSignal => A(0), TestSignalName => "A(0)", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_A0_WENeg, SetupHigh => tsetup_A0_WENeg, HoldLow => thold_A0_WENeg, HoldHigh => thold_A0_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_A_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A_WENeg ); -- tCS -- CENeg LOW before WENeg falling edge VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_WENegf, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_WENegf ); -- tWPWS -- WPNeg setup before WENeg rising edge VitalSetupHoldCheck ( TestSignal => WPNeg, TestSignalName => "WPNeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_WPNeg_WENeg, SetupHigh => tsetup_WPNeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WPNeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WPNeg_WENeg ); -- tOEH -- OENeg HIGH after WENeg falling edge VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldHigh => thold_OENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_OENeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_OENeg_WENeg ); -- IF CENeg'Event THEN -- tAS, tAH -- Address lines setup and hold near CENeg falling edge VitalSetupHoldCheck ( TestSignal => A(0), TestSignalName => "A(0)", RefSignal => CENeg, RefSignalName => "CENeg", SetupLow => tsetup_A0_WENeg, SetupHigh => tsetup_A0_WENeg, HoldLow => thold_A0_WENeg, HoldHigh => thold_A0_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_A_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A_CENeg ); -- tWS ( CE controlled WRITE ) -- WENeg LOW before CENeg falling edge VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CENeg, RefSignalName => "CENeg", SetupLow => tsetup_WENeg_CENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_CENeg ); -- tWH -- WENeg LOW after CENeg / VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CENeg, RefSignalName => "CENeg", HoldLow => thold_WENeg_CENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_CENeg ); -- tCP,tCPH -- CENeg LOW and HIGH pulse width check VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CENeg", PulseWidthHigh => tpw_CENeg_posedge, PulseWidthLow => tpw_CENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CENeg ); -- tDS,tDH -- Data lines setup and hold near WENeg rising edge VitalSetupHoldCheck ( TestSignal => Din(0), TestSignalName => "Din(0)", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_DQ0_WENeg, SetupHigh => tsetup_DQ0_WENeg, HoldLow => thold_DQ0_WENeg, HoldHigh => thold_DQ0_WENeg, CheckEnabled => CENeg = '0' AND OENeg = '1' AND DIn /= DOut_zd, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_DQ_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_DQ_WENeg ); -- tDS,tDH -- Data lines setup and hold near CENeg rising edge VitalSetupHoldCheck ( TestSignal => Din(0), TestSignalName => "Din(0)", RefSignal => CENeg, RefSignalName => "CENeg", SetupLow => tsetup_DQ0_WENeg, SetupHigh => tsetup_DQ0_WENeg, HoldLow => thold_DQ0_WENeg, HoldHigh => thold_DQ0_WENeg, CheckEnabled => WENeg = '0' AND OENeg = '1' AND DIn /= DOut_zd, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_DQ_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_DQ_CENeg ); -- tOEH -- WENeg HIGH after OENeg falling edge VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => OENeg, RefSignalName => "OENeg", HoldHigh => thold_WENeg_OENeg, HoldLow => thold_WENeg_OENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_OENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_OENeg ); -- tWADVS, tWADVH -- WENeg HIGH near ADVNeg falling edge VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupHigh => tsetup_WENeg_ADVNeg, HoldHigh => thold_WENeg_ADVNeg, CheckEnabled => SYNC, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_ADVNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_ADVNeg ); -- tADVP -- ADVNeg LOW pulse width check VitalPeriodPulseCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", PulseWidthLow => tpw_ADVNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_ADVNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_ADVNeg ); -- tCH -- CENeg LOW after WENeg rising edge VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_WENegr, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_WENegr ); -- tRH -- CENeg HIGH after RESETNeg rising edge VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => RESET_D, RefSignalName => "RESETNeg", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => CENeg='1', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_RESETNeg ); -- tRH -- OENeg HIGH after RESETNeg rising edge VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OENeg", RefSignal => RESET_D, RefSignalName => "RESETNeg", HoldHigh => thold_OENeg_RESETNeg, CheckEnabled => OENeg='1', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_OENeg_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_OENeg_RESETNeg ); -- tRH -- WENeg HIGH after RESETNeg rising edge VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => RESETNeg, RefSignalName => "RESETNeg", HoldHigh => thold_WENeg_RESETNeg, CheckEnabled => WENeg='1', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_RESETNeg ); -- tPW,tPWH -- WENeg LOW and HIGH pulse width check VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WENeg", PulseWidthHigh => tpw_WENeg_posedge, PulseWidthLow => tpw_WENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_WENeg ); -- END IF; -- tWP -- RESET LOW pulse width check VitalPeriodPulseCheck ( TestSignal => RESETNeg, TestSignalName => "RESETNeg", PulseWidthLow => tpw_RESETNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_RESETNeg ); -- READ recovery time before WRITE -- tGHWL, OENeg HIGH to WENeg LOW VitalRecoveryRemovalCheck ( TestSignal => OENeg, TestSignalName => "OENeg", RefSignal => WENeg, RefSignalName => "WENeg", Recovery => trecovery_OENeg_WENeg, ActiveLow => TRUE, CheckEnabled => CENeg = '0', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => RD_OENeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Rviol_OENeg_WENeg ); -- READ recovery time before WRITE ( CE controlled WRITE ) -- tGHEL, OENeg HIGH to CENeg LOW VitalRecoveryRemovalCheck ( TestSignal => OENeg, TestSignalName => "OENeg", RefSignal => CENeg, RefSignalName => "CENeg", Recovery => trecovery_OENeg_CENeg, ActiveLow => TRUE, CheckEnabled => WENeg = '0', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => RD_OENeg_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Rviol_OENeg_CENeg ); Violation := Tviol_CENeg_CLK OR Tviol_ADVNeg_CLK OR Tviol_CENeg_WENegr OR Tviol_CENeg_WENegf OR Tviol_WENeg_ADVNeg OR Tviol_WPNeg_WENeg OR Tviol_WENeg_CENeg OR Tviol_CENeg_RESETNeg OR Tviol_OENeg_RESETNeg OR Tviol_WENeg_RESETNeg OR Tviol_OENeg_WENeg OR Tviol_WENeg_OENeg OR Tviol_WENeg_CLK OR Tviol_A_CLK OR Tviol_A_WENeg OR Tviol_DQ_WENeg OR Pviol_CLK OR Pviol_CENeg OR Pviol_WENeg OR Pviol_ADVNeg OR Pviol_RESETNeg OR Rviol_RY_CENeg OR Rviol_OENeg_CENeg OR Rviol_OENeg_WENeg; ASSERT Violation = '0' REPORT InstancePath & partID & " simulation may be inaccurate due " & "to timing violations" SEVERITY WARNING; END IF; -- TimingChecksOn END PROCESS VITALTimingCheck; ---------------------------------------------------------------------------- -- Latch Address and data, device mode dependant -- ---------------------------------------------------------------------------- CommandDetect : PROCESS ( WENeg_gl,OENeg_gl,CENeg_gl,CLK,ADVNeg ) VARIABLE ADVInit : BOOLEAN := FALSE; VARIABLE CLKInit : BOOLEAN := FALSE; VARIABLE REST : BOOLEAN := FALSE; VARIABLE LATCHED : BOOLEAN := FALSE; BEGIN ADVInit := rising_edge(ADVNeg); CLKInit := ADVNeg = '0' AND rising_edge(CLK); REST := SYNC AND CENeg_gl = '0'; IF falling_edge(ADVNeg) THEN LATCHED := FALSE; END IF; -- Latch Address IF (( ADVInit OR CLKInit ) AND REST ) OR ( NOT SYNC AND (( WENeg_gl = '0' ) AND ( CENeg_gl = '0' ) AND ( OENeg_gl = '1' ) AND (( WENeg_gl'Event ) OR (CENeg_gl'Event )))) THEN IF ( NOT LATCHED AND SYNC ) OR NOT SYNC THEN -- address latched on rising clock edge while ADV# LOW -- address latched on rising ADV# edge -- assumption : address kept stable for both these events IF SYNC THEN LATCHED := TRUE; END IF; IF ( WORDNeg = '1' ) THEN CommandRegAddr <= to_nat(A) mod 16#1000#; ELSE CommandRegAddr <= to_nat( A & Am1 ) mod 16#1000#; LatchAddrLSB <= Am1; END IF; LatchAddr <= A; IF SYNC AND WENeg_gl = '1' THEN ReadAddrLatched <= TRUE AFTER 0 ns, FALSE AFTER tcomm; END IF; ELSE IF SYNC THEN LATCHED := FALSE; END IF; END IF; END IF; -- Latch address for both sync and async modes -- Latch Data IF ( OENeg_gl = '1' ) AND ((rising_edge(CENeg_gl) AND (WENeg_gl = '0') AND NOT WENeg_gl'Event) OR (rising_edge(WENeg_gl) AND (CENeg_gl = '0') AND NOT CENeg_gl'Event)) THEN CommandRegData <= to_nat(Din(7 downto 0)); LatchData <= Din; CommandDataLatched <= TRUE AFTER 0 ns, FALSE AFTER tcomm; END IF; END PROCESS CommandDetect; ---------------------------------------------------------------------------- -- Pulse Width Protection -- ---------------------------------------------------------------------------- Res : process ( RESETNeg ) BEGIN IF RESETNeg = '0' THEN RESET_D <= RESETNeg AFTER 500 ns; ELSE RESET_D <= '1'; END IF; END PROCESS Res; OE_burst <= OENeg AFTER tpd_OENeg_DQ0(trz0) WHEN OENeg = '0' ELSE OENeg; CENeg_gl <= CENeg AFTER 5 ns WHEN CENeg = '0' ELSE CENeg; OENeg_gl <= OENeg AFTER 5 ns WHEN OENeg = '1' ELSE OENeg; WENeg_gl <= WENeg AFTER 5 ns WHEN WENeg = '0' ELSE WENeg; ---------------------------------------------------------------------------- -- Recognizing command sequences -- ---------------------------------------------------------------------------- CommandStateGen : PROCESS( CommandDataLatched,RESET_D,Transition, SEDone,PassProgDone, PassWindow, PErase_out, SUS_out, CErase_out,SAWindow_out, WPProg_out, RESInterval_out, NVProg_out, NVErs_out,PoweredUp, RESETNeg) VARIABLE FirstUnlockCycle : BOOLEAN := FALSE; VARIABLE IrregularSeq : BOOLEAN := FALSE; VARIABLE SecSiEE : NATURAL RANGE 0 to 3; VARIABLE ESPProg : BOOLEAN; VARIABLE AllProtected : BOOLEAN; VARIABLE CmdSec : NATURAL RANGE 0 TO SecNum; VARIABLE SEProtected : BOOLEAN; VARIABLE PassWORD : BOOLEAN; VARIABLE UNLOCK_1 : BOOLEAN; VARIABLE UNLOCK_2 : BOOLEAN; VARIABLE VALIDCYC : BOOLEAN; VARIABLE PassData : std_logic_vector(31 downto 0); VARIABLE PassAddr : NATURAL RANGE 0 to 3; VARIABLE PassORDER : NATURAL RANGE 0 to 4:=0; BEGIN IF ( CommandDataLatched'Event ) AND ( CommandDataLatched = TRUE ) THEN UNLOCK_1 := (((CommandRegAddr = 16#555#) AND (WORDNeg = '1')) OR (( CommandRegAddr = 16#AAA# ) AND (WORDNeg = '0'))) AND (CommandRegData = 16#AA#); UNLOCK_2 := (((CommandRegAddr = 16#2AA#) AND (WORDNeg = '1')) OR ((CommandRegAddr = 16#555#) AND (WORDNeg = '0'))) AND (CommandRegData = 16#55#); VALIDCYC := ((CommandRegAddr = 16#555# AND WORDNeg='1') OR (CommandRegAddr = 16#AAA# AND WORDNeg='0')); CASE CommandCurrentState IS WHEN INIT => IF RESET_D = '1' THEN IrregularSeq := FALSE; -- Detection of CFI Query, unable when SecSi enabled IF ((((CommandRegAddr = 16#55#) AND (WORDNeg='1')) OR((CommandRegAddr = 16#AA#) AND (WORDNeg='0'))) AND (CommandRegData = 16#98# ) AND NOT SecSiENABLED ) AND CommandCurrentState /= UBP THEN CurrentState <= READ_CFI; CommandCurrentState <= RESET_OR_IGNORE; -- Detection of first unlock cycle ELSIF UNLOCK_1 AND NOT FirstUnlockCycle THEN FirstUnlockCycle := TRUE; CurrentState <= CANNOTREAD; -- Detection of second unlock cycle ELSIF UNLOCK_2 AND FirstUnlockCycle THEN FirstUnlockCycle := FALSE; -- Two unlock cycles finished properly CommandCurrentState <= TWO_UNLOCK; ELSE IrregularSeq := TRUE; FirstUnlockCycle := FALSE; END IF; END IF; WHEN UBP => IrregularSeq := TRUE; IF ( CommandRegData = 16#A0# ) AND ( CESeqUBP = 0 ) AND ( RESSeqUBP = 0 ) THEN IrregularSeq := FALSE; CurrentState <= PROGCYC; CommandCurrentState <= WRITECYC; ELSIF ( CommandRegData = 16#80# ) AND ( CESeqUBP = 0 ) AND ( RESSeqUBP = 0 ) THEN IrregularSeq := FALSE; CurrentState <= CANNOTREAD; CESeqUBP := 1; ELSIF ( CommandRegData = 16#10# ) AND ( CESeqUBP = 1 ) AND ( RESSeqUBP = 0 )THEN IrregularSeq := FALSE; CurrentState <= CESTATUS; CommandCurrentState <= CE; CErase_in <= '1'; CESeqUBP := 0; ELSIF ( CommandRegData = 16#98# ) AND (CESeqUBP = 0) AND (RESSeqUBP = 0) THEN IrregularSeq := FALSE; CurrentState <= READ_CFI; CommandCurrentState <= RESET_OR_IGNORE; ELSIF ( CommandRegData = 16#90# ) AND ( RESSeqUBP = 0 ) AND ( CESeqUBP = 0 ) THEN IrregularSeq := FALSE; CurrentState <= CANNOTREAD; RESSeqUBP := 1; ELSIF ( CommandRegData = 16#00# ) AND ( RESSeqUBP = 1 ) AND ( CESeqUBP = 0 ) THEN IrregularSeq := FALSE; CurrentState <= STATE(SYNC); CommandCurrentState <= INIT; RESSeqUBP := 0; DetectedCommand <= UBPASSRES; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; ELSE RESSeqUBP := 0; CESeqUBP := 0; CurrentState <= CANNOTREAD; CommandCurrentState <= UBP; END IF; WHEN TWO_UNLOCK => IrregularSeq := TRUE; -- Detection of Program Command IF VALIDCYC AND (CommandRegData = 16#A0#) THEN IrregularSeq := FALSE; CurrentState <= PROGCYC; CommandCurrentState <= WRITECYC; END IF; -- Detection of Chip Erase command IF VALIDCYC AND ( CommandRegData = 16#80# ) THEN IrregularSeq := FALSE; CurrentState <= CANNOTREAD; CommandCurrentState <= CERASESEQ; CESeq := 0; END IF; -- Detection of Configuration Register Veriy -- mod 16#1000# IF ((CommandRegAddr) = 16#555#) AND ( CommandRegData = 16#C6# ) THEN IrregularSeq := FALSE; CurrentState <= CRVERIFY; CommandCurrentState <= RESET_OR_IGNORE; IF ( ReturnBank(LatchAddr) = SMALL) THEN CRVerifySmallBank <= TRUE; ELSE CRVerifySmallBank <= FALSE; END IF; END IF; -- Detection of Configuration Register Write IF VALIDCYC AND ( CommandRegData = 16#D0# ) THEN IrregularSeq := FALSE; CurrentState <= CRWRITE; CommandCurrentState <= WRITECYC; END IF; --Detection of Protection bits operation IF VALIDCYC AND ( CommandRegData = 16#60# ) THEN IrregularSeq := FALSE; CurrentState <= BITSTATUS; CommandCurrentState <= BITOP; PPBSequenceProg := 0; PPBSequenceErase := 0; SSBSequence := 0; PPMLBSequence := 0; SPMLBSequence := 0; SecSiPBSequence := 0; END IF; -- Detection of DYB Write or Erase IF VALIDCYC AND ( CommandRegData = 16#48# ) THEN IrregularSeq := FALSE; CurrentState <= DYB_WE; CommandCurrentState <= WRITECYC; END IF; -- Detection of DYB/PPB Status IF VALIDCYC AND ( CommandRegData = 16#58# ) THEN IrregularSeq := FALSE; BankDYBPPB <= ReturnBank(LatchAddr); CurrentState <= DYBPPBSTATUS; CommandCurrentState <= RESET_OR_IGNORE; END IF; -- Detection of PPB Lock Bit Set IF VALIDCYC AND ( CommandRegData = 16#78# ) THEN IrregularSeq := FALSE; CurrentState <= STATE(SYNC); CommandCurrentState <= INIT; DetectedCommand <= PPBLOCK_SET; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; END IF; -- Detection of leading sequence of AUTOSELECT, -- SecSi EXIT or PPB Status IF (((CommandRegAddr) = 16#555# AND WORDNeg = '1') OR ((CommandRegAddr) = 16#AAA# AND WORDNeg = '0')) AND ( CommandRegData = 16#90# ) THEN IrregularSeq := FALSE; BankASEL <= ReturnBank(LatchAddr); CurrentState <= ASEL; CommandCurrentState <= SecEXIT; ASELFlag := FALSE; END IF; -- Detection of UNLOCK BYPASS -- not recognizeable when SecSi enabled IF VALIDCYC AND ( CommandRegData = 16#20# ) THEN IrregularSeq := FALSE; -- command ignored but not illegal IF NOT SecSiENABLED THEN CurrentState <= CANNOTREAD; CommandCurrentState <= UBP; CESeqUBP := 0; RESSeqUBP := 0; DetectedCommand <= UBPASS; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; END IF; END IF; -- Detection of SecSi ENTRY IF VALIDCYC AND ( CommandRegData = 16#88# ) THEN IrregularSeq := FALSE; DetectedCommand <= SecSi_ENTRY; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; CurrentState <= STATE(SYNC); CommandCurrentState <= INIT; END IF; -- Detection of Password Program command -- not recognizeable if PPMLB set IF VALIDCYC AND (PasswordModeLock = '0') AND (CommandRegData = 16#38#) THEN IrregularSeq := FALSE; CommandCurrentState <= PASS_PROGRAM; CurrentState <= CANNOTREAD; PassProgSequence := 3; END IF; -- Detection of Password Verify command IF VALIDCYC AND ( CommandRegData = 16#C8# ) THEN IrregularSeq := FALSE; CommandCurrentState <= RESET_OR_IGNORE; CurrentState <= PASS_VERIFY; END IF; -- Detection of Password Unlock command IF VALIDCYC AND ( CommandRegData = 16#28# ) THEN IrregularSeq := FALSE; PassUnlockSequence := 3; CommandCurrentState <= PASS_UNLOCK; --PassWindow <= '1'; END IF; WHEN SecEXIT => IrregularSeq := TRUE; IF ( CommandRegData = 16#00# ) THEN IrregularSeq := FALSE; DetectedCommand <= SecSi_EXIT; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; CommandCurrentState <= INIT; CurrentState <= STATE(SYNC); END IF; WHEN CEraseSEQ => IrregularSeq := TRUE; IF UNLOCK_1 AND ( CESeq = 0 ) THEN IrregularSeq := FALSE; CESeq := 1; END IF; IF UNLOCK_2 AND ( CESeq = 1 ) THEN IrregularSeq := FALSE; CESeq := 2; END IF; IF VALIDCYC AND ( CommandRegData = 16#10# ) AND ( CESeq = 2 ) THEN IrregularSeq := FALSE; CESeq := 0; CurrentState <= CESTATUS; CommandCurrentState <= CE; CErase_in <= '1'; END IF; IF (( CommandRegData = 16#30# ) AND ( CESeq = 2 )) THEN IrregularSeq := FALSE; CESeq := 0; CmdSec := ReturnSectorID(LatchAddr); EraseSecFlag(CmdSec) <= TRUE; AllProtected := (DYB(CmdSec)='1') OR (PPB(ReturnGroupID(CmdSec))='1') OR ( WPNeg = '0' AND (CmdSec = HWProtect1 OR CmdSec = HWProtect2 )); IF AllProtected THEN SETime <= 0 ns; ELSE SETime <= tdevice_SE; END IF; BankE(EraseBankSMALL, EraseBankLARGE, TRUE); CurrentState <= SESTATUS; CommandCurrentState <= SETIMEOUT; SAWindow_in <= '1'; END IF; WHEN BITOP => IrregularSeq := TRUE; IF (CommandRegData = 16#68# ) THEN IF ((LatchAddr(5 downto 0) = OW0) OR (LatchAddr(5 downto 0) = OW1)) AND (SecSiPBSequence = 0) THEN -- SecSi Protection bit program IrregularSeq := FALSE; SecSiPBSequence := 1; CurrentState <= NV_STATUS; CommandCurrentState <= PROGRAM_NV; NVProg_in <= '1'; END IF; IF ((LatchAddr(5 downto 0) = PL0) OR (LatchAddr(5 downto 0) = PL1)) AND (PPMLBSequence = 0) THEN -- PPMLB Program IrregularSeq := FALSE; PPMLBSequence := 1; CurrentState <= NV_STATUS; CommandCurrentState <= PROGRAM_NV; -- if SPMLB already set, mode permanently chosen -- can't set PPMLB, time-out without programming NVProg_in <= '1'; END IF; IF ((LatchAddr(5 downto 0) = SL0) OR (LatchAddr(5 downto 0) = SL1)) AND (SPMLBSequence = 0) THEN -- SPMLB Program IrregularSeq := FALSE; SPMLBSequence := 1; CurrentState <= NV_STATUS; CommandCurrentState <= PROGRAM_NV; NVProg_in <= '1'; -- can be programmed END IF; IF ((LatchAddr(5 downto 0) = WP0) OR (LatchAddr(5 downto 0) = WP1)) AND (PPBSequenceProg = 0) THEN -- PPB Program, SA dependent IrregularSeq := FALSE; PPBSequenceProg := 1; CurrentState <= NV_STATUS; CommandCurrentState <= PROGRAM_NV; GroupId <= ReturnGroupID(ReturnSectorID(LatchAddr)); NVProg_in <= '1'; END IF; END IF; IF (CommandRegData = 16#48# ) THEN IF ((LatchAddr(5 downto 0) = OW0) OR (LatchAddr(5 downto 0) = OW1)) AND (SecSiPBSequence = 1) THEN -- SecSi Protection bit program IrregularSeq := FALSE; SecSiPBSequence := 2; CurrentState <= BITSTATUS; CommandCurrentState <= IRREG; END IF; IF ((LatchAddr(5 downto 0) = PL0) OR (LatchAddr(5 downto 0) = PL1)) AND (PPMLBSequence = 1) THEN -- PPMLB Program IrregularSeq := FALSE; PPMLBSequence := 2; CurrentState <= BITSTATUS; CommandCurrentState <= IRREG; END IF; IF ((LatchAddr(5 downto 0) = SL0) OR (LatchAddr(5 downto 0) = SL1)) AND (SPMLBSequence = 1) THEN -- SPMLB Program IrregularSeq := FALSE; SPMLBSequence := 2; CurrentState <= BITSTATUS; CommandCurrentState <= IRREG; END IF; IF ((LatchAddr(5 downto 0) = WP0) OR (LatchAddr(5 downto 0) = WP1)) AND (PPBSequenceProg = 1) AND(ReturnGroupID(ReturnSectorID(LatchAddr)) = GroupID) THEN -- PPB Program, SA dependent IrregularSeq := FALSE; PPBSequenceProg := 2; CurrentState <= PPB_VERIFY; CommandCurrentState <= IRREG; END IF; END IF; -- All PPB Erase IF ((LatchAddr(5 downto 0) = WP0) OR (LatchAddr(5 downto 0) = WP1)) AND (PPBSequenceErase = 0) AND ( CommandRegData = 16#60#) THEN IrregularSeq := FALSE; PPBSequenceErase := 1; CurrentState <= NV_STATUS; CommandCurrentState <= PROGRAM_NV; NVErs_in <= '1'; END IF; IF ((LatchAddr(5 downto 0) = WP0) OR (LatchAddr(5 downto 0) = WP1)) AND (PPBSequenceErase = 1) AND ( CommandRegData = 16#40# ) THEN IrregularSeq := FALSE; PPBSequenceErase := 2; CurrentState <= PPB_ALL_STATUS; CommandCurrentState <= IRREG; SectorID <= ReturnSectorID(LatchAddr); END IF; IF IrregularSeq THEN PPBSequenceProg := 0; PPBSequenceErase := 0; SSBSequence := 0; PPMLBSequence := 0; SPMLBSequence := 0; SecSiPBSequence := 0; END IF; WHEN RESET_OR_IGNORE => IF ( CommandRegData = 16#F0# ) THEN IF UNLOCKBYPASS THEN CurrentState <= CANNOTREAD; CommandCurrentState <= UBP; ELSE CurrentState <= STATE(SYNC); CommandCurrentState <= INIT; END IF; END IF; WHEN PROGRAM | PROGRAM_UBP | PROGRAM_E=> -- During EPA only Suspend command is valid -- Suspend command not possible when SecSi enabled IF (CommandRegData = 16#B0#) AND NOT SecSiENABLED AND (ReturnBank(LatchAddr) = BankProg ) THEN SUS_in <= '1'; ProgSuspend <= '1', '0' AFTER tcomm; END IF; WHEN SETIMEOUT => IrregularSeq := TRUE; -- New SA within 80us window IF (CommandRegData = 16#30#) THEN BankE(EraseBankSMALL, EraseBankLARGE, TRUE); IrregularSeq := FALSE; EraseSecFlag(ReturnSectorID(LatchAddr))<=TRUE; CmdSec := ReturnSectorID(LatchAddr); SEProtected := (DYB(CmdSec)='1') OR (PPB(ReturnGroupID(CmdSec))='1') OR ( WPNeg = '0' AND (CmdSec = HWProtect1 OR CmdSec = HWProtect2 )); AllProtected := AllProtected AND SEProtected; IF NOT SEProtected THEN SETime <= SETime + tdevice_SE; END IF; -- Restart sector address window SAWindow_in <= '0','1' AFTER 1 ns; END IF; -- Erase Suspend, Sector Erase has not yet begun, -- suspension immediate -- ignored if SecSi enabled IF (CommandRegData = 16#B0#)AND BusyBankE(EraseBankSMALL, EraseBankLARGE, LatchAddr) THEN -- if SecSi enabled, command is ignored, not illegal IrregularSeq := FALSE; IF NOT SecSiENABLED THEN SAWindow_in <= '0'; SEStartSuspend <= '1', '0' AFTER tcomm; CommandCurrentState <= ESP; SecSiEE := 0; ESPProg := FALSE; CurrentState <= READ_ESP; END IF; END IF; -- additional activities in this case -- excludes activities performed at the end of this process IF IrregularSeq THEN SAWindow_in <= '0'; EraseSecFlag <= (OTHERS=>FALSE); END IF; WHEN SE => -- Suspend command not possible when SecSi enabled IF (CommandRegData = 16#B0#) AND NOT SecSiENABLED AND BusyBankE(EraseBankSMALL, EraseBankLARGE, LatchAddr) THEN SUS_in <= '1'; SESuspend <= '1', '0' AFTER tcomm; END IF; WHEN PSP | PSP_E => -- Recognize SecSiEntry and SecSiExit IF UNLOCK_1 AND (SecSiEE=0) THEN SecSiEE:=1; ELSIF UNLOCK_2 AND (SecSiEE=1) THEN SecSiEE := 2; ELSIF VALIDCYC AND ( CommandRegData = 16#88# ) AND ( SecSiEE = 2 ) THEN SecSiEE := 0; DetectedCommand <= SecSi_ENTRY; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; --ELSIF(((CommandRegAddr mod 16#1000#)=16#555# AND WORDNeg='1') ELSIF(((CommandRegAddr)=16#555# AND WORDNeg='1') OR ((CommandRegAddr) = 16#AAA# AND WORDNeg = '0')) AND (CommandRegData = 16#90# ) AND (SecSiEE = 2) THEN SecSiEE := 3; CurrentState <= ASEL; BankASEL <= ReturnBank(LatchAddr); ASELFlag := FALSE; ELSIF ((CommandRegData = 16#00# ) AND (SecSiEE = 3)) THEN SecSiEE := 0; DetectedCommand <= SecSi_EXIT; IF CommandCurrentState = PSP THEN CurrentState <= READ_PSP; ELSE CurrentState <= READ_PSP_E; END IF; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; -- Recognize Resume command ELSIF ( CommandRegData = 16#30# ) AND NOT SecSiENABLED AND ( ReturnBank(LatchAddr) = BankProg ) AND SecSiEE = 0 THEN IF CommandCurrentState = PSP THEN IF UNLOCKBYPASS THEN CommandCurrentState <= PROGRAM_UBP; ELSE CommandCurrentState <= PROGRAM; END IF; CurrentState <= WRITESTATUS; ELSIF CommandCurrentState = PSP_E THEN CommandCurrentState <= PROGRAM_E; CurrentState <= WRITESTATUS_E; END IF; ProgResume <= '1','0' AFTER tcomm; -- Recognize CFI query ELSIF ( CommandRegData = 16#98# ) AND NOT SecSiENABLED AND ((CommandRegAddr = 16#AA# AND WORDNeg = '0') OR (CommandRegAddr = 16#55# AND WORDNeg = '1')) AND SecSiEE = 0 THEN IF CommandCurrentState = PSP THEN CommandCurrentState <= PSP_CFI; CurrentState <= READ_CFI; ELSIF CommandCurrentState = PSP_E THEN CommandCurrentState <= PSP_E_CFI; CurrentState <= READ_CFI; END IF; ELSE SecSiEE :=0; CurrentState <= READ_PSP; IF CommandCurrentState = PSP_E THEN CurrentState <= READ_PSP_E; END IF; END IF; WHEN PSP_CFI | PSP_E_CFI | PSP_ASEL | PSP_E_ASEL | ESP_CFI | ESP_ASEL => IF ( CommandRegData = 16#F0# ) THEN IF CommandCurrentState = ESP_CFI OR CommandCurrentState = ESP_ASEL THEN CommandCurrentState <= ESP; CurrentState <= READ_ESP; ELSE IF (CommandCurrentState = PSP_CFI) OR (CommandCurrentState = PSP_ASEL) THEN CurrentState <= READ_PSP; CommandCurrentState <= PSP; ELSE CurrentState <= READ_PSP_E; CommandCurrentState <= PSP_E; END IF; END IF; END IF; WHEN ESP => -- Recognize SecSiEntry,SecSiExit and Program command IF UNLOCK_1 AND (SecSiEE = 0) AND NOT ESPProg THEN SecSiEE:=1; ELSIF UNLOCK_2 AND (SecSiEE = 1) AND NOT ESPProg THEN SecSiEE := 2; ELSIF VALIDCYC AND (CommandRegData = 16#88# ) AND (SecSiEE = 2) AND NOT ESPProg THEN SecSiEE := 0; DetectedCommand <= SecSi_ENTRY; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; ELSIF (((CommandRegAddr)=16#555# AND WORDNeg='1') OR((CommandRegAddr) = 16#AAA# AND WORDNeg = '0')) AND (CommandRegData = 16#90# ) AND (SecSiEE = 2) AND NOT ESPProg THEN SecSiEE := 3; CurrentState <= ASEL; BankASEL <= ReturnBank(LatchAddr); ASELFlag := FALSE; ELSIF (CommandRegData = 16#00# ) AND (SecSiEE = 3) AND NOT ESPProg THEN SecSiEE := 0; DetectedCommand <= SecSi_EXIT; CurrentState <= READ_ESP; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; ELSIF VALIDCYC AND (CommandRegData = 16#A0# ) AND (SecSiEE = 2) AND NOT ESPProg THEN SecSiEE := 0; ESPProg := FALSE; CommandCurrentState <= WRITECYC; CurrentState <= PROGCYC_E; -- Recognize Resume command,ignore if SecSi enabled ELSIF ( CommandRegData = 16#30# ) AND NOT SecSiENABLED AND BusyBankE(EraseBankSMALL, EraseBankLARGE, LatchAddr) AND SecSiEE = 0 THEN CommandCurrentState <= SE; CurrentState <= SESTATUS; SEResume <= '1','0' AFTER tcomm; -- Recognize CFI query ELSIF ( CommandRegData = 16#98# ) AND NOT SecSiENABLED AND (((CommandRegAddr = 16#55#) AND (WORDNeg = '1')) OR((CommandRegAddr = 16#AA#) AND (WORDNeg = '0'))) AND SecSiEE = 0 THEN CommandCurrentState <= ESP_CFI; CurrentState <= READ_CFI; ELSE SecSiEE := 0; ESPProg := FALSE; CurrentState <= READ_ESP; END IF; WHEN PASS_PROGRAM => IF (PassProgSequence = 0) AND UNLOCK_1 THEN PassProgSequence := 1; ELSIF (PassProgSequence = 1) AND UNLOCK_2 THEN PassProgSequence := 2; ELSIF (PassProgSequence = 2) AND ( CommandRegData = 16#38# ) AND VALIDCYC THEN PassProgSequence := 3; ELSIF PasswordMODELock = '0' AND PassProgSequence = 3 THEN PassProgSequence := 0; IF WORDNeg = '0' THEN PassWORD := TRUE; PassProgDone <= '0', '1' AFTER tdevice_EPA16; ELSE PassWORD := FALSE; PassProgDone <= '0', '1' AFTER tdevice_EPA32; END IF; PassAddr := to_nat(LatchAddr(0)&LatchAddrLSB); PassData := LatchData; StatusReg(7) := LatchData(7); CurrentState <= PASS_PROGRAM_STATUS; CommandCurrentState <= DUMMY; ELSIF CommandRegData = 16#F0# THEN CurrentState <= STATE(SYNC); CommandCurrentState <= INIT; ELSE PassProgSequence := 0; END IF; WHEN PASS_UNLOCK => IF (PassUnlockSequence=0) AND UNLOCK_1 THEN PassUnlockSequence := 1; ELSIF (PassUnlockSequence=1) AND UNLOCK_2 THEN PassUnlockSequence := 2; ELSIF (PassUnlockSequence=2) AND ( CommandRegData = 16#28# ) AND VALIDCYC THEN PassUnlockSequence := 3; ELSIF PasswordMODELock = '1' AND PassUnlockSequence = 3 THEN PassUnlockSequence := 0; IF ( PassWindow = '1' ) THEN PassWindow <= '0', '1' AFTER tdevice_UNLOCK; PassAddr := to_nat(LatchAddr(0)&LatchAddrLSB); PassData := LatchData; StatusReg(7) := LatchData(7); PassWORD := WORDNeg = '0'; CurrentState <= PASS_UNLOCK_STATUS; CommandCurrentState <= DUMMY; END IF; ELSIF CommandRegData = 16#F0# THEN CurrentState <= STATE(SYNC); CommandCurrentState <= INIT; ELSE PassUnlockSequence := 0; END IF; WHEN OTHERS => NULL; END CASE; END IF; -- CommandDataLatched'Event / TRUE -- Irregular sequence of user commands must RESET device IF IrregularSeq = TRUE THEN IrregularSeq := FALSE; IF UNLOCKBYPASS THEN CommandCurrentState <= UBP; CurrentState <= CANNOTREAD; ELSE CommandCurrentState <= INIT; CurrentState <= STATE(SYNC); END IF; END IF; IF Transition'Event THEN CASE Transition IS WHEN INIT_T => IF UNLOCKBYPASS THEN CommandCurrentState <= UBP; CurrentState <= CANNOTREAD; ELSE CommandCurrentState <= INIT; CurrentState <= STATE(SYNC); END IF; WHEN ESP_T => CommandCurrentState <= ESP; CurrentState <= READ_ESP; SecSiEE := 0; ESPProg := FALSE; WHEN WPPROG_T => WPProg_in <= '1'; CommandCurrentState <= DUMMY; IF CurrentState = PROGCYC THEN CurrentState <= WRITESTATUS; ELSE CurrentState <= WRITESTATUS_E; --progcyc_E END IF; WHEN EPA_T => IF CurrentState = PROGCYC THEN IF UNLOCKBYPASS THEN CommandCurrentState <= PROGRAM_UBP; ELSE CommandCurrentState <= PROGRAM; END IF; CurrentState <= WRITESTATUS; ELSE -- progcyc_E CommandCurrentState <= PROGRAM_E; CurrentState <= WRITESTATUS_E; END IF; WHEN SYNC_T => IF CurrentState = ASEL AND NOT ASELFLag THEN UPDATESTATES(SecSiEE,ASELFlag, CommandCurrentState,CommandBack); ELSE CommandBack <= CommandCurrentState; END IF; CurrentState <= READ_BURST; CommandCurrentState <= DUMMY; CurrentBack <= CurrentState; WHEN SYNCSTATUS_T => CurrentState <= STATUS_SYNC; CurrentBack <= CurrentState; IF CurrentState = ASEL AND NOT ASELFLag THEN UPDATESTATES(SecSiEE,ASELFlag, CommandCurrentState,CommandBack); ELSE CommandBack <= CommandCurrentState; END IF; IF CurrentState = BITSTATUS OR CurrentState = PPB_ALL_STATUS OR CurrentState = PPB_VERIFY OR CurrentState = DYBPPBSTATUS THEN CommandCurrentState <= RESET_OR_IGNORE; CommandBack <= RESET_OR_IGNORE; END IF; WHEN SYNCBACK_T => CurrentState <= CurrentBack; CommandCurrentState <= CommandBack; WHEN DUMMY_T => IF CurrentState = ASEL AND NOT ASELFLag THEN UPDATESTATES(SecSiEE,ASELFlag, CommandCurrentState,CommandBack); ELSE CommandCurrentState <= RESET_OR_IGNORE; END IF; WHEN OTHERS => NULL; END CASE; END IF; IF ( RESETneg'Event ) THEN IF RESETNeg = '0' THEN IF CommandCurrentState = PROGRAM OR CommandCurrentState = PROGRAM_E OR CommandCurrentState = SE OR CommandCurrentState = CE OR CommandCurrentState = PROGRAM_NV THEN RESInterval_in <= '1'; END IF; ELSE IF NOT RESFlag THEN ResInterval_in <= '0'; END IF; END IF; END IF; IF falling_edge(RESET_D) THEN BankE(EraseBankSMALL, EraseBankLARGE, FALSE); FirstUnlockCycle := FALSE; IrregularSeq := FALSE; PassORDER := 0; -- In password mode the only way too clear PPBLock is pass unlock IF PasswordMODELock = '1' THEN PPBLockBit := '1'; ELSE PPBLockBit := '0'; END IF; WPProg_in <= '0'; PErase_in <= '0'; SUS_in <= '0'; CErase_in <= '0'; SAWindow_in <= '0'; NVProg_in <= '0'; NVErs_in <= '0'; PassProgDone <= '1'; PassWindow <= '1'; EraseSecFlag <= (OTHERS => FALSE); IF CommandCurrentState = PROGRAM OR CommandCurrentState = PROGRAM_E OR CommandCurrentState = SE OR CommandCurrentState = CE OR CommandCurrentState = PROGRAM_NV THEN RESFlag := TRUE; CommandCurrentState <= DUMMY; CurrentState <= DUMMY; ELSE CommandCurrentState <= INIT; CurrentState <= READ_ASYNC; END IF; END IF; -- RESETNeg event IF rising_edge(PoweredUp) THEN CommandCurrentState <= INIT; CurrentState <= READ_ASYNC; END IF; IF rising_edge(RESInterval_out) THEN RESInterval_in <= '0'; CommandCurrentState <= INIT; CurrentState <= READ_ASYNC; END IF; IF rising_edge(SEDone) THEN EraseSecFlag <= (OTHERS => FALSE); CommandCurrentState <= INIT; CurrentState <= STATE(SYNC); BankE(EraseBankSMALL, EraseBankLARGE, FALSE); END IF; IF rising_edge(NVProg_out) OR rising_edge(NVErs_out) THEN NVProg_in <= '0'; NVErs_in <= '0'; CommandCurrentState <= BITOP; CurrentState <= CANNOTREAD; -- if operation irregular do not execute detected command IF NVProg_out'Event THEN IF SecSiPBSequence = 1 THEN DetectedCommand <= SecSiPB_PROG; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; ELSIF PPMLBSequence = 1 THEN DetectedCommand <= PPMLB_PROG; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; ELSIF SPMLBSequence = 1 THEN DetectedCommand <= SPMLB_PROG; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; ELSIF PPBSequenceProg = 1 THEN DetectedCommand <= PPB_PROG; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; END IF; END IF; IF rising_edge(NVErs_out) THEN IF PPBSequenceErase = 1 THEN DetectedCommand <= PPB_ERASE; CommandCompleted <= '1' AFTER 0 ns, '0' AFTER tcomm; END IF; END IF; END IF; IF rising_edge(PassProgDone) THEN IF PassWORD THEN PasswordRegion(PassAddr) <= PassData(15 downto 0) AND PasswordRegion(PassAddr); ELSE IF PassAddr < 2 THEN PasswordRegion(0) <= PassData(15 downto 0) AND PasswordRegion(0); PasswordRegion(1) <= PassData(31 downto 16) AND PasswordRegion(1); ELSE PasswordRegion(2) <= PassData(15 downto 0) AND PasswordRegion(2); PasswordRegion(3) <= PassData(31 downto 16) AND PasswordRegion(3); END IF; END IF; CurrentState <= CANNOTREAD; CommandCurrentState <= PASS_PROGRAM; END IF; -- Program of a protected location timeout IF rising_edge(WPProg_out) THEN WPProg_in <= '0'; IF CurrentState = WRITESTATUS THEN IF UNLOCKBYPASS THEN CommandCurrentState <= UBP; CurrentState <= CANNOTREAD; ELSE CommandCurrentState <= INIT; CurrentState <= STATE(SYNC); END IF; ELSE --writestatus_E CommandCurrentState <= ESP; CurrentState <= READ_ESP; SecSiEE := 0; ESPProg := FALSE; END IF; -- current state END IF; IF ( SAWindow_out'Event ) AND ( SAWindow_out = '1' ) THEN -- end of timeout while sector erase operation for next sector address -- SE now begins SAWIndow_in <= '0'; IF AllProtected THEN CommandCurrentState <= DUMMY; CurrentState <= SESTATUS; PErase_in <= '1'; ELSE CommandCurrentState <= SE; CurrentState <= SESTATUS; SEStart <= '1','0' AFTER tcomm; END IF; END IF; IF rising_edge(PassWindow) THEN CommandCurrentState <= PASS_UNLOCK; CurrentState <= CANNOTREAD; IF PassWORD THEN IF (PassAddr = PassORDER) AND (PassData(15 downto 0) = PasswordRegion(PassAddr)) THEN PassORDER:= PassORDER + 1; ELSE PassORDER:= 0; END IF; ELSE IF ((PassAddr < 2) AND (PasswordRegion(1)&PasswordRegion(0) = PassData) AND PassORDER = 0) OR ((PassAddr >= 2) AND (PasswordRegion(3)&PasswordRegion(2) = PassData) AND PassORDER =2) THEN IF PassORDER = 0 THEN PassORDER := 2; ELSE PassORDER := 4; END IF; ELSE PassORDER := 0; END IF; END IF; IF PassORDER = 4 THEN PassORDER := 0; PPBLockBit := '0'; END IF; END IF; IF rising_edge(PErase_out) THEN PErase_in <= '0'; CommandCurrentState <= INIT; CurrentState <= STATE(SYNC); END IF; IF rising_edge(SUS_out) THEN SUS_in <= '0'; SecSiEE := 0; ESPProg := FALSE; IF CommandCurrentState = PROGRAM OR CommandCurrentState = PROGRAM_UBP THEN CommandCurrentState <= PSP; CurrentState <= READ_PSP; END IF; IF CommandCurrentState = SE THEN CommandCurrentState <= ESP; CurrentState <= READ_ESP; END IF; IF CommandCurrentState = PROGRAM_E THEN CommandCurrentState <= PSP_E; CurrentState <= READ_PSP_E; END IF; END IF; IF rising_edge(CErase_out) THEN CErase_in <= '0'; IF UNLOCKBYPASS THEN CommandCurrentState <= UBP; CurrentState <= CANNOTREAD; ELSE CommandCurrentState <= INIT; CurrentState <= STATE(SYNC); END IF; END IF; END PROCESS CommandStateGen; -------------------------------------------------------------------------- -- Model Functionality -- -- Read modes, detected commands and write cycles -- -------------------------------------------------------------------------- Functional : PROCESS(WENeg_gl,OENeg_gl,CENeg_gl,CommandCompleted,ProgDone, CommandDataLatched,CErase_out, SEDone, A, Am1, RESET_D, CLK, ADVNeg, ReadAddrLatched, PoweredUp ) VARIABLE Flash : FlashMem := (OTHERS => MaxData); VARIABLE CFI_array : CFI_TYPE; VARIABLE ASEL_array : ASEL_TYPE; VARIABLE AddrConv : NATURAL; VARIABLE DataProg : std_logic_vector ( 31 downto 0 ); VARIABLE FlashData : std_logic_vector ( 31 downto 0 ); VARIABLE CFIIndex : NATURAL; VARIABLE AddrProg : NATURAL; VARIABLE WordProg : BOOLEAN; VARIABLE SectorProg : NATURAL RANGE 0 to SecNum ; VARIABLE GroupProg : NATURAL RANGE 0 to GroupNum ; VARIABLE SEC : NATURAL; VARIABLE HelpSLV : std_logic_vector(20 downto 0); VARIABLE BurstAddr : AddrArrayTYPE; VARIABLE BurstBorder : NATURAL RANGE 0 to 32; VARIABLE BurstCount : NATURAL RANGE 0 to 32; VARIABLE BurstInd : NATURAL RANGE 0 to 32; VARIABLE BurstDelay : NATURAL RANGE 0 to 10; VARIABLE ReadOK : BOOLEAN; VARIABLE SyncData : std_logic_vector(31 downto 0); VARIABLE ReadData : std_logic_vector(31 downto 0); VARIABLE RdA : std_logic_vector(19 downto 0); VARIABLE RdAm1 : std_logic; FILE mem_f : text is mem_file_name; FILE prot_f : text is prot_file_name; FILE secsi_f : text is secsi_file_name; VARIABLE buf : line; VARIABLE ind : NATURAL; VARIABLE DOut_temp : std_logic_vector(31 downto 0); CONSTANT MemSize : NATURAL := 16#1FFFFF#;--Bytes VARIABLE addr_ind : NATURAL; BEGIN -- Reaction to completly defined commands -- after entering the user valid command sequence IF rising_edge(CommandCompleted) THEN CASE DetectedCommand IS WHEN PPBLOCK_SET => -- Depends on protection mode reflected by PasswordMODELock IF ( PasswordMODELock = '0' ) THEN PPBLockBit := '1'; END IF; WHEN PPB_PROG => IF ( PPBLockBit = '0' ) THEN PPB(GroupID) := '1'; END IF; WHEN PPB_ERASE => IF ( PPBLockBit = '0' ) THEN EraseAllPPBs(PPB,PPBLockBit); END IF; WHEN SecSi_ENTRY => SecSiENABLED <= TRUE; WHEN SecSi_EXIT => SecSiENABLED <= FALSE; WHEN SecSiPB_PROG => SecSiPB <= '1'; WHEN PPMLB_PROG => IF ( PersistentMODELock /= '1' ) THEN PasswordMODELock <= '1'; PPBLockBit := '1'; END IF; WHEN SPMLB_PROG => IF ( PasswordMODELock /= '1' ) THEN PersistentMODELock <= '1'; END IF; WHEN UBPASS => UNLOCKBYPASS <= TRUE; WHEN UBPASSRES => UNLOCKBYPASS <= FALSE; END CASE; END IF; -- Detection of WRITE conditions IF CommandDataLatched'Event AND CommandDataLatched = TRUE THEN CASE CurrentState IS WHEN PROGCYC | PROGCYC_E => SectorProg := ReturnSectorID(LatchAddr); GroupProg := ReturnGroupID(SectorProg); BankProg <= ReturnBank(LatchAddr); DataProg(7) := LatchData(7); StatusReg(7) := LatchData(7); IF ( (DYB(SectorProg)='1') OR (PPB(GroupProg)='1')) OR -- Programming a protected sector ((( SectorProg = HWProtect1 ) OR ( SectorProg = HWProtect2 )) AND ( WPNeg = '0')) OR -- Hardware protected ( (SectorProg = SecSiSector) AND ( SecSiENABLED ) AND (SecSiPB = '1') ) OR -- Programming within SecSi sector when SecSi protected -- SecSi overlays but can not be changed due to -- SecSi Protection bit status ((CurrentState = PROGCYC_E) AND EraseSecFlag(SectorProg)) THEN -- trying to program an erasing sector from erase-suspend Transition <= WPPROG_T, NONE_T AFTER ttran; ELSE -- Status for 1us then return to initial state IF ( WORDNeg = '0' ) THEN AddrProg := to_nat(LatchAddr(19 downto 0)&LatchAddrLSB); DataProg(15 downto 0) := LatchData(15 downto 0); WORDProg := TRUE; ELSE AddrProg := to_nat(LatchAddr(19 downto 0)&'0'); DataProg := LatchData(31 downto 0); WORDProg := FALSE; END IF; ProgStart <= '1', '0' AFTER tcomm; Transition <= EPA_T, NONE_T AFTER ttran; END IF; WHEN CRWRITE => ConfReg := LatchData( 15 downto 0 ); SYNC <= LatchData(15)='0'; Transition <= INIT_T, NONE_T AFTER ttran; WHEN DYB_WE => IF ((NOT SecSiENABLED) OR (SecSiENABLED AND ( ReturnSectorID(LatchAddr) /= SecSiSector))) AND ( to_nat(LatchData(7 downto 0)) <= 1 ) THEN DYB(ReturnSectorID(LatchAddr)) <= LatchData(0); END IF; Transition <= INIT_T, NONE_T AFTER ttran; WHEN OTHERS => NULL; END CASE; END IF; -- Detection of CLK rising edges, burst mode, sync reads IF ( SYNC ) THEN IF rising_edge(CLK) THEN CASE CurrentState IS WHEN READ_BURST => IF ( BurstDelay > 0 ) THEN BurstDelay := BurstDelay - 1; END IF; IF BurstDelay = 0 THEN ReadOK := OE_burst = '0' AND CENeg_gl = '0' AND WENeg_gl ='1'; IF ReadOK THEN IF WrapArround(ConfReg(8),WORDNeg, BurstCount,BurstInd,BurstBorder) THEN INDNeg_zd <= '0'; ELSE INDNeg_zd <= '1'; END IF; ELSE IF NOT ( OENeg = '0' AND OE_burst = '1' ) THEN IF Dout_zd /= Zzz & Zzz THEN Dout_zd <= Zzz & Zzz; END IF; INDNeg_zd <= 'Z'; END IF; END IF; IF SecSiENABLED AND ReturnSectorID(RdA) = SecSiSector THEN IF TimingModel(12) = 'T' THEN --TimingModel = "AM29BDD320GTXXX" ReadData := to_slv(SecSiRegion(BurstAddr(BurstCount+1) mod SecSiSize),16) & to_slv(SecSiRegion(BurstAddr(BurstCount) mod SecSiSize),16); ELSE ReadData := to_slv(SecSiRegion((BurstAddr(BurstCount+1) - 16#1FF000#) mod SecSiSize),16) & to_slv(SecSiRegion((BurstAddr(BurstCount) - 16#1FF000#) mod SecSiSize),16); END IF; ELSE ReadData := to_slv(Flash(BurstAddr(BurstCount+1)) ,16) & to_slv(Flash(BurstAddr(BurstCount)),16); END IF; IF WORDNeg = '0' THEN IF ReadOK THEN Dout_zd(15 downto 0) <= ReadData(15 downto 0); END IF; BurstCount := BurstCount + 1; ELSE IF ReadOK THEN Dout_zd <= ReadData; END IF; BurstCount := BurstCount + 2; END IF; IF NOT ReadOK THEN Dout_temp := ReadData; END IF; IF BurstCount = BurstBorder THEN BurstCount := 0; END IF; END IF; WHEN STATUS_SYNC => -- sync READ operation, does not iterate like BURST MODE -- same data returned after initial delay IF ( BurstDelay > 0 ) THEN BurstDelay := BurstDelay - 1; END IF; IF BurstDelay = 0 THEN ReadOK := OENeg_gl = '0' AND CENeg_gl = '0' AND WENeg_gl ='1'; IF Dout_zd /= Zzz & Zzz THEN Dout_zd <= Zzz & Zzz; END IF; IF WORDNeg = '0' THEN IF ReadOK THEN Dout_zd(15 downto 0) <= SyncData(15 downto 0); END IF; ELSE IF ReadOK THEN Dout_zd <= SyncData; END IF; END IF; END IF; WHEN OTHERS => NULL; END CASE; END IF; -- Detection of BURST Halt IF CurrentState = READ_BURST OR CurrentState = STATUS_SYNC THEN IF ( falling_edge(ADVNeg) ) THEN Transition <= SYNCBACK_T, NONE_T AFTER ttran; IF CurrentState = READ_BURST THEN INDNeg_zd <= '1'; END IF; END IF; IF( rising_edge(CENeg_gl)) THEN Transition <= SYNCBACK_T, NONE_T AFTER ttran; INDNeg_zd <= 'Z'; END IF; -- do not halt, outputs HiZ IF ( rising_edge(OENeg_gl)) THEN INDNeg_zd <= 'Z'; END IF; END IF; END IF; -- Detection of READ conditions IF ( NOT SYNC AND (((CENeg_gl = '0') AND (OENeg_gl = '0') AND (WENeg_gl = '1') AND (RESET_D = '1') AND (CENeg_gl'Event OR OENeg_gl'Event)) OR ((A'Event OR Am1'Event) AND OENeg = '0' AND WENeg = '1' AND CENeg='0'))) OR ( SYNC AND ReadAddrLatched'Event AND (ReadAddrLatched = TRUE)) THEN -- In sync MODE data returned reffers to latched address -- In async MODE data returned reffers to address lines IF SYNC THEN RdA := LatchAddr; RdAm1 := LatchAddrLSB; ELSE RdA := A; RdAm1 := Am1; END IF; IF NOT SYNC AND NOT ( CurrentState = DUMMY OR CurrentState = CANNOTREAD ) THEN INDNeg_zd <= '1'; END IF; IF WORDNeg = '0' THEN Dout_zd(31 downto 16) <= Zzz; END IF; CASE CurrentState IS WHEN CANNOTREAD => NULL; WHEN READ_SYNC => LINEARACCESS_INIT(WORDNeg,LatchAddr,LatchAddrLSB,ConfReg, BurstAddr,BurstBorder,BurstCount,BurstDelay,BurstInd); Transition <= SYNC_T, NONE_T AFTER ttran; WHEN READ_ASYNC => FlashData := to_slv(Flash(to_nat(RdA&'1')),16) &to_slv(Flash(to_nat(RdA&'0')),16); READPROC( DOut_zd, RdAm1,FlashData,WORDNeg,SecSiENABLED,RdA); WHEN CRVERIFY => IF (((CRVerifySmallBank = TRUE )AND( ReturnBank(RdA) = SMALL)) OR ((CRVerifySmallBank = FALSE ) AND( ReturnBank(RdA) = LARGE))) THEN -- Right bank addressed IF SYNC THEN SyncData := Zero & ConfReg; BurstDelay := to_nat(ConfReg(13 downto 10)) + 2; Transition <= SYNCSTATUS_T, NONE_T AFTER ttran; ELSE IF WORDNeg = '1' THEN Dout_zd(31 downto 16) <= Zero; END IF; Dout_zd(15 downto 0) <= ConfReg; Transition <= DUMMY_T, NONE_T AFTER ttran; END IF; ELSE -- Bank not addressed and this READ should return memory data IF NOT SYNC THEN FlashData := to_slv(Flash(to_nat(RdA&'1')),16) & to_slv(Flash(to_nat(RdA&'0')),16); READPROC( DOut_zd, RdAm1,FlashData,WORDNeg, SecSiENABLED,RdA); ELSE LINEARACCESS_INIT(WORDNeg,LatchAddr,LatchAddrLSB, ConfReg,BurstAddr,BurstBorder,BurstCount, BurstDelay,BurstInd); Transition <= SYNC_T, NONE_T AFTER ttran; END IF; END IF; WHEN BITSTATUS => -- RD(0) is corresponding bit IF ( WORDNeg = '1'