------------------------------------------------------------------------------ -- File name : s29jl032j4.vhd ------------------------------------------------------------------------------- -- Copyright (C) 2008 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 B.Colakovic 08 Dec 02 Initial release ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: FLASH -- Technology: Flash Memory -- Part: S29JL032J4 -- -- Description: 32 Megabit Simultaneous Read/Write Flash Memory -- -------------------------------------------------------------------------------- -- Comments : -- 16th character in TimingModel determines whether top or bottom boot -- architecture is used ------------------------------------------------------------------------------- -- Known Bugs: -- ------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.VITAL_timing.ALL; USE IEEE.VITAL_primitives.ALL; LIBRARY FMF; USE FMF.gen_utils.all; USE FMF.conversions.all; USE STD.textio.ALL; ------------------------------------------------------------------------------- -- ENTITY DECLARATION FOR s29jl032j4 FLASH ------------------------------------------------------------------------------- ENTITY s29jl032j4 IS GENERIC ( -- tipd delays: interconnect path delays tipd_A0 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A1 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A2 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A3 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A4 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A5 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A6 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A7 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A8 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A9 : VitalDelayType01 := VitalZeroDelay01; --address tipd_A10 : VitalDelayType01 := VitalZeroDelay01; --lines tipd_A11 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A12 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A13 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A14 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A15 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A16 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A17 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A18 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A19 : VitalDelayType01 := VitalZeroDelay01; -- tipd_A20 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; -- data tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; -- lines tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; -- tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; tipd_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; tipd_BYTENeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays tpd_RESETNeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; tpd_A0_DQ0 : VitalDelayType01 := UnitDelay01;--tACC tpd_CENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; --(tCE,tCE,tDF,-,tDF,-) tpd_OENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z; --(tOE,tOE,tDF,-,tDF,-) tpd_WENeg_RY : VitalDelayType01Z := UnitDelay01Z;--tBUSY tpd_BYTENeg_DQ15 : VitalDelayType01Z := UnitDelay01Z; --(tfhqa:-:-, tfhqa,-:-, -:-:tflqz, tfhqa:-:-:, -:-:tflqz, tfhqa:-:-:) --tsetup values tsetup_A0_CENeg : VitalDelayType := UnitDelay; --tAS edge \ tsetup_A0_OENeg : VitalDelayType := UnitDelay; --tASO edge \ tsetup_DQ0_CENeg : VitalDelayType := UnitDelay; --tDS edge / tsetup_OENeg_WENeg : VitalDelayType := UnitDelay; --0,edge / tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; --0 ns / --thold values thold_A0_CENeg : VitalDelayType := UnitDelay; --tAH edge \ thold_A0_OENeg : VitalDelayType := UnitDelay; --tAHT edge / thold_DQ0_CENeg : VitalDelayType := UnitDelay; --tDH edge / thold_OENeg_WENeg_noedge_negedge : VitalDelayType := UnitDelay; --tOEH edge / thold_OENeg_WENeg_noedge_posedge : VitalDelayType := UnitDelay; --tOEH edge / thold_CENeg_WENeg : VitalDelayType := UnitDelay; --tCH edge / thold_CENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH edge / thold_BYTENeg_CENeg : VitalDelayType := UnitDelay; --telfh, tehfl --tpw values: pulse width tpw_RESETNeg_negedge: VitalDelayType := UnitDelay; --tRP tpw_WENeg_negedge : VitalDelayType := UnitDelay; --tWP tpw_WENeg_posedge : VitalDelayType := UnitDelay; --tWPH tpw_A0_negedge : VitalDelayType := UnitDelay; --tWC tpw_A0_posedge : VitalDelayType := UnitDelay; --tWC tpw_OENeg_posedge : VitalDelayType := UnitDelay; --tOEPH -- tdevice values: values for internal delays --Program Operation --byte write tdevice_POB : VitalDelayType := 6 us; --word write tdevice_POW : VitalDelayType := 6 us; --UNLOCK BYPASS tdevice_POu : VitalDelayType := 4 us; --Sector Erase Operation tWHWH2 tdevice_SEO : VitalDelayType := 0.4 sec; --Timing Limit Exceeded tdevice_HANG : VitalDelayType := 5000 ms; --program/erase suspend timeout tdevice_START : VitalDelayType := 35 us; --sector erase command sequence timeout tdevice_CTMOUTP : VitalDelayType := 80 us; --device ready after Hardware reset(during embeded algorithm) tdevice_READYP : VitalDelayType := 20 us; --tReady -- Password Unlock Operation tdevice_UNLOCK : VitalDelayType := 2 us; -- Protection Bit Program tdevice_PROTP : VitalDelayType := 100 us; -- Protection Bit Erase tdevice_PROTE : VitalDelayType := 1200 us; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- memory file to be loaded flash_file_name : STRING := "none";--"s29jl032j.mem"; prot_file_name : STRING := "none";--"s29jl032j_prot.mem"; secsi_file_name : STRING := "none";--"s29jl032j_secsi.mem"; UserPreload : BOOLEAN := FALSE; LongTiming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING ); PORT ( A20 : IN std_ulogic := 'U'; -- A19 : IN std_ulogic := 'U'; -- A18 : IN std_ulogic := 'U'; -- A17 : IN std_ulogic := 'U'; -- A16 : IN std_ulogic := 'U'; -- A15 : IN std_ulogic := 'U'; -- A14 : IN std_ulogic := 'U'; -- A13 : IN std_ulogic := 'U'; --address A12 : IN std_ulogic := 'U'; --lines A11 : IN std_ulogic := 'U'; -- A10 : IN std_ulogic := 'U'; -- A9 : IN std_ulogic := 'U'; -- A8 : IN std_ulogic := 'U'; -- A7 : IN std_ulogic := 'U'; -- A6 : IN std_ulogic := 'U'; -- A5 : IN std_ulogic := 'U'; -- A4 : IN std_ulogic := 'U'; -- A3 : IN std_ulogic := 'U'; -- A2 : IN std_ulogic := 'U'; -- A1 : IN std_ulogic := 'U'; -- A0 : IN std_ulogic := 'U'; -- DQ15 : INOUT std_ulogic := 'U'; -- DQ14 : INOUT std_ulogic := 'U'; -- DQ13 : INOUT std_ulogic := 'U'; -- DQ12 : INOUT std_ulogic := 'U'; -- DQ11 : INOUT std_ulogic := 'U'; -- DQ10 : INOUT std_ulogic := 'U'; -- DQ9 : INOUT std_ulogic := 'U'; -- data DQ8 : INOUT std_ulogic := 'U'; -- lines DQ7 : INOUT std_ulogic := 'U'; -- DQ6 : INOUT std_ulogic := 'U'; -- DQ5 : INOUT std_ulogic := 'U'; -- DQ4 : INOUT std_ulogic := 'U'; -- DQ3 : INOUT std_ulogic := 'U'; -- DQ2 : INOUT std_ulogic := 'U'; -- DQ1 : INOUT std_ulogic := 'U'; -- DQ0 : INOUT std_ulogic := 'U'; -- CENeg : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; BYTENeg : IN std_ulogic := '1'; RY : OUT std_ulogic := 'U' ; --RY/BY# WPNeg : IN std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of s29jl032j4 : ENTITY IS TRUE; END s29jl032j4; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of s29jl032j4 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "s29jl032j4"; CONSTANT MaxData : NATURAL := 16#FF#; --65535; CONSTANT SecSize : NATURAL := 16#FFFF#; --65535 bytes CONSTANT SecSiSize : NATURAL := 255; CONSTANT GroupNum : NATURAL := 16; CONSTANT SecNum : NATURAL := 63;--128 sectors for all flash memory CONSTANT SubSecNum : NATURAL := 7; CONSTANT HiAddrBit : NATURAL := 20; CONSTANT OW : NATURAL := to_nat("00011010"); CONSTANT PL : NATURAL := to_nat("00001010"); CONSTANT SL : NATURAL := to_nat("00010010"); CONSTANT WP : NATURAL := to_nat("00000010"); -- interconnect path delay signals SIGNAL A20_ipd : std_ulogic := 'U'; SIGNAL A19_ipd : std_ulogic := 'U'; SIGNAL A18_ipd : std_ulogic := 'U'; SIGNAL A17_ipd : std_ulogic := 'U'; SIGNAL A16_ipd : std_ulogic := 'U'; SIGNAL A15_ipd : std_ulogic := 'U'; SIGNAL A14_ipd : std_ulogic := 'U'; SIGNAL A13_ipd : std_ulogic := 'U'; SIGNAL A12_ipd : std_ulogic := 'U'; SIGNAL A11_ipd : std_ulogic := 'U'; SIGNAL A10_ipd : std_ulogic := 'U'; SIGNAL A9_ipd : std_ulogic := 'U'; SIGNAL A8_ipd : std_ulogic := 'U'; SIGNAL A7_ipd : std_ulogic := 'U'; SIGNAL A6_ipd : std_ulogic := 'U'; SIGNAL A5_ipd : std_ulogic := 'U'; SIGNAL A4_ipd : std_ulogic := 'U'; SIGNAL A3_ipd : std_ulogic := 'U'; SIGNAL A2_ipd : std_ulogic := 'U'; SIGNAL A1_ipd : std_ulogic := 'U'; SIGNAL A0_ipd : std_ulogic := 'U'; SIGNAL DQ15_ipd : std_ulogic := 'U'; SIGNAL DQ14_ipd : std_ulogic := 'U'; SIGNAL DQ13_ipd : std_ulogic := 'U'; SIGNAL DQ12_ipd : std_ulogic := 'U'; SIGNAL DQ11_ipd : std_ulogic := 'U'; SIGNAL DQ10_ipd : std_ulogic := 'U'; SIGNAL DQ9_ipd : std_ulogic := 'U'; SIGNAL DQ8_ipd : std_ulogic := 'U'; SIGNAL DQ7_ipd : std_ulogic := 'U'; SIGNAL DQ6_ipd : std_ulogic := 'U'; SIGNAL DQ5_ipd : std_ulogic := 'U'; SIGNAL DQ4_ipd : std_ulogic := 'U'; SIGNAL DQ3_ipd : std_ulogic := 'U'; SIGNAL DQ2_ipd : std_ulogic := 'U'; SIGNAL DQ1_ipd : std_ulogic := 'U'; SIGNAL DQ0_ipd : std_ulogic := 'U'; SIGNAL CENeg_ipd : std_ulogic := 'U'; SIGNAL OENeg_ipd : std_ulogic := 'U'; SIGNAL WENeg_ipd : std_ulogic := 'U'; SIGNAL RESETNeg_ipd : std_ulogic := 'U'; SIGNAL BYTENeg_ipd : std_ulogic := '1'; SIGNAL WPNeg_ipd : std_ulogic := 'U'; --- internal delays SIGNAL POB_in : std_ulogic := '0'; SIGNAL POB_out : std_ulogic := '0'; SIGNAL POW_in : std_ulogic := '0'; SIGNAL POW_out : std_ulogic := '0'; SIGNAL POU_in : std_ulogic := '0'; SIGNAL POU_out : std_ulogic := '0'; SIGNAL SEO_in : std_ulogic := '0'; SIGNAL SEO_out : std_ulogic := '0'; SIGNAL HANG_out : std_ulogic := '0'; --Program/Erase Timing Limit SIGNAL HANG_in : std_ulogic := '0'; SIGNAL START_T1 : std_ulogic := '0'; --Start TimeOut; SUSPEND SIGNAL START_T1_in : std_ulogic := '0'; SIGNAL CTMOUT : std_ulogic := '0'; --Sector Erase TimeOut SIGNAL CTMOUT_in : std_ulogic := '0'; SIGNAL READY_in : std_ulogic := '0'; SIGNAL READY : std_ulogic := '0'; -- Device ready after reset SIGNAL PBPROG_in : std_ulogic := '0'; SIGNAL PBPROG_out : std_ulogic := '0'; SIGNAL PBERASE_in : std_ulogic := '0'; SIGNAL PBERASE_out : std_ulogic := '0'; SIGNAL UNLOCKDONE_in : std_ulogic := '0'; SIGNAL UNLOCKDONE_out : std_ulogic := '0'; SIGNAL PASSPDONE_in : std_ulogic := '0'; SIGNAL PASSPDONE_out : std_ulogic := '0'; -- Annotate SIGNAL P1_in : std_ulogic := '0'; SIGNAL P1_out : std_ulogic := '0'; SIGNAL P2_in : std_ulogic := '0'; SIGNAL P2_out : std_ulogic := '0'; SIGNAL P3_in : std_ulogic := '0'; SIGNAL P3_out : std_ulogic := '0'; BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays POB :VitalBuf(POB_out, POB_in, (tdevice_POB ,UnitDelay)); POW :VitalBuf(POW_out, POW_in, (tdevice_POW ,UnitDelay)); POU :VitalBuf(POU_out, POU_in, (tdevice_POU ,UnitDelay)); SEO :VitalBuf(SEO_out, SEO_in, (tdevice_SEO ,UnitDelay)); HANG :VitalBuf(HANG_out, HANG_in, (tdevice_HANG ,UnitDelay)); START :VitalBuf(START_T1, START_T1_in,(tdevice_START ,UnitDelay)); CTMOUTP :VitalBuf(CTMOUT, CTMOUT_in, (tdevice_CTMOUTP ,UnitDelay)); READYP :VitalBuf(READY, READY_in, (tdevice_READYP ,UnitDelay)); PROTP :VitalBuf(P1_out, P1_in, (tdevice_PROTP ,UnitDelay)); PROTE :VitalBuf(P2_out, P2_in, (tdevice_PROTE ,UnitDelay)); UNLOCK :VitalBuf(P3_out, P3_in, (tdevice_UNLOCK ,UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (A20_ipd, A20, tipd_A20); w_2 : VitalWireDelay (A19_ipd, A19, tipd_A19); w_3 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_4 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_5 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_6 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_7 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_8 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_9 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_10 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_11 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_12 : VitalWireDelay (A9_ipd, A9, tipd_A9); w_13 : VitalWireDelay (A8_ipd, A8, tipd_A8); w_14 : VitalWireDelay (A7_ipd, A7, tipd_A7); w_15 : VitalWireDelay (A6_ipd, A6, tipd_A6); w_16 : VitalWireDelay (A5_ipd, A5, tipd_A5); w_17 : VitalWireDelay (A4_ipd, A4, tipd_A4); w_18 : VitalWireDelay (A3_ipd, A3, tipd_A3); w_19 : VitalWireDelay (A2_ipd, A2, tipd_A2); w_20 : VitalWireDelay (A1_ipd, A1, tipd_A1); w_21 : VitalWireDelay (A0_ipd, A0, tipd_A0); w_22 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_23 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_24 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_25 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_26 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_27 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_28 : VitalWireDelay (DQ9_ipd, DQ9, tipd_DQ9); w_29 : VitalWireDelay (DQ8_ipd, DQ8, tipd_DQ8); w_30 : VitalWireDelay (DQ7_ipd, DQ7, tipd_DQ7); w_31 : VitalWireDelay (DQ6_ipd, DQ6, tipd_DQ6); w_32 : VitalWireDelay (DQ5_ipd, DQ5, tipd_DQ5); w_33 : VitalWireDelay (DQ4_ipd, DQ4, tipd_DQ4); w_34 : VitalWireDelay (DQ3_ipd, DQ3, tipd_DQ3); w_35 : VitalWireDelay (DQ2_ipd, DQ2, tipd_DQ2); w_36 : VitalWireDelay (DQ1_ipd, DQ1, tipd_DQ1); w_37 : VitalWireDelay (DQ0_ipd, DQ0, tipd_DQ0); w_38 : VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg); w_39 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_40 : VitalWireDelay (RESETNeg_ipd, RESETNeg, tipd_RESETNeg); w_41 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); w_42 : VitalWireDelay (BYTENeg_ipd, BYTENeg, tipd_BYTENeg); w_43 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg); END BLOCK; --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK PORT ( A : IN std_logic_vector(HiAddrBit downto 0) := (OTHERS => 'U'); DIn : IN std_logic_vector(15 downto 0) := (OTHERS => 'U'); DOut : OUT std_ulogic_vector(15 downto 0) := (OTHERS => 'Z'); CENeg : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; RESETNeg : IN std_ulogic := 'U'; BYTENeg : IN std_ulogic := 'U'; RY : OUT std_ulogic := 'U' ; WPNeg : IN std_ulogic := 'U' ); PORT MAP ( A(20) => A20_ipd, A(19) => A19_ipd, A(18) => A18_ipd, A(17) => A17_ipd, A(16) => A16_ipd, A(15) => A15_ipd, A(14) => A14_ipd, A(13) => A13_ipd, A(12) => A12_ipd, A(11) => A11_ipd, A(10) => A10_ipd, A(9) => A9_ipd, A(8) => A8_ipd, A(7) => A7_ipd, A(6) => A6_ipd, A(5) => A5_ipd, A(4) => A4_ipd, A(3) => A3_ipd, A(2) => A2_ipd, A(1) => A1_ipd, A(0) => A0_ipd, DIn(15) => DQ15_ipd, DIn(14) => DQ14_ipd, DIn(13) => DQ13_ipd, DIn(12) => DQ12_ipd, DIn(11) => DQ11_ipd, DIn(10) => DQ10_ipd, DIn(9) => DQ9_ipd, DIn(8) => DQ8_ipd, DIn(7) => DQ7_ipd, DIn(6) => DQ6_ipd, DIn(5) => DQ5_ipd, DIn(4) => DQ4_ipd, DIn(3) => DQ3_ipd, DIn(2) => DQ2_ipd, DIn(1) => DQ1_ipd, DIn(0) => DQ0_ipd, DOut(15) => DQ15, DOut(14) => DQ14, DOut(13) => DQ13, DOut(12) => DQ12, DOut(11) => DQ11, DOut(10) => DQ10, DOut(9) => DQ9, DOut(8) => DQ8, DOut(7) => DQ7, DOut(6) => DQ6, DOut(5) => DQ5, DOut(4) => DQ4, DOut(3) => DQ3, DOut(2) => DQ2, DOut(1) => DQ1, DOut(0) => DQ0, CENeg => CENeg_ipd, OENeg => OENeg_ipd, WENeg => WENeg_ipd, RESETNeg => RESETNeg_ipd, BYTENeg => BYTENeg_ipd, RY => RY , WPNeg => WPNeg_ipd ); -- State Machine : State_Type TYPE state_type IS ( RESET, Z001, PREL_SETBWB, PREL_ULBYPASS, ESP_ULBYPASS, PREL_ULBYPASS_RESET, ESP_ULBYPASS_RESET, CFI, -- CFI MOD AS, -- autoselect AS_CFI, -- CFI from autoselect UBP_CFI, A0SEEN, OTP, OTP_Z001, OTP_PREL, OTP_EXIT, OTP_A0SEEN, C8, C8_Z001, C8_PREL, ERS, SERS, ESPS, SERS_EXEC, ESP, ESP_SETBWB, ESP_Z001, ESP_A0SEEN, ESP_AS, ESP_CFI, ESP_AS_CFI, PGMS, PSP, PSPS, PSP_CFI, PSP_Z001, PSP_PREL, PSP_AS, PSP_AS_CFI, PASSPROG_PREL, PASSPROG, PASSVERIFY, PASSUNLOCK0, PASSUNLOCK1, PASSUNLOCK2, PASSUNLOCK3, PASSUNLOCK4, PASSUNLOCK5, PASSUNLOCK6, PASSUNLOCK7, PROTBIT_PREL, PPBDYB, DYBWE, PPB_PROGRAM, PPB_VERIFY, PPB_ERASE, PPMLB_PROGRAM, SPMLB_PROGRAM, SSPB_PROGRAM, PPMLB_VERIFY, SPMLB_VERIFY, SSPB_VERIFY ); --Array of Sub sector start-end address within sector TYPE SubSecSEAddr IS ARRAY (0 TO SubSecNum) OF NATURAL; --Addresses of all Sectors devided to sub sectors TYPE SubSecAddr IS ARRAY (0 TO 1) OF SubSecSEAddr;--SecType; --Flash Memory Array TYPE SecType IS ARRAY (0 TO SecSize) OF INTEGER RANGE -1 TO MaxData; TYPE MemArray IS ARRAY (0 TO SecNum) OF SecType; --SecSi Sector TYPE SecSiType IS ARRAY ( 0 TO SecSiSize) OF INTEGER RANGE -1 TO MaxData; --Common Flash Interface Query codes TYPE CFItype IS ARRAY (16#10# TO 16#5B#) OF NATURAL RANGE 0 TO 16#FFFF#; TYPE PassType IS ARRAY(0 TO 7) OF std_logic_vector(7 downto 0); TYPE PgmsTargetType IS (MEMORY, OTP); -- states SIGNAL current_state : state_type; -- SIGNAL next_state : state_type; -- -- powerup SIGNAL PoweredUp : std_logic := '0'; --zero delay signals SIGNAL DOut_zd : std_logic_vector(15 downto 0):=(OTHERS=>'Z'); SIGNAL DOut_Pass : std_logic_vector(15 downto 0):=(OTHERS=>'Z'); SIGNAL RY_zd : std_logic := 'Z'; --FSM control signals SIGNAL BankNum : NATURAL :=1 ; SIGNAL BankBypassLock : std_logic_vector(1 DOWNTO 0) :=(OTHERS => '0'); SIGNAL BankAutosel : std_logic_vector(1 DOWNTO 0) :=(OTHERS => '0'); SIGNAL ULBYPASS : std_logic := '0'; --Unlock Bypass Active SIGNAL PSP_ACT : std_logic := '0'; --Program Suspend SIGNAL ESP_ACT : std_logic := '0'; --Erase Suspend SIGNAL OTP_ACT : std_logic := '0'; --SecSi access SHARED VARIABLE DOut_zd_var : std_logic_vector(15 downto 0) :=(OTHERS=>'Z'); --Model should never hang!!!!!!!!!!!!!!! SIGNAL HANG : std_logic := '0'; SIGNAL PDONE : std_logic := '1'; --Prog. Done SIGNAL PSTART : std_logic := '0'; --Start Programming SIGNAL PSUSP : std_logic := '0'; --Suspend Programming SIGNAL PRES : std_logic := '0'; --Resume Programming --Program location is in protected sector SIGNAL PERR : std_logic := '0'; SIGNAL EDONE : std_logic := '1'; --Ers. Done SIGNAL ESTART : std_logic := '0'; --Start Erase SIGNAL ESUSP : std_logic := '0'; --Suspend Erase SIGNAL ERES : std_logic := '0'; --Resume Erase --All sectors selected for erasure are protected SIGNAL EERR : std_logic := '0'; --Sectors selected for erasure SIGNAL ERS_QUEUE : std_logic_vector(SecNum downto 0) := (OTHERS => '0'); SIGNAL ERS_SUB_QUEUE : std_logic_vector(SubSecNum downto 0) := (OTHERS => '0'); --Command Register SIGNAL write : std_logic := '0'; SIGNAL read : std_logic := '0'; -- Access time variables SHARED VARIABLE OPENLATCH : BOOLEAN; SHARED VARIABLE FROMCE : BOOLEAN; SHARED VARIABLE FROMOE : BOOLEAN; --Sector Address SIGNAL SecAddr : NATURAL RANGE 0 TO SecNum := 0; SIGNAL SubSect : NATURAL RANGE 0 TO SubSecNum := 0; SIGNAL SA : NATURAL RANGE 0 TO SecNum := 0; SIGNAL SSA : NATURAL RANGE 0 TO SubSecNum := 0; SIGNAL BA : NATURAL RANGE 0 TO 3 := 0; --Address within sector SIGNAL Address : NATURAL RANGE 0 TO SecSize := 0; --Address within Subsector SIGNAL SubAddr : NATURAL RANGE 0 TO SecSize := 0; SIGNAL D_tmp0 : NATURAL RANGE 0 TO MaxData; SIGNAL D_tmp1 : NATURAL RANGE 0 TO MaxData; --A19:A11 Don't Care SIGNAL Addr : NATURAL RANGE 0 TO 16#7FFF# := 0; --glitch protection SIGNAL gWE_n : std_logic := '1'; SIGNAL gCE_n : std_logic := '1'; SIGNAL gOE_n : std_logic := '1'; SIGNAL RST : std_logic := '1'; SIGNAL reseted : std_logic := '0'; -- Mem(SecAddr)(Address).... SHARED VARIABLE Mem : MemArray := (OTHERS =>(OTHERS=> MaxData)); -- Protection parameters SHARED VARIABLE SubSec_Prot : std_logic_vector(SubSecNum downto 0) := (OTHERS => '0'); SHARED VARIABLE DYB : std_logic_vector(SecNum downto 0) := (OTHERS => '0'); SHARED VARIABLE DYB_SubSec : std_logic_vector(SubSecNum downto 0) := (OTHERS => '0'); SHARED VARIABLE PPB : std_logic_vector(GroupNum downto 0) := (OTHERS => '0'); SHARED VARIABLE PPB_SubSec : std_logic_vector(SubSecNum downto 0) := (OTHERS => '0'); SHARED VARIABLE PPBLock : std_logic; SHARED VARIABLE PPMLB : std_logic; SHARED VARIABLE SPMLB : std_logic; SHARED VARIABLE SSPB : std_logic; SHARED VARIABLE PPB_ers_ccl : NATURAL RANGE 0 TO 100 := 0; --s29jl032j4 SHARED VARIABLE sssa : SubSecAddr := ((16#0000#,16#1000#,16#2000#,16#3000#,16#4000#,16#5000#,16#6000#,16#7000#), (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#), (16#0FFF#,16#1FFF#,16#2FFF#,16#3FFF#,16#4FFF#,16#5FFF#,16#6FFF#,16#7FFF#)); SHARED VARIABLE CFI_array : CFItype := (OTHERS => 0); SHARED VARIABLE SecSi : SecSiType := (OTHERS => 0); SHARED VARIABLE Password : PassType; -- Addresses of the Protected Sector SIGNAL ProtSecNum_1 : NATURAL ; SIGNAL ProtSecNum_2 : NATURAL ; SHARED VARIABLE BankProg : std_logic_vector(1 downto 0) := "00"; SIGNAL BankErase : std_logic_vector(1 downto 0) := "00"; SIGNAL BankEraseExec : std_logic_vector(1 downto 0) := "00"; -- timing check violation SIGNAL Viol : X01 := '0'; FUNCTION GroupID(SECT : NATURAL) RETURN NATURAL IS VARIABLE result : NATURAL; BEGIN IF TimingModel(16) = '1' THEN result := 0; IF ( SECT = 0 ) THEN result := SECT; ELSIF ( SECT >= 1 ) AND ( SECT <= 3 ) THEN result := 1; ELSIF ( SECT >= 4 ) AND ( SECT <= 59 ) THEN result := (SECT - 4) / 4 + 2; ELSIF ( SECT >= 60 ) AND ( SECT <= 62 ) THEN result := 16; END IF; ELSE result := 0; IF ( SECT >= 1 ) AND ( SECT <= 3 ) THEN result := 0; ELSIF ( SECT >= 4 ) AND ( SECT <= 59 ) THEN result := (SECT - 4) / 4 + 1; ELSIF ( SECT >= 60 ) AND ( SECT <= 62 ) THEN result := 15; ELSE result := 16; END IF; END IF; RETURN result; END GroupID; --Address of variable size sector (bottom or top boot sector) SIGNAL VarSect : INTEGER := -1; SIGNAL vs : INTEGER;--0 if VarSect = 0 else 1 PROCEDURE generate_out ( DOut_zd : OUT std_logic_vector(15 downto 0); SecAddr : IN NATURAL; BYTENeg : IN std_logic; SecSi_acc : IN NATURAL; Address : IN NATURAL ) IS BEGIN IF SecSi_acc = 0 THEN IF Mem(SecAddr)(Address) = -1 THEN DOut_zd(7 downto 0) := (OTHERS=>'X'); ELSE DOut_zd(7 downto 0) := to_slv(Mem(SecAddr)(Address),8); END IF; IF BYTENeg = '1' THEN IF Mem(SecAddr)(Address+1) = -1 THEN DOut_zd(15 downto 8) := (OTHERS=>'X'); ELSE DOut_zd(15 downto 8):=to_slv(Mem(SecAddr)(Address+1),8); END IF; END IF; ELSE IF SecSi(Address)=-1 THEN DOut_zd(7 downto 0) := (OTHERS=>'X'); ELSE DOut_zd(7 downto 0) := to_slv(SecSi(Address),8); END IF; IF BYTENeg='1' THEN IF SecSi(Address)=-1 THEN DOut_zd(15 downto 8) := (OTHERS=>'X'); ELSE DOut_zd(15 downto 8) := to_slv(SecSi(Address+1),8); END IF; END IF; END IF; END PROCEDURE generate_out; BEGIN --------------------------------------------------------------------------- --protected sectors --------------------------------------------------------------------------- ProtSecNum_1 <= SubSecNum WHEN TimingModel(16) = '1' ELSE 1 ;-- WHEN TimingModel = "S29JL032JXXXXXXX2X" ProtSecNum_2 <= SubSecNum - 1 WHEN TimingModel(16) = '1' ELSE 0 ;-- WHEN TimingModel = "S29JL032JXXXXXXX2X" --------------------------------------------------------------------------- --------------------------------------------------------------------------- --VarSect --------------------------------------------------------------------------- VarSect <= SecNum WHEN TimingModel(16) = '1' ELSE 0;--WHEN TimingModel = "S29JL032JXXXXXXX2X" vs <= 1 WHEN TimingModel(16) = '1' ELSE 0; -- WHEN TimingModel = "S29JL032JXXXXXXX2X" --------------------------------------------------------------------------- --Power Up time 100 ns; --------------------------------------------------------------------------- PoweredUp <= '1' AFTER 100 ns; RST <= RESETNeg AFTER 500 ns; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(A, Din, CENeg, OENeg, WENeg, RESETNeg) -- Timing Check Variables VARIABLE Tviol_A0_CENeg : X01 := '0'; VARIABLE TD_A0_CENeg : VitalTimingDataType; VARIABLE Tviol_A0_OENeg : X01 := '0'; VARIABLE TD_A0_OENeg : VitalTimingDataType; VARIABLE Tviol_A0_WENeg : X01 := '0'; VARIABLE TD_A0_WENeg : VitalTimingDataType; VARIABLE Tviol_BYTENeg_WENeg : X01 := '0'; VARIABLE TD_BYTENeg_WENeg : VitalTimingDataType; VARIABLE Tviol_DQ0_CENeg : X01 := '0'; VARIABLE TD_DQ0_CENeg : VitalTimingDataType; VARIABLE Tviol_DQ0_WENeg : X01 := '0'; VARIABLE TD_DQ0_WENeg : VitalTimingDataType; VARIABLE Tviol_CENeg_RESETNeg : X01 := '0'; VARIABLE TD_CENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_OENeg_RESETNeg : X01 := '0'; VARIABLE TD_OENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_WENeg_RESETNeg : X01 := '0'; VARIABLE TD_WENeg_RESETNeg : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_F : X01 := '0'; VARIABLE TD_CENeg_WENeg_F : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_R : X01 := '0'; VARIABLE TD_CENeg_WENeg_R : VitalTimingDataType; VARIABLE Tviol_OENeg_WENeg_F : X01 := '0'; VARIABLE TD_OENeg_WENeg_F : VitalTimingDataType; VARIABLE Tviol_OENeg_WENeg : X01 := '0'; VARIABLE TD_OENeg_WENeg : VitalTimingDataType; VARIABLE Tviol_OENeg_WENeg_R : X01 := '0'; VARIABLE TD_OENeg_WENeg_R : VitalTimingDataType; VARIABLE Tviol_WENeg_CENeg_F : X01 := '0'; VARIABLE TD_WENeg_CENeg_F : VitalTimingDataType; VARIABLE Tviol_WENeg_CENeg_R : X01 := '0'; VARIABLE TD_WENeg_CENeg_R : VitalTimingDataType; VARIABLE Tviol_CENeg_OENeg : X01 := '0'; VARIABLE TD_CENeg_OENeg : VitalTimingDataType; VARIABLE Tviol_BYTENeg_CENeg : X01 := '0'; VARIABLE TD_BYTENeg_CENeg : VitalTimingDataType; VARIABLE Pviol_RESETNeg : X01 := '0'; VARIABLE PD_RESETNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CENeg : X01 := '0'; VARIABLE PD_CENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_WENeg : X01 := '0'; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A0 : X01 := '0'; VARIABLE PD_A0 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A1 : X01 := '0'; VARIABLE PD_A1 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A2 : X01 := '0'; VARIABLE PD_A2 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A3 : X01 := '0'; VARIABLE PD_A3 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A4 : X01 := '0'; VARIABLE PD_A4 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A5 : X01 := '0'; VARIABLE PD_A5 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A6 : X01 := '0'; VARIABLE PD_A6 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A7 : X01 := '0'; VARIABLE PD_A7 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A8 : X01 := '0'; VARIABLE PD_A8 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A9 : X01 := '0'; VARIABLE PD_A9 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A10 : X01 := '0'; VARIABLE PD_A10 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A11 : X01 := '0'; VARIABLE PD_A11 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A12 : X01 := '0'; VARIABLE PD_A12 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A13 : X01 := '0'; VARIABLE PD_A13 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A14 : X01 := '0'; VARIABLE PD_A14 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A15 : X01 := '0'; VARIABLE PD_A15 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A16 : X01 := '0'; VARIABLE PD_A16 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A17 : X01 := '0'; VARIABLE PD_A17 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A18 : X01 := '0'; VARIABLE PD_A18 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A19 : X01 := '0'; VARIABLE PD_A19 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_A20 : X01 := '0'; VARIABLE PD_A20 : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_OENeg : X01 := '0'; VARIABLE PD_OENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01 := '0'; BEGIN --------------------------------------------------------------------------- -- Timing Check Section --------------------------------------------------------------------------- IF (TimingChecksOn) THEN -- Setup/Hold Check between A and CENeg VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CENeg, RefSignalName => "CE#", SetupHigh => tsetup_A0_CENeg, SetupLow => tsetup_A0_CENeg, HoldHigh => thold_A0_CENeg, HoldLow => thold_A0_CENeg, CheckEnabled => WENeg = '0' AND OENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_CENeg, Violation => Tviol_A0_CENeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => OENeg, RefSignalName => "OE#", SetupHigh => tsetup_A0_OENeg, SetupLow => tsetup_A0_OENeg, CheckEnabled => WENeg = '1' AND CENeg = '0' AND (PDONE = '0' OR EDONE = '0'), RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_OENeg, Violation => Tviol_A0_OENeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => OENeg, RefSignalName => "OE#", HoldHigh => thold_A0_OENeg, HoldLow => thold_A0_OENeg, CheckEnabled => WENeg = '1' AND CENeg = '0' AND (PDONE = '0' OR EDONE = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_OENeg, Violation => Tviol_A0_OENeg ); -- Setup/Hold Check between A and WENeg VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_A0_CENeg, SetupLow => tsetup_A0_CENeg, HoldHigh => thold_A0_CENeg, HoldLow => thold_A0_CENeg, CheckEnabled => CENeg = '0' AND OENeg = '1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_WENeg, Violation => Tviol_A0_WENeg ); -- Setup/Hold Check between BYTENeg and WENeg VitalSetupHoldCheck ( TestSignal => BYTENeg, TestSignalName => "BYTENeg", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_A0_CENeg, SetupLow => tsetup_A0_CENeg, HoldHigh => thold_A0_CENeg, HoldLow => thold_A0_CENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_BYTENeg_WENeg, Violation => Tviol_BYTENeg_WENeg ); -- Setup/Hold Check between DQ and CENeg VitalSetupHoldCheck ( TestSignal => DQ0, TestSignalName => "DQ", RefSignal => CENeg, RefSignalName => "CE#", SetupHigh => tsetup_DQ0_CENeg, SetupLow => tsetup_DQ0_CENeg, HoldHigh => thold_DQ0_CENeg, HoldLow => thold_DQ0_CENeg, CheckEnabled => WENeg = '0' AND OENeg = '1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_DQ0_CENeg, Violation => Tviol_DQ0_CENeg ); -- Setup/Hold Check between DQ and WENeg VitalSetupHoldCheck ( TestSignal => DQ0, TestSignalName => "DQ", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_DQ0_CENeg, SetupLow => tsetup_DQ0_CENeg, HoldHigh => thold_DQ0_CENeg, HoldLow => thold_DQ0_CENeg, CheckEnabled => CENeg = '0' AND OENeg = '1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_DQ0_WENeg, Violation => Tviol_DQ0_WENeg ); -- Hold Check between CENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_RESETNeg, Violation => Tviol_CENeg_RESETNeg ); -- Hold Check between OENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_RESETNeg, Violation => Tviol_OENeg_RESETNeg ); -- Hold Check between WENeg and RESETNeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => RESETNeg, RefSignalName => "RESET#", HoldHigh => thold_CENeg_RESETNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_RESETNeg, Violation => Tviol_WENeg_RESETNeg ); -- Setup/Hold Check between BYTENeg and CENeg VitalSetupHoldCheck ( TestSignal => BYTENeg, TestSignalName => "BYTE#", RefSignal => CENeg, RefSignalName => "CE#", HoldHigh => thold_BYTENeg_CENeg,--5ns HoldLow => thold_BYTENeg_CENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_BYTENeg_CENeg, Violation => Tviol_BYTENeg_CENeg ); -- Hold Check between OENeg and WENeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => WENeg, RefSignalName => "WE#", HoldHigh => thold_OENeg_WENeg_noedge_posedge,--toeh HoldLow => thold_OENeg_WENeg_noedge_posedge,--toeh CheckEnabled => PDONE = '0' OR EDONE = '0',--toggle RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_WENeg, Violation => Tviol_OENeg_WENeg ); -- Hold Check between OENeg and WENeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => WENeg, RefSignalName => "WE#", HoldHigh => thold_OENeg_WENeg_noedge_negedge,--toeh HoldLow => thold_OENeg_WENeg_noedge_negedge,--toeh CheckEnabled => PDONE = '1' AND EDONE = '1', --read RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_WENeg_R, Violation => Tviol_OENeg_WENeg_R ); -- Hold Check between OENeg and WENeg VitalSetupHoldCheck ( TestSignal => OENeg, TestSignalName => "OE#", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_OENeg_WENeg,--0 CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_OENeg_WENeg_F, Violation => Tviol_OENeg_WENeg_F ); -- Hold Check between CENeg and OENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => OENeg, RefSignalName => "OE#", HoldHigh => thold_CENeg_WENeg,--0 CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_OENeg, Violation => Tviol_CENeg_OENeg ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => CENeg, RefSignalName => "CE#", SetupLow => tsetup_CENeg_WENeg,--0 CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CENeg_F, Violation => Tviol_WENeg_CENeg_F ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => CENeg, RefSignalName => "CE#", HoldLow => thold_CENeg_WENeg,--0 CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CENeg_R, Violation => Tviol_WENeg_CENeg_R ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", SetupLow => tsetup_CENeg_WENeg,--0 CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_F, Violation => Tviol_CENeg_WENeg_F ); -- Setup/Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", HoldLow => thold_CENeg_WENeg,--0 CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_R, Violation => Tviol_CENeg_WENeg_R ); -- PulseWidth Check for RESETNeg VitalPeriodPulseCheck ( TestSignal => RESETNeg, TestSignalName => "RESET#", PulseWidthLow => tpw_RESETNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RESETNeg, Violation => Pviol_RESETNeg ); -- PulseWidth Check for WENeg VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WE#", PulseWidthHigh => tpw_WENeg_posedge, PulseWidthLow => tpw_WENeg_negedge, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, Violation => Pviol_WENeg, CheckEnabled => CENeg = '0' ); -- PulseWidth Check for CENeg VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CE#", PulseWidthHigh => tpw_WENeg_posedge, PulseWidthLow => tpw_WENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg, Violation => Pviol_CENeg ); -- PulseWidth Check for A VitalPeriodPulseCheck ( TestSignal => A(0), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A0, Violation => Pviol_A0 ); VitalPeriodPulseCheck ( TestSignal => A(1), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A1, Violation => Pviol_A1 ); VitalPeriodPulseCheck ( TestSignal => A(2), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A2, Violation => Pviol_A2 ); VitalPeriodPulseCheck ( TestSignal => A(3), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A3, Violation => Pviol_A3 ); VitalPeriodPulseCheck ( TestSignal => A(4), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A4, Violation => Pviol_A4 ); VitalPeriodPulseCheck ( TestSignal => A(5), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A5, Violation => Pviol_A5 ); VitalPeriodPulseCheck ( TestSignal => A(6), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A6, Violation => Pviol_A6 ); VitalPeriodPulseCheck ( TestSignal => A(7), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A7, Violation => Pviol_A7 ); VitalPeriodPulseCheck ( TestSignal => A(8), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A8, Violation => Pviol_A8 ); VitalPeriodPulseCheck ( TestSignal => A(9), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A9, Violation => Pviol_A9 ); VitalPeriodPulseCheck ( TestSignal => A(10), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A10, Violation => Pviol_A10 ); VitalPeriodPulseCheck ( TestSignal => A(11), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A11, Violation => Pviol_A11 ); VitalPeriodPulseCheck ( TestSignal => A(12), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A12, Violation => Pviol_A12 ); VitalPeriodPulseCheck ( TestSignal => A(13), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A13, Violation => Pviol_A13 ); VitalPeriodPulseCheck ( TestSignal => A(14), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A14, Violation => Pviol_A14 ); VitalPeriodPulseCheck ( TestSignal => A(15), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A15, Violation => Pviol_A15 ); VitalPeriodPulseCheck ( TestSignal => A(16), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A16, Violation => Pviol_A16 ); VitalPeriodPulseCheck ( TestSignal => A(17), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A17, Violation => Pviol_A17 ); VitalPeriodPulseCheck ( TestSignal => A(18), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A18, Violation => Pviol_A18 ); VitalPeriodPulseCheck ( TestSignal => A(19), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A19, Violation => Pviol_A19 ); VitalPeriodPulseCheck ( TestSignal => A(20), TestSignalName => "A", PulseWidthHigh => tpw_A0_negedge, PulseWidthLow => tpw_A0_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_A20, Violation => Pviol_A20 ); -- PulseWidth Check for A VitalPeriodPulseCheck ( TestSignal => OENeg, TestSignalName => "OE#", PulseWidthHigh => tpw_OENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_OENeg, Violation => Pviol_OENeg ); Violation := Tviol_A0_CENeg OR Tviol_A0_OENeg OR Tviol_A0_WENeg OR Tviol_BYTENeg_WENeg OR Tviol_DQ0_CENeg OR Tviol_DQ0_WENeg OR Tviol_CENeg_RESETNeg OR Tviol_OENeg_RESETNeg OR Tviol_WENeg_RESETNeg OR Tviol_BYTENeg_CENeg OR Tviol_OENeg_WENeg_F OR Tviol_OENeg_WENeg OR Tviol_OENeg_WENeg_R OR Tviol_CENeg_OENeg OR Tviol_WENeg_CENeg_F OR Tviol_WENeg_CENeg_R OR Tviol_CENeg_WENeg_F OR Tviol_CENeg_WENeg_R OR Pviol_RESETNeg OR Pviol_WENeg OR Pviol_CENeg OR Pviol_A0 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_OENeg; Viol <= Violation; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY WARNING; END IF; END PROCESS VITALTimingCheck; ---------------------------------------------------------------------------- -- sequential process for reset control and FSM state transition ---------------------------------------------------------------------------- StateTransition : PROCESS(next_state, RESETNeg, RST, READY, PDone, EDone, PoweredUp) VARIABLE R : std_logic := '0'; --prog or erase in progress VARIABLE E : std_logic := '0'; --reset timming error BEGIN IF PoweredUp='1' THEN --Hardware reset timing control IF falling_edge(RESETNeg) THEN E := '0'; IF (PDONE='0' OR EDONE='0') THEN --if program or erase in progress READY_in <= '1'; R :='1'; ELSE READY_in <= '0'; R:='0'; --prog or erase not in progress END IF; ELSIF rising_edge(RESETNeg) AND RST='1' THEN --RESET# pulse < tRP READY_in <= '0'; R := '0'; E := '1'; END IF; IF RESETNeg='1' AND ( R='0' OR (R='1' AND READY='1')) THEN current_state <= next_state; READY_in <= '0'; E := '0'; R := '0'; reseted <= '1'; ELSIF (R='0' AND RESETNeg='0' AND RST='0')OR (R='1' AND RESETNeg='0' AND RST='0' AND READY='0')OR (R='1' AND RESETNeg='1' AND RST='0' AND READY='0')OR (R='1' AND RESETNeg='1' AND RST='1' AND READY='0') THEN --no state transition while RESET# low current_state <= RESET; --reset start reseted <= '0'; END IF; ELSE current_state <= RESET; -- reset reseted <= '0'; E := '0'; R := '0'; END IF; END PROCESS StateTransition; --------------------------------------------------------------------------- --Glitch Protection: Inertial Delay does not propagate pulses <5ns --------------------------------------------------------------------------- gWE_n <= WENeg AFTER 3 ns; gCE_n <= CENeg AFTER 3 ns; gOE_n <= OENeg AFTER 3 ns; --latch address on rising edge and data on falling edge of write write_dc: PROCESS (gWE_n, gCE_n, gOE_n, RESETNeg, reseted) BEGIN IF RESETNeg /= '0' AND reseted = '1' THEN IF (gWE_n = '0') AND (gCE_n = '0') AND (gOE_n = '1') THEN write <= '1'; ELSIF (gWE_n = '1' OR gCE_n = '1') AND gOE_n = '1' THEN write <= '0'; ELSE write <= 'X'; END IF; END IF; IF ((gWE_n = '1') AND (gCE_n = '0') AND (gOE_n = '0') )THEN read <= '1'; ELSE read <= '0'; END IF; END PROCESS write_dc; --------------------------------------------------------------------------- --Process that reports warning when changes on signals WE#, CE#, OE# are --discarded --------------------------------------------------------------------------- PulseWatch : PROCESS (WENeg, CENeg, OENeg, gWE_n, gCE_n, gOE_n) BEGIN IF NOW > 0 ns THEN IF ((WENeg'EVENT AND (WENeg = '1') AND(gWE_n ='1')) AND CENeg = '0') OR ((OENeg'EVENT AND (OENeg = '1') AND(gOE_n ='1'))AND CENeg = '0') OR (CENeg'EVENT AND (CENeg = '1') AND(gCE_n ='1')) THEN ASSERT false REPORT "Glitch detected on write control signals" SEVERITY warning; END IF; END IF; END PROCESS PulseWatch; ---------------------------------------------------------------------------- -- Device internal operation control ---------------------------------------------------------------------------- -- Protection Bit Program ProtPROG : PROCESS(PBPROG_in) BEGIN IF PBPROG_in = '0' THEN PBPROG_out <= '0'; ELSE PBPROG_out <= '1' AFTER (tdevice_PROTP - 1 ns); END IF; END PROCESS ProtPROG; -- Protection Bit Erase ProtERS : PROCESS(PBERASE_in) VARIABLE EraseSIM : TIME; BEGIN IF PBERASE_in = '0' THEN PBERASE_out <= '0'; ELSE PBERASE_out <= '1' AFTER (tdevice_PROTE - 1 ns); END IF; END PROCESS ProtERS; -- Password Unlock UNL : PROCESS(UNLOCKDONE_in) BEGIN IF UNLOCKDONE_in = '0' THEN UNLOCKDONE_out <= '0'; ELSE UNLOCKDONE_out <= '1' AFTER (tdevice_UNLOCK - 1 ns); END IF; END PROCESS UNL; -- Password Program PassP : PROCESS(PASSPDONE_in) BEGIN IF PASSPDONE_in = '0' THEN PASSPDONE_out <= '0'; ELSE PASSPDONE_out <= '1' AFTER (tdevice_POW - 1 ns); END IF; END PROCESS PassP; --------------------------------------------------------------------------- --Latch address on falling edge of WE# or CE# what ever comes later --Latches data on rising edge of WE# or CE# what ever comes first -- also Write cycle decode --------------------------------------------------------------------------- BusCycleDecode : PROCESS(A, Din, write, WENeg, CENeg, OENeg, BYTENeg, reseted, read) VARIABLE A_tmp : NATURAL RANGE 0 TO 16#7FFF#; VARIABLE BA_tmp : NATURAL RANGE 0 TO 7; VARIABLE SA_tmp : NATURAL RANGE 0 TO SecNum; VARIABLE A_tmp1 : NATURAL RANGE 0 TO SecSize; VARIABLE A_tmp2 : NATURAL RANGE 0 TO SecSize; VARIABLE CE : std_logic; VARIABLE i : NATURAL; BEGIN IF (reseted= '1') AND ((falling_edge(WENeg) AND CENeg='0' AND OENeg = '1' ) OR (falling_edge(CENeg) AND WENeg /= OENeg ) OR (falling_edge(OENeg) AND WENeg='1' AND CENeg = '0' ) OR ((A'EVENT OR (Din(15)'EVENT AND BYTENeg='0') OR BYTENeg'EVENT ) AND WENeg = '1' AND CENeg = '0' AND OENeg = '0')) THEN A_tmp := to_nat( A(14 downto 0) ); A_tmp2 := to_nat( A(11 downto 0) ); SA_tmp:= to_nat( A(HiAddrBit downto 15)); BA_tmp := to_nat(A(20 downto 18)); IF (BYTENeg = '0') THEN IF Din(15) = '1' THEN A_tmp1 := to_nat( A(14 downto 0) & '1' ); ELSE A_tmp1 := to_nat( A(14 downto 0) & '0' ); END IF; ELSE A_tmp1 := to_nat( A(14 downto 0) & '0' ); END IF; ELSIF (reseted= '1') AND (rising_edge(WENeg) OR rising_edge(CENeg)) AND write = '1' THEN D_tmp0 <= to_nat(Din(7 downto 0)); IF BYTENeg = '1' THEN D_tmp1 <= to_nat(Din(15 downto 8)); END IF; END IF; IF (reseted= '1') AND (rising_edge(write) OR falling_edge(OENeg) OR falling_edge(CENeg) OR ((A'EVENT OR (Din(15)'EVENT AND BYTENeg = '0') OR BYTENeg'EVENT ) AND WENeg = '1' AND CENeg = '0' AND OENeg = '0' )) THEN SecAddr <= SA_tmp; Address <= A_tmp1; SubAddr <= A_tmp2; FOR i IN 0 TO SubSecNum LOOP IF A_tmp >= sssa(vs)(i) AND A_tmp <= ssea(vs)(i) THEN SubSect <= i; END IF; END LOOP; CASE BA_tmp IS WHEN 0 | 1 | 2 | 3 => BA <= 0; WHEN 4| 5 | 6 | 7 => BA <= 1; WHEN OTHERS => NULL; END CASE; CE := CENeg; Addr <= A_tmp; END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- Timing control for the Program Operations --------------------------------------------------------------------------- ProgTime :PROCESS(OTP_ACT, PSTART, BYTENeg, ESP_ACT, reseted, PSUSP, PRES) VARIABLE duration : time; VARIABLE elapsed : time; VARIABLE start : time; VARIABLE pob : time; VARIABLE pow : time; VARIABLE pou : time; BEGIN pob := tdevice_POB; pow := tdevice_POW; pou := tdevice_POU; IF LongTiming THEN pob := tdevice_POB; pow := tdevice_POW; pou := tdevice_POU; ELSE pob := (tdevice_POB)/1; pow := (tdevice_POW)/1; pou := (tdevice_POU)/1; END IF; IF rising_edge(reseted) THEN PDONE <= '1'; -- reset done, programing terminated ELSIF reseted = '1' THEN IF rising_edge(PSTART) AND PDONE='1' THEN IF((((SA /= VarSect AND (DYB(SA) = '0' AND PPB(GroupID(SA)) = '0') AND (Ers_queue(SA)='0' OR ESP_ACT='0'))OR (SA = VarSect AND SubSec_Prot(SSA) = '0' AND (DYB_SubSec(SSA) = '0' AND PPB_SubSec(SSA) = '0') AND (Ers_Sub_queue(SSA) = '0' OR ESP_ACT = '0'))) AND (OTP_ACT = '0'))OR (OTP_ACT = '1' AND SecAddr = 0 AND SSPB = '0' AND Address > 127 AND Address < 256)) THEN IF ULBYPASS = '1' THEN duration := pou;--tdevice_POW; ELSIF BYTENeg = '1' THEN duration := pow;--tdevice_POW; ELSE duration := pob;--tdevice_POB; END IF; elapsed := 0 ns; PDONE <= '0', '1' AFTER duration; start := NOW; ELSE PERR <= '1', '0' AFTER 1 us; END IF; ELSIF rising_edge(PSUSP) AND PDONE = '0' THEN elapsed := NOW - start; duration := duration - elapsed; PDONE <= '0'; ELSIF rising_edge(PRES) AND PDONE = '0' THEN start := NOW; PDONE <= '0', '1' AFTER duration; END IF; END IF; END PROCESS ProgTime; --------------------------------------------------------------------------- -- Timing control for the Erase Operations --------------------------------------------------------------------------- ErsTime :PROCESS(ESTART, ESUSP, ERES, Ers_Queue, Ers_Sub_Queue, reseted) VARIABLE cnt : NATURAL RANGE 0 TO SecNum+2*SubSecNum+1 := 0; VARIABLE elapsed : time; VARIABLE duration : time; VARIABLE start : time; VARIABLE seo : time; BEGIN IF LongTiming THEN seo := tdevice_SEO; ELSE seo := (tdevice_SEO)/1000; END IF; IF rising_edge(reseted) THEN EDONE <= '1'; -- reset done, ERASE terminated ELSIF reseted = '1' THEN IF rising_edge(ESTART) AND EDONE = '1' THEN cnt := 0; FOR i IN Ers_Queue'RANGE LOOP IF i = VarSect THEN FOR j IN 0 TO SubSecNum LOOP IF Ers_Sub_Queue(j) = '1' AND SubSec_Prot(j) /= '1' AND (DYB_SubSec(j) = '0' AND PPB_SubSec(j) = '0') THEN cnt := cnt + 1; END IF; END LOOP; ELSIF Ers_Queue(i) = '1' AND (DYB(i) = '0' AND PPB(GroupID(i)) = '0') THEN cnt := cnt +1; END IF; END LOOP; IF cnt > 0 THEN elapsed := 0 ns; duration := cnt* seo; EDONE <= '0', '1' AFTER duration; start := NOW; ELSE EERR <= '1', '0' AFTER 100 us; END IF; ELSIF rising_edge(ESUSP) AND EDONE = '0' THEN elapsed := NOW - start; duration := duration - elapsed; EDONE <= '0'; ELSIF rising_edge(ERES) AND EDONE = '0' THEN start := NOW; EDONE <= '0', '1' AFTER duration; END IF; END IF; END PROCESS; --------------------------------------------------------------------------- -- Main Behavior Process -- combinational process for next state generation --------------------------------------------------------------------------- StateGen :PROCESS(write, Addr, D_tmp0, ULBYPASS, PDONE, EDONE, HANG, CTMOUT, BankAutosel, BankBypassLock, SecAddr, START_T1, reseted, READY, PERR, EERR, UNLOCKDONE_out) VARIABLE PATTERN_1 : boolean := FALSE; VARIABLE PATTERN_2 : boolean := FALSE; VARIABLE A_PAT_1 : boolean := FALSE; --DATA High Byte VARIABLE DataHi : NATURAL RANGE 0 TO MaxData := 0; --DATA Low Byte VARIABLE DataLo : NATURAL RANGE 0 TO MaxData := 0; BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- IF falling_edge(write) THEN DataLo := D_tmp0; PATTERN_1 := (Addr = 16#555#) AND (DataLo = 16#AA#); PATTERN_2 := (Addr = 16#2AA#) AND (DataLo = 16#55#); A_PAT_1 := ((Addr = 16#555#) AND (ULBYPASS = '0')) OR (ULBYPASS = '1'); END IF; IF reseted /= '1' THEN next_state <= current_state; ELSE CASE current_state IS WHEN RESET => IF falling_edge(write) THEN IF (PATTERN_1)THEN next_state <= Z001; ELSIF ((Addr=16#55#) AND (DataLo=16#98#))THEN next_state <= CFI; ELSE next_state <= RESET; END IF; END IF; WHEN Z001 => IF falling_edge(write) THEN IF (PATTERN_2) THEN next_state <= PREL_SETBWB; ELSE next_state <= RESET; END IF; END IF; WHEN CFI => IF falling_edge(write) THEN IF (DataLo=16#F0#) THEN next_state <= RESET; ELSE next_state <= CFI; END IF; END IF; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo=16#20#)) THEN next_state <= PREL_ULBYPASS; ELSIF (A_PAT_1 AND (DataLo=16#90#)) THEN next_state <= AS; ELSIF (A_PAT_1 AND (DataLo=16#A0#)) THEN next_state <= A0SEEN; ELSIF (A_PAT_1 AND (DataLo=16#88#)) THEN next_state <= OTP; ELSIF (A_PAT_1 AND (DataLo=16#80#)) THEN next_state <= C8; ELSIF (A_PAT_1 AND (DataLo = 16#38#)) AND PPMLB /= '1' THEN next_state <= PASSPROG_PREL; ELSIF (A_PAT_1 AND (DataLo = 16#C8#)) THEN next_state <= PASSVERIFY; ELSIF (A_PAT_1 AND (DataLo = 16#28#)) THEN next_state <= PASSUNLOCK0; ELSIF (A_PAT_1 AND (DataLo = 16#60#)) THEN next_state <= PROTBIT_PREL; ELSIF (A_PAT_1 AND (DataLo = 16#58#)) THEN next_state <= PPBDYB; ELSIF (A_PAT_1 AND (DataLo = 16#48#)) THEN next_state <= DYBWE; ELSIF (A_PAT_1 AND (DataLo = 16#78#)) THEN next_state <= RESET; ELSE next_state <= RESET; END IF; END IF; WHEN PREL_ULBYPASS => IF falling_edge(write) THEN IF (DataLo=16#90#) THEN next_state <= PREL_ULBYPASS_RESET; ELSIF (DataLo = 16#A0#) THEN next_state <= A0SEEN; ELSIF (DataLo = 16#98#) THEN next_state <= UBP_CFI; ELSIF (DataLo = 16#80#) THEN next_state <= C8_PREL; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; WHEN PREL_ULBYPASS_RESET => IF falling_edge(write) THEN IF (DataLo = 16#00#) THEN next_state <= RESET; ELSE next_state <= PREL_ULBYPASS; END IF; END IF; WHEN UBP_CFI => IF falling_edge(WRITE) AND (DataLo = 16#F0#) THEN next_state <= PREL_ULBYPASS; END IF; WHEN AS => IF falling_edge(write) THEN IF (DataLo = 16#F0#) THEN next_state <= RESET; ELSIF ((Addr=16#55#) AND (DataLo=16#98#)) THEN next_state <= AS_CFI; ELSE next_state <= AS; END IF; END IF; WHEN AS_CFI => IF falling_edge(write) THEN IF (DataLo=16#F0#) THEN next_state <= AS; ELSE next_state <= AS_CFI; END IF; END IF; WHEN A0SEEN => IF falling_edge(write) THEN 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 OTP => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= OTP_Z001; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= OTP_PREL; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_PREL => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#90#))THEN next_state <= OTP_EXIT; ELSIF (A_PAT_1 AND (DataLo = 16#A0#) AND (PSP_ACT = '0') AND (ESP_ACT = '0')) THEN next_state <= OTP_A0SEEN; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_EXIT => IF falling_edge(write) THEN IF DataLo=16#00# THEN IF PSP_ACT = '1' THEN next_state <= PSP; ELSIF ESP_ACT = '1' THEN next_state <= ESP; ELSE next_state <= RESET; END IF; ELSE next_state <= OTP; END IF; END IF; WHEN OTP_A0SEEN => IF falling_edge(write) THEN next_state <= PGMS; --set OTP ELSE next_state <= OTP_A0SEEN; END IF; WHEN C8 => IF falling_edge(write) THEN IF PATTERN_1 THEN next_state <= C8_Z001; ELSE next_state <= RESET; END IF; END IF; WHEN C8_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= C8_PREL; ELSE next_state <= RESET; END IF; END IF; WHEN C8_PREL => IF falling_edge(write) THEN IF (A_PAT_1 OR ULBYPASS = '1') AND DataLo = 16#10# THEN next_state <= ERS; ELSIF DataLo = 16#30# THEN next_state <= SERS; ELSE next_state <= RESET; END IF; END IF; WHEN ERS => IF rising_edge(EDONE) OR falling_edge(EERR) THEN IF ULBYPASS = '1' THEN next_state <= PREL_ULBYPASS; ELSE next_state <= RESET; END IF; END IF; WHEN SERS => IF CTMOUT = '1' THEN next_state <= SERS_EXEC; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN IF BankErase(BA) = '1' THEN next_state <= ESP; -- ESP according to datasheet ELSE next_state <= SERS; END IF; ELSIF (DataLo = 16#30#) THEN next_state <= SERS; ELSE next_state <= RESET; END IF; END IF; WHEN ESPS => IF (START_T1 = '1') THEN next_state <= ESP; END IF; WHEN SERS_EXEC => IF rising_edge(EDONE) OR falling_edge(EERR) THEN next_state <= RESET; ELSIF EERR /= '1' THEN IF falling_edge(write) THEN IF DataLo=16#B0# AND BankErase(BA) = '1' THEN next_state <= ESPS; END IF; END IF; END IF; WHEN ESP => IF falling_edge(write) THEN IF DataLo = 16#30# AND BankErase(BA) = '1' THEN next_state <= SERS_EXEC; ELSE IF PATTERN_1 THEN next_state <= ESP_Z001; ELSIF Addr = 16#55# AND DataLo = 16#98# THEN next_state <= ESP_CFI; END IF; END IF; END IF; WHEN ESP_ULBYPASS => IF falling_edge(write) THEN IF (DataLo=16#A0#) THEN next_state <= ESP_A0SEEN; ELSIF (DataLo=16#90#) THEN next_state <= ESP_ULBYPASS_RESET; END IF; END IF; WHEN ESP_ULBYPASS_RESET => IF falling_edge(write) THEN IF (DataLo=16#00#) THEN next_state <= ESP; ELSE next_state <= ESP_ULBYPASS; END IF; END IF; WHEN ESP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= ESP_SETBWB; ELSE next_state <= ESP; END IF; END IF; WHEN ESP_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo=16#90#)) THEN next_state <= ESP_AS; ELSIF A_PAT_1 AND DataLo = 16#A0# THEN next_state <= ESP_A0SEEN; ELSIF (A_PAT_1 AND (DataLo=16#20#)) THEN next_state <= ESP_ULBYPASS; ELSIF (A_PAT_1 AND (DataLo=16#88#)) THEN next_state <= OTP; ELSE next_state <= ESP; END IF; END IF; WHEN ESP_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= ESP; ELSE next_state <= ESP_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 ESP_AS => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN -- resret ULBYPASS next_state <= ESP; ELSIF ((Addr=16#55#) AND (DataLo=16#98#)) THEN next_state <= ESP_AS_CFI; 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 PGMS => IF rising_edge(PDONE) OR falling_edge(PERR) THEN IF ESP_ACT = '1' THEN IF ULBYPASS = '1' THEN next_state <= ESP_ULBYPASS; ELSE next_state <= ESP; END IF; ELSIF ULBYPASS = '1' THEN next_state <= PREL_ULBYPASS; ELSIF OTP_ACT = '1' THEN next_state <= OTP; ELSE next_state <= RESET; END IF; ELSIF falling_edge(write) AND PERR /= '1' THEN IF DataLo = 16#B0# AND BankProg(BA) = '1' THEN next_state <= PSPS; END IF; END IF; WHEN PSPS => IF (START_T1 = '1') THEN next_state <= PSP; END IF; WHEN PSP => IF falling_edge(write) THEN IF DataLo = 16#30# AND BankProg(BA) = '1' THEN next_state <= PGMS; ELSIF Addr = 16#55# AND DataLo = 16#98# THEN next_state <= PSP_CFI; ELSIF PATTERN_1 THEN next_state <= PSP_Z001; END IF; END IF; WHEN PSP_CFI => IF falling_edge(write) THEN IF Addr = 16#55# AND DataLo = 16#98# THEN null; ELSIF DataLo =16#F0# THEN next_state <= PSP; END IF; END IF; WHEN PSP_Z001 => IF falling_edge(write) THEN IF PATTERN_2 THEN next_state <= PSP_PREL; ELSE next_state <= PSP; END IF; END IF; WHEN PSP_PREL => IF falling_edge(write) THEN IF A_PAT_1 AND DataLo = 16#90# THEN next_state <= PSP_AS; ELSIF A_PAT_1 AND DataLo =16#88# THEN next_state <= OTP;--set PS ELSIF A_PAT_1 AND DataLo = 16#58# THEN next_state <= PPBDYB; ELSE next_state <= PSP; END IF; END IF; WHEN PSP_AS => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN -- reset ULBYPASS next_state <= PSP; ELSIF ((Addr=16#55#) AND (DataLo=16#98#)) THEN next_state <= PSP_AS_CFI; END IF; END IF; WHEN PSP_AS_CFI => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN next_state <= PSP_AS; ELSE next_state <= PSP_AS_CFI; END IF; END IF; WHEN PASSPROG_PREL => IF falling_edge(WRITE) THEN next_state <= PASSPROG; END IF; WHEN PASSPROG => IF falling_edge(WRITE) AND PASSPDONE_out = '1' AND DataLo = 16#F0# THEN next_state <= RESET; END IF; WHEN PASSVERIFY => IF falling_edge(WRITE) AND DataLo = 16#F0# THEN next_state <= RESET; END IF; WHEN PASSUNLOCK0 => IF rising_edge(UNLOCKDONE_out) THEN next_state <= PASSUNLOCK1; END IF; WHEN PASSUNLOCK1 => IF rising_edge(UNLOCKDONE_out) THEN next_state <= PASSUNLOCK2; END IF; WHEN PASSUNLOCK2 => IF rising_edge(UNLOCKDONE_out) THEN next_state <= PASSUNLOCK3; END IF; WHEN PASSUNLOCK3 => IF rising_edge(UNLOCKDONE_out) THEN IF BYTENeg = '1' THEN next_state <= RESET; ELSE next_state <= PASSUNLOCK4; END IF; END IF; WHEN PASSUNLOCK4 => IF rising_edge(UNLOCKDONE_out) THEN next_state <= PASSUNLOCK5; END IF; WHEN PASSUNLOCK5 => IF rising_edge(UNLOCKDONE_out) THEN next_state <= PASSUNLOCK6; END IF; WHEN PASSUNLOCK6 => IF rising_edge(UNLOCKDONE_out) THEN next_state <= PASSUNLOCK7; END IF; WHEN PASSUNLOCK7 => IF rising_edge(UNLOCKDONE_out) THEN next_state <= RESET; END IF; WHEN PROTBIT_PREL => IF falling_edge(WRITE) THEN IF DataLo = 16#68# AND (Addr mod 16#100# = WP) THEN next_state <= PPB_PROGRAM; ELSIF DataLo = 16#60# AND (Addr mod 16#100# = WP) THEN next_state <= PPB_ERASE; ELSIF DataLo = 16#68# AND (Addr mod 16#100# = PL) THEN next_state <= PPMLB_PROGRAM; ELSIF DataLo = 16#68# AND (Addr mod 16#100# = SL) THEN next_state <= SPMLB_PROGRAM; ELSIF DataLo = 16#68# AND (Addr mod 16#100# = OW) THEN next_state <= SSPB_PROGRAM; ELSIF DataLo = 16#48# AND (Addr mod 16#100# = PL) THEN next_state <= PPMLB_VERIFY; ELSIF DataLo = 16#48# AND (Addr mod 16#100# = SL) THEN next_state <= SPMLB_VERIFY; ELSIF DataLo = 16#48# AND (Addr mod 16#100# = OW) THEN next_state <= SSPB_VERIFY; ELSE next_state <= RESET; END IF; END IF; WHEN PPBDYB => IF falling_edge(WRITE) AND DataLo = 16#F0# THEN IF PSP_ACT = '1' THEN next_state <= PSP; ELSE next_state <= RESET; END IF; END IF; WHEN DYBWE => IF falling_edge(WRITE) THEN next_state <= RESET; END IF; WHEN PPB_PROGRAM => IF falling_edge(WRITE) AND PBPROG_out = '1' AND DataLo = 16#48# AND ( Addr mod 16#100# = WP ) THEN next_state <= PPB_VERIFY; END IF; WHEN PPB_VERIFY => IF falling_edge(WRITE) THEN IF DataLo = 16#F0# THEN next_state <= RESET; END IF; END IF; WHEN PPB_ERASE => IF falling_edge(WRITE) AND PBERASE_out = '1' AND DataLo = 16#40# AND ( Addr mod 16#100# = WP ) THEN next_state <= PPB_VERIFY; END IF; WHEN PPMLB_PROGRAM => IF falling_edge(WRITE) AND PBPROG_out = '1' AND DataLo = 16#48# AND ( Addr mod 16#100# = PL ) THEN next_state <= PPMLB_VERIFY; END IF; WHEN SPMLB_PROGRAM => IF falling_edge(WRITE) AND PBPROG_out = '1' AND DataLo = 16#48# AND ( Addr mod 16#100# = SL ) THEN next_state <= SPMLB_VERIFY; END IF; WHEN SSPB_PROGRAM => IF falling_edge(WRITE) AND PBPROG_out = '1' AND DataLo = 16#48# AND ( Addr mod 16#100# = OW ) THEN next_state <= SSPB_VERIFY; END IF; WHEN PPMLB_VERIFY => IF falling_edge(WRITE) AND DataLo = 16#F0# THEN next_state <= RESET; END IF; WHEN SPMLB_VERIFY => IF falling_edge(WRITE) AND DataLo = 16#F0# THEN next_state <= RESET; END IF; WHEN SSPB_VERIFY => IF falling_edge(WRITE) AND DataLo = 16#F0# THEN next_state <= RESET; END IF; END CASE; END IF; END PROCESS StateGen; WP_CTRL: PROCESS(WPNeg) BEGIN --Hardware Write Protection IF falling_edge(WPNeg) THEN SubSec_Prot(ProtSecNum_1) := '1'; SubSec_Prot(ProtSecNum_2) := '1'; ELSIF rising_edge(WPNeg) THEN SubSec_Prot(ProtSecNum_1) := '0'; SubSec_Prot(ProtSecNum_2) := '0'; END IF; END PROCESS WP_CTRL; --------------------------------------------------------------------------- --FSM Output generation and general funcionality --------------------------------------------------------------------------- Functional : PROCESS(write, read, D_tmp0, D_tmp1, Address, SecAddr, Addr, PDONE, EDONE, HANG, START_T1, CTMOUT, RST, reseted, BYTENeg, READY, current_state, PBPROG_out, gOE_n, PBERASE_out, PASSPDONE_out, UNLOCKDONE_out) --Program TYPE WDataType IS ARRAY ( 0 TO 1) OF--n INTEGER RANGE -1 TO MaxData; TYPE WAddrType IS ARRAY ( 0 TO 1) OF INTEGER RANGE -1 TO SecSize;--n VARIABLE WData : WDataType:=(OTHERS=>0);--n VARIABLE WAddr : WAddrType:=(OTHERS=>-1);--n VARIABLE PATTERN_1 : boolean := FALSE; VARIABLE PATTERN_2 : boolean := FALSE; VARIABLE A_PAT_1 : boolean := FALSE; VARIABLE oe : boolean := FALSE; --Status reg. VARIABLE Status : std_logic_vector(15 downto 0) := (OTHERS=>'0'); VARIABLE PGMS_FLAG : PgmsTargetType; VARIABLE old_bit : std_logic_vector(7 downto 0); VARIABLE new_bit : std_logic_vector(7 downto 0); VARIABLE old_int : INTEGER RANGE -1 to MaxData; VARIABLE new_int : INTEGER RANGE -1 to MaxData; VARIABLE wr_cnt : NATURAL RANGE 0 TO 31; --DATA High Byte VARIABLE DataHi : NATURAL RANGE 0 TO MaxData := 0; --DATA Low Byte VARIABLE DataLo : NATURAL RANGE 0 TO MaxData := 0; VARIABLE temp : std_logic_vector(7 downto 0); VARIABLE SecSiAddr : NATURAL RANGE 0 TO SecSiSize := 0; VARIABLE PR_FLAG : BOOLEAN := FALSE; VARIABLE ER_FLAG : BOOLEAN := FALSE; VARIABLE WAddrPass : NATURAL RANGE 0 TO 7; VARIABLE WDataPassLo : std_logic_vector(7 downto 0); VARIABLE WDataPassHi : std_logic_vector(7 downto 0); VARIABLE UnlockPass : BOOLEAN; VARIABLE PBSecAddr : NATURAL RANGE 0 TO SecNum; VARIABLE PBSubSecAddr: NATURAL RANGE 0 TO SubSecNum; VARIABLE ASAddr : NATURAL; BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- IF falling_edge(write) THEN DataLo := D_tmp0; DataHi := D_tmp1; PATTERN_1 := (Addr = 16#555#) AND (DataLo = 16#AA#) ; PATTERN_2 := (Addr = 16#2AA#) AND (DataLo = 16#55#) ; A_PAT_1 := ((Addr = 16#555#)AND (ULBYPASS = '0')) OR (ULBYPASS = '1'); END IF; IF falling_edge(RST) AND RESETNeg = '0' THEN IF PPMLB = '1' THEN PPBLock := '1'; ELSE PPBLock := '0'; END IF; Ers_Queue <= (OTHERS => '0'); Ers_Sub_Queue <= (OTHERS => '0'); DYB := (OTHERS => '0'); DYB_SubSec := (OTHERS => '0'); START_T1_in <= '0'; END IF; oe:=rising_edge(read)OR(read = '1' AND(Address'EVENT OR SecAddr'EVENT)); IF reseted = '1' THEN CASE current_state IS WHEN RESET => BankProg := "00"; BankBypassLock <= "00"; BankAutosel <= "00"; BankErase <= "00"; BankEraseExec <= "00"; OTP_ACT <= '0'; ESP_ACT <= '0'; PSP_ACT <= '0'; ULBYPASS <= '0'; CTMOUT_in <= '0'; IF oe THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; --ready signal active RY_zd <= '1'; WHEN Z001 => null; WHEN PREL_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#20#)) THEN BankBypassLock(BA) <= '1'; ULBYPASS <= '1'; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN BankAutosel(BA) <= '1'; ULBYPASS <= '0'; ELSIF (A_PAT_1 AND (DataLo = 16#88#)) THEN ULBYPASS <= '0'; OTP_ACT <= '1'; ELSIF (A_PAT_1 AND DataLo = 16#78#) THEN PPBLock := '1'; END IF; END IF; WHEN PREL_ULBYPASS => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#90#)) THEN ULBYPASS <= '0'; END IF; ELSIF (oe AND BankBypassLock(BA) = '0') THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; --ready signal active RY_zd <= '1'; WHEN ESP_ULBYPASS => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#90#)) THEN ULBYPASS <= '0'; END IF; ELSIF (oe AND BankBypassLock(BA) = '0') THEN ----------------------------------------------------------- --read ----------------------------------------------------------- IF(SecAddr /= VarSect AND Ers_Queue(SecAddr) /= '1') OR (SecAddr = VarSect AND Ers_Sub_Queue(SubSect) /= '1') THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; ELSE ------------------------------------------------------- --read status ------------------------------------------------------- Status(7) := '1'; -- Status(6) No toggle Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd <= Status; END IF; END IF; --ready signal active RY_zd <= '1'; WHEN PREL_ULBYPASS_RESET | ESP_ULBYPASS_RESET => IF falling_edge(write) THEN IF (DataLo=16#00#) THEN BankBypassLock <= "00"; ULBYPASS <= '0'; END IF; END IF; WHEN A0SEEN => IF falling_edge(write) THEN IF (BankBypassLock(BA)='1' AND ULBYPASS = '1') OR ULBYPASS = '0' THEN BankProg(BA) := '1'; PSTART <= '1', '0' AFTER 1 ns; PSUSP <= '0'; PRES <= '0'; PGMS_FLAG := MEMORY; PR_FLAG := FALSE; WData(0) := -1; WData(1) := -1; IF Viol = '0' THEN WData(0) := DataLo; WData(1) := DataHi; END IF; WAddr(0) := Address; SA <= SecAddr; SSA <= SubSect; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); IF BYTENeg = '1' THEN WAddr(1) := WAddr(0) + 1; ELSE WAddr(1) := -1; END IF; END IF; END IF; WHEN OTP => OTP_ACT <= '1'; IF oe THEN --read SecSi Sector Region SecSiAddr := Address MOD (SecSiSize +1); generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => SecSiAddr, BYTENeg => BYTENeg, SecSi_Acc => 1); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; --ready signal active RY_zd <= '1'; WHEN OTP_Z001 => null; WHEN OTP_PREL => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#90#))THEN ULBYPASS <= '0'; END IF; END IF; WHEN OTP_A0SEEN => IF falling_edge(write) THEN OTP_ACT <= '1'; BankProg(BA) := '1'; PSTART <= '1', '0' AFTER 1 ns; PSUSP <= '0'; PRES <= '0'; PGMS_FLAG := OTP; PR_FLAG := FALSE; WData(0) := -1; WData(1) := -1; IF Viol = '0' THEN WData(0) := DataLo; WData(1) := DataHi; END IF; WAddr(0) := Address; SA <= SecAddr; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); ASSERT SecAddr = 0 REPORT "Invalid sector Address in SecSi" SEVERITY warning; ASSERT Address < 256 REPORT "Invalid program address in SecSi region. " & "Address= " & to_int_str(Address) SEVERITY warning; ASSERT Address > 127 REPORT "Invalid program address in factory"& " SecSi region. " & "Address= " & to_int_str(Address) SEVERITY warning; IF BYTENeg = '1' THEN WAddr(1) := WAddr(0) + 1; ELSE WAddr(1) := -1; END IF; END IF; WHEN CFI | AS_CFI | ESP_CFI | ESP_AS_CFI | PSP_CFI | PSP_AS_CFI | UBP_CFI => IF oe THEN IF ((Addr >= 16#10# AND Addr <= 16#3C#) OR (Addr >= 16#40# AND Addr <= 16#50#) OR (Addr >= 16#57# AND Addr <= 16#5B#)) THEN DOut_zd(15 downto 0) <= to_slv(CFI_array(Addr),16); IF BYTENeg = '0' THEN DOut_zd(15 downto 8) <= (OTHERS=> 'Z'); END IF; IF BYTENeg = '0' AND NOT((Address mod 2) = 0)THEN DOut_zd(7 downto 0) <= (OTHERS=> 'Z'); END IF; ELSE ASSERT FALSE REPORT "Invalid CFI query address" SEVERITY warning; DOut_zd <= (OTHERS =>'Z'); END IF; END IF; WHEN C8 => IF falling_edge(write) THEN null; END IF; WHEN C8_Z001 => IF falling_edge(write) THEN null; END IF; WHEN C8_PREL => IF falling_edge(write) THEN IF (A_PAT_1 OR ULBYPASS = '1') AND DataLo = 16#10# THEN --Start Chip Erase ESTART <= '1', '0' AFTER 1 ns; ESUSP <= '0'; ERES <= '0'; Ers_Queue <= (OTHERS => '1'); Ers_Sub_Queue <= (OTHERS => '1'); Status := (OTHERS => '0'); ER_FLAG := FALSE; FOR i IN 0 TO SecNum LOOP IF (i /= VarSect) THEN IF (DYB(i) = '0' AND PPB(GroupID(i)) = '0') THEN BankEraseExec(BA) <= '1'; END IF; ELSE FOR i IN 0 TO SubSecNum LOOP IF (SubSec_Prot(i) = '0') AND (DYB_SubSec(i) = '0' AND PPB_SubSec(i) = '0') THEN BankEraseExec(BA) <= '1'; END IF; END LOOP; END IF; END LOOP; BankErase <= "11", BankEraseExec AFTER 100 us; ELSIF DataLo = 16#30# THEN --put selected sector to sec. ers. queue --start timeout Ers_Queue <= (OTHERS => '0'); Ers_Sub_Queue <= (OTHERS => '0'); ER_FLAG := FALSE; IF SecAddr = VarSect THEN Ers_Sub_Queue(SubSect) <= '1'; ELSE Ers_Queue(SecAddr) <= '1'; END IF; BankErase(BA)<= '1'; IF (SecAddr /= Varsect) AND (DYB(SecAddr) = '0' AND PPB(GroupID(SecAddr)) = '0') THEN BankEraseExec(BA) <= '1'; ELSIF (SecAddr = Varsect) AND SubSec_Prot(SubSect) = '0' AND DYB_SubSec(SubSect) = '0' AND PPB_SubSec(SubSect) = '0' THEN BankEraseExec(BA) <= '1'; END IF; CTMOUT_in <= '1'; END IF; END IF; WHEN ERS => IF oe THEN ----------------------------------------------------------- -- read status / embeded erase algorithm - Chip Erase ----------------------------------------------------------- Status(7) := '0'; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; Status(2) := NOT Status(2); --toggle DOut_zd <= Status; END IF; IF EERR /= '1' THEN IF NOT ER_FLAG THEN ER_FLAG:= TRUE; FOR i IN 0 TO SecNum LOOP IF i = VarSect THEN FOR j IN 0 TO SubSecNum LOOP IF SubSec_Prot(j) /= '1' AND (DYB_SubSec(j) = '0' AND PPB_SubSec(j) = '0') THEN Mem(i)(2*sssa(vs)(j) TO 2*ssea(vs)(j)+1):= (OTHERS => -1); END IF; END LOOP; ELSIF (DYB(i) = '0' AND PPB(GroupID(i)) = '0') THEN Mem(i):= (OTHERS => -1); END IF; END LOOP; END IF; IF EDONE = '1' THEN ER_FLAG:= FALSE; FOR i IN 0 TO SecNum LOOP IF i = VarSect THEN FOR j IN 0 TO SubSecNum LOOP IF SubSec_prot(j) /= '1' AND (DYB_SubSec(j) = '0' AND PPB_SubSec(j) = '0') THEN Mem(i)(2*sssa(vs)(j) TO 2*ssea(vs)(j)+1):= (OTHERS => MaxData); END IF; END LOOP; ELSIF (DYB(i) = '0' AND PPB(GroupID(i)) = '0') THEN Mem(i):= (OTHERS => MaxData); END IF; END LOOP; Ers_Queue <= (OTHERS => '0'); Ers_Sub_Queue <= (OTHERS => '0'); END IF; END IF; -- busy signal active RY_zd <= '0'; WHEN SERS => IF CTMOUT = '1' THEN CTMOUT_in <= '0'; START_T1_in <= '0'; ESTART <= '1', '0' AFTER 1 ns; ESUSP <= '0'; ERES <= '0'; FOR i IN 0 TO BankNum LOOP IF BankEraseExec(i)='0' AND BankErase(i) = '1' THEN BankErase(i) <= '0' AFTER 100 us; END IF; END LOOP; ELSIF falling_edge(write) THEN IF (DataLo = 16#B0#) THEN --need to start erase process prior to suspend IF BankErase(BA) = '1' THEN ESTART <= '1', '0' AFTER 1 ns; ERES <= '0'; -- CTMOUT reset CTMOUT_in <= '0'; ESUSP <= '1' AFTER 1 ns, '0' AFTER 2 ns; END IF; ELSIF (DataLo = 16#30#) THEN CTMOUT_in <= '0', '1' AFTER 1 ns; IF SecAddr = VarSect THEN Ers_Sub_Queue(SubSect) <= '1'; ELSE Ers_Queue(SecAddr) <= '1'; END IF; BankErase(BA)<= '1'; IF (SecAddr /= VarSect) AND (DYB(SecAddr) = '0' AND PPB(GroupID(SecAddr)) = '0') THEN BankEraseExec(BA) <= '1'; ELSIF (SecAddr = VarSect) AND SubSec_Prot(SubSect) = '0' AND DYB_SubSec(SubSect) = '0' AND PPB_SubSec(SubSect) = '0' THEN BankEraseExec(BA) <= '1'; END IF; ELSE CTMOUT_in <= '0'; END IF; ELSIF oe THEN IF BankErase(BA) = '1' THEN ----------------------------------------------------- --read status - sector erase timeout ----------------------------------------------------- Status(7) := '1'; Status(3) := '0'; DOut_zd <= Status; ELSE generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; END IF; --ready signal active RY_zd <= '0'; WHEN ESPS => IF (START_T1 = '1') THEN ESP_ACT <= '1'; START_T1_in <= '0'; ELSIF oe THEN IF BankErase(BA) = '1' THEN ----------------------------------------------------------- --read status / erase suspend timeout - stil erasing ----------------------------------------------------------- IF((SecAddr = VarSect)AND(Ers_Sub_Queue(SubSect)='1')) OR ((SecAddr /= VarSect)AND (Ers_Queue(SecAddr)='1')) THEN Status(7) := '0'; Status(2) := NOT Status(2); --toggle ELSE Status(7) := '1'; END IF; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; DOut_zd <= Status; ELSE generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; END IF; --busy signal active RY_zd <= '0'; WHEN SERS_EXEC => IF oe THEN IF BankErase(BA) = '1' THEN ----------------------------------------------------------- --read status Erase Busy ----------------------------------------------------------- IF((SecAddr = VarSect)AND(Ers_Sub_Queue(SubSect)= '1')) OR ((SecAddr /= VarSect) AND (Ers_Queue(SecAddr) = '1')) THEN Status(7) := '0'; Status(2) := NOT Status(2); --toggle ELSE Status(7) := '1'; END IF; Status(6) := NOT Status(6); --toggle Status(5) := '0'; Status(3) := '1'; DOut_zd <= Status; ELSE generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; END IF; IF EERR /= '1' THEN IF NOT ER_FLAG THEN ER_FLAG:= TRUE; FOR i IN Ers_Queue'RANGE LOOP IF i = VarSect THEN FOR j IN 0 TO SubSecNum LOOP IF Ers_Sub_Queue(j) = '1' AND SubSec_Prot(j) /= '1' AND (DYB_SubSec(j) = '0' AND PPB_SubSec(j) = '0') THEN Mem(i)(2*sssa(vs)(j) TO 2*ssea(vs)(j)+1):= (OTHERS => -1); END IF; END LOOP; ELSIF Ers_Queue(i) = '1' AND (DYB(i) = '0' AND PPB(GroupID(i)) = '0') THEN Mem(i) := (OTHERS => -1); END IF; END LOOP; END IF; IF EDONE = '1' THEN ER_FLAG:= FALSE; FOR i IN Ers_Queue'RANGE LOOP IF i = VarSect THEN FOR j IN 0 TO SubSecNum LOOP IF Ers_Sub_Queue(j) = '1' AND SubSec_Prot(j) /= '1' AND (DYB_SubSec(j) = '0' AND PPB_SubSec(j) = '0') THEN Mem(i)(2*sssa(vs)(j) TO 2*ssea(vs)(j)+1):= (OTHERS => MaxData); END IF; END LOOP; ELSIF Ers_Queue(i) = '1' AND (DYB(i) = '0' AND PPB(GroupID(i)) = '0') THEN Mem(i) := (OTHERS => MaxData); END IF; END LOOP; Ers_Queue <= (OTHERS => '0'); Ers_Sub_Queue <= (OTHERS => '0'); ELSIF falling_edge(write) THEN IF DataLo=16#B0# AND BankErase(BA) = '1' THEN START_T1_in <= '1'; ESUSP <= '1', '0' AFTER 1 ns; END IF; END IF; END IF; --busy signal active RY_zd <= '0'; WHEN ESP => ESP_ACT <= '1'; BankProg := "00"; IF falling_edge(write) THEN IF DataLo = 16#30# AND BankErase(BA) = '1' THEN --resume erase ERES <= '1', '0' AFTER 1 ns; ESP_ACT <= '0'; END IF; ELSIF oe THEN ----------------------------------------------------------- --read ----------------------------------------------------------- IF(SecAddr /= VarSect AND Ers_Queue(SecAddr) /= '1') OR (SecAddr = VarSect AND Ers_Sub_Queue(SubSect) /= '1') THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; ELSE ------------------------------------------------------- --read status ------------------------------------------------------- Status(7) := '1'; -- Status(6) No toggle Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd <= Status; END IF; END IF; --ready signal active RY_zd <= '1'; WHEN ESP_Z001 => null; WHEN ESP_SETBWB => IF falling_edge(write) THEN IF (A_PAT_1 AND (DataLo = 16#20#)) THEN BankBypassLock(BA) <= '1'; ULBYPASS <= '1'; ELSIF (A_PAT_1 AND (DataLo = 16#90#)) THEN BankAutosel(BA) <= '1'; ULBYPASS <= '0'; END IF; END IF; WHEN ESP_A0SEEN => IF falling_edge(write) THEN IF (BankBypassLock(BA)='1' AND ULBYPASS = '1') OR ULBYPASS = '0' THEN BankProg(BA) := '1'; PSTART <= '1', '0' AFTER 1 ns; PSUSP <= '0'; PRES <= '0'; PGMS_FLAG := MEMORY; PR_FLAG := FALSE; WData(0) := -1; WData(1) := -1; IF Viol = '0' THEN WData(0) := DataLo; WData(1) := DataHi; END IF; WAddr(0) := Address; SA <= SecAddr; SSA <= SubSect; temp := to_slv(DataLo, 8); Status(7) := NOT temp(7); IF BYTENeg = '1' THEN WAddr(1) := WAddr(0) +1; ELSE WAddr(1) := -1; END IF; END IF; END IF; WHEN OTP_EXIT => IF falling_edge(write) THEN IF DataLo=16#00# THEN OTP_ACT <='0'; END IF; END IF; WHEN AS | ESP_AS | PSP_AS => IF falling_edge(write) THEN IF DataLo = 16#F0# THEN OTP_ACT <='0'; IF ESP_ACT = '1' OR PSP_ACT = '1' THEN ULBYPASS <= '0'; END IF; END IF; ELSIF oe THEN IF (BankAutosel(BA)='1') THEN ASAddr := Addr MOD 256; IF BYTENeg = '1' AND (ASAddr = 0 OR ASAddr = 2 OR ASAddr = 3) THEN DOut_zd(15 downto 8) <= to_slv(0,8); ELSIF BYTENeg = '1' AND ASAddr = 1 THEN DOut_zd(15 downto 8) <= to_slv(16#22#,8); ELSE DOut_zd(15 downto 8) <= "ZZZZZZZZ"; END IF; IF ASAddr = 0 THEN DOut_zd(7 downto 0) <= to_slv(16#01#,8); ELSIF ASAddr = 1 THEN IF TimingModel(16) = '1' THEN DOut_zd(7 downto 0) <= to_slv(16#5C#,8); ELSE DOut_zd(7 downto 0) <= to_slv(16#5F#,8); END IF; ELSIF ASAddr = 2 THEN DOut_zd(7 downto 1) <= to_slv(0,7); IF (SecAddr = VarSect) THEN DOut_zd(0) <= PPB_SubSec(SubSect); ELSE DOut_zd(0) <= PPB(GroupID(SecAddr)); END IF; ELSIF ASAddr = 3 THEN IF SSPB = '0' THEN DOut_zd(7 downto 0) <= to_slv(16#80#,8); ELSE DOut_zd(7 downto 0) <= to_slv(16#C0#,8); END IF; ELSE DOut_zd(7 downto 0) <= "ZZZZZZZZ"; END IF; ELSE IF ESP_ACT = '1' AND ((SecAddr /= VarSect AND Ers_Queue(SecAddr) = '1') OR (SecAddr = VarSect AND Ers_Sub_Queue(SubSect) = '1')) THEN --------------------------------------------------- --read status --------------------------------------------------- Status(7) := '1'; -- Status(6) No toggle Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd <= Status; ELSIF PSP_ACT = '1' AND (((SecAddr = VarSect) AND (SecAddr = SA) AND (SubSect = SSA)) OR ((SecAddr /= VarSect) AND (SecAddr = SA))) THEN --read program suspended sector --Invalid (not allowed) ASSERT false REPORT "Read from program suspended sector " & "is NOT allowed" SEVERITY warning; ELSE generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; END IF; END IF; WHEN PGMS => IF oe THEN IF ESP_ACT = '0' THEN IF BankProg(BA) = '1' THEN ----------------------------------------------------- --read status ----------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; --Status(2) no toggle Status(1) := '0'; DOut_zd <= Status; IF ((SecAddr = VarSect) AND (SecAddr = SA) AND (SubSect = SSA)) OR ((SecAddr /= VarSect) AND (SecAddr = SA)) OR OTP_ACT ='1' THEN DOut_zd(7) <= Status(7); ELSE DOut_zd(7) <= NOT Status(7); END IF; ELSE generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; ELSE IF BankProg(BA) /= '1' THEN IF (SecAddr /= VarSect AND Ers_Queue(SecAddr) /= '1') OR (SecAddr=VarSect AND Ers_Sub_Queue(SubSect) /='1') THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; ELSE --------------------------------------------------- --read status --------------------------------------------------- Status(7) := '1'; -- Status(6) No toggle Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd <= Status; END IF; ELSE ------------------------------------------------------ --read status ------------------------------------------------------ Status(6) := NOT Status(6); --toggle Status(5) := '0'; --Status(2) no toggle Status(1) := '0'; DOut_zd <= Status; IF ((SecAddr = VarSect)AND(SecAddr = SA) AND (SubSect = SSA)) OR ((SecAddr /= VarSect)AND (SecAddr = SA)) OR OTP_ACT ='1' THEN DOut_zd(7) <= Status(7); ELSE DOut_zd(7) <= NOT Status(7); END IF; END IF; END IF; END IF; IF PERR/='1' THEN IF NOT PR_FLAG THEN PR_FLAG:=TRUE; IF WAddr(1) < 0 THEN wr_cnt := 0; ELSE wr_cnt := 1; END IF; FOR i IN wr_cnt downto 0 LOOP new_int:= WData(i); IF WAddr(i) < 0 THEN old_int := -1; ELSIF PGMS_FLAG = MEMORY THEN --mem write old_int := Mem(SA)(WAddr(i)); ELSIF PGMS_FLAG = OTP THEN old_int := SecSi(WAddr(i)); END IF; IF new_int > -1 THEN new_bit := to_slv(new_int,8); IF (PGMS_FLAG = OTP OR PGMS_FLAG = MEMORY) AND (old_int>-1) THEN old_bit := to_slv(old_int,8); FOR j IN 0 TO 7 LOOP IF old_bit(j) = '0' THEN new_bit(j) := '0'; END IF; END LOOP; ELSE new_bit(0) := 'X'; END IF; IF new_bit(0)/='X' THEN new_int := to_nat(new_bit); WData(i) := new_int; ELSE WData(i) := -1; END IF; ELSE WData(i) := -1; END IF; END LOOP; FOR i IN wr_cnt downto 0 LOOP IF PGMS_FLAG = MEMORY THEN --mem write Mem(SA)(WAddr(i)) := -1; ELSIF PGMS_FLAG = OTP THEN SecSi(WAddr(i)) := -1; END IF; END LOOP; END IF; IF HANG /= '1' AND PDONE = '1' AND (NOT PERR'EVENT) THEN PR_FLAG :=FALSE; FOR i IN wr_cnt downto 0 LOOP IF WAddr(i) > -1 AND WData(i) > -1 THEN IF PGMS_FLAG = MEMORY THEN --mem write Mem(SA)(WAddr(i)) := WData(i); ELSIF PGMS_FLAG = OTP THEN --SecSi write SecSi(WAddr(i)) := WData(i); END IF; END IF; WData(i) := -1; END LOOP; ELSIF falling_edge(write) THEN IF DataLo = 16#B0# AND BankProg(BA) = '1' THEN START_T1_in <= '1'; END IF; END IF; END IF; --busy signal active RY_zd <= '0'; WHEN PSPS => PSUSP <= '1'; IF (START_T1 = '1') THEN START_T1_in <= '0'; ELSIF oe THEN ----------------------------------------------------------- --read status / stil programming ----------------------------------------------------------- IF ESP_ACT = '0' THEN IF BankProg(BA) = '1' THEN ----------------------------------------------------- --read status ----------------------------------------------------- Status(6) := NOT Status(6); --toggle Status(5) := '0'; --Status(2) no toggle Status(1) := '0'; DOut_zd <= Status; IF ((SecAddr = VarSect) AND (SecAddr = SA) AND (SubSect = SSA)) OR ((SecAddr /= VarSect) AND (SecAddr = SA)) OR OTP_ACT ='1' THEN DOut_zd(7) <= Status(7); ELSE DOut_zd(7) <= NOT Status(7); END IF; ELSE generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; ELSE IF BankProg(BA) /= '1' THEN IF (SecAddr /= VarSect AND Ers_Queue(SecAddr) /= '1') OR (SecAddr=VarSect AND Ers_Sub_Queue(SubSect) /='1') THEN generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; ELSE --------------------------------------------------- --read status --------------------------------------------------- Status(7) := '1'; -- Status(6) No toggle Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd <= Status; END IF; ELSE ------------------------------------------------------ --read status ------------------------------------------------------ Status(6) := NOT Status(6); --toggle Status(5) := '0'; --Status(2) no toggle Status(1) := '0'; DOut_zd <= Status; IF ((SecAddr = VarSect)AND(SecAddr = SA) AND (SubSect = SSA)) OR ((SecAddr /= VarSect)AND (SecAddr = SA)) OR OTP_ACT ='1' THEN DOut_zd(7) <= Status(7); ELSE DOut_zd(7) <= NOT Status(7); END IF; END IF; END IF; END IF; --busy signal active RY_zd <= '0'; WHEN PSP => PSUSP <= '0'; IF falling_edge(write) THEN IF DataLo = 16#30# AND BankProg(BA) = '1' THEN PRES <= '1', '0' AFTER 1 ns; PSP_ACT <= '0'; END IF; ELSIF oe THEN ----------------------------------------------------------- --read - program suspend ----------------------------------------------------------- IF(((SecAddr = VarSect) AND (SecAddr = SA) AND (SubSect = SSA)) OR ((SecAddr /= VarSect) AND (SecAddr = SA))) THEN --read program suspended sector --Invalid (not allowed) ASSERT false REPORT "Read from program suspended sector " & "is NOT allowed" SEVERITY warning; ELSIF ESP_ACT = '1' AND ((SecAddr /= VarSect AND Ers_Queue(SecAddr) = '1') OR (SecAddr = VarSect AND Ers_Sub_Queue(SubSect) = '1')) THEN ------------------------------------------------------- --read status ------------------------------------------------------- Status(7) := '1'; -- Status(6) No toggle Status(5) := '0'; Status(2) := NOT Status(2); --toggle DOut_zd <= Status; ELSE --read sector other than suspended. generate_out ( DOut_zd => DOut_zd_var, SecAddr => SecAddr, Address => Address, BYTENeg => BYTENeg, SecSi_Acc => 0); DOut_zd(15 downto 0) <= DOut_zd_var; END IF; END IF; --ready signal active RY_zd <= '1'; WHEN PSP_Z001 => null; WHEN PSP_PREL => IF falling_edge(write) THEN IF A_PAT_1 AND (DataLo =16#88# OR DataLo = 16#58# ) THEN PSP_ACT <= '1'; ELSIF A_PAT_1 AND DataLo = 16#90# THEN BankAutosel(BA) <= '1'; PSP_ACT <= '1'; END IF; END IF; WHEN PASSPROG_PREL => IF falling_edge(WRITE) THEN WAddrPASS := Address mod 8; WDataPassLo := to_slv(DataLo,8); WDataPassHi := to_slv(DataHi,8); PASSPDONE_in <= '0', '1' AFTER 1 ns; RY_zd <= '0'; END IF; WHEN PASSPROG => IF rising_edge(PASSPDONE_out) THEN Password(WAddrPASS) := WDataPassLo AND Password(WAddrPASS); IF BYTENeg = '1' THEN Password(WAddrPASS+1) := WDataPassHi AND Password(WAddrPASS+1); END IF; RY_zd <= '1'; END IF; IF oe AND PASSPDONE_out = '0' THEN Status(7) := NOT WDataPassLo(7); Status(6) := NOT Status(6); Status(5) := '0'; Status(1) := '0'; DOut_zd <= Status; END IF; WHEN PASSVERIFY => IF oe THEN IF PPMLB /= '1' THEN DOut_zd(7 downto 0) <= Password(Address mod 8); ELSE DOut_zd(7 downto 0) <= (OTHERS => '1'); END IF; IF BYTENeg = '1' THEN IF PPMLB /= '1' THEN DOut_zd(15 downto 8) <= Password((Address mod 8)+1); ELSE DOut_zd(15 downto 8) <= (OTHERS => '1'); END IF; END IF; END IF; WHEN PASSUNLOCK0 => IF falling_edge(WRITE) THEN IF BYTENeg = '1' THEN UnlockPass := (to_nat(Password(0)) = DataLo) AND (Address mod 8) = 0; UnlockPass := UnlockPass AND (to_nat(Password(1)) = DataHi) AND (Address mod 8) = 0; ELSE UnlockPass := (to_nat(Password(0)) = DataLo) AND (Address mod 8) = 0; END IF; UNLOCKDONE_in <= '0','1' AFTER 1 ns; RY_zd <= '0'; END IF; IF rising_edge(UNLOCKDONE_out) THEN RY_zd <= '1'; END IF; IF oe AND UNLOCKDONE_out = '0' THEN Status(6) := NOT Status(6); DOut_zd <= Status; END IF; WHEN PASSUNLOCK1 => IF falling_edge(WRITE) AND UNLOCKDONE_out = '1' THEN IF BYTENeg = '1' THEN UnlockPass := UnlockPass AND (to_nat(Password(2)) = DataLo) AND (Address mod 8) = 2; UnlockPass := UnlockPass AND (to_nat(Password(3)) = DataHi) AND (Address mod 8) = 2; ELSE UnlockPass := UnlockPass AND (to_nat(Password(1)) = DataLo) AND (Address mod 8) = 1; END IF; UNLOCKDONE_in <= '0','1' AFTER 1 ns; RY_zd <= '0'; END IF; IF rising_edge(UNLOCKDONE_out) THEN RY_zd <= '1'; END IF; IF oe AND UNLOCKDONE_out = '0' THEN Status(6) := NOT Status(6); DOut_zd <= Status; END IF; WHEN PASSUNLOCK2 => IF falling_edge(WRITE) AND UNLOCKDONE_out = '1' THEN IF BYTENeg = '1' THEN UnlockPass := UnlockPass AND (to_nat(Password(4)) = DataLo) AND (Address mod 8) = 4; UnlockPass := UnlockPass AND (to_nat(Password(5)) = DataHi) AND (Address mod 8) = 4; ELSE UnlockPass := UnlockPass AND (to_nat(Password(2)) = DataLo) AND (Address mod 8) = 2; END IF; UNLOCKDONE_in <= '0','1' AFTER 1 ns; RY_zd <= '0'; END IF; IF rising_edge(UNLOCKDONE_out) THEN RY_zd <= '1'; END IF; IF oe AND UNLOCKDONE_out = '0' THEN Status(6) := NOT Status(6); DOut_zd <= Status; END IF; WHEN PASSUNLOCK3 => IF falling_edge(WRITE) AND UNLOCKDONE_out = '1' THEN IF BYTENeg = '1' THEN UnlockPass := UnlockPass AND (to_nat(Password(6)) = DataLo) AND (Address mod 8) = 6; UnlockPass := UnlockPass AND (to_nat(Password(7)) = DataHi) AND (Address mod 8) = 6; ELSE UnlockPass := UnlockPass AND (to_nat(Password(3)) = DataLo) AND (Address mod 8) = 3; END IF; UNLOCKDONE_in <= '0','1' AFTER 1 ns; RY_zd <= '0'; END IF; IF rising_edge(UNLOCKDONE_out) THEN IF BYTENeg = '1' THEN IF UnlockPass THEN PPBLock := '0'; END IF; END IF; RY_zd <= '1'; END IF; IF oe AND UNLOCKDONE_out = '0' THEN Status(6) := NOT Status(6); DOut_zd <= Status; END IF; WHEN PASSUNLOCK4 => IF falling_edge(WRITE) AND UNLOCKDONE_out = '1' THEN UnlockPass := UnlockPass AND (to_nat(Password(4)) = DataLo) AND (Address mod 8) = 4; UNLOCKDONE_in <= '0','1' AFTER 1 ns; RY_zd <= '0'; END IF; IF rising_edge(UNLOCKDONE_out) THEN RY_zd <= '1'; END IF; IF oe AND UNLOCKDONE_out = '0' THEN Status(6) := NOT Status(6); DOut_zd <= Status; END IF; WHEN PASSUNLOCK5 => IF falling_edge(WRITE) AND UNLOCKDONE_out = '1' THEN UnlockPass := UnlockPass AND (to_nat(Password(5)) = DataLo) AND (Address mod 8) = 5; UNLOCKDONE_in <= '0','1' AFTER 1 ns; RY_zd <= '0'; END IF; IF rising_edge(UNLOCKDONE_out) THEN RY_zd <= '1'; END IF; IF oe AND UNLOCKDONE_out = '0' THEN Status(6) := NOT Status(6); DOut_zd <= Status; END IF; WHEN PASSUNLOCK6 => IF falling_edge(WRITE) AND UNLOCKDONE_out = '1' THEN UnlockPass := UnlockPass AND (to_nat(Password(6)) = DataLo) AND (Address mod 8) = 6; UNLOCKDONE_in <= '0','1' AFTER 1 ns; RY_zd <= '0'; END IF; IF rising_edge(UNLOCKDONE_out) THEN RY_zd <= '1'; END IF; IF oe AND UNLOCKDONE_out = '0' THEN Status(6) := NOT Status(6); DOut_zd <= Status; END IF; WHEN PASSUNLOCK7 => IF falling_edge(WRITE) AND UNLOCKDONE_out = '1' THEN UnlockPass := UnlockPass AND (to_nat(Password(7)) = DataLo) AND (Address mod 8) = 7; UNLOCKDONE_in <= '0','1' AFTER 1 ns; RY_zd <= '0'; END IF; IF rising_edge(UNLOCKDONE_out) THEN IF UnlockPass THEN PPBLock := '0'; END IF; RY_zd <= '1'; END IF; IF oe AND UNLOCKDONE_out = '0' THEN Status(6) := NOT Status(6); DOut_zd <= Status; END IF; WHEN PROTBIT_PREL => IF falling_edge(WRITE) THEN IF DataLo = 16#68# AND (Addr mod 16#100# = WP) THEN PBSecAddr := SecAddr; PBSubSecAddr := SubSect; PBPROG_in <= '0', '1' AFTER 1 ns; RY_zd <= '0'; ELSIF DataLo = 16#60# AND (Addr mod 16#100# = WP) THEN PBErase_in <= '0', '1' AFTER 1 ns; RY_zd <= '0'; ELSIF DataLo = 16#68# AND (Addr mod 16#100# = PL) THEN PBPROG_in <= '0', '1' AFTER 1 ns; RY_zd <= '0'; ELSIF DataLo = 16#68# AND (Addr mod 16#100# = SL) THEN PBPROG_in <= '0', '1' AFTER 1 ns; RY_zd <= '0'; ELSIF DataLo = 16#68# AND (Addr mod 16#100# = OW) THEN PBPROG_in <= '0', '1' AFTER 1 ns; RY_zd <= '0'; END IF; END IF; WHEN PPBDYB => IF oe THEN DOut_zd(7 downto 0) <= (OTHERS => '0'); DOut_zd(1) <= PPBLock; IF SecAddr = VarSect THEN DOut_zd(0) <= DYB_SubSec(SubSect); ELSE DOut_zd(0) <= DYB(SecAddr); END IF; IF BYTENeg = '1' THEN DOut_zd(15 downto 8) <= (OTHERS => '0'); END IF; END IF; WHEN DYBWE => IF falling_edge(WRITE) THEN IF DataLo mod 2 = 0 THEN IF SecAddr = VarSect THEN DYB_SubSec(SubSect) := '0'; ELSE DYB(SecAddr) := '0'; END IF; ELSE IF SecAddr = VarSect THEN DYB_SubSec(SubSect) := '1'; ELSE DYB(SecAddr) := '1'; END IF; END IF; END IF; WHEN PPB_PROGRAM => IF rising_edge(PBPROG_out) THEN IF PPBLock = '0' THEN IF SecAddr = VarSect THEN PPB_SubSec(PBSubSecAddr) := '1'; ELSE PPB(GroupID(PBSecAddr)) := '1'; END IF; END IF; RY_zd <= '1'; END IF; WHEN PPB_VERIFY => IF oe THEN DOut_zd(7 downto 1) <= (OTHERS => '0'); IF SecAddr = VarSect THEN DOut_zd(0) <= PPB_SubSec(SubSect); ELSE DOut_zd(0) <= PPB(GroupID(SecAddr)); END IF; IF BYTENeg = '1' THEN DOut_zd(15 downto 8) <= (OTHERS => '0'); END IF; END IF; WHEN PPB_ERASE => IF rising_edge(PBERASE_out) THEN IF PPBLock = '0' THEN IF PPB_ers_ccl < 100 THEN PPB := (OTHERS => '0'); PPB_SubSec := (OTHERS => '0'); PPB_ers_ccl := PPB_ers_ccl +1; ELSE ASSERT false REPORT "PPBs are limited to 100 erase cycle" SEVERITY warning; END IF; END IF; RY_zd <= '1'; END IF; WHEN PPMLB_PROGRAM => IF rising_edge(PBPROG_out) THEN IF SPMLB /= '1' THEN PPMLB := '1'; END IF; RY_zd <= '1'; END IF; WHEN SPMLB_PROGRAM => IF rising_edge(PBPROG_out) THEN IF PPMLB /= '1' THEN SPMLB := '1'; END IF; RY_zd <= '1'; END IF; WHEN SSPB_PROGRAM => IF rising_edge(PBPROG_out) THEN SSPB := '1'; RY_zd <= '1'; END IF; WHEN PPMLB_VERIFY => IF oe THEN IF Addr mod 16#100# = PL THEN DOut_zd(7 downto 0) <= (OTHERS => '0'); DOut_zd(0) <= PPMLB; IF BYTENeg = '1' THEN DOut_zd(15 downto 8) <= (OTHERS => '0'); END IF; ELSE DOut_zd(7 downto 0) <= (OTHERS => 'Z'); IF BYTENeg = '1' THEN DOut_zd(15 downto 8) <= (OTHERS => 'Z'); END IF; END IF; END IF; WHEN SPMLB_VERIFY => IF oe THEN IF Addr mod 16#100# = SL THEN DOut_zd(7 downto 0) <= (OTHERS => '0'); DOut_zd(0) <= SPMLB; IF BYTENeg = '1' THEN DOut_zd(15 downto 8) <= (OTHERS => '0'); END IF; ELSE DOut_zd(7 downto 0) <= (OTHERS => 'Z'); IF BYTENeg = '1' THEN DOut_zd(15 downto 8) <= (OTHERS => 'Z'); END IF; END IF; END IF; WHEN SSPB_VERIFY => IF oe THEN IF Addr mod 16#100# = OW THEN DOut_zd(7 downto 0) <= (OTHERS => '0'); DOut_zd(0) <= SSPB; IF BYTENeg = '1' THEN DOut_zd(15 downto 8) <= (OTHERS => '0'); END IF; ELSE DOut_zd(7 downto 0) <= (OTHERS => 'Z'); IF BYTENeg = '1' THEN DOut_zd(15 downto 8) <= (OTHERS => 'Z'); END IF; END IF; END IF; END CASE; END IF; --Output Disable Control IF (gOE_n = '1') OR (gCE_n = '1') OR (RESETNeg = '0' AND RST = '0') THEN DOut_zd <= (OTHERS=>'Z'); ELSE IF (BYTENeg = '0') THEN DOut_zd(15 downto 8) <= (OTHERS =>'Z'); END IF; END IF; END PROCESS Functional; --------------------------------------------------------------------------- ---- File Read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_file : text is flash_file_name; FILE prot_file : text is prot_file_name; FILE secsi_file : text is secsi_file_name; VARIABLE ind : NATURAL RANGE 0 TO SecSize:= 0; VARIABLE buf : line; CONSTANT SecS : NATURAL := SecSize+1; CONSTANT MemSize : NATURAL := 16#3FFFFF#;--Bytes VARIABLE addr_ind : NATURAL; VARIABLE sec_ind : NATURAL; VARIABLE offset : NATURAL; VARIABLE report_err : BOOLEAN := FALSE; BEGIN WAIT ON VarSect; --Preload Control ----------------------------------------------------------------------- -- File read Section ---------------------------------------------------------------------- PPB := (OTHERS => '0');-- unprotected state PPB_SubSec := (OTHERS => '0');-- unprotected state DYB := (OTHERS => '0');-- unprotected state DYB_SubSec := (OTHERS => '0');-- unprotected state PPBLock := '0'; PPMLB := '0'; SPMLB := '0'; SSPB := '0'; Password := (OTHERS => ( OTHERS => '1')); PPB_ers_ccl := 0; ----------------------------------------------------------------------- --CFI array data ----------------------------------------------------------------------- --CFI query identification string -- !!!!!! WORD ADDRESSES (x16) - for x8 addressing double addr CFI_array(16#10#) := 16#0051#; CFI_array(16#11#) := 16#0052#; CFI_array(16#12#) := 16#0059#; CFI_array(16#13#) := 16#0002#; CFI_array(16#14#) := 16#0000#; CFI_array(16#15#) := 16#0040#; CFI_array(16#16#) := 16#0000#; CFI_array(16#17#) := 16#0000#; CFI_array(16#18#) := 16#0000#; CFI_array(16#19#) := 16#0000#; CFI_array(16#1A#) := 16#0000#; --system interface string CFI_array(16#1B#) := 16#0027#; CFI_array(16#1C#) := 16#0036#; CFI_array(16#1D#) := 16#0000#; CFI_array(16#1E#) := 16#0000#; CFI_array(16#1F#) := 16#0003#; CFI_array(16#20#) := 16#0000#; CFI_array(16#21#) := 16#0009#; CFI_array(16#22#) := 16#0000#; CFI_array(16#23#) := 16#0005#; CFI_array(16#24#) := 16#0000#; CFI_array(16#25#) := 16#0004#; CFI_array(16#26#) := 16#0000#; --device geometry definition CFI_array(16#27#) := 16#0016#; CFI_array(16#28#) := 16#0002#; CFI_array(16#29#) := 16#0000#; CFI_array(16#2A#) := 16#0000#; CFI_array(16#2B#) := 16#0000#; CFI_array(16#2C#) := 16#0002#; CFI_array(16#2D#) := 16#0007#; CFI_array(16#2E#) := 16#0000#; CFI_array(16#2F#) := 16#0020#; CFI_array(16#30#) := 16#0000#; CFI_array(16#31#) := 16#003E#; CFI_array(16#32#) := 16#0000#; CFI_array(16#33#) := 16#0000#; CFI_array(16#34#) := 16#0001#; CFI_array(16#35#) := 16#0000#; CFI_array(16#36#) := 16#0000#; CFI_array(16#37#) := 16#0000#; CFI_array(16#38#) := 16#0000#; CFI_array(16#39#) := 16#0000#; CFI_array(16#3A#) := 16#0000#; CFI_array(16#3B#) := 16#0000#; CFI_array(16#3C#) := 16#0000#; --primary vendor-specific extended query CFI_array(16#40#) := 16#0050#; CFI_array(16#41#) := 16#0052#; CFI_array(16#42#) := 16#0049#; CFI_array(16#43#) := 16#0031#; CFI_array(16#44#) := 16#0033#; CFI_array(16#45#) := 16#000C#; CFI_array(16#46#) := 16#0002#; CFI_array(16#47#) := 16#0001#; CFI_array(16#48#) := 16#0001#; CFI_array(16#49#) := 16#0007#; CFI_array(16#4A#) := 16#0020#; CFI_array(16#4B#) := 16#0000#; CFI_array(16#4C#) := 16#0000#; CFI_array(16#4D#) := 16#0085#; CFI_array(16#4E#) := 16#0095#; CFI_array(16#4F#) := 16#0002# + vs; CFI_array(16#50#) := 16#0001#; CFI_array(16#57#) := 16#0002#; CFI_array(16#58#) := 16#0027#; CFI_array(16#59#) := 16#0020#; CFI_array(16#5A#) := 16#0000#; CFI_array(16#5B#) := 16#0000#; IF (flash_file_name /= "none" AND UserPreload ) THEN ------------------------------------------------------------------------------- -----s29jl032j4 memory preload file format------ ------------------------------------------------------------------------------- -- / - comment -- @aa - stands for address within sector -- dd -
is byte to be written at Mem(aa++) -- (aa is incremented at every load) -- only first 1-7 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! ------------------------------------------------------------------------------- addr_ind := 0; Mem := (OTHERS => (OTHERS => MaxData)); WHILE (not ENDFILE (mem_file)) LOOP READLINE (mem_file, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 7)); sec_ind := addr_ind / SecS; offset := addr_ind - ( sec_ind * SecS ); ELSE IF addr_ind <= MemSize THEN Mem(sec_ind)(offset) := h(buf(1 to 2)); addr_ind := (addr_ind + 1); sec_ind := addr_ind / SecS; offset := addr_ind - ( sec_ind * SecS ); ELSE IF report_err = FALSE THEN REPORT "Memory file:" & flash_file_name & " Address range error" SEVERITY error; report_err := TRUE; END IF; END IF; END IF; END LOOP; END IF; IF (prot_file_name /= "none" AND UserPreload ) THEN ------------------------------------------------------------------------------- -----s29jl032j4 sector protection preload file format------ ------------------------------------------------------------------------------- -- / - comment -- @aa - stands for address within sector -- (aaaa is incremented at every load) -- b - is 0 for protected sector , 1 for unprotect. -- If > SecNum SecSi is protected/unprotected -- only first 1-2 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! ------------------------------------------------------------------------------- ind := 0; WHILE (not ENDFILE (prot_file)) LOOP READLINE (prot_file, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address ind := h(buf(2 to 3)); ELSE IF ind > SecNum THEN IF buf(1) = '1' THEN PPB_SubSec(ind - SecNum) := '1'; END IF; ELSE IF (buf(1) = '1') THEN PPB(GroupID(ind)) := '1'; END IF; ind := ind + 1; END IF; END IF; END LOOP; END IF; -- Secure Silicon Sector Region preload IF (SecSi_file_name /= "none" AND UserPreload ) THEN ------------------------------------------------------------------------------- -----s29jl032j4 Secsi preload file format------ ------------------------------------------------------------------------------- -- / - comment -- @aa - stands for address within sector -- dd -
is byte to be written at SecSi(aa++) -- (aa is incremented at every load) -- only first 1-5 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! ------------------------------------------------------------------------------- SecSi := (OTHERS => MaxData); ind := 0; WHILE (not ENDFILE (SecSi_file)) LOOP READLINE (SecSi_file, buf); IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN ind := h(buf(2 TO 4)); ELSE IF ind <= SecSiSize THEN SecSi(ind) := h(buf(1 TO 2)); ind := ind + 1; END IF; END IF; END LOOP; END IF; WAIT; END PROCESS MemPreload; DOutPassThrough : PROCESS(DOut_zd) VARIABLE ValidData : std_logic_vector(15 downto 0); VARIABLE CEDQ_t : TIME; VARIABLE OEDQ_t : TIME; VARIABLE ADDRDQ_t : TIME; BEGIN IF DOut_zd(0) /= 'Z' THEN OPENLATCH := TRUE; CEDQ_t := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(trz0); OEDQ_t := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(trz0); ADDRDQ_t := -A'LAST_EVENT + tpd_A0_DQ0(tr01);-- IF ( BYTENeg = '0' ) AND (DIn(15)'LAST_EVENT < A'LAST_EVENT) THEN ADDRDQ_t := -DIn(15)'LAST_EVENT + tpd_A0_DQ0(tr01);-- END IF; FROMOE := (OEDQ_t >= CEDQ_t) AND (OEDQ_t > 0 ns); FROMCE := (CEDQ_t > OEDQ_t) AND (CEDQ_t > 0 ns); IF BYTENeg = '0' THEN ValidData := "ZZZZZZZZXXXXXXXX"; ELSE ValidData := "XXXXXXXXXXXXXXXX"; END IF; IF ((ADDRDQ_t > 0 ns) AND (((ADDRDQ_t > CEDQ_t) AND FROMCE) OR ((ADDRDQ_t > OEDQ_t) AND FROMOE))) THEN DOut_Pass <= ValidData, DOut_zd AFTER ADDRDQ_t; ELSE DOut_Pass <= DOut_zd; END IF; ELSE CEDQ_t := -CENeg'LAST_EVENT + tpd_CENeg_DQ0(tr0z); OEDQ_t := -OENeg'LAST_EVENT + tpd_OENeg_DQ0(tr0z); FROMOE := (OEDQ_t <= CEDQ_t) AND (OEDQ_t > 0 ns); FROMCE := (CEDQ_t < OEDQ_t) AND (CEDQ_t > 0 ns); DOut_Pass <= DOut_zd; OPENLATCH := FALSE; DOut_Pass <= DOut_zd; END IF; END PROCESS DOutPassThrough; ----------------------------------------------------------------------- -- Path Delay Section ----------------------------------------------------------------------- RY_OUT: PROCESS(RY_zd) VARIABLE RY_GlitchData : VitalGlitchDataType; VARIABLE RYData : std_logic; BEGIN IF RY_zd = '1' THEN RYData := 'Z'; ELSE RYData := RY_zd; END IF; VitalPathDelay01Z( OutSignal => RY, OutSignalName => "RY/BY#", OutTemp => RYData, Mode => VitalTransport, GlitchData => RY_GlitchData, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_WENeg_RY, PathCondition => TRUE), 1 => (InputChangeTime => WENeg'LAST_EVENT, PathDelay => tpd_WENeg_RY, PathCondition => TRUE), 2 => (InputChangeTime => READY'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; --------------------------------------------------------------------------- -- Path Delay Section for DOut signal --------------------------------------------------------------------------- D_Out_PathDelay_Gen : FOR i IN 0 TO 7 GENERATE PROCESS(DOut_Pass(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_Pass(i), GlitchData => D0_GlitchData, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMOE) OR (OPENLATCH AND FROMCE)), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMCE) OR (OPENLATCH AND FROMOE)), 2 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0), PathCondition => NOT FROMOE AND NOT FROMCE), 3 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0), PathCondition => BYTENeg = '0' AND DOut_pass(i) /= 'X'), 4 => (InputChangeTime => BYTENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_BYTENeg_DQ15), PathCondition => BYTENeg = '1'), 5 => (InputChangeTime => RESETNeg'LAST_EVENT, PathDelay => tpd_RESETNeg_DQ0, PathCondition => RESETNeg='0') ) ); END PROCESS; END GENERATE D_Out_PathDelay_Gen; --------------------------------------------------------------------------- -- Path Delay Section for DOut signal --------------------------------------------------------------------------- D_Out_15_7_PathDelay_Gen : FOR i IN 8 TO 15 GENERATE PROCESS(DOut_Pass(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_Pass(i), GlitchData => D0_GlitchData, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMOE) OR (OPENLATCH AND FROMCE)), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_DQ0, PathCondition => (NOT OPENLATCH AND NOT FROMCE) OR (OPENLATCH AND FROMOE)), 2 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0), PathCondition => NOT FROMOE AND NOT FROMCE), 3 => (InputChangeTime => Din(15)'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_A0_DQ0), PathCondition => BYTENeg = '0' AND DOut_pass(i) /= 'X'), 4 => (InputChangeTime => BYTENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_BYTENeg_DQ15), PathCondition => BYTENeg = '1'), 5 => (InputChangeTime => RESETNeg'LAST_EVENT, PathDelay => tpd_RESETNeg_DQ0, PathCondition => RESETNeg='0'), 6 => (InputChangeTime => BYTENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(tpd_BYTENeg_DQ15), PathCondition => BYTENeg = '0') ) ); END PROCESS; END GENERATE D_Out_15_7_PathDelay_Gen; END BLOCK behavior; END vhdl_behavioral;