----------------------------------------------------------------------------- -- File name : am29pdl128g.vhd ------------------------------------------------------------------------------- -- Copyright (C) 2007 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 S.Petrovic 07 Jul 19 Initial version -- ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: FLASH -- Technology: Flash Memory -- Part: AM29PDL128G -- -- Description: 128Mbit (4M x32-Bit) Simultaneous operation, -- Bottom/Top boot sector -- ------------------------------------------------------------------------------- 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 am29pdl128g IS GENERIC ( -- tipd delays: interconnect path delays tipd_A0 : VitalDelayType01 := VitalZeroDelay01; tipd_A1 : VitalDelayType01 := VitalZeroDelay01; tipd_A2 : VitalDelayType01 := VitalZeroDelay01; tipd_A3 : VitalDelayType01 := VitalZeroDelay01; tipd_A4 : VitalDelayType01 := VitalZeroDelay01; tipd_A5 : VitalDelayType01 := VitalZeroDelay01; tipd_A6 : VitalDelayType01 := VitalZeroDelay01; tipd_A7 : VitalDelayType01 := VitalZeroDelay01; tipd_A8 : VitalDelayType01 := VitalZeroDelay01; tipd_A9 : VitalDelayType01 := VitalZeroDelay01; tipd_A10 : VitalDelayType01 := VitalZeroDelay01; tipd_A11 : VitalDelayType01 := VitalZeroDelay01; tipd_A12 : VitalDelayType01 := VitalZeroDelay01; tipd_A13 : VitalDelayType01 := VitalZeroDelay01; tipd_A14 : VitalDelayType01 := VitalZeroDelay01; tipd_A15 : VitalDelayType01 := VitalZeroDelay01; tipd_A16 : VitalDelayType01 := VitalZeroDelay01; tipd_A17 : VitalDelayType01 := VitalZeroDelay01; tipd_A18 : VitalDelayType01 := VitalZeroDelay01; tipd_A19 : VitalDelayType01 := VitalZeroDelay01; tipd_A20 : VitalDelayType01 := VitalZeroDelay01; tipd_A21 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; tipd_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_WPNeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WORDNeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays for FLASH tpd_A0_DQ0_PgRead_eq_0 : VitalDelayType01 := UnitDelay01; tpd_A0_DQ0_PgRead_eq_1 : VitalDelayType01 := UnitDelay01; tpd_CENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; tpd_OENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; tpd_WENeg_RYBYNeg : VitalDelayType01Z := UnitDelay01Z; --tFLQZ/tFHQV tpd_WORDNeg_DQ31 : VitalDelayType01Z := UnitDelay01Z; tsetup_WORDNeg_WENeg : VitalDelayType := UnitDelay;-- tsetup_A0_WENeg : VitalDelayType := UnitDelay;--tAS tsetup_A0_OENeg : VitalDelayType := UnitDelay;--tASO tsetup_DQ0_WENeg : VitalDelayType := UnitDelay;--tDVWH tsetup_CENeg_WENeg : VitalDelayType := UnitDelay;--tCS tsetup_WENeg_CENeg : VitalDelayType := UnitDelay; tsetup_WENeg_OENeg_noedge_embd_eq_0 : VitalDelayType := UnitDelay;--no toggling tsetup_WENeg_OENeg_noedge_embd_eq_1 : VitalDelayType := UnitDelay;--when toggling thold_WORDNeg_WENeg : VitalDelayType := UnitDelay;-- thold_A0_WENeg : VitalDelayType := UnitDelay;--tAH thold_A0_OENeg : VitalDelayType := UnitDelay;--tAHT thold_DQ0_WENeg : VitalDelayType := UnitDelay;--tWHDX thold_CENeg_WENeg : VitalDelayType := UnitDelay;--tCH thold_WENeg_OENeg : VitalDelayType := UnitDelay;--tOEH thold_WENeg_CENeg : VitalDelayType := UnitDelay;--tGHWL thold_WORDNeg_CENeg : VitalDelayType := UnitDelay;--tELFH,tELFL thold_CENeg_RESETNeg : VitalDelayType := UnitDelay;--tRH thold_OENeg_RESETNeg : VitalDelayType := UnitDelay;--tRH --read cycle tpw_A0_negedge : VitalDelayType := UnitDelay; tpw_A0_posedge : VitalDelayType := UnitDelay; tpw_CENeg_negedge : VitalDelayType := UnitDelay;--tCP tpw_CENeg_posedge : VitalDelayType := UnitDelay;--tCPH tpw_WENeg_negedge : VitalDelayType := UnitDelay;--WP tpw_WENeg_posedge : VitalDelayType := UnitDelay;--tWPH tpw_OENeg_posedge : VitalDelayType := UnitDelay;--tOEPH tpw_RESETNeg_negedge : VitalDelayType := UnitDelay;--tRP -- tdevice values: values for internal delays tdevice_POW : VitalDelayType := 12.6 us; tdevice_PODW : VitalDelayType := 16 us; --Sector Erase Operation tWHWH2 tdevice_SEO : VitalDelayType := 200 ms; --erase suspend timeout - only max time specified tdevice_ETSTART : VitalDelayType := 20 us; --sector erase command sequence timeout tdevice_CTMOUT : VitalDelayType := 80 us; --device Ready after Hardware reset(during embeded algorithm) tdevice_READY : VitalDelayType := 20 us; --PPB program time tdevice_PPBW : VitalDelayType := 100 us; --PPB erase time tdevice_PPBE : VitalDelayType := 1.2 ms; -- unlock ppbLock command - time neaded for bouth part of password tdevice_UNLOCK : VitalDelayType := 2 us; --tUNLOCK -- 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"; secsi_file_name : STRING := "none"; prot_file_name : STRING := "none"; UserPreload : BOOLEAN := FALSE; LongTiming : BOOLEAN := TRUE; FactoryLocked : BOOLEAN := FALSE; -- For FMF SDF technology file usage TimingModel : STRING --:= DefaultTimingModel ); PORT ( A21 : IN std_ulogic := 'U'; A20 : IN std_ulogic := 'U'; A19 : IN std_ulogic := 'U'; A18 : IN std_ulogic := 'U'; A17 : IN std_ulogic := 'U'; A16 : IN std_ulogic := 'U'; A15 : IN std_ulogic := 'U'; A14 : IN std_ulogic := 'U'; A13 : IN std_ulogic := 'U'; A12 : IN std_ulogic := 'U'; A11 : IN std_ulogic := 'U'; A10 : IN std_ulogic := 'U'; A9 : IN std_ulogic := 'U'; A8 : IN std_ulogic := 'U'; A7 : IN std_ulogic := 'U'; A6 : IN std_ulogic := 'U'; A5 : IN std_ulogic := 'U'; A4 : IN std_ulogic := 'U'; A3 : IN std_ulogic := 'U'; A2 : IN std_ulogic := 'U'; A1 : IN std_ulogic := 'U'; A0 : IN std_ulogic := 'U'; 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'; DQ8 : INOUT std_ulogic := 'U'; DQ7 : INOUT std_ulogic := 'U'; DQ6 : INOUT std_ulogic := 'U'; DQ5 : INOUT std_ulogic := 'U'; DQ4 : INOUT std_ulogic := 'U'; DQ3 : INOUT std_ulogic := 'U'; DQ2 : INOUT std_ulogic := 'U'; DQ1 : INOUT std_ulogic := 'U'; DQ0 : INOUT std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; WORDNeg : IN std_ulogic := 'U'; RYBYNeg : OUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of am29pdl128g : ENTITY IS TRUE; END am29pdl128g; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of am29pdl128g IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "am29pdl128g"; CONSTANT MaxData : NATURAL := 16#FFFF#; CONSTANT SecSize : NATURAL := 16#8000#; --32kwords CONSTANT SubSecSize : NATURAL := 16#1000#; --4kWords CONSTANT SecSiSize : NATURAL := 16#80#;--128 CONSTANT BankN : NATURAL := 4; CONSTANT SecN : NATURAL := 256; CONSTANT SSecN : NATURAL := 8; CONSTANT HAddr : NATURAL := 21; CONSTANT BotSec : NATURAL := 0; CONSTANT TopSec : NATURAL := 255; CONSTANT glitch_t : TIME := 5 ns; CONSTANT PL : NATURAL := 16#0A#; -- PPMLB address CONSTANT SL : NATURAL := 16#12#; -- SPMLB address CONSTANT OW : NATURAL := 16#1A#; -- secsi address CONSTANT WP : NATURAL := 16#3A#; -- PPB program address CONSTANT EP : NATURAL := 16#7A#; -- PPB erase address -- interconnect path delay signals 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 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 WPNeg_ipd : std_ulogic := 'U'; SIGNAL RESETNeg_ipd : std_ulogic := 'U'; SIGNAL WORDNeg_ipd : std_ulogic := 'U'; --- internal delays SIGNAL Pow_in : std_ulogic := '0'; SIGNAL Pow_out : std_ulogic := '0'; SIGNAL Seo_in : std_ulogic := '0'; SIGNAL Seo_out : std_ulogic := '0'; SIGNAL ETStart_in : std_ulogic := '0'; SIGNAL ETStart_out : std_ulogic := '0'; -- Suspend Erase Timeout SIGNAL CTMOUT_in : std_ulogic := '0'; SIGNAL CTMOUT_out : std_ulogic := '0'; -- Start Erase timeout SIGNAL Ready_in : std_ulogic := '0'; SIGNAL Ready_out : std_ulogic := '0'; -- Device Ready after reset SIGNAL Ppbw_in : std_ulogic := '0'; SIGNAL Ppbw_out : std_ulogic := '0'; SIGNAL Ppbe_in : std_ulogic := '0'; SIGNAL Ppbe_out : std_ulogic := '0'; SIGNAL Unlock_in : std_ulogic := '0'; SIGNAL Unlock_out : std_ulogic := '0'; BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays POW :VitalBuf(Pow_out, Pow_in, (tdevice_POW ,UnitDelay)); SEO :VitalBuf(Seo_out, Seo_in, (tdevice_SEO ,UnitDelay)); CTMOUT :VitalBuf(CTMOUT_out, CTMOUT_in, (tdevice_CTMOUT ,UnitDelay)); READY :VitalBuf(Ready_out, Ready_in, (tdevice_READY ,UnitDelay)); ETSTART:VitalBuf(ETStart_out,ETStart_in, (tdevice_ETSTART ,UnitDelay)); UNLOCK :VitalBuf(Unlock_out, Unlock_in, (tdevice_UNLOCK ,UnitDelay)); PPBW :VitalBuf(Ppbw_out, Ppbw_in, (tdevice_PPBW ,UnitDelay)); PPBE :VitalBuf(Ppbe_out, Ppbe_in, (tdevice_PPBE ,UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_0 : VitalWireDelay (A21_ipd, A21, tipd_A21); w_1 : VitalWireDelay (A20_ipd, A20, tipd_A20); w_2 : VitalWireDelay (A19_ipd, A19, tipd_A19); w_3 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_4 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_5 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_6 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_7 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_8 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_9 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_10 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_11 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_12 : VitalWireDelay (A9_ipd, A9 , tipd_A9 ); w_13 : VitalWireDelay (A8_ipd, A8 , tipd_A8 ); w_14 : VitalWireDelay (A7_ipd, A7 , tipd_A7 ); w_15 : VitalWireDelay (A6_ipd, A6 , tipd_A6 ); w_16 : VitalWireDelay (A5_ipd, A5 , tipd_A5 ); w_17 : VitalWireDelay (A4_ipd, A4 , tipd_A4 ); w_18 : VitalWireDelay (A3_ipd, A3 , tipd_A3 ); w_19 : VitalWireDelay (A2_ipd, A2 , tipd_A2 ); w_20 : VitalWireDelay (A1_ipd, A1 , tipd_A1 ); w_21 : VitalWireDelay (A0_ipd, A0 , tipd_A0 ); w_22 : VitalWireDelay (DQ31_ipd, DQ31, tipd_DQ31); w_23 : VitalWireDelay (DQ30_ipd, DQ30, tipd_DQ30); w_24 : VitalWireDelay (DQ29_ipd, DQ29, tipd_DQ29); w_25 : VitalWireDelay (DQ28_ipd, DQ28, tipd_DQ28); w_26 : VitalWireDelay (DQ27_ipd, DQ27, tipd_DQ27); w_27 : VitalWireDelay (DQ26_ipd, DQ26, tipd_DQ26); w_28 : VitalWireDelay (DQ25_ipd, DQ25, tipd_DQ25); w_29 : VitalWireDelay (DQ24_ipd, DQ24, tipd_DQ24); w_30 : VitalWireDelay (DQ23_ipd, DQ23, tipd_DQ23); w_31 : VitalWireDelay (DQ22_ipd, DQ22, tipd_DQ22); w_32 : VitalWireDelay (DQ21_ipd, DQ21, tipd_DQ21); w_33 : VitalWireDelay (DQ20_ipd, DQ20, tipd_DQ20); w_34 : VitalWireDelay (DQ19_ipd, DQ19, tipd_DQ19); w_35 : VitalWireDelay (DQ18_ipd, DQ18, tipd_DQ18); w_36 : VitalWireDelay (DQ17_ipd, DQ17, tipd_DQ17); w_37 : VitalWireDelay (DQ16_ipd, DQ16, tipd_DQ16); w_38 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_39 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_40 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_41 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_42 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_43 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_44 : VitalWireDelay (DQ9_ipd, DQ9, tipd_DQ9); w_45 : VitalWireDelay (DQ8_ipd, DQ8, tipd_DQ8); w_46 : VitalWireDelay (DQ7_ipd, DQ7, tipd_DQ7); w_47 : VitalWireDelay (DQ6_ipd, DQ6, tipd_DQ6); w_48 : VitalWireDelay (DQ5_ipd, DQ5, tipd_DQ5); w_49 : VitalWireDelay (DQ4_ipd, DQ4, tipd_DQ4); w_50 : VitalWireDelay (DQ3_ipd, DQ3, tipd_DQ3); w_51 : VitalWireDelay (DQ2_ipd, DQ2, tipd_DQ2); w_52 : VitalWireDelay (DQ1_ipd, DQ1, tipd_DQ1); w_53 : VitalWireDelay (DQ0_ipd, DQ0, tipd_DQ0); w_54 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); w_55 : VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg); w_56 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_57 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg); w_58 : VitalWireDelay (RESETNeg_ipd, RESETNeg, tipd_RESETNeg); w_59 : VitalWireDelay (WORDNeg_ipd, WORDNeg, tipd_WORDNeg); END BLOCK; --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK PORT ( A : IN std_logic_vector(HAddr DOWNTO 0) := (OTHERS => 'U'); DIn : IN std_logic_vector(31 DOWNTO 0) := (OTHERS => 'U'); DOut : OUT std_logic_vector(31 DOWNTO 0) := (OTHERS => 'Z'); 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'; RYBYNeg : OUT std_ulogic := 'U' ); PORT MAP ( A(21)=> A21_ipd, A(20)=> A20_ipd, A(19)=> A19_ipd, A(18)=> A18_ipd, A(17)=> A17_ipd, A(16)=> A16_ipd, A(15)=> A15_ipd, A(14)=> A14_ipd, A(13)=> A13_ipd, A(12)=> A12_ipd, A(11)=> A11_ipd, A(10)=> A10_ipd, A(9) => A9_ipd, A(8) => A8_ipd, A(7) => A7_ipd, A(6) => A6_ipd, A(5) => A5_ipd, A(4) => A4_ipd, A(3) => A3_ipd, A(2) => A2_ipd, A(1) => A1_ipd, A(0) => A0_ipd, DIn(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, 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, CENeg => CENeg_ipd, OENeg => OENeg_ipd, WENeg => WENeg_ipd, WPNeg => WPNeg_ipd, WORDNeg => WORDNeg_ipd, RESETNeg => RESETNeg_ipd, RYBYNeg => RYBYNeg ); -- State Machine : State_Type TYPE state_type IS ( RESET, Z001, PREL_SETBWB, PREL_ULBYPASS, UNLOCK_RESET, DYB, STATUS_BPROTECT, PPB_ERASE, PPB_PROGRAM, PPB_PROGRAM_VERIFY, PPB_ERASE_VERIFY, PPB_LOCK, PERSISTANT_MODE_PROGRAM, PERSISTANT_MODE_VERIFY, OTP_LOCK_PROGRAM, OTP_LOCK_VERIFY, PASSWORD_MODE_PROGRAM, PASSWORD_MODE_VERIFY, PASSWORD_VERIFY, PASSWORD_UNLOCK_SET, PASSWORD_UNLOCK, PROT_STATUS, CFI, AS, AS_CFI, A0SEEN, C8, C8_Z001, C8_PREL, ERS, SERS, ESPS, SERS_EXEC, ESP, ESP_AS, ESP_Z001, ESP_PREL, ESP_CFI, ESP_ULBYPASS, ESP_UNLOCK_RESET, ESP_AS_CFI, ESP_A0SEEN, PGMS, OTP, OTP_Z001, OTP_PREL, OTP_AS, OTP_A0SEEN ); --Array of Sub sector start-end address within sector TYPE SubSecAddr IS ARRAY (0 TO SSecN-1) OF NATURAL; TYPE SecType IS ARRAY (0 TO SecSize-1) OF INTEGER RANGE -1 TO MaxData; --Flash Memory Bank Array TYPE MemArray IS ARRAY (0 TO SecN-1) OF SecType; TYPE SecSiArray IS ARRAY (0 TO SecSiSize-1) OF INTEGER RANGE -1 TO MaxData; -- states SIGNAL current_state : state_type; SIGNAL next_state : state_type; -- Powerup SIGNAL PoweredUp : std_logic := '0'; --zero delay signals SIGNAL RY_zd : std_logic := '1'; SIGNAL RY_t : std_logic := '1'; SIGNAL DOut_zd : std_logic_vector(31 DOWNTO 0) := (OTHERS =>'Z'); SIGNAL DOut_pass : std_logic_vector(31 DOWNTO 0) := (OTHERS =>'Z'); SIGNAL Dout_x : std_logic_vector(31 DOWNTO 0) := (OTHERS =>'Z'); --FSM control signals SIGNAL Ulbypass : std_logic := '0'; -- Program Control Signals SIGNAL PGMS_ACT : std_logic := '0'; --Erase Embedded SIGNAL PDone : std_logic := '1'; --Prog. Done SIGNAL PStart : std_logic := '0'; --Start Programming SHARED VARIABLE PErr : BOOLEAN := FALSE; --Error Program -- Erase Control Signals SIGNAL ERS_ACT : std_logic := '0'; --Erae Embedded SIGNAL EDone : std_logic := '1'; --Ers. Done SIGNAL EStart : std_logic := '0'; --Start Erase SIGNAL ESusp : std_logic := '0'; --Suspend Erase SIGNAL EStart_susp : std_logic := '0'; --Start and suspend Erase SIGNAL ERes : std_logic := '0'; --Resume Erase SHARED VARIABLE EErr : BOOLEAN := FALSE; --Error ERASE SHARED VARIABLE ers_cnt : NATURAL := 0; SHARED VARIABLE PassProg : BOOLEAN := FALSE; --Sectors selected for erasure SHARED VARIABLE Ers_Queue : std_logic_vector(SecN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE ET_queue : std_logic_vector(SSecN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE EB_queue : std_logic_vector(SSecN-1 DOWNTO 0) := (OTHERS => '0'); --Command Register SIGNAL write : std_logic := '0'; SIGNAL read : std_logic := '0'; SIGNAL oe : BOOLEAN := FALSE; --Address within sector SHARED VARIABLE ALatch : std_logic_vector(HAddr DOWNTO 0); SHARED VARIABLE Address : NATURAL RANGE 0 TO SecSize := 0; SHARED VARIABLE BA : NATURAL RANGE 0 TO BankN-1 := 0; SHARED VARIABLE SubSA : NATURAL RANGE 0 TO SSecN := 0; SHARED VARIABLE SA : NATURAL RANGE 0 TO SecN := 0; SHARED VARIABLE AddrFsm : NATURAL := 0; SHARED VARIABLE SaPPB : NATURAL; SHARED VARIABLE SSaPPB : NATURAL; SHARED VARIABLE AddrPpb : NATURAL; SHARED VARIABLE AddrMode: NATURAL; SHARED VARIABLE A_passw : NATURAL:= 0; SIGNAL Data : std_logic_vector(15 DOWNTO 0):= (OTHERS =>'0') ; SIGNAL Data1 : std_logic_vector(15 DOWNTO 0):= (OTHERS =>'0') ; SIGNAL DataLo : NATURAL RANGE 0 TO 16#FF#; --glitch protection SIGNAL gWE_n : std_logic; SIGNAL gCE_n : std_logic; SIGNAL gOE_n : std_logic; SIGNAL RST : std_logic := '1'; SIGNAL reseted : std_logic := '0'; -- protection, password, secsi control signals SIGNAL BProt_done : std_logic := '1'; SIGNAL PPrDone : std_logic := '1'; SIGNAL PUDone : std_logic := '1'; SHARED VARIABLE OTP_lock : std_logic := '1'; SHARED VARIABLE FactoryLock : std_logic := '1'; SHARED VARIABLE Ppb_lock_b : std_logic := '0'; SHARED VARIABLE PerMLock : std_logic := '0'; SHARED VARIABLE PasMLock : std_logic := '0'; SHARED VARIABLE PasUnCycle : NATURAL := 0; SHARED VARIABLE DybProt : std_logic; SIGNAL OTP_ACT : std_logic; -- Mem(BA)(Address) SHARED VARIABLE Mem : MemArray := (OTHERS => (OTHERS => MaxData)); -- OTP Memory SHARED VARIABLE SecSi : SecSiArray := (OTHERS=> MaxData); --protected sectors and sub sectors SIGNAL S_prot : std_logic_vector(SecN-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL ST_prot : std_logic_vector(SSecN-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL SB_prot : std_logic_vector(SSecN-1 DOWNTO 0) := (OTHERS => '0'); --protected DYB sectors AND sub sectors SHARED VARIABLE SDyb_prot : std_logic_vector(SecN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE SBDyb_prot : std_logic_vector(SSecN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE STDyb_prot : std_logic_vector(SSecN-1 DOWNTO 0) := (OTHERS => '0'); --protected PPB sectors AND sub sectors SHARED VARIABLE SPpb_prot : std_logic_vector(SecN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE SBPpb_prot : std_logic_vector(SSecN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE STPpb_prot : std_logic_vector(SSecN-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL sec_prot : std_logic := '0'; SHARED VARIABLE sssa : SubSecAddr := (16#0000#, 16#1000#, 16#2000#, 16#3000#, 16#4000#, 16#5000#, 16#6000#, 16#7000#); SHARED VARIABLE ssea : SubSecAddr:= (16#0FFF#, 16#1FFF#, 16#2FFF#, 16#3FFF#, 16#4FFF#, 16#5FFF#, 16#6FFF#, 16#7FFF#); -- timing check violation SIGNAL Viol : X01 := '0'; -- insert for bankmode SHARED VARIABLE BankAutoSel : std_logic_vector(BankN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE BBusy : std_logic_vector(BankN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE BErase_t : std_logic_vector(BankN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE BankBypassLock : std_logic_vector(BankN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE BSecSi : std_logic_vector(BankN-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL BErase : std_logic_vector(BankN-1 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE tpd_OE : BOOLEAN := FALSE; SHARED VARIABLE tpd_CE : BOOLEAN := FALSE; SHARED VARIABLE read_page : BOOLEAN := FALSE; -- Access time variables SHARED VARIABLE OPENLATCH : BOOLEAN; SHARED VARIABLE FROMCE : BOOLEAN; SHARED VARIABLE FROMOE : BOOLEAN; SHARED VARIABLE ERASE_START : TIME; -- return address range for all sectors PROCEDURE ADDRHILO( VARIABLE AddrLO : INOUT NATURAL RANGE 0 to 16#7FFFFF#; VARIABLE AddrHI : INOUT NATURAL RANGE 0 to 16#7FFFFF#; VARIABLE SectorID : NATURAL) IS BEGIN IF (SectorID <= 7) THEN AddrLO := SectorID*16#1000#; AddrHI := SectorID*16#1000# + 16#0FFF#; ELSIF (SectorID > 7) AND (SectorID < 262) THEN AddrLO := SA*16#8000#; AddrHI := SA*16#8000#+16#7FFF#; ELSE AddrLO := (SectorID - 262)*16#1000# + 16#7F8000#; AddrHI := (SectorID - 262)*16#1000# + 16#7F8FFF#; END IF; END AddrHILO; BEGIN --------------------------------------------------------------------------- --Power Up time 100 ns; --------------------------------------------------------------------------- PoweredUp <= '1' AFTER 100 ns; RST <= RESETNeg AFTER 500 ns; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(CENeg, WENeg, OENeg, RESETNeg, A, DIn)--WORDNeg --Setup/Hold checks variables VARIABLE Tviol_A0_WENeg : X01 := '0'; VARIABLE Tviol_A0_CENeg : X01 := '0'; VARIABLE Tviol_A0_OENeg : X01 := '0'; VARIABLE Tviol_DQ0_WENeg : X01 := '0'; VARIABLE Tviol_DQ0_CENeg : X01 := '0'; VARIABLE Tviol_WENeg_CENeg : X01 := '0'; VARIABLE Tviol_CENeg_WENeg : X01 := '0'; VARIABLE Tviol_WORDNeg_WENeg : X01 := '0'; VARIABLE Tviol_WORDNeg_CENeg : X01 := '0'; VARIABLE Tviol_WENeg_OENeg_embd_0 : X01 := '0'; VARIABLE Tviol_WENeg_OENeg_embd_1 : X01 := '0'; VARIABLE Tviol_RYBYNeg_WENeg : X01 := '0'; VARIABLE Tviol_RYBYNeg_CENeg : X01 := '0'; VARIABLE Tviol_WENeg_OENeg : X01 := '0'; VARIABLE Tviol_CENeg_RESETNeg : X01 := '0'; VARIABLE Tviol_OENeg_RESETNeg : X01 := '0'; VARIABLE TD_A0_WENeg : VitalTimingDataType; VARIABLE TD_A0_CENeg : VitalTimingDataType; VARIABLE TD_A0_OENeg : VitalTimingDataType; VARIABLE TD_DQ0_WENeg : VitalTimingDataType; VARIABLE TD_DQ0_CENeg : VitalTimingDataType; VARIABLE TD_WENeg_CENeg : VitalTimingDataType; VARIABLE TD_CENeg_WENeg : VitalTimingDataType; VARIABLE TD_WORDNeg_WENeg : VitalTimingDataType; VARIABLE TD_WORDNeg_CENeg : VitalTimingDataType; VARIABLE TD_RYBYNeg_WENeg : VitalTimingDataType; VARIABLE TD_RYBYNeg_CENeg : VitalTimingDataType; VARIABLE TD_WENeg_OENeg_embd_0 : VitalTimingDataType; VARIABLE TD_WENeg_OENeg_embd_1 : VitalTimingDataType; VARIABLE TD_WENeg_OENeg : VitalTimingDataType; VARIABLE TD_CENeg_RESETNeg : VitalTimingDataType; VARIABLE TD_OENeg_RESETNeg : VitalTimingDataType; -- Pulse width cheks variables VARIABLE Pviol_A0 : X01 := '0'; VARIABLE Pviol_A1 : X01 := '0'; VARIABLE Pviol_A2 : X01 := '0'; VARIABLE Pviol_A3 : X01 := '0'; VARIABLE Pviol_A4 : X01 := '0'; VARIABLE Pviol_A5 : X01 := '0'; VARIABLE Pviol_A6 : X01 := '0'; VARIABLE Pviol_A7 : X01 := '0'; VARIABLE Pviol_A8 : X01 := '0'; VARIABLE Pviol_A9 : X01 := '0'; VARIABLE Pviol_A10 : X01 := '0'; VARIABLE Pviol_A11 : X01 := '0'; VARIABLE Pviol_A12 : X01 := '0'; VARIABLE Pviol_A13 : X01 := '0'; VARIABLE Pviol_A14 : X01 := '0'; VARIABLE Pviol_A15 : X01 := '0'; VARIABLE Pviol_A16 : X01 := '0'; VARIABLE Pviol_A17 : X01 := '0'; VARIABLE Pviol_A18 : X01 := '0'; VARIABLE Pviol_A19 : X01 := '0'; VARIABLE Pviol_A20 : X01 := '0'; VARIABLE Pviol_A21 : X01 := '0'; VARIABLE Pviol_CENeg_l : X01 := '0'; VARIABLE Pviol_CENeg_h : X01 := '0'; VARIABLE Pviol_OENeg : X01 := '0'; VARIABLE Pviol_WENeg_l : X01 := '0'; VARIABLE Pviol_WENeg_h : X01 := '0'; VARIABLE Pviol_RESETNeg : X01 := '0'; VARIABLE PD_A0 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A1 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A2 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A3 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A4 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A5 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A6 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A7 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A8 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A9 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A10 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A11 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A12 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A13 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A14 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A15 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A16 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A17 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A18 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A19 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A20 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_A21 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_CENeg_l : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_CENeg_h : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_OENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_WENeg_l : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_WENeg_h : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_RESETNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01; BEGIN IF TimingChecksOn THEN -- Setup/Hold Checks Violation := '0'; VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_A0_WENeg, SetupHigh => tsetup_A0_WENeg, HoldLow => thold_A0_WENeg, HoldHigh => thold_A0_WENeg, CheckEnabled => CENeg = '0', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_A0_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_WENeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CENeg, RefSignalName => "CENeg", SetupLow => tsetup_A0_WENeg, SetupHigh => tsetup_A0_WENeg, HoldLow => thold_A0_WENeg, HoldHigh => thold_A0_WENeg, CheckEnabled => WENeg = '0', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_A0_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_CENeg ); VitalSetupHoldCheck ( -- during embedded alg. TestSignal => A, TestSignalName => "A", RefSignal => OENeg, RefSignalName => "OENeg", SetupLow => tsetup_A0_OENeg, SetupHigh => tsetup_A0_OENeg, CheckEnabled => (PGMS_ACT = '1' OR ERS_ACT = '1' OR BProt_done = '0') AND CENeg = '0' AND WENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_A0_OENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_OENeg ); VitalSetupHoldCheck ( -- during embedded alg. tAHT TestSignal => A, TestSignalName => "A", RefSignal => OENeg, RefSignalName => "OENeg", HoldLow => thold_A0_OENeg, HoldHigh => thold_A0_OENeg, CheckEnabled => (PGMS_ACT = '1' OR ERS_ACT = '1' OR BProt_done = '0') AND CENeg = '0' AND WENeg = '1', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_A0_OENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_OENeg ); VitalSetupHoldCheck ( -- during embedded alg. tAHT TestSignal => A, TestSignalName => "A", RefSignal => CENeg, RefSignalName => "CENeg", HoldLow => thold_A0_OENeg, HoldHigh => thold_A0_OENeg, CheckEnabled => (PGMS_ACT = '1' OR ERS_ACT = '1' OR BProt_done = '0') AND OENeg = '0' AND WENeg = '1', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_A0_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_CENeg ); VitalSetupHoldCheck ( TestSignal => WORDNeg, TestSignalName => "WORDNeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_WORDNeg_WENeg, SetupHigh => tsetup_WORDNeg_WENeg, HoldLow => thold_WORDNeg_WENeg, HoldHigh => thold_WORDNeg_WENeg, CheckEnabled => CENeg = '0', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_WORDNeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WORDNeg_WENeg ); VitalSetupHoldCheck ( TestSignal => WORDNeg, TestSignalName => "WORDNeg", RefSignal => CENeg, RefSignalName => "CENeg", HoldLow => thold_WORDNeg_CENeg, HoldHigh => thold_WORDNeg_CENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_WORDNeg_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WORDNeg_CENeg ); VitalSetupHoldCheck ( TestSignal => Din, TestSignalName => "Din", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_DQ0_WENeg, SetupHigh => tsetup_DQ0_WENeg, HoldLow => thold_DQ0_WENeg, HoldHigh => thold_DQ0_WENeg, CheckEnabled => CENeg = '0', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_DQ0_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_DQ0_WENeg ); VitalSetupHoldCheck ( TestSignal => Din, TestSignalName => "Din", RefSignal => CENeg, RefSignalName => "CENeg", SetupLow => tsetup_DQ0_WENeg, SetupHigh => tsetup_DQ0_WENeg, HoldLow => thold_DQ0_WENeg, HoldHigh => thold_DQ0_WENeg, CheckEnabled => WENeg = '0', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_DQ0_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_DQ0_CENeg ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => OENeg, RefSignalName => "OENeg", SetupHigh => tsetup_WENeg_OENeg_noedge_embd_eq_1, CheckEnabled => EDone = '0' OR PDone = '0' OR Bprot_done = '0', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_OENeg_embd_1, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_OENeg_embd_1 ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => OENeg, RefSignalName => "OENeg", SetupHigh => tsetup_WENeg_OENeg_noedge_embd_eq_0, CheckEnabled => EDone = '1' AND PDone = '1' AND Bprot_done = '1', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_OENeg_embd_0, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_OENeg_embd_0 ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_WENeg ); 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 ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => OENeg, RefSignalName => "OENeg", HoldHigh => thold_WENeg_OENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WENeg_OENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_OENeg ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_WENeg ); 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 ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => RESETNeg, RefSignalName => "RESETNeg", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_RESETNeg ); VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OENeg", RefSignal => RESETNeg, RefSignalName => "RESETNeg", HoldHigh => thold_OENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_OENeg_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_OENeg_RESETNeg ); VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WENeg", PulseWidthLow => tpw_WENeg_negedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg_l, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_WENeg_l ); VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WENeg", PulseWidthHigh => tpw_WENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg_h, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_WENeg_h ); VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CENeg", PulseWidthLow => tpw_CENeg_negedge, CheckEnabled => WENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg_l, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CENeg_l ); VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CENeg", PulseWidthHigh => tpw_CENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg_h, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CENeg_h ); VitalPeriodPulseCheck ( --during embedded alg. TestSignal => OENeg, TestSignalName => "OENeg", PulseWidthHigh => tpw_OENeg_posedge, CheckEnabled => (EDone = '0' OR PDone = '0' OR Bprot_done = '0') AND CENeg = '0' AND WENeg = '1', HeaderMsg => InstancePath & PartID, PeriodData => PD_OENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_OENeg ); VitalPeriodPulseCheck ( TestSignal => A0, TestSignalName => "Address 0", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A0, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A0 ); VitalPeriodPulseCheck ( TestSignal => A1, TestSignalName => "Address 1", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A1, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A1 ); VitalPeriodPulseCheck ( TestSignal => A2, TestSignalName => "Address 2", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A2, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A2 ); VitalPeriodPulseCheck ( TestSignal => A3, TestSignalName => "Address 3", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A3, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A3 ); VitalPeriodPulseCheck ( TestSignal => A4, TestSignalName => "Address 4", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A4, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A4 ); VitalPeriodPulseCheck ( TestSignal => A5, TestSignalName => "Address 5", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A5, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A5 ); VitalPeriodPulseCheck ( TestSignal => A6, TestSignalName => "Address 6", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A6, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A6 ); VitalPeriodPulseCheck ( TestSignal => A7, TestSignalName => "Address 7", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A7, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A7 ); VitalPeriodPulseCheck ( TestSignal => A8, TestSignalName => "Address 8", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A8, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A8 ); VitalPeriodPulseCheck ( TestSignal => A9, TestSignalName => "Address 9", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A9, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A9 ); VitalPeriodPulseCheck ( TestSignal => A10, TestSignalName => "Address 10", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A10, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A10 ); VitalPeriodPulseCheck ( TestSignal => A11, TestSignalName => "Address 11", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A11, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A11 ); VitalPeriodPulseCheck ( TestSignal => A12, TestSignalName => "Address 12", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A12, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A12 ); VitalPeriodPulseCheck ( TestSignal => A13, TestSignalName => "Address 13", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A13, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A13 ); VitalPeriodPulseCheck ( TestSignal => A14, TestSignalName => "Address 14", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A14, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A14 ); VitalPeriodPulseCheck ( TestSignal => A15, TestSignalName => "Address 15", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A15, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A15 ); VitalPeriodPulseCheck ( TestSignal => A16, TestSignalName => "Address 16", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A16, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A16 ); VitalPeriodPulseCheck ( TestSignal => A17, TestSignalName => "Address 17", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A17, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A17 ); VitalPeriodPulseCheck ( TestSignal => A18, TestSignalName => "Address 18", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A18, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A18 ); VitalPeriodPulseCheck ( TestSignal => A19, TestSignalName => "Address 19", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A19, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A19 ); VitalPeriodPulseCheck ( TestSignal => A20, TestSignalName => "Address 20", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A20, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A20 ); VitalPeriodPulseCheck ( TestSignal => A21, TestSignalName => "Address 21", PulseWidthLow => tpw_A0_negedge, PulseWidthHigh => tpw_A0_posedge, CheckEnabled => CENeg = '0', HeaderMsg => InstancePath & PartID, PeriodData => PD_A21, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_A21 ); VitalPeriodPulseCheck ( TestSignal => RESETNeg, TestSignalName=> "RESETNeg", PulseWidthLow => tpw_RESETNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RESETNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_RESETNeg ); Violation := Tviol_A0_WENeg OR Tviol_A0_CENeg OR Tviol_A0_OENeg OR Tviol_WORDNeg_WENeg OR Tviol_WORDNeg_CENeg OR Tviol_DQ0_WENeg OR Tviol_DQ0_CENeg OR Tviol_WENeg_OENeg_embd_0 OR Tviol_WENeg_OENeg_embd_1 OR Tviol_WENeg_OENeg OR Tviol_WENeg_CENeg OR Tviol_CENeg_WENeg OR Tviol_RYBYNeg_WENeg OR Tviol_RYBYNeg_CENeg OR Tviol_CENeg_RESETNeg OR Tviol_OENeg_RESETNeg OR Pviol_A0 OR Pviol_A1 OR Pviol_A2 OR Pviol_A3 OR Pviol_A4 OR Pviol_A5 OR Pviol_A6 OR Pviol_A7 OR Pviol_A8 OR Pviol_A9 OR Pviol_A10 OR Pviol_A11 OR Pviol_A12 OR Pviol_A13 OR Pviol_A14 OR Pviol_A15 OR Pviol_A16 OR Pviol_A17 OR Pviol_A18 OR Pviol_A19 OR Pviol_A20 OR Pviol_A21 OR Pviol_CENeg_l OR Pviol_CENeg_h OR Pviol_OENeg OR Pviol_WENeg_l OR Pviol_WENeg_h OR Pviol_RESETNeg; ASSERT Violation = '0' REPORT InstancePath & partID & " simulation may be inaccurate due to timing violations" SEVERITY WARNING; Viol <= violation; END IF; -- TimingChecksOn END PROCESS VITALTimingCheck; --------------------------------------------------------------------------- -- sequential process for reset control and FSM state transition --------------------------------------------------------------------------- StateTransition : PROCESS(next_state, RESETNeg, RST, Ready_out, PDone, EDone, PoweredUp) VARIABLE R : std_logic := '0'; --prog or erase in progress VARIABLE E : std_logic := '0'; --reset timming error BEGIN IF PoweredUp = '1' THEN --Hardware reset timing control IF falling_edge(RESETNeg) THEN E := '0'; IF (PDone = '0' OR EDone = '0') THEN --IF program or erase in progress Ready_in <= '1'; R := '1'; ELSE Ready_in <= '0'; R := '0'; --prog or erase not in progress END IF; ELSIF rising_edge(RESETNeg) AND RST = '1' THEN --RESET# pulse < tRP Ready_in <= '0'; R := '0'; E := '1'; END IF; IF RESETNeg = '1' AND ( R = '0' OR (R = '1' AND Ready_out = '1')) THEN current_state <= next_state; Ready_in <= '0'; E := '0'; R := '0'; reseted <= '1'; ELSIF (R = '0' AND RESETNeg = '0' AND RST = '0') OR (R = '1' AND RESETNeg = '0' AND RST = '0' AND Ready_out = '0') OR (R = '1' AND RESETNeg = '1' AND RST = '0' AND Ready_out = '0') OR (R = '1' AND RESETNeg = '1' AND RST = '1' AND Ready_out = '0') THEN --no state transition while RESET# low current_state <= RESET; --reset start reseted <= '0'; END IF; ELSE current_state <= RESET; -- reset reseted <= '0'; E := '0'; R := '0'; END IF; END PROCESS StateTransition; --------------------------------------------------------------------------- --Glitch Protection: Inertial Delay does not propagate pulses <5ns --------------------------------------------------------------------------- gWE_n <= WENeg AFTER 5 ns; gCE_n <= CENeg AFTER 5 ns; gOE_n <= OENeg AFTER 5 ns; -- process that detect read or write cycle on bus write_dc: PROCESS (gWE_n, gCE_n, gOE_n, RESETNeg, reseted) BEGIN IF RESETNeg /= '0' AND reseted = '1' THEN IF (gWE_n = '0') AND (gCE_n = '0') AND (gOE_n = '1') THEN write <= '1'; ELSIF (gWE_n = '1' OR gCE_n = '1') AND gOE_n = '1' THEN write <= '0'; ELSE write <= '0'; END IF; END IF; IF reseted = '1' THEN IF ((gWE_n = '1') AND (gCE_n = '0') AND (gOE_n = '0')) THEN read <= '1'; ELSE read <= '0'; END IF; 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 (WENeg'EVENT AND (WENeg = gWE_n) AND CENeg = '0') OR (CENeg'EVENT AND (CENeg = gCE_n)) OR (OENeg'EVENT AND (OENeg = gOE_n) AND CENeg = '0') THEN ASSERT false REPORT "Glitch detected on control signals" SEVERITY warning; END IF; END PROCESS PulseWatch; --------------------------------------------------------------------------- -- Latch address process --------------------------------------------------------------------------- BusCycleDecode : PROCESS(A, Din, write, WORDNeg, WENeg, CENeg, OENeg, reseted) VARIABLE BA_tmp : NATURAL; VARIABLE Addrtmp2 : NATURAL RANGE 0 TO 16#7FFFFF#; VARIABLE conv : NATURAL; VARIABLE sector : NATURAL; VARIABLE AddrLO, AddrHI : NATURAL; VARIABLE A_tmp : NATURAL; BEGIN IF reseted = '1' THEN IF (rising_edge(WENeg) OR rising_edge(CENeg)) AND write = '1' THEN DataLo <= to_nat(Din(7 DOWNTO 0)); Data <= Din(15 downto 0); IF WORDNeg = '1' THEN Data1 <= Din(31 downto 16); END IF; ELSIF (CENeg = '0' AND WENeg /= OENeg AND Din(31)/='X') THEN ALatch := A; IF WORDNeg = '0' THEN IF Din(31)/='Z' THEN Addrtmp2 := to_nat(A & Din(31)); END IF; ELSE Addrtmp2 := to_nat(A & '0'); END IF; BA_tmp := to_nat(A(21 downto 19)); A_tmp := to_nat(A); END IF; IF rising_edge(write) OR falling_edge(OENeg) OR ((A'EVENT OR (Din(31)'EVENT AND WORDNeg='0') OR WORDNeg'EVENT ) AND WENeg='1' AND CENeg='0' AND OENeg='0' ) OR (CENeg='0' AND OENeg='0' AND WENeg='1') THEN conv := Addrtmp2 / 16#8000#; IF ( conv = 0 ) THEN sector := Addrtmp2 / 16#1000#; SubSA := Addrtmp2 / 16#1000#; ELSIF ( conv >= 1 ) AND ( conv < 255 ) THEN sector := conv+7; SubSA := 0; ELSE sector:= 262 + (Addrtmp2 - 16#7F8000#)/16#1000#; SubSA := (Addrtmp2 - 16#7F8000#)/16#1000#; END IF; IF ( sector <=7 ) THEN SA := BotSec; ELSIF ( sector < 262) THEN SA := sector-7; ELSE SA := TopSec; END IF; ADDRHILO(AddrLO, AddrHI, sector); Address := Addrtmp2 - AddrLO; IF SA = 0 THEN Address := Address + SubSA*16#1000#; ELSIF SA = 255 THEN Address := Address MOD 16#1000# + SubSA*16#1000#; END IF; AddrFsm := (Address MOD 16#1000#)/2; AddrPpb := to_nat(ALatch(6 DOWNTO 0)); AddrMode := to_nat(ALatch(5 DOWNTO 0)); A_passw := Addrtmp2 MOD 4; IF BA_tmp = 0 THEN BA := 0; ELSIF BA_tmp = 7 THEN BA := 3; ELSIF BA_tmp = 1 OR BA_tmp = 2 OR BA_tmp = 3 THEN BA := 1; ELSE BA := 2; END IF; END IF; END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- Timing control for the Program Operations --------------------------------------------------------------------------- ProgTime : PROCESS (PSTART, WORDNeg, ESusp, OTP_ACT, reseted) VARIABLE duration : time; VARIABLE start : time; VARIABLE Prog : time; VARIABLE cnt : NATURAL RANGE 0 TO SecN + 1 := 0; BEGIN IF WORDNeg = '0' THEN Prog := tdevice_POW; ELSE Prog := tdevice_PODW; END IF; IF LongTiming = FALSE THEN Prog := Prog/1; ELSE Prog := Prog; END IF; IF rising_edge(reseted) THEN PDone <= '1'; -- reset done, programming terminated ELSIF reseted = '1' THEN IF rising_edge(PStart) AND PDone = '1' THEN IF NOT PErr THEN duration := Prog - glitch_t; PDone <= '0', '1' AFTER duration; ELSE PDone <= '0', '1' AFTER 1 us; ASSERT FALSE REPORT "Cannot write in suspend/ protect sector" SEVERITY NOTE; END IF; END IF; END IF; END PROCESS ProgTime; --------------------------------------------------------------------------- -- Timing control for the Erase Operations --------------------------------------------------------------------------- ErsTime :PROCESS(EStart, ESusp, EStart_susp, ERes, reseted) VARIABLE elapsed : time; VARIABLE duration : time; VARIABLE start : time; VARIABLE Seo : time; BEGIN IF LongTiming THEN Seo := tdevice_SEO; ELSE Seo := tdevice_SEO/100; END IF; IF rising_edge(reseted) THEN EDone <= '1'; -- reset done, ERASE terminated ELSIF reseted = '1' THEN IF (rising_edge(EStart) OR rising_edge(EStart_susp)) AND EDone = '1' THEN IF NOT EErr THEN elapsed := 0 ns; duration := ers_cnt*Seo; EDone <= '0', '1' AFTER duration ; start := NOW; ELSE EDone <= '0', '1' AFTER 100 us; REPORT "Erase in protected sector is aborted" SEVERITY WARNING; END IF; END IF; IF (rising_edge(ESusp) OR rising_edge(EStart_susp)) AND EDone = '0' THEN elapsed := NOW - start; duration := duration - elapsed; EDone <= '0'; ELSIF rising_edge(ERes) AND EDone = '0' THEN start := NOW; EDone <= '0', '1' AFTER duration; END IF; END IF; END PROCESS; --------------------------------------------------------------------------- -- Main Behavior Process -- combinational process for next state generation --------------------------------------------------------------------------- StateGen :PROCESS(write, PDone, EDone, CTMOUT_out, ETStart_out, reseted, A, PPrDone, PUDone, BProt_done) VARIABLE PATTERN_1 : BOOLEAN := FALSE; VARIABLE PATTERN_2 : BOOLEAN := FALSE; VARIABLE A_PAT : BOOLEAN := FALSE; VARIABLE AddrCFI : BOOLEAN := FALSE; BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- IF falling_edge(write) THEN PATTERN_1 := (AddrFsm = 16#555# AND DataLo = 16#AA#); PATTERN_2 := (AddrFsm = 16#2AA# AND DataLo = 16#55#); A_PAT := (AddrFsm = 16#555# AND BankBypassLock(BA) = '0') OR BankBypassLock(BA) = '1'; AddrCFI := (AddrFsm = 16#55#); 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 ((AddrCFI) AND (DataLo = 16#98#)) THEN next_state <= CFI; ELSE next_state <= RESET; END IF; END IF; WHEN Z001 => IF falling_edge(write) THEN IF (PATTERN_2) THEN next_state <= PREL_SETBWB; ELSE next_state <= RESET; END IF; END IF; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT AND (DataLo = 16#A0#)) THEN next_state <= A0SEEN; ELSIF (A_PAT AND (DataLo = 16#20#)) THEN next_state <= PREL_ULBYPASS; ELSIF (A_PAT AND (DataLo = 16#90#)) THEN next_state <= AS; ELSIF (A_PAT AND (DataLo=16#38#)) THEN next_state <= OTP_A0SEEN; ELSIF (A_PAT AND (DataLo=16#C8#)) THEN next_state <= PASSWORD_VERIFY; ELSIF (A_PAT AND (DataLo=16#28#)) THEN next_state <= PASSWORD_UNLOCK_SET; ELSIF (A_PAT AND (DataLo=16#88#)) THEN next_state <= OTP; ELSIF (A_PAT AND (DataLo=16#48#)) THEN next_state <= DYB; ELSIF (A_PAT AND (DataLo=16#60#)) THEN next_state <= STATUS_BPROTECT; ELSIF (A_PAT AND (DataLo=16#58#)) THEN next_state <= PROT_STATUS; ELSIF (A_PAT AND (DataLo=16#78#)) THEN next_state <= PPB_LOCK; ELSIF (A_PAT AND (DataLo = 16#80#)) THEN next_state <= C8; ELSE next_state <= RESET; END IF; END IF; WHEN PREL_ULBYPASS => IF falling_edge(write) THEN IF (DataLo = 16#90#) THEN next_state <= UNLOCK_RESET; ELSIF (DataLo = 16#A0#) THEN next_state <= A0SEEN; ELSIF (DataLo = 16#80#) THEN next_state <= C8_PREL; ELSIF ((AddrCFI) AND (DataLo = 16#98#)) THEN next_state <= CFI; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; WHEN PASSWORD_UNLOCK_SET => IF (falling_edge(PUDone)) THEN next_state <= PASSWORD_UNLOCK; END IF; WHEN PASSWORD_UNLOCK => IF (rising_edge(PUDone)) THEN IF OTP_act = '0' THEN next_state <= RESET; ELSE next_state <= OTP; END IF; 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 AND (DataLo = 16#90#))THEN IF BSecSi(BA) = '1' THEN next_state <= OTP_AS; ELSE next_state <= OTP; END IF; ELSIF (A_PAT AND((DataLo = 16#A0#) OR (DataLo=16#38#)))THEN next_state <= OTP_A0SEEN; ELSIF (A_PAT AND (DataLo=16#C8#)) THEN next_state <= PASSWORD_VERIFY; ELSIF (A_PAT AND (DataLo=16#28#)) THEN next_state <= PASSWORD_UNLOCK_SET; ELSIF (A_PAT AND (DataLo=16#48#)) THEN next_state <= DYB; ELSIF (A_PAT AND (DataLo=16#60#)) THEN next_state <= STATUS_BPROTECT; ELSIF (A_PAT AND (DataLo=16#58#)) THEN next_state <= PROT_STATUS; ELSIF (A_PAT AND (DataLo=16#78#)) THEN next_state <= PPB_LOCK; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_AS => IF falling_edge(write) THEN IF DataLo=16#00# THEN IF ERS_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 UNLOCK_RESET => IF falling_edge(write) THEN IF (DataLo = 16#00#) THEN next_state <= RESET; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; WHEN STATUS_BPROTECT => IF falling_edge(write) THEN IF (DataLo=16#68# AND AddrPpb=WP) THEN next_state <= PPB_PROGRAM; ELSIF (DataLo=16#60# AND AddrPpb=EP) THEN next_state <= PPB_ERASE; ELSIF (DataLo=16#68# AND (AddrMode=SL)) THEN next_state <= PERSISTANT_MODE_PROGRAM; ELSIF (DataLo=16#68# AND (AddrMode=PL)) THEN next_state <= PASSWORD_MODE_PROGRAM; ELSIF (DataLo=16#68# AND (AddrPpb=OW)) THEN next_state <= OTP_LOCK_PROGRAM; END IF; END IF; WHEN OTP_LOCK_PROGRAM => IF BProt_done = '1' AND falling_edge(write) AND (DataLo=16#48# AND (AddrPpb=OW)) THEN next_state <= OTP_LOCK_VERIFY; END IF; WHEN OTP_LOCK_VERIFY => IF falling_edge(write) THEN IF (DataLo=16#68# AND (AddrPpb=OW)) THEN next_state <= OTP_LOCK_PROGRAM; END IF; END IF; WHEN PERSISTANT_MODE_PROGRAM => IF BProt_done = '1' AND falling_edge(write) AND (DataLo=16#48# AND (AddrMode=SL)) THEN next_state <= PERSISTANT_MODE_VERIFY; END IF; WHEN PERSISTANT_MODE_VERIFY => IF falling_edge(write) THEN IF (DataLo=16#68# AND (AddrMode=SL)) THEN next_state <= PERSISTANT_MODE_PROGRAM; END IF; END IF; WHEN PASSWORD_MODE_PROGRAM => IF BProt_done = '1' AND falling_edge(write) AND (DataLo=16#48# AND (AddrMode=PL)) THEN next_state <= PASSWORD_MODE_VERIFY; END IF; WHEN PASSWORD_MODE_VERIFY => IF falling_edge(write) THEN IF (DataLo=16#68# AND (AddrMode=PL)) THEN next_state <= PASSWORD_MODE_PROGRAM; END IF; END IF; WHEN PPB_PROGRAM => IF BProt_done = '1' AND falling_edge(write) AND (DataLo=16#48# AND AddrPpb=WP) THEN next_state <= PPB_PROGRAM_VERIFY; END IF; WHEN PPB_PROGRAM_VERIFY => IF falling_edge(write) THEN IF (DataLo=16#68# AND AddrPpb=WP) THEN next_state <= PPB_PROGRAM; END IF; END IF; WHEN PPB_ERASE => IF BProt_done = '1' AND falling_edge(write) AND (DataLo=16#40#) THEN next_state <= PPB_ERASE_VERIFY; END IF; WHEN PPB_ERASE_VERIFY => IF falling_edge(write) THEN IF (DataLo=16#60# AND AddrPpb=EP) THEN next_state <= PPB_ERASE; END IF; END IF; WHEN AS => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= RESET; ELSIF ((AddrCFI) AND (DataLo = 16#98#)) THEN next_state <= AS_CFI; END IF; END IF; WHEN AS_CFI => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= AS; END IF; END IF; WHEN CFI => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN IF Ulbypass = '0' THEN next_state <= RESET; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; END IF; WHEN A0SEEN => IF falling_edge(write) THEN IF (BankBypassLock(BA) = '1' AND Ulbypass = '1') OR Ulbypass = '0' THEN next_state <= PGMS; ELSE next_state <= PREL_ULBYPASS; END IF; ELSE next_state <= A0SEEN; END IF; WHEN C8 => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= C8_Z001; ELSE next_state <= RESET; END IF; END IF; WHEN C8_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= C8_PREL; ELSE next_state <= RESET; END IF; END IF; WHEN C8_PREL => IF falling_edge(write) THEN IF A_PAT AND DataLo = 16#10# THEN next_state <= ERS; --chip erase ELSIF DataLo = 16#30# AND Ulbypass='0' THEN next_state <= SERS; ELSE IF Ulbypass = '0' THEN next_state <= RESET; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; END IF; WHEN ERS => IF rising_edge(EDone) THEN IF Ulbypass = '1' THEN next_state <= PREL_ULBYPASS; ELSE next_state <= RESET; END IF; END IF; WHEN SERS => IF (CTMOUT_out = '1') THEN next_state <= SERS_EXEC; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN IF BErase(BA) = '1' AND NOT EErr THEN next_state <= ESP; -- ESP according to datasheet END IF; ELSIF (DataLo = 16#30#) THEN next_state <= SERS; ELSE next_state <= RESET; END IF; END IF; WHEN SERS_EXEC => IF rising_edge(EDone) THEN next_state <= RESET; ELSIF falling_edge(write) AND NOT EErr AND DataLo = 16#B0# AND BErase(BA) = '1' THEN next_state <= ESPS; END IF; WHEN ESPS => IF (ETStart_out = '1') THEN next_state <= ESP; END IF; WHEN ESP => IF falling_edge(write) THEN IF DataLo = 16#30# AND BErase(BA) = '1' THEN next_state <= SERS_EXEC; ELSE IF AddrCFI AND DataLo = 16#98# THEN next_state <= ESP_CFI; ELSIF PATTERN_1 THEN next_state <= ESP_Z001; END IF; END IF; END IF; WHEN ESP_ULBYPASS => IF falling_edge(write) THEN IF DataLo = 16#30# AND BErase(BA) = '1' THEN next_state <= SERS_EXEC; ELSIF AddrCFI AND DataLo = 16#98# THEN next_state <= ESP_CFI; ELSIF (DataLo = 16#A0#) THEN next_state <= ESP_A0SEEN; ELSIF (DataLo = 16#90#) THEN next_state <= ESP_UNLOCK_RESET; END IF; END IF; WHEN ESP_UNLOCK_RESET => IF falling_edge(write) AND (DataLo = 16#00#) THEN next_state <= ESP; END IF; WHEN ESP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= ESP_PREL; ELSE next_state <= ESP; END IF; END IF; WHEN ESP_PREL => IF falling_edge(write) THEN IF (A_PAT AND (DataLo = 16#90#)) THEN next_state <= ESP_AS; ELSIF A_PAT AND DataLo = 16#A0# THEN next_state <= ESP_A0SEEN; ELSIF (A_PAT AND (DataLo = 16#20#)) THEN next_state <= ESP_ULBYPASS; ELSIF (A_PAT AND (DataLo=16#88#)) THEN next_state <= OTP; ELSE next_state <= ESP; END IF; END IF; WHEN ESP_AS => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= ESP; ELSIF ((AddrCFI) AND (DataLo = 16#98#)) THEN next_state <= ESP_AS_CFI; ELSE next_state <= ESP_AS; END IF; END IF; WHEN ESP_CFI => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN IF Ulbypass = '0' THEN next_state <= ESP; ELSE next_state <= ESP_ULBYPASS; END IF; END IF; END IF; WHEN ESP_AS_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= ESP_AS; ELSE next_state <= ESP_AS_CFI; END IF; END IF; WHEN ESP_A0SEEN => IF falling_edge(write) THEN IF (BankBypassLock(BA) = '1' AND Ulbypass = '1') OR Ulbypass = '0' THEN next_state <= PGMS; ELSE next_state <= ESP_ULBYPASS; END IF; END IF; WHEN PGMS => IF rising_edge(PDone) THEN IF OTP_ACT = '1' THEN next_state <= OTP; ELSIF ERS_ACT = '1' THEN IF Ulbypass = '0' THEN next_state <= ESP; ELSE next_state <= ESP_ULBYPASS; END IF; ELSIF Ulbypass = '1' THEN next_state <= PREL_ULBYPASS; ELSE next_state <= RESET; END IF; END IF; WHEN OTHERS => END CASE; CASE current_state IS WHEN PPB_ERASE| PASSWORD_VERIFY| PPB_LOCK | PROT_STATUS| DYB | OTP_LOCK_PROGRAM| PERSISTANT_MODE_PROGRAM| PPB_PROGRAM | STATUS_BPROTECT | OTP_LOCK_VERIFY | PASSWORD_MODE_VERIFY | PPB_PROGRAM_VERIFY | PPB_ERASE_VERIFY | PERSISTANT_MODE_VERIFY => IF falling_edge(write) THEN IF DataLo=16#F0# THEN IF OTP_act = '0' THEN next_state <= RESET; ELSE next_state <= OTP; END IF; END IF; END IF; WHEN OTHERS => END CASE; END IF; END PROCESS StateGen; WP_PROC: PROCESS(reseted, WPNeg, sec_prot) BEGIN IF reseted = '1' THEN S_prot <= SPpb_prot OR SDyb_prot; ST_prot <= STPpb_prot OR STDyb_prot; SB_prot <= SBPpb_prot OR SBDyb_prot; --Hardware Write Protection IF WPNeg = '0' THEN ST_prot(SSecN-1 DOWNTO SSecN-2) <= (OTHERS => '1'); SB_prot(1 DOWNTO 0) <= (OTHERS => '1'); END IF; END IF; END PROCESS WP_PROC; --------------------------------------------------------------------------- --FSM Output generation and general funcionality --------------------------------------------------------------------------- Functional : PROCESS(write, read, oe, Data,Data1, A, Din(31), PDone, EDone, ETStart_out, CTMOUT_out, RST, reseted, Ready_out, gOE_n, gCE_n, current_state, PPrDone, PUDone, BProt_done, WORDNeg) PROCEDURE generate_out IS VARIABLE SecSiAddr : NATURAL ; BEGIN IF BSecSi(BA) = '1' THEN SecSiAddr := Address MOD 16#100#; IF SecSiAddr < 16#04# AND SA = 0 AND PasMLock = '1' THEN Dout_zd <= (OTHERS => '1');--returns all Fh ELSIF ( SecSiAddr < SecSiSize AND SA = 0 ) THEN IF SecSi( SecSiAddr) >-1 THEN DOut_zd(15 downto 0) <= to_slv(SecSi( SecSiAddr),16); IF ( WORDNeg = '1' ) THEN DOut_zd(31 downto 16) <= to_slv(SecSi( SecSiAddr+1),16); END IF; ELSE DOut_zd(15 downto 0) <= (OTHERS=>'X'); IF ( WORDNeg = '1' ) THEN DOut_zd(31 downto 16) <= (OTHERS=>'X'); END IF; END IF; ELSE REPORT "Invalid SecSi Address" severity WARNING; END IF; ELSE IF Mem(SA)(Address) = -1 THEN DOut_zd(15 downto 0) <= (OTHERS => 'X'); ELSE DOut_zd(15 downto 0) <= to_slv(Mem(SA)(Address),16); END IF; IF WORDNeg = '1' THEN IF Mem(SA)(Address+1) = -1 THEN DOut_zd(31 downto 16) <= (OTHERS => 'X'); ELSE DOut_zd(31 downto 16) <= to_slv(Mem(SA)(Address+1),16); END IF; END IF; END IF; END PROCEDURE generate_out; -- PROCEDURE FOR READ AUTOSELECT SECTOR PROCEDURE Read_AS IS VARIABLE AS_Addr : NATURAL; BEGIN AS_addr := to_nat(ALatch) MOD 16#100#; IF (AS_addr = 1 OR AS_addr = 16#0E# OR AS_addr = 16#0F#) THEN IF WORDNeg = '1' THEN DOut_zd(31 downto 8) <= to_slv(16#222222#,24); ELSE DOut_zd(31 downto 16) <= (OTHERS =>'Z'); DOut_zd(15 downto 8) <= to_slv(16#0022#,8); END IF; ELSIF (AS_addr = 0 OR AS_addr = 2 OR AS_addr = 3) THEN IF WORDNeg = '1' THEN DOut_zd(31 downto 8) <= (OTHERS =>'0'); ELSE DOut_zd(31 downto 16) <= (OTHERS =>'Z'); DOut_zd(15 downto 8) <= to_slv(16#00#,8); END IF; END IF; --lower bytes IF AS_addr = 0 THEN DOut_zd(7 downto 0) <= to_slv(1,8); ELSIF AS_addr = 1 THEN DOut_zd(7 downto 0) <= to_slv(16#7E#,8); ELSIF AS_addr = 2 THEN IF (((SA /= TopSec) AND (SA /= BotSec) AND(S_prot(SA)='0')) OR ((SA = TopSec) AND (ST_prot(SubSA) = '0')) OR ((SA = BotSec) AND (SB_prot(SubSA) = '0'))) THEN DOut_zd(7 downto 0) <= to_slv(16#00#,8); ELSE DOut_zd(7 downto 0) <= to_slv(16#01#,8); END IF; ELSIF AS_addr = 3 THEN IF FactoryLock = '1' THEN DOut_zd(7 downto 0) <= to_slv(16#80#,8); ELSE DOut_zd(7 downto 0) <= to_slv(16#00#,8); END IF; ELSIF AS_addr = 16#0E# THEN DOut_zd(7 downto 0) <= to_slv(16#0D#,8); ELSIF AS_addr = 16#0F# THEN DOut_zd(7 downto 0) <= to_slv(16#00#,8); ELSE DOut_zd(15 downto 0) <= (OTHERS =>'Z'); IF WORDNeg ='1' THEN DOut_zd(31 downto 16) <= (OTHERS =>'Z'); END IF; END IF; END PROCEDURE Read_AS; -- procedure read from memory when erase embaded algoritam is suspend PROCEDURE Readmem_ErasESuspend( VARIABLE Status : INOUT std_logic_vector(7 DOWNTO 0)) IS VARIABLE rd_nosusp : BOOLEAN := TRUE; BEGIN rd_nosusp := TRUE; IF (SA /= TopSec AND SA /= BotSec AND Ers_Queue(SA) = '1' AND S_prot(SA) = '0') OR (SA = TopSec AND ET_queue(SubSA)= '1' AND ST_prot(SubSA)= '0') OR (SA = BotSec AND EB_queue(SubSA)= '1' AND SB_prot(SubSA)='0') THEN rd_nosusp := FALSE; END IF; IF rd_nosusp = TRUE THEN generate_out ; ELSE ----------------------------------------------------------- --read status / erase suspend timeout - stil erasing ----------------------------------------------------------- Status(7) := '1'; -- Status(6) No toggle Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; END IF; END PROCEDURE Readmem_ErasESuspend; PROCEDURE Read_EraseStatus ( VARIABLE Status : INOUT std_logic_vector(7 DOWNTO 0)) IS BEGIN Status(7) := '0'; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; IF NOW - ERASE_START > 100 us THEN IF (SA /= TopSec AND SA /= BotSec AND Ers_Queue(SA) = '1' AND S_prot(SA) = '0') OR (SA=TopSec AND ET_queue(SubSA)='1' AND ST_prot(SubSA)='0') OR (SA=BotSec AND EB_queue(SubSA)='1' AND SB_prot(SubSA)='0') THEN Status(2) := NOT Status(2); --toggle END IF; ELSE IF (SA /= TopSec AND SA /= BotSec AND Ers_Queue(SA) = '1') OR (SA = TopSec AND ET_queue(SubSA) = '1') OR (SA = BotSec AND EB_queue(SubSA) = '1') THEN Status(2) := NOT Status(2); --toggle END IF; END IF; END PROCEDURE Read_EraseStatus; PROCEDURE bit_status ( VARIABLE Status :INOUT std_logic_vector(7 DOWNTO 0)) IS BEGIN IF BProt_done = '0' THEN Status(6) := NOT Status(6); --toggle END IF; --toggle DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; END PROCEDURE bit_status; PROCEDURE EraseMem ( VARIABLE ErsMem : INTEGER) IS VARIABLE i : INTEGER := 0; VARIABLE y : INTEGER := 0; BEGIN FOR i IN 0 TO SecN -1 LOOP IF i = TopSec THEN FOR y IN 0 TO SSecN -1 LOOP IF ST_prot(y) = '0' AND ET_queue(y) = '1' THEN Mem(i)(sssa(y) TO ssea(y)) := (OTHERS=>ErsMem); ers_cnt := ers_cnt + 1; END IF; END LOOP; ELSIF i = BotSec THEN FOR y IN 0 TO SSecN -1 LOOP IF SB_prot(y) = '0' AND EB_queue(y) = '1' THEN Mem(i)(sssa(y) TO ssea(y)) := (OTHERS=>ErsMem); ers_cnt := ers_cnt + 1; END IF; END LOOP; ELSE IF S_prot(i) = '0' AND Ers_Queue(i) = '1' THEN Mem(i) := (OTHERS => ErsMem); ers_cnt := ers_cnt + 1; END IF; END IF; END LOOP; END PROCEDURE EraseMem; PROCEDURE SetErsQ IS BEGIN IF (SA = TopSec) THEN ET_queue(SubSA) := '1'; ELSIF (SA = BotSec) THEN EB_queue(SubSA) := '1'; ELSE Ers_Queue(SA) := '1'; END IF; BErase(BA)<= '1'; IF (SA /= TopSec AND SA /= BotSec) AND S_prot(SA) = '0' THEN BErase_t(BA) := '1'; EErr := FALSE; ELSIF (SA = TopSec) AND ST_prot(SubSA) = '0' THEN BErase_t(BA) := '1'; EErr := FALSE; ELSIF (SA = BotSec) AND SB_prot(SubSA) = '0' THEN BErase_t(BA) := '1'; EErr := FALSE; END IF; END PROCEDURE SetErsQ; PROCEDURE SetB_ers IS BEGIN FOR i IN 0 TO BankN -1 LOOP IF BErase_t(i) = '0' AND BErase(i) = '1' THEN BErase(i) <= '0' AFTER 100 us; END IF; END LOOP; END PROCEDURE SetB_ers; --Common Flash Interface Query codes TYPE CFItype IS ARRAY (16#10# TO 16#5B#)OF INTEGER RANGE -1 TO 16#FF#; VARIABLE CFI_array : CFItype := (OTHERS => -1); --Program TYPE WDataType IS ARRAY ( 0 TO 1) OF INTEGER RANGE -1 TO MaxData; TYPE WAddrType IS ARRAY ( 0 TO 1) OF INTEGER RANGE -1 TO SecSize;--n VARIABLE WRData : WDataType:=(OTHERS=>0);--n VARIABLE WRA : WAddrType:=(OTHERS=>-1);--n VARIABLE A_PAT : BOOLEAN := FALSE; -- VARIABLE oe : BOOLEAN := FALSE; VARIABLE rd_nosusp : BOOLEAN := FALSE; VARIABLE DybData : INTEGER; VARIABLE PpbBL : NATURAL; VARIABLE PpbBH : NATURAL; VARIABLE WRSA : NATURAL := 0; VARIABLE PassA : NATURAL := 0; VARIABLE ErsMem : INTEGER := 0; VARIABLE wr_cnt : NATURAL RANGE 0 TO 31; VARIABLE old_bit : std_logic_vector(15 downto 0); VARIABLE new_bit : std_logic_vector(15 downto 0); VARIABLE old_int : INTEGER RANGE -1 to MaxData; VARIABLE new_int : INTEGER RANGE -1 to MaxData; VARIABLE temp : std_logic_vector( 7 DOWNTO 0); VARIABLE PassD : std_logic_vector(31 DOWNTO 0); VARIABLE Status : std_logic_vector( 7 DOWNTO 0) := (OTHERS => '0'); VARIABLE All_ones : std_logic_vector(SecN-3 DOWNTO 0) := (OTHERS => '1'); BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- IF falling_edge(write) THEN A_PAT := (AddrFsm = 16#555# AND BankBypassLock(BA) = '0') OR BankBypassLock(BA) = '1'; END IF; oe<=rising_edge(read) OR (read = '1' AND (WORDNeg'EVENT OR A'EVENT OR (Din(31)'EVENT AND WORDNeg = '0' ))); IF reseted = '1' THEN RY_zd <= '1'; CASE current_state IS WHEN RESET => Ulbypass <= '0'; BErase <= (OTHERS => '0'); BErase_t := (OTHERS => '0'); BankBypassLock := (OTHERS => '0'); BankAutoSel := (OTHERS => '0'); BSecSi := (OTHERS => '0'); BBusy := (OTHERS => '0'); Ers_Queue := (OTHERS => '0'); ET_queue := (OTHERS => '0'); EB_queue := (OTHERS => '0'); EErr := TRUE; PErr := TRUE; PassProg := FALSE; BProt_done <= '1'; ERS_ACT <= '0'; PGMS_ACT <= '0'; CTMOUT_in <= '0'; OTP_ACT <= '0'; IF falling_edge(write) THEN NULL; ELSIF oe THEN generate_out; END IF; WHEN OTP => Ulbypass <= '0'; BankBypassLock := (OTHERS => '0'); BankAutoSel := (OTHERS => '0'); BBusy := (OTHERS => '0'); PGMS_ACT <= '0'; OTP_ACT <= '1'; IF oe THEN generate_out; END IF; --ready signal active WHEN OTP_Z001 => NULL; WHEN OTP_PREL => NULL; WHEN OTP_AS => IF DataLo=16#00# AND falling_edge(write) THEN BSecSi := (OTHERS => '0'); OTP_ACT <= '0'; END IF; WHEN Z001 => NULL; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT AND (DataLo = 16#20#)) THEN BankBypassLock(BA) := '1'; ELSIF (A_PAT AND (DataLo=16#38#)) THEN PassProg := TRUE; ELSIF (A_PAT AND (DataLo = 16#90#)) THEN --autoselect mode BankAutoSel(BA) := '1'; ELSIF (A_PAT AND (DataLo=16#88#)) THEN BSecSi(BA) := '1'; END IF; END IF; WHEN PASSWORD_UNLOCK_SET => IF falling_edge(write) THEN PUDone <= '0', '1' AFTER tdevice_UNLOCK - glitch_t; PassA := A_passw; PassD(15 downto 0) := Data; IF WORDNeg = '1' THEN PassD(31 downto 16):= Data1; END IF; Status(7) := Data(7); END IF; WHEN PASSWORD_UNLOCK => IF oe THEN Status(5) := '0'; Status(6) := NOT Status(6); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; DOut_zd(15 DOWNTO 8) <= (OTHERS => '0'); DOut_zd(7 DOWNTO 0) <= Status; END IF; IF (rising_edge(PUDone)) THEN IF WORDNeg = '1' THEN IF Secsi(PassA) = to_nat(PassD(15 downto 0)) AND Secsi(PassA+1) = to_nat(PassD(31 downto 16)) AND PasUnCycle = 0 AND PassA = 0 THEN PasUnCycle := 1; ELSIF PasUnCycle = 1 AND PassA = 2 AND Secsi(PassA) = to_nat(PassD(15 downto 0)) AND Secsi(PassA+1) = to_nat(PassD(31 downto 16)) THEN PasUnCycle := 0; Ppb_lock_b := NOT PasMLock AND Ppb_lock_b; ELSE PasUnCycle := 0; END IF; ELSE IF Secsi(PassA) = to_nat(PassD(15 downto 0)) AND PasUnCycle = 0 AND PassA = 0 THEN PasUnCycle := 1; ELSIF PasUnCycle = 1 AND PassA = 1 AND Secsi(PassA) = to_nat(PassD(15 downto 0)) THEN PasUnCycle := 2; ELSIF Secsi(PassA) = to_nat(PassD(15 downto 0)) AND PasUnCycle = 2 AND PassA = 2 THEN PasUnCycle := 3; ELSIF PasUnCycle = 3 AND PassA = 3 AND Secsi(PassA) = to_nat(PassD(15 downto 0)) THEN PasUnCycle := 0; Ppb_lock_b := NOT PasMLock AND Ppb_lock_b; ELSE PasUnCycle := 0; END IF; END IF; END IF; RY_zd <= '0'; WHEN PASSWORD_VERIFY => IF oe THEN IF PasMLock = '1' THEN Dout_zd <= (OTHERS => '1'); ELSE --at SecSi address PassA := A_passw; Dout_zd(15 downto 0) <= to_slv(Secsi(PassA),16); IF WORDNeg = '1' THEN Dout_zd(31 downto 16) <= to_slv(Secsi(PassA+1),16); END IF; END IF; END IF; WHEN DYB => IF falling_edge(write) AND DataLo /= 16#F0# THEN DybData := DataLo MOD 16; IF (DybData= 0 ) THEN DybProt := '0'; END IF; IF (DybData = 1) THEN DybProt := '1'; END IF; IF (SA /= BotSec) AND (SA /= TopSec) AND (DybData = 0 OR DybData=1) THEN SDyb_prot(SA) := DybProt; ELSIF SA = BotSec THEN SBDyb_prot(SubSA) := DybProt; ELSE STDyb_prot(SubSA) := DybProt; END IF; sec_prot <= '1', '0' AFTER 1 ns; END IF; WHEN PPB_LOCK => IF PasMLock = '0' THEN Ppb_lock_b := '1'; END IF; WHEN STATUS_BPROTECT => IF falling_edge(write) THEN IF (DataLo=16#68# AND AddrPpb=WP) THEN BProt_done <= '0', '1' AFTER tdevice_PPBW - glitch_t; SaPPB := SA; SSaPPB := SubSA; ELSIF (DataLo=16#60# AND AddrPpb=EP) THEN BProt_done <= '0', '1' AFTER tdevice_PPBE - glitch_t; ELSIF (DataLo=16#68# AND (AddrMode=SL)) THEN BProt_done <= '0', '1' AFTER tdevice_PPBW - glitch_t; ELSIF (DataLo=16#68# AND ( AddrMode=PL)) THEN BProt_done <= '0', '1' AFTER tdevice_PPBW - glitch_t; ELSIF (DataLo=16#68# AND (AddrPpb=OW)) THEN BProt_done <= '0', '1' AFTER tdevice_PPBW - glitch_t; END IF; END IF; IF oe THEN DOut_zd(15 DOWNTO 1) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; IF AddrMode=OW THEN DOut_zd(0) <= Otp_Lock; END IF; IF AddrMode=SL THEN DOut_zd(0) <= PerMLock; END IF; IF AddrMode=PL THEN DOut_zd(0) <= PasMLock; END IF; END IF; WHEN OTP_LOCK_PROGRAM => IF BProt_done = '0' THEN RY_zd <= '0'; END IF; IF rising_edge(BProt_done) THEN OTP_lock := '1'; END IF; IF oe THEN bit_status(Status); END IF; WHEN PERSISTANT_MODE_PROGRAM => IF BProt_done = '0' THEN RY_zd <= '0'; END IF; IF rising_edge(BProt_done) THEN PerMLock := NOT PasMLock; END IF; IF oe THEN bit_status(Status); END IF; WHEN PASSWORD_MODE_PROGRAM => IF BProt_done = '0' THEN RY_zd <= '0'; END IF; IF rising_edge(BProt_done) THEN PasMLock := NOT PerMLock; END IF; IF oe THEN bit_status(Status); END IF; WHEN PPB_PROGRAM => IF BProt_done = '0' THEN RY_zd <= '0'; END IF; IF rising_edge(BProt_done) AND Ppb_lock_b = '0' THEN PpbBL := (SaPPB / 4)*4;--sector group(PpbBH-PpbBL) PpbBH := (SaPPB / 4)*4 + 3; IF ((SaPPB - BotSec) > 0 AND(SaPPB - BotSec) < 4) THEN SPpb_prot(BotSec+3 DOWNTO BotSec+1) := "111"; ELSIF ((TopSec - SaPPB) > 0 AND (TopSec - SaPPB) <4 ) THEN SPpb_prot(TopSec-1 DOWNTO TopSec-3) := "111"; ELSIF (SaPPB /= BotSec) AND (SaPPB /= TopSec) THEN SPpb_prot(PpbBH DOWNTO PpbBL) := (OTHERS => '1'); ELSIF SaPPB = BotSec THEN SBPpb_prot(SSaPPB) := '1'; ELSE STPpb_prot(SSaPPB) := '1'; END IF; sec_prot <= '1', '0' AFTER 1 ns; END IF; IF oe THEN bit_status(Status); END IF; WHEN PPB_ERASE => IF BProt_done = '0' THEN RY_zd <= '0'; END IF; IF rising_edge(BProt_done) AND Ppb_lock_b = '0' THEN SPpb_prot := (OTHERS => '0'); SBPpb_prot := (OTHERS => '0'); STPpb_prot := (OTHERS => '0'); sec_prot <= '1', '0' AFTER 1 ns; END IF; IF oe THEN bit_status(Status); END IF; WHEN PPB_PROGRAM_VERIFY => IF oe AND (AddrPpb=WP) THEN DOut_zd(15 DOWNTO 1) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; IF (((SaPPB /= BotSec) AND (SaPPB /= TopSec) AND (SPpb_prot(SaPPB) = '0')) OR ((SaPPB = BotSec) AND (SBPpb_prot(SSaPPB) = '0')) OR ((SaPPB = TopSec) AND (STPpb_prot(SSaPPB) = '0'))) THEN -- sector unlock DOut_zd(0) <= '0'; ELSE -- sector lock DOut_zd(0) <= '1'; END IF; END IF; IF falling_edge(write) THEN IF (DataLo=16#68# AND AddrPpb=WP) THEN SaPPB := SA; SSaPPB := SubSA; BProt_done <= '0', '1' AFTER tdevice_PPBW - glitch_t; END IF; END IF; WHEN OTP_LOCK_VERIFY => IF oe AND (AddrPpb=OW)THEN DOut_zd(15 DOWNTO 1) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; DOut_zd(0) <= OTP_lock; END IF; IF falling_edge(write) THEN IF (DataLo=16#68# AND AddrPpb=OW) THEN BProt_done <= '0', '1' AFTER tdevice_PPBW - glitch_t; END IF; END IF; WHEN PERSISTANT_MODE_VERIFY => IF oe AND (AddrPpb=SL)THEN DOut_zd(15 DOWNTO 1) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; DOut_zd(0) <= PerMLock; END IF; IF falling_edge(write) THEN IF (DataLo=16#68# AND AddrMode=SL) THEN BProt_done <= '0', '1' AFTER tdevice_PPBW - glitch_t; END IF; END IF; WHEN PASSWORD_MODE_VERIFY => IF oe AND (AddrMode=PL)THEN DOut_zd(15 DOWNTO 1) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; DOut_zd(0) <= PasMLock; END IF; IF falling_edge(write) THEN IF (DataLo=16#68# AND AddrMode=PL) THEN BProt_done <= '0', '1' AFTER tdevice_PPBW - glitch_t; END IF; END IF; WHEN PPB_ERASE_VERIFY => IF oe AND (AddrPpb=WP) THEN DOut_zd(15 DOWNTO 1) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; IF to_nat(STPpb_prot) = 0 AND to_nat(SBPpb_prot) = 0 AND to_nat(SPpb_prot) = 0 THEN -- unlock DOut_zd(0) <= '0'; ELSE -- sector lock DOut_zd(0) <= '1'; END IF; END IF; IF falling_edge(write) THEN IF (DataLo=16#60# AND AddrPpb=EP) THEN BProt_done <= '0', '1' AFTER tdevice_PPBE - glitch_t; END IF; END IF; WHEN PROT_STATUS => IF oe THEN DOut_zd(15 DOWNTO 1) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; IF ( (SA/=BotSec AND SA/=TopSec AND S_prot(SA) = '0') OR (SA=BotSec AND SB_prot(SubSA)='0') OR (SA = TopSec AND ST_prot(SubSA) = '0')) THEN -- sector unlock DOut_zd(0) <= '0'; DOut_zd(1) <= Ppb_lock_b; ELSE -- sector lock DOut_zd(0) <= '1'; DOut_zd(1) <= Ppb_lock_b; END IF; END IF; WHEN AS => IF oe THEN IF BankAutoSel(BA) = '1' THEN Read_AS; ELSE generate_out; END IF; END IF; IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN --remove autoselect mode bank BankAutoSel := (OTHERS => '0'); END IF; END IF; WHEN PREL_ULBYPASS => Ulbypass <= '1'; IF oe THEN IF BankBypassLock(BA) = '1' THEN Dout_zd <= (OTHERS => 'Z') ; ELSE generate_out; END IF; END IF; WHEN UNLOCK_RESET | ESP_UNLOCK_RESET => IF falling_edge(write) THEN IF (DataLo = 16#00#) THEN BankBypassLock := (OTHERS => '0'); Ulbypass <= '0'; END IF; END IF; WHEN CFI | AS_CFI | ESP_CFI | ESP_AS_CFI => IF oe THEN DOut_zd(31 DOWNTO 0) <= (OTHERS => '0'); IF ((AddrFsm >= 16#10#) AND (AddrFsm <= 16#3C#)) OR ((AddrFsm >= 16#40#) AND(AddrFsm <= 16#5B#)) THEN IF (CFI_array(AddrFsm) /= -1) THEN DOut_zd(7 DOWNTO 0) <= to_slv(CFI_array(AddrFsm),8); ELSE DOut_zd <= (OTHERS =>'Z'); END IF; ELSE ASSERT FALSE REPORT "Invalid CFI query address" SEVERITY warning; DOut_zd <= (OTHERS =>'Z'); END IF; END IF; WHEN OTP_A0SEEN => IF falling_edge(write) THEN IF SA = 0 AND OTP_lock = '0' AND ((Address > 16#03# AND (Address <= SecSiSize )) OR (PasMLock = '0' AND Address < 16#04#)) THEN IF NOT PassProg THEN WRA(0) := Address; ELSE WRA(0) := A_passw;--pass. prog END IF; WRData(0) := -1; WRData(1) := -1; IF Viol = '0' THEN WRData(0) := to_nat(Data); WRData(1) := to_nat(Data1); END IF; WRA(1) := -1; IF WORDNeg = '1' THEN WRA(1) := WRA(0) + 1; END IF; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); BBusy := (OTHERS => '1'); PErr := FALSE; PStart <= '1', '0' AFTER 1 ns; ELSE temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); BBusy := (OTHERS => '1'); PErr := TRUE; PStart <= '1', '0' AFTER 1 ns; END IF; END IF; WHEN A0SEEN | ESP_A0SEEN => IF falling_edge(write) THEN IF (BankBypassLock(BA) = '1' AND Ulbypass = '1') OR Ulbypass = '0' THEN IF (SA /= TopSec AND SA /= BotSec AND Ers_Queue(SA)='0' AND S_prot(SA) = '0') OR (SA = TopSec AND ET_queue(SubSA) = '0' AND ST_prot(SubSA) = '0') OR(SA = BotSec AND EB_queue(SubSA) = '0' AND SB_prot(SubSA) = '0') THEN WRSA := SA; WRA(0) := Address; WRA(1) := Address+1; WRData(0) := -1; WRData(1) := -1; IF Viol = '0' THEN WRData(0) := to_nat(Data); WRData(1) := to_nat(Data1); END IF; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); BBusy := (OTHERS => '0'); BBusy(BA) := '1'; PErr := FALSE; PStart <= '1', '0' AFTER 1 ns; ELSE temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); BBusy := (OTHERS => '0'); BBusy(BA) := '1'; PErr := TRUE; PStart <= '1', '0' AFTER 1 ns; END IF; END IF; END IF; WHEN PGMS => RY_zd <= '0'; PGMS_ACT <= '1'; IF oe THEN IF BBusy(BA) = '1' THEN ---------------------------------------------------------- --read status ---------------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; --Status(2) no toggle Status(1) := '0'; DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; ELSE -- read from non program bank!!!!!!!!!!!!!!!!! Readmem_ErasESuspend(Status); END IF; END IF; IF NOT PErr THEN PGMS_ACT <= '0'; wr_cnt := 0; IF WORDNeg ='1' THEN wr_cnt := 1; END IF; FOR i IN wr_cnt downto 0 LOOP new_int:= WRData(i); IF WRA(i) < 0 THEN old_int := -1; ELSIF (OTP_ACT = '1' OR PAssProg) THEN old_int:=SecSi(WRA(i)); ELSE old_int:=Mem(WRSA)(WRA(i)); END IF; WRData(i):= -1; IF new_int>-1 THEN new_bit:=to_slv(new_int,16); IF old_int>-1 THEN old_bit:=to_slv(old_int,16); FOR j IN 0 TO 15 LOOP IF old_bit(j) = '0' THEN new_bit(j):='0'; END IF; END LOOP; new_int:=to_nat(new_bit); END IF; WRData(i):= new_int; END IF; END LOOP; FOR i IN wr_cnt downto 0 LOOP IF ( OTP_ACT = '1' OR PassProg) THEN SecSi(WRA(i)) := -1; ELSE Mem(WRSA)(WRA(i)) := -1; END IF; END LOOP; IF PDone = '1' AND NOT PErr THEN FOR i IN wr_cnt downto 0 LOOP IF( OTP_ACT = '1' OR PassProg) THEN --mem write SecSi(WRA(i)) := WRData(i); ELSE Mem(WRSA)(WRA(i)) := WRData(i); END IF; WRData(i):= -1; END LOOP; PassProg := FALSE; END IF; END IF; IF rising_edge(PDone) THEN BBusy := (OTHERS => '0'); END IF; WHEN C8 | C8_Z001 => IF falling_edge(write) THEN null; END IF; WHEN C8_PREL => IF falling_edge(write) THEN IF DataLo = 16#10# THEN ers_cnt := 0; EStart <= '1', '0' AFTER 1 ns; ESusp <= '0'; ERes <= '0'; Ers_Queue := (OTHERS => '1'); ET_queue := (OTHERS => '1'); EB_queue := (OTHERS => '1'); BErase <= (OTHERS => '1'); IF (S_prot(SecN-2 DOWNTO 1) = All_ones) AND (SB_prot = X"FF") AND (ST_prot = X"FF") THEN EErr := TRUE; ELSE EErr := FALSE; END IF; ERS_ACT <= '1'; ERASE_START := NOW; ErsMem := -1; EraseMem(ErsMem); ELSIF Ulbypass='0' AND DataLo = 16#30# THEN --put selected sector to sec. ers. queue --start timeout EErr := TRUE; ers_cnt := 0; Status := "00001000"; SetErsQ; CTMOUT_in <= '1'; ERS_ACT <= '1'; END IF; END IF; WHEN ERS => RY_zd <= '0'; IF oe THEN Read_EraseStatus(Status); DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; END IF; IF rising_edge(EDone) THEN IF NOT EErr THEN ErsMem := MaxData; EraseMem(ErsMem); END IF; END IF; WHEN SERS => IF (CTMOUT_out = '1') THEN CTMOUT_in <= '0'; ETStart_in <= '0'; EStart <= '1', '0' AFTER 1 ns; ESusp <= '0'; ERes <= '0'; SetB_ers; ErsMem := -1; EraseMem(ErsMem); ERASE_START := NOW; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0# AND NOT EErr AND BErase(BA) = '1') THEN --need to start erase process prior to suspend ErsMem := -1; EraseMem(ErsMem); ERASE_START := NOW; SetB_ers; EStart_susp <= '1', '0' AFTER 1 ns; CTMOUT_in <= '0'; ERes <= '0'; ELSIF (DataLo = 16#30#) THEN CTMOUT_in <= '0', '1' AFTER 1 ns; SetErsQ; ELSE CTMOUT_in <= '0'; END IF; ELSIF oe THEN IF BErase(BA) = '1' THEN ------------------------------------------------------- --read status - sector erase timeout ------------------------------------------------------- Status(3) := '0'; DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; ELSE generate_out ; END IF; END IF; WHEN ESPS => RY_zd <= '0'; IF (ETStart_out = '1') THEN ETStart_in <= '0'; ELSIF oe THEN IF BErase(BA) = '1' THEN ------------------------------------------------------ --read status / erase suspend timeout - stil erasing ------------------------------------------------------ Read_EraseStatus(Status); DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; ELSE generate_out; END IF; END IF; WHEN SERS_EXEC => RY_zd <= '0'; IF oe THEN IF BErase(BA) = '1' THEN ----------------------------------------------------------- --read status Erase Busy ----------------------------------------------------------- Read_EraseStatus(Status); DOut_zd(7 DOWNTO 0) <= Status; DOut_zd(15 DOWNTO 8) <= (OTHERS => '0'); IF WORDNeg = '1' THEN DOut_zd(31 DOWNTO 16) <= (OTHERS => '0'); END IF; ELSE generate_out; END IF; END IF; IF rising_edge(EDone) AND NOT EErr THEN ErsMem := MaxData; EraseMem(ErsMem); END IF; IF falling_edge(write) AND NOT EErr THEN IF DataLo = 16#B0# AND BErase(BA) = '1' THEN ETStart_in <= '1'; ESusp <= '1', '0' AFTER 1 ns; END IF; END IF; WHEN ESP => OTP_ACT <= '0'; BSecSi := (OTHERS => '0'); IF falling_edge(write) THEN IF DataLo = 16#30# AND BErase(BA) = '1' THEN ERes <= '1', '0' AFTER 1 ns; END IF; ELSIF oe THEN ----------------------------------------------------------- --read memory ----------------------------------------------------------- Readmem_ErasESuspend(Status); END IF; WHEN ESP_Z001 => null; WHEN ESP_PREL => IF falling_edge(write) THEN IF (A_PAT AND (DataLo = 16#20#)) THEN BankBypassLock(BA) := '1'; ELSIF (A_PAT AND (DataLo = 16#90#)) THEN --autoselect mode BankAutoSel(BA) := '1'; ELSIF (A_PAT AND (DataLo=16#88#)) THEN BSecSi(BA) := '1'; END IF; END IF; WHEN ESP_ULBYPASS =>--SecAddr=TopSec/SecAddr=BotSec!! Ulbypass <= '1'; IF falling_edge(write) THEN IF DataLo = 16#30# AND BErase(BA) = '1' THEN ERes <= '1', '0' AFTER 1 ns; END IF; ELSIF oe THEN ----------------------------------------------------------- --read memory ----------------------------------------------------------- Readmem_ErasESuspend(Status); END IF; WHEN ESP_AS => IF oe THEN IF BankAutoSel(BA) = '1' THEN Read_AS; ELSE ----------------------------------------------------------- --read memory ----------------------------------------------------------- Readmem_ErasESuspend(Status); END IF; END IF; IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN --remove autoselect mode bank BankAutoSel := (OTHERS => '0'); END IF; END IF; END CASE; ELSE SBDyb_prot := (OTHERS => '0'); STDyb_prot := (OTHERS => '0'); SDyb_prot := (OTHERS => '0'); sec_prot <= '1', '0' AFTER 1 ns; Ppb_lock_b := PasMLock; PasUnCycle := 0; PassProg := FALSE; 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(31 downto 16) <= (OTHERS =>'Z'); END IF; END IF; IF NOW = 0 ns THEN ------------------------------------------------------------------- --CFI array data ------------------------------------------------------------------- --CFI query identification string CFI_array(16#10#) := 16#51#; CFI_array(16#11#) := 16#52#; CFI_array(16#12#) := 16#59#; CFI_array(16#13#) := 16#02#; CFI_array(16#14#) := 16#00#; CFI_array(16#15#) := 16#40#; CFI_array(16#16#) := 16#00#; CFI_array(16#17#) := 16#00#; CFI_array(16#18#) := 16#00#; CFI_array(16#19#) := 16#00#; CFI_array(16#1A#) := 16#00#; --system interface string CFI_array(16#1B#) := 16#27#; CFI_array(16#1C#) := 16#31#; CFI_array(16#1D#) := 16#00#; CFI_array(16#1E#) := 16#00#; CFI_array(16#1F#) := 16#04#; CFI_array(16#20#) := 16#00#; CFI_array(16#21#) := 16#09#; CFI_array(16#22#) := 16#00#; CFI_array(16#23#) := 16#05#; CFI_array(16#24#) := 16#00#; CFI_array(16#25#) := 16#04#; CFI_array(16#26#) := 16#00#; --device geometry definition CFI_array(16#27#) := 16#18#; CFI_array(16#28#) := 16#05#; CFI_array(16#29#) := 16#00#; CFI_array(16#2A#) := 16#00#; CFI_array(16#2B#) := 16#00#; CFI_array(16#2C#) := 16#03#; CFI_array(16#2D#) := 16#07#; CFI_array(16#2E#) := 16#00#; CFI_array(16#2F#) := 16#20#; CFI_array(16#30#) := 16#00#; CFI_array(16#31#) := 16#FD#; CFI_array(16#32#) := 16#00#; CFI_array(16#33#) := 16#00#; CFI_array(16#34#) := 16#01#; CFI_array(16#35#) := 16#07#; CFI_array(16#36#) := 16#00#; CFI_array(16#37#) := 16#20#; CFI_array(16#38#) := 16#00#; CFI_array(16#39#) := 16#00#; CFI_array(16#3A#) := 16#00#; CFI_array(16#3B#) := 16#00#; CFI_array(16#3C#) := 16#00#; --primary vendor-specific extended query CFI_array(16#40#) := 16#50#; CFI_array(16#41#) := 16#52#; CFI_array(16#42#) := 16#49#; CFI_array(16#43#) := 16#31#; CFI_array(16#44#) := 16#33#; CFI_array(16#45#) := 16#04#; CFI_array(16#46#) := 16#02#; CFI_array(16#47#) := 16#01#; CFI_array(16#48#) := 16#01#; CFI_array(16#49#) := 16#07#; CFI_array(16#4A#) := 16#E7#; CFI_array(16#4B#) := 16#00#; CFI_array(16#4C#) := 16#02#; CFI_array(16#4D#) := 16#B5#; CFI_array(16#4E#) := 16#05#; CFI_array(16#4F#) := 16#01#; CFI_array(16#50#) := 16#00#; CFI_array(16#57#) := 16#04#; CFI_array(16#58#) := 16#27#; CFI_array(16#59#) := 16#60#; CFI_array(16#5A#) := 16#60#; CFI_array(16#5B#) := 16#27#; END IF; END PROCESS Functional; --------------------------------------------------------------------------- ---- File read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_f : text is mem_file_name; FILE secsi_f : text is secsi_file_name; FILE prot_f : text is prot_file_name; VARIABLE addr_ind : NATURAL; VARIABLE sec_ind : NATURAL; VARIABLE offset : NATURAL; VARIABLE ind : NATURAL; VARIABLE buf : line; VARIABLE sect : NATURAL; CONSTANT SecGroupNumb : NATURAL := 79; VARIABLE PPB : std_logic_vector(SecN + 2*SSecN-3 downto 0) :=(OTHERS=>'0'); VARIABLE line : NATURAL :=0; VARIABLE report_err : BOOLEAN := FALSE; BEGIN ----------------------------------------------------------------------- --am29pdl128g memory word preload file format ----------------------------------------------------------------------- -- / - comment -- @aaaaaa - stands for address -- dddd - is word to be written at Mem(aaaaaa++) -- (aaaaaa is incremented at every load) -- only first 1-7 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! ----------------------------------------------------------------------- IF UserPreload AND (mem_file_name /= "none" ) THEN Mem := (OTHERS => (OTHERS => MaxData)); addr_ind := 0; WHILE (not ENDFILE (mem_f)) LOOP READLINE (mem_f, buf); line := line +1; IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN addr_ind := h(buf(2 to 7)); sec_ind := addr_ind / SecSize; offset := addr_ind - (sec_ind * SecSize); ELSE IF addr_ind <= SecSize * SecN - 1 THEN Mem(sec_ind)(offset):= h(buf(1 to 4)); addr_ind := (addr_ind + 1); sec_ind := addr_ind / SecSize; offset := addr_ind - (sec_ind * SecSize); ELSE IF report_err = FALSE THEN REPORT "Memory file:" & mem_file_name & " Address range overflow" SEVERITY warning; report_err := TRUE; END IF; END IF; END IF; END LOOP; END IF; ----------------------------------------------------------------------- -- am29pdl128g Sector Protect word preload file ----------------------------------------------------------------------- -- am29pdl128g_prot sector protect file -- // - comment -- @ss - stands for sector group identification -- d - is bit to be written at SecProt(ss++) -- (ss is incremented at every load) -- only first 1-3 columns are loaded. NO empty lines !!!!!!!!!!!!! ----------------------------------------------------------------------- report_err := FALSE; line := 0; IF (prot_file_name /= "none" AND UserPreload ) THEN sec_ind := 0; WHILE (not ENDFILE (prot_f)) LOOP READLINE (prot_f, buf); line := line +1; IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address sec_ind := h(buf(2 to 3)); ELSE IF sec_ind <= SecGroupNumb THEN IF (buf(1) = '1') THEN IF sec_ind <= SSecN-1 THEN PPB(sec_ind) := '1'; ELSIF sec_ind = SSecN THEN PPB(SSecN+2 DOWNTO SSecN) := (OTHERS => '1'); ELSIF sec_ind <= SecGroupNumb - SSecN-1 THEN PPB((sec_ind-6)*4+2 DOWNTO (sec_ind-6)*4-1) := (OTHERS => '1'); ELSIF sec_ind = SecGroupNumb - SSecN THEN PPB(261 DOWNTO 259) := (OTHERS => '1'); ELSIF sec_ind <= SecGroupNumb THEN PPB(190 + sec_ind) := '1'; END IF; END IF; ELSE IF report_err = FALSE THEN REPORT "Protect file:" & prot_file_name & " Address range overflow" & " at line "&to_int_str(line) SEVERITY warning; report_err := TRUE; END IF; END IF; sec_ind := sec_ind + 1; END IF; END LOOP; SBPpb_prot := PPB(SSecN-1 DOWNTO 0); SPpb_prot(SecN-2 DOWNTO 1) := PPB(SecN+SSecN-3 DOWNTO SSecN); STPpb_prot := PPB(SecN+ 2*SSecN-3 DOWNTO SecN+SSecN-2); END IF; IF NOT FactoryLocked THEN Otp_Lock := '0'; FactoryLock := '0'; END IF; ----------------------------------------------------------------------- -- am29pdl128g Secure Silicon Sector Region preload file ----------------------------------------------------------------------- -- / - comment -- @aa - stands for address -- dddd - is word to be written at SecSi(aa++) -- (aa is incremented at every load) -- only first 1-4 columns are loaded. NO empty lines !!!!!!!! ----------------------------------------------------------------------- report_err := FALSE; line := 0; IF (secsi_file_name /= "none" AND UserPreload ) THEN SecSi := (OTHERS => MaxData); addr_ind := 0; WHILE (not ENDFILE (secsi_f)) LOOP READLINE (secsi_f, buf); line := line +1; IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN addr_ind := h(buf(2 to 3)); --address ELSE IF addr_ind <= SecSiSize-1 THEN SecSi(addr_ind) := h(buf(1 to 4)); addr_ind := addr_ind + 1; ELSE IF report_err = FALSE THEN REPORT "SecSi file:" & mem_file_name & " Address range overflow"& " at line "&to_int_str(line) SEVERITY warning; report_err := TRUE; END IF; END IF; END IF; END LOOP; END IF; WAIT; END PROCESS; ----------------------------------------------------------------------- -- Read Page process ----------------------------------------------------------------------- PD_PAGE : PROCESS (read, A, Din(31)) VARIABLE Address_page : std_logic_vector(HAddr-2 DOWNTO 0); BEGIN IF rising_edge(read) THEN Address_page := A(HAddr DOWNTO 2); ELSIF (A'event OR (Din(31)'event AND WORDNeg = '0')) AND read = '1' AND reseted = '1' THEN IF A(HAddr DOWNTO 2) = Address_page THEN read_page := TRUE; ELSE read_page := FALSE; Address_page := A(HAddr DOWNTO 2); END IF; ELSE read_page := FALSE; END IF; END PROCESS PD_PAGE; ------------------------------------------------------------------------ -- Path Delay Section ----------------------------------------------------------------------- DOutPassThrough : PROCESS(DOut_zd) VARIABLE tOD : time := 0 ns; VARIABLE tCD : time := 0 ns; VARIABLE tAD : time := 0 ns; VARIABLE tpd_A0_DQ0 : TIME; BEGIN Dout_x <= (OTHERS => 'X'); IF DOut_zd(0) /= 'Z' THEN tpd_OE := FALSE; tpd_CE := FALSE; tOD := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(trz1) ; tCD := -gCE_n'LAST_EVENT + tpd_CENeg_DQ0(trz1)-5 ns ; tAD := -A'LAST_EVENT + tpd_A0_DQ0_PgRead_eq_0(tr10); IF ( WORDNeg = '0' ) AND (DIn(31)'LAST_EVENT < A'LAST_EVENT) THEN tAD := -DIn(31)'LAST_EVENT + tpd_A0_DQ0_PgRead_eq_0(tr10); END IF; IF tOD >= tCD AND (tOD) > 0 ns THEN tpd_OE := TRUE; ELSIF tCD >= tOD AND tCD > 0 ns THEN tpd_CE := TRUE; END IF; IF tAD > 0 ns AND ((tAD >= tOD AND tpd_OE = TRUE) OR (tAD >= tCD AND tpd_CE = TRUE)) THEN Dout_pass <= Dout_x, Dout_zd AFTER tAD; ELSE Dout_pass <= Dout_zd; END IF; ELSE tCD := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(tr0z) ; tOD := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(tr0z) ; tpd_OE :=(tOD <= tCD) AND (tOD > 0 ns); tpd_CE :=(tCD < tOD) AND (tCD > 0 ns); IF tpd_CE = TRUE THEN tpd_OE := FALSE; ELSIF tpd_OE = TRUE THEN tpd_CE := FALSE; ELSE tpd_OE := TRUE; tpd_CE := TRUE; END IF; DOut_Pass <= DOut_zd; END IF; END PROCESS DOutPassThrough; RY_OUT: PROCESS(RY_zd) VARIABLE RY_GlitchData : VitalGlitchDataType; VARIABLE RY_tmp : std_logic; BEGIN IF RY_zd = '1' THEN RY_tmp := 'Z'; ELSE RY_tmp := '0'; END IF; VitalPathDelay01Z( OutSignal => RY_t, OutSignalName => "RYBYNeg", OutTemp => RY_tmp, Mode => VitalTransport, GlitchData => RY_GlitchData, Paths => ( 0 => (InputChangeTime => WENeg'LAST_EVENT, PathDelay => tpd_WENeg_RYBYNeg, PathCondition => TRUE), 1 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_WENeg_RYBYNeg, PathCondition => TRUE), 2 => (InputChangeTime => Ready_out'LAST_EVENT, PathDelay => VitalZeroDelay01Z, PathCondition => EDone = '1'), 3 => (InputChangeTime => EDone'LAST_EVENT, PathDelay => VitalZeroDelay01Z, PathCondition => EDone = '1'), 4 => (InputChangeTime => PDone'LAST_EVENT, PathDelay => VitalZeroDelay01Z, PathCondition => PDone = '1') ) ); END PROCESS RY_Out; RYBYNeg <= RY_t; --------------------------------------------------------------------------- -- Path Delay Section for signal DOut(15 downto 0) --------------------------------------------------------------------------- D_Out_PathDelay_Gen : FOR i IN 0 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, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => tpd_OE ), 1 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => tpd_CE ), 2 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_PgRead_eq_0), PathCondition => NOT(tpd_OE OR tpd_CE)AND NOT read_page), 3 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_PgRead_eq_1), PathCondition => read_page), 4 =>(InputChangeTime => Din(31)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_PgRead_eq_0), PathCondition => (WORDNeg = '0' AND DOut_pass(i) /= 'X') AND NOT read_page), 5 =>(InputChangeTime => Din(31)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_PgRead_eq_1), PathCondition => (WORDNeg = '0' AND DOut_pass(i) /= 'X') AND read_page), 6 => (InputChangeTime => WORDNeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_WORDNeg_DQ31), PathCondition => WORDNeg = '1'), 7 => (InputChangeTime => WORDNeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_WORDNeg_DQ31), PathCondition => WORDNeg = '0') ) ); END PROCESS; END GENERATE D_Out_PathDelay_Gen; --------------------------------------------------------------------------- -- Path Delay Section for signal DOut(31 downto 16) --------------------------------------------------------------------------- D_Out_PathDelay_Gen_DW : FOR i IN 16 TO 31 GENERATE PROCESS(DOut_pass(i)) VARIABlE D0_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_pass(i), GlitchData => D0_GlitchData, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => tpd_OE ), 1 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => tpd_CE ), 2 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_PgRead_eq_0), PathCondition => NOT(tpd_OE OR tpd_CE)AND NOT read_page), 3 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_PgRead_eq_1), PathCondition => read_page), 4 =>(InputChangeTime => Din(31)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_PgRead_eq_0), PathCondition => (WORDNeg = '0' AND DOut_pass(i) /= 'X') AND NOT read_page), 5 =>(InputChangeTime => Din(31)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0_PgRead_eq_1), PathCondition => (WORDNeg = '0' AND DOut_pass(i) /= 'X') AND read_page), 6 => (InputChangeTime => WORDNeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_WORDNeg_DQ31), PathCondition => WORDNeg = '1'), 7 => (InputChangeTime => WORDNeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_WORDNeg_DQ31), PathCondition => WORDNeg = '0') ) ); END PROCESS; END GENERATE D_Out_PathDelay_Gen_DW; END BLOCK behavior; END vhdl_behavioral;