-------------------------------------------------------------------------------- -- File name : i28f128p33.vhd -------------------------------------------------------------------------------- -- Copyright (C) 2007-2009 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 I.Milutinovic 07 Jun 13 Initial Release -- V1.1 J.Stoickov 09 Mar 31 Added tdevice values -- V1.2 J.Stoickov 09 Apr 01 Write mode corrected for the WENeg -- and CENeg signals rise at same time -- V1.3 S.Petrovic 09 Apr 15 BLOCK inputs mapped to no-weak- -- value signals without calling -- ALLIGN_TYPES function, -- ADV LOW is removed as condition -- for write address latching -- -------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: FLASH -- Technology: FLASH MEMORY -- Part: I28F128P33 -- -- Description: 128 Mbit Intel Strata Flash Memory (P33) Family -- -------------------------------------------------------------------------------- -- Comments : -- -- -------------------------------------------------------------------------------- -- Known Bugs: -- -------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.VITAL_timing.ALL; USE IEEE.VITAL_primitives.ALL; USE STD.textio.ALL; LIBRARY FMF; USE FMF.gen_utils.all; USE FMF.conversions.all; ------------------------------------------------------------------------------ -- ENTITY DECLARATION ------------------------------------------------------------------------------- ENTITY i28f128p33 IS GENERIC ( -- tipd delays: interconnect path delays tipd_A1 : VitalDelayType01 := VitalZeroDelay01; tipd_A2 : VitalDelayType01 := VitalZeroDelay01; tipd_A3 : VitalDelayType01 := VitalZeroDelay01; tipd_A4 : VitalDelayType01 := VitalZeroDelay01; tipd_A5 : VitalDelayType01 := VitalZeroDelay01; tipd_A6 : VitalDelayType01 := VitalZeroDelay01; tipd_A7 : VitalDelayType01 := VitalZeroDelay01; tipd_A8 : VitalDelayType01 := VitalZeroDelay01; tipd_A9 : VitalDelayType01 := VitalZeroDelay01; tipd_A10 : VitalDelayType01 := VitalZeroDelay01; tipd_A11 : VitalDelayType01 := VitalZeroDelay01; tipd_A12 : VitalDelayType01 := VitalZeroDelay01; tipd_A13 : VitalDelayType01 := VitalZeroDelay01; tipd_A14 : VitalDelayType01 := VitalZeroDelay01; tipd_A15 : VitalDelayType01 := VitalZeroDelay01; tipd_A16 : VitalDelayType01 := VitalZeroDelay01; tipd_A17 : VitalDelayType01 := VitalZeroDelay01; tipd_A18 : VitalDelayType01 := VitalZeroDelay01; tipd_A19 : VitalDelayType01 := VitalZeroDelay01; tipd_A20 : VitalDelayType01 := VitalZeroDelay01; tipd_A21 : VitalDelayType01 := VitalZeroDelay01; tipd_A22 : VitalDelayType01 := VitalZeroDelay01; tipd_A23 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; tipd_ADVNeg : VitalDelayType01 := VitalZeroDelay01; tipd_CENeg : VitalDelayType01 := VitalZeroDelay01; tipd_CLK : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RSTNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays tpd_A1_DQ0_InitialPageAccess : VitalDelayType01 := UnitDelay01; tpd_A1_DQ0_SubsequentPageAccess: VitalDelayType01 := UnitDelay01; tpd_ADVNeg_DQ0 : VitalDelayType01 := UnitDelay01; tpd_CENeg_DQ0 : VitalDelayType01ZX := UnitDelay01ZX; tpd_OENeg_DQ0 : VitalDelayType01ZX := UnitDelay01ZX; tpd_CLK_DQ0 : VitalDelayType01ZX := UnitDelay01ZX; tpd_CENeg_WAITOut : VitalDelayType01Z := UnitDelay01Z; tpd_OENeg_WAITOut : VitalDelayType01Z := UnitDelay01Z; tpd_CLK_WAITOut : VitalDelayType01Z := UnitDelay01Z; -- tsetup values tsetup_A1_ADVNeg : VitalDelayType := UnitDelay; tsetup_CENeg_ADVNeg : VitalDelayType := UnitDelay; tsetup_RSTNeg_ADVNeg : VitalDelayType := UnitDelay; tsetup_CLK_ADVNeg : VitalDelayType := UnitDelay; tsetup_WENeg_ADVNeg : VitalDelayType := UnitDelay; tsetup_A1_CLK : VitalDelayType := UnitDelay; tsetup_ADVNeg_CLK : VitalDelayType := UnitDelay; tsetup_CENeg_CLK : VitalDelayType := UnitDelay; tsetup_WENeg_CLK : VitalDelayType := UnitDelay; tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; tsetup_DQ0_WENeg : VitalDelayType := UnitDelay; tsetup_A1_WENeg : VitalDelayType := UnitDelay; tsetup_WPNeg_WENeg : VitalDelayType := UnitDelay; tsetup_ADVNeg_WENeg : VitalDelayType := UnitDelay; tsetup_CLK_WENeg : VitalDelayType := UnitDelay; tsetup_WENeg_OENeg : VitalDelayType := UnitDelay; -- thold values thold_A1_ADVNeg : VitalDelayType := UnitDelay; thold_A1_CLK : VitalDelayType := UnitDelay; thold_CENeg_WENeg : VitalDelayType := UnitDelay; thold_DQ0_WENeg : VitalDelayType := UnitDelay; thold_A1_WENeg : VitalDelayType := UnitDelay; -- tpw values: pulse widths tpw_CENeg_posedge : VitalDelayType := UnitDelay; tpw_ADVNeg_negedge : VitalDelayType := UnitDelay; tpw_ADVNeg_posedge : VitalDelayType := UnitDelay; tpw_WENeg_negedge : VitalDelayType := UnitDelay; tpw_WENeg_posedge : VitalDelayType := UnitDelay; tpw_RSTNeg_negedge : VitalDelayType := UnitDelay; tpw_CLK_posedge : VitalDelayType := UnitDelay; tpw_CLK_negedge : VitalDelayType := UnitDelay; --tperiod values tperiod_CLK : VitalDelayType := UnitDelay; -- trecovery values trecovery_RSTNeg_WENeg : VitalDelayType := UnitDelay; --tdevice values tdevice_WordProgram : VitalDelayType := 200 us;--tPROG/W tdevice_WordProgram9V : VitalDelayType := 190 us;--tPROG/W tdevice_BuffProgram : VitalDelayType := 880 us;--tBUFF tdevice_BuffProgram9V : VitalDelayType := 680 us;--tBUFF tdevice_BEFP : VitalDelayType := 320 us;--tBEFP/W tdevice_BEFPsetup : VitalDelayType := 5 us;--tBEFP/Setup tdevice_EraseParameter : VitalDelayType := 2.5 sec;--tERS/PB tdevice_EraseMain : VitalDelayType := 4 sec;--tERS/MB tdevice_ProgramSuspend : VitalDelayType := 25 us;--tSUSP/P tdevice_EraseSuspend : VitalDelayType := 25 us;--tSUSP/E tdevice_RstDuringErsPrg : VitalDelayType := 25 us;--tPLRH -- analog generic: values of VPP input in volts VPP_voltage : NATURAL RANGE 2 TO 9; -- This generic should be set to 2 or 9. -- The VPP port determines if any voltage is present on Vpp pin, -- this generic determines if applied voltage is 2V or 9V. -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- memory preload files to be loaded mem_file_name : STRING := "none"; prot_reg_file_name : STRING := "none"; otp_blocks_file_name: STRING := "none"; UserPreload : BOOLEAN := TRUE; LongTiming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING -- := DefaultTimingModel ); PORT ( A23 : IN std_ulogic := 'U'; A22 : IN std_ulogic := 'U'; A21 : IN std_ulogic := 'U'; A20 : IN std_ulogic := 'U'; A19 : IN std_ulogic := 'U'; A18 : IN std_ulogic := 'U'; A17 : IN std_ulogic := 'U'; A16 : IN std_ulogic := 'U'; A15 : IN std_ulogic := 'U'; A14 : IN std_ulogic := 'U'; A13 : IN std_ulogic := 'U'; A12 : IN std_ulogic := 'U'; A11 : IN std_ulogic := 'U'; A10 : IN std_ulogic := 'U'; A9 : IN std_ulogic := 'U'; A8 : IN std_ulogic := 'U'; A7 : IN std_ulogic := 'U'; A6 : IN std_ulogic := 'U'; A5 : IN std_ulogic := 'U'; A4 : IN std_ulogic := 'U'; A3 : IN std_ulogic := 'U'; A2 : IN std_ulogic := 'U'; A1 : IN std_ulogic := 'U'; DQ15 : INOUT std_ulogic := 'U'; DQ14 : INOUT std_ulogic := 'U'; DQ13 : INOUT std_ulogic := 'U'; DQ12 : INOUT std_ulogic := 'U'; DQ11 : INOUT std_ulogic := 'U'; DQ10 : INOUT std_ulogic := 'U'; DQ9 : INOUT std_ulogic := 'U'; DQ8 : INOUT std_ulogic := 'U'; DQ7 : INOUT std_ulogic := 'U'; DQ6 : INOUT std_ulogic := 'U'; DQ5 : INOUT std_ulogic := 'U'; DQ4 : INOUT std_ulogic := 'U'; DQ3 : INOUT std_ulogic := 'U'; DQ2 : INOUT std_ulogic := 'U'; DQ1 : INOUT std_ulogic := 'U'; DQ0 : INOUT std_ulogic := 'U'; ADVNeg : IN std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; CLK : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; RSTNeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; VPP : IN std_ulogic := 'U'; WAITOut : OUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of i28f128p33 : ENTITY IS TRUE; END i28f128p33; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION - Static memory allocation ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral_static_memory_allocation of i28f128p33 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral_static_memory_allocation : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "i28f128p33"; CONSTANT MaxData : NATURAL := 16#FFFF#; CONSTANT MemSize : NATURAL := 16#7FFFFF#; CONSTANT HiAddrBit : NATURAL := 22; CONSTANT MainBlockSize : NATURAL := 16#010000#; CONSTANT ParameterBlockSize: NATURAL := 16#004000#; CONSTANT HiBlockNum : NATURAL := 130; CONSTANT DeviceID_B : NATURAL := 16#8821#; CONSTANT DeviceID_T : NATURAL := 16#881E#; -- ipd SIGNAL A23_ipd : std_ulogic := 'U'; SIGNAL A22_ipd : std_ulogic := 'U'; SIGNAL A21_ipd : std_ulogic := 'U'; SIGNAL A20_ipd : std_ulogic := 'U'; SIGNAL A19_ipd : std_ulogic := 'U'; SIGNAL A18_ipd : std_ulogic := 'U'; SIGNAL A17_ipd : std_ulogic := 'U'; SIGNAL A16_ipd : std_ulogic := 'U'; SIGNAL A15_ipd : std_ulogic := 'U'; SIGNAL A14_ipd : std_ulogic := 'U'; SIGNAL A13_ipd : std_ulogic := 'U'; SIGNAL A12_ipd : std_ulogic := 'U'; SIGNAL A11_ipd : std_ulogic := 'U'; SIGNAL A10_ipd : std_ulogic := 'U'; SIGNAL A9_ipd : std_ulogic := 'U'; SIGNAL A8_ipd : std_ulogic := 'U'; SIGNAL A7_ipd : std_ulogic := 'U'; SIGNAL A6_ipd : std_ulogic := 'U'; SIGNAL A5_ipd : std_ulogic := 'U'; SIGNAL A4_ipd : std_ulogic := 'U'; SIGNAL A3_ipd : std_ulogic := 'U'; SIGNAL A2_ipd : std_ulogic := 'U'; SIGNAL A1_ipd : std_ulogic := 'U'; SIGNAL 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 ADVNeg_ipd : std_ulogic := 'U'; SIGNAL CENeg_ipd : std_ulogic := 'U'; SIGNAL CLK_ipd : std_ulogic := 'U'; SIGNAL OENeg_ipd : std_ulogic := 'U'; SIGNAL RSTNeg_ipd : std_ulogic := 'U'; SIGNAL WENeg_ipd : std_ulogic := 'U'; SIGNAL WPNeg_ipd : std_ulogic := 'U'; -- nwv SIGNAL A23_nwv : std_ulogic := 'U'; SIGNAL A22_nwv : std_ulogic := 'U'; SIGNAL A21_nwv : std_ulogic := 'U'; SIGNAL A20_nwv : std_ulogic := 'U'; SIGNAL A19_nwv : std_ulogic := 'U'; SIGNAL A18_nwv : std_ulogic := 'U'; SIGNAL A17_nwv : std_ulogic := 'U'; SIGNAL A16_nwv : std_ulogic := 'U'; SIGNAL A15_nwv : std_ulogic := 'U'; SIGNAL A14_nwv : std_ulogic := 'U'; SIGNAL A13_nwv : std_ulogic := 'U'; SIGNAL A12_nwv : std_ulogic := 'U'; SIGNAL A11_nwv : std_ulogic := 'U'; SIGNAL A10_nwv : std_ulogic := 'U'; SIGNAL A9_nwv : std_ulogic := 'U'; SIGNAL A8_nwv : std_ulogic := 'U'; SIGNAL A7_nwv : std_ulogic := 'U'; SIGNAL A6_nwv : std_ulogic := 'U'; SIGNAL A5_nwv : std_ulogic := 'U'; SIGNAL A4_nwv : std_ulogic := 'U'; SIGNAL A3_nwv : std_ulogic := 'U'; SIGNAL A2_nwv : std_ulogic := 'U'; SIGNAL A1_nwv : std_ulogic := 'U'; SIGNAL DQ15_nwv : std_ulogic := 'U'; SIGNAL DQ14_nwv : std_ulogic := 'U'; SIGNAL DQ13_nwv : std_ulogic := 'U'; SIGNAL DQ12_nwv : std_ulogic := 'U'; SIGNAL DQ11_nwv : std_ulogic := 'U'; SIGNAL DQ10_nwv : std_ulogic := 'U'; SIGNAL DQ9_nwv : std_ulogic := 'U'; SIGNAL DQ8_nwv : std_ulogic := 'U'; SIGNAL DQ7_nwv : std_ulogic := 'U'; SIGNAL DQ6_nwv : std_ulogic := 'U'; SIGNAL DQ5_nwv : std_ulogic := 'U'; SIGNAL DQ4_nwv : std_ulogic := 'U'; SIGNAL DQ3_nwv : std_ulogic := 'U'; SIGNAL DQ2_nwv : std_ulogic := 'U'; SIGNAL DQ1_nwv : std_ulogic := 'U'; SIGNAL DQ0_nwv : std_ulogic := 'U'; SIGNAL ADVNeg_nwv : std_ulogic := 'U'; SIGNAL CENeg_nwv : std_ulogic := 'U'; SIGNAL CLK_nwv : std_ulogic := 'U'; SIGNAL OENeg_nwv : std_ulogic := 'U'; SIGNAL RSTNeg_nwv : std_ulogic := 'U'; SIGNAL WENeg_nwv : std_ulogic := 'U'; SIGNAL WPNeg_nwv : std_ulogic := 'U'; --internal delays SIGNAL WordProgram_in_t : std_ulogic := '0'; SIGNAL WordProgram_in : std_ulogic := '0'; SIGNAL WordProgram9V_in_t : std_ulogic := '0'; SIGNAL WordProgram_out_t : std_ulogic := '0'; SIGNAL WordProgram_out : std_ulogic := '0'; SIGNAL WordProgram9V_out_t : std_ulogic := '0'; SIGNAL BuffProgram_in : std_ulogic := '0'; SIGNAL BuffProgram_in_t : std_ulogic := '0'; SIGNAL BuffProgram9V_in_t : std_ulogic := '0'; SIGNAL BuffProgram_out : std_ulogic := '0'; SIGNAL BuffProgram_out_t : std_ulogic := '0'; SIGNAL BuffProgram9V_out_t : std_ulogic := '0'; SIGNAL BEFP_in : std_ulogic := '0'; SIGNAL BEFP_out : std_ulogic := '0'; SIGNAL BEFP_in_t : std_ulogic := '0'; SIGNAL BEFP_out_t : std_ulogic := '0'; SIGNAL BEFPsetup_in : std_ulogic := '0'; SIGNAL BEFPsetup_out : std_ulogic := '0'; SIGNAL ParameterErase_in : std_ulogic := '0'; SIGNAL MainErase_in : std_ulogic := '0'; SIGNAL ParameterErase_in_t : std_ulogic := '0'; SIGNAL MainErase_in_t : std_ulogic := '0'; SIGNAL ParameterErase_out : std_logic := '0'; SIGNAL MainErase_out : std_logic := '0'; SIGNAL ParameterErase_out_t : std_ulogic := '0'; SIGNAL MainErase_out_t : std_ulogic := '0'; SIGNAL ProgramSuspend_in : std_ulogic := '0'; SIGNAL ProgramSuspend_out : std_ulogic := '0'; SIGNAL EraseSuspend_in : std_ulogic := '0'; SIGNAL EraseSuspend_out : std_ulogic := '0'; SIGNAL RstDuringErsPrg_in : std_ulogic := '0'; SIGNAL RstDuringErsPrg_out : std_ulogic := '0'; BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays WordProgram : VitalBuf(WordProgram_out_t, WordProgram_in_t, (UnitDelay, tdevice_WordProgram)); WordProgram9V : VitalBuf(WordProgram9V_out_t, WordProgram9V_in_t, (UnitDelay, tdevice_WordProgram9V)); BuffProgram : VitalBuf(BuffProgram_out_t, BuffProgram_in_t, (UnitDelay, tdevice_BuffProgram)); BuffProgram9V : VitalBuf(BuffProgram9V_out_t, BuffProgram9V_in_t, (UnitDelay, tdevice_BuffProgram9V)); BEFP : VitalBuf(BEFP_out_t, BEFP_in_t, (UnitDelay, tdevice_BEFP)); BEFPsetup : VitalBuf(BEFPsetup_out, BEFPsetup_in, (UnitDelay, tdevice_BEFPsetup)); EraseParameter : VitalBuf(ParameterErase_out_t, ParameterErase_in_t, (UnitDelay, tdevice_EraseParameter)); EraseMain : VitalBuf(MainErase_out_t, MainErase_in_t, (UnitDelay, tdevice_EraseMain)); ProgramSuspend : VitalBuf(ProgramSuspend_out, ProgramSuspend_in, (UnitDelay, tdevice_ProgramSuspend)); EraseSuspend : VitalBuf(EraseSuspend_out, EraseSuspend_in, (UnitDelay, tdevice_EraseSuspend)); RstDuringErsPrg: VitalBuf(RstDuringErsPrg_out,RstDuringErsPrg_in, (UnitDelay, tdevice_RstDuringErsPrg)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (A23_ipd, A23, tipd_A23); w_2 : VitalWireDelay (A22_ipd, A22, tipd_A22); w_3 : VitalWireDelay (A21_ipd, A21, tipd_A21); w_4 : VitalWireDelay (A20_ipd, A20, tipd_A20); w_5 : VitalWireDelay (A19_ipd, A19, tipd_A19); w_6 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_7 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_8 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_9 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_10 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_11 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_12 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_13 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_14 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_15 : VitalWireDelay (A9_ipd, A9, tipd_A9); w_16 : VitalWireDelay (A8_ipd, A8, tipd_A8); w_17 : VitalWireDelay (A7_ipd, A7, tipd_A7); w_18 : VitalWireDelay (A6_ipd, A6, tipd_A6); w_19 : VitalWireDelay (A5_ipd, A5, tipd_A5); w_20 : VitalWireDelay (A4_ipd, A4, tipd_A4); w_21 : VitalWireDelay (A3_ipd, A3, tipd_A3); w_22 : VitalWireDelay (A2_ipd, A2, tipd_A2); w_23 : VitalWireDelay (A1_ipd, A1, tipd_A1); w_24 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_25 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_26 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_27 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_28 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_29 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_30 : VitalWireDelay (DQ9_ipd, DQ9, tipd_DQ9); w_31 : VitalWireDelay (DQ8_ipd, DQ8, tipd_DQ8); w_32 : VitalWireDelay (DQ7_ipd, DQ7, tipd_DQ7); w_33 : VitalWireDelay (DQ6_ipd, DQ6, tipd_DQ6); w_34 : VitalWireDelay (DQ5_ipd, DQ5, tipd_DQ5); w_35 : VitalWireDelay (DQ4_ipd, DQ4, tipd_DQ4); w_36 : VitalWireDelay (DQ3_ipd, DQ3, tipd_DQ3); w_37 : VitalWireDelay (DQ2_ipd, DQ2, tipd_DQ2); w_38 : VitalWireDelay (DQ1_ipd, DQ1, tipd_DQ1); w_39 : VitalWireDelay (DQ0_ipd, DQ0, tipd_DQ0); w_40 : VitalWireDelay (ADVNeg_ipd, ADVNeg, tipd_ADVNeg); w_41 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); w_42 : VitalWireDelay (CLK_ipd, CLK, tipd_CLK); w_43 : VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg); w_44 : VitalWireDelay (RSTNeg_ipd, RSTNeg, tipd_RSTNeg); w_45 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_46 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg); END BLOCK; -- sig_nwv <= To_UX01(sig_ipd); A23_nwv <= To_UX01(A23_ipd); A22_nwv <= To_UX01(A22_ipd); A21_nwv <= To_UX01(A21_ipd); A20_nwv <= To_UX01(A20_ipd); A19_nwv <= To_UX01(A19_ipd); A18_nwv <= To_UX01(A18_ipd); A17_nwv <= To_UX01(A17_ipd); A16_nwv <= To_UX01(A16_ipd); A15_nwv <= To_UX01(A15_ipd); A14_nwv <= To_UX01(A14_ipd); A13_nwv <= To_UX01(A13_ipd); A12_nwv <= To_UX01(A12_ipd); A11_nwv <= To_UX01(A11_ipd); A10_nwv <= To_UX01(A10_ipd); A9_nwv <= To_UX01(A9_ipd); A8_nwv <= To_UX01(A8_ipd); A7_nwv <= To_UX01(A7_ipd); A6_nwv <= To_UX01(A6_ipd); A5_nwv <= To_UX01(A5_ipd); A4_nwv <= To_UX01(A4_ipd); A3_nwv <= To_UX01(A3_ipd); A2_nwv <= To_UX01(A2_ipd); A1_nwv <= To_UX01(A1_ipd); DQ15_nwv <= To_UX01(DQ15_ipd); DQ14_nwv <= To_UX01(DQ14_ipd); DQ13_nwv <= To_UX01(DQ13_ipd); DQ12_nwv <= To_UX01(DQ12_ipd); DQ11_nwv <= To_UX01(DQ11_ipd); DQ10_nwv <= To_UX01(DQ10_ipd); DQ9_nwv <= To_UX01(DQ9_ipd); DQ8_nwv <= To_UX01(DQ8_ipd); DQ7_nwv <= To_UX01(DQ7_ipd); DQ6_nwv <= To_UX01(DQ6_ipd); DQ5_nwv <= To_UX01(DQ5_ipd); DQ4_nwv <= To_UX01(DQ4_ipd); DQ3_nwv <= To_UX01(DQ3_ipd); DQ2_nwv <= To_UX01(DQ2_ipd); DQ1_nwv <= To_UX01(DQ1_ipd); DQ0_nwv <= To_UX01(DQ0_ipd); ADVNeg_nwv <= To_UX01(ADVNeg_ipd); CENeg_nwv <= To_UX01(CENeg_ipd ); CLK_nwv <= To_UX01(CLK_ipd ); OENeg_nwv <= To_UX01(OENeg_ipd ); RSTNeg_nwv <= To_UX01(RSTNeg_ipd); WENeg_nwv <= To_UX01(WENeg_ipd ); WPNeg_nwv <= To_UX01(WPNeg_ipd ); --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK PORT ( A : IN std_logic_vector(HiAddrBit downto 0) := (OTHERS => 'U'); DQIn : IN std_logic_vector(15 downto 0) := (OTHERS => 'U'); DQOut : OUT std_logic_vector(15 downto 0) := (OTHERS => 'Z'); ADVNeg : IN std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; CLK : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; RSTNeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; VPP : IN std_ulogic := 'U'; WAITOut : OUT std_ulogic := 'Z' ); PORT MAP ( A(22) => A23_nwv, A(21) => A22_nwv, A(20) => A21_nwv, A(19) => A20_nwv, A(18) => A19_nwv, A(17) => A18_nwv, A(16) => A17_nwv, A(15) => A16_nwv, A(14) => A15_nwv, A(13) => A14_nwv, A(12) => A13_nwv, A(11) => A12_nwv, A(10) => A11_nwv, A(9) => A10_nwv, A(8) => A9_nwv, A(7) => A8_nwv, A(6) => A7_nwv, A(5) => A6_nwv, A(4) => A5_nwv, A(3) => A4_nwv, A(2) => A3_nwv, A(1) => A2_nwv, A(0) => A1_nwv, DQIn(15) => DQ15_nwv, DQIn(14) => DQ14_nwv, DQIn(13) => DQ13_nwv, DQIn(12) => DQ12_nwv, DQIn(11) => DQ11_nwv, DQIn(10) => DQ10_nwv, DQIn(9) => DQ9_nwv, DQIn(8) => DQ8_nwv, DQIn(7) => DQ7_nwv, DQIn(6) => DQ6_nwv, DQIn(5) => DQ5_nwv, DQIn(4) => DQ4_nwv, DQIn(3) => DQ3_nwv, DQIn(2) => DQ2_nwv, DQIn(1) => DQ1_nwv, DQIn(0) => DQ0_nwv, DQOut(15) => DQ15, DQOut(14) => DQ14, DQOut(13) => DQ13, DQOut(12) => DQ12, DQOut(11) => DQ11, DQOut(10) => DQ10, DQOut(9) => DQ9, DQOut(8) => DQ8, DQOut(7) => DQ7, DQOut(6) => DQ6, DQOut(5) => DQ5, DQOut(4) => DQ4, DQOut(3) => DQ3, DQOut(2) => DQ2, DQOut(1) => DQ1, DQOut(0) => DQ0, ADVNeg => ADVNeg_nwv, CENeg => CENeg_nwv , CLK => CLK_nwv , OENeg => OENeg_nwv , RSTNeg => RSTNeg_nwv, WENeg => WENeg_nwv , WPNeg => WPNeg_nwv , VPP => VPP, WAITOut => WAITOut ); -- Read State Machine : Read_State_Type TYPE read_state_type IS ( READ_ARRAY, READ_STATUS, READ_ID, READ_QUERY ); -- State Machine : State_Type TYPE state_type IS ( RESET_POWER_DOWN, READY, LOCK_SETUP, OTP_SETUP, OTP_BUSY, PROG_SETUP, PROG_BUSY, PROG_SUSP, BP_SETUP, BP_LOAD, BP_CONFIRM, BP_BUSY, BP_SUSP, ERASE_SETUP, ERASE_BUSY, ERS_SUSP, PROG_SETUP_ERS_SUSP, PROG_BUSY_ERS_SUSP, PROG_SUSP_ERS_SUSP, BP_SETUP_ERS_SUSP, BP_LOAD_ERS_SUSP, BP_CONFIRM_ERS_SUSP, BP_BUSY_ERS_SUSP, BP_SUSP_ERS_SUSP, LOCK_SETUP_ERS_SUSP, BEFP_SETUP, BEFP_LOAD, BEFP_BUSY ); --states SIGNAL current_state : state_type; SIGNAL next_state : state_type; SIGNAL read_state : read_state_type; SIGNAL Write : std_logic := '1'; SIGNAL Read : std_logic := '0'; SIGNAL abort : std_logic := '0'; SIGNAL BP_ProgramResume : std_logic := '0'; SIGNAL MainEraseResume : std_logic := '0'; SIGNAL ParameterEraseResume : std_logic := '0'; SIGNAL WordProgramResume : std_logic := '0'; SHARED VARIABLE bp_suspend : std_logic := '0'; SIGNAL ExtendProgTime : BOOLEAN := FALSE; SIGNAL AssertWAITOut : std_logic := '0'; SIGNAL DeassertWAITOut : std_logic := '0'; --timing check violation SIGNAL Viol : X01 := '0'; --zero delay signals SIGNAL DQOut_zd : std_logic_vector(15 downto 0):=(OTHERS=>'Z'); SIGNAL DQOut_pass : std_logic_vector(15 DOWNTO 0):=(OTHERS=>'Z'); SIGNAL WAITOut_zd : std_logic := 'Z'; --access time variables SHARED VARIABLE FROMOEx : BOOLEAN; SHARED VARIABLE FROMCEx : BOOLEAN; SHARED VARIABLE FROMOE : BOOLEAN; SHARED VARIABLE FROMCE : BOOLEAN; --variables for delay SHARED VARIABLE t_DQx, t_DQ : VitalDelayType := 0 ns; --Memory array declaration TYPE MemStore IS ARRAY (0 to MemSize) OF INTEGER RANGE -1 TO MaxData; SHARED VARIABLE Mem : MemStore := (OTHERS => MaxData); --Device Registers --Read Configuration Register SIGNAL RCR : std_logic_vector(15 downto 0) := "1011111111001111"; --Status Register SIGNAL SR : std_logic_vector(7 downto 0) := "10000000"; --Protection registers TYPE PR_type IS ARRAY(16#80# TO 16#109#) OF INTEGER RANGE -1 TO MaxData; SHARED VARIABLE PR : PR_type := (OTHERS => 16#FFFF#); --Block Lock Status TYPE block_status_t IS (UNLOCKED, LOCKED, LOCKED_DOWN); TYPE blocks_status IS ARRAY (HiBlockNum downto 0) OF block_status_t; SHARED VARIABLE Block_Lock : blocks_status := (OTHERS => LOCKED); SHARED VARIABLE BlockLockBit : std_logic_vector(HiBlockNum downto 0) := (OTHERS =>'1'); SHARED VARIABLE BlockLockDownBit: std_logic_vector(HiBlockNum downto 0) := (OTHERS =>'0'); --OTP Block Status -- '0' - block is not OTP (default) -- '1' - block is OTP SHARED VARIABLE OTP: std_logic_vector(HiBlockNum downto 0) := (OTHERS =>'0'); --CFI Array --Common Flash Interface Query codes TYPE CFItype IS ARRAY (16#10# TO 16#156#) OF NATURAL RANGE 0 TO 16#100#; SHARED VARIABLE CFI_array : CFItype := (OTHERS => 0); SIGNAL AddressChange : std_logic := '0'; SIGNAL Pmode : std_logic := '0'; SIGNAL CLOCK : std_logic := '0'; SHARED VARIABLE LATCHED : BOOLEAN; SHARED VARIABLE LatchedAddr : NATURAL; SHARED VARIABLE LatchedData : NATURAL; SHARED VARIABLE ReadAddr : NATURAL; TYPE BUFF IS ARRAY (0 TO 31) OF NATURAL; SHARED VARIABLE DataBuff : BUFF; SHARED VARIABLE AddrBuff : BUFF; SHARED VARIABLE burst_cntr : INTEGER := 0; SHARED VARIABLE BurstLength : NATURAL := 0; FUNCTION BlockNumber(ADDR: NATURAL) RETURN NATURAL IS VARIABLE block_number: NATURAL; BEGIN block_number := ADDR / MainBlockSize; IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T') THEN IF block_number = (MemSize/MainBlockSize) THEN block_number := block_number + (ADDR mod MainBlockSize) / ParameterBlockSize; END IF; ELSIF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN IF block_number = 0 THEN block_number := block_number + (ADDR mod MainBlockSize) / ParameterBlockSize; ELSE block_number := block_number + MainBlockSize / ParameterBlockSize - 1; END IF; END IF; RETURN block_number; END BlockNumber; FUNCTION StartBlockAddr(block_number: NATURAL ) RETURN NATURAL IS VARIABLE start_block_addr: NATURAL; BEGIN IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T') THEN start_block_addr := block_number * MainBlockSize; IF block_number > (HiBlockNum - 3) THEN start_block_addr := start_block_addr - (block_number + 3 - HiBlockNum) * MainBlockSize + (block_number + 3 - HiBlockNum) * ParameterBlockSize; END IF; ELSIF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN IF block_number < 4 THEN start_block_addr := block_number * ParameterBlockSize; ELSE start_block_addr := (block_number - 3) * MainBlockSize; END IF; END IF; RETURN start_block_addr; END StartBlockAddr; FUNCTION BlockSize(block_number: NATURAL) RETURN NATURAL IS VARIABLE block_size: NATURAL; BEGIN IF (block_number < 4 AND ((TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B'))) OR (block_number > (HiBlockNum - 4) AND ((TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T'))) THEN block_size := ParameterBlockSize; ELSE block_size := MainBlockSize; END IF; RETURN block_size; END BlockSize; BEGIN --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(A, DQIn, ADVNeg, CENeg, CLK, RSTNeg, WENeg, WPNeg) -- Timing Check Variables VARIABLE Tviol_A1_ADVNeg : X01 := '0'; VARIABLE TD_A1_ADVNeg : VitalTimingDataType; VARIABLE Tviol_CENeg_ADVNeg : X01 := '0'; VARIABLE TD_CENeg_ADVNeg : VitalTimingDataType; VARIABLE Tviol_RSTNeg_ADVNeg : X01 := '0'; VARIABLE TD_RSTNeg_ADVNeg : VitalTimingDataType; VARIABLE Tviol_WENeg_ADVNeg : X01 := '0'; VARIABLE TD_WENeg_ADVNeg : VitalTimingDataType; VARIABLE Tviol_A1_CLK_rising : X01 := '0'; VARIABLE TD_A1_CLK_rising : VitalTimingDataType; VARIABLE Tviol_A1_CLK_falling : X01 := '0'; VARIABLE TD_A1_CLK_falling : VitalTimingDataType; VARIABLE Tviol_ADVNeg_CLK_rising : X01 := '0'; VARIABLE TD_ADVNeg_CLK_rising : VitalTimingDataType; VARIABLE Tviol_ADVNeg_CLK_falling : X01 := '0'; VARIABLE TD_ADVNeg_CLK_falling : VitalTimingDataType; VARIABLE Tviol_CENeg_CLK_rising : X01 := '0'; VARIABLE TD_CENeg_CLK_rising : VitalTimingDataType; VARIABLE Tviol_CENeg_CLK_falling : X01 := '0'; VARIABLE TD_CENeg_CLK_falling : VitalTimingDataType; VARIABLE Tviol_WENeg_CLK_rising : X01 := '0'; VARIABLE TD_WENeg_CLK_rising : VitalTimingDataType; VARIABLE Tviol_WENeg_CLK_falling : X01 := '0'; VARIABLE TD_WENeg_CLK_falling : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_setup : X01 := '0'; VARIABLE TD_CENeg_WENeg_setup : VitalTimingDataType; VARIABLE Tviol_DQ0_WENeg : X01 := '0'; VARIABLE TD_DQ0_WENeg : VitalTimingDataType; VARIABLE Tviol_A1_WENeg : X01 := '0'; VARIABLE TD_A1_WENeg : VitalTimingDataType; VARIABLE Tviol_WPNeg_WENeg : X01 := '0'; VARIABLE TD_WPNeg_WENeg : VitalTimingDataType; VARIABLE Tviol_ADVNeg_WENeg : X01 := '0'; VARIABLE TD_ADVNeg_WENeg : VitalTimingDataType; VARIABLE Tviol_CLK_rising_WENeg : X01 := '0'; VARIABLE TD_CLK_rising_WENeg : VitalTimingDataType; VARIABLE Tviol_CLK_falling_WENeg : X01 := '0'; VARIABLE TD_CLK_falling_WENeg : VitalTimingDataType; VARIABLE Tviol_WENeg_OENeg : X01 := '0'; VARIABLE TD_WENeg_OENeg : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_hold : X01 := '0'; VARIABLE TD_CENeg_WENeg_hold : VitalTimingDataType; VARIABLE Pviol_CENeg : X01 := '0'; VARIABLE PD_CENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_ADVNeg : X01 := '0'; VARIABLE PD_ADVNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_WENeg : X01 := '0'; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_RSTNeg : X01 := '0'; VARIABLE PD_RSTNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CLK : X01 := '0'; VARIABLE PD_CLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Rviol_RSTNeg_WENeg : X01 := '0'; VARIABLE RD_RSTNeg_WENeg : VitalTimingDataType; VARIABLE Violation : X01 := '0'; BEGIN --------------------------------------------------------------------------- -- Timing Check Section --------------------------------------------------------------------------- IF (TimingChecksOn) THEN VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupHigh => tsetup_A1_ADVNeg, SetupLow => tsetup_A1_ADVNeg, HoldHigh => thold_A1_ADVNeg, HoldLow => thold_A1_ADVNeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A1_ADVNeg, Violation => Tviol_A1_ADVNeg ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupLow => tsetup_CENeg_ADVNeg, CheckEnabled => CENeg='0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_ADVNeg, Violation => Tviol_CENeg_ADVNeg ); VitalSetupHoldCheck ( TestSignal => RSTNeg, TestSignalName => "RSTNeg", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupLow => tsetup_RSTNeg_ADVNeg, CheckEnabled => RSTNeg='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_RSTNeg_ADVNeg, Violation => Tviol_RSTNeg_ADVNeg ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupHigh => tsetup_WENeg_ADVNeg, CheckEnabled => WENeg='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_ADVNeg, Violation => Tviol_WENeg_ADVNeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_A1_CLK, SetupLow => tsetup_A1_CLK, CheckEnabled => RCR(6)='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A1_CLK_rising, Violation => Tviol_A1_CLK_rising ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_A1_CLK, SetupLow => tsetup_A1_CLK, CheckEnabled => RCR(6)='0', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A1_CLK_falling, Violation => Tviol_A1_CLK_falling ); VitalSetupHoldCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_ADVNeg_CLK, CheckEnabled => RCR(6)='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_ADVNeg_CLK_rising, Violation => Tviol_ADVNeg_CLK_rising ); VitalSetupHoldCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_ADVNeg_CLK, CheckEnabled => RCR(6)='0', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_ADVNeg_CLK_falling, Violation => Tviol_ADVNeg_CLK_falling ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_CENeg_CLK, CheckEnabled => RCR(6)='1' AND CENeg='0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_CLK_rising, Violation => Tviol_CENeg_CLK_rising ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_CENeg_CLK, CheckEnabled => RCR(6)='0' AND CENeg='0', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_CLK_falling, Violation => Tviol_CENeg_CLK_falling ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_WENeg_CLK, CheckEnabled => RCR(6)='1' AND WENeg='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CLK_rising, Violation => Tviol_WENeg_CLK_rising ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_WENeg_CLK, CheckEnabled => RCR(6)='0' AND WENeg='1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CLK_falling, Violation => Tviol_WENeg_CLK_falling ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => true, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_setup, Violation => Tviol_CENeg_WENeg_setup ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldLow => thold_CENeg_WENeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_hold, Violation => Tviol_CENeg_WENeg_hold ); VitalSetupHoldCheck ( TestSignal => DQIn, TestSignalName => "DQ", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_DQ0_WENeg, SetupLow => tsetup_DQ0_WENeg, HoldHigh => thold_DQ0_WENeg, HoldLow => thold_DQ0_WENeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_DQ0_WENeg, Violation => Tviol_DQ0_WENeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_A1_WENeg, SetupLow => tsetup_A1_WENeg, HoldHigh => thold_A1_WENeg, HoldLow => thold_A1_WENeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A1_WENeg, Violation => Tviol_A1_WENeg ); VitalSetupHoldCheck ( TestSignal => WPNeg, TestSignalName => "WPNeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_WPNeg_WENeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WPNeg_WENeg, Violation => Tviol_WPNeg_WENeg ); VitalSetupHoldCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_ADVNeg_WENeg, CheckEnabled => ADVNeg='1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_ADVNeg_WENeg, Violation => Tviol_ADVNeg_WENeg ); VitalSetupHoldCheck ( TestSignal => CLK, TestSignalName => "CLK", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_CLK_WENeg, CheckEnabled => RCR(6)='1' AND CLK='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CLK_rising_WENeg, Violation => Tviol_CLK_rising_WENeg ); VitalSetupHoldCheck ( TestSignal => CLK, TestSignalName => "CLK", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_CLK_WENeg, CheckEnabled => RCR(6)='0' AND CLK='0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CLK_falling_WENeg, Violation => Tviol_CLK_falling_WENeg ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => OENeg, RefSignalName => "OENeg", SetupHigh => tsetup_WENeg_OENeg, CheckEnabled => WENeg='1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_OENeg, Violation => Tviol_WENeg_OENeg ); VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CENeg", PulseWidthHigh => tpw_CENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg, Violation => Pviol_CENeg ); VitalPeriodPulseCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", PulseWidthHigh => tpw_ADVNeg_posedge, PulseWidthLow => tpw_ADVNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_ADVNeg, Violation => Pviol_ADVNeg ); VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WENeg", PulseWidthHigh => tpw_WENeg_posedge, PulseWidthLow => tpw_WENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, Violation => Pviol_WENeg ); VitalPeriodPulseCheck ( TestSignal => RSTNeg, TestSignalName => "RSTNeg", PulseWidthLow => tpw_RSTNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RSTNeg, Violation => Pviol_RSTNeg ); VitalPeriodPulseCheck ( TestSignal => CLK, TestSignalName => "CLK", Period => tperiod_CLK, PulseWidthHigh => tpw_CLK_posedge, PulseWidthLow => tpw_CLK_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CLK, Violation => Pviol_CLK ); VitalRecoveryRemovalCheck ( TestSignal => RSTNeg, TestSignalName => "RSTNeg", RefSignal => WENeg, RefSignalName => "WENeg", Recovery => trecovery_RSTNeg_WENeg, ActiveLow => true, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => RD_RSTNeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Rviol_RSTNeg_WENeg ); Violation := Tviol_A1_ADVNeg OR Tviol_CENeg_ADVNeg OR Tviol_RSTNeg_ADVNeg OR Tviol_WENeg_ADVNeg OR Tviol_A1_CLK_rising OR Tviol_A1_CLK_falling OR Tviol_ADVNeg_CLK_rising OR Tviol_ADVNeg_CLK_falling OR Tviol_CENeg_CLK_rising OR Tviol_CENeg_CLK_falling OR Tviol_WENeg_CLK_rising OR Tviol_WENeg_CLK_falling OR Tviol_CENeg_WENeg_setup OR Tviol_CENeg_WENeg_hold OR Tviol_DQ0_WENeg OR Tviol_A1_WENeg OR Tviol_WPNeg_WENeg OR Tviol_ADVNeg_WENeg OR Tviol_CLK_rising_WENeg OR Tviol_CLK_falling_WENeg OR Tviol_WENeg_OENeg OR Pviol_CENeg OR Pviol_ADVNeg OR Pviol_WENeg OR Pviol_CLK OR Rviol_RSTNeg_WENeg; Viol <= Violation; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY WARNING; END IF; END PROCESS VITALTimingCheck; -- clocked process for FSM state transition PROCESS(next_state) BEGIN IF (ExtendProgTime = FALSE) THEN current_state <= next_state; END IF; END PROCESS; RSTControl : PROCESS(RSTNeg) BEGIN IF falling_edge(RSTNeg) THEN IF WordProgram_out = '1' OR BuffProgram_out ='1' OR ParameterErase_out = '1' OR MainErase_out = '1' OR BEFP_out = '1' THEN RstDuringErsPrg_in <= '1', '0' AFTER 1 ns; END IF; END IF; END PROCESS RSTControl; CLKControl : PROCESS(CLK) BEGIN IF RSTNeg = '1' AND CENeg = '0' AND WENeg = '1' AND ((RCR(6) = '0' AND falling_edge(CLK)) OR (RCR(6) = '1' AND rising_edge(CLK))) THEN CLOCK <= '1', '0' AFTER 1 ns; END IF; END PROCESS CLKControl; BusCycleDecode : PROCESS(A, DQin, WENeg, OENeg, CENeg, ADVNeg, CLOCK, RSTNeg) VARIABLE BurstDelay : NATURAL RANGE 0 TO 7; VARIABLE DataHold : NATURAL RANGE 0 TO 1; BEGIN IF (RSTNeg = '0') OR (CENeg = '1') OR falling_edge(ADVNeg) THEN LATCHED := FALSE; END IF; IF RSTNeg = '1' AND current_state /= RESET_POWER_DOWN THEN -- Address latch IF CENeg = '0' AND LATCHED = FALSE AND ((rising_edge(ADVNeg) AND WENeg = '1') OR (ADVNeg = '0' AND WENeg = '1' AND RCR(15) = '0' AND rising_edge(CLOCK))) THEN LatchedAddr := to_nat(A); ReadAddr := LatchedAddr; LATCHED := TRUE; burst_cntr := 0; BurstDelay := to_nat(RCR(13 downto 11)); CASE RCR(2 downto 0) IS WHEN "001" => BurstLength := 4; WHEN "010" => BurstLength := 8; WHEN "011" => BurstLength := 16; WHEN OTHERS => BurstLength := 0; END CASE; DataHold := 0; END IF; -- Write control IF OENeg = '1' THEN IF WENeg = '0' AND CENeg = '0' THEN Write <= '0'; ELSIF (CENeg = '0' AND rising_edge(WENeg)) OR (WENeg = '0' AND rising_edge(CENeg)) OR (rising_edge(WENeg) AND rising_edge(CENeg)) THEN LatchedData := to_nat(DQIn); LatchedAddr := to_nat(A); Write <= '1'; END IF; END IF; -- Read control IF RCR(15) = '1' THEN IF WENeg = '1' AND CENeg = '0' AND OENeg = '0' THEN IF (ADVNeg = '0') THEN ReadAddr := to_nat(A); END IF; Read <= '1'; ELSE Read <= '0'; Pmode <= '0'; END IF; IF Read = '1' AND A(1 downto 0)'EVENT THEN Pmode <= '1', '0' AFTER 2 ns; END IF; ELSE IF rising_edge(CLOCK) THEN IF BurstDelay > 0 THEN BurstDelay := BurstDelay - 1; IF RCR(8) = '1' AND (BurstDelay = 0 OR (BurstDelay = 1 AND RCR(9) = '1')) THEN DeassertWAITOut <= NOT DeassertWAITOut; END IF; ELSE IF DataHold = 0 THEN burst_cntr := burst_cntr + 1; IF OENeg = '0' THEN Read <= NOT Read; END IF; IF RCR(9) = '1' THEN DataHold := 1; END IF; IF burst_cntr > (BurstLength - to_nat(RCR(8))) AND BurstLength > 0 THEN AssertWAITOut <= NOT AssertWAITOut; -- Extra wait cycles will occur after every 4 words -- if DH = 1 clock cycle -- (variable burst_cntr is updated -- in Output process below): ELSIF read_state = READ_ARRAY AND RCR(9) = '0' AND to_nat(RCR(13 downto 11)) > 4 THEN IF RCR(8) = '0' THEN -- WAIT with data IF burst_cntr > 4 OR burst_cntr <= 0 THEN AssertWAITOut <= NOT AssertWAITOut; ELSE DeassertWAITOut <= NOT DeassertWAITOut; END IF; ELSE -- WAIT before data IF burst_cntr >= 4 OR burst_cntr < 0 THEN AssertWAITOut <= NOT AssertWAITOut; ELSE DeassertWAITOut <= NOT DeassertWAITOut; END IF; END IF; ELSE DeassertWAITOut <= NOT DeassertWAITOut; END IF; ELSE DataHold := DataHold - 1; END IF; END IF; END IF; END IF; END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- FSM Process -- combinational process for next state generation --------------------------------------------------------------------------- StateGen: PROCESS(RSTNeg, Write, abort, WordProgram_out, BuffProgram_out, ExtendProgTime, BEFP_out, BEFPsetup_out, ParameterErase_out, MainErase_out, ProgramSuspend_out, EraseSuspend_out, RstDuringErsPrg_out) VARIABLE word_cntr : NATURAL := 0; VARIABLE BEFP_block : NATURAL := 0; BEGIN IF falling_edge(RSTNeg) THEN next_state <= RESET_POWER_DOWN; ELSE CASE current_state IS WHEN RESET_POWER_DOWN => IF (rising_edge(RSTNeg) AND RstDuringErsPrg_out = '0') OR (RstDuringErsPrg_out'EVENT AND RstDuringErsPrg_out = '0') THEN next_state <= READY; END IF; WHEN READY => IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#10# | 16#40# => next_state <= PROG_SETUP; WHEN 16#E8# => next_state <= BP_SETUP; WHEN 16#20# => next_state <= ERASE_SETUP; WHEN 16#80# => next_state <= BEFP_SETUP; WHEN 16#60# => next_state <= LOCK_SETUP; WHEN 16#C0# => next_state <= OTP_SETUP; WHEN OTHERS => next_state <= current_state; END CASE; END IF; WHEN LOCK_SETUP => IF rising_edge(Write) THEN next_state <= READY; END IF; WHEN OTP_SETUP => IF rising_edge(Write) THEN next_state <= OTP_BUSY; END IF; WHEN OTP_BUSY => IF abort'EVENT OR (WordProgram_out'EVENT AND WordProgram_out = '0') THEN next_state <= READY; END IF; WHEN PROG_SETUP => IF rising_edge(Write) THEN next_state <= PROG_BUSY; END IF; WHEN PROG_BUSY => IF abort'EVENT OR (WordProgram_out'EVENT AND WordProgram_out = '0') THEN next_state <= READY; ELSIF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN next_state <= PROG_SUSP; END IF; WHEN PROG_SUSP => IF rising_edge(Write) AND LatchedData = 16#D0# THEN next_state <= PROG_BUSY; END IF; WHEN BP_SETUP => IF rising_edge(Write) THEN word_cntr := LatchedData + 1; next_state <= BP_LOAD; END IF; WHEN BP_LOAD => IF rising_edge(Write) THEN word_cntr := word_cntr - 1; IF word_cntr = 0 THEN next_state <= BP_CONFIRM; END IF; END IF; WHEN BP_CONFIRM => IF rising_edge(Write) THEN IF LatchedData = 16#D0# THEN next_state <= BP_BUSY; ELSE next_state <= READY; END IF; END IF; WHEN BP_BUSY => IF abort'EVENT OR (BuffProgram_out'EVENT AND BuffProgram_out = '0') THEN next_state <= READY; ELSIF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN next_state <= BP_SUSP; ELSIF ExtendProgTime'EVENT THEN next_state <= current_state; END IF; WHEN BP_SUSP => IF rising_edge(Write) AND LatchedData = 16#D0# THEN next_state <= BP_BUSY; END IF; WHEN ERASE_SETUP => IF rising_edge(Write) THEN IF LatchedData=16#D0# THEN next_state <= ERASE_BUSY; ELSE next_state <= READY; END IF; END IF; WHEN ERASE_BUSY => IF abort'EVENT OR (ParameterErase_out'EVENT AND ParameterErase_out = '0') OR (MainErase_out'EVENT AND MainErase_out = '0') THEN next_state <= READY; ELSIF EraseSuspend_out'EVENT AND EraseSuspend_out = '0' THEN next_state <= ERS_SUSP; END IF; WHEN ERS_SUSP => IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#10# | 16#40# => next_state <= PROG_SETUP_ERS_SUSP; WHEN 16#E8# => next_state <= BP_SETUP_ERS_SUSP; WHEN 16#D0# => next_state <= ERASE_BUSY; WHEN 16#60# => next_state <= LOCK_SETUP_ERS_SUSP; WHEN OTHERS => next_state <= current_state; END CASE; END IF; WHEN PROG_SETUP_ERS_SUSP => IF rising_edge(Write) THEN next_state <= PROG_BUSY_ERS_SUSP; END IF; WHEN PROG_BUSY_ERS_SUSP => IF abort'EVENT OR (WordProgram_out'EVENT AND WordProgram_out = '0') THEN next_state <= ERS_SUSP; ELSIF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN next_state <= PROG_SUSP_ERS_SUSP; END IF; WHEN PROG_SUSP_ERS_SUSP=> IF rising_edge(Write) AND LatchedData = 16#D0# THEN next_state <= PROG_BUSY_ERS_SUSP; END IF; WHEN BP_SETUP_ERS_SUSP => IF rising_edge(Write) THEN word_cntr := LatchedData + 1; next_state <= BP_LOAD_ERS_SUSP; END IF; WHEN BP_LOAD_ERS_SUSP => IF rising_edge(Write) THEN word_cntr := word_cntr - 1; IF word_cntr = 0 THEN next_state <= BP_CONFIRM_ERS_SUSP; END IF; END IF; WHEN BP_CONFIRM_ERS_SUSP => IF rising_edge(Write) THEN IF LatchedData=16#D0# THEN next_state <= BP_BUSY_ERS_SUSP; ELSE next_state <= ERS_SUSP; END IF; END IF; WHEN BP_BUSY_ERS_SUSP => IF abort'EVENT OR (BuffProgram_out'EVENT AND BuffProgram_out = '0') THEN next_state <= ERS_SUSP; ELSIF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN next_state <= BP_SUSP_ERS_SUSP; ELSIF ExtendProgTime'EVENT THEN next_state <= current_state; END IF; WHEN BP_SUSP_ERS_SUSP => IF rising_edge(Write) AND LatchedData = 16#D0# THEN next_state <= BP_BUSY_ERS_SUSP; END IF; WHEN LOCK_SETUP_ERS_SUSP => IF rising_edge(Write) THEN next_state <= ERS_SUSP; END IF; WHEN BEFP_SETUP => IF rising_edge(Write) THEN IF LatchedData /= 16#D0# THEN next_state <= READY; ELSE BEFP_block := BlockNumber(LatchedAddr); word_cntr := 32; END IF; ELSIF falling_edge(BEFPsetup_out) THEN IF SR(4) = '0' THEN next_state <= BEFP_LOAD; ELSE next_state <= READY; END IF; END IF; WHEN BEFP_LOAD => IF rising_edge(Write) THEN IF BlockNumber(LatchedAddr) /= BEFP_block AND LatchedData = 16#FFFF# THEN next_state <= READY; ELSE word_cntr := word_cntr - 1; IF word_cntr = 0 THEN next_state <= BEFP_BUSY; END IF; END IF; END IF; WHEN BEFP_BUSY => IF falling_edge(BEFP_out) THEN word_cntr := 32; next_state <= BEFP_LOAD; END IF; END CASE; END IF; END PROCESS StateGen; ---------------------------------------------------------------------------- -- Main behavior process ---------------------------------------------------------------------------- Functional: PROCESS(Write, WordProgram_out, current_state, RSTNeg, BuffProgram_out, VPP, ParameterErase_out, MainErase_out, BEFPsetup_out, BEFP_out) VARIABLE prog_bits : std_logic_vector(15 downto 0); VARIABLE mem_bits : std_logic_vector(15 downto 0); VARIABLE word_cntr : NATURAL := 0; VARIABLE word_number : INTEGER := 0; VARIABLE block_number : NATURAL := 0; VARIABLE erasing_block: NATURAL := 0; VARIABLE lowest_addr : NATURAL := 0; VARIABLE highest_addr : NATURAL := 0; VARIABLE start_addr : NATURAL := 0; VARIABLE BEFP_addr : NATURAL := 0; VARIABLE BEFP_block : NATURAL := 0; VARIABLE aborted : std_ulogic := '0'; BEGIN -- Clear Status reg IF current_state/=RESET_POWER_DOWN AND current_state/=OTP_BUSY AND current_state/=PROG_BUSY AND current_state/=BP_BUSY AND current_state/=ERASE_BUSY AND current_state/=PROG_BUSY_ERS_SUSP AND current_state/=BP_BUSY_ERS_SUSP AND current_state/=BEFP_SETUP AND current_state/=BEFP_LOAD AND rising_edge(Write) AND LatchedData = 16#50# THEN SR <= "10000000"; END IF; CASE current_state IS WHEN RESET_POWER_DOWN => SR <= "10000000"; Block_Lock := (OTHERS => LOCKED); BlockLockBit := (OTHERS =>'1'); BlockLockDownBit := (OTHERS =>'0'); read_state <= READ_ARRAY; RCR <= "1011111111001111"; WHEN READY => IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN OTHERS => NULL; END CASE; END IF; WHEN LOCK_SETUP | LOCK_SETUP_ERS_SUSP => IF rising_edge(Write) THEN block_number := BlockNumber(LatchedAddr); IF LatchedData = 16#03# THEN RCR <= A(15 DOWNTO 0); read_state <= READ_ARRAY; ELSIF LatchedData = 16#01# THEN read_state <= READ_STATUS; IF Block_Lock(block_number) = UNLOCKED THEN Block_Lock(block_number) := LOCKED; END IF; BlockLockBit(block_number) := '1'; ELSIF LatchedData = 16#D0# THEN read_state <= READ_STATUS; IF NOT(Block_Lock(block_number) = LOCKED_DOWN AND WPNeg = '0') THEN Block_Lock(block_number) := UNLOCKED; BlockLockBit(block_number) := '0'; END IF; ELSIF LatchedData = 16#2F# THEN read_state <= READ_STATUS; Block_Lock(block_number) := LOCKED_DOWN; BlockLockBit(block_number) := '1'; BlockLockDownBit(block_number) := '1'; ELSE read_state <= READ_STATUS; SR(4) <= '1'; SR(5) <= '1'; END IF; ELSE read_state <= READ_STATUS; END IF; WHEN OTP_SETUP => read_state <= READ_STATUS; IF rising_edge(Write) THEN DataBuff(0) := LatchedData; AddrBuff(0) := LatchedAddr; WordProgram_in <= '1', '0' AFTER 1 ns; END IF; WHEN OTP_BUSY => IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# | 16#90# | 16#98# => read_state <= READ_STATUS; WHEN OTHERS => NULL; END CASE; END IF; mem_bits := to_slv(PR(16#80#), 16); prog_bits := to_slv(PR(16#89#), 16); SR(7) <= '0'; IF VPP /= '1' THEN SR(3) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF AddrBuff(0) < 16#80# OR AddrBuff(0) > 16#109# THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF AddrBuff(0) > 16#80# AND AddrBuff(0) < 16#85# THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF AddrBuff(0) > 16#84# AND AddrBuff(0) < 16#89# AND mem_bits(1) /= '1' THEN SR(1) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF AddrBuff(0) > 16#89# AND AddrBuff(0) < 16#10A# THEN IF prog_bits((AddrBuff(0)-16#8A#)/8) /= '1' THEN SR(1) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; END IF; END IF; IF falling_edge(RSTNeg) THEN PR(AddrBuff(0)) := -1; END IF; IF (WordProgram_out'EVENT AND WordProgram_out = '0' AND abort = '0' ) THEN IF PR(AddrBuff(0)) > -1 THEN prog_bits := to_slv(DataBuff(0), 16); mem_bits := to_slv(PR(AddrBuff(0)), 16); FOR I IN 0 TO 15 LOOP IF prog_bits(I) = '0' THEN mem_bits(I) := '0'; END IF; END LOOP; PR(AddrBuff(0)) := to_nat(mem_bits); END IF; SR(7) <= '1'; END IF; WHEN PROG_SETUP | PROG_SETUP_ERS_SUSP => read_state <= READ_STATUS; IF rising_edge(Write) THEN DataBuff(0) := LatchedData; AddrBuff(0) := LatchedAddr; WordProgram_in <= '1', '0' AFTER 1 ns; END IF; WHEN PROG_BUSY | PROG_BUSY_ERS_SUSP => SR(2) <= '0'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#B0# => ProgramSuspend_in <= '1', '0' AFTER 1 ns; WHEN OTHERS => NULL; END CASE; END IF; block_number := BlockNumber(AddrBuff(0)); IF VPP = '0' THEN SR(3) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF OTP(block_number) = '1' THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF Block_Lock(block_number) /= UNLOCKED THEN SR(1) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSE SR(7) <= '0'; END IF; IF falling_edge(RSTNeg) THEN Mem(AddrBuff(0)) := -1; END IF; IF ( WordProgram_out'EVENT AND WordProgram_out = '0' AND abort = '0' ) THEN IF (Mem(AddrBuff(0)) > -1) THEN prog_bits := to_slv(DataBuff(0), 16); mem_bits := to_slv(Mem(AddrBuff(0)), 16); FOR I IN 0 TO 15 LOOP IF prog_bits(I) = '0' THEN mem_bits(I) := '0'; END IF; END LOOP; Mem(AddrBuff(0)) := to_nat(mem_bits); END IF; SR(7) <= '1'; END IF; WHEN PROG_SUSP | PROG_SUSP_ERS_SUSP => SR(2) <= '1'; SR(7) <= '1'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#D0# => WordProgramResume <= '1', '0' AFTER 1 ns; WHEN OTHERS => NULL; END CASE; END IF; WHEN BP_SETUP | BP_SETUP_ERS_SUSP => read_state <= READ_STATUS; IF rising_edge(Write) THEN word_number := LatchedData; word_cntr := 0; END IF; WHEN BP_LOAD | BP_LOAD_ERS_SUSP => read_state <= READ_STATUS; IF rising_edge(Write) THEN DataBuff(word_cntr) := LatchedData; AddrBuff(word_cntr) := LatchedAddr; IF word_cntr = 0 THEN lowest_addr := LatchedAddr; highest_addr := LatchedAddr; ELSE IF LatchedAddr < lowest_addr THEN lowest_addr := LatchedAddr; END IF; IF LatchedAddr > highest_addr THEN highest_addr := LatchedAddr; END IF; END IF; word_cntr := word_cntr + 1; END IF; WHEN BP_CONFIRM | BP_CONFIRM_ERS_SUSP => read_state <= READ_STATUS; IF rising_edge(Write) THEN IF LatchedData = 16#D0# THEN BuffProgram_in <= '1', '0' AFTER 1 ns; ELSE SR(7) <= '1'; SR(5) <= '1'; SR(4) <= '1'; END IF; END IF; WHEN BP_BUSY | BP_BUSY_ERS_SUSP => SR(2) <= '0'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#B0# => ProgramSuspend_in <= '1', '0' AFTER 1 ns; bp_suspend := '1'; WHEN OTHERS => NULL; END CASE; END IF; block_number := BlockNumber(AddrBuff(0)); IF VPP = '0' THEN SR(3) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF OTP(block_number) = '1' THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF Block_Lock(block_number) /= UNLOCKED THEN SR(1) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF lowest_addr < AddrBuff(0) OR (highest_addr > (AddrBuff(0) + word_number) AND word_number /= -1) THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF BlockNumber(highest_addr) /= block_number THEN SR(4) <= '1'; SR(5) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSE SR(7) <= '0'; END IF; IF falling_edge(RSTNeg) THEN FOR J IN 0 TO word_number LOOP Mem(AddrBuff(J)) := -1; END LOOP; END IF; IF BuffProgram_out'EVENT AND BuffProgram_out = '0' AND abort = '0' THEN FOR J IN 0 TO word_number LOOP IF (Mem(AddrBuff(J)) > -1) THEN prog_bits := to_slv(DataBuff(J), 16); mem_bits := to_slv(Mem(AddrBuff(J)), 16); FOR I IN 0 TO 15 LOOP IF prog_bits(I) = '0' THEN mem_bits(I) := '0'; END IF; END LOOP; Mem(AddrBuff(J)) := to_nat(mem_bits); IF (AddrBuff(J) / 32) /= (AddrBuff(0) / 32) THEN ExtendProgTime <= TRUE, FALSE AFTER 2 ns; word_number := -1; BuffProgram_in <= '1', '0' AFTER 1 ns; END IF; END IF; END LOOP; SR(7) <= '1'; END IF; WHEN BP_SUSP | BP_SUSP_ERS_SUSP => SR(2) <= '1'; SR(7) <= '1'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#D0# => BP_ProgramResume <= '1', '0' AFTER 1 ns; bp_suspend := '0'; WHEN OTHERS => NULL; END CASE; END IF; WHEN ERASE_SETUP => read_state <= READ_STATUS; IF rising_edge(Write) THEN IF LatchedData = 16#D0# THEN erasing_block := BlockNumber(LatchedAddr); IF BlockSize(erasing_block) = ParameterBlockSize THEN ParameterErase_in <= '1' , '0' AFTER 1 ns; ELSE MainErase_in <= '1' , '0' AFTER 1 ns; END IF; ELSE SR(7) <= '1'; SR(5) <= '1'; SR(4) <= '1'; END IF; END IF; WHEN ERASE_BUSY => SR(6) <= '0'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#B0# => EraseSuspend_in <= '1', '0' AFTER 1 ns; WHEN OTHERS => NULL; END CASE; END IF; aborted := '0'; IF VPP = '0' THEN SR(3) <= '1'; SR(5) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; aborted := '1'; ELSIF OTP(erasing_block) = '1' THEN SR(5) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; aborted := '1'; ELSIF Block_Lock(erasing_block) /= UNLOCKED THEN SR(1) <= '1'; SR(5) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; aborted := '1'; ELSE SR(7) <= '0'; END IF; start_addr := StartBlockAddr(erasing_block); IF (aborted = '0') THEN FOR I IN 0 TO (BlockSize(erasing_block) - 1) LOOP Mem(start_addr + I) := -1; END LOOP; END IF; IF ((ParameterErase_out'EVENT AND ParameterErase_out = '0') OR (MainErase_out'EVENT AND MainErase_out = '0')) AND abort = '0' THEN FOR I IN 0 TO (BlockSize(erasing_block) - 1) LOOP Mem(start_addr + I) := MaxData; END LOOP; SR(7) <= '1'; END IF; WHEN ERS_SUSP => SR(6) <= '1'; SR(7) <= '1'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#D0# => IF BlockSize(erasing_block) = ParameterBlockSize THEN ParameterEraseResume <= '1', '0' AFTER 1 ns; ELSE MainEraseResume <= '1', '0' AFTER 1 ns; END IF; WHEN OTHERS => NULL; END CASE; END IF; WHEN BEFP_SETUP => read_state <= READ_STATUS; IF rising_edge(Write) AND LatchedData = 16#D0# THEN BEFP_addr := LatchedAddr; BEFP_block := BlockNumber(LatchedAddr); word_cntr := 0; IF VPP /= '1' OR VPP_voltage /= 9 THEN SR(3) <= '1'; SR(4) <= '1'; END IF; IF Block_Lock(BEFP_block) /= UNLOCKED THEN SR(1) <= '1'; SR(4) <= '1'; ELSIF (BEFP_addr mod 32) /= 0 OR OTP(BEFP_block) = '1' THEN SR(4) <= '1'; END IF; BEFPsetup_in <= '1', '0' AFTER 1 ns; ELSIF falling_edge(BEFPsetup_out) THEN IF SR(4) = '0' THEN SR(7) <= '0'; SR(0) <= '0'; END IF; END IF; WHEN BEFP_LOAD => IF rising_edge(Write) THEN IF BlockNumber(LatchedAddr) /= BEFP_block AND LatchedData = 16#FFFF# THEN SR(7) <= '1'; SR(0) <= '0'; ELSE DataBuff(word_cntr) := LatchedData; word_cntr := word_cntr + 1; IF word_cntr = 31 THEN BEFP_in <= '1', '0' AFTER 1 ns; END IF; END IF; END IF; WHEN BEFP_BUSY => IF falling_edge(RSTNeg) THEN FOR J IN 0 TO 31 LOOP Mem(BEFP_addr + J) := -1; END LOOP; END IF; IF falling_edge(BEFP_out) THEN FOR J IN 0 TO 31 LOOP IF Mem(BEFP_addr + J) > -1 THEN prog_bits := to_slv(DataBuff(J), 16); mem_bits := to_slv(Mem(BEFP_addr + J), 16); FOR I IN 0 TO 15 LOOP IF prog_bits(I) = '0' THEN mem_bits(I) := '0'; END IF; END LOOP; Mem(BEFP_addr + J) := to_nat(mem_bits); END IF; END LOOP; BEFP_addr := BEFP_addr + 32; IF BEFP_addr > MemSize OR BlockNumber(BEFP_addr) > BEFP_block THEN BEFP_addr := BEFP_addr - BlockSize(BEFP_block); END IF; SR(0) <= '0'; word_cntr := 0; ELSE SR(0) <= '1'; END IF; WHEN OTHERS => NULL; END CASE; END PROCESS Functional; --------------------------------------------------------------------------- -- combinatorial output generation --------------------------------------------------------------------------- Output: PROCESS(Read, A, OENeg, CENeg) VARIABLE DQOut_tmp : std_logic_vector(15 downto 0); VARIABLE read_out : boolean; BEGIN CASE read_state IS WHEN READ_ARRAY => IF RCR(15) = '1' THEN IF A(HiAddrBit downto 2)'EVENT AND ADVNeg = '0' THEN ReadAddr := to_nat(A); ELSIF A(1 downto 0)'EVENT THEN ReadAddr := ReadAddr - (ReadAddr mod 4) + to_nat(A(1 downto 0)); END IF; END IF; IF current_state = PROG_BUSY OR current_state = PROG_BUSY_ERS_SUSP OR current_state = BP_BUSY OR current_state = BP_BUSY_ERS_SUSP OR current_state = ERASE_BUSY THEN DQOut_tmp := (OTHERS => 'U'); ELSE IF Mem(ReadAddr) > -1 THEN DQOut_tmp := to_slv(Mem(ReadAddr), 16); ELSE DQOut_tmp := "XXXXXXXXXXXXXXXX"; END IF; END IF; WHEN READ_ID => IF (((ReadAddr-2) mod MainBlockSize) = 0) OR (((TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B')) AND (ReadAddr < MainBlockSize AND ((ReadAddr-2) mod ParameterBlockSize) = 0)) OR (((TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T')) AND (ReadAddr > (MemSize - MainBlockSize) AND ((ReadAddr-2) mod ParameterBlockSize) = 0)) THEN DQOut_tmp(0) := BlockLockBit( BlockNumber(ReadAddr)); DQOut_tmp(1) := BlockLockDownBit( BlockNumber(ReadAddr)); DQOut_tmp(15 DOWNTO 2) := (OTHERS=>'0'); ELSIF ReadAddr = 16#00# THEN DQOut_tmp := to_slv(16#0089#, 16); ELSIF ReadAddr = 16#01# THEN IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN DQOut_tmp := to_slv(DeviceID_B, 16); ELSIF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T') THEN DQOut_tmp := to_slv(DeviceID_T, 16); END IF; ELSIF ReadAddr = 16#05# THEN DQOut_tmp := RCR; ELSIF ReadAddr >= 16#80# AND ReadAddr <= 16#109# THEN IF PR(ReadAddr) > -1 THEN DQOut_tmp := to_slv(PR(ReadAddr), 16); ELSE DQOut_tmp := "XXXXXXXXXXXXXXXX"; END IF; END IF; WHEN READ_QUERY => IF (ReadAddr >= 16#10# AND ReadAddr <= 16#38#) OR (ReadAddr >= 16#10A# AND ReadAddr <= 16#156#) THEN DQOut_tmp := to_slv(CFI_array(ReadAddr), 16); ELSE -- RESERVED OR Address out of range DQOut_tmp := (OTHERS => '0'); END IF; WHEN OTHERS => DQOut_tmp(7 downto 0) := SR; DQOut_tmp(15 downto 8) := (OTHERS => '0'); END CASE; IF RCR(15) = '1' THEN -- Asynchronous read IF rising_edge(Read) OR (Read = '1' AND ((A'EVENT AND ADVNeg = '0') OR (A(1 downto 0)'EVENT ))) THEN DQOut_zd <= DQOut_tmp; ELSIF falling_edge(Read) THEN DQOut_zd <= (others => 'Z'); END IF; ELSE -- Burst read IF Read'EVENT THEN IF burst_cntr > BurstLength AND BurstLength /= 0 THEN read_out := FALSE; ELSIF read_state = READ_ARRAY THEN IF RCR(9) = '0' AND to_nat(RCR(13 downto 11)) > 4 AND (burst_cntr >= 5 OR burst_cntr < 1) THEN read_out := FALSE; IF burst_cntr >= 5 THEN burst_cntr := 5 - to_nat(RCR(13 downto 11)); END IF; ELSE read_out := TRUE; IF ReadAddr < MemSize THEN ReadAddr := ReadAddr + 1; END IF; IF RCR(3) = '0' AND BurstLength /= 0 THEN IF (ReadAddr mod BurstLength) = 0 THEN ReadAddr := ReadAddr - BurstLength; END IF; END IF; END IF; ELSE read_out := TRUE; END IF; IF read_out = TRUE THEN DQOut_zd <= DQOut_tmp; ELSE DQOut_zd <= "XXXXXXXXXXXXXXX0"; END IF; ELSIF CENeg = '0' AND OENeg = '0' THEN DQOut_zd <= (OTHERS => 'X'); ELSE DQOut_zd <= (OTHERS => 'Z'); END IF; END IF; IF CENeg = '1' OR OENeg = '1' THEN DQOut_zd <= (OTHERS => 'Z'); END IF; END PROCESS Output; WAITOut_control: PROCESS(CENeg, OENeg, AssertWAITOut, DeassertWAITOut) IS PROCEDURE Assert_WAITOut IS BEGIN IF RCR(10) = '0' THEN WAITOut_zd <= '0'; ELSE WAITOut_zd <= '1'; END IF; END PROCEDURE; PROCEDURE Deassert_WAITOut IS BEGIN IF RCR(10) = '0' THEN WAITOut_zd <= '1'; ELSE WAITOut_zd <= '0'; END IF; END PROCEDURE; BEGIN IF OENeg = '1' OR CENeg = '1' OR RSTNeg = '0' OR current_state = RESET_POWER_DOWN THEN WAITOut_zd <= 'Z'; ELSIF (falling_edge(OENeg) AND CENeg = '0') OR (falling_edge(CENeg) AND OENeg = '0') THEN IF RCR(15) = '1' THEN Deassert_WAITOut; ELSE Assert_WAITOut; END IF; ELSIF AssertWAITOut'EVENT THEN Assert_WAITOut; ELSIF DeassertWAITOut'EVENT THEN Deassert_WAITOut; END IF; END PROCESS WAITOut_control; ------------------------------------------------------------------------ -- Erase start, suspend, resume process ------------------------------------------------------------------------ Erase_time: PROCESS (MainErase_in, EraseSuspend_out, MainEraseResume, ParameterErase_in, ParameterEraseResume, abort, RstDuringErsPrg_out) VARIABLE merase_duration : TIME; VARIABLE perase_duration : TIME; VARIABLE melapsed : TIME; VARIABLE pelapsed : TIME; VARIABLE mstart : TIME; VARIABLE pstart : TIME; BEGIN IF LongTiming = TRUE THEN merase_duration := tdevice_EraseMain; perase_duration := tdevice_EraseParameter; ELSE merase_duration := tdevice_EraseMain / 1000; perase_duration := tdevice_EraseParameter/1000; END IF; IF (RstDuringErsPrg_out'EVENT AND RstDuringErsPrg_out = '0') OR abort'EVENT THEN MainErase_out <= '0'; ParameterErase_out <= '0'; END IF; IF rising_edge(MainErase_in) THEN melapsed := 0 ns; MainErase_out <= '1', '0' AFTER merase_duration; mstart := NOW; END IF; IF rising_edge(ParameterErase_in) THEN pelapsed := 0 ns; ParameterErase_out <= '1', '0' AFTER perase_duration; pstart := NOW; END IF; IF EraseSuspend_out'EVENT AND EraseSuspend_out = '0' THEN melapsed := NOW - mstart; merase_duration := merase_duration - melapsed; MainErase_out <= '1'; pelapsed := NOW - pstart; perase_duration := perase_duration - pelapsed; ParameterErase_out <= '1'; END IF; IF rising_edge(MainEraseResume) THEN mstart := NOW; MainErase_out <= '1', '0' AFTER merase_duration; END IF; IF rising_edge(ParameterEraseResume) THEN pstart := NOW; ParameterErase_out <= '1', '0' AFTER perase_duration; END IF; END PROCESS Erase_time; ------------------------------------------------------------------------- -- Process for programming start, suspend, resume ------------------------------------------------------------------------- Program_time: PROCESS (BuffProgram_in, ProgramSuspend_out, BP_ProgramResume , WordProgram_in, WordProgramResume, abort, RstDuringErsPrg_out) VARIABLE buffp_duration : TIME; VARIABLE wordp_duration : TIME; VARIABLE elapsed : TIME; VARIABLE start : TIME; VARIABLE welapsed : TIME; VARIABLE wstart : TIME; BEGIN IF VPP_voltage /= 9 THEN IF LongTiming = TRUE THEN buffp_duration := tdevice_BuffProgram; ELSE buffp_duration := tdevice_BuffProgram / 10; END IF; wordp_duration := tdevice_WordProgram; ELSE IF LongTiming = TRUE THEN buffp_duration := tdevice_BuffProgram9V; ELSE buffp_duration := tdevice_BuffProgram9V / 10; END IF; wordp_duration := tdevice_WordProgram9V; END IF; IF (RstDuringErsPrg_out'EVENT AND RstDuringErsPrg_out = '0') OR abort'EVENT THEN WordProgram_out <= '0'; BuffProgram_out <= '0'; END IF; IF rising_edge(WordProgram_in) THEN welapsed := 0 ns; WordProgram_out <= '1', '0' AFTER wordp_duration; wstart := NOW; END IF; IF rising_edge(BuffProgram_in) THEN elapsed := 0 ns; BuffProgram_out <= '1', '0' AFTER buffp_duration; start := NOW; END IF; IF rising_edge(WordProgramResume) THEN wstart := NOW; WordProgram_out <= '1', '0' AFTER wordp_duration; END IF; IF rising_edge(BP_ProgramResume) THEN start := NOW; BuffProgram_out <= '1', '0' AFTER buffp_duration; END IF; IF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN IF bp_suspend = '1' THEN elapsed := NOW - start; buffp_duration := buffp_duration - elapsed; BuffProgram_out <= '1'; ELSE welapsed := NOW - wstart; wordp_duration := wordp_duration - welapsed; WordProgram_out <= '1'; END IF; END IF; END PROCESS Program_time; BEFP_time : PROCESS (BEFP_in) BEGIN IF rising_edge(BEFP_in) THEN IF LongTiming = TRUE THEN BEFP_out <= '1' , '0' AFTER tdevice_BEFP; ELSE BEFP_out <= '1' , '0' AFTER tdevice_BEFP / 10; END IF; END IF; END PROCESS BEFP_time; ---------------------------------------------------------------------------- ---- CFI Preload Process ---------------------------------------------------------------------------- CFIPreload : PROCESS BEGIN CFI_array := (OTHERS => 16#FF#); -- CFI Indentification CFI_array(16#10#):=16#51#; CFI_array(16#11#):=16#52#; CFI_array(16#12#):=16#59#; CFI_array(16#13#):=16#01#; CFI_array(16#14#):=16#00#; CFI_array(16#15#):=16#0A#; CFI_array(16#16#):=16#01#; CFI_array(16#17#):=16#00#; CFI_array(16#18#):=16#00#; CFI_array(16#19#):=16#00#; CFI_array(16#1A#):=16#00#; -- System Interface Information CFI_array(16#1B#):=16#23#; CFI_array(16#1C#):=16#36#; CFI_array(16#1D#):=16#85#; CFI_array(16#1E#):=16#95#; CFI_array(16#1F#):=16#08#; CFI_array(16#20#):=16#09#; CFI_array(16#21#):=16#0A#; CFI_array(16#22#):=16#00#; CFI_array(16#23#):=16#01#; CFI_array(16#24#):=16#01#; CFI_array(16#25#):=16#02#; CFI_array(16#26#):=16#00#; -- Device Geometry definition CFI_array(16#27#):=16#18#; CFI_array(16#28#):=16#01#; CFI_array(16#29#):=16#00#; CFI_array(16#2A#):=16#06#; CFI_array(16#2B#):=16#00#; CFI_array(16#2C#):=16#02#; IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN CFI_array(16#2D#):=16#03#; CFI_array(16#2E#):=16#00#; CFI_array(16#2F#):=16#80#; CFI_array(16#30#):=16#00#; CFI_array(16#31#):=16#7E#; CFI_array(16#32#):=16#00#; CFI_array(16#33#):=16#00#; CFI_array(16#34#):=16#02#; ELSE CFI_array(16#2D#):=16#7E#; CFI_array(16#2E#):=16#00#; CFI_array(16#2F#):=16#00#; CFI_array(16#30#):=16#02#; CFI_array(16#31#):=16#03#; CFI_array(16#32#):=16#00#; CFI_array(16#33#):=16#80#; CFI_array(16#34#):=16#00#; END IF; CFI_array(16#35#):=16#00#; CFI_array(16#36#):=16#00#; CFI_array(16#37#):=16#00#; CFI_array(16#38#):=16#00#; -- Primary-vendor specific extended query CFI_array(16#10A#):=16#50#; CFI_array(16#10B#):=16#52#; CFI_array(16#10C#):=16#49#; CFI_array(16#10D#):=16#31#; CFI_array(16#10E#):=16#34#; CFI_array(16#10F#):=16#E6#; CFI_array(16#110#):=16#01#; CFI_array(16#111#):=16#00#; CFI_array(16#112#):=16#00#; CFI_array(16#113#):=16#01#; CFI_array(16#114#):=16#03#; CFI_array(16#115#):=16#00#; CFI_array(16#116#):=16#30#; CFI_array(16#117#):=16#90#; -- Protection register information CFI_array(16#118#):=16#02#; CFI_array(16#119#):=16#80#; CFI_array(16#11A#):=16#00#; CFI_array(16#11B#):=16#03#; CFI_array(16#11C#):=16#03#; CFI_array(16#11D#):=16#89#; CFI_array(16#11E#):=16#00#; CFI_array(16#11F#):=16#00#; CFI_array(16#120#):=16#00#; CFI_array(16#121#):=16#00#; CFI_array(16#122#):=16#00#; CFI_array(16#123#):=16#00#; CFI_array(16#124#):=16#10#; CFI_array(16#125#):=16#00#; CFI_array(16#126#):=16#04#; -- Burst read information CFI_array(16#127#):=16#03#; CFI_array(16#128#):=16#04#; CFI_array(16#129#):=16#01#; CFI_array(16#12A#):=16#02#; CFI_array(16#12B#):=16#03#; CFI_array(16#12C#):=16#07#; --Partition and Erase Block Region Information CFI_array(16#12D#):=16#01#; CFI_array(16#12E#):=16#24#; CFI_array(16#12F#):=16#00#; CFI_array(16#130#):=16#01#; CFI_array(16#131#):=16#00#; CFI_array(16#132#):=16#11#; CFI_array(16#133#):=16#00#; CFI_array(16#134#):=16#00#; CFI_array(16#135#):=16#02#; IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN CFI_array(16#136#):=16#03#; CFI_array(16#137#):=16#00#; CFI_array(16#138#):=16#80#; CFI_array(16#139#):=16#00#; ELSE CFI_array(16#136#):=16#7E#; CFI_array(16#137#):=16#00#; CFI_array(16#138#):=16#00#; CFI_array(16#139#):=16#02#; END IF; CFI_array(16#13A#):=16#64#; CFI_array(16#13B#):=16#00#; CFI_array(16#13C#):=16#02#; CFI_array(16#13D#):=16#03#; CFI_array(16#13E#):=16#00#; CFI_array(16#13F#):=16#80#; CFI_array(16#140#):=16#00#; CFI_array(16#141#):=16#00#; CFI_array(16#142#):=16#00#; CFI_array(16#143#):=16#80#; IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN CFI_array(16#144#):=16#7E#; CFI_array(16#145#):=16#00#; CFI_array(16#146#):=16#00#; CFI_array(16#147#):=16#02#; ELSE CFI_array(16#144#):=16#03#; CFI_array(16#145#):=16#00#; CFI_array(16#146#):=16#80#; CFI_array(16#147#):=16#00#; END IF; CFI_array(16#148#):=16#64#; CFI_array(16#149#):=16#00#; CFI_array(16#14A#):=16#02#; CFI_array(16#14B#):=16#03#; CFI_array(16#14C#):=16#00#; CFI_array(16#14D#):=16#80#; CFI_array(16#14E#):=16#00#; CFI_array(16#14F#):=16#00#; CFI_array(16#150#):=16#00#; CFI_array(16#151#):=16#80#; CFI_array(16#152#):=16#FF#; CFI_array(16#153#):=16#FF#; CFI_array(16#154#):=16#FF#; CFI_array(16#155#):=16#FF#; CFI_array(16#156#):=16#FF#; WAIT; END PROCESS CFIPreload; --------------------------------------------------------------------------- ---- File Read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_f : text is mem_file_name; FILE prot_reg_f : text is prot_reg_file_name; FILE otp_blocks_f : text is otp_blocks_file_name; VARIABLE buf : line; VARIABLE addr_ind : INTEGER; BEGIN Mem := (OTHERS => MaxData); PR := (OTHERS => MaxData); PR(16#80#) := 16#FFFE#; OTP := (OTHERS => '0'); IF (mem_file_name /= "none" AND UserPreload) THEN -- i28f128p33 memory file -- / - comment -- @aaaaaa - stands for address -- dddd - is word to be written at Mem(aaaaaa) -- (aaaaaa is incremented at every load) -- No empty lines. addr_ind := 0; WHILE (not ENDFILE (mem_f)) LOOP READLINE (mem_f, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 7)); ELSE IF addr_ind < MemSize THEN Mem(addr_ind) := h(buf(1 to 4)); addr_ind := (addr_ind + 1)mod MemSize; ELSE REPORT "ERROR preloaded location out of range"; END IF; END IF; END LOOP; END IF; IF (prot_reg_file_name /= "none" AND UserPreload ) THEN -- i28f128p33 protection registers file -- / - comment -- @aaa - stands for address -- dddd - is word to be written at PR(aaa) -- (aaa is incremented at every load) -- No empty lines. addr_ind := 0; WHILE (not ENDFILE (prot_reg_f)) LOOP READLINE (prot_reg_f, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 4)); ELSE IF addr_ind >= 16#80# AND addr_ind <= 16#109# THEN PR(addr_ind) := h(buf(1 to 4)); addr_ind := (addr_ind + 1); ELSE REPORT "ERROR preloaded location out of range"; END IF; END IF; END LOOP; END IF; IF (otp_blocks_file_name /= "none" AND UserPreload ) THEN -- i28f128p33 OTP blocks file -- / - comment -- @aaa - stands for address -- d - : 1 - block is OTP, 0 - block is not OTP (default) -- (aaa is incremented at every load) -- No empty lines. addr_ind := 0; WHILE (not ENDFILE (otp_blocks_f)) LOOP READLINE (otp_blocks_f, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 4)); ELSE IF addr_ind <= HiBlockNum THEN IF (buf(1) = '1') THEN OTP(addr_ind) := '1'; END IF; addr_ind := (addr_ind + 1); ELSE REPORT "ERROR preloaded location out of range"; END IF; END IF; END LOOP; END IF; WAIT; END PROCESS MemPreload; AddressEvent : PROCESS(A(HiAddrbit downto 2)) BEGIN IF (LATCHED = FALSE) THEN AddressChange <= NOT AddressChange; END IF; END PROCESS AddressEvent; ----------------------------------------------------------------------- -- Path Delay Section ----------------------------------------------------------------------- DQOutPassThrough : PROCESS(DQOut_zd) VARIABLE CEDQ_t : TIME; VARIABLE OEDQ_t : TIME; VARIABLE ADDRDQ_t : TIME; VARIABLE CEDQx_t : TIME; VARIABLE OEDQx_t : TIME; BEGIN IF (RCR(15) = '1') THEN FROMOE := FALSE; FROMCE := FALSE; FROMOEx := FALSE; FROMCEx := FALSE; IF (DQOut_zd(0) /= 'Z') THEN OEDQx_t := - OENeg'LAST_EVENT + tpd_OENeg_DQ0(trzx); CEDQx_t := - CENeg'LAST_EVENT + tpd_CENeg_DQ0(trzx); IF (OEDQx_t >= CEDQx_t) AND (OEDQx_t >= 0 ns) THEN t_DQx := tpd_OENeg_DQ0(trzx); FROMOEx := TRUE; ELSIF (CEDQx_t > OEDQx_t) AND (CEDQx_t >= 0 ns) THEN t_DQx := tpd_CENeg_DQ0(trzx); FROMCEx := TRUE; END IF; OEDQ_t := - OENeg'LAST_EVENT + tpd_OENeg_DQ0(trz0); CEDQ_t := - CENeg'LAST_EVENT + tpd_CENeg_DQ0(trz0); IF (Pmode = '0') THEN ADDRDQ_t := - AddressChange'LAST_EVENT + tpd_A1_DQ0_InitialPageAccess(tr01); ELSE ADDRDQ_t := - A(1 downto 0)'LAST_EVENT + tpd_A1_DQ0_SubsequentPageAccess(tr01); END IF; IF (OEDQ_t >= CEDQ_t) AND (OEDQ_t > 0 ns) THEN t_DQ := tpd_OENeg_DQ0(trz0); FROMOE := TRUE; ELSIF (CEDQ_t > OEDQ_t) AND (CEDQ_t > 0 ns) THEN t_DQ := tpd_CENeg_DQ0(trz0); FROMCE := TRUE; ELSIF Pmode = '0' THEN t_DQ := tpd_A1_DQ0_InitialPageAccess(tr01); ELSIF Pmode = '1' THEN t_DQ := tpd_A1_DQ0_SubsequentPageAccess(tr01); END IF; IF ((ADDRDQ_t > 0 ns) AND (((ADDRDQ_t > CEDQ_t) AND FROMCE) OR ((ADDRDQ_t > OEDQ_t) AND FROMOE))) THEN DQOut_Pass <= "XXXXXXXXXXXXXXXX", DQOut_zd AFTER ADDRDQ_t; ELSE DQOut_Pass <= "XXXXXXXXXXXXXXXX", DQOut_zd AFTER 1 ns; END IF; ELSE FROMOE := TRUE; FROMCE := TRUE; FROMOEx := TRUE; FROMCEx := TRUE; t_DQx := tpd_OENeg_DQ0(tr0x); t_DQ := tpd_OENeg_DQ0(tr0z); DQOut_Pass <= "XXXXXXXXXXXXXXXX", DQOut_zd AFTER 1 ns; END IF; ELSE IF (DQOut_zd(0) /= 'Z') THEN IF (DQOut_zd(0) /= 'X') THEN t_DQx := tpd_CLK_DQ0(tr0x); t_DQ := tpd_CLK_DQ0(tr01); IF (DQOut_zd(1) = 'X') THEN DQOut_Pass <= "XXXXXXXXXXXXXXXX"; ELSE DQOut_Pass <= "XXXXXXXXXXXXXXXX", DQOut_zd AFTER 1 ns; END IF; ELSE t_DQx := tpd_OENeg_DQ0(tr0x); DQOut_Pass <= DQOut_zd; END IF; ELSE t_DQ := tpd_OENeg_DQ0(tr0z); DQOut_Pass <= DQOut_zd; END IF; END IF; END PROCESS DQOutPassThrough; --------------------------------------------------------------------------- -- Path Delay Section for DQOut signal --------------------------------------------------------------------------- DQOut_PathDelay_Gen : FOR i IN 0 TO 15 GENERATE PROCESS(DQOut_Pass(i)) VARIABLE DQ0_GlitchData: VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DQOut(i), OutSignalName => "DQOut", OutTemp => DQOut_Pass(i), GlitchData => DQ0_GlitchData, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQx), PathCondition => RCR(15) = '1' AND FROMCEx AND DQOut_Pass(0) = 'X' ), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQx), PathCondition => RCR(15) = '1' AND FROMOEx AND DQOut_Pass(0) = 'X'), 2 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '1' AND FROMCE AND DQOut_Pass(0) /= 'X' ), 3 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '1' AND FROMOE AND DQOut_Pass(0) /= 'X'), 4 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '1' AND DQOut_Pass(0) /= 'X' ), 5 => (InputChangeTime => CLK'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQx), PathCondition => RCR(15) = '0' AND DQOut_Pass(0) = 'X'), 6 => (InputChangeTime => CLK'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '0' AND DQOut_Pass(0) /= 'X'), 7 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQx), PathCondition => RCR(15) = '0' AND DQOut_Pass(0) = 'X'), 8 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '0' AND DQOut_Pass(0) /= 'X') ) ); END PROCESS; END GENERATE DQOut_PathDelay_Gen; ----------------------------------------------------------------------- -- Path Delay Section for WAITOut ----------------------------------------------------------------------- WT_OUT: PROCESS(WAITOut_zd) VARIABLE WT_GlitchData: VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => WAITOut, OutSignalName => "WAITOut", OutTemp => WAITOut_zd, Mode => VitalTransport, GlitchData => WT_GlitchData, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_WAITOut, PathCondition => TRUE), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_WAITOut, PathCondition => TRUE), 2 => (InputChangeTime => CLK'LAST_EVENT, PathDelay => tpd_CLK_WAITOut, PathCondition => TRUE) ) ); END PROCESS WT_Out; END BLOCK behavior; END vhdl_behavioral_static_memory_allocation; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION - Dynamic memory allocation ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral_dynamic_memory_allocation of i28f128p33 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral_dynamic_memory_allocation : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "i28f128p33"; CONSTANT MaxData : NATURAL := 16#FFFF#; CONSTANT MemSize : NATURAL := 16#7FFFFF#; CONSTANT HiAddrBit : NATURAL := 22; CONSTANT MainBlockSize : NATURAL := 16#010000#; CONSTANT ParameterBlockSize: NATURAL := 16#004000#; CONSTANT HiBlockNum : NATURAL := 130; CONSTANT DeviceID_B : NATURAL := 16#8821#; CONSTANT DeviceID_T : NATURAL := 16#881E#; -- ipd SIGNAL A23_ipd : std_ulogic := 'U'; SIGNAL A22_ipd : std_ulogic := 'U'; SIGNAL A21_ipd : std_ulogic := 'U'; SIGNAL A20_ipd : std_ulogic := 'U'; SIGNAL A19_ipd : std_ulogic := 'U'; SIGNAL A18_ipd : std_ulogic := 'U'; SIGNAL A17_ipd : std_ulogic := 'U'; SIGNAL A16_ipd : std_ulogic := 'U'; SIGNAL A15_ipd : std_ulogic := 'U'; SIGNAL A14_ipd : std_ulogic := 'U'; SIGNAL A13_ipd : std_ulogic := 'U'; SIGNAL A12_ipd : std_ulogic := 'U'; SIGNAL A11_ipd : std_ulogic := 'U'; SIGNAL A10_ipd : std_ulogic := 'U'; SIGNAL A9_ipd : std_ulogic := 'U'; SIGNAL A8_ipd : std_ulogic := 'U'; SIGNAL A7_ipd : std_ulogic := 'U'; SIGNAL A6_ipd : std_ulogic := 'U'; SIGNAL A5_ipd : std_ulogic := 'U'; SIGNAL A4_ipd : std_ulogic := 'U'; SIGNAL A3_ipd : std_ulogic := 'U'; SIGNAL A2_ipd : std_ulogic := 'U'; SIGNAL A1_ipd : std_ulogic := 'U'; SIGNAL 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 ADVNeg_ipd : std_ulogic := 'U'; SIGNAL CENeg_ipd : std_ulogic := 'U'; SIGNAL CLK_ipd : std_ulogic := 'U'; SIGNAL OENeg_ipd : std_ulogic := 'U'; SIGNAL RSTNeg_ipd : std_ulogic := 'U'; SIGNAL WENeg_ipd : std_ulogic := 'U'; SIGNAL WPNeg_ipd : std_ulogic := 'U'; -- nwv SIGNAL A23_nwv : std_ulogic := 'U'; SIGNAL A22_nwv : std_ulogic := 'U'; SIGNAL A21_nwv : std_ulogic := 'U'; SIGNAL A20_nwv : std_ulogic := 'U'; SIGNAL A19_nwv : std_ulogic := 'U'; SIGNAL A18_nwv : std_ulogic := 'U'; SIGNAL A17_nwv : std_ulogic := 'U'; SIGNAL A16_nwv : std_ulogic := 'U'; SIGNAL A15_nwv : std_ulogic := 'U'; SIGNAL A14_nwv : std_ulogic := 'U'; SIGNAL A13_nwv : std_ulogic := 'U'; SIGNAL A12_nwv : std_ulogic := 'U'; SIGNAL A11_nwv : std_ulogic := 'U'; SIGNAL A10_nwv : std_ulogic := 'U'; SIGNAL A9_nwv : std_ulogic := 'U'; SIGNAL A8_nwv : std_ulogic := 'U'; SIGNAL A7_nwv : std_ulogic := 'U'; SIGNAL A6_nwv : std_ulogic := 'U'; SIGNAL A5_nwv : std_ulogic := 'U'; SIGNAL A4_nwv : std_ulogic := 'U'; SIGNAL A3_nwv : std_ulogic := 'U'; SIGNAL A2_nwv : std_ulogic := 'U'; SIGNAL A1_nwv : std_ulogic := 'U'; SIGNAL DQ15_nwv : std_ulogic := 'U'; SIGNAL DQ14_nwv : std_ulogic := 'U'; SIGNAL DQ13_nwv : std_ulogic := 'U'; SIGNAL DQ12_nwv : std_ulogic := 'U'; SIGNAL DQ11_nwv : std_ulogic := 'U'; SIGNAL DQ10_nwv : std_ulogic := 'U'; SIGNAL DQ9_nwv : std_ulogic := 'U'; SIGNAL DQ8_nwv : std_ulogic := 'U'; SIGNAL DQ7_nwv : std_ulogic := 'U'; SIGNAL DQ6_nwv : std_ulogic := 'U'; SIGNAL DQ5_nwv : std_ulogic := 'U'; SIGNAL DQ4_nwv : std_ulogic := 'U'; SIGNAL DQ3_nwv : std_ulogic := 'U'; SIGNAL DQ2_nwv : std_ulogic := 'U'; SIGNAL DQ1_nwv : std_ulogic := 'U'; SIGNAL DQ0_nwv : std_ulogic := 'U'; SIGNAL ADVNeg_nwv : std_ulogic := 'U'; SIGNAL CENeg_nwv : std_ulogic := 'U'; SIGNAL CLK_nwv : std_ulogic := 'U'; SIGNAL OENeg_nwv : std_ulogic := 'U'; SIGNAL RSTNeg_nwv : std_ulogic := 'U'; SIGNAL WENeg_nwv : std_ulogic := 'U'; SIGNAL WPNeg_nwv : std_ulogic := 'U'; --internal delays SIGNAL WordProgram_in_t : std_ulogic := '0'; SIGNAL WordProgram_in : std_ulogic := '0'; SIGNAL WordProgram9V_in_t : std_ulogic := '0'; SIGNAL WordProgram_out_t : std_ulogic := '0'; SIGNAL WordProgram_out : std_ulogic := '0'; SIGNAL WordProgram9V_out_t : std_ulogic := '0'; SIGNAL BuffProgram_in : std_ulogic := '0'; SIGNAL BuffProgram_in_t : std_ulogic := '0'; SIGNAL BuffProgram9V_in_t : std_ulogic := '0'; SIGNAL BuffProgram_out : std_ulogic := '0'; SIGNAL BuffProgram_out_t : std_ulogic := '0'; SIGNAL BuffProgram9V_out_t : std_ulogic := '0'; SIGNAL BEFP_in : std_ulogic := '0'; SIGNAL BEFP_out : std_ulogic := '0'; SIGNAL BEFP_in_t : std_ulogic := '0'; SIGNAL BEFP_out_t : std_ulogic := '0'; SIGNAL BEFPsetup_in : std_ulogic := '0'; SIGNAL BEFPsetup_out : std_ulogic := '0'; SIGNAL ParameterErase_in : std_ulogic := '0'; SIGNAL MainErase_in : std_ulogic := '0'; SIGNAL ParameterErase_in_t : std_ulogic := '0'; SIGNAL MainErase_in_t : std_ulogic := '0'; SIGNAL ParameterErase_out : std_ulogic := '0'; SIGNAL MainErase_out : std_ulogic := '0'; SIGNAL ParameterErase_out_t : std_ulogic := '0'; SIGNAL MainErase_out_t : std_ulogic := '0'; SIGNAL ProgramSuspend_in : std_ulogic := '0'; SIGNAL ProgramSuspend_out : std_ulogic := '0'; SIGNAL EraseSuspend_in : std_ulogic := '0'; SIGNAL EraseSuspend_out : std_ulogic := '0'; SIGNAL RstDuringErsPrg_in : std_ulogic := '0'; SIGNAL RstDuringErsPrg_out : std_ulogic := '0'; -- ------------------------------------------------------------------------- -- Memory data initial value. -- Default value may be overridden by conigure_memory procedure -- ------------------------------------------------------------------------- SHARED VARIABLE max_data : NATURAL := 16#FFFF#; -- ------------------------------------------------------------------------- -- Data types required to implement link list structure -- ------------------------------------------------------------------------- TYPE mem_data_t; TYPE mem_data_pointer_t IS ACCESS mem_data_t; TYPE mem_data_t IS RECORD key_address : INTEGER; val_data : INTEGER; successor : mem_data_pointer_t; END RECORD; -- ------------------------------------------------------------------------- -- Array of linked lists. -- Support memory region partitioning for faster access. -- ------------------------------------------------------------------------- TYPE mem_data_pointer_array_t IS ARRAY(NATURAL RANGE <>) OF mem_data_pointer_t; -- ------------------------------------------------------------------------- -- Override mechanism provided for default parameter values -- ------------------------------------------------------------------------- PROCEDURE configure_memory( max_data_c : IN INTEGER) IS BEGIN max_data := max_data_c; END PROCEDURE configure_memory; -- ------------------------------------------------------------------------- -- Create linked listed -- ------------------------------------------------------------------------- PROCEDURE create_list( key_address : IN INTEGER; val_data : IN INTEGER; root : INOUT mem_data_pointer_t) IS BEGIN root := NEW mem_data_t; root.successor := NULL; root.key_address := key_address; root.val_data := val_data; END PROCEDURE create_list; -- ------------------------------------------------------------------------- -- Iterate through linked listed comapring key values -- Stop when key value greater or equal -- ------------------------------------------------------------------------- PROCEDURE position_list( key_address : IN INTEGER; root : INOUT mem_data_pointer_t; found : INOUT mem_data_pointer_t; prev : INOUT mem_data_pointer_t) IS BEGIN found := root; prev := NULL; WHILE ((found /= NULL) AND (found.key_address < key_address)) LOOP prev := found; found := found.successor; END LOOP; END PROCEDURE position_list; -- ------------------------------------------------------------------------- -- Add new element to a linked list -- ------------------------------------------------------------------------- PROCEDURE insert_list( key_address : IN INTEGER; val_data : IN INTEGER; root : INOUT mem_data_pointer_t) IS VARIABLE new_element : mem_data_pointer_t; VARIABLE found : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; BEGIN position_list(key_address, root, found, prev); -- Insert at list tail IF (found = NULL) THEN prev.successor := NEW mem_data_t; prev.successor.key_address := key_address; prev.successor.val_data := val_data; prev.successor.successor := NULL; ELSE -- Element exists, update memory data value IF (found.key_address = key_address) THEN found.val_data := val_data; ELSE -- No element found, allocate and link new_element := NEW mem_data_t; new_element.key_address := key_address; new_element.val_data := val_data; new_element.successor := found; -- Possible root position IF (prev /= NULL) THEN prev.successor := new_element; ELSE root := new_element; END IF; END IF; END IF; END PROCEDURE insert_list; -- ------------------------------------------------------------------------- -- Remove element from a linked list -- ------------------------------------------------------------------------- PROCEDURE remove_list( key_address : IN INTEGER; root : INOUT mem_data_pointer_t) IS VARIABLE found : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; BEGIN position_list(key_address, root, found, prev); IF (found /= NULL) THEN -- Key value match IF (found.key_address = key_address) THEN -- Handle root position removal IF (prev /= NULL) THEN prev.successor := found.successor; ELSE root := found.successor; END IF; DEALLOCATE(found); END IF; END IF; END PROCEDURE remove_list; -- ------------------------------------------------------------------------- -- Remove range of elements from a linked list -- Higher performance than one-by-one removal -- ------------------------------------------------------------------------- PROCEDURE remove_list_range( address_low : IN INTEGER; address_high : IN INTEGER; root : INOUT mem_data_pointer_t) IS VARIABLE iter : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; VARIABLE link_element : mem_data_pointer_t; BEGIN iter := root; prev := NULL; -- Find first linked list element belonging to -- a specified address range [address_low, address_high] WHILE ((iter /= NULL) AND NOT ( (iter.key_address >= address_low) AND (iter.key_address <= address_high))) LOOP prev := iter; iter := iter.successor; END LOOP; -- Continue until address_high reached -- Deallocate linked list elements pointed by iterator IF (iter /= NULL) THEN WHILE ((iter /= NULL) AND (iter.key_address >= address_low) AND (iter.key_address <= address_high)) LOOP link_element := iter.successor; DEALLOCATE(iter); iter := link_element; END LOOP; -- Handle possible root value change IF prev /= NULL THEN prev.successor := link_element; ELSE root := link_element; END IF; END IF; END PROCEDURE remove_list_range; -- ------------------------------------------------------------------------- -- Address range to be erased -- ------------------------------------------------------------------------- PROCEDURE erase_mem( address_low : IN INTEGER; address_high : IN INTEGER; linked_list : INOUT mem_data_pointer_t) IS BEGIN remove_list_range( address_low, address_high, linked_list ); END PROCEDURE erase_mem; -- ------------------------------------------------------------------------- -- Memory READ operation performed above dynamically allocated space -- ------------------------------------------------------------------------- PROCEDURE read_mem( linked_list : INOUT mem_data_pointer_t; data : INOUT INTEGER; address : IN INTEGER) IS VARIABLE found : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; VARIABLE mem_data : INTEGER; BEGIN IF (linked_list = NULL) THEN -- Not allocated, not written, initial value mem_data := max_data ; ELSE position_list(address, linked_list, found, prev); IF (found /= NULL) THEN IF found.key_address = address THEN -- Allocated, val_data stored mem_data := found.val_data; ELSE -- Not allocated, not written, initial value mem_data := max_data ; END IF; ELSE -- Not allocated, not written, initial value mem_data := max_data ; END IF; END IF; data := mem_data; END PROCEDURE read_mem; -- ------------------------------------------------------------------------- -- Memory WRITE operation performed above dynamically allocated space -- ------------------------------------------------------------------------- PROCEDURE write_mem( linked_list : INOUT mem_data_pointer_t; address : IN INTEGER; data : IN INTEGER) IS BEGIN IF (data /= max_data ) THEN -- Handle possible root value update IF (linked_list /= NULL) THEN insert_list(address, data, linked_list); ELSE create_list(address, data, linked_list); END IF; ELSE -- Deallocate if initial value written -- No linked list, NOP, initial value implicit IF (linked_list /= NULL) THEN remove_list(address, linked_list); END IF; END IF; END PROCEDURE write_mem; BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays WordProgram : VitalBuf(WordProgram_out_t, WordProgram_in_t, (UnitDelay, tdevice_WordProgram)); WordProgram9V : VitalBuf(WordProgram9V_out_t, WordProgram9V_in_t, (UnitDelay, tdevice_WordProgram9V)); BuffProgram : VitalBuf(BuffProgram_out_t, BuffProgram_in_t, (UnitDelay, tdevice_BuffProgram)); BuffProgram9V : VitalBuf(BuffProgram9V_out_t, BuffProgram9V_in_t, (UnitDelay, tdevice_BuffProgram9V)); BEFP : VitalBuf(BEFP_out_t, BEFP_in_t, (UnitDelay, tdevice_BEFP)); BEFPsetup : VitalBuf(BEFPsetup_out, BEFPsetup_in, (UnitDelay, tdevice_BEFPsetup)); EraseParameter : VitalBuf(ParameterErase_out_t, ParameterErase_in_t, (UnitDelay, tdevice_EraseParameter)); EraseMain : VitalBuf(MainErase_out_t, MainErase_in_t, (UnitDelay, tdevice_EraseMain)); ProgramSuspend : VitalBuf(ProgramSuspend_out, ProgramSuspend_in, (UnitDelay, tdevice_ProgramSuspend)); EraseSuspend : VitalBuf(EraseSuspend_out, EraseSuspend_in, (UnitDelay, tdevice_EraseSuspend)); RstDuringErsPrg: VitalBuf(RstDuringErsPrg_out,RstDuringErsPrg_in, (UnitDelay, tdevice_RstDuringErsPrg)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (A23_ipd, A23, tipd_A23); w_2 : VitalWireDelay (A22_ipd, A22, tipd_A22); w_3 : VitalWireDelay (A21_ipd, A21, tipd_A21); w_4 : VitalWireDelay (A20_ipd, A20, tipd_A20); w_5 : VitalWireDelay (A19_ipd, A19, tipd_A19); w_6 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_7 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_8 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_9 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_10 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_11 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_12 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_13 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_14 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_15 : VitalWireDelay (A9_ipd, A9, tipd_A9); w_16 : VitalWireDelay (A8_ipd, A8, tipd_A8); w_17 : VitalWireDelay (A7_ipd, A7, tipd_A7); w_18 : VitalWireDelay (A6_ipd, A6, tipd_A6); w_19 : VitalWireDelay (A5_ipd, A5, tipd_A5); w_20 : VitalWireDelay (A4_ipd, A4, tipd_A4); w_21 : VitalWireDelay (A3_ipd, A3, tipd_A3); w_22 : VitalWireDelay (A2_ipd, A2, tipd_A2); w_23 : VitalWireDelay (A1_ipd, A1, tipd_A1); w_24 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_25 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_26 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_27 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_28 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_29 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_30 : VitalWireDelay (DQ9_ipd, DQ9, tipd_DQ9); w_31 : VitalWireDelay (DQ8_ipd, DQ8, tipd_DQ8); w_32 : VitalWireDelay (DQ7_ipd, DQ7, tipd_DQ7); w_33 : VitalWireDelay (DQ6_ipd, DQ6, tipd_DQ6); w_34 : VitalWireDelay (DQ5_ipd, DQ5, tipd_DQ5); w_35 : VitalWireDelay (DQ4_ipd, DQ4, tipd_DQ4); w_36 : VitalWireDelay (DQ3_ipd, DQ3, tipd_DQ3); w_37 : VitalWireDelay (DQ2_ipd, DQ2, tipd_DQ2); w_38 : VitalWireDelay (DQ1_ipd, DQ1, tipd_DQ1); w_39 : VitalWireDelay (DQ0_ipd, DQ0, tipd_DQ0); w_40 : VitalWireDelay (ADVNeg_ipd, ADVNeg, tipd_ADVNeg); w_41 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); w_42 : VitalWireDelay (CLK_ipd, CLK, tipd_CLK); w_43 : VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg); w_44 : VitalWireDelay (RSTNeg_ipd, RSTNeg, tipd_RSTNeg); w_45 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_46 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg); END BLOCK; -- sig_nwv <= To_UX01(sig_ipd); A23_nwv <= To_UX01(A23_ipd); A22_nwv <= To_UX01(A22_ipd); A21_nwv <= To_UX01(A21_ipd); A20_nwv <= To_UX01(A20_ipd); A19_nwv <= To_UX01(A19_ipd); A18_nwv <= To_UX01(A18_ipd); A17_nwv <= To_UX01(A17_ipd); A16_nwv <= To_UX01(A16_ipd); A15_nwv <= To_UX01(A15_ipd); A14_nwv <= To_UX01(A14_ipd); A13_nwv <= To_UX01(A13_ipd); A12_nwv <= To_UX01(A12_ipd); A11_nwv <= To_UX01(A11_ipd); A10_nwv <= To_UX01(A10_ipd); A9_nwv <= To_UX01(A9_ipd); A8_nwv <= To_UX01(A8_ipd); A7_nwv <= To_UX01(A7_ipd); A6_nwv <= To_UX01(A6_ipd); A5_nwv <= To_UX01(A5_ipd); A4_nwv <= To_UX01(A4_ipd); A3_nwv <= To_UX01(A3_ipd); A2_nwv <= To_UX01(A2_ipd); A1_nwv <= To_UX01(A1_ipd); DQ15_nwv <= To_UX01(DQ15_ipd); DQ14_nwv <= To_UX01(DQ14_ipd); DQ13_nwv <= To_UX01(DQ13_ipd); DQ12_nwv <= To_UX01(DQ12_ipd); DQ11_nwv <= To_UX01(DQ11_ipd); DQ10_nwv <= To_UX01(DQ10_ipd); DQ9_nwv <= To_UX01(DQ9_ipd); DQ8_nwv <= To_UX01(DQ8_ipd); DQ7_nwv <= To_UX01(DQ7_ipd); DQ6_nwv <= To_UX01(DQ6_ipd); DQ5_nwv <= To_UX01(DQ5_ipd); DQ4_nwv <= To_UX01(DQ4_ipd); DQ3_nwv <= To_UX01(DQ3_ipd); DQ2_nwv <= To_UX01(DQ2_ipd); DQ1_nwv <= To_UX01(DQ1_ipd); DQ0_nwv <= To_UX01(DQ0_ipd); ADVNeg_nwv <= To_UX01(ADVNeg_ipd); CENeg_nwv <= To_UX01(CENeg_ipd ); CLK_nwv <= To_UX01(CLK_ipd ); OENeg_nwv <= To_UX01(OENeg_ipd ); RSTNeg_nwv <= To_UX01(RSTNeg_ipd); WENeg_nwv <= To_UX01(WENeg_ipd ); WPNeg_nwv <= To_UX01(WPNeg_ipd ); --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK PORT ( A : IN std_logic_vector(HiAddrBit downto 0) := (OTHERS => 'U'); DQIn : IN std_logic_vector(15 downto 0) := (OTHERS => 'U'); DQOut : OUT std_logic_vector(15 downto 0) := (OTHERS => 'Z'); ADVNeg : IN std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; CLK : IN std_ulogic := 'U'; OENeg : IN std_ulogic := 'U'; RSTNeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; VPP : IN std_ulogic := 'U'; WAITOut : OUT std_ulogic := 'Z' ); PORT MAP ( A(22) => A23_nwv, A(21) => A22_nwv, A(20) => A21_nwv, A(19) => A20_nwv, A(18) => A19_nwv, A(17) => A18_nwv, A(16) => A17_nwv, A(15) => A16_nwv, A(14) => A15_nwv, A(13) => A14_nwv, A(12) => A13_nwv, A(11) => A12_nwv, A(10) => A11_nwv, A(9) => A10_nwv, A(8) => A9_nwv, A(7) => A8_nwv, A(6) => A7_nwv, A(5) => A6_nwv, A(4) => A5_nwv, A(3) => A4_nwv, A(2) => A3_nwv, A(1) => A2_nwv, A(0) => A1_nwv, DQIn(15) => DQ15_nwv, DQIn(14) => DQ14_nwv, DQIn(13) => DQ13_nwv, DQIn(12) => DQ12_nwv, DQIn(11) => DQ11_nwv, DQIn(10) => DQ10_nwv, DQIn(9) => DQ9_nwv, DQIn(8) => DQ8_nwv, DQIn(7) => DQ7_nwv, DQIn(6) => DQ6_nwv, DQIn(5) => DQ5_nwv, DQIn(4) => DQ4_nwv, DQIn(3) => DQ3_nwv, DQIn(2) => DQ2_nwv, DQIn(1) => DQ1_nwv, DQIn(0) => DQ0_nwv, DQOut(15) => DQ15, DQOut(14) => DQ14, DQOut(13) => DQ13, DQOut(12) => DQ12, DQOut(11) => DQ11, DQOut(10) => DQ10, DQOut(9) => DQ9, DQOut(8) => DQ8, DQOut(7) => DQ7, DQOut(6) => DQ6, DQOut(5) => DQ5, DQOut(4) => DQ4, DQOut(3) => DQ3, DQOut(2) => DQ2, DQOut(1) => DQ1, DQOut(0) => DQ0, ADVNeg => ADVNeg_nwv, CENeg => CENeg_nwv , CLK => CLK_nwv , OENeg => OENeg_nwv , RSTNeg => RSTNeg_nwv, WENeg => WENeg_nwv , WPNeg => WPNeg_nwv , VPP => VPP, WAITOut => WAITOut ); -- Read State Machine : Read_State_Type TYPE read_state_type IS ( READ_ARRAY, READ_STATUS, READ_ID, READ_QUERY ); -- State Machine : State_Type TYPE state_type IS ( RESET_POWER_DOWN, READY, LOCK_SETUP, OTP_SETUP, OTP_BUSY, PROG_SETUP, PROG_BUSY, PROG_SUSP, BP_SETUP, BP_LOAD, BP_CONFIRM, BP_BUSY, BP_SUSP, ERASE_SETUP, ERASE_BUSY, ERS_SUSP, PROG_SETUP_ERS_SUSP, PROG_BUSY_ERS_SUSP, PROG_SUSP_ERS_SUSP, BP_SETUP_ERS_SUSP, BP_LOAD_ERS_SUSP, BP_CONFIRM_ERS_SUSP, BP_BUSY_ERS_SUSP, BP_SUSP_ERS_SUSP, LOCK_SETUP_ERS_SUSP, BEFP_SETUP, BEFP_LOAD, BEFP_BUSY ); --states SIGNAL current_state : state_type; SIGNAL next_state : state_type; SIGNAL read_state : read_state_type; SIGNAL Write : std_logic := '1'; SIGNAL Read : std_logic := '0'; SIGNAL abort : std_logic := '0'; SIGNAL BP_ProgramResume : std_logic := '0'; SIGNAL MainEraseResume : std_logic := '0'; SIGNAL ParameterEraseResume : std_logic := '0'; SIGNAL WordProgramResume : std_logic := '0'; SHARED VARIABLE bp_suspend : std_logic := '0'; SIGNAL ExtendProgTime : BOOLEAN := FALSE; SIGNAL AssertWAITOut : std_logic := '0'; SIGNAL DeassertWAITOut : std_logic := '0'; --timing check violation SIGNAL Viol : X01 := '0'; --zero delay signals SIGNAL DQOut_zd : std_logic_vector(15 downto 0):=(OTHERS=>'Z'); SIGNAL DQOut_pass : std_logic_vector(15 DOWNTO 0):=(OTHERS=>'Z'); SIGNAL WAITOut_zd : std_logic := 'Z'; --access time variables SHARED VARIABLE FROMOEx : BOOLEAN; SHARED VARIABLE FROMCEx : BOOLEAN; SHARED VARIABLE FROMOE : BOOLEAN; SHARED VARIABLE FROMCE : BOOLEAN; --variables for delay SHARED VARIABLE t_DQx, t_DQ : VitalDelayType := 0 ns; --Device Registers --Read Configuration Register SIGNAL RCR : std_logic_vector(15 downto 0) := "1011111111001111"; --Status Register SIGNAL SR : std_logic_vector(7 downto 0) := "10000000"; --Protection registers TYPE PR_type IS ARRAY(16#80# TO 16#109#) OF INTEGER RANGE -1 TO MaxData; SHARED VARIABLE PR : PR_type := (OTHERS => 16#FFFF#); --Block Lock Status TYPE block_status_t IS (UNLOCKED, LOCKED, LOCKED_DOWN); TYPE blocks_status IS ARRAY (HiBlockNum downto 0) OF block_status_t; SHARED VARIABLE Block_Lock : blocks_status := (OTHERS => LOCKED); SHARED VARIABLE BlockLockBit : std_logic_vector(HiBlockNum downto 0) := (OTHERS =>'1'); SHARED VARIABLE BlockLockDownBit: std_logic_vector(HiBlockNum downto 0) := (OTHERS =>'0'); --OTP Block Status -- '0' - block is not OTP (default) -- '1' - block is OTP SHARED VARIABLE OTP: std_logic_vector(HiBlockNum downto 0) := (OTHERS =>'0'); --CFI Array --Common Flash Interface Query codes TYPE CFItype IS ARRAY (16#10# TO 16#156#) OF NATURAL RANGE 0 TO 16#100#; SHARED VARIABLE CFI_array : CFItype := (OTHERS => 0); SIGNAL AddressChange : std_logic := '0'; SIGNAL Pmode : std_logic := '0'; SIGNAL CLOCK : std_logic := '0'; SHARED VARIABLE LATCHED : BOOLEAN; SHARED VARIABLE LatchedAddr : NATURAL; SHARED VARIABLE LatchedData : NATURAL; SHARED VARIABLE ReadAddr : NATURAL; TYPE BUFF IS ARRAY (0 TO 31) OF NATURAL; SHARED VARIABLE DataBuff : BUFF; SHARED VARIABLE AddrBuff : BUFF; SHARED VARIABLE burst_cntr : INTEGER := 0; SHARED VARIABLE BurstLength : NATURAL := 0; ------------------------------------------------------------------------ -- Handle dynamic memory allocation ------------------------------------------------------------------------ -- Partition dynamically allocated space for performance -- Access dynamically allocated space SHARED VARIABLE linked_list : mem_data_pointer_array_t(0 TO HiBlockNum); SHARED VARIABLE corrupt_flag : std_logic_vector(HiBlockNum downto 0) :=(OTHERS=>'0'); -- Asure proper initialization PROCEDURE initialize IS VARIABLE I : INTEGER; BEGIN FOR I IN 0 TO HiBlockNum LOOP linked_list(I) := NULL; END LOOP; END PROCEDURE initialize; FUNCTION BlockNumber(ADDR: NATURAL) RETURN NATURAL IS VARIABLE block_number: NATURAL; BEGIN block_number := ADDR / MainBlockSize; IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T') THEN IF block_number = (MemSize/MainBlockSize) THEN block_number := block_number + (ADDR mod MainBlockSize) / ParameterBlockSize; END IF; ELSIF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN IF block_number = 0 THEN block_number := block_number + (ADDR mod MainBlockSize) / ParameterBlockSize; ELSE block_number := block_number + MainBlockSize / ParameterBlockSize - 1; END IF; END IF; RETURN block_number; END BlockNumber; FUNCTION StartBlockAddr(block_number: NATURAL) RETURN NATURAL IS VARIABLE start_block_addr: NATURAL; BEGIN IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T') THEN start_block_addr := block_number * MainBlockSize; IF block_number > (HiBlockNum - 3) THEN start_block_addr := start_block_addr - (block_number + 3 - HiBlockNum) * MainBlockSize + (block_number + 3 - HiBlockNum) * ParameterBlockSize; END IF; ELSIF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN IF block_number < 4 THEN start_block_addr := block_number * ParameterBlockSize; ELSE start_block_addr := (block_number - 3) * MainBlockSize; END IF; END IF; RETURN start_block_addr; END StartBlockAddr; FUNCTION BlockSize(block_number: NATURAL) RETURN NATURAL IS VARIABLE block_size: NATURAL; BEGIN IF (block_number < 4 AND ((TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B'))) OR (block_number > (HiBlockNum - 4) AND ((TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T'))) THEN block_size := ParameterBlockSize; ELSE block_size := MainBlockSize; END IF; RETURN block_size; END BlockSize; BEGIN --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(A, DQIn, ADVNeg, CENeg, CLK, RSTNeg, WENeg, WPNeg) -- Timing Check Variables VARIABLE Tviol_A1_ADVNeg : X01 := '0'; VARIABLE TD_A1_ADVNeg : VitalTimingDataType; VARIABLE Tviol_CENeg_ADVNeg : X01 := '0'; VARIABLE TD_CENeg_ADVNeg : VitalTimingDataType; VARIABLE Tviol_RSTNeg_ADVNeg : X01 := '0'; VARIABLE TD_RSTNeg_ADVNeg : VitalTimingDataType; VARIABLE Tviol_WENeg_ADVNeg : X01 := '0'; VARIABLE TD_WENeg_ADVNeg : VitalTimingDataType; VARIABLE Tviol_A1_CLK_rising : X01 := '0'; VARIABLE TD_A1_CLK_rising : VitalTimingDataType; VARIABLE Tviol_A1_CLK_falling : X01 := '0'; VARIABLE TD_A1_CLK_falling : VitalTimingDataType; VARIABLE Tviol_ADVNeg_CLK_rising : X01 := '0'; VARIABLE TD_ADVNeg_CLK_rising : VitalTimingDataType; VARIABLE Tviol_ADVNeg_CLK_falling : X01 := '0'; VARIABLE TD_ADVNeg_CLK_falling : VitalTimingDataType; VARIABLE Tviol_CENeg_CLK_rising : X01 := '0'; VARIABLE TD_CENeg_CLK_rising : VitalTimingDataType; VARIABLE Tviol_CENeg_CLK_falling : X01 := '0'; VARIABLE TD_CENeg_CLK_falling : VitalTimingDataType; VARIABLE Tviol_WENeg_CLK_rising : X01 := '0'; VARIABLE TD_WENeg_CLK_rising : VitalTimingDataType; VARIABLE Tviol_WENeg_CLK_falling : X01 := '0'; VARIABLE TD_WENeg_CLK_falling : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_setup : X01 := '0'; VARIABLE TD_CENeg_WENeg_setup : VitalTimingDataType; VARIABLE Tviol_DQ0_WENeg : X01 := '0'; VARIABLE TD_DQ0_WENeg : VitalTimingDataType; VARIABLE Tviol_A1_WENeg : X01 := '0'; VARIABLE TD_A1_WENeg : VitalTimingDataType; VARIABLE Tviol_WPNeg_WENeg : X01 := '0'; VARIABLE TD_WPNeg_WENeg : VitalTimingDataType; VARIABLE Tviol_ADVNeg_WENeg : X01 := '0'; VARIABLE TD_ADVNeg_WENeg : VitalTimingDataType; VARIABLE Tviol_CLK_rising_WENeg : X01 := '0'; VARIABLE TD_CLK_rising_WENeg : VitalTimingDataType; VARIABLE Tviol_CLK_falling_WENeg : X01 := '0'; VARIABLE TD_CLK_falling_WENeg : VitalTimingDataType; VARIABLE Tviol_WENeg_OENeg : X01 := '0'; VARIABLE TD_WENeg_OENeg : VitalTimingDataType; VARIABLE Tviol_CENeg_WENeg_hold : X01 := '0'; VARIABLE TD_CENeg_WENeg_hold : VitalTimingDataType; VARIABLE Pviol_CENeg : X01 := '0'; VARIABLE PD_CENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_ADVNeg : X01 := '0'; VARIABLE PD_ADVNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_WENeg : X01 := '0'; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_RSTNeg : X01 := '0'; VARIABLE PD_RSTNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CLK : X01 := '0'; VARIABLE PD_CLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Rviol_RSTNeg_WENeg : X01 := '0'; VARIABLE RD_RSTNeg_WENeg : VitalTimingDataType; VARIABLE Violation : X01 := '0'; BEGIN --------------------------------------------------------------------------- -- Timing Check Section --------------------------------------------------------------------------- IF (TimingChecksOn) THEN VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupHigh => tsetup_A1_ADVNeg, SetupLow => tsetup_A1_ADVNeg, HoldHigh => thold_A1_ADVNeg, HoldLow => thold_A1_ADVNeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A1_ADVNeg, Violation => Tviol_A1_ADVNeg ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupLow => tsetup_CENeg_ADVNeg, CheckEnabled => CENeg='0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_ADVNeg, Violation => Tviol_CENeg_ADVNeg ); VitalSetupHoldCheck ( TestSignal => RSTNeg, TestSignalName => "RSTNeg", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupLow => tsetup_RSTNeg_ADVNeg, CheckEnabled => RSTNeg='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_RSTNeg_ADVNeg, Violation => Tviol_RSTNeg_ADVNeg ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => ADVNeg, RefSignalName => "ADVNeg", SetupHigh => tsetup_WENeg_ADVNeg, CheckEnabled => WENeg='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_ADVNeg, Violation => Tviol_WENeg_ADVNeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_A1_CLK, SetupLow => tsetup_A1_CLK, CheckEnabled => RCR(6)='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A1_CLK_rising, Violation => Tviol_A1_CLK_rising ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_A1_CLK, SetupLow => tsetup_A1_CLK, CheckEnabled => RCR(6)='0', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_A1_CLK_falling, Violation => Tviol_A1_CLK_falling ); VitalSetupHoldCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_ADVNeg_CLK, CheckEnabled => RCR(6)='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_ADVNeg_CLK_rising, Violation => Tviol_ADVNeg_CLK_rising ); VitalSetupHoldCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_ADVNeg_CLK, CheckEnabled => RCR(6)='0', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_ADVNeg_CLK_falling, Violation => Tviol_ADVNeg_CLK_falling ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_CENeg_CLK, CheckEnabled => RCR(6)='1' AND CENeg='0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_CLK_rising, Violation => Tviol_CENeg_CLK_rising ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_CENeg_CLK, CheckEnabled => RCR(6)='0' AND CENeg='0', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_CLK_falling, Violation => Tviol_CENeg_CLK_falling ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_WENeg_CLK, CheckEnabled => RCR(6)='1' AND WENeg='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CLK_rising, Violation => Tviol_WENeg_CLK_rising ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_WENeg_CLK, CheckEnabled => RCR(6)='0' AND WENeg='1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CLK_falling, Violation => Tviol_WENeg_CLK_falling ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => true, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_setup, Violation => Tviol_CENeg_WENeg_setup ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldLow => thold_CENeg_WENeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_hold, Violation => Tviol_CENeg_WENeg_hold ); VitalSetupHoldCheck ( TestSignal => DQIn, TestSignalName => "DQ", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_DQ0_WENeg, SetupLow => tsetup_DQ0_WENeg, HoldHigh => thold_DQ0_WENeg, HoldLow => thold_DQ0_WENeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_DQ0_WENeg, Violation => Tviol_DQ0_WENeg ); VitalSetupHoldCheck ( TestSignal => A, TestSignalName => "A", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_A1_WENeg, SetupLow => tsetup_A1_WENeg, HoldHigh => thold_A1_WENeg, HoldLow => thold_A1_WENeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A1_WENeg, Violation => Tviol_A1_WENeg ); VitalSetupHoldCheck ( TestSignal => WPNeg, TestSignalName => "WPNeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_WPNeg_WENeg, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WPNeg_WENeg, Violation => Tviol_WPNeg_WENeg ); VitalSetupHoldCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_ADVNeg_WENeg, CheckEnabled => ADVNeg='1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_ADVNeg_WENeg, Violation => Tviol_ADVNeg_WENeg ); VitalSetupHoldCheck ( TestSignal => CLK, TestSignalName => "CLK", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_CLK_WENeg, CheckEnabled => RCR(6)='1' AND CLK='1', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CLK_rising_WENeg, Violation => Tviol_CLK_rising_WENeg ); VitalSetupHoldCheck ( TestSignal => CLK, TestSignalName => "CLK", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_CLK_WENeg, CheckEnabled => RCR(6)='0' AND CLK='0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CLK_falling_WENeg, Violation => Tviol_CLK_falling_WENeg ); VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WENeg", RefSignal => OENeg, RefSignalName => "OENeg", SetupHigh => tsetup_WENeg_OENeg, CheckEnabled => WENeg='1', RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_OENeg, Violation => Tviol_WENeg_OENeg ); VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CENeg", PulseWidthHigh => tpw_CENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg, Violation => Pviol_CENeg ); VitalPeriodPulseCheck ( TestSignal => ADVNeg, TestSignalName => "ADVNeg", PulseWidthHigh => tpw_ADVNeg_posedge, PulseWidthLow => tpw_ADVNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_ADVNeg, Violation => Pviol_ADVNeg ); VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WENeg", PulseWidthHigh => tpw_WENeg_posedge, PulseWidthLow => tpw_WENeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, Violation => Pviol_WENeg ); VitalPeriodPulseCheck ( TestSignal => RSTNeg, TestSignalName => "RSTNeg", PulseWidthLow => tpw_RSTNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RSTNeg, Violation => Pviol_RSTNeg ); VitalPeriodPulseCheck ( TestSignal => CLK, TestSignalName => "CLK", Period => tperiod_CLK, PulseWidthHigh => tpw_CLK_posedge, PulseWidthLow => tpw_CLK_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_CLK, Violation => Pviol_CLK ); VitalRecoveryRemovalCheck ( TestSignal => RSTNeg, TestSignalName => "RSTNeg", RefSignal => WENeg, RefSignalName => "WENeg", Recovery => trecovery_RSTNeg_WENeg, ActiveLow => true, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => RD_RSTNeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Rviol_RSTNeg_WENeg ); Violation := Tviol_A1_ADVNeg OR Tviol_CENeg_ADVNeg OR Tviol_RSTNeg_ADVNeg OR Tviol_WENeg_ADVNeg OR Tviol_A1_CLK_rising OR Tviol_A1_CLK_falling OR Tviol_ADVNeg_CLK_rising OR Tviol_ADVNeg_CLK_falling OR Tviol_CENeg_CLK_rising OR Tviol_CENeg_CLK_falling OR Tviol_WENeg_CLK_rising OR Tviol_WENeg_CLK_falling OR Tviol_CENeg_WENeg_setup OR Tviol_CENeg_WENeg_hold OR Tviol_DQ0_WENeg OR Tviol_A1_WENeg OR Tviol_WPNeg_WENeg OR Tviol_ADVNeg_WENeg OR Tviol_CLK_rising_WENeg OR Tviol_CLK_falling_WENeg OR Tviol_WENeg_OENeg OR Pviol_CENeg OR Pviol_ADVNeg OR Pviol_WENeg OR Pviol_CLK OR Rviol_RSTNeg_WENeg; Viol <= Violation; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY WARNING; END IF; END PROCESS VITALTimingCheck; -- clocked process for FSM state transition PROCESS(next_state) BEGIN IF (ExtendProgTime = FALSE) THEN current_state <= next_state; END IF; END PROCESS; RSTControl : PROCESS(RSTNeg) BEGIN IF falling_edge(RSTNeg) THEN IF WordProgram_out = '1' OR BuffProgram_out ='1' OR ParameterErase_out = '1' OR MainErase_out = '1' OR BEFP_out = '1' THEN RstDuringErsPrg_in <= '1', '0' AFTER 1 ns; END IF; END IF; END PROCESS RSTControl; CLKControl : PROCESS(CLK) BEGIN IF RSTNeg = '1' AND CENeg = '0' AND WENeg = '1' AND ((RCR(6) = '0' AND falling_edge(CLK)) OR (RCR(6) = '1' AND rising_edge(CLK))) THEN CLOCK <= '1', '0' AFTER 1 ns; END IF; END PROCESS CLKControl; BusCycleDecode : PROCESS(A, DQin, WENeg, OENeg, CENeg, ADVNeg, CLOCK, RSTNeg) VARIABLE BurstDelay : NATURAL RANGE 0 TO 7; VARIABLE DataHold : NATURAL RANGE 0 TO 1; BEGIN IF (RSTNeg = '0') OR (CENeg = '1') OR falling_edge(ADVNeg) THEN LATCHED := FALSE; END IF; IF RSTNeg = '1' AND current_state /= RESET_POWER_DOWN THEN -- Address latch IF CENeg = '0' AND LATCHED = FALSE AND ((rising_edge(ADVNeg) AND WENeg = '1') OR (ADVNeg = '0' AND WENeg = '1' AND RCR(15) = '0' AND rising_edge(CLOCK))) THEN LatchedAddr := to_nat(A); ReadAddr := LatchedAddr; LATCHED := TRUE; burst_cntr := 0; BurstDelay := to_nat(RCR(13 downto 11)); CASE RCR(2 downto 0) IS WHEN "001" => BurstLength := 4; WHEN "010" => BurstLength := 8; WHEN "011" => BurstLength := 16; WHEN OTHERS => BurstLength := 0; END CASE; DataHold := 0; END IF; -- Write control IF OENeg = '1' THEN IF WENeg = '0' AND CENeg = '0' THEN Write <= '0'; ELSIF (CENeg = '0' AND rising_edge(WENeg)) OR (WENeg = '0' AND rising_edge(CENeg)) OR (rising_edge(WENeg) AND rising_edge(CENeg)) THEN LatchedData := to_nat(DQIn); LatchedAddr := to_nat(A); Write <= '1'; END IF; END IF; -- Read control IF RCR(15) = '1' THEN IF WENeg = '1' AND CENeg = '0' AND OENeg = '0' THEN IF (ADVNeg = '0') THEN ReadAddr := to_nat(A); END IF; Read <= '1'; ELSE Read <= '0'; Pmode <= '0'; END IF; IF Read = '1' AND A(1 downto 0)'EVENT THEN Pmode <= '1', '0' AFTER 2 ns; END IF; ELSE IF rising_edge(CLOCK) THEN IF BurstDelay > 0 THEN BurstDelay := BurstDelay - 1; IF RCR(8) = '1' AND (BurstDelay = 0 OR (BurstDelay = 1 AND RCR(9) = '1')) THEN DeassertWAITOut <= NOT DeassertWAITOut; END IF; ELSE IF DataHold = 0 THEN burst_cntr := burst_cntr + 1; IF OENeg = '0' THEN Read <= NOT Read; END IF; IF RCR(9) = '1' THEN DataHold := 1; END IF; IF burst_cntr > (BurstLength - to_nat(RCR(8))) AND BurstLength > 0 THEN AssertWAITOut <= NOT AssertWAITOut; -- Extra wait cycles will occur after every 4 words -- if DH = 1 clock cycle -- (variable burst_cntr is updated -- in Output process below): ELSIF read_state = READ_ARRAY AND RCR(9) = '0' AND to_nat(RCR(13 downto 11)) > 4 THEN IF RCR(8) = '0' THEN -- WAIT with data IF burst_cntr > 4 OR burst_cntr <= 0 THEN AssertWAITOut <= NOT AssertWAITOut; ELSE DeassertWAITOut <= NOT DeassertWAITOut; END IF; ELSE -- WAIT before data IF burst_cntr >= 4 OR burst_cntr < 0 THEN AssertWAITOut <= NOT AssertWAITOut; ELSE DeassertWAITOut <= NOT DeassertWAITOut; END IF; END IF; ELSE DeassertWAITOut <= NOT DeassertWAITOut; END IF; ELSE DataHold := DataHold - 1; END IF; END IF; END IF; END IF; END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- FSM Process -- combinational process for next state generation --------------------------------------------------------------------------- StateGen: PROCESS(RSTNeg, Write, abort, WordProgram_out, BuffProgram_out, ExtendProgTime, BEFP_out, BEFPsetup_out, ParameterErase_out, MainErase_out, ProgramSuspend_out, EraseSuspend_out, RstDuringErsPrg_out) VARIABLE word_cntr : NATURAL := 0; VARIABLE BEFP_block : NATURAL := 0; BEGIN IF falling_edge(RSTNeg) THEN next_state <= RESET_POWER_DOWN; ELSE CASE current_state IS WHEN RESET_POWER_DOWN => IF (rising_edge(RSTNeg) AND RstDuringErsPrg_out = '0') OR (RstDuringErsPrg_out'EVENT AND RstDuringErsPrg_out = '0') THEN next_state <= READY; END IF; WHEN READY => IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#10# | 16#40# => next_state <= PROG_SETUP; WHEN 16#E8# => next_state <= BP_SETUP; WHEN 16#20# => next_state <= ERASE_SETUP; WHEN 16#80# => next_state <= BEFP_SETUP; WHEN 16#60# => next_state <= LOCK_SETUP; WHEN 16#C0# => next_state <= OTP_SETUP; WHEN OTHERS => next_state <= current_state; END CASE; END IF; WHEN LOCK_SETUP => IF rising_edge(Write) THEN next_state <= READY; END IF; WHEN OTP_SETUP => IF rising_edge(Write) THEN next_state <= OTP_BUSY; END IF; WHEN OTP_BUSY => IF abort'EVENT OR (WordProgram_out'EVENT AND WordProgram_out = '0') THEN next_state <= READY; END IF; WHEN PROG_SETUP => IF rising_edge(Write) THEN next_state <= PROG_BUSY; END IF; WHEN PROG_BUSY => IF abort'EVENT OR (WordProgram_out'EVENT AND WordProgram_out = '0') THEN next_state <= READY; ELSIF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN next_state <= PROG_SUSP; END IF; WHEN PROG_SUSP => IF rising_edge(Write) AND LatchedData = 16#D0# THEN next_state <= PROG_BUSY; END IF; WHEN BP_SETUP => IF rising_edge(Write) THEN word_cntr := LatchedData + 1; next_state <= BP_LOAD; END IF; WHEN BP_LOAD => IF rising_edge(Write) THEN word_cntr := word_cntr - 1; IF word_cntr = 0 THEN next_state <= BP_CONFIRM; END IF; END IF; WHEN BP_CONFIRM => IF rising_edge(Write) THEN IF LatchedData = 16#D0# THEN next_state <= BP_BUSY; ELSE next_state <= READY; END IF; END IF; WHEN BP_BUSY => IF abort'EVENT OR (BuffProgram_out'EVENT AND BuffProgram_out = '0') THEN next_state <= READY; ELSIF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN next_state <= BP_SUSP; ELSIF ExtendProgTime'EVENT THEN next_state <= current_state; END IF; WHEN BP_SUSP => IF rising_edge(Write) AND LatchedData = 16#D0# THEN next_state <= BP_BUSY; END IF; WHEN ERASE_SETUP => IF rising_edge(Write) THEN IF LatchedData=16#D0# THEN next_state <= ERASE_BUSY; ELSE next_state <= READY; END IF; END IF; WHEN ERASE_BUSY => IF abort'EVENT OR (ParameterErase_out'EVENT AND ParameterErase_out = '0') OR (MainErase_out'EVENT AND MainErase_out = '0') THEN next_state <= READY; ELSIF EraseSuspend_out'EVENT AND EraseSuspend_out = '0' THEN next_state <= ERS_SUSP; END IF; WHEN ERS_SUSP => IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#10# | 16#40# => next_state <= PROG_SETUP_ERS_SUSP; WHEN 16#E8# => next_state <= BP_SETUP_ERS_SUSP; WHEN 16#D0# => next_state <= ERASE_BUSY; WHEN 16#60# => next_state <= LOCK_SETUP_ERS_SUSP; WHEN OTHERS => next_state <= current_state; END CASE; END IF; WHEN PROG_SETUP_ERS_SUSP => IF rising_edge(Write) THEN next_state <= PROG_BUSY_ERS_SUSP; END IF; WHEN PROG_BUSY_ERS_SUSP => IF abort'EVENT OR (WordProgram_out'EVENT AND WordProgram_out = '0') THEN next_state <= ERS_SUSP; ELSIF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN next_state <= PROG_SUSP_ERS_SUSP; END IF; WHEN PROG_SUSP_ERS_SUSP=> IF rising_edge(Write) AND LatchedData = 16#D0# THEN next_state <= PROG_BUSY_ERS_SUSP; END IF; WHEN BP_SETUP_ERS_SUSP => IF rising_edge(Write) THEN word_cntr := LatchedData + 1; next_state <= BP_LOAD_ERS_SUSP; END IF; WHEN BP_LOAD_ERS_SUSP => IF rising_edge(Write) THEN word_cntr := word_cntr - 1; IF word_cntr = 0 THEN next_state <= BP_CONFIRM_ERS_SUSP; END IF; END IF; WHEN BP_CONFIRM_ERS_SUSP => IF rising_edge(Write) THEN IF LatchedData=16#D0# THEN next_state <= BP_BUSY_ERS_SUSP; ELSE next_state <= ERS_SUSP; END IF; END IF; WHEN BP_BUSY_ERS_SUSP => IF abort'EVENT OR (BuffProgram_out'EVENT AND BuffProgram_out = '0') THEN next_state <= ERS_SUSP; ELSIF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN next_state <= BP_SUSP_ERS_SUSP; ELSIF ExtendProgTime'EVENT THEN next_state <= current_state; END IF; WHEN BP_SUSP_ERS_SUSP => IF rising_edge(Write) AND LatchedData = 16#D0# THEN next_state <= BP_BUSY_ERS_SUSP; END IF; WHEN LOCK_SETUP_ERS_SUSP => IF rising_edge(Write) THEN next_state <= ERS_SUSP; END IF; WHEN BEFP_SETUP => IF rising_edge(Write) THEN IF LatchedData /= 16#D0# THEN next_state <= READY; ELSE BEFP_block := BlockNumber(LatchedAddr); word_cntr := 32; END IF; ELSIF falling_edge(BEFPsetup_out) THEN IF SR(4) = '0' THEN next_state <= BEFP_LOAD; ELSE next_state <= READY; END IF; END IF; WHEN BEFP_LOAD => IF rising_edge(Write) THEN IF BlockNumber(LatchedAddr) /= BEFP_block AND LatchedData = 16#FFFF# THEN next_state <= READY; ELSE word_cntr := word_cntr - 1; IF word_cntr = 0 THEN next_state <= BEFP_BUSY; END IF; END IF; END IF; WHEN BEFP_BUSY => IF falling_edge(BEFP_out) THEN word_cntr := 32; next_state <= BEFP_LOAD; END IF; END CASE; END IF; END PROCESS StateGen; ---------------------------------------------------------------------------- -- Main behavior process ---------------------------------------------------------------------------- Functional: PROCESS(current_state, Write, WordProgram_out, BuffProgram_out, VPP, RSTNeg, ParameterErase_out, MainErase_out, BEFPsetup_out, BEFP_out) VARIABLE prog_bits : std_logic_vector(15 downto 0); VARIABLE mem_bits : std_logic_vector(15 downto 0); VARIABLE word_cntr : NATURAL := 0; VARIABLE word_number : INTEGER := 0; VARIABLE block_number : NATURAL := 0; VARIABLE erasing_block: NATURAL := 0; VARIABLE lowest_addr : NATURAL := 0; VARIABLE highest_addr : NATURAL := 0; VARIABLE start_addr : NATURAL := 0; VARIABLE BEFP_addr : NATURAL := 0; VARIABLE BEFP_block : NATURAL := 0; VARIABLE mem_data : INTEGER; VARIABLE BlockAddr : INTEGER; VARIABLE aborted : std_ulogic := '0'; BEGIN -- Clear Status reg IF current_state/=RESET_POWER_DOWN AND current_state/=OTP_BUSY AND current_state/=PROG_BUSY AND current_state/=BP_BUSY AND current_state/=ERASE_BUSY AND current_state/=PROG_BUSY_ERS_SUSP AND current_state/=BP_BUSY_ERS_SUSP AND current_state/=BEFP_SETUP AND current_state/=BEFP_LOAD AND current_state/=BEFP_LOAD AND rising_edge(Write) AND LatchedData = 16#50# THEN SR <= "10000000"; END IF; CASE current_state IS WHEN RESET_POWER_DOWN => SR <= "10000000"; Block_Lock := (OTHERS => LOCKED); BlockLockBit := (OTHERS =>'1'); BlockLockDownBit := (OTHERS =>'0'); read_state <= READ_ARRAY; RCR <= "1011111111001111"; WHEN READY => IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN OTHERS => NULL; END CASE; END IF; WHEN LOCK_SETUP | LOCK_SETUP_ERS_SUSP => IF rising_edge(Write) THEN block_number := BlockNumber(LatchedAddr); IF LatchedData = 16#03# THEN RCR <= A(15 DOWNTO 0); read_state <= READ_ARRAY; ELSIF LatchedData = 16#01# THEN read_state <= READ_STATUS; IF Block_Lock(block_number) = UNLOCKED THEN Block_Lock(block_number) := LOCKED; END IF; BlockLockBit(block_number) := '1'; ELSIF LatchedData = 16#D0# THEN read_state <= READ_STATUS; IF NOT(Block_Lock(block_number) = LOCKED_DOWN AND WPNeg = '0') THEN Block_Lock(block_number) := UNLOCKED; BlockLockBit(block_number) := '0'; END IF; ELSIF LatchedData = 16#2F# THEN read_state <= READ_STATUS; Block_Lock(block_number) := LOCKED_DOWN; BlockLockBit(block_number) := '1'; BlockLockDownBit(block_number) := '1'; ELSE read_state <= READ_STATUS; SR(4) <= '1'; SR(5) <= '1'; END IF; ELSE read_state <= READ_STATUS; END IF; WHEN OTP_SETUP => read_state <= READ_STATUS; IF rising_edge(Write) THEN DataBuff(0) := LatchedData; AddrBuff(0) := LatchedAddr; WordProgram_in <= '1', '0' AFTER 1 ns; END IF; WHEN OTP_BUSY => IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# | 16#90# | 16#98# => read_state <= READ_STATUS; WHEN OTHERS => NULL; END CASE; END IF; mem_bits := to_slv(PR(16#80#), 16); prog_bits := to_slv(PR(16#89#), 16); SR(7) <= '0'; IF VPP /= '1' THEN SR(3) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF AddrBuff(0) < 16#80# OR AddrBuff(0) > 16#109# THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF AddrBuff(0) > 16#80# AND AddrBuff(0) < 16#85# THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF AddrBuff(0) > 16#84# AND AddrBuff(0) < 16#89# AND mem_bits(1) /= '1' THEN SR(1) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF AddrBuff(0) > 16#89# AND AddrBuff(0) < 16#10A# THEN IF prog_bits((AddrBuff(0)-16#8A#)/8) /= '1' THEN SR(1) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; END IF; END IF; IF falling_edge(RSTNeg) THEN PR(AddrBuff(0)) := -1; END IF; IF WordProgram_out'EVENT AND WordProgram_out = '0' AND abort = '0' THEN IF PR(AddrBuff(0)) > -1 THEN prog_bits := to_slv(DataBuff(0), 16); mem_bits := to_slv(PR(AddrBuff(0)), 16); FOR I IN 0 TO 15 LOOP IF prog_bits(I) = '0' THEN mem_bits(I) := '0'; END IF; END LOOP; PR(AddrBuff(0)) := to_nat(mem_bits); END IF; SR(7) <= '1'; END IF; WHEN PROG_SETUP | PROG_SETUP_ERS_SUSP => read_state <= READ_STATUS; IF rising_edge(Write) THEN DataBuff(0) := LatchedData; AddrBuff(0) := LatchedAddr; WordProgram_in <= '1', '0' AFTER 1 ns; END IF; WHEN PROG_BUSY | PROG_BUSY_ERS_SUSP => SR(2) <= '0'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#B0# => ProgramSuspend_in <= '1', '0' AFTER 1 ns; WHEN OTHERS => NULL; END CASE; END IF; block_number := BlockNumber(AddrBuff(0)); IF VPP = '0' THEN SR(3) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF OTP(block_number) = '1' THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF Block_Lock(block_number) /= UNLOCKED THEN SR(1) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSE SR(7) <= '0'; END IF; read_mem (linked_list(block_number), mem_data, AddrBuff(0)); IF falling_edge(RSTNeg) THEN write_mem (linked_list(block_number), AddrBuff(0), -1); END IF; IF WordProgram_out'EVENT AND WordProgram_out = '0' AND abort = '0' THEN IF mem_data > -1 THEN prog_bits := to_slv(DataBuff(0), 16); read_mem (linked_list(block_number), mem_data, AddrBuff(0)); mem_bits := to_slv(mem_data, 16); FOR I IN 0 TO 15 LOOP IF prog_bits(I) = '0' THEN mem_bits(I) := '0'; END IF; END LOOP; mem_data := to_nat(mem_bits); write_mem (linked_list(block_number), AddrBuff(0), mem_data); END IF; SR(7) <= '1'; END IF; WHEN PROG_SUSP | PROG_SUSP_ERS_SUSP => SR(2) <= '1'; SR(7) <= '1'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#D0# => WordProgramResume <= '1', '0' AFTER 1 ns; WHEN OTHERS => NULL; END CASE; END IF; WHEN BP_SETUP | BP_SETUP_ERS_SUSP => read_state <= READ_STATUS; IF rising_edge(Write) THEN word_number := LatchedData; word_cntr := 0; END IF; WHEN BP_LOAD | BP_LOAD_ERS_SUSP => read_state <= READ_STATUS; IF rising_edge(Write) THEN DataBuff(word_cntr) := LatchedData; AddrBuff(word_cntr) := LatchedAddr; IF word_cntr = 0 THEN lowest_addr := LatchedAddr; highest_addr := LatchedAddr; ELSE IF LatchedAddr < lowest_addr THEN lowest_addr := LatchedAddr; END IF; IF LatchedAddr > highest_addr THEN highest_addr := LatchedAddr; END IF; END IF; word_cntr := word_cntr + 1; END IF; WHEN BP_CONFIRM | BP_CONFIRM_ERS_SUSP => read_state <= READ_STATUS; IF rising_edge(Write) THEN IF LatchedData = 16#D0# THEN BuffProgram_in <= '1', '0' AFTER 1 ns; ELSE SR(7) <= '1'; SR(5) <= '1'; SR(4) <= '1'; END IF; END IF; WHEN BP_BUSY | BP_BUSY_ERS_SUSP => SR(2) <= '0'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#B0# => ProgramSuspend_in <= '1', '0' AFTER 1 ns; bp_suspend := '1'; WHEN OTHERS => NULL; END CASE; END IF; block_number := BlockNumber(AddrBuff(0)); IF VPP = '0' THEN SR(3) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF OTP(block_number) = '1' THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF Block_Lock(block_number) /= UNLOCKED THEN SR(1) <= '1'; SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF lowest_addr < AddrBuff(0) OR (highest_addr > (AddrBuff(0) + word_number) AND word_number /= -1) THEN SR(4) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSIF BlockNumber(highest_addr) /= block_number THEN SR(4) <= '1'; SR(5) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; ELSE SR(7) <= '0'; END IF; IF falling_edge(RSTNeg) THEN FOR J IN 0 TO word_number LOOP write_mem (linked_list(block_number), AddrBuff(J), -1); END LOOP; END IF; IF BuffProgram_out'EVENT AND BuffProgram_out = '0' AND abort = '0' THEN FOR J IN 0 TO word_number LOOP prog_bits := to_slv(DataBuff(J), 16); read_mem(linked_list(block_number), mem_data, AddrBuff(J)); IF mem_data > -1 THEN mem_bits := to_slv(mem_data, 16); FOR I IN 0 TO 15 LOOP IF prog_bits(I) = '0' THEN mem_bits(I) := '0'; END IF; END LOOP; mem_data := to_nat(mem_bits); write_mem (linked_list(block_number), AddrBuff(J), mem_data); IF (AddrBuff(J) / 32) /= (AddrBuff(0) / 32) THEN ExtendProgTime <= TRUE, FALSE AFTER 2 ns; word_number := -1; BuffProgram_in <= '1', '0' AFTER 1 ns; END IF; END IF; END LOOP; SR(7) <= '1'; END IF; WHEN BP_SUSP | BP_SUSP_ERS_SUSP => SR(2) <= '1'; SR(7) <= '1'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#D0# => BP_ProgramResume <= '1', '0' AFTER 1 ns; bp_suspend := '0'; WHEN OTHERS => NULL; END CASE; END IF; WHEN ERASE_SETUP => read_state <= READ_STATUS; IF rising_edge(Write) THEN IF LatchedData = 16#D0# THEN erasing_block := BlockNumber(LatchedAddr); IF BlockSize(erasing_block) = ParameterBlockSize THEN ParameterErase_in <= '1' , '0' AFTER 1 ns; ELSE MainErase_in <= '1' , '0' AFTER 1 ns; END IF; ELSE SR(7) <= '1'; SR(5) <= '1'; SR(4) <= '1'; END IF; END IF; WHEN ERASE_BUSY => SR(6) <= '0'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#B0# => EraseSuspend_in <= '1', '0' AFTER 1 ns; WHEN OTHERS => NULL; END CASE; END IF; aborted := '0'; IF VPP = '0' THEN SR(3) <= '1'; SR(5) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; aborted := '1'; ELSIF OTP(erasing_block) = '1' THEN SR(5) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; aborted := '1'; ELSIF Block_Lock(erasing_block) /= UNLOCKED THEN SR(1) <= '1'; SR(5) <= '1'; SR(7) <= '1'; abort <= '1' , '0' AFTER 1 ns; aborted := '1'; ELSE SR(7) <= '0'; END IF; start_addr := StartBlockAddr(erasing_block); IF (aborted = '0') THEN FOR I IN 0 TO (BlockSize(erasing_block) - 1) LOOP corrupt_flag(erasing_block) := '1'; END LOOP; END IF; IF ((ParameterErase_out'EVENT AND ParameterErase_out = '0') OR (MainErase_out'EVENT AND MainErase_out = '0')) AND abort = '0' THEN corrupt_flag(erasing_block) := '0'; erase_mem(start_addr, start_addr+BlockSize(erasing_block)-1, linked_list(erasing_block) ); SR(7) <= '1'; END IF; WHEN ERS_SUSP => SR(6) <= '1'; SR(7) <= '1'; IF rising_edge(Write) THEN CASE LatchedData IS WHEN 16#FF# => read_state <= READ_ARRAY; WHEN 16#70# => read_state <= READ_STATUS; WHEN 16#90# => read_state <= READ_ID; WHEN 16#98# => read_state <= READ_QUERY; WHEN 16#D0# => IF BlockSize(erasing_block) = ParameterBlockSize THEN ParameterErase_in <= '1', '0' AFTER 1 ns; ELSE MainErase_in <= '1', '0' AFTER 1 ns; END IF; WHEN OTHERS => NULL; END CASE; END IF; WHEN BEFP_SETUP => read_state <= READ_STATUS; IF rising_edge(Write) AND LatchedData = 16#D0# THEN BEFP_addr := LatchedAddr; BEFP_block := BlockNumber(LatchedAddr); word_cntr := 0; IF VPP /= '1' OR VPP_voltage /= 9 THEN SR(3) <= '1'; SR(4) <= '1'; END IF; IF Block_Lock(BEFP_block) /= UNLOCKED THEN SR(1) <= '1'; SR(4) <= '1'; ELSIF (BEFP_addr mod 32) /= 0 OR OTP(BEFP_block) = '1' THEN SR(4) <= '1'; END IF; BEFPsetup_in <= '1', '0' AFTER 1 ns; ELSIF falling_edge(BEFPsetup_out) THEN IF SR(4) = '0' THEN SR(7) <= '0'; SR(0) <= '0'; END IF; END IF; WHEN BEFP_LOAD => IF rising_edge(Write) THEN IF BlockNumber(LatchedAddr) /= BEFP_block AND LatchedData = 16#FFFF# THEN SR(7) <= '1'; SR(0) <= '0'; ELSE DataBuff(word_cntr) := LatchedData; word_cntr := word_cntr + 1; IF word_cntr = 31 THEN BEFP_in <= '1', '0' AFTER 1 ns; END IF; END IF; END IF; WHEN BEFP_BUSY => IF falling_edge(RSTNeg) THEN FOR J IN 0 TO 31 LOOP write_mem (linked_list(BEFP_block), BEFP_addr + J, -1); END LOOP; END IF; IF falling_edge(BEFP_out) THEN FOR J IN 0 TO 31 LOOP prog_bits := to_slv(DataBuff(J), 16); read_mem(linked_list(BEFP_block), mem_data, BEFP_addr + J); IF mem_data > -1 THEN mem_bits := to_slv(mem_data, 16); FOR I IN 0 TO 15 LOOP IF prog_bits(I) = '0' THEN mem_bits(I) := '0'; END IF; END LOOP; mem_data := to_nat(mem_bits); write_mem (linked_list(BEFP_block), BEFP_addr + J, mem_data); END IF; END LOOP; BEFP_addr := BEFP_addr + 32; IF BEFP_addr > MemSize OR BlockNumber(BEFP_addr) > BEFP_block THEN BEFP_addr := BEFP_addr - BlockSize(BEFP_block); END IF; SR(0) <= '0'; word_cntr := 0; ELSE SR(0) <= '1'; END IF; WHEN OTHERS => NULL; END CASE; END PROCESS Functional; --------------------------------------------------------------------------- -- combinatorial output generation --------------------------------------------------------------------------- Output: PROCESS(Read, A, OENeg, CENeg) VARIABLE DQOut_tmp : std_logic_vector(15 downto 0); VARIABLE read_out : boolean; VARIABLE BlockAddr : INTEGER; VARIABLE mem_data : INTEGER; BEGIN CASE read_state IS WHEN READ_ARRAY => IF RCR(15) = '1' THEN IF A(HiAddrBit downto 2)'EVENT AND ADVNeg = '0' THEN ReadAddr := to_nat(A); ELSIF A(1 downto 0)'EVENT THEN ReadAddr := ReadAddr - (ReadAddr mod 4) + to_nat(A(1 downto 0)); END IF; END IF; IF current_state = PROG_BUSY OR current_state = PROG_BUSY_ERS_SUSP OR current_state = BP_BUSY OR current_state = BP_BUSY_ERS_SUSP OR current_state = ERASE_BUSY THEN DQOut_tmp := (OTHERS => 'U'); ELSE BlockAddr := BlockNumber(ReadAddr); read_mem(linked_list(BlockAddr), mem_data, ReadAddr); IF mem_data > -1 AND corrupt_flag(BlockAddr) = '0' THEN DQOut_tmp := to_slv(mem_data, 16); ELSE DQOut_tmp := "XXXXXXXXXXXXXXXX"; END IF; END IF; WHEN READ_ID => IF (((ReadAddr-2) mod MainBlockSize) = 0) OR (((TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B')) AND (ReadAddr < MainBlockSize AND ((ReadAddr-2) mod ParameterBlockSize) = 0)) OR (((TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T')) AND (ReadAddr > (MemSize - MainBlockSize) AND ((ReadAddr-2) mod ParameterBlockSize) = 0)) THEN DQOut_tmp(0) := BlockLockBit( BlockNumber(ReadAddr)); DQOut_tmp(1) := BlockLockDownBit( BlockNumber(ReadAddr)); DQOut_tmp(15 DOWNTO 2) := (OTHERS=>'0'); ELSIF ReadAddr = 16#00# THEN DQOut_tmp := to_slv(16#0089#, 16); ELSIF ReadAddr = 16#01# THEN IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN DQOut_tmp := to_slv(DeviceID_B, 16); ELSIF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'T') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'T') THEN DQOut_tmp := to_slv(DeviceID_T, 16); END IF; ELSIF ReadAddr = 16#05# THEN DQOut_tmp := RCR; ELSIF ReadAddr >= 16#80# AND ReadAddr <= 16#109# THEN IF PR(ReadAddr) > -1 THEN DQOut_tmp := to_slv(PR(ReadAddr), 16); ELSE DQOut_tmp := "XXXXXXXXXXXXXXXX"; END IF; END IF; WHEN READ_QUERY => IF (ReadAddr >= 16#10# AND ReadAddr <= 16#38#) OR (ReadAddr >= 16#10A# AND ReadAddr <= 16#156#) THEN DQOut_tmp := to_slv(CFI_array(ReadAddr), 16); ELSE -- RESERVED OR Address out of range DQOut_tmp := (OTHERS => '0'); END IF; WHEN OTHERS => DQOut_tmp(7 downto 0) := SR; DQOut_tmp(15 downto 8) := (OTHERS => '0'); END CASE; IF RCR(15) = '1' THEN -- Asynchronous read IF rising_edge(Read) OR (Read = '1' AND ((A'EVENT AND ADVNeg = '0') OR (A(1 downto 0)'EVENT ))) THEN DQOut_zd <= DQOut_tmp; ELSIF falling_edge(Read) THEN DQOut_zd <= (others => 'Z'); END IF; ELSE -- Burst read IF Read'EVENT THEN IF burst_cntr > BurstLength AND BurstLength /= 0 THEN read_out := FALSE; ELSIF read_state = READ_ARRAY THEN IF RCR(9) = '0' AND to_nat(RCR(13 downto 11)) > 4 AND (burst_cntr >= 5 OR burst_cntr < 1) THEN read_out := FALSE; IF burst_cntr >= 5 THEN burst_cntr := 5 - to_nat(RCR(13 downto 11)); END IF; ELSE read_out := TRUE; IF ReadAddr < MemSize THEN ReadAddr := ReadAddr + 1; END IF; IF RCR(3) = '0' AND BurstLength /= 0 THEN IF (ReadAddr mod BurstLength) = 0 THEN ReadAddr := ReadAddr - BurstLength; END IF; END IF; END IF; ELSE read_out := TRUE; END IF; IF read_out = TRUE THEN DQOut_zd <= DQOut_tmp; ELSE DQOut_zd <= "XXXXXXXXXXXXXXX0"; END IF; ELSIF CENeg = '0' AND OENeg = '0' THEN DQOut_zd <= (OTHERS => 'X'); ELSE DQOut_zd <= (OTHERS => 'Z'); END IF; END IF; IF CENeg = '1' OR OENeg = '1' THEN DQOut_zd <= (OTHERS => 'Z'); END IF; END PROCESS Output; WAITOut_control: PROCESS(CENeg, OENeg, AssertWAITOut, DeassertWAITOut) IS PROCEDURE Assert_WAITOut IS BEGIN IF RCR(10) = '0' THEN WAITOut_zd <= '0'; ELSE WAITOut_zd <= '1'; END IF; END PROCEDURE; PROCEDURE Deassert_WAITOut IS BEGIN IF RCR(10) = '0' THEN WAITOut_zd <= '1'; ELSE WAITOut_zd <= '0'; END IF; END PROCEDURE; BEGIN IF OENeg = '1' OR CENeg = '1' OR RSTNeg = '0' OR current_state = RESET_POWER_DOWN THEN WAITOut_zd <= 'Z'; ELSIF (falling_edge(OENeg) AND CENeg = '0') OR (falling_edge(CENeg) AND OENeg = '0') THEN IF RCR(15) = '1' THEN Deassert_WAITOut; ELSE Assert_WAITOut; END IF; ELSIF AssertWAITOut'EVENT THEN Assert_WAITOut; ELSIF DeassertWAITOut'EVENT THEN Deassert_WAITOut; END IF; END PROCESS WAITOut_control; ------------------------------------------------------------------------ -- Erase start, suspend, resume process ------------------------------------------------------------------------ Erase_time: PROCESS (MainErase_in, EraseSuspend_out, MainEraseResume, ParameterErase_in, ParameterEraseResume, RstDuringErsPrg_out, abort) VARIABLE merase_duration : TIME; VARIABLE perase_duration : TIME; VARIABLE melapsed : TIME; VARIABLE pelapsed : TIME; VARIABLE mstart : TIME; VARIABLE pstart : TIME; BEGIN IF LongTiming = TRUE THEN merase_duration := tdevice_EraseMain; perase_duration := tdevice_EraseParameter; ELSE merase_duration := tdevice_EraseMain / 1000; perase_duration := tdevice_EraseParameter/1000; END IF; IF (RstDuringErsPrg_out'EVENT AND RstDuringErsPrg_out = '0') OR abort'EVENT THEN MainErase_out <= '0'; ParameterErase_out <= '0'; END IF; IF rising_edge(MainErase_in) THEN melapsed := 0 ns; MainErase_out <= '1', '0' AFTER merase_duration; mstart := NOW; END IF; IF rising_edge(ParameterErase_in) THEN pelapsed := 0 ns; ParameterErase_out <= '1', '0' AFTER perase_duration; pstart := NOW; END IF; IF EraseSuspend_out'EVENT AND EraseSuspend_out = '0' THEN melapsed := NOW - mstart; merase_duration := merase_duration - melapsed; MainErase_out <= '1'; pelapsed := NOW - pstart; perase_duration := perase_duration - pelapsed; ParameterErase_out <= '1'; END IF; IF rising_edge(MainEraseResume) THEN mstart := NOW; MainErase_out <= '1', '0' AFTER merase_duration; END IF; IF rising_edge(ParameterEraseResume) THEN pstart := NOW; ParameterErase_out <= '1', '0' AFTER perase_duration; END IF; END PROCESS Erase_time; ------------------------------------------------------------------------- -- Process for programming start, suspend, resume ------------------------------------------------------------------------- Program_time: PROCESS (BuffProgram_in, ProgramSuspend_out, BP_ProgramResume , WordProgram_in, WordProgramResume, RstDuringErsPrg_out, abort) VARIABLE buffp_duration : TIME; VARIABLE wordp_duration : TIME; VARIABLE elapsed : TIME; VARIABLE start : TIME; VARIABLE welapsed : TIME; VARIABLE wstart : TIME; BEGIN IF VPP_voltage /= 9 THEN IF LongTiming = TRUE THEN buffp_duration := tdevice_BuffProgram; ELSE buffp_duration := tdevice_BuffProgram / 10; END IF; wordp_duration := tdevice_WordProgram; ELSE IF LongTiming = TRUE THEN buffp_duration := tdevice_BuffProgram9V; ELSE buffp_duration := tdevice_BuffProgram9V / 10; END IF; wordp_duration := tdevice_WordProgram9V; END IF; IF (RstDuringErsPrg_out'EVENT AND RstDuringErsPrg_out = '0') OR abort'EVENT THEN WordProgram_out <= '0'; BuffProgram_out <= '0'; END IF; IF rising_edge(WordProgram_in) THEN welapsed := 0 ns; WordProgram_out <= '1', '0' AFTER wordp_duration; wstart := NOW; END IF; IF rising_edge(BuffProgram_in) THEN elapsed := 0 ns; BuffProgram_out <= '1', '0' AFTER buffp_duration; start := NOW; END IF; IF rising_edge(WordProgramResume) THEN wstart := NOW; WordProgram_out <= '1', '0' AFTER wordp_duration; END IF; IF rising_edge(BP_ProgramResume) THEN start := NOW; BuffProgram_out <= '1', '0' AFTER buffp_duration; END IF; IF ProgramSuspend_out'EVENT AND ProgramSuspend_out = '0' THEN IF bp_suspend = '1' THEN elapsed := NOW - start; buffp_duration := buffp_duration - elapsed; BuffProgram_out <= '1'; ELSE welapsed := NOW - wstart; wordp_duration := wordp_duration - welapsed; WordProgram_out <= '1'; END IF; END IF; END PROCESS Program_time; BEFP_time : PROCESS (BEFP_in) BEGIN IF rising_edge(BEFP_in) THEN IF LongTiming = TRUE THEN BEFP_out <= '1' , '0' AFTER tdevice_BEFP; ELSE BEFP_out <= '1' , '0' AFTER tdevice_BEFP / 10; END IF; END IF; END PROCESS BEFP_time; ---------------------------------------------------------------------------- ---- CFI Preload Process ---------------------------------------------------------------------------- CFIPreload : PROCESS BEGIN CFI_array := (OTHERS => 16#FF#); -- CFI Indentification CFI_array(16#10#):=16#51#; CFI_array(16#11#):=16#52#; CFI_array(16#12#):=16#59#; CFI_array(16#13#):=16#01#; CFI_array(16#14#):=16#00#; CFI_array(16#15#):=16#0A#; CFI_array(16#16#):=16#01#; CFI_array(16#17#):=16#00#; CFI_array(16#18#):=16#00#; CFI_array(16#19#):=16#00#; CFI_array(16#1A#):=16#00#; -- System Interface Information CFI_array(16#1B#):=16#23#; CFI_array(16#1C#):=16#36#; CFI_array(16#1D#):=16#85#; CFI_array(16#1E#):=16#95#; CFI_array(16#1F#):=16#08#; CFI_array(16#20#):=16#09#; CFI_array(16#21#):=16#0A#; CFI_array(16#22#):=16#00#; CFI_array(16#23#):=16#01#; CFI_array(16#24#):=16#01#; CFI_array(16#25#):=16#02#; CFI_array(16#26#):=16#00#; -- Device Geometry definition CFI_array(16#27#):=16#18#; CFI_array(16#28#):=16#01#; CFI_array(16#29#):=16#00#; CFI_array(16#2A#):=16#06#; CFI_array(16#2B#):=16#00#; CFI_array(16#2C#):=16#02#; IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN CFI_array(16#2D#):=16#03#; CFI_array(16#2E#):=16#00#; CFI_array(16#2F#):=16#80#; CFI_array(16#30#):=16#00#; CFI_array(16#31#):=16#7E#; CFI_array(16#32#):=16#00#; CFI_array(16#33#):=16#00#; CFI_array(16#34#):=16#02#; ELSE CFI_array(16#2D#):=16#7E#; CFI_array(16#2E#):=16#00#; CFI_array(16#2F#):=16#00#; CFI_array(16#30#):=16#02#; CFI_array(16#31#):=16#03#; CFI_array(16#32#):=16#00#; CFI_array(16#33#):=16#80#; CFI_array(16#34#):=16#00#; END IF; CFI_array(16#35#):=16#00#; CFI_array(16#36#):=16#00#; CFI_array(16#37#):=16#00#; CFI_array(16#38#):=16#00#; -- Primary-vendor specific extended query CFI_array(16#10A#):=16#50#; CFI_array(16#10B#):=16#52#; CFI_array(16#10C#):=16#49#; CFI_array(16#10D#):=16#31#; CFI_array(16#10E#):=16#34#; CFI_array(16#10F#):=16#E6#; CFI_array(16#110#):=16#01#; CFI_array(16#111#):=16#00#; CFI_array(16#112#):=16#00#; CFI_array(16#113#):=16#01#; CFI_array(16#114#):=16#03#; CFI_array(16#115#):=16#00#; CFI_array(16#116#):=16#30#; CFI_array(16#117#):=16#90#; -- Protection register information CFI_array(16#118#):=16#02#; CFI_array(16#119#):=16#80#; CFI_array(16#11A#):=16#00#; CFI_array(16#11B#):=16#03#; CFI_array(16#11C#):=16#03#; CFI_array(16#11D#):=16#89#; CFI_array(16#11E#):=16#00#; CFI_array(16#11F#):=16#00#; CFI_array(16#120#):=16#00#; CFI_array(16#121#):=16#00#; CFI_array(16#122#):=16#00#; CFI_array(16#123#):=16#00#; CFI_array(16#124#):=16#10#; CFI_array(16#125#):=16#00#; CFI_array(16#126#):=16#04#; -- Burst read information CFI_array(16#127#):=16#03#; CFI_array(16#128#):=16#04#; CFI_array(16#129#):=16#01#; CFI_array(16#12A#):=16#02#; CFI_array(16#12B#):=16#03#; CFI_array(16#12C#):=16#07#; --Partition and Erase Block Region Information CFI_array(16#12D#):=16#01#; CFI_array(16#12E#):=16#24#; CFI_array(16#12F#):=16#00#; CFI_array(16#130#):=16#01#; CFI_array(16#131#):=16#00#; CFI_array(16#132#):=16#11#; CFI_array(16#133#):=16#00#; CFI_array(16#134#):=16#00#; CFI_array(16#135#):=16#02#; IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN CFI_array(16#136#):=16#03#; CFI_array(16#137#):=16#00#; CFI_array(16#138#):=16#80#; CFI_array(16#139#):=16#00#; ELSE CFI_array(16#136#):=16#7E#; CFI_array(16#137#):=16#00#; CFI_array(16#138#):=16#00#; CFI_array(16#139#):=16#02#; END IF; CFI_array(16#13A#):=16#64#; CFI_array(16#13B#):=16#00#; CFI_array(16#13C#):=16#02#; CFI_array(16#13D#):=16#03#; CFI_array(16#13E#):=16#00#; CFI_array(16#13F#):=16#80#; CFI_array(16#140#):=16#00#; CFI_array(16#141#):=16#00#; CFI_array(16#142#):=16#00#; CFI_array(16#143#):=16#80#; IF (TimingModel(3 to 4) = "28" AND TimingModel(12) = 'B') OR (TimingModel(3 to 4) = "48" AND TimingModel(13) = 'B') THEN CFI_array(16#144#):=16#7E#; CFI_array(16#145#):=16#00#; CFI_array(16#146#):=16#00#; CFI_array(16#147#):=16#02#; ELSE CFI_array(16#144#):=16#03#; CFI_array(16#145#):=16#00#; CFI_array(16#146#):=16#80#; CFI_array(16#147#):=16#00#; END IF; CFI_array(16#148#):=16#64#; CFI_array(16#149#):=16#00#; CFI_array(16#14A#):=16#02#; CFI_array(16#14B#):=16#03#; CFI_array(16#14C#):=16#00#; CFI_array(16#14D#):=16#80#; CFI_array(16#14E#):=16#00#; CFI_array(16#14F#):=16#00#; CFI_array(16#150#):=16#00#; CFI_array(16#151#):=16#80#; CFI_array(16#152#):=16#FF#; CFI_array(16#153#):=16#FF#; CFI_array(16#154#):=16#FF#; CFI_array(16#155#):=16#FF#; CFI_array(16#156#):=16#FF#; WAIT; END PROCESS CFIPreload; --------------------------------------------------------------------------- ---- File Read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_f : text is mem_file_name; FILE prot_reg_f : text is prot_reg_file_name; FILE otp_blocks_f : text is otp_blocks_file_name; VARIABLE buf : line; VARIABLE addr_ind : INTEGER; VARIABLE mem_data : INTEGER; VARIABLE BlockAddr : INTEGER; BEGIN configure_memory(16#FFFF#); initialize; PR := (OTHERS => MaxData); PR(16#80#) := 16#FFFE#; OTP := (OTHERS => '0'); IF (mem_file_name /= "none" AND UserPreload) THEN -- i28f128p33 memory file -- / - comment -- @aaaaaa - stands for address -- dddd - is word to be written at Mem(aaaaaa) -- (aaaaaa is incremented at every load) -- No empty lines. addr_ind := 0; WHILE (not ENDFILE (mem_f)) LOOP READLINE (mem_f, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 7)); ELSE IF addr_ind < MemSize THEN mem_data := h(buf(1 to 4)); BlockAddr := BlockNumber(addr_ind); write_mem( linked_list(BlockAddr), addr_ind, mem_data ); addr_ind := (addr_ind + 1) mod MemSize; ELSE REPORT "ERROR preloaded location out of range"; END IF; END IF; END LOOP; END IF; IF (prot_reg_file_name /= "none" AND UserPreload ) THEN -- i28f128p33 protection registers file -- / - comment -- @aaa - stands for address -- dddd - is word to be written at PR(aaa) -- (aaa is incremented at every load) -- No empty lines. addr_ind := 0; WHILE (not ENDFILE (prot_reg_f)) LOOP READLINE (prot_reg_f, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 4)); ELSE IF addr_ind >= 16#80# AND addr_ind <= 16#109# THEN PR(addr_ind) := h(buf(1 to 4)); addr_ind := (addr_ind + 1); ELSE REPORT "ERROR preloaded location out of range"; END IF; END IF; END LOOP; END IF; IF (otp_blocks_file_name /= "none" AND UserPreload ) THEN -- i28f128p33 OTP blocks file -- / - comment -- @aaa - stands for address -- d - : 1 - block is OTP, 0 - block is not OTP (default) -- (aaa is incremented at every load) -- No empty lines. addr_ind := 0; WHILE (not ENDFILE (otp_blocks_f)) LOOP READLINE (otp_blocks_f, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --address addr_ind := h(buf(2 to 4)); ELSE IF addr_ind <= HiBlockNum THEN IF (buf(1) = '1') THEN OTP(addr_ind) := '1'; END IF; addr_ind := (addr_ind + 1); ELSE REPORT "ERROR preloaded location out of range"; END IF; END IF; END LOOP; END IF; WAIT; END PROCESS MemPreload; AddressEvent : PROCESS(A(HiAddrbit downto 2)) BEGIN IF (LATCHED = FALSE) THEN AddressChange <= NOT AddressChange; END IF; END PROCESS AddressEvent; ----------------------------------------------------------------------- -- Path Delay Section ----------------------------------------------------------------------- DQOutPassThrough : PROCESS(DQOut_zd) VARIABLE CEDQ_t : TIME; VARIABLE OEDQ_t : TIME; VARIABLE ADDRDQ_t : TIME; VARIABLE CEDQx_t : TIME; VARIABLE OEDQx_t : TIME; BEGIN IF (RCR(15) = '1') THEN FROMOE := FALSE; FROMCE := FALSE; FROMOEx := FALSE; FROMCEx := FALSE; IF (DQOut_zd(0) /= 'Z') THEN OEDQx_t := - OENeg'LAST_EVENT + tpd_OENeg_DQ0(trzx); CEDQx_t := - CENeg'LAST_EVENT+ tpd_CENeg_DQ0(trzx); IF (OEDQx_t >= CEDQx_t) AND (OEDQx_t >= 0 ns) THEN t_DQx := tpd_OENeg_DQ0(trzx); FROMOEx := TRUE; ELSIF (CEDQx_t > OEDQx_t) AND (CEDQx_t >= 0 ns) THEN t_DQx := tpd_CENeg_DQ0(trzx); FROMCEx := TRUE; END IF; OEDQ_t := - OENeg'LAST_EVENT + tpd_OENeg_DQ0(trz0); CEDQ_t := - CENeg'LAST_EVENT + tpd_CENeg_DQ0(trz0); IF (Pmode = '0') THEN ADDRDQ_t := - AddressChange'LAST_EVENT + tpd_A1_DQ0_InitialPageAccess(tr01); ELSE ADDRDQ_t := - A(1 downto 0)'LAST_EVENT + tpd_A1_DQ0_SubsequentPageAccess(tr01); END IF; IF (OEDQ_t >= CEDQ_t) AND (OEDQ_t > 0 ns) THEN t_DQ := tpd_OENeg_DQ0(trz0); FROMOE := TRUE; ELSIF (CEDQ_t > OEDQ_t) AND (CEDQ_t > 0 ns) THEN t_DQ := tpd_CENeg_DQ0(trz0); FROMCE := TRUE; ELSIF Pmode = '0' THEN t_DQ := tpd_A1_DQ0_InitialPageAccess(tr01); ELSIF Pmode = '1' THEN t_DQ := tpd_A1_DQ0_SubsequentPageAccess(tr01); END IF; IF ((ADDRDQ_t > 0 ns) AND (((ADDRDQ_t > CEDQ_t) AND FROMCE) OR ((ADDRDQ_t > OEDQ_t) AND FROMOE))) THEN DQOut_Pass <= "XXXXXXXXXXXXXXXX", DQOut_zd AFTER ADDRDQ_t; ELSE DQOut_Pass <= "XXXXXXXXXXXXXXXX", DQOut_zd AFTER 1 ns; END IF; ELSE FROMOE := TRUE; FROMCE := TRUE; FROMOEx := TRUE; FROMCEx := TRUE; t_DQx := tpd_OENeg_DQ0(tr0x); t_DQ := tpd_OENeg_DQ0(tr0z); DQOut_Pass <= "XXXXXXXXXXXXXXXX" , DQOut_zd AFTER 1 ns; END IF; ELSE IF (DQOut_zd(0) /= 'Z') THEN IF (DQOut_zd(0) /= 'X') THEN t_DQx := tpd_CLK_DQ0(tr0x); t_DQ := tpd_CLK_DQ0(tr01); IF (DQOut_zd(1) = 'X') THEN DQOut_Pass <= "XXXXXXXXXXXXXXXX"; ELSE DQOut_Pass <= "XXXXXXXXXXXXXXXX", DQOut_zd AFTER 1 ns; END IF; ELSE t_DQx := tpd_OENeg_DQ0(tr0x); DQOut_Pass <= DQOut_zd; END IF; ELSE t_DQ := tpd_OENeg_DQ0(tr0z); DQOut_Pass <= DQOut_zd; END IF; END IF; END PROCESS DQOutPassThrough; --------------------------------------------------------------------------- -- Path Delay Section for DQOut signal --------------------------------------------------------------------------- DQOut_PathDelay_Gen : FOR i IN 0 TO 15 GENERATE PROCESS(DQOut_Pass(i)) VARIABLE DQ0_GlitchData: VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => DQOut(i), OutSignalName => "DQOut", OutTemp => DQOut_Pass(i), GlitchData => DQ0_GlitchData, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQx), PathCondition => RCR(15) = '1' AND FROMCEx AND DQOut_Pass(0) = 'X' ), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQx), PathCondition => RCR(15) = '1' AND FROMOEx AND DQOut_Pass(0) = 'X'), 2 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '1' AND FROMCE AND DQOut_Pass(0) /= 'X'), 3 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '1' AND FROMOE AND DQOut_Pass(0) /= 'X'), 4 => (InputChangeTime => A'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '1' AND DQOut_Pass(0) /= 'X' ), 5 => (InputChangeTime => CLK'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQx), PathCondition => RCR(15) = '0' AND DQOut_Pass(0) = 'X'), 6 => (InputChangeTime => CLK'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '0' AND DQOut_Pass(0) /= 'X'), 7 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQx), PathCondition => RCR(15) = '0' AND DQOut_Pass(0) = 'X'), 8 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => VitalExtendToFillDelay(t_DQ), PathCondition => RCR(15) = '0' AND DQOut_Pass(0) /= 'X') ) ); END PROCESS; END GENERATE DQOut_PathDelay_Gen; ----------------------------------------------------------------------- -- Path Delay Section for WAITOut ----------------------------------------------------------------------- WT_OUT: PROCESS(WAITOut_zd) VARIABLE WT_GlitchData: VitalGlitchDataType; BEGIN VitalPathDelay01Z( OutSignal => WAITOut, OutSignalName => "WAITOut", OutTemp => WAITOut_zd, Mode => VitalTransport, GlitchData => WT_GlitchData, Paths => ( 0 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_WAITOut, PathCondition => TRUE), 1 => (InputChangeTime => OENeg'LAST_EVENT, PathDelay => tpd_OENeg_WAITOut, PathCondition => TRUE), 2 => (InputChangeTime => CLK'LAST_EVENT, PathDelay => tpd_CLK_WAITOut, PathCondition => TRUE) ) ); END PROCESS WT_Out; END BLOCK behavior; END vhdl_behavioral_dynamic_memory_allocation;