------------------------------------------------------------------------------- -- File name : s30ms512r01.vhd ------------------------------------------------------------------------------- -- Copyright (C) 2006 Free Model Foundry; http://www.FreeModelFoundry.com -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License version 2 as -- published by the Free Software Foundation. -- -- MODIFICATION HISTORY: -- -- version: | author: | mod date: | changes made: -- V1.0 A.Anic 06 Mar 27 Initial Version -- V1.1 S.Janevski 06 Nov 30 New specification update ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: FLASH -- Technology: FLASH MEMORY -- Part: s30ms512r01 -- -- Description: 512Mb (32Mx16) NAND interface Flash Memory ------------------------------------------------------------------------------- -- Known Bugs: -- ------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.VITAL_timing.ALL; USE IEEE.VITAL_primitives.ALL; USE STD.textio.ALL; LIBRARY FMF; USE FMF.gen_utils.ALL; USE FMF.conversions.ALL; ------------------------------------------------------------------------------- -- ENTITY DECLARATION ------------------------------------------------------------------------------- ENTITY s30ms512r01 IS GENERIC ( tipd_IO15 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO14 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO13 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO12 : VitalDelayType01 := VitalZeroDelay01; --data tipd_IO11 : VitalDelayType01 := VitalZeroDelay01; --input tipd_IO10 : VitalDelayType01 := VitalZeroDelay01; --/output tipd_IO9 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO8 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO7 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO6 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO5 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO4 : VitalDelayType01 := VitalZeroDelay01; --data tipd_IO3 : VitalDelayType01 := VitalZeroDelay01; --input tipd_IO2 : VitalDelayType01 := VitalZeroDelay01; --/output tipd_IO1 : VitalDelayType01 := VitalZeroDelay01; -- tipd_IO0 : VitalDelayType01 := VitalZeroDelay01; -- tipd_CLE : VitalDelayType01 := VitalZeroDelay01; -- tipd_ALE : VitalDelayType01 := VitalZeroDelay01; -- tipd_CENeg : VitalDelayType01 := VitalZeroDelay01; -- tipd_RENeg : VitalDelayType01 := VitalZeroDelay01; -- tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; -- tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; -- --tpd delays tpd_CENeg_IO0 : VitalDelayType01Z := UnitDelay01Z; -- tcea, tchz tpd_RENeg_IO0 : VitalDelayType01Z := UnitDelay01Z; -- trea, trhZ tpd_WENeg_RY : VitalDelayType01 := UnitDelay01; -- twb --tsetup values tsetup_CLE_WENeg : VitalDelayType := UnitDelay; -- tcls edge \ tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; -- tcs edge \ tsetup_WENeg_CENeg : VitalDelayType := UnitDelay; -- twhc edge \ tsetup_ALE_WENeg : VitalDelayType := UnitDelay; -- tals edge \ tsetup_IO0_WENeg : VitalDelayType := UnitDelay; -- tds edge / tsetup_ALE_RENeg : VitalDelayType := UnitDelay; -- tar edge \ tsetup_CLE_RENeg : VitalDelayType := UnitDelay; -- tclr edge \ tsetup_WENeg_RENeg : VitalDelayType := UnitDelay; -- twhr edge \ tsetup_RENeg_WENeg : VitalDelayType := UnitDelay; -- trhw edge \ tsetup_WPNeg_WENeg : VitalDelayType := UnitDelay; -- tww edge / tsetup_CENeg_RENeg : VitalDelayType := UnitDelay; -- tcr edge \ --thold values thold_CLE_WENeg : VitalDelayType := UnitDelay; -- tclh edge / thold_CENeg_WENeg : VitalDelayType := UnitDelay; -- tch edge / thold_ALE_WENeg : VitalDelayType := UnitDelay; -- talh edge / thold_IO0_WENeg : VitalDelayType := UnitDelay; -- tdh edge / thold_CENeg_RENeg : VitalDelayType := UnitDelay; -- tch edge / --tpw values: pulse width tpw_WENeg_negedge : VitalDelayType := UnitDelay; -- twp tpw_WENeg_posedge : VitalDelayType := UnitDelay; -- twh tpw_RENeg_negedge : VitalDelayType := UnitDelay; -- trp tpw_RENeg_posedge : VitalDelayType := UnitDelay; -- treh --tperiod values tperiod_WENeg : VitalDelayType := UnitDelay; --twc tperiod_RENeg : VitalDelayType := UnitDelay; --trc --tdevice values: values for internal delay tdevice_PROG : VitalDelayType := 800 us; -- Program Operation tdevice_SPROG : VitalDelayType := 260 us; -- Segment Program Operation tdevice_ERS : VitalDelayType := 50 ms; -- Erase Operation tdevice_DBSY : VitalDelayType := 400 ns; -- Dummy busy time tdevice_TR : VitalDelayType := 25 us; -- Page transfer time tdevice_TRP : VitalDelayType := 8 us; -- Page transfer time tdevice_TPT : VitalDelayType := 25 us; -- Pipeline transfer time tdevice_RST : VitalDelayType := 1 us; -- Time for reset tdevice_SUSP : VitalDelayType := 15 us; -- Time for erase suspend tdevice_PRESUS : VitalDelayType := 1.5 us; -- Premble Suspend time tdevice_OTP : VitalDelayType := 5 us; -- OTP busy time tdevice_OTPD : VitalDelayType := 150 us; -- OTP default busy time tdevice_TPRE : VitalDelayType := 200 us; -- Time for reading buffer after power-up -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXOn; -- memory file to be loaded mem_file_name : STRING := "none"; --"s30ms512r01.mem"; OTP_file_name : STRING := "none"; --"s30ms512r01_OTP.mem"; protOTP_file_name : STRING := "none"; --"s30ms512r01_OTPprot.mem"; UserPreload : BOOLEAN := FALSE; Long_Timming : BOOLEAN := TRUE; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( IO15 : INOUT std_ulogic := 'U'; -- IO14 : INOUT std_ulogic := 'U'; -- IO13 : INOUT std_ulogic := 'U'; -- IO12 : INOUT std_ulogic := 'U'; --data IO11 : INOUT std_ulogic := 'U'; --input/output IO10 : INOUT std_ulogic := 'U'; -- IO9 : INOUT std_ulogic := 'U'; -- IO8 : INOUT std_ulogic := 'U'; -- IO7 : INOUT std_ulogic := 'U'; -- IO6 : INOUT std_ulogic := 'U'; -- IO5 : INOUT std_ulogic := 'U'; -- IO4 : INOUT std_ulogic := 'U'; --data IO3 : INOUT std_ulogic := 'U'; --input/output IO2 : INOUT std_ulogic := 'U'; -- IO1 : INOUT std_ulogic := 'U'; -- IO0 : INOUT std_ulogic := 'U'; -- CLE : IN std_ulogic := 'U'; -- ALE : IN std_ulogic := 'U'; -- CENeg : IN std_ulogic := 'U'; -- RENeg : IN std_ulogic := 'U'; -- WENeg : IN std_ulogic := 'U'; -- WPNeg : IN std_ulogic := 'U'; -- RY : OUT std_ulogic := '0' -- ); ATTRIBUTE VITAL_LEVEL0 of s30ms512r01 : ENTITY IS TRUE; END ENTITY s30ms512r01; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral_dynamic_memory_allocation OF s30ms512r01 IS ATTRIBUTE VITAL_LEVEL0 OF vhdl_behavioral_dynamic_memory_allocation : ARCHITECTURE IS TRUE; CONSTANT PartId : STRING := "s30ms512r01"; CONSTANT MaxData : NATURAL := 16#FFFF#; CONSTANT BlockNum : NATURAL := 511; -- number of blocks CONSTANT BlockSize : NATURAL := 63; -- size of block in pages CONSTANT PageNum : NATURAL := 16#7FFF#; -- block * numinblock CONSTANT PageNumInBl : NATURAL := 64; CONSTANT PageSize : NATURAL := 1055; -- with spare CONSTANT SegmentNum : NATURAL := 7; -- 8 segment within page CONSTANT SegmentSize : natural := 256; CONSTANT SperSegSize : NATURAL := 8; CONSTANT SpareSize : natural := 32; CONSTANT MainSize : NATURAL := 1024; CONSTANT OTPPageNum : NATURAL := 7; CONSTANT MainAreaAddBit : natural := 10; CONSTANT HAddBitPag : NATURAL := 16; CONSTANT HAddBitBl : natural := 25; CONSTANT HAddBitSpareSeg : NATURAL := 4; CONSTANT HAddBitSeg : NATURAL := 9; -- Interconnect path delay signals SIGNAL IO15_ipd : std_ulogic := 'U'; SIGNAL IO14_ipd : std_ulogic := 'U'; SIGNAL IO13_ipd : std_ulogic := 'U'; SIGNAL IO12_ipd : std_ulogic := 'U'; SIGNAL IO11_ipd : std_ulogic := 'U'; SIGNAL IO10_ipd : std_ulogic := 'U'; SIGNAL IO9_ipd : std_ulogic := 'U'; SIGNAL IO8_ipd : std_ulogic := 'U'; SIGNAL IO7_ipd : std_ulogic := 'U'; SIGNAL IO6_ipd : std_ulogic := 'U'; SIGNAL IO5_ipd : std_ulogic := 'U'; SIGNAL IO4_ipd : std_ulogic := 'U'; SIGNAL IO3_ipd : std_ulogic := 'U'; SIGNAL IO2_ipd : std_ulogic := 'U'; SIGNAL IO1_ipd : std_ulogic := 'U'; SIGNAL IO0_ipd : std_ulogic := 'U'; SIGNAL CLE_ipd : std_ulogic := 'U'; SIGNAL ALE_ipd : std_ulogic := 'U'; SIGNAL CENeg_ipd : std_ulogic := 'U'; SIGNAL RENeg_ipd : std_ulogic := 'U'; SIGNAL WENeg_ipd : std_ulogic := 'U'; SIGNAL WPNeg_ipd : std_ulogic := 'U'; -- internal delays SIGNAL PROG_in : std_ulogic := '0'; SIGNAL PROG_out : std_ulogic := '0'; SIGNAL ERS_in : std_ulogic := '0'; SIGNAL ERS_out : std_ulogic := '0'; SIGNAL DBSY_in : std_ulogic := '0'; SIGNAL DBSY_out : std_ulogic := '0'; SIGNAL TR_in : std_ulogic := '0'; SIGNAL TR_out : std_ulogic := '0'; SIGNAL TRP_in : std_ulogic := '0'; SIGNAL TRP_out : std_ulogic := '0'; SIGNAL TPT_in : std_ulogic := '0'; SIGNAL TPT_out : std_ulogic := '0'; SIGNAL ERS_SUSP_in : std_ulogic := '0'; SIGNAL ERS_SUSP_out : std_ulogic := '0'; SIGNAL ERS_PRESUS_in : std_ulogic := '0'; SIGNAL ERS_PRESUS_out : std_ulogic := '0'; SIGNAL OTP_in : std_ulogic := '0'; SIGNAL OTP_out : std_ulogic := '0'; SIGNAL WAIT_OTP_in : std_ulogic := '0'; SIGNAL WAIT_OTP_out : std_ulogic := '0'; SIGNAL DEF_OTP_in : std_ulogic := '0'; SIGNAL DEF_OTP_out: std_ulogic := '0'; SIGNAL TPRE_in : std_ulogic := '0'; SIGNAL TPRE_out : std_ulogic := '0'; SIGNAL PROG_tmp_in : std_ulogic := '0'; SIGNAL PROG_tmp_out : std_ulogic := '0'; SIGNAL SPROG_in : std_ulogic := '0'; SIGNAL SPROG_out : std_ulogic := '0'; SIGNAL DBSY_tmp_in : std_ulogic := '0'; SIGNAL DBSY_tmp_out : std_ulogic := '0'; SIGNAL TRP_tmp_in : std_ulogic := '0'; SIGNAL TRP_tmp_out : std_ulogic := '0'; SIGNAL TR_tmp_in : std_ulogic := '0'; SIGNAL TR_tmp_out : std_ulogic := '0'; SIGNAL TPT_tmp_in : std_ulogic := '0'; SIGNAL TPT_tmp_out : std_ulogic := '0'; SIGNAL RST_tmp_in : std_ulogic := '0'; SIGNAL RST_tmp_out : std_ulogic := '0'; SIGNAL ERS_SUSP_tmp_in : std_ulogic := '0'; SIGNAL ERS_SUSP_tmp_out : std_ulogic := '0'; SIGNAL ERS_PRESUS_tmp_in : std_ulogic := '0'; SIGNAL ERS_PRESUS_tmp_out : std_ulogic := '0'; SIGNAL OTP_tmp_in : std_ulogic := '0'; SIGNAL OTP_tmp_out : std_ulogic := '0'; SIGNAL OTPD_tmp_in : std_ulogic := '0'; SIGNAL OTPD_tmp_out : std_ulogic := '0'; SIGNAL TPRE_tmp_in : std_ulogic := '0'; SIGNAL TPRE_tmp_out : std_ulogic := '0'; BEGIN -- ARCHITECTURE vhdl_behavioral ----------------------------------------------------------------------------- -- Internal delays ----------------------------------------------------------------------------- -- Vital primitives which incorporate internal delays PROG : VitalBUF(PROG_tmp_out, PROG_tmp_in, (tdevice_PROG, UnitDelay)); SPROG : VitalBUF(SPROG_out, SPROG_in, (tdevice_SPROG, UnitDelay)); ERS : VitalBUF(ERS_out, ERS_in, (tdevice_ERS, UnitDelay)); DBSY : VitalBUF(DBSY_tmp_out, DBSY_tmp_in, (tdevice_DBSY, UnitDelay)); TR : VitalBUF(TR_tmp_out, TR_tmp_in, (tdevice_TR, UnitDelay)); TRP : VitalBUF(TRP_tmp_out, TRP_tmp_in, (tdevice_TRP, UnitDelay)); TPT : VitalBUF(TPT_tmp_out, TPT_tmp_in, (tdevice_TPT, UnitDelay)); RST : VitalBUF(RST_tmp_out, RST_tmp_in, (tdevice_RST, UnitDelay)); SUSP : VitalBUF(ERS_SUSP_tmp_out, ERS_SUSP_tmp_in, (tdevice_SUSP, UnitDelay)); PRESUS : VitalBUF(ERS_PRESUS_tmp_out, ERS_PRESUS_tmp_in, (tdevice_PRESUS, UnitDelay)); OTP : VitalBUF(OTP_tmp_out, OTP_tmp_in, (tdevice_OTP, UnitDelay)); OTPD : VitalBUF(OTPD_tmp_out, OTPD_tmp_in, (tdevice_OTPD,UnitDelay)); TPRE : VitalBUF(TPRE_tmp_out, TPRE_tmp_in, (tdevice_TPRE, UnitDelay)); ----------------------------------------------------------------------------- -- WIRE DELAYS ----------------------------------------------------------------------------- WireDelay : BLOCK IS BEGIN -- BLOCK WireDelay w_1 : VitalWireDelay( IO15_ipd, IO15, tipd_IO15 ); w_2 : VitalWireDelay( IO14_ipd, IO14, tipd_IO14 ); w_3 : VitalWireDelay( IO13_ipd, IO13, tipd_IO13 ); w_4 : VitalWireDelay( IO12_ipd, IO12, tipd_IO12 ); w_5 : VitalWireDelay( IO11_ipd, IO11, tipd_IO11 ); w_6 : VitalWireDelay( IO10_ipd, IO10, tipd_IO10 ); w_7 : VitalWireDelay( IO9_ipd, IO9, tipd_IO9 ); w_8 : VitalWireDelay( IO8_ipd, IO8, tipd_IO8 ); w_9 : VitalWireDelay( IO7_ipd, IO7, tipd_IO7 ); w_10 : VitalWireDelay( IO6_ipd, IO6, tipd_IO6 ); w_11 : VitalWireDelay( IO5_ipd, IO5, tipd_IO5 ); w_12 : VitalWireDelay( IO4_ipd, IO4, tipd_IO4 ); w_13 : VitalWireDelay( IO3_ipd, IO3, tipd_IO3 ); w_14 : VitalWireDelay( IO2_ipd, IO2, tipd_IO2 ); w_15 : VitalWireDelay( IO1_ipd, IO1, tipd_IO1 ); w_16 : VitalWireDelay( IO0_ipd, IO0, tipd_IO0 ); w_17 : VitalWireDelay( CLE_ipd, CLE, tipd_CLE ); w_18 : VitalWireDelay( ALE_ipd, ALE, tipd_ALE ); w_19 : VitalWireDelay( CENeg_ipd, CENeg, tipd_CENeg ); w_20 : VitalWireDelay( RENeg_ipd, RENeg, tipd_RENeg ); w_21 : VitalWireDelay( WENeg_ipd, WENeg, tipd_WENeg ); w_22 : VitalWireDelay( WPNeg_ipd, WPNeg, tipd_WPNeg ); END BLOCK WireDelay; ----------------------------------------------------------------------------- -- Main Behavior Block ----------------------------------------------------------------------------- Behavior : BLOCK PORT ( A : IN std_logic_vector(7 DOWNTO 0) := (OTHERS => 'U'); DIN : IN std_logic_vector(15 DOWNTO 0) := (OTHERS => 'U'); DOUT : OUT std_logic_vector(15 DOWNTO 0) := (OTHERS => 'Z'); CLE : IN std_ulogic := 'U'; ALE : IN std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; RENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; RY : Out std_ulogic := '0' ); PORT MAP ( A(7) => IO7_ipd, A(6) => IO6_ipd, A(5) => IO5_ipd, A(4) => IO4_ipd, A(3) => IO3_ipd, A(2) => IO2_ipd, A(1) => IO1_ipd, A(0) => IO0_ipd, DIn(15) => IO15_ipd, DIn(14) => IO14_ipd, DIn(13) => IO13_ipd, DIn(12) => IO12_ipd, DIn(11) => IO11_ipd, DIn(10) => IO10_ipd, DIn(9) => IO9_ipd, DIn(8) => IO8_ipd, DIn(7) => IO7_ipd, DIn(6) => IO6_ipd, DIn(5) => IO5_ipd, DIn(4) => IO4_ipd, DIn(3) => IO3_ipd, DIn(2) => IO2_ipd, DIn(1) => IO1_ipd, DIn(0) => IO0_ipd, DOut(15) => IO15, DOut(14) => IO14, DOut(13) => IO13, DOut(12) => IO12, DOut(11) => IO11, DOut(10) => IO10, DOut(9) => IO9, DOut(8) => IO8, DOut(7) => IO7, DOut(6) => IO6, DOut(5) => IO5, DOut(4) => IO4, DOut(3) => IO3, DOut(2) => IO2, DOut(1) => IO1, DOut(0) => IO0, CLE => CLE_ipd, ALE => ALE_ipd, CENeg => CENeg_ipd, RENeg => RENeg_ipd, WENeg => WENeg_ipd, WPNeg => WPNeg_ipd, RY => RY ); -- State Machine : State_Type TYPE state_type IS ( IDLE, UNKNOWN, -- wrong command sequneces PREL_RD, RESET, A0_RD, A1_RD, A2_RD, RD_WCMD, -- waiting for the confirm read command BUFF_TR, RD, CAC_PREL, -- Coloumn address change A0_CAC, A1_CAC, -- Wait for confirm EO command ID_PREL, ID, PREL_PRG, PGD_PREL, A0_PRG, A1_PRG, A2_PRG, DATA_PRG, WFPD, -- wait for program done WFPPD, PGMS_CAC, A0_PRG_CAC, PGMS, CBSY, RDY_PRG, PREL_ERS, A1_ERS, A2_ERS, ERS_EXEC, ERS_SUSP, A0_PGD, A1_PGD, A2_PGD, A3_PGD, PREL_OTP, DEF_OVER, DEF_REM, WAIT_STATE, WAIT_STATE_1, WAIT_STATE_2 ); -- Page Array TYPE PageArr IS ARRAY (0 TO PageSize) OF Integer RANGE -1 TO MaxData; -- Flash Memory Array TYPE MemArr IS ARRAY (0 TO PageNum) OF PageArr; TYPE OTPArr IS ARRAY (0 TO OTPPageNum) OF PageArr; TYPE MemSegArr IS ARRAY (0 TO PageNum) OF std_logic_vector (SegmentNum DOWNTO 0); TYPE OTPSegArr IS ARRAY (0 TO OTPPageNum) OF std_logic_vector (SegmentNum DOWNTO 0); TYPE IDArr IS ARRAY (0 TO 5) OF integer RANGE -1 TO MaxData; TYPE OTPDefaultType IS (Removed, Overlaid); TYPE ProtStatusType IS ARRAY (0 TO OTPPageNum) OF std_logic; TYPE SegAddrBoundary IS ARRAY (0 TO SegmentNum) OF NATURAL; -- ---------------------------------------------------------------------- -- 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; -- states SIGNAL current_state : State_Type; SIGNAL next_state : State_Type; -- control signals SIGNAL STAT_ACT : std_logic := '0'; SIGNAL ERS_ACT : std_logic := '0'; SIGNAL PRG_ACT : std_logic := '0'; SIGNAL RD_ACT : std_logic := '0'; SIGNAL RSTSTART : std_logic := '0'; SIGNAL RSTDONE : std_logic := '0'; -- Control signals for read operation SIGNAL PGR_ACT : std_logic := '0'; -- Page read in progress SIGNAL PPGR_ACT : std_logic := '0'; -- Partial page read SIGNAL PGD_ACT : std_logic := '0'; -- Page Duplicate SIGNAL PIPR_ACT : std_logic := '0'; -- Pipeline read -- powerup SIGNAL PoweredUp : std_logic := '0'; SIGNAL reseted : std_logic := '0'; SIGNAL write : std_logic := '0'; SIGNAL read : std_logic := '0'; SIGNAL DOut_zd : std_logic_vector(15 DOWNTO 0) := (OTHERS => 'Z'); SIGNAL DOut_Pass : std_logic_vector(15 DOWNTO 0) := (OTHERS => 'Z'); SIGNAL RY_zd : std_logic := '0'; SIGNAL RY_Pass : std_logic := '0'; SIGNAL PROG1_in : std_ulogic := '0'; SIGNAL PROG1_out : std_ulogic := '0'; SIGNAL PROG2_in : std_ulogic := '0'; SIGNAL PROG2_out : std_ulogic := '0'; SIGNAL DBSY1_in : std_ulogic := '0'; SIGNAL DBSY1_out : std_ulogic := '0'; SIGNAL ERES : std_logic := '0'; SIGNAL ESUSP : std_logic := '0'; SIGNAL ESTART : std_logic := '0'; SIGNAL EDONE : std_logic := '0'; SIGNAL ESUSP_ACT : std_logic := '0'; SIGNAL OTP_STAT_ACT : std_logic := '0'; SHARED VARIABLE FROMCE : BOOLEAN := FALSE; SHARED VARIABLE FROMRE : BOOLEAN := FALSE; -- 8 BIT ADDRESS SIGNAL AddrCom : std_logic_vector(7 DOWNTO 0); -- Data SIGNAL Data : integer RANGE -1 TO MaxData; -- ID control signals SIGNAL IDAddr : integer RANGE 0 TO 7; SHARED VARIABLE SegForProg : std_logic_vector (SegmentNum DOWNTO 0); SHARED VARIABLE SegProgSt : std_logic_vector (SegmentNum DOWNTO 0) := "00000000"; SHARED VARIABLE Tmp : std_logic_vector (3 DOWNTO 0) := "0000"; SHARED VARIABLE ProgramedFlag : MemSegArr; SHARED VARIABLE OTPProgramedFlag : OTPSegArr; SHARED VARIABLE WrBlck : INTEGER RANGE 0 to BlockNum; SHARED VARIABLE ErsBlck : INTEGER RANGE 0 to BlockNum; SHARED VARIABLE TmpBlck : INTEGER RANGE 0 to BlockNum; SHARED VARIABLE ssa : SegAddrBoundary :=(16#000# ,16#100# ,16#200# ,16#300# ,16#400# ,16#408# ,16#410# ,16#418#); -- Segments ending addresses SHARED VARIABLE sea : SegAddrBoundary := (16#0FF# ,16#1FF# ,16#2FF# ,16#3FF# ,16#407# ,16#40F# ,16#417# ,16#41F#); -- Mem(Page)(Address) SHARED VARIABLE OTP_Area : OTPArr := (OTHERS => (OTHERS => MaxData)); SHARED VARIABLE ProtStatus : std_logic_vector(15 DOWNTO 0); SHARED VARIABLE WriteProtect : BOOLEAN := FALSE; -- ID Array SHARED VARIABLE IDArray : IDArr; -- Page duplicate buffer SHARED VARIABLE PDBuffer : PageArr := (OTHERS => 0); -- Status SHARED VARIABLE Status : std_logic_vector(15 DOWNTO 0) := "0000000001100100"; SHARED VARIABLE prog_time : TIME; SHARED VARIABLE erase_time : TIME; SHARED VARIABLE page_prog_time : TIME; SHARED VARIABLE seg_prog_time : TIME; -- timing check violation SIGNAL Viol : X01 := '0'; -- ------------------------------------------------------------------------- -- 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; -- ------------------------------------------------------------------------- -- Create side linked list modelling corrupted memory area -- ------------------------------------------------------------------------- PROCEDURE create_list_range( address_low : IN INTEGER; address_high : IN INTEGER; root : INOUT mem_data_pointer_t; last : INOUT mem_data_pointer_t) IS VARIABLE new_element : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; BEGIN create_list(address_low, -1, root); prev := root; -- Linked list representing memory region : -- [address_low, address_high], memory data value corrupted -- Heightens corrupt and erase operation performance FOR I IN (address_low + 1) TO address_high LOOP new_element := NEW mem_data_t; new_element.key_address := I; new_element.val_data := -1; prev.successor := new_element; prev := new_element; END LOOP; prev.successor := NULL; last := prev; END PROCEDURE create_list_range; -- ------------------------------------------------------------------------- -- Merge corrupted with memory area -- ------------------------------------------------------------------------- PROCEDURE insert_list_range( root_dst : INOUT mem_data_pointer_t; root_src : INOUT mem_data_pointer_t; root_src_last : INOUT mem_data_pointer_t) IS VARIABLE key : INTEGER; VARIABLE found : mem_data_pointer_t; VARIABLE prev : mem_data_pointer_t; BEGIN IF (root_dst /= NULL) THEN key := root_src.key_address; -- Insert side created corrupted memory region -- into corresponding linked list position_list(key, root_dst, found, prev); IF (found = NULL) THEN prev.successor := root_src; ELSE root_src_last.successor := found; IF (prev /= NULL) THEN prev.successor := root_src; ELSE root_dst := root_src; END IF; END IF; ELSE root_dst := root_src; END IF; END PROCEDURE insert_list_range; -- ------------------------------------------------------------------------- -- Address range to be corrupted -- ------------------------------------------------------------------------- PROCEDURE corrupt_mem( address_low : IN INTEGER; address_high : IN INTEGER; linked_list : INOUT mem_data_pointer_t) IS VARIABLE sub_linked_list : mem_data_pointer_t; VARIABLE sub_linked_list_last : mem_data_pointer_t; BEGIN sub_linked_list := NULL; sub_linked_list_last := NULL; IF (linked_list /= NULL) THEN remove_list_range( address_low, address_high, linked_list ); END IF; create_list_range( address_low, address_high, sub_linked_list, sub_linked_list_last ); insert_list_range( linked_list, sub_linked_list, sub_linked_list_last ); END PROCEDURE corrupt_mem; -- ------------------------------------------------------------------------- -- 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; ------------------------------------------------------------------------- -- Handle dynamic memory allocation ------------------------------------------------------------------------- -- Partition dynamically allocated space for performance CONSTANT list_num : INTEGER := 512; CONSTANT list_size : INTEGER := 16#10800#; -- Access dynamically allocated space SHARED VARIABLE linked_list : mem_data_pointer_array_t(0 TO list_num); SHARED VARIABLE list_id_v : NATURAL; -- Asure proper initialization PROCEDURE initialize IS VARIABLE I : INTEGER; BEGIN configure_memory(16#FFFF#); FOR I IN 0 TO list_num LOOP linked_list(I) := NULL; END LOOP; END PROCEDURE initialize; -- Memory region parition map, DUT specific FUNCTION list_id( list_address : IN INTEGER) RETURN NATURAL IS BEGIN RETURN (list_address / list_size); END FUNCTION list_id; PROCEDURE getSegment ( paddress : IN integer RANGE 0 TO PageSize; j : OUT integer RANGE -1 TO SegmentNum) IS BEGIN -- PROCEDURE getSegment FOR i IN 0 TO SegmentNum LOOP IF paddress >= ssa(i) AND paddress <= sea(i) THEN j := i; END IF; END LOOP; -- i END PROCEDURE getSegment; BEGIN --------------------------------------------------------------------------- -- Power Up time 10 us --------------------------------------------------------------------------- PoweredUp <= '1' AFTER 10 us; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS (A,DIn,CLE,ALE,CENeg,RENeg,WENeg,WPNeg) IS -- Timing check variables VARIABLE TViol_IO0_WENeg : X01 := '0'; VARIABLE TD_IO0_WENeg : VitalTimingDataType; VARIABLE TViol_CLE_WENeg_F : X01 := '0'; VARIABLE TD_CLE_WENeg_F : VitalTimingDataType; VARIABLE TViol_ALE_WENeg_F : X01 := '0'; VARIABLE TD_ALE_WENeg_F : VitalTimingDataType; VARIABLE TViol_CENeg_WENeg_F : X01 := '0'; VARIABLE TD_CENeg_WENeg_F : VitalTimingDataType; VARIABLE TViol_WPNeg_WENeg_F : X01 := '0'; VARIABLE TD_WPNeg_WENeg_F : VitalTimingDataType; VARIABLE TViol_WENeg_CENeg_F : X01 := '0'; VARIABLE TD_WENeg_CENeg_F : VitalTimingDataType; VARIABLE TViol_CLE_RENeg : X01 := '0'; VARIABLE TD_CLE_RENeg : VitalTimingDataType; VARIABLE TViol_ALE_RENeg : X01 := '0'; VARIABLE TD_ALE_RENeg : VitalTimingDataType; VARIABLE TViol_WENeg_RENeg : X01 := '0'; VARIABLE TD_WENeg_RENeg : VitalTimingDataType; VARIABLE TViol_CENeg_RENeg_F : X01 := '0'; VARIABLE TD_CENeg_RENeg_F : VitalTimingDataType; VARIABLE TViol_RENeg_WENeg : X01 := '0'; VARIABLE TD_RENeg_WENeg : VitalTimingDataType; VARIABLE TViol_CLE_WENeg_R : X01 := '0'; VARIABLE TD_CLE_WENeg_R : VitalTimingDataType; VARIABLE TViol_ALE_WENeg_R : X01 := '0'; VARIABLE TD_ALE_WENeg_R : VitalTimingDataType; VARIABLE TViol_CENeg_WENeg_R : X01 := '0'; VARIABLE TD_CENeg_WENeg_R : VitalTimingDataType; VARIABLE TViol_CENeg_RENeg_H : X01 := '0'; VARIABLE TD_CENeg_RENeg_H : VitalTimingDataType; VARIABLE PViol_WENeg : X01 := '0'; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PViol_RENeg : X01 := '0'; VARIABLE PD_RENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01 := '0'; BEGIN -- PROCESS VITALTimingCheck IF ( TimingChecksOn ) THEN -------------------------------------------------------------------- -- Timing Check Section -------------------------------------------------------------------- -- Setup/Hold Check between IO and WENeg VitalSetupHoldCheck ( TestSignal => IO0, TestSignalName => "IO", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_IO0_WENeg, SetupLow => tsetup_IO0_WENeg, HoldHigh => thold_IO0_WENeg, HoldLow => thold_IO0_WENeg, CheckEnabled => CENeg = '0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_IO0_WENeg, Violation => TViol_IO0_WENeg ); -- Setup Check between CLE and WENeg VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_CLE_WENeg, SetupLow => tsetup_CLE_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CLE_WENeg_F, Violation => TViol_CLE_WENeg_F ); -- Setup Check between ALE and WENeg VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_ALE_WENeg, SetupLow => tsetup_ALE_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_ALE_WENeg_F, Violation => TViol_ALE_WENeg_F ); -- Setup Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_F, Violation => TViol_CENeg_WENeg_F ); -- Setup Check between WENeg and CENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => CENeg, RefSignalName => "CE#", SetupHigh => tsetup_WENeg_CENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CENeg_F, Violation => TViol_WENeg_CENeg_F ); -- Setup Check between CLE and RENeg VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => RENeg, RefSignalName => "RE#", SetupLow => tsetup_CLE_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CLE_RENeg, Violation => TViol_CLE_RENeg ); -- Setup Check between ALE and RENeg VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => RENeg, RefSignalName => "RE#", SetupLow => tsetup_ALE_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_ALE_RENeg, Violation => TViol_ALE_RENeg ); -- Setup Check between WENeg and RENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => RENeg, RefSignalName => "RE#", SetupHigh => tsetup_WENeg_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_RENeg, Violation => TViol_WENeg_RENeg ); -- Setup Check between CENeg and RENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => RENeg, RefSignalName => "RE#", SetupLow => tsetup_CENeg_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_RENeg_F, Violation => TViol_CENeg_RENeg_F ); -- Setup Check between RENeg and WENeg VitalSetupHoldCheck ( TestSignal => RENeg, TestSignalName => "RE#", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_RENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_RENeg_WENeg, Violation => TViol_RENeg_WENeg ); -- Setup Check between WPNeg and WENeg VitalSetupHoldCheck ( TestSignal => WPNeg, TestSignalName => "WP#", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_WPNeg_WENeg, SetupLow => tsetup_WPNeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WPNeg_WENeg_F, Violation => TViol_WPNeg_WENeg_F ); -- Hold Check between CLE and WENeg VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => WENeg, RefSignalName => "WE#", HoldHigh => thold_CLE_WENeg, HoldLow => thold_CLE_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CLE_WENeg_R, Violation => TViol_CLE_WENeg_R ); -- Hold Check between ALE and WENeg VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => WENeg, RefSignalName => "WE#", HoldHigh => thold_ALE_WENeg, HoldLow => thold_ALE_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_ALE_WENeg_R, Violation => TViol_ALE_WENeg_R ); -- Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_R, Violation => TViol_CENeg_WENeg_R ); -- Hold Check between CENeg and RENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => RENeg, RefSignalName => "RE#", HoldLow => thold_CENeg_RENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_RENeg_H, Violation => TViol_CENeg_RENeg_H ); -- Period and Pulse Width Check for WENeg VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WE#", Period => tperiod_WENeg, PulseWidthLow => tpw_WENeg_negedge, PulseWidthHigh => tpw_WENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, Violation => PViol_WENeg ); -- Period and Pulse Width Check for RENeg VitalPeriodPulseCheck ( TestSignal => RENeg, TestSignalName => "RE#", Period => tperiod_RENeg, PulseWidthLow => tpw_RENeg_negedge, PulseWidthHigh => tpw_RENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RENeg, Violation => PViol_RENeg ); Violation := TViol_IO0_WENeg OR TViol_CLE_WENeg_F OR TViol_ALE_WENeg_F OR TViol_CENeg_WENeg_F OR TViol_WPNeg_WENeg_F OR TViol_WENeg_CENeg_F OR TViol_CLE_RENeg OR TViol_ALE_RENeg OR TViol_WENeg_RENeg OR TViol_CENeg_RENeg_F OR TViol_RENeg_WENeg OR TViol_CLE_WENeg_R OR TViol_ALE_WENeg_R OR TViol_CENeg_WENeg_R OR TViol_CENeg_RENeg_H OR PViol_RENeg OR PViol_WENeg; Viol <= Violation; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY WARNING; END IF; END PROCESS VITALTimingCheck; --------------------------------------------------------------------------- -- Proces for reset control and FSM state transition --------------------------------------------------------------------------- StateTransition: PROCESS (next_state, PoweredUp) IS BEGIN -- PROCESS StateTransition IF rising_edge(PoweredUp) THEN reseted <= '1'; current_state <= BUFF_TR; IF (Long_Timming = TRUE) THEN page_prog_time := tdevice_PROG; seg_prog_time := tdevice_SPROG; erase_time:= tdevice_ERS; ELSE page_prog_time := tdevice_PROG/100; seg_prog_time := tdevice_SPROG/100; erase_time:= tdevice_ERS/1000; END IF; ELSIF PoweredUp = '1' THEN current_state <= next_state; ELSE current_state <= IDLE; reseted <= '0'; END IF; END PROCESS StateTransition; --------------------------------------------------------------------------- -- Proces for generating the write and read signals --------------------------------------------------------------------------- wr_rd_gen: PROCESS (WENeg, CENeg, RENeg) IS BEGIN -- PROCESS wr_rd_gen IF WENeg = '0' AND CENeg = '0' AND RENeg = '1' THEN write <= '1'; ELSIF WENeg = '1' AND CENeg = '0' AND RENeg = '1' THEN write <= '0'; ELSE write <= 'X'; END IF; IF WENeg = '1' AND CENeg = '0' AND RENeg = '0' THEN read <= '1'; ELSIF WENeg = '1' AND CENeg = '0' AND RENeg = '1' THEN read <= '0'; ELSE read <= 'X'; END IF; END PROCESS wr_rd_gen; --------------------------------------------------------------------------- -- Latches 8 bit address on the rising edge of WE# -- Latches data on rising edge of WE# --------------------------------------------------------------------------- BusCycleDecode: PROCESS (A, DIn, WENeg, CENeg, RENeg) IS BEGIN -- PROCESS BusCycleDecode -- latch address IF rising_edge(WENeg) AND ALE = '1' AND CLE = '0' AND CENeg = '0' AND RENeg = '1' THEN AddrCom <= A(7 DOWNTO 0); END IF; -- latch data IF rising_edge(WENeg) AND ALE = '0' AND CENeg = '0' AND RENeg = '1' THEN Data <= to_nat(DIn(15 DOWNTO 0)); END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- Timing control for the Reset Operation --------------------------------------------------------------------------- RstTime: PROCESS (RSTSTART, reseted) IS VARIABLE duration : time; BEGIN -- PROCESS RstTime IF rising_edge(reseted) THEN RSTDONE <= '1'; --reset done ELSIF reseted = '1' THEN IF rising_edge(RSTSTART) AND RSTDONE = '1' THEN IF PGR_ACT = '1' OR PRG_ACT = '1' THEN IF Long_Timming THEN duration := tdevice_RST; ELSE duration := tdevice_RST/1; END IF; ELSE IF Long_Timming THEN duration := tdevice_RST + tpd_WENeg_RY(tr10); ELSE duration := tdevice_RST/1 + tpd_WENeg_RY(tr10); END IF; END IF; RSTDONE <= '0', '1' AFTER duration ; END IF; END IF; END PROCESS RstTime; ErsTime :PROCESS(ESTART, ESUSP, ERES, reseted) IS VARIABLE elapsed : time; VARIABLE duration : time; VARIABLE start : time; BEGIN IF rising_edge(reseted) THEN EDONE <= '1'; -- reset done, ERASE terminated ELSIF reseted = '1' THEN IF rising_edge(ESTART) AND EDONE = '1' THEN elapsed := 0 ns; duration := erase_time + tpd_WENeg_RY(tr10); EDONE <= '0', '1' AFTER duration; start := NOW; ELSIF rising_edge(ESUSP) AND EDONE = '0' THEN elapsed := NOW - start; duration := duration - elapsed; EDONE <= '0'; ELSIF rising_edge(ERES) AND EDONE = '0' THEN start := NOW; EDONE <= '0', '1' AFTER duration; END IF; END IF; END PROCESS ErsTime; --------------------------------------------------------------------------- -- Main Behavior Process -- combinational process for next state generation --------------------------------------------------------------------------- StateGen: PROCESS (write, read, reseted, current_state, ERS_out, PROG_out, TR_out,TRP_out, TPT_out,TPRE_out, DBSY_out, RSTDONE, DBSY1_out, PROG1_out, PROG2_out, DEF_OTP_out, OTP_out, WAIT_OTP_out, ERS_SUSP_out, EDONE) IS BEGIN -- PROCESS StateGen ------------------------------------------------------------------------- -- Funcionality section ------------------------------------------------------------------------- IF reseted /= '1' THEN next_state <= current_state; ELSIF rising_edge(reseted) THEN next_state <= BUFF_TR; ELSE CASE current_state IS WHEN IDLE => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#00# THEN next_state <= PREL_RD; -- ELSIF CLE='1' AND ALE='0' AND Data=16#90# THEN next_state <= ID_PREL; ELSIF CLE='1' AND ALE='0' AND Data=16#80# THEN next_state <= PREL_PRG; ELSIF CLE='1' AND ALE='0' AND Data=16#60# THEN next_state <= PREL_ERS; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN next_state <= IDLE; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#B0# THEN IF ESUSP_ACT = '0' THEN next_state <= PREL_OTP; ELSE next_state <= IDLE; END IF; ELSE next_state <= IDLE; END IF; END IF; WHEN UNKNOWN => IF falling_edge(write) THEN IF CLE = '1' AND ALE='0' AND Data=16#FF# THEN next_state <= RESET; END IF; END IF; WHEN RESET => IF RSTDONE = '1' THEN next_state <= IDLE; END IF; WHEN PREL_RD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A0_RD; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_RD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A1_RD; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_RD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A2_RD; ELSE next_state <= IDLE; END IF; END IF; WHEN A2_RD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= RD_WCMD; ELSE next_state <= IDLE; END IF; END IF; WHEN RD_WCMD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#30# THEN IF (ESUSP_ACT = '1' AND TmpBlck = ErsBlck) THEN next_state <= IDLE; ELSE next_state <= BUFF_TR; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#31# THEN IF (ESUSP_ACT = '1' AND TmpBlck = ErsBlck) THEN next_state <= IDLE; ELSE next_state <= BUFF_TR; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#32# THEN IF ESUSP_ACT = '0' THEN next_state <= BUFF_TR; ELSE next_state <= IDLE; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#33# THEN IF ESUSP_ACT = '0' THEN next_state <= BUFF_TR; ELSE next_state <= IDLE; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#35# THEN IF (ESUSP_ACT = '1' AND TmpBlck = ErsBlck) THEN next_state <= IDLE; ELSE next_state <= BUFF_TR; END IF; ELSIF CLE = '1' THEN next_state <= IDLE; END IF; END IF; WHEN BUFF_TR => IF TR_out'event AND TR_out = '1' THEN next_state <= RD; -- buffer transfered ELSIF TRP_out'event AND TRP_out = '1' THEN next_state <= RD; -- partial buffer transfered ELSIF TPT_out'event AND TPT_out = '1' THEN next_state <= RD; -- pipeline buffer transfered ELSIF TPRE_out'event AND TPRE_out = '1' THEN next_state <= RD; -- buffer transfered END IF; WHEN RD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN IF STAT_ACT = '1' THEN next_state <= RD; ELSE next_state <= PREL_RD; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#80# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN next_state <= PREL_PRG; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#90# AND PGD_ACT='0' AND PIPR_ACT='0' THEN next_state <= ID_PREL; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN next_state <= RD; ELSIF CLE = '1' AND Data = 16#60# AND ALE = '0' AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN next_state <= PREL_ERS; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#85# AND PGD_ACT = '1' THEN next_state <= PGD_PREL; -- Read next column address ELSIF CLE = '1' AND ALE = '0' AND Data = 16#05# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN next_state <= CAC_PREL; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#B0# AND PGD_ACT='0' AND PIPR_ACT='0' THEN IF ESUSP_ACT = '0' THEN next_state <= PREL_OTP; ELSE next_state <= IDLE; END IF; ELSE next_state <= IDLE; END IF; END IF; WHEN CAC_PREL => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A0_CAC; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_CAC => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A1_CAC; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_CAC => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#E0# THEN next_state <= RD; ELSE next_state <= IDLE; END IF; END IF; WHEN ID_PREL => IF falling_edge(write) THEN IF ALE = '1' AND AddrCom = X"00" THEN next_state <= ID; ELSE next_state <= IDLE; END IF; END IF; WHEN ID => IF falling_edge(write) THEN IF CLE='1' AND ALE = '0' AND Data=16#00# THEN next_state <= PREL_RD; -- ELSIF CLE='1' AND ALE = '0' AND Data=16#90# THEN next_state <= ID_PREL; ELSIF CLE='1' AND ALE = '0' AND Data=16#80# THEN next_state <= PREL_PRG; ELSIF CLE='1' AND ALE = '0' AND Data=16#60# THEN next_state <= PREL_ERS; ELSIF CLE='1' AND ALE = '0' AND Data=16#70# THEN next_state <= IDLE; ELSIF CLE='1' AND ALE='0' AND Data=16#B0# THEN IF ESUSP_ACT = '0' THEN next_state <= PREL_OTP; ELSE next_state <= IDLE; END IF; ELSE next_state <= IDLE; END IF; END IF; WHEN PREL_PRG => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A0_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_PRG => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A1_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_PRG => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A2_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN A2_PRG => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= DATA_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN DATA_PRG => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#10# THEN IF (ESUSP_ACT = '1' AND WrBlck = ErsBlck) THEN next_state <= IDLE; ELSE IF PRG_ACT = '1' THEN next_state <= WFPPD; ELSE next_state <= PGMS; END IF; END IF; ELSIF CLE = '1' AND ALE = '0' AND PGD_ACT = '0' AND Data = 16#15# THEN IF ESUSP_ACT = '0' THEN IF PRG_ACT='1' THEN next_state <= WFPD; ELSE next_state <= CBSY; END IF; ELSE next_state <= IDLE; END IF; ELSIF CLE ='1' AND ALE='0' AND Data = 16#85# THEN next_state <= PGMS_CAC; ELSIF CLE='1' THEN next_state <= UNKNOWN; ELSIF ALE='0' AND CLE='0' THEN next_state <= DATA_PRG; -- write next word to buffer END IF; END IF; WHEN WFPD => -- Waiting for programing done IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; -- reset END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN next_state <= CBSY; -- programming done END IF; WHEN WFPPD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; -- reset END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN next_state <= PGMS; -- next start programing END IF; WHEN PGMS_CAC => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A0_PRG_CAC; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_PRG_CAC => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= DATA_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN PGMS => IF PROG_out'event AND PROG_out = '1' THEN next_state <= IDLE; -- programming done ELSIF PROG2_out'event AND PROG2_out = '1' THEN next_state <= IDLE; -- programming done ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN next_state <= IDLE; -- otp page protect done END IF; WHEN CBSY => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; -- reset END IF; ELSIF DBSY_out'event AND DBSY_out = '1' THEN next_state <= RDY_PRG; ELSIF DBSY1_out'event AND DBSY1_out = '1' THEN next_state <= RDY_PRG; END IF; WHEN RDY_PRG => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#80# THEN next_state <= PREL_PRG; ELSIF CLE = '1' AND ALE='0' AND Data = 16#FF# THEN next_state <= RESET; ELSIF CLE='1' AND ALE='0' AND Data = 16#70# THEN next_state <= RDY_PRG; ELSE next_state <= IDLE; END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN next_state <= IDLE; END IF; WHEN PREL_ERS => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A1_ERS; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_ERS => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A2_ERS; ELSE next_state <= IDLE; END IF; END IF; WHEN A2_ERS => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data = 16#D0# AND WPNeg /= '0' AND NOT(WriteProtect) THEN next_state <= ERS_EXEC; ELSIF CLE='1' THEN next_state <= IDLE; END IF; END IF; WHEN ERS_EXEC => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ERS_PRESUS_in='0' THEN next_state <= ERS_SUSP; END IF; ELSIF rising_edge(EDONE) THEN next_state <= IDLE; END IF; WHEN ERS_SUSP => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# THEN next_state <= RESET; END IF; ELSIF ERS_SUSP_out'event AND ERS_SUSP_out = '1' THEN next_state <= IDLE; -- erase suspend END IF; WHEN PGD_PREL => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A0_PGD; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_PGD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A1_PGD; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_PGD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A2_PGD; ELSE next_state <= IDLE; END IF; END IF; WHEN A2_PGD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A3_PGD; ELSE next_state <= IDLE; END IF; END IF; WHEN A3_PGD => IF falling_edge(write) THEN IF ALE = '0' AND CLE = '0' THEN next_state <= DATA_PRG; ELSIF ALE = '0' AND CLE = '1' AND Data = 16#10# THEN IF (ESUSP_ACT = '1' AND WrBlck = ErsBlck) THEN next_state <= IDLE; ELSE next_state <= PGMS; END IF; ELSIF ALE = '0' AND CLE ='1' AND Data = 16#85# THEN next_state <= PGMS_CAC; ELSIF CLE = '1' THEN next_state <= IDLE; END IF; END IF; WHEN PREL_OTP => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN next_state <= WAIT_STATE_2; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#01# THEN next_state <= WAIT_STATE_2; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#02# THEN next_state <= WAIT_STATE; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#03# THEN next_state <= DEF_OVER; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#04# THEN next_state <= DEF_REM; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#05# THEN next_state <= WAIT_STATE_1; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; END IF; WHEN WAIT_STATE => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF WAIT_OTP_out'event AND WAIT_OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN WAIT_STATE_1 => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF WAIT_OTP_out'event AND WAIT_OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN WAIT_STATE_2 => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF OTP_out'event AND OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN DEF_OVER => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN DEF_REM => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN OTHERS => NULL; END CASE; CASE current_state IS WHEN IDLE | PREL_RD | A0_RD | A1_RD | A2_RD | RD_WCMD | RD | CAC_PREL | A0_CAC | A1_CAC | ID_PREL | ID | PREL_PRG | PGD_PREL | A0_PRG | A1_PRG | A2_PRG | DATA_PRG | PGMS_CAC | A0_PRG_CAC | PGMS | PREL_ERS | A1_ERS | A2_ERS | A0_PGD | A1_PGD | A2_PGD | A3_PGD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN IF ESUSP_ACT = '0' THEN next_state <= RESET; ELSE next_state <= current_state; END IF; END IF; END IF; WHEN BUFF_TR => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND TPRE_in = '0' THEN IF ESUSP_ACT = '0' THEN next_state <= RESET; ELSE next_state <= current_state; END IF; END IF; END IF; WHEN OTHERS => NULL; END CASE; END IF; END PROCESS StateGen; --------------------------------------------------------------------------- -- FSM Output Generation and general funcionality --------------------------------------------------------------------------- Functional : PROCESS (read, write, Data, AddrCom, reseted, current_state, RENeg, CENeg, ALE, CLE, ERS_out, PROG_out, TR_out, TRP_out, DBSY_out, RSTDONE, PROG2_out, DEF_OTP_out, WAIT_OTP_out, TPRE_out, WPNeg, PROG1_out, DBSY1_out, PRG_ACT, ERS_SUSP_out, ERS_PRESUS_out, EDONE, OTP_out, TPT_out) IS VARIABLE oe : BOOLEAN := false; VARIABLE TmpPage : INTEGER RANGE 0 to PageNum; VARIABLE TmpSegm : INTEGER RANGE 0 TO SegmentNum; VARIABLE AddrWithinPage : INTEGER RANGE 0 TO PageSize; VARIABLE PageWithinBlock : INTEGER RANGE 0 TO BlockSize; VARIABLE Segment : INTEGER RANGE 0 TO SegmentNum; VARIABLE pom_seg : INTEGER RANGE 0 TO SegmentNum; VARIABLE RowAddr : std_logic_vector(23 DOWNTO 0); VARIABLE ColAddr : std_logic_vector(15 DOWNTO 0); VARIABLE RdPage : INTEGER RANGE 0 to PageNum; VARIABLE RdAddr : INTEGER RANGE 0 TO PageSize+1; VARIABLE RdSeg : INTEGER RANGE 0 TO SegmentNum; VARIABLE RdBlck : INTEGER RANGE 0 to BlockNum; VARIABLE WrPage : INTEGER RANGE 0 to PageNum; VARIABLE WrAddr : INTEGER RANGE 0 TO PageSize+1; VARIABLE WrSeg : INTEGER RANGE 0 TO SegmentNum; VARIABLE CWrPage : INTEGER RANGE 0 to PageNum; VARIABLE ProgBlck : INTEGER RANGE 0 to BlockNum; VARIABLE ProgPage : INTEGER RANGE 0 to PageNum; VARIABLE ProtPage : INTEGER RANGE 0 to PageNum; VARIABLE PIP_Addr : INTEGER RANGE 0 TO PageSize+1; VARIABLE PIP_Blck : INTEGER RANGE 0 TO BlockNum; VARIABLE PIP_Page : INTEGER RANGE 0 TO PageNum; VARIABLE OTPOverlay : BOOLEAN := FALSE; VARIABLE OTPOverlayPIP : BOOLEAN := FALSE; VARIABLE FirstByte : BOOLEAN := TRUE; VARIABLE SetDefault : BOOLEAN := FALSE; VARIABLE OTPDefault : OTPDefaultType; VARIABLE WrBuffData : PageArr; VARIABLE CashBuffData : PageArr; -- First pipeline read VARIABLE FirstPipe : BOOLEAN := true; VARIABLE firstFlag : BOOLEAN := FALSE; VARIABLE Protect : BOOLEAN := FALSE; VARIABLE mem_data : INTEGER; VARIABLE SegForProg : std_logic_vector (SegmentNum DOWNTO 0); VARIABLE CashSegForProg : std_logic_vector (SegmentNum DOWNTO 0); VARIABLE SegProgSt : std_logic_vector (SegmentNum DOWNTO 0) := "00000000"; VARIABLE Tmp : std_logic_vector (3 DOWNTO 0) := "0000"; VARIABLE tmp_cnt : INTEGER RANGE 0 TO 4; PROCEDURE Read_Data ( VARIABLE Addr : INOUT integer RANGE 0 TO PageSize; VARIABLE Page : IN integer RANGE -1 TO PageNum) IS BEGIN -- PROCEDURE read_data read_mem( linked_list(list_id(Page * (PageSize+1) + Addr)), mem_data, Page * (PageSize+1) + Addr); IF mem_data /= -1 THEN DOut_zd <= to_slv(mem_data,16); ELSE DOut_zd <= ( OTHERS => 'X'); END IF; IF PPGR_ACT = '0' THEN IF Addr /= PageSize THEN Addr := Addr+1; END IF; ELSE getSegment(Addr, Segment); IF Segment < 4 THEN IF Addr < sea(Segment) THEN Addr := Addr+1; ELSIF Addr = sea(Segment) THEN Segment := Segment + 4; Addr := ssa(Segment); END IF; ELSE IF Addr < sea(Segment) THEN Addr := Addr+1; END IF; END IF; END IF; END PROCEDURE Read_Data; PROCEDURE Read_OTP ( VARIABLE Addr : INOUT integer RANGE 0 TO PageSize; VARIABLE Page : IN integer RANGE -1 TO PageNum) IS BEGIN -- PROCEDURE read_data IF Page <= 7 THEN IF OTP_Area(Page)(Addr) /= -1 THEN DOut_zd <= to_slv(OTP_Area(Page)(Addr),16); ELSE DOut_zd <= (OTHERS => 'X'); END IF; ELSE DOut_zd <= (OTHERS => '1'); END IF; IF PPGR_ACT = '0' THEN IF Addr /= PageSize THEN Addr := Addr+1; END IF; ELSE getSegment(Addr, Segment); IF Segment < 4 THEN IF Addr < sea(Segment) THEN Addr := Addr+1; ELSIF Addr = sea(Segment) THEN Segment := Segment + 4; Addr := ssa(Segment); END IF; ELSE IF Addr < sea(Segment) THEN Addr := Addr+1; END IF; END IF; END IF; END PROCEDURE Read_OTP; PROCEDURE EndProgramming IS BEGIN PRG_ACT <= '0'; Status(5) := '1'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(1 DOWNTO 0) := "00"; IF WPNeg /= '0' AND NOT(WriteProtect) THEN IF OTPOverlay AND ProgBlck = 0 THEN IF ProgPage <= 7 THEN FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProtStatus(ProgPage) = '1' AND WrBuffData(j) /= -1 AND OTPProgramedFlag(ProgPage)(pom_seg) = '0' THEN OTP_Area(ProgPage)(j):=WrBuffData(j); END IF; END LOOP; OTPProgramedFlag(ProgPage) :=CashSegForProg; ELSE Status(0) := '1'; END IF; ELSE list_id_v := list_id(ProgPage * (PageSize + 1)); FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProgramedFlag(ProgPage)(pom_seg)='0' AND WrBuffData(j) /= -1 THEN write_mem(linked_list(list_id_v), ProgPage * (PageSize + 1) + j, WrBuffData(j)); END IF; END LOOP; ProgramedFlag(ProgPage) := CashSegForProg; END IF; END IF; END PROCEDURE EndProgramming; PROCEDURE getAddress ( Column : IN std_logic_vector(15 DOWNTO 0) ) IS BEGIN -- PROCEDURE getAddress IF Column(MainAreaAddBit) = '0' THEN TmpSegm := to_nat(Column(HAddBitSeg DOWNTO HAddBitSeg-1)); AddrWithinPage := to_nat(Column); ELSE TmpSegm := MainSize/SegmentSize + to_nat(Column(HAddBitSpareSeg DOWNTO HAddBitSpareSeg-1)); AddrWithinPage := MainSize + to_nat(Column(HAddBitSpareSeg DOWNTO 0)); END IF; END PROCEDURE getAddress; PROCEDURE getPage ( Row : IN std_logic_vector(23 DOWNTO 0)) IS BEGIN -- PROCEDURE getPage PageWithinBlock :=to_nat(Row(HAddBitPag-MainAreaAddBit-1 DOWNTO 0)); TmpBlck := to_nat(Row(HAddBitBl-MainAreaAddBit-1 DOWNTO HAddBitPag-MainAreaAddBit)); TmpPage := TmpBlck*PageNumInBl + PageWithinBlock; END PROCEDURE getPage; BEGIN -- PROCESS Functional ---------------------------------------------------------------------- -- Funcionality section ---------------------------------------------------------------------- oe := rising_edge(read); Status(7) := WPNeg; IF reseted /= '1' THEN RY_zd <= '0'; ELSIF rising_edge(reseted) THEN TPRE_in <= '1'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSE CASE current_state IS WHEN IDLE => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN STAT_ACT <= '1'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN STAT_ACT <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#90# THEN STAT_ACT <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#B0# THEN STAT_ACT <= '0'; ELSIF CLE='1' AND ALE='0' AND Data=16#80# THEN STAT_ACT <= '0'; IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE='1' AND ALE='0' AND Data=16#60# THEN STAT_ACT <= '0'; IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; OTP_STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; ELSE STAT_ACT <= '0'; END IF; END IF; IF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN UNKNOWN => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ERS_ACT <= '0'; PGD_ACT <= '0'; RD_ACT <= '0'; PIPR_ACT <= '0'; PGR_ACT <= '0'; PRG_ACT <= '0'; Status(5) := '1'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; END IF; END IF; WHEN RESET => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN STAT_ACT <= '1'; END IF; END IF; IF RSTDONE = '1' THEN RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(1 DOWNTO 0) := "00"; OTP_STAT_ACT <= '0'; PRG_ACT <= '0'; ERS_ACT <= '0'; RD_ACT <= '0'; PGD_ACT <= '0'; PIPR_ACT <= '0'; PGR_ACT <= '0'; Protect := false; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN PREL_RD => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A0_RD => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(15 DOWNTO 8) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A1_RD => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A2_RD => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(15 DOWNTO 8) := AddrCom; RowAddr(23 DOWNTO 16) := X"00"; getPage(RowAddr); getAddress(ColAddr); ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN RD_WCMD => IF falling_edge(write) THEN IF CLE = '1' AND ALE='0' AND Data = 16#30# AND ((ESUSP_ACT = '1' AND TmpBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN PGR_ACT <= '1'; PIPR_ACT <= '0'; FirstPipe := true; RdPage := TmpPage; RdBlck := TmpBlck; RdAddr := AddrWithinPage; RdSeg := TmpSegm; TR_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#31# AND ((ESUSP_ACT = '1' AND TmpBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN PPGR_ACT <= '1'; PGR_ACT <= '1'; RdPage := TmpPage; RdBlck := TmpBlck; RdAddr := AddrWithinPage; RdSeg := TmpSegm; TRP_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ELSIF CLE = '1' AND ALE='0' AND Data = 16#32# AND ESUSP_ACT='0' THEN PIPR_ACT <= '1'; IF FirstPipe = true THEN FirstPipe := false; ELSE RdPage := PIP_Page; RdBlck := PIP_Blck; RdAddr := PIP_Addr; END IF; PGR_ACT <= '1'; PIP_Page := TmpPage; PIP_Blck := TmpBlck; PIP_Addr := AddrWithinPage; TPT_in <= '1'; -- Time for pipeline read RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; OTPOverlay := OTPOverlayPIP; ELSIF CLE='1' AND ALE='0' AND Data = 16#33# AND ESUSP_ACT='0' THEN TPT_in <= '1'; -- Time for pipeline read PIPR_ACT <= '0'; FirstPipe := true; PGR_ACT <= '1'; RdAddr := PIP_Addr; RdPage := PIP_Page; RdBlck := PIP_Blck; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; OTPOverlay := OTPOverlayPIP; ELSIF CLE = '1' AND ALE='0' AND Data = 16#35# AND ((ESUSP_ACT = '1' AND TmpBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN PGD_ACT <= '1'; PGR_ACT <= '1'; TR_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; getPage(RowAddr); getAddress(ColAddr); RdPage := TmpPage; RdBlck := TmpBlck; RdAddr := AddrWithinPage; PDBuffer := (OTHERS => -1); ELSIF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN BUFF_TR => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# AND TPRE_in = '0' AND ESUSP_ACT = '0' THEN TR_in <= '0'; TRP_in <= '0'; TPT_in <= '0'; DBSY_in <= '0'; STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE = '1' AND ALE='0' AND Data = 16#70# THEN STAT_ACT <= '1'; END IF; ELSIF TR_out'event AND TR_out = '1' THEN PGR_ACT <= '0'; RY_zd <= '1'; Status(6 downto 5):= "11"; TR_in <= '0'; IF PGD_ACT = '1' THEN list_id_v := list_id(RdPage * (PageSize + 1)); IF OTPOverlay AND RdBlck = 0 THEN IF RdPage <= 7 THEN PDBuffer := OTP_Area(RdPage); ELSE FOR i IN 0 TO PageSize LOOP PDBuffer(i) := 16#FFFF#; END LOOP; END IF; ELSE FOR I IN 0 TO PageSize LOOP read_mem( linked_list(list_id_v), mem_data, RdPage * (PageSize + 1) + I ); PDBuffer(I) := mem_data; END LOOP; END IF; END IF; ELSIF TRP_out'event AND TRP_out = '1' THEN PGR_ACT <= '0'; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; TRP_in <= '0'; ELSIF TPT_out'event AND TPT_out = '1' THEN PGR_ACT <= '0'; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; TPT_in <= '0'; ELSIF TPRE_out'event AND TPRE_out = '1' THEN PGR_ACT <= '0'; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; TPRE_in <= '0'; RdPage := 0; RdBlck := 0; RdAddr := 0; RdSeg := 0; END IF; IF oe THEN IF PIPR_ACT='1' THEN IF OTPOverlay AND RdBlck = 0 THEN Read_OTP(RdAddr,RdPage); ELSE Read_Data(RdAddr,RdPage); END IF; ELSIF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN RD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN IF STAT_ACT = '1' THEN STAT_ACT <= '0'; ELSE PPGR_ACT <= '0'; PGD_ACT <= '0'; OTPOverlayPIP := OTPOverlay; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; END IF; ELSIF CLE = '1' AND ALE='0' AND Data = 16#70# THEN STAT_ACT <= '1'; ELSIF CLE = '1' AND ALE='0' AND Data = 16#90# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN STAT_ACT <= '0'; PPGR_ACT <= '0'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSIF CLE = '1' AND ALE='0' AND Data = 16#80# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN STAT_ACT <= '0'; PPGR_ACT <= '0'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#60# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN STAT_ACT <= '0'; PPGR_ACT <= '0'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE='1' AND ALE = '0' AND Data=16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE = '0' AND Data=16#85# AND PGD_ACT='1' THEN PPGR_ACT <= '0'; STAT_ACT <= '0'; ELSIF CLE='1' AND ALE = '0' AND Data=16#05# AND PGD_ACT = '0' AND PIPR_ACT='0' THEN STAT_ACT <= '0'; ELSIF CLE='1' AND ALE = '0' AND Data=16#B0# AND PGD_ACT = '0' AND PIPR_ACT='0' THEN IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; PPGR_ACT <= '0'; STAT_ACT <= '0'; ELSE STAT_ACT <= '0'; PGD_ACT <= '0'; PIPR_ACT <= '0'; END IF; END IF; IF oe THEN IF PGD_ACT='0' AND STAT_ACT='0' AND OTP_STAT_ACT = '0' THEN IF OTPOverlay AND RdBlck = 0 THEN Read_OTP(RdAddr,RdPage); ELSE Read_Data(RdAddr,RdPage); END IF; ELSIF OTP_STAT_ACT = '1' AND RdBlck = 0 THEN IF FirstByte THEN Dout_zd <= ProtStatus; FirstByte := false; ELSE IF OTPDefault = Overlaid THEN Dout_zd <= X"0000"; ELSE Dout_zd <= X"0001"; END IF; OTP_STAT_ACT <= '0'; END IF; ELSIF STAT_ACT='1' THEN Dout_zd <= Status; END IF; END IF; WHEN CAC_PREL => IF falling_edge(write) THEN IF ALE = '1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data = 16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A0_CAC => IF falling_edge(write) THEN IF ALE = '1' THEN ColAddr(15 DOWNTO 8) := AddrCom; ELSIF CLE='1' AND Data = 16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A1_CAC => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data = 16#E0# THEN getAddress(ColAddr); getSegment(AddrWithinPage, pom_seg); IF (pom_seg MOD 4) = RdSeg THEN RdAddr := AddrWithinPage; ELSE REPORT LF&"Changed address is not"&LF& " in same partial page" SEVERITY WARNING; END IF; ELSIF CLE='1' AND ALE='0' AND Data = 16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF ALE = '1' THEN END IF; END IF; WHEN ID_PREL => IF falling_edge(write) THEN IF ALE = '1' AND AddrCom = X"00" THEN IDAddr <= 0; ELSIF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END if; END IF; WHEN ID => IF falling_edge(write) THEN IF CLE ='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE='0' AND Data=16#80# THEN IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE='1' AND ALE='0' AND Data=16#60# THEN IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSIF CLE='1' AND ALE='0' AND Data=16#00# THEN STAT_ACT <= '0'; END IF; END IF; IF oe THEN IF IDAddr < 6 THEN DOut_zd <= to_slv(IDArray(IDAddr),16); IDAddr <= IDAddr+1; ELSE DOut_zd <= (OTHERS => 'Z'); END IF; END IF; WHEN PREL_PRG => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN A0_PRG => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(15 DOWNTO 8) := AddrCom; getAddress(ColAddr); WrAddr := AddrWithinPage; WrSeg := TmpSegm; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN A1_PRG => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN A2_PRG => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(15 DOWNTO 8) := AddrCom; RowAddr(23 DOWNTO 16):= X"00"; getPage(RowAddr); WrPage := TmpPage; WrBlck := TmpBlck; CashBuffData := (OTHERS => -1); IF OTPOverlay AND WrBlck = 0 THEN IF WrPage <= 7 THEN SegForProg := OTPProgramedFlag(WrPage); END IF; ELSE SegForProg := ProgramedFlag(WrPage); END IF; SegProgSt:= "00000000"; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN DATA_PRG => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF ALE='0' AND CLE = '0' AND WrAddr <= PageSize THEN getSegment(WrAddr,WrSeg); IF OTPOverlay AND WrBlck = 0 THEN IF WrPage <= 7 THEN IF ProtStatus(WrPage) = '1' AND OTPProgramedFlag(WrPage)(WrSeg) = '0' THEN CashBuffData(WrAddr) := Data; SegForProg(WrSeg) := '1'; SegProgSt(WrSeg) := '1'; END IF; END IF; ELSE IF ProgramedFlag(WrPage)(WrSeg) = '0' THEN CashBuffData(WrAddr) := Data; SegForProg(WrSeg) := '1'; SegProgSt(WrSeg) := '1'; END IF; END IF; WrAddr := WrAddr+1; ELSIF CLE='1' AND ALE='0' AND Data=16#10# AND ((ESUSP_ACT = '1' AND WrBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN IF PRG_ACT = '0' THEN Tmp := SegProgSt(3 DOWNTO 0) OR SegProgSt(7 DOWNTO 4); tmp_cnt := 0; FOR i IN 0 TO 3 LOOP IF Tmp(i) = '1' THEN tmp_cnt := tmp_cnt + 1; END IF; END LOOP; IF tmp_cnt = 4 THEN prog_time := page_prog_time + tpd_WENeg_RY(tr10); ELSIF tmp_cnt = 0 THEN prog_time := 0 ns; ELSE prog_time := tmp_cnt * seg_prog_time + tpd_WENeg_RY(tr10); END IF; IF NOT(Protect) THEN PRG_ACT <= '1'; PROG_in <= '1'; ELSE DEF_OTP_in <= '1'; END IF; END IF; RY_zd <= '0'; Status(5) := '0'; firstFlag := true; ELSIF CLE = '1' AND ALE = '0' AND PGD_ACT = '0' AND Data = 16#15# AND ESUSP_ACT='0' THEN IF PRG_ACT = '0' THEN DBSY_in <= '1'; END IF; RY_zd <= '0'; Status(6) := '0'; firstFlag := true; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN PGMS_CAC => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A0_PRG_CAC => IF falling_edge(write) THEN IF ALE = '1' THEN ColAddr(15 DOWNTO 8) := AddrCom; getAddress(ColAddr); WrAddr := AddrWithinPage; WrSeg := TmpSegm; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN WFPD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; END if; ELSIF PROG1_out'event AND PROG1_out = '1' THEN DBSY1_in <= '1'; Status(5) := '1'; END IF; IF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN WFPPD => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; PROG1_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN Status(5) := '0'; PROG2_in <= '1'; PROG1_in <= '0'; Status(1 DOWNTO 0) := "00"; Tmp := SegProgSt(3 DOWNTO 0) OR SegProgSt(7 DOWNTO 4); tmp_cnt := 0; FOR i IN 0 TO 3 LOOP IF Tmp(i) = '1' THEN tmp_cnt := tmp_cnt + 1; END IF; END LOOP; IF tmp_cnt = 4 THEN prog_time := page_prog_time; ELSIF tmp_cnt = 0 THEN prog_time := 0 ns; ELSE prog_time := tmp_cnt * seg_prog_time; END IF; IF WPNeg /= '0' AND NOT(WriteProtect) THEN IF OTPOverlay AND ProgBlck = 0 THEN IF ProgPage <= 7 THEN FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProtStatus(ProgPage) = '1' AND WrBuffData(j) /= -1 AND OTPProgramedFlag(ProgPage)(pom_seg) = '0' THEN OTP_Area(ProgPage)(j):=WrBuffData(j); END IF; END LOOP; OTPProgramedFlag(ProgPage) :=CashSegForProg; ELSE Status(0) := '1'; END IF; ELSE list_id_v := list_id(ProgPage * (PageSize + 1)); FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProgramedFlag(ProgPage)(pom_seg)='0' AND WrBuffData(j) /= -1 THEN write_mem(linked_list(list_id_v), ProgPage * (PageSize + 1) + j, WrBuffData(j)); END IF; END LOOP; ProgramedFlag(ProgPage) := CashSegForProg; END IF; END IF; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN PGMS => IF WPNeg /= '0' AND NOT(WriteProtect) AND firstFlag AND NOT(Protect) THEN firstFlag := false; IF NOT(Protect) THEN IF OTPOverlay AND WrBlck = 0 THEN IF WrPage <= 7 THEN FOR i IN 0 TO PageSize LOOP getSegment(i,WrSeg); IF ProtStatus(WrPage) = '1' AND CashBuffData(i) /= -1 THEN IF OTPProgramedFlag(WrPage)(WrSeg) = '0' THEN OTP_Area(WrPage)(i) := -1; ELSE CashBuffData(i) := -1; END IF; END IF; END LOOP; END IF; ELSE list_id_v := list_id(WrPage * (PageSize + 1)); FOR i IN 0 TO PageSize LOOP getSegment(i,WrSeg); IF ProgramedFlag(WrPage)(WrSeg) = '0' AND CashBuffData(i) /= -1 THEN write_mem(linked_list(list_id_v), WrPage*(PageSize + 1) + i, -1); END IF; END LOOP; END IF; END IF; WrBuffData := CashBuffData; ProgPage := WrPage; ProgBlck := WrBlck; END IF; IF PROG_out'event AND PROG_out = '1' THEN RY_zd <= '1'; PGD_ACT <= '0'; ELSIF PROG2_out'event AND PROG2_out = '1' THEN RY_zd <= '1'; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN RY_zd <= '1'; END IF; IF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN PRG_ACT <= '0'; Status(5) := '1'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(1 DOWNTO 0) := "00"; IF WPNeg /= '0' AND NOT(WriteProtect) AND NOT(Protect) THEN IF OTPOverlay AND ProgBlck = 0 THEN IF ProgPage <= 7 THEN FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProtStatus(ProgPage) = '1' AND WrBuffData(j) /= -1 AND OTPProgramedFlag(ProgPage)(pom_seg) = '0' THEN OTP_Area(ProgPage)(j):=WrBuffData(j); END IF; END LOOP; OTPProgramedFlag(ProgPage) := SegForProg; ELSE Status(0) := '1'; END IF; ELSE list_id_v := list_id(ProgPage * (PageSize + 1)); FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProgramedFlag(ProgPage)(pom_seg)='0' AND WrBuffData(j) /= -1 THEN write_mem(linked_list(list_id_v), ProgPage * (PageSize + 1) + j, WrBuffData(j)); END IF; END LOOP; ProgramedFlag(ProgPage) := SegForProg; END IF; END IF; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSIF rising_edge(DEF_OTP_out) THEN IF WPNeg /= '0' AND NOT(WriteProtect) AND Protect THEN ProtStatus(ProgPage) := '0'; Protect := false; Status(5) := '1'; Status(0) := '1'; END IF; DEF_OTP_in <= '0'; END IF; IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; Protect := false; DEF_OTP_in <= '0'; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; -- read status END IF; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN CBSY => IF firstFlag THEN Status(6) := '0'; firstFlag := false; CWrPage := WrPage; END IF; IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# THEN DBSY_in <= '0'; DBSY1_in <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; -- read status END IF; ELSIF DBSY_out'event AND DBSY_out = '1' THEN IF WPNeg /= '0' AND NOT(WriteProtect) THEN IF OTPOverlay AND WrBlck = 0 THEN IF CWrPage <= 7 THEN IF ProtStatus(CWrPage) = '1' THEN FOR i IN 0 TO PageSize LOOP IF CashBuffData(i) /= -1 THEN OTP_Area(CWrPage)(i) := -1; END IF; END LOOP; END IF; END IF; ELSE list_id_v := list_id(CWrPage * (PageSize + 1)); FOR i IN 0 TO PageSize LOOP IF CashBuffData(i) /= -1 THEN write_mem(linked_list(list_id_v), CWrPage*(PageSize + 1) + i, -1); END IF; END LOOP; END IF; END IF; PRG_ACT <= '1'; PROG1_in <= '1' ; Tmp := SegProgSt(3 DOWNTO 0) OR SegProgSt(7 DOWNTO 4); tmp_cnt := 0; FOR i IN 0 TO 3 LOOP IF Tmp(i) = '1' THEN tmp_cnt := tmp_cnt + 1; END IF; END LOOP; IF tmp_cnt = 4 THEN prog_time := page_prog_time; ELSIF tmp_cnt = 0 THEN prog_time := 0 ns; ELSE prog_time := tmp_cnt * seg_prog_time; END IF; Status(6) := '1'; Status(5) := '0'; RY_zd <= '1'; DBSY_in <= '0'; Status(6) := '1'; ProgPage := CWrPage; ProgBlck := WrBlck; WrBuffData := CashBuffData; CashSegForProg := SegForProg; ELSIF DBSY1_out'event AND DBSY1_out = '1' THEN IF WPNeg /= '0' AND NOT(WriteProtect) THEN IF OTPOverlay AND WrBlck = 0 THEN IF CWrPage <= 7 THEN IF ProtStatus(CWrPage) = '1' THEN FOR i IN 0 TO PageSize LOOP IF CashBuffData(i) /= -1 THEN OTP_Area(CWrPage)(i) := -1; END IF; END LOOP; END IF; END IF; ELSE list_id_v := list_id(CWrPage * (PageSize + 1)); FOR i IN 0 TO PageSize LOOP IF CashBuffData(i) /= -1 THEN write_mem(linked_list(list_id_v), CWrPage*(PageSize + 1) + i, -1); END IF; END LOOP; END IF; END IF; PRG_ACT <= '1'; PROG1_in <= '1' ; Tmp := SegProgSt(3 DOWNTO 0) OR SegProgSt(7 DOWNTO 4); tmp_cnt := 0; FOR i IN 0 TO 3 LOOP IF Tmp(i) = '1' THEN tmp_cnt := tmp_cnt + 1; END IF; END LOOP; IF tmp_cnt = 4 THEN prog_time := page_prog_time; ELSIF tmp_cnt = 0 THEN prog_time := 0 ns; ELSE prog_time := tmp_cnt * seg_prog_time; END IF; Status(6) := '1'; Status(5) := '0'; RY_zd <= '1'; DBSY1_in <= '0'; Status(6) := '1'; ProgPage := CWrPage; ProgBlck := WrBlck; WrBuffData := CashBuffData; CashSegForProg := SegForProg; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN RDY_PRG => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data = 16#70# THEN STAT_ACT <= '1'; ELSIF CLE='1' AND ALE='0' AND Data = 16#80# THEN STAT_ACT <= '0'; ELSIF CLE='1' AND ALE='0' AND Data=16#FF# THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSE STAT_ACT <= '0'; END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN RY_zd <= '1'; Status(5) := '1'; END IF; IF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN PREL_ERS => IF falling_edge(write) THEN IF ALE = '1' THEN RowAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A1_ERS => IF falling_edge(write) THEN IF ALE = '1' THEN RowAddr(15 DOWNTO 8) := AddrCom; RowAddr(23 DOWNTO 16) := X"00"; ELSIF CLE = '1' AND Data = 16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A2_ERS => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#D0# AND WPNeg /= '0' AND NOT(WriteProtect)THEN IF ESUSP_ACT = '0' THEN getPage(RowAddr); ErsBlck := TmpBlck; IF OTPOverlay AND ErsBlck = 0 THEN IF ProtStatus(7 DOWNTO 0) = "11111111" THEN FOR i IN 0 TO 7 LOOP OTP_Area(i) := (OTHERS => -1); OTPProgramedFlag(i) := (OTHERS => '0'); END LOOP; END IF; ELSE list_id_v := list_id(ErsBlck * PageNumInBl * (PageSize + 1)); FOR i IN ErsBlck * PageNumInBl TO (ErsBlck*PageNumInBl)+BlockSize LOOP corrupt_mem( i * (PageSize + 1), i * (PageSize + 1) + PageSize, linked_list(list_id_v) ); ProgramedFlag(i) := (OTHERS => '0'); END LOOP; END IF; ESTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ERS_PRESUS_in <= '1'; ELSE RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1) := '0'; Status(0) := '0'; ESUSP_ACT <= '0'; ERES <= '1', '0' AFTER 1 ns; ERS_PRESUS_in <= '1'; END IF; END IF; END IF; WHEN ERS_EXEC => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ERS_PRESUS_in='0' THEN ERS_SUSP_in <= '1'; STAT_ACT <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN STAT_ACT <= '1'; END IF; ELSIF rising_edge(EDONE) THEN IF OTPOverlay AND ErsBlck = 0 THEN IF ProtStatus(7 DOWNTO 0) = "11111111" THEN FOR i IN 0 TO 7 LOOP OTP_Area(i) := (OTHERS => MaxData); OTPProgramedFlag(i) := (OTHERS => '0'); END LOOP; END IF; ELSE list_id_v := list_id(ErsBlck * PageNumInBl * (PageSize + 1)); FOR i IN ErsBlck * PageNumInBl TO (ErsBlck * PageNumInBl) + BlockSize LOOP erase_mem( i * (PageSize + 1), i * (PageSize + 1) + PageSize, linked_list(list_id_v) ); ProgramedFlag(i) := (OTHERS => '0'); END LOOP; END IF; RY_zd <= '1'; ERS_PRESUS_in <= '0'; Status(6 DOWNTO 5) := "11"; Status(1 DOWNTO 0) := "00"; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSIF rising_edge(ERS_PRESUS_out) THEN ERS_PRESUS_in <= '0'; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN ERS_SUSP => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ERS_SUSP_in <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN STAT_ACT <= '1'; END IF; ELSIF ERS_SUSP_out'event AND ERS_SUSP_out = '1' THEN ESUSP <= '1', '0' AFTER 1 ns; ESUSP_ACT <= '1'; ERS_SUSP_in <= '0'; Status(6 DOWNTO 5) := "11"; Status(1 DOWNTO 0) := "11"; RY_zd <= '1'; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN PGD_PREL => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A0_PGD => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(15 DOWNTO 8) := AddrCom; getAddress(ColAddr); WrAddr := AddrWithinPage; WrSeg := TmpSegm; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A1_PGD => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A2_PGD => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(15 DOWNTO 8) := AddrCom; RowAddr(23 DOWNTO 16):= X"00"; getPage(RowAddr); WrPage := TmpPage; WrBlck := TmpBlck; CashBuffData := PDBuffer; SegForProg := (OTHERS => '1'); SegProgSt := (OTHERS => '1'); ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A3_PGD => IF falling_edge(write) THEN IF ALE='0' AND CLE='0' AND WrAddr <= PageSize THEN getSegment(WrAddr,WrSeg); IF ProgramedFlag(WrPage)(WrSeg) = '0' THEN CashBuffData(WrAddr) := Data; END IF; SegForProg(WrSeg) := '1'; WrAddr := WrAddr+1; ELSIF ALE='0' AND CLE='1' AND Data=16#10# AND ((ESUSP_ACT = '1' AND WrBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN prog_time := page_prog_time + tpd_WENeg_RY(tr10); PRG_ACT <= '1'; PROG_in <= '1'; RY_zd <= '0'; Status(5) := '0'; firstFlag := true; ELSIF ALE='0' AND CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN PREL_OTP => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN OTPOverlay := true; OTP_in <= '1'; RY_zd <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#01# THEN OTPOverlay := false; OTP_in <= '1'; RY_zd <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#02# THEN OTP_STAT_ACT <= '1'; FirstByte := true; WAIT_OTP_in <= '1'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#03# THEN DEF_OTP_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#04# THEN DEF_OTP_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#05# THEN WAIT_OTP_in <= '1'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN WAIT_STATE => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF WAIT_OTP_out'event AND WAIT_OTP_out = '1' THEN WAIT_OTP_in <= '0'; END IF; WHEN WAIT_STATE_1 => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF WAIT_OTP_out'event AND WAIT_OTP_out = '1' THEN WAIT_OTP_in <= '0'; Protect := true; OTPOverlay := true; END IF; WHEN WAIT_STATE_2 => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF OTP_out'event AND OTP_out = '1' THEN OTP_in <= '0'; RY_zd <= '1'; END IF; WHEN DEF_OVER => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN DEF_OTP_in <= '0'; IF NOT(SetDefault) THEN SetDefault := true; OTPDefault := Overlaid; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(0) := '0'; ELSE RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(0) := '1'; END IF; END IF; WHEN DEF_REM => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN DEF_OTP_in <= '0'; IF NOT(SetDefault) THEN SetDefault := true; OTPDefault := Removed; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(0) := '0'; ELSE RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(0) := '1'; END IF; END IF; WHEN OTHERS => NULL; END CASE; END IF; IF RENeg = '1' OR CENeg='1' THEN DOut_zd <= (OTHERS => 'Z'); END IF; END PROCESS Functional; pr1_buff: PROCESS (PROG1_in) IS BEGIN -- PROCESS dypr_buff IF PROG1_in'event AND PROG1_in = '1' THEN PROG1_out <= '1' AFTER prog_time; ELSIF PROG1_in'event AND PROG1_in='0' THEN PROG1_out <= '0'; END IF; END PROCESS pr1_buff; pr2_buff: PROCESS (PROG2_in) IS BEGIN -- PROCESS dypr_buff IF PROG2_in'event AND PROG2_in='1' THEN PROG2_out <= '1' AFTER prog_time; ELSIF PROG2_in'event AND PROG2_in='0' THEN PROG2_out <= '0'; END IF; END PROCESS pr2_buff; Normal_Prog: PROCESS (PROG_in) IS BEGIN IF rising_edge(PROG_in) THEN PROG_out <= '1' AFTER prog_time; ELSIF falling_edge (PROG_in) THEN PROG_out <= '0'; END IF; END PROCESS Normal_Prog; OTPDefault_Prog: PROCESS (DEF_OTP_in) IS BEGIN IF rising_edge(DEF_OTP_in) THEN DEF_OTP_out <= '1' AFTER tdevice_OTPD + tpd_WENeg_RY(tr10); ELSIF falling_edge (DEF_OTP_in) THEN DEF_OTP_out <= '0'; END IF; END PROCESS OTPDefault_Prog; WAIT_OTP_prot: PROCESS (WAIT_OTP_in) IS BEGIN IF rising_edge(WAIT_OTP_in) THEN WAIT_OTP_out <= '1' AFTER tpd_WENeg_RY(tr10); ELSIF falling_edge (WAIT_OTP_in) THEN WAIT_OTP_out <= '0'; END IF; END PROCESS WAIT_OTP_prot; WAIT_OTP: PROCESS (OTP_in) IS BEGIN IF rising_edge(OTP_in) THEN OTP_out <= '1' AFTER tdevice_OTP + tpd_WENeg_RY(tr10); ELSIF falling_edge (OTP_in) THEN OTP_out <= '0'; END IF; END PROCESS WAIT_OTP; Page_Read: PROCESS (TR_in) IS BEGIN IF rising_edge(TR_in) THEN IF (Long_Timming = TRUE) THEN TR_out <= '0','1' AFTER tdevice_TR; ELSE TR_out <= '0','1' AFTER tdevice_TR/5; END IF; ELSE TR_out <= '0'; END IF; END PROCESS Page_Read; Partial_Read: PROCESS (TRP_in) IS BEGIN IF rising_edge(TRP_in) THEN IF (Long_Timming = TRUE) THEN TRP_out <= '0','1' AFTER tdevice_TRP; ELSE TRP_out <= '0','1' AFTER tdevice_TRP/1; END IF; ELSE TRP_out <= '0'; END IF; END PROCESS Partial_Read; Pipeline_Read: PROCESS (TPT_in) IS BEGIN IF rising_edge(TPT_in) THEN IF (Long_Timming = TRUE) THEN TPT_out <= '0','1' AFTER tdevice_TPT; ELSE TPT_out <= '0','1' AFTER tdevice_TPT/5; END IF; ELSE TPT_out <= '0'; END IF; END PROCESS Pipeline_Read; DBSYTime: PROCESS (DBSY_in) IS BEGIN IF rising_edge(DBSY_in) THEN IF (Long_Timming = TRUE) THEN DBSY_out <= '0','1' AFTER (tdevice_DBSY+tpd_WENeg_RY(tr10)); ELSE DBSY_out <= '0','1' AFTER (tdevice_DBSY+tpd_WENeg_RY(tr10))/1; END IF; ELSE DBSY_out <= '0'; END IF; END PROCESS DBSYTime; DBSY1Time: PROCESS (DBSY1_in) IS BEGIN IF rising_edge(DBSY1_in) THEN IF (Long_Timming = TRUE) THEN DBSY1_out <= '0','1' AFTER (tdevice_DBSY+tpd_WENeg_RY(tr10)); ELSE DBSY1_out <= '0','1' AFTER (tdevice_DBSY+tpd_WENeg_RY(tr10))/1; END IF; ELSE DBSY1_out <= '0'; END IF; END PROCESS DBSY1Time; SuspendTime: PROCESS (ERS_SUSP_in) IS BEGIN IF rising_edge(ERS_SUSP_in) THEN IF (Long_Timming = TRUE) THEN ERS_SUSP_out <= '0','1' AFTER tdevice_SUSP; ELSE ERS_SUSP_out <= '0','1' AFTER tdevice_SUSP/1; END IF; ELSE ERS_SUSP_out <= '0'; END IF; END PROCESS SuspendTime; PreSuspendTime: PROCESS (ERS_PRESUS_in) IS BEGIN IF rising_edge(ERS_PRESUS_in) THEN IF (Long_Timming = TRUE) THEN ERS_PRESUS_out <= '0','1' AFTER tdevice_PRESUS + tpd_WENeg_RY(tr10); ELSE ERS_PRESUS_out <= '0','1' AFTER tdevice_PRESUS/1 + tpd_WENeg_RY(tr10); END IF; ELSE ERS_PRESUS_out <= '0'; END IF; END PROCESS PreSuspendTime; PRETime: PROCESS (TPRE_in) IS BEGIN IF rising_edge(TPRE_in) THEN IF (Long_Timming = TRUE) THEN TPRE_out <= '0','1' AFTER (tdevice_TPRE - 10 us); ELSE TPRE_out <= '0','1' AFTER (tdevice_TPRE - 10 us)/20; END IF; ELSE TPRE_out <= '0'; END IF; END PROCESS PRETime; IDPreload: PROCESS (PoweredUp) IS BEGIN -- PROCESS IDPreload IF PoweredUp='1' THEN IDArray(0) := 16#01#; IDArray(1) := 16#91#; IDArray(2) := 16#01#; IDArray(3) := 16#00#; IDArray(4) := 16#22#; IDArray(5) := 16#00#; END IF; END PROCESS IDPreload; -- purpose: Memory preload process -- inputs : PoweredUp MemPreload: PROCESS (PoweredUp) -- text file input variable FILE mem_file : text IS mem_file_name; FILE OTP_file : text IS OTP_file_name; FILE protOTP_file : text IS protOTP_file_name; VARIABLE buf : line; VARIABLE i : natural; VARIABLE ind : natural; VARIABLE pind : natural; VARIABLE index : natural; VARIABLE p_data : NATURAL; VARIABLE segment : NATURAL; VARIABLE over : BOOLEAN; VARIABLE mem_data : INTEGER; VARIABLE mem_addr : INTEGER; BEGIN -- PROCESS MemPreload initialize; IF PoweredUp = '1' THEN ProgramedFlag := (OTHERS => (OTHERS => '0')); OTPProgramedFlag := (OTHERS => (OTHERS => '0')); OTP_Area := (OTHERS => (OTHERS => MaxData)); ProtStatus := "0000000011111111"; ------------------------------------------------------------------- -- Memory preload file format for s30ms ------------------------------------------------------------------- -- / - comment -- @aaaaaaa - stands for page address and address within -- first 1056 words of a page -- dddd - is word to be written at Mem(Page)(offset++) -- page is div 1056 -- offset is mod 1056 -- offset is incremented on every write ------------------------------------------------------------------- IF mem_file_name /= "none" THEN ind := 0; WHILE (NOT ENDFILE (mem_file)) LOOP READLINE(mem_file,buf); IF buf(1)='/' THEN next; ELSIF buf(1) = '@' THEN ind := h(buf(2 TO 8)); ELSE p_data := h(buf(1 TO 4)); IF ind = 0 THEN pind := 0; index := 0; ELSIF ind <= PageSize THEN pind := 0; index := ind; ELSE pind := natural(ind/(PageSize+1)); index := ind - pind * (PageSize+1); END IF; IF pind <= PageNum AND index <= PageSize THEN IF p_data /= 16#FFFF# THEN mem_addr := pind * (PageSize+1) + index; mem_data := h(buf(1 TO 4)); write_mem( linked_list(list_id(mem_addr)), mem_addr, mem_data); END IF; getSegment(index,segment); ProgramedFlag(pind)(segment) := '1'; ind := ind + 1; ELSE REPORT "Memory address out of range"; END IF; END IF; END LOOP; END IF; ------------------------------------------------------------------- -- Memory preload file format for s30ms ------------------------------------------------------------------- -- / - comment -- @aaaa - stands for page address and address within -- first 1056 words of a page -- dddd - is word to be written at Mem(Page)(offset++) -- page is div 1056 -- offset is mod 1056 -- offset is incremented on every write ------------------------------------------------------------------- IF OTP_file_name /= "none" THEN ind := 0; WHILE (NOT ENDFILE (OTP_file)) LOOP READLINE(OTP_file,buf); IF buf(1)='/' THEN next; ELSIF buf(1) = '@' THEN ind := h(buf(2 TO 5)); ELSE p_data := h(buf(1 TO 4)); IF ind = 0 THEN pind := 0; index := 0; ELSIF ind <= PageSize THEN pind := 0; index := ind; ELSE pind := natural(ind/(PageSize+1)); index := ind - pind * (PageSize+1); END IF; IF pind <= OTPPageNum AND index <= PageSize THEN IF p_data /= 16#FFFF# THEN OTP_Area(pind)(index) := h(buf(1 TO 4)); END IF; getSegment(index,segment); OTPProgramedFlag(pind)(segment) := '1'; ind := ind + 1; ELSE REPORT "Memory address out of range"; END IF; END IF; END LOOP; END IF; IF protOTP_file_name /= "none" THEN ind := 0; WHILE (not ENDFILE (protOTP_file) AND not over) LOOP READLINE (protOTP_file, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --sector number ind := h(buf(2 TO 2)); ELSE IF (buf(1) = '1') THEN IF ind <= OTPPageNum THEN ProtStatus(ind) := '0'; END IF; END IF; IF ind < OTPPageNum THEN ind := ind + 1; ELSE over := true; END IF; END IF; END LOOP; END IF; END IF; END PROCESS MemPreload; RPassTrough: PROCESS (RY_zd) IS BEGIN -- PROCESS RPassTrough IF RY_zd = '0' THEN RY_Pass <= '0'; ELSE RY_Pass <= 'Z'; END IF; END PROCESS RPassTrough; --------------------------------------------------------------------------- -- Path delay section --------------------------------------------------------------------------- PROCESS (RY_Pass) VARIABLE RY_GlitchData : VitalGlitchDataType; BEGIN -- PROCESS VitalPathDelay01( OutSignal => RY, OutSignalName => "RY", OutTemp => RY_Pass, GlitchData => RY_GlitchData, Mode => VitalTransport, Paths => ( 0 =>(InputChangeTime => WENeg'LAST_EVENT, PathDelay => tpd_WENeg_RY, PathCondition => true) ) ); END PROCESS; D_Out_Path_Gen : FOR i IN 0 TO 15 GENERATE BEGIN -- GENERATE D_Out_Path_Gen PROCESS (DOut_zd(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN -- PROCESS VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_zd(i), GlitchData => D0_GlitchData, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => RENeg'LAST_EVENT, PathDelay => tpd_RENeg_IO0, PathCondition => true), 1 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_IO0, PathCondition => true) ) ); END PROCESS; END GENERATE D_Out_Path_Gen; END BLOCK Behavior; END ARCHITECTURE vhdl_behavioral_dynamic_memory_allocation; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral_static_memory_allocation OF s30ms512r01 IS ATTRIBUTE VITAL_LEVEL0 OF vhdl_behavioral_static_memory_allocation : ARCHITECTURE IS TRUE; CONSTANT PartId : STRING := "s30ms512r01"; CONSTANT MaxData : NATURAL := 16#FFFF#; CONSTANT BlockNum : NATURAL := 511; -- number of blocks CONSTANT BlockSize : NATURAL := 63; -- size of block in pages CONSTANT PageNum : NATURAL := 16#7FFF#; -- block * numinblock CONSTANT PageNumInBl : NATURAL := 64; CONSTANT PageSize : NATURAL := 1055; -- with spare CONSTANT SegmentNum : NATURAL := 7; -- 8 segment within page CONSTANT SegmentSize : natural := 256; CONSTANT SperSegSize : NATURAL := 8; CONSTANT SpareSize : natural := 32; CONSTANT MainSize : NATURAL := 1024; CONSTANT OTPPageNum : NATURAL := 7; CONSTANT MainAreaAddBit : natural := 10; CONSTANT HAddBitPag : NATURAL := 16; CONSTANT HAddBitBl : natural := 25; CONSTANT HAddBitSpareSeg : NATURAL := 4; CONSTANT HAddBitSeg : NATURAL := 9; -- Interconnect path delay signals SIGNAL IO15_ipd : std_ulogic := 'U'; SIGNAL IO14_ipd : std_ulogic := 'U'; SIGNAL IO13_ipd : std_ulogic := 'U'; SIGNAL IO12_ipd : std_ulogic := 'U'; SIGNAL IO11_ipd : std_ulogic := 'U'; SIGNAL IO10_ipd : std_ulogic := 'U'; SIGNAL IO9_ipd : std_ulogic := 'U'; SIGNAL IO8_ipd : std_ulogic := 'U'; SIGNAL IO7_ipd : std_ulogic := 'U'; SIGNAL IO6_ipd : std_ulogic := 'U'; SIGNAL IO5_ipd : std_ulogic := 'U'; SIGNAL IO4_ipd : std_ulogic := 'U'; SIGNAL IO3_ipd : std_ulogic := 'U'; SIGNAL IO2_ipd : std_ulogic := 'U'; SIGNAL IO1_ipd : std_ulogic := 'U'; SIGNAL IO0_ipd : std_ulogic := 'U'; SIGNAL CLE_ipd : std_ulogic := 'U'; SIGNAL ALE_ipd : std_ulogic := 'U'; SIGNAL CENeg_ipd : std_ulogic := 'U'; SIGNAL RENeg_ipd : std_ulogic := 'U'; SIGNAL WENeg_ipd : std_ulogic := 'U'; SIGNAL WPNeg_ipd : std_ulogic := 'U'; -- internal delays SIGNAL PROG_in : std_ulogic := '0'; SIGNAL PROG_out : std_ulogic := '0'; SIGNAL ERS_in : std_ulogic := '0'; SIGNAL ERS_out : std_ulogic := '0'; SIGNAL DBSY_in : std_ulogic := '0'; SIGNAL DBSY_out : std_ulogic := '0'; SIGNAL TR_in : std_ulogic := '0'; SIGNAL TR_out : std_ulogic := '0'; SIGNAL TRP_in : std_ulogic := '0'; SIGNAL TRP_out : std_ulogic := '0'; SIGNAL TPT_in : std_ulogic := '0'; SIGNAL TPT_out : std_ulogic := '0'; SIGNAL ERS_SUSP_in : std_ulogic := '0'; SIGNAL ERS_SUSP_out : std_ulogic := '0'; SIGNAL ERS_PRESUS_in : std_ulogic := '0'; SIGNAL ERS_PRESUS_out : std_ulogic := '0'; SIGNAL OTP_in : std_ulogic := '0'; SIGNAL OTP_out : std_ulogic := '0'; SIGNAL WAIT_OTP_in : std_ulogic := '0'; SIGNAL WAIT_OTP_out : std_ulogic := '0'; SIGNAL DEF_OTP_in : std_ulogic := '0'; SIGNAL DEF_OTP_out: std_ulogic := '0'; SIGNAL TPRE_in : std_ulogic := '0'; SIGNAL TPRE_out : std_ulogic := '0'; SIGNAL PROG_tmp_in : std_ulogic := '0'; SIGNAL PROG_tmp_out : std_ulogic := '0'; SIGNAL SPROG_in : std_ulogic := '0'; SIGNAL SPROG_out : std_ulogic := '0'; SIGNAL DBSY_tmp_in : std_ulogic := '0'; SIGNAL DBSY_tmp_out : std_ulogic := '0'; SIGNAL TRP_tmp_in : std_ulogic := '0'; SIGNAL TRP_tmp_out : std_ulogic := '0'; SIGNAL TR_tmp_in : std_ulogic := '0'; SIGNAL TR_tmp_out : std_ulogic := '0'; SIGNAL TPT_tmp_in : std_ulogic := '0'; SIGNAL TPT_tmp_out : std_ulogic := '0'; SIGNAL RST_tmp_in : std_ulogic := '0'; SIGNAL RST_tmp_out : std_ulogic := '0'; SIGNAL ERS_SUSP_tmp_in : std_ulogic := '0'; SIGNAL ERS_SUSP_tmp_out : std_ulogic := '0'; SIGNAL ERS_PRESUS_tmp_in : std_ulogic := '0'; SIGNAL ERS_PRESUS_tmp_out : std_ulogic := '0'; SIGNAL OTP_tmp_in : std_ulogic := '0'; SIGNAL OTP_tmp_out : std_ulogic := '0'; SIGNAL OTPD_tmp_in : std_ulogic := '0'; SIGNAL OTPD_tmp_out : std_ulogic := '0'; SIGNAL TPRE_tmp_in : std_ulogic := '0'; SIGNAL TPRE_tmp_out : std_ulogic := '0'; BEGIN -- ARCHITECTURE vhdl_behavioral ----------------------------------------------------------------------------- -- Internal delays ----------------------------------------------------------------------------- -- Vital primitives which incorporate internal delays PROG : VitalBUF(PROG_tmp_out, PROG_tmp_in, (tdevice_PROG, UnitDelay)); SPROG : VitalBUF(SPROG_out, SPROG_in, (tdevice_SPROG, UnitDelay)); ERS : VitalBUF(ERS_out, ERS_in, (tdevice_ERS, UnitDelay)); DBSY : VitalBUF(DBSY_tmp_out, DBSY_tmp_in, (tdevice_DBSY, UnitDelay)); TR : VitalBUF(TR_tmp_out, TR_tmp_in, (tdevice_TR, UnitDelay)); TRP : VitalBUF(TRP_tmp_out, TRP_tmp_in, (tdevice_TRP, UnitDelay)); TPT : VitalBUF(TPT_tmp_out, TPT_tmp_in, (tdevice_TPT, UnitDelay)); RST : VitalBUF(RST_tmp_out, RST_tmp_in, (tdevice_RST, UnitDelay)); SUSP : VitalBUF(ERS_SUSP_tmp_out, ERS_SUSP_tmp_in, (tdevice_SUSP, UnitDelay)); PRESUS : VitalBUF(ERS_PRESUS_tmp_out, ERS_PRESUS_tmp_in, (tdevice_PRESUS, UnitDelay)); OTP : VitalBUF(OTP_tmp_out, OTP_tmp_in, (tdevice_OTP, UnitDelay)); OTPD : VitalBUF(OTPD_tmp_out, OTPD_tmp_in, (tdevice_OTPD,UnitDelay)); TPRE : VitalBUF(TPRE_tmp_out, TPRE_tmp_in, (tdevice_TPRE, UnitDelay)); ----------------------------------------------------------------------------- -- WIRE DELAYS ----------------------------------------------------------------------------- WireDelay : BLOCK IS BEGIN -- BLOCK WireDelay w_1 : VitalWireDelay( IO15_ipd, IO15, tipd_IO15 ); w_2 : VitalWireDelay( IO14_ipd, IO14, tipd_IO14 ); w_3 : VitalWireDelay( IO13_ipd, IO13, tipd_IO13 ); w_4 : VitalWireDelay( IO12_ipd, IO12, tipd_IO12 ); w_5 : VitalWireDelay( IO11_ipd, IO11, tipd_IO11 ); w_6 : VitalWireDelay( IO10_ipd, IO10, tipd_IO10 ); w_7 : VitalWireDelay( IO9_ipd, IO9, tipd_IO9 ); w_8 : VitalWireDelay( IO8_ipd, IO8, tipd_IO8 ); w_9 : VitalWireDelay( IO7_ipd, IO7, tipd_IO7 ); w_10 : VitalWireDelay( IO6_ipd, IO6, tipd_IO6 ); w_11 : VitalWireDelay( IO5_ipd, IO5, tipd_IO5 ); w_12 : VitalWireDelay( IO4_ipd, IO4, tipd_IO4 ); w_13 : VitalWireDelay( IO3_ipd, IO3, tipd_IO3 ); w_14 : VitalWireDelay( IO2_ipd, IO2, tipd_IO2 ); w_15 : VitalWireDelay( IO1_ipd, IO1, tipd_IO1 ); w_16 : VitalWireDelay( IO0_ipd, IO0, tipd_IO0 ); w_17 : VitalWireDelay( CLE_ipd, CLE, tipd_CLE ); w_18 : VitalWireDelay( ALE_ipd, ALE, tipd_ALE ); w_19 : VitalWireDelay( CENeg_ipd, CENeg, tipd_CENeg ); w_20 : VitalWireDelay( RENeg_ipd, RENeg, tipd_RENeg ); w_21 : VitalWireDelay( WENeg_ipd, WENeg, tipd_WENeg ); w_22 : VitalWireDelay( WPNeg_ipd, WPNeg, tipd_WPNeg ); END BLOCK WireDelay; ----------------------------------------------------------------------------- -- Main Behavior Block ----------------------------------------------------------------------------- Behavior : BLOCK PORT ( A : IN std_logic_vector(7 DOWNTO 0) := (OTHERS => 'U'); DIN : IN std_logic_vector(15 DOWNTO 0) := (OTHERS => 'U'); DOUT : OUT std_logic_vector(15 DOWNTO 0) := (OTHERS => 'Z'); CLE : IN std_ulogic := 'U'; ALE : IN std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; RENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; RY : Out std_ulogic := '0' ); PORT MAP ( A(7) => IO7_ipd, A(6) => IO6_ipd, A(5) => IO5_ipd, A(4) => IO4_ipd, A(3) => IO3_ipd, A(2) => IO2_ipd, A(1) => IO1_ipd, A(0) => IO0_ipd, DIn(15) => IO15_ipd, DIn(14) => IO14_ipd, DIn(13) => IO13_ipd, DIn(12) => IO12_ipd, DIn(11) => IO11_ipd, DIn(10) => IO10_ipd, DIn(9) => IO9_ipd, DIn(8) => IO8_ipd, DIn(7) => IO7_ipd, DIn(6) => IO6_ipd, DIn(5) => IO5_ipd, DIn(4) => IO4_ipd, DIn(3) => IO3_ipd, DIn(2) => IO2_ipd, DIn(1) => IO1_ipd, DIn(0) => IO0_ipd, DOut(15) => IO15, DOut(14) => IO14, DOut(13) => IO13, DOut(12) => IO12, DOut(11) => IO11, DOut(10) => IO10, DOut(9) => IO9, DOut(8) => IO8, DOut(7) => IO7, DOut(6) => IO6, DOut(5) => IO5, DOut(4) => IO4, DOut(3) => IO3, DOut(2) => IO2, DOut(1) => IO1, DOut(0) => IO0, CLE => CLE_ipd, ALE => ALE_ipd, CENeg => CENeg_ipd, RENeg => RENeg_ipd, WENeg => WENeg_ipd, WPNeg => WPNeg_ipd, RY => RY ); -- State Machine : State_Type TYPE state_type IS ( IDLE, UNKNOWN, -- wrong command sequneces PREL_RD, RESET, A0_RD, A1_RD, A2_RD, RD_WCMD, -- waiting for the confirm read command BUFF_TR, RD, CAC_PREL, -- Coloumn address change A0_CAC, A1_CAC, -- Wait for confirm EO command ID_PREL, ID, PREL_PRG, PGD_PREL, A0_PRG, A1_PRG, A2_PRG, DATA_PRG, WFPD, -- wait for program done WFPPD, PGMS_CAC, A0_PRG_CAC, PGMS, CBSY, RDY_PRG, PREL_ERS, A1_ERS, A2_ERS, ERS_EXEC, ERS_SUSP, A0_PGD, A1_PGD, A2_PGD, A3_PGD, PREL_OTP, DEF_OVER, DEF_REM, WAIT_STATE, WAIT_STATE_1, WAIT_STATE_2 ); -- Page Array TYPE PageArr IS ARRAY (0 TO PageSize) OF Integer RANGE -1 TO MaxData; -- Flash Memory Array TYPE MemArr IS ARRAY (0 TO PageNum) OF PageArr; TYPE OTPArr IS ARRAY (0 TO OTPPageNum) OF PageArr; TYPE MemSegArr IS ARRAY (0 TO PageNum) OF std_logic_vector (SegmentNum DOWNTO 0); TYPE OTPSegArr IS ARRAY (0 TO OTPPageNum) OF std_logic_vector (SegmentNum DOWNTO 0); TYPE IDArr IS ARRAY (0 TO 5) OF integer RANGE -1 TO MaxData; TYPE OTPDefaultType IS (Removed, Overlaid); TYPE ProtStatusType IS ARRAY (0 TO OTPPageNum) OF std_logic; TYPE SegAddrBoundary IS ARRAY (0 TO SegmentNum) OF NATURAL; -- states SIGNAL current_state : State_Type; SIGNAL next_state : State_Type; -- control signals Signal STAT_ACT : std_logic := '0'; SIGNAL ERS_ACT : std_logic := '0'; SIGNAL PRG_ACT : std_logic := '0'; SIGNAL RD_ACT : std_logic := '0'; SIGNAL RSTSTART : std_logic := '0'; SIGNAL RSTDONE : std_logic := '0'; -- Control signals for read operation SIGNAL PGR_ACT : std_logic := '0'; -- Page read in progress SIGNAL PPGR_ACT : std_logic := '0'; -- Partial page read SIGNAL PGD_ACT : std_logic := '0'; -- Page Duplicate SIGNAL PIPR_ACT : std_logic := '0'; -- Pipeline read -- powerup SIGNAL PoweredUp : std_logic := '0'; SIGNAL reseted : std_logic := '0'; SIGNAL write : std_logic := '0'; SIGNAL read : std_logic := '0'; SIGNAL DOut_zd : std_logic_vector(15 DOWNTO 0) := (OTHERS => 'Z'); SIGNAL DOut_Pass : std_logic_vector(15 DOWNTO 0) := (OTHERS => 'Z'); SIGNAL RY_zd : std_logic := '0'; SIGNAL RY_Pass : std_logic := '0'; SIGNAL PROG1_in : std_ulogic := '0'; SIGNAL PROG1_out : std_ulogic := '0'; SIGNAL PROG2_in : std_ulogic := '0'; SIGNAL PROG2_out : std_ulogic := '0'; SIGNAL DBSY1_in : std_ulogic := '0'; SIGNAL DBSY1_out : std_ulogic := '0'; SIGNAL ERES : std_logic := '0'; SIGNAL ESUSP : std_logic := '0'; SIGNAL ESTART : std_logic := '0'; SIGNAL EDONE : std_logic := '0'; SIGNAL ESUSP_ACT : std_logic := '0'; SIGNAL OTP_STAT_ACT : std_logic := '0'; SHARED VARIABLE FROMCE : BOOLEAN := FALSE; SHARED VARIABLE FROMRE : BOOLEAN := FALSE; -- 8 BIT ADDRESS SIGNAL AddrCom : std_logic_vector(7 DOWNTO 0); -- Data SIGNAL Data : integer RANGE -1 TO MaxData; -- ID control signals SIGNAL IDAddr : integer RANGE 0 TO 7; SHARED VARIABLE SegForProg : std_logic_vector (SegmentNum DOWNTO 0); SHARED VARIABLE SegProgSt : std_logic_vector (SegmentNum DOWNTO 0) := "00000000"; SHARED VARIABLE Tmp : std_logic_vector (3 DOWNTO 0) := "0000"; SHARED VARIABLE ProgramedFlag : MemSegArr; SHARED VARIABLE OTPProgramedFlag : OTPSegArr; SHARED VARIABLE WrBlck : INTEGER RANGE 0 to BlockNum; SHARED VARIABLE ErsBlck : INTEGER RANGE 0 to BlockNum; SHARED VARIABLE TmpBlck : INTEGER RANGE 0 to BlockNum; SHARED VARIABLE ssa : SegAddrBoundary := (16#000# ,16#100# ,16#200# ,16#300# ,16#400# ,16#408# ,16#410# ,16#418#); -- Segments ending addresses SHARED VARIABLE sea : SegAddrBoundary := (16#0FF# ,16#1FF# ,16#2FF# ,16#3FF# ,16#407# ,16#40F# ,16#417# ,16#41F#); -- Mem(Page)(Address) SHARED VARIABLE Mem : MemArr := (OTHERS => (OTHERS => MaxData)); SHARED VARIABLE OTP_Area : OTPArr := (OTHERS => (OTHERS => MaxData)); SHARED VARIABLE ProtStatus : std_logic_vector(15 DOWNTO 0); SHARED VARIABLE WriteProtect : BOOLEAN := FALSE; -- ID Array SHARED VARIABLE IDArray : IDArr; -- Page duplicate buffer SHARED VARIABLE PDBuffer : PageArr := (OTHERS => 0); -- Status SHARED VARIABLE Status : std_logic_vector(15 DOWNTO 0) := "0000000001100100"; SHARED VARIABLE prog_time : TIME; SHARED VARIABLE erase_time : TIME; SHARED VARIABLE page_prog_time : TIME; SHARED VARIABLE seg_prog_time : TIME; -- timing check violation SIGNAL Viol : X01 := '0'; PROCEDURE getSegment ( paddress : IN integer RANGE 0 TO PageSize; j : OUT integer RANGE -1 TO SegmentNum) IS BEGIN -- PROCEDURE getSegment FOR i IN 0 TO SegmentNum LOOP IF paddress >= ssa(i) AND paddress <= sea(i) THEN j := i; END IF; END LOOP; -- i END PROCEDURE getSegment; BEGIN --------------------------------------------------------------------------- -- Power Up time 10 us --------------------------------------------------------------------------- PoweredUp <= '1' AFTER 10 us; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS (A,DIn,CLE,ALE,CENeg,RENeg,WENeg,WPNeg) IS -- Timing check variables VARIABLE TViol_IO0_WENeg : X01 := '0'; VARIABLE TD_IO0_WENeg : VitalTimingDataType; VARIABLE TViol_CLE_WENeg_F : X01 := '0'; VARIABLE TD_CLE_WENeg_F : VitalTimingDataType; VARIABLE TViol_ALE_WENeg_F : X01 := '0'; VARIABLE TD_ALE_WENeg_F : VitalTimingDataType; VARIABLE TViol_CENeg_WENeg_F : X01 := '0'; VARIABLE TD_CENeg_WENeg_F : VitalTimingDataType; VARIABLE TViol_WPNeg_WENeg_F : X01 := '0'; VARIABLE TD_WPNeg_WENeg_F : VitalTimingDataType; VARIABLE TViol_WENeg_CENeg_F : X01 := '0'; VARIABLE TD_WENeg_CENeg_F : VitalTimingDataType; VARIABLE TViol_CLE_RENeg : X01 := '0'; VARIABLE TD_CLE_RENeg : VitalTimingDataType; VARIABLE TViol_ALE_RENeg : X01 := '0'; VARIABLE TD_ALE_RENeg : VitalTimingDataType; VARIABLE TViol_WENeg_RENeg : X01 := '0'; VARIABLE TD_WENeg_RENeg : VitalTimingDataType; VARIABLE TViol_CENeg_RENeg_F : X01 := '0'; VARIABLE TD_CENeg_RENeg_F : VitalTimingDataType; VARIABLE TViol_RENeg_WENeg : X01 := '0'; VARIABLE TD_RENeg_WENeg : VitalTimingDataType; VARIABLE TViol_CLE_WENeg_R : X01 := '0'; VARIABLE TD_CLE_WENeg_R : VitalTimingDataType; VARIABLE TViol_ALE_WENeg_R : X01 := '0'; VARIABLE TD_ALE_WENeg_R : VitalTimingDataType; VARIABLE TViol_CENeg_WENeg_R : X01 := '0'; VARIABLE TD_CENeg_WENeg_R : VitalTimingDataType; VARIABLE TViol_CENeg_RENeg_H : X01 := '0'; VARIABLE TD_CENeg_RENeg_H : VitalTimingDataType; VARIABLE PViol_WENeg : X01 := '0'; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PViol_RENeg : X01 := '0'; VARIABLE PD_RENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01 := '0'; BEGIN -- PROCESS VITALTimingCheck IF ( TimingChecksOn ) THEN -------------------------------------------------------------------- -- Timing Check Section -------------------------------------------------------------------- -- Setup/Hold Check between IO and WENeg VitalSetupHoldCheck ( TestSignal => IO0, TestSignalName => "IO", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_IO0_WENeg, SetupLow => tsetup_IO0_WENeg, HoldHigh => thold_IO0_WENeg, HoldLow => thold_IO0_WENeg, CheckEnabled => CENeg = '0', RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_IO0_WENeg, Violation => TViol_IO0_WENeg ); -- Setup Check between CLE and WENeg VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_CLE_WENeg, SetupLow => tsetup_CLE_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CLE_WENeg_F, Violation => TViol_CLE_WENeg_F ); -- Setup Check between ALE and WENeg VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_ALE_WENeg, SetupLow => tsetup_ALE_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_ALE_WENeg_F, Violation => TViol_ALE_WENeg_F ); -- Setup Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_F, Violation => TViol_CENeg_WENeg_F ); -- Setup Check between WENeg and CENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => CENeg, RefSignalName => "CE#", SetupHigh => tsetup_WENeg_CENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CENeg_F, Violation => TViol_WENeg_CENeg_F ); -- Setup Check between CLE and RENeg VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => RENeg, RefSignalName => "RE#", SetupLow => tsetup_CLE_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CLE_RENeg, Violation => TViol_CLE_RENeg ); -- Setup Check between ALE and RENeg VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => RENeg, RefSignalName => "RE#", SetupLow => tsetup_ALE_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_ALE_RENeg, Violation => TViol_ALE_RENeg ); -- Setup Check between WENeg and RENeg VitalSetupHoldCheck ( TestSignal => WENeg, TestSignalName => "WE#", RefSignal => RENeg, RefSignalName => "RE#", SetupHigh => tsetup_WENeg_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_RENeg, Violation => TViol_WENeg_RENeg ); -- Setup Check between CENeg and RENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => RENeg, RefSignalName => "RE#", SetupLow => tsetup_CENeg_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_RENeg_F, Violation => TViol_CENeg_RENeg_F ); -- Setup Check between RENeg and WENeg VitalSetupHoldCheck ( TestSignal => RENeg, TestSignalName => "RE#", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_RENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_RENeg_WENeg, Violation => TViol_RENeg_WENeg ); -- Setup Check between WPNeg and WENeg VitalSetupHoldCheck ( TestSignal => WPNeg, TestSignalName => "WP#", RefSignal => WENeg, RefSignalName => "WE#", SetupHigh => tsetup_WPNeg_WENeg, SetupLow => tsetup_WPNeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & PartID, TimingData => TD_WPNeg_WENeg_F, Violation => TViol_WPNeg_WENeg_F ); -- Hold Check between CLE and WENeg VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => WENeg, RefSignalName => "WE#", HoldHigh => thold_CLE_WENeg, HoldLow => thold_CLE_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CLE_WENeg_R, Violation => TViol_CLE_WENeg_R ); -- Hold Check between ALE and WENeg VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => WENeg, RefSignalName => "WE#", HoldHigh => thold_ALE_WENeg, HoldLow => thold_ALE_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_ALE_WENeg_R, Violation => TViol_ALE_WENeg_R ); -- Hold Check between CENeg and WENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => WENeg, RefSignalName => "WE#", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_WENeg_R, Violation => TViol_CENeg_WENeg_R ); -- Hold Check between CENeg and RENeg VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CE#", RefSignal => RENeg, RefSignalName => "RE#", HoldLow => thold_CENeg_RENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CENeg_RENeg_H, Violation => TViol_CENeg_RENeg_H ); -- Period and Pulse Width Check for WENeg VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WE#", Period => tperiod_WENeg, PulseWidthLow => tpw_WENeg_negedge, PulseWidthHigh => tpw_WENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, Violation => PViol_WENeg ); -- Period and Pulse Width Check for RENeg VitalPeriodPulseCheck ( TestSignal => RENeg, TestSignalName => "RE#", Period => tperiod_RENeg, PulseWidthLow => tpw_RENeg_negedge, PulseWidthHigh => tpw_RENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RENeg, Violation => PViol_RENeg ); Violation := TViol_IO0_WENeg OR TViol_CLE_WENeg_F OR TViol_ALE_WENeg_F OR TViol_CENeg_WENeg_F OR TViol_WPNeg_WENeg_F OR TViol_WENeg_CENeg_F OR TViol_CLE_RENeg OR TViol_ALE_RENeg OR TViol_WENeg_RENeg OR TViol_CENeg_RENeg_F OR TViol_RENeg_WENeg OR TViol_CLE_WENeg_R OR TViol_ALE_WENeg_R OR TViol_CENeg_WENeg_R OR TViol_CENeg_RENeg_H OR PViol_RENeg OR PViol_WENeg; Viol <= Violation; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY WARNING; END IF; END PROCESS VITALTimingCheck; --------------------------------------------------------------------------- -- Proces for reset control and FSM state transition --------------------------------------------------------------------------- StateTransition: PROCESS (next_state, PoweredUp) IS BEGIN -- PROCESS StateTransition IF rising_edge(PoweredUp) THEN reseted <= '1'; current_state <= BUFF_TR; IF (Long_Timming = TRUE) THEN page_prog_time := tdevice_PROG; seg_prog_time := tdevice_SPROG; erase_time:= tdevice_ERS; ELSE page_prog_time := tdevice_PROG/100; seg_prog_time := tdevice_SPROG/100; erase_time:= tdevice_ERS/1000; END IF; ELSIF PoweredUp = '1' THEN current_state <= next_state; ELSE current_state <= IDLE; reseted <= '0'; END IF; END PROCESS StateTransition; --------------------------------------------------------------------------- -- Proces for generating the write and read signals --------------------------------------------------------------------------- wr_rd_gen: PROCESS (WENeg, CENeg, RENeg) IS BEGIN -- PROCESS wr_rd_gen IF WENeg = '0' AND CENeg = '0' AND RENeg = '1' THEN write <= '1'; ELSIF WENeg = '1' AND CENeg = '0' AND RENeg = '1' THEN write <= '0'; ELSE write <= 'X'; END IF; IF WENeg = '1' AND CENeg = '0' AND RENeg = '0' THEN read <= '1'; ELSIF WENeg = '1' AND CENeg = '0' AND RENeg = '1' THEN read <= '0'; ELSE read <= 'X'; END IF; END PROCESS wr_rd_gen; --------------------------------------------------------------------------- -- Latches 8 bit address on the rising edge of WE# -- Latches data on rising edge of WE# --------------------------------------------------------------------------- BusCycleDecode: PROCESS (A, DIn, WENeg, CENeg, RENeg) IS BEGIN -- PROCESS BusCycleDecode -- latch address IF rising_edge(WENeg) AND ALE = '1' AND CLE = '0' AND CENeg = '0' AND RENeg = '1' THEN AddrCom <= A(7 DOWNTO 0); END IF; -- latch data IF rising_edge(WENeg) AND ALE = '0' AND CENeg = '0' AND RENeg = '1' THEN Data <= to_nat(DIn(15 DOWNTO 0)); END IF; END PROCESS BusCycleDecode; --------------------------------------------------------------------------- -- Timing control for the Reset Operation --------------------------------------------------------------------------- RstTime: PROCESS (RSTSTART, reseted) IS VARIABLE duration : time; BEGIN -- PROCESS RstTime IF rising_edge(reseted) THEN RSTDONE <= '1'; --reset done ELSIF reseted = '1' THEN IF rising_edge(RSTSTART) AND RSTDONE = '1' THEN IF PGR_ACT = '1' OR PRG_ACT = '1' THEN IF Long_Timming THEN duration := tdevice_RST; ELSE duration := tdevice_RST/1; END IF; ELSE IF Long_Timming THEN duration := tdevice_RST + tpd_WENeg_RY(tr10); ELSE duration := tdevice_RST/1 + tpd_WENeg_RY(tr10); END IF; END IF; RSTDONE <= '0', '1' AFTER duration ; END IF; END IF; END PROCESS RstTime; ErsTime :PROCESS(ESTART, ESUSP, ERES, reseted) IS VARIABLE elapsed : time; VARIABLE duration : time; VARIABLE start : time; BEGIN IF rising_edge(reseted) THEN EDONE <= '1'; -- reset done, ERASE terminated ELSIF reseted = '1' THEN IF rising_edge(ESTART) AND EDONE = '1' THEN elapsed := 0 ns; duration := erase_time + tpd_WENeg_RY(tr10); EDONE <= '0', '1' AFTER duration; start := NOW; ELSIF rising_edge(ESUSP) AND EDONE = '0' THEN elapsed := NOW - start; duration := duration - elapsed; EDONE <= '0'; ELSIF rising_edge(ERES) AND EDONE = '0' THEN start := NOW; EDONE <= '0', '1' AFTER duration; END IF; END IF; END PROCESS ErsTime; --------------------------------------------------------------------------- -- Main Behavior Process -- combinational process for next state generation --------------------------------------------------------------------------- StateGen: PROCESS (write, read, reseted, current_state, ERS_out, PROG_out, TR_out,TRP_out, TPT_out,TPRE_out, DBSY_out, RSTDONE, DBSY1_out, PROG1_out, PROG2_out, DEF_OTP_out, OTP_out, WAIT_OTP_out, ERS_SUSP_out, EDONE) IS BEGIN -- PROCESS StateGen ------------------------------------------------------------------------- -- Funcionality section ------------------------------------------------------------------------- IF reseted /= '1' THEN next_state <= current_state; ELSIF rising_edge(reseted) THEN next_state <= BUFF_TR; ELSE CASE current_state IS WHEN IDLE => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#00# THEN next_state <= PREL_RD; -- ELSIF CLE='1' AND ALE='0' AND Data=16#90# THEN next_state <= ID_PREL; ELSIF CLE='1' AND ALE='0' AND Data=16#80# THEN next_state <= PREL_PRG; ELSIF CLE='1' AND ALE='0' AND Data=16#60# THEN next_state <= PREL_ERS; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN next_state <= IDLE; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#B0# THEN IF ESUSP_ACT = '0' THEN next_state <= PREL_OTP; ELSE next_state <= IDLE; END IF; ELSE next_state <= IDLE; END IF; END IF; WHEN UNKNOWN => IF falling_edge(write) THEN IF CLE = '1' AND ALE='0' AND Data=16#FF# THEN next_state <= RESET; END IF; END IF; WHEN RESET => IF RSTDONE = '1' THEN next_state <= IDLE; END IF; WHEN PREL_RD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A0_RD; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_RD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A1_RD; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_RD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A2_RD; ELSE next_state <= IDLE; END IF; END IF; WHEN A2_RD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= RD_WCMD; ELSE next_state <= IDLE; END IF; END IF; WHEN RD_WCMD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#30# THEN IF (ESUSP_ACT = '1' AND TmpBlck = ErsBlck) THEN next_state <= IDLE; ELSE next_state <= BUFF_TR; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#31# THEN IF (ESUSP_ACT = '1' AND TmpBlck = ErsBlck) THEN next_state <= IDLE; ELSE next_state <= BUFF_TR; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#32# THEN IF ESUSP_ACT = '0' THEN next_state <= BUFF_TR; ELSE next_state <= IDLE; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#33# THEN IF ESUSP_ACT = '0' THEN next_state <= BUFF_TR; ELSE next_state <= IDLE; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#35# THEN IF (ESUSP_ACT = '1' AND TmpBlck = ErsBlck) THEN next_state <= IDLE; ELSE next_state <= BUFF_TR; END IF; ELSIF CLE = '1' THEN next_state <= IDLE; END IF; END IF; WHEN BUFF_TR => IF TR_out'event AND TR_out = '1' THEN next_state <= RD; -- buffer transfered ELSIF TRP_out'event AND TRP_out = '1' THEN next_state <= RD; -- partial buffer transfered ELSIF TPT_out'event AND TPT_out = '1' THEN next_state <= RD; -- pipeline buffer transfered ELSIF TPRE_out'event AND TPRE_out = '1' THEN next_state <= RD; -- buffer transfered END IF; WHEN RD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN IF STAT_ACT = '1' THEN next_state <= RD; ELSE next_state <= PREL_RD; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#80# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN next_state <= PREL_PRG; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#90# AND PGD_ACT='0' AND PIPR_ACT='0' THEN next_state <= ID_PREL; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN next_state <= RD; ELSIF CLE = '1' AND Data = 16#60# AND ALE = '0' AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN next_state <= PREL_ERS; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#85# AND PGD_ACT = '1' THEN next_state <= PGD_PREL; -- Read next column address ELSIF CLE = '1' AND ALE = '0' AND Data = 16#05# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN next_state <= CAC_PREL; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#B0# AND PGD_ACT='0' AND PIPR_ACT='0' THEN IF ESUSP_ACT = '0' THEN next_state <= PREL_OTP; ELSE next_state <= IDLE; END IF; ELSE next_state <= IDLE; END IF; END IF; WHEN CAC_PREL => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A0_CAC; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_CAC => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A1_CAC; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_CAC => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#E0# THEN next_state <= RD; ELSE next_state <= IDLE; END IF; END IF; WHEN ID_PREL => IF falling_edge(write) THEN IF ALE = '1' AND AddrCom = X"00" THEN next_state <= ID; ELSE next_state <= IDLE; END IF; END IF; WHEN ID => IF falling_edge(write) THEN IF CLE='1' AND ALE = '0' AND Data=16#00# THEN next_state <= PREL_RD; -- ELSIF CLE='1' AND ALE = '0' AND Data=16#90# THEN next_state <= ID_PREL; ELSIF CLE='1' AND ALE = '0' AND Data=16#80# THEN next_state <= PREL_PRG; ELSIF CLE='1' AND ALE = '0' AND Data=16#60# THEN next_state <= PREL_ERS; ELSIF CLE='1' AND ALE = '0' AND Data=16#70# THEN next_state <= IDLE; ELSIF CLE='1' AND ALE='0' AND Data=16#B0# THEN IF ESUSP_ACT = '0' THEN next_state <= PREL_OTP; ELSE next_state <= IDLE; END IF; ELSE next_state <= IDLE; END IF; END IF; WHEN PREL_PRG => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A0_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_PRG => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A1_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_PRG => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A2_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN A2_PRG => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= DATA_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN DATA_PRG => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#10# THEN IF (ESUSP_ACT = '1' AND WrBlck = ErsBlck) THEN next_state <= IDLE; ELSE IF PRG_ACT = '1' THEN next_state <= WFPPD; ELSE next_state <= PGMS; END IF; END IF; ELSIF CLE = '1' AND ALE = '0' AND PGD_ACT = '0' AND Data = 16#15# THEN IF ESUSP_ACT = '0' THEN IF PRG_ACT='1' THEN next_state <= WFPD; ELSE next_state <= CBSY; END IF; ELSE next_state <= IDLE; END IF; ELSIF CLE ='1' AND ALE='0' AND Data = 16#85# THEN next_state <= PGMS_CAC; ELSIF CLE='1' THEN next_state <= UNKNOWN; ELSIF ALE='0' AND CLE='0' THEN next_state <= DATA_PRG; -- write next word to buffer END IF; END IF; WHEN WFPD => -- Waiting for programing done IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; -- reset END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN next_state <= CBSY; -- programming done END IF; WHEN WFPPD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; -- reset END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN next_state <= PGMS; -- next start programing END IF; WHEN PGMS_CAC => IF falling_edge(write) THEN IF ALE='1' THEN next_state <= A0_PRG_CAC; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_PRG_CAC => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= DATA_PRG; ELSE next_state <= IDLE; END IF; END IF; WHEN PGMS => IF PROG_out'event AND PROG_out = '1' THEN next_state <= IDLE; -- programming done ELSIF PROG2_out'event AND PROG2_out = '1' THEN next_state <= IDLE; -- programming done ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN next_state <= IDLE; -- otp page protect done END IF; WHEN CBSY => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; -- reset END IF; ELSIF DBSY_out'event AND DBSY_out = '1' THEN next_state <= RDY_PRG; ELSIF DBSY1_out'event AND DBSY1_out = '1' THEN next_state <= RDY_PRG; END IF; WHEN RDY_PRG => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#80# THEN next_state <= PREL_PRG; ELSIF CLE = '1' AND ALE='0' AND Data = 16#FF# THEN next_state <= RESET; ELSIF CLE='1' AND ALE='0' AND Data = 16#70# THEN next_state <= RDY_PRG; ELSE next_state <= IDLE; END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN next_state <= IDLE; END IF; WHEN PREL_ERS => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A1_ERS; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_ERS => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A2_ERS; ELSE next_state <= IDLE; END IF; END IF; WHEN A2_ERS => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data = 16#D0# AND WPNeg /= '0' AND NOT(WriteProtect) THEN next_state <= ERS_EXEC; ELSIF CLE='1' THEN next_state <= IDLE; END IF; END IF; WHEN ERS_EXEC => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ERS_PRESUS_in='0' THEN next_state <= ERS_SUSP; END IF; ELSIF rising_edge(EDONE) THEN next_state <= IDLE; END IF; WHEN ERS_SUSP => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# THEN next_state <= RESET; END IF; ELSIF ERS_SUSP_out'event AND ERS_SUSP_out = '1' THEN next_state <= IDLE; -- erase suspend END IF; WHEN PGD_PREL => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A0_PGD; ELSE next_state <= IDLE; END IF; END IF; WHEN A0_PGD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A1_PGD; ELSE next_state <= IDLE; END IF; END IF; WHEN A1_PGD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A2_PGD; ELSE next_state <= IDLE; END IF; END IF; WHEN A2_PGD => IF falling_edge(write) THEN IF ALE = '1' THEN next_state <= A3_PGD; ELSE next_state <= IDLE; END IF; END IF; WHEN A3_PGD => IF falling_edge(write) THEN IF ALE = '0' AND CLE = '0' THEN next_state <= DATA_PRG; ELSIF ALE = '0' AND CLE = '1' AND Data = 16#10# THEN IF (ESUSP_ACT = '1' AND WrBlck = ErsBlck) THEN next_state <= IDLE; ELSE next_state <= PGMS; END IF; ELSIF ALE = '0' AND CLE ='1' AND Data = 16#85# THEN next_state <= PGMS_CAC; ELSIF CLE = '1' THEN next_state <= IDLE; END IF; END IF; WHEN PREL_OTP => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN next_state <= WAIT_STATE_2; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#01# THEN next_state <= WAIT_STATE_2; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#02# THEN next_state <= WAIT_STATE; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#03# THEN next_state <= DEF_OVER; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#04# THEN next_state <= DEF_REM; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#05# THEN next_state <= WAIT_STATE_1; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; END IF; WHEN WAIT_STATE => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF WAIT_OTP_out'event AND WAIT_OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN WAIT_STATE_1 => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF WAIT_OTP_out'event AND WAIT_OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN WAIT_STATE_2 => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF OTP_out'event AND OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN DEF_OVER => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN DEF_REM => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN next_state <= RESET; ELSE next_state <= IDLE; END IF; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN next_state <= IDLE; END IF; WHEN OTHERS => NULL; END CASE; CASE current_state IS WHEN IDLE | PREL_RD | A0_RD | A1_RD | A2_RD | RD_WCMD | RD | CAC_PREL | A0_CAC | A1_CAC | ID_PREL | ID | PREL_PRG | PGD_PREL | A0_PRG | A1_PRG | A2_PRG | DATA_PRG | PGMS_CAC | A0_PRG_CAC | PGMS | PREL_ERS | A1_ERS | A2_ERS | A0_PGD | A1_PGD | A2_PGD | A3_PGD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN IF ESUSP_ACT = '0' THEN next_state <= RESET; ELSE next_state <= current_state; END IF; END IF; END IF; WHEN BUFF_TR => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND TPRE_in = '0' THEN IF ESUSP_ACT = '0' THEN next_state <= RESET; ELSE next_state <= current_state; END IF; END IF; END IF; WHEN OTHERS => NULL; END CASE; END IF; END PROCESS StateGen; --------------------------------------------------------------------------- -- FSM Output Generation and general funcionality --------------------------------------------------------------------------- Functional : PROCESS (read, write, Data, AddrCom, reseted, current_state, RENeg, CENeg, ALE, CLE, ERS_out, PROG_out, TR_out, TRP_out, DBSY_out, RSTDONE, PROG2_out, DEF_OTP_out, WAIT_OTP_out, TPRE_out, WPNeg, PROG1_out, DBSY1_out, PRG_ACT, ERS_SUSP_out, ERS_PRESUS_out, EDONE, OTP_out, TPT_out) IS VARIABLE oe : BOOLEAN := false; VARIABLE TmpPage : INTEGER RANGE 0 to PageNum; VARIABLE TmpSegm : INTEGER RANGE 0 TO SegmentNum; VARIABLE AddrWithinPage : INTEGER RANGE 0 TO PageSize; VARIABLE PageWithinBlock : INTEGER RANGE 0 TO BlockSize; VARIABLE Segment : INTEGER RANGE 0 TO SegmentNum; VARIABLE pom_seg : INTEGER RANGE 0 TO SegmentNum; VARIABLE RowAddr : std_logic_vector(23 DOWNTO 0); VARIABLE ColAddr : std_logic_vector(15 DOWNTO 0); VARIABLE RdPage : INTEGER RANGE 0 to PageNum; VARIABLE RdAddr : INTEGER RANGE 0 TO PageSize+1; VARIABLE RdSeg : INTEGER RANGE 0 TO SegmentNum; VARIABLE RdBlck : INTEGER RANGE 0 to BlockNum; VARIABLE WrPage : INTEGER RANGE 0 to PageNum; VARIABLE WrAddr : INTEGER RANGE 0 TO PageSize+1; VARIABLE WrSeg : INTEGER RANGE 0 TO SegmentNum; VARIABLE CWrPage : INTEGER RANGE 0 to PageNum; VARIABLE ProgBlck : INTEGER RANGE 0 to BlockNum; VARIABLE ProgPage : INTEGER RANGE 0 to PageNum; VARIABLE ProtPage : INTEGER RANGE 0 to PageNum; VARIABLE PIP_Addr : INTEGER RANGE 0 TO PageSize+1; VARIABLE PIP_Blck : INTEGER RANGE 0 TO BlockNum; VARIABLE PIP_Page : INTEGER RANGE 0 TO PageNum; VARIABLE OTPOverlay : BOOLEAN := FALSE; VARIABLE OTPOverlayPIP : BOOLEAN := FALSE; VARIABLE FirstByte : BOOLEAN := TRUE; VARIABLE SetDefault : BOOLEAN := FALSE; VARIABLE OTPDefault : OTPDefaultType; VARIABLE WrBuffData : PageArr; VARIABLE CashBuffData : PageArr; -- First pipeline read VARIABLE FirstPipe : BOOLEAN := true; VARIABLE firstFlag : BOOLEAN := FALSE; VARIABLE Protect : BOOLEAN := FALSE; VARIABLE SegForProg : std_logic_vector (SegmentNum DOWNTO 0); VARIABLE CashSegForProg : std_logic_vector (SegmentNum DOWNTO 0); VARIABLE SegProgSt : std_logic_vector (SegmentNum DOWNTO 0) := "00000000"; VARIABLE Tmp : std_logic_vector (3 DOWNTO 0) := "0000"; VARIABLE tmp_cnt : INTEGER RANGE 0 TO 4; PROCEDURE Read_Data ( VARIABLE Addr : INOUT integer RANGE 0 TO PageSize; VARIABLE Page : IN integer RANGE -1 TO PageNum) IS BEGIN -- PROCEDURE read_data IF Mem(Page)(Addr) /= -1 THEN DOut_zd <= to_slv(Mem(Page)(Addr),16); ELSE DOut_zd <= ( OTHERS => 'X'); END IF; IF PPGR_ACT = '0' THEN IF Addr /= PageSize THEN Addr := Addr+1; END IF; ELSE getSegment(Addr, Segment); IF Segment < 4 THEN IF Addr < sea(Segment) THEN Addr := Addr+1; ELSIF Addr = sea(Segment) THEN Segment := Segment + 4; Addr := ssa(Segment); END IF; ELSE IF Addr < sea(Segment) THEN Addr := Addr+1; END IF; END IF; END IF; END PROCEDURE Read_Data; PROCEDURE Read_OTP ( VARIABLE Addr : INOUT integer RANGE 0 TO PageSize; VARIABLE Page : IN integer RANGE -1 TO PageNum) IS BEGIN -- PROCEDURE read_data IF Page <= 7 THEN IF OTP_Area(Page)(Addr) /= -1 THEN DOut_zd <= to_slv(OTP_Area(Page)(Addr),16); ELSE DOut_zd <= (OTHERS => 'X'); END IF; ELSE DOut_zd <= (OTHERS => '1'); END IF; IF PPGR_ACT = '0' THEN IF Addr /= PageSize THEN Addr := Addr+1; END IF; ELSE getSegment(Addr, Segment); IF Segment < 4 THEN IF Addr < sea(Segment) THEN Addr := Addr+1; ELSIF Addr = sea(Segment) THEN Segment := Segment + 4; Addr := ssa(Segment); END IF; ELSE IF Addr < sea(Segment) THEN Addr := Addr+1; END IF; END IF; END IF; END PROCEDURE Read_OTP; PROCEDURE EndProgramming IS BEGIN PRG_ACT <= '0'; Status(5) := '1'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(1 DOWNTO 0) := "00"; IF WPNeg /= '0' AND NOT(WriteProtect) THEN IF OTPOverlay AND ProgBlck = 0 THEN IF ProgPage <= 7 THEN FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProtStatus(ProgPage) = '1' AND WrBuffData(j) /= -1 AND OTPProgramedFlag(ProgPage)(pom_seg) = '0' THEN OTP_Area(ProgPage)(j) := WrBuffData(j); END IF; END LOOP; OTPProgramedFlag(ProgPage) := CashSegForProg; ELSE Status(0) := '1'; END IF; ELSE FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProgramedFlag(ProgPage)(pom_seg) = '0' AND WrBuffData(j) /= -1 THEN Mem(ProgPage)(j):= WrBuffData(j); END IF; END LOOP; ProgramedFlag(ProgPage) := CashSegForProg; END IF; END IF; END PROCEDURE EndProgramming; PROCEDURE getAddress ( Column : IN std_logic_vector(15 DOWNTO 0) ) IS BEGIN -- PROCEDURE getAddress IF Column(MainAreaAddBit) = '0' THEN TmpSegm := to_nat(Column(HAddBitSeg DOWNTO HAddBitSeg-1)); AddrWithinPage := to_nat(Column); ELSE TmpSegm := MainSize/SegmentSize + to_nat(Column(HAddBitSpareSeg DOWNTO HAddBitSpareSeg-1)); AddrWithinPage := MainSize + to_nat(Column(HAddBitSpareSeg DOWNTO 0)); END IF; END PROCEDURE getAddress; PROCEDURE getPage ( Row : IN std_logic_vector(23 DOWNTO 0)) IS BEGIN -- PROCEDURE getPage PageWithinBlock :=to_nat(Row(HAddBitPag-MainAreaAddBit-1 DOWNTO 0)); TmpBlck := to_nat(Row(HAddBitBl-MainAreaAddBit-1 DOWNTO HAddBitPag-MainAreaAddBit)); TmpPage := TmpBlck*PageNumInBl + PageWithinBlock; END PROCEDURE getPage; BEGIN -- PROCESS Functional ---------------------------------------------------------------------- -- Funcionality section ---------------------------------------------------------------------- oe := rising_edge(read); Status(7) := WPNeg; IF reseted /= '1' THEN RY_zd <= '0'; ELSIF rising_edge(reseted) THEN TPRE_in <= '1'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSE CASE current_state IS WHEN IDLE => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN STAT_ACT <= '1'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN STAT_ACT <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#90# THEN STAT_ACT <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#B0# THEN STAT_ACT <= '0'; ELSIF CLE='1' AND ALE='0' AND Data=16#80# THEN STAT_ACT <= '0'; IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE='1' AND ALE='0' AND Data=16#60# THEN STAT_ACT <= '0'; IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; OTP_STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; ELSE STAT_ACT <= '0'; END IF; END IF; IF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN UNKNOWN => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ERS_ACT <= '0'; PGD_ACT <= '0'; RD_ACT <= '0'; PIPR_ACT <= '0'; PGR_ACT <= '0'; PRG_ACT <= '0'; Status(5) := '1'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; END IF; END IF; WHEN RESET => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN STAT_ACT <= '1'; END IF; END IF; IF RSTDONE = '1' THEN RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(1 DOWNTO 0) := "00"; OTP_STAT_ACT <= '0'; PRG_ACT <= '0'; ERS_ACT <= '0'; RD_ACT <= '0'; PGD_ACT <= '0'; PIPR_ACT <= '0'; PGR_ACT <= '0'; Protect := false; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN PREL_RD => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A0_RD => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(15 DOWNTO 8) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A1_RD => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A2_RD => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(15 DOWNTO 8) := AddrCom; RowAddr(23 DOWNTO 16) := X"00"; getPage(RowAddr); getAddress(ColAddr); ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN RD_WCMD => IF falling_edge(write) THEN IF CLE = '1' AND ALE='0' AND Data = 16#30# AND ((ESUSP_ACT = '1' AND TmpBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN PGR_ACT <= '1'; PIPR_ACT <= '0'; FirstPipe := true; RdPage := TmpPage; RdBlck := TmpBlck; RdAddr := AddrWithinPage; RdSeg := TmpSegm; TR_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#31# AND ((ESUSP_ACT = '1' AND TmpBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN PPGR_ACT <= '1'; PGR_ACT <= '1'; RdPage := TmpPage; RdBlck := TmpBlck; RdAddr := AddrWithinPage; RdSeg := TmpSegm; TRP_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ELSIF CLE = '1' AND ALE='0' AND Data = 16#32# AND ESUSP_ACT='0' THEN PIPR_ACT <= '1'; IF FirstPipe = true THEN FirstPipe := false; ELSE RdPage := PIP_Page; RdBlck := PIP_Blck; RdAddr := PIP_Addr; END IF; PGR_ACT <= '1'; PIP_Page := TmpPage; PIP_Blck := TmpBlck; PIP_Addr := AddrWithinPage; TPT_in <= '1'; -- Time for pipeline read RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; OTPOverlay := OTPOverlayPIP; ELSIF CLE='1' AND ALE='0' AND Data = 16#33# AND ESUSP_ACT='0' THEN TPT_in <= '1'; -- Time for pipeline read PIPR_ACT <= '0'; FirstPipe := true; PGR_ACT <= '1'; RdAddr := PIP_Addr; RdPage := PIP_Page; RdBlck := PIP_Blck; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; OTPOverlay := OTPOverlayPIP; ELSIF CLE = '1' AND ALE='0' AND Data = 16#35# AND ((ESUSP_ACT = '1' AND TmpBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN PGD_ACT <= '1'; PGR_ACT <= '1'; TR_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; getPage(RowAddr); getAddress(ColAddr); RdPage := TmpPage; RdBlck := TmpBlck; RdAddr := AddrWithinPage; PDBuffer := (OTHERS => -1); ELSIF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN BUFF_TR => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# AND TPRE_in = '0' AND ESUSP_ACT = '0' THEN TR_in <= '0'; TRP_in <= '0'; TPT_in <= '0'; DBSY_in <= '0'; STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE = '1' AND ALE='0' AND Data = 16#70# THEN STAT_ACT <= '1'; END IF; ELSIF TR_out'event AND TR_out = '1' THEN PGR_ACT <= '0'; RY_zd <= '1'; Status(6 downto 5):= "11"; TR_in <= '0'; IF PGD_ACT = '1' THEN IF OTPOverlay AND RdBlck = 0 THEN IF RdPage <= 7 THEN PDBuffer := OTP_Area(RdPage); ELSE FOR i IN 0 TO PageSize LOOP PDBuffer(i) := 16#FFFF#; END LOOP; END IF; ELSE PDBuffer := Mem(RdPage); END IF; END IF; ELSIF TRP_out'event AND TRP_out = '1' THEN PGR_ACT <= '0'; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; TRP_in <= '0'; ELSIF TPT_out'event AND TPT_out = '1' THEN PGR_ACT <= '0'; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; TPT_in <= '0'; ELSIF TPRE_out'event AND TPRE_out = '1' THEN PGR_ACT <= '0'; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; TPRE_in <= '0'; RdPage := 0; RdBlck := 0; RdAddr := 0; RdSeg := 0; END IF; IF oe THEN IF PIPR_ACT='1' THEN IF OTPOverlay AND RdBlck = 0 THEN Read_OTP(RdAddr,RdPage); ELSE Read_Data(RdAddr,RdPage); END IF; ELSIF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN RD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN IF STAT_ACT = '1' THEN STAT_ACT <= '0'; ELSE PPGR_ACT <= '0'; PGD_ACT <= '0'; OTPOverlayPIP := OTPOverlay; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; END IF; ELSIF CLE = '1' AND ALE='0' AND Data = 16#70# THEN STAT_ACT <= '1'; ELSIF CLE = '1' AND ALE='0' AND Data = 16#90# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN STAT_ACT <= '0'; PPGR_ACT <= '0'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSIF CLE = '1' AND ALE='0' AND Data = 16#80# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN STAT_ACT <= '0'; PPGR_ACT <= '0'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#60# AND PGD_ACT = '0' AND PIPR_ACT = '0' THEN STAT_ACT <= '0'; PPGR_ACT <= '0'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE='1' AND ALE = '0' AND Data=16#FF# AND ESUSP_ACT = '0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE = '0' AND Data=16#85# AND PGD_ACT='1' THEN PPGR_ACT <= '0'; STAT_ACT <= '0'; ELSIF CLE='1' AND ALE = '0' AND Data=16#05# AND PGD_ACT = '0' AND PIPR_ACT='0' THEN STAT_ACT <= '0'; ELSIF CLE='1' AND ALE = '0' AND Data=16#B0# AND PGD_ACT = '0' AND PIPR_ACT='0' THEN IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; PPGR_ACT <= '0'; STAT_ACT <= '0'; ELSE STAT_ACT <= '0'; PGD_ACT <= '0'; PIPR_ACT <= '0'; END IF; END IF; IF oe THEN IF PGD_ACT='0' AND STAT_ACT='0' AND OTP_STAT_ACT = '0' THEN IF OTPOverlay AND RdBlck = 0 THEN Read_OTP(RdAddr,RdPage); ELSE Read_Data(RdAddr,RdPage); END IF; ELSIF OTP_STAT_ACT = '1' AND RdBlck = 0 THEN IF FirstByte THEN Dout_zd <= ProtStatus; FirstByte := false; ELSE IF OTPDefault = Overlaid THEN Dout_zd <= X"0000"; ELSE Dout_zd <= X"0001"; END IF; OTP_STAT_ACT <= '0'; END IF; ELSIF STAT_ACT='1' THEN Dout_zd <= Status; END IF; END IF; WHEN CAC_PREL => IF falling_edge(write) THEN IF ALE = '1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data = 16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A0_CAC => IF falling_edge(write) THEN IF ALE = '1' THEN ColAddr(15 DOWNTO 8) := AddrCom; ELSIF CLE='1' AND Data = 16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A1_CAC => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data = 16#E0# THEN getAddress(ColAddr); getSegment(AddrWithinPage, pom_seg); IF (pom_seg MOD 4) = RdSeg THEN RdAddr := AddrWithinPage; ELSE REPORT LF&"Changed address is not"&LF& " in same partial page" SEVERITY WARNING; END IF; ELSIF CLE='1' AND ALE='0' AND Data = 16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF ALE = '1' THEN END IF; END IF; WHEN ID_PREL => IF falling_edge(write) THEN IF ALE = '1' AND AddrCom = X"00" THEN IDAddr <= 0; ELSIF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END if; END IF; WHEN ID => IF falling_edge(write) THEN IF CLE ='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE='0' AND Data=16#80# THEN IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE='1' AND ALE='0' AND Data=16#60# THEN IF WPNeg = '1' THEN WriteProtect := false; ELSE WriteProtect := true; END IF; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSIF CLE='1' AND ALE='0' AND Data=16#00# THEN STAT_ACT <= '0'; END IF; END IF; IF oe THEN IF IDAddr < 6 THEN DOut_zd <= to_slv(IDArray(IDAddr),16); IDAddr <= IDAddr+1; ELSE DOut_zd <= (OTHERS => 'Z'); END IF; END IF; WHEN PREL_PRG => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN A0_PRG => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(15 DOWNTO 8) := AddrCom; getAddress(ColAddr); WrAddr := AddrWithinPage; WrSeg := TmpSegm; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN A1_PRG => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN A2_PRG => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(15 DOWNTO 8) := AddrCom; RowAddr(23 DOWNTO 16):= X"00"; getPage(RowAddr); WrPage := TmpPage; WrBlck := TmpBlck; CashBuffData := (OTHERS => -1); IF OTPOverlay AND WrBlck = 0 THEN IF WrPage <= 7 THEN SegForProg := OTPProgramedFlag(WrPage); END IF; ELSE SegForProg := ProgramedFlag(WrPage); END IF; SegProgSt:= "00000000"; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN DATA_PRG => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF ALE='0' AND CLE = '0' AND WrAddr <= PageSize THEN getSegment(WrAddr,WrSeg); IF OTPOverlay AND WrBlck = 0 THEN IF WrPage <= 7 THEN IF ProtStatus(WrPage) = '1' AND OTPProgramedFlag(WrPage)(WrSeg) = '0' THEN CashBuffData(WrAddr) := Data; SegForProg(WrSeg) := '1'; SegProgSt(WrSeg) := '1'; END IF; END IF; ELSE IF ProgramedFlag(WrPage)(WrSeg) = '0' THEN CashBuffData(WrAddr) := Data; SegForProg(WrSeg) := '1'; SegProgSt(WrSeg) := '1'; END IF; END IF; WrAddr := WrAddr+1; ELSIF CLE='1' AND ALE='0' AND Data=16#10# AND ((ESUSP_ACT = '1' AND WrBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN IF PRG_ACT = '0' THEN Tmp := SegProgSt(3 DOWNTO 0) OR SegProgSt(7 DOWNTO 4); tmp_cnt := 0; FOR i IN 0 TO 3 LOOP IF Tmp(i) = '1' THEN tmp_cnt := tmp_cnt + 1; END IF; END LOOP; IF tmp_cnt = 4 THEN prog_time := page_prog_time + tpd_WENeg_RY(tr10); ELSIF tmp_cnt = 0 THEN prog_time := 0 ns; ELSE prog_time := tmp_cnt * seg_prog_time + tpd_WENeg_RY(tr10); END IF; IF NOT(Protect) THEN PRG_ACT <= '1'; PROG_in <= '1'; ELSE DEF_OTP_in <= '1'; END IF; END IF; RY_zd <= '0'; Status(5) := '0'; firstFlag := true; ELSIF CLE = '1' AND ALE = '0' AND PGD_ACT = '0' AND Data = 16#15# AND ESUSP_ACT='0' THEN IF PRG_ACT = '0' THEN DBSY_in <= '1'; END IF; RY_zd <= '0'; Status(6) := '0'; firstFlag := true; END IF; ELSIF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; WHEN PGMS_CAC => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A0_PRG_CAC => IF falling_edge(write) THEN IF ALE = '1' THEN ColAddr(15 DOWNTO 8) := AddrCom; getAddress(ColAddr); WrAddr := AddrWithinPage; WrSeg := TmpSegm; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN WFPD => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; END if; ELSIF PROG1_out'event AND PROG1_out = '1' THEN DBSY1_in <= '1'; Status(5) := '1'; END IF; IF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN WFPPD => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; PROG1_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN Status(5) := '0'; PROG2_in <= '1'; PROG1_in <= '0'; Status(1 DOWNTO 0) := "00"; Tmp := SegProgSt(3 DOWNTO 0) OR SegProgSt(7 DOWNTO 4); tmp_cnt := 0; FOR i IN 0 TO 3 LOOP IF Tmp(i) = '1' THEN tmp_cnt := tmp_cnt + 1; END IF; END LOOP; IF tmp_cnt = 4 THEN prog_time := page_prog_time; ELSIF tmp_cnt = 0 THEN prog_time := 0 ns; ELSE prog_time := tmp_cnt * seg_prog_time; END IF; IF WPNeg /= '0' AND NOT(WriteProtect) THEN IF OTPOverlay AND ProgBlck = 0 THEN IF ProgPage <= 7 THEN FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProtStatus(ProgPage) = '1' AND WrBuffData(j) /= -1 AND OTPProgramedFlag(ProgPage)(pom_seg) = '0' THEN OTP_Area(ProgPage)(j):=WrBuffData(j); END IF; END LOOP; OTPProgramedFlag(ProgPage) :=CashSegForProg; ELSE Status(0) := '1'; END IF; ELSE FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProgramedFlag(ProgPage)(pom_seg)='0' AND WrBuffData(j) /= -1 THEN Mem(ProgPage)(j):= WrBuffData(j); END IF; END LOOP; ProgramedFlag(ProgPage) := CashSegForProg; END IF; END IF; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN PGMS => IF WPNeg /= '0' AND NOT(WriteProtect) AND firstFlag THEN firstFlag := false; IF NOT(Protect) THEN IF OTPOverlay AND WrBlck = 0 THEN IF WrPage <= 7 THEN FOR i IN 0 TO PageSize LOOP getSegment(i,WrSeg); IF ProtStatus(WrPage) = '1' AND CashBuffData(i) /= -1 THEN IF OTPProgramedFlag(WrPage)(WrSeg) = '0' THEN OTP_Area(WrPage)(i) := -1; ELSE CashBuffData(i) := -1; END IF; END IF; END LOOP; END IF; ELSE FOR i IN 0 TO PageSize LOOP getSegment(i,WrSeg); IF ProgramedFlag(WrPage)(WrSeg) = '0' AND CashBuffData(i) /= -1 THEN Mem(WrPage)(i):= -1; ELSE CashBuffData(i) := -1; END IF; END LOOP; END IF; END IF; WrBuffData := CashBuffData; ProgPage := WrPage; ProgBlck := WrBlck; END IF; IF PROG_out'event AND PROG_out = '1' THEN RY_zd <= '1'; PGD_ACT <= '0'; ELSIF PROG2_out'event AND PROG2_out = '1' THEN RY_zd <= '1'; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN RY_zd <= '1'; END IF; IF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN PRG_ACT <= '0'; Status(5) := '1'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(1 DOWNTO 0) := "00"; IF WPNeg /= '0' AND NOT(WriteProtect) AND NOT(Protect) THEN IF OTPOverlay AND ProgBlck = 0 THEN IF ProgPage <= 7 THEN FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProtStatus(ProgPage) = '1' AND WrBuffData(j) /= -1 AND OTPProgramedFlag(ProgPage)(pom_seg) = '0' THEN OTP_Area(ProgPage)(j):=WrBuffData(j); END IF; END LOOP; OTPProgramedFlag(ProgPage) := SegForProg; ELSE Status(0) := '1'; END IF; ELSE FOR j IN 0 TO PageSize LOOP getSegment(j,pom_seg); IF ProgramedFlag(ProgPage)(pom_seg)='0' AND WrBuffData(j) /= -1 THEN Mem(ProgPage)(j):= WrBuffData(j); END IF; END LOOP; ProgramedFlag(ProgPage) := SegForProg; END IF; END IF; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSIF rising_edge(DEF_OTP_out) THEN IF WPNeg /= '0' AND NOT(WriteProtect) AND Protect THEN ProtStatus(ProgPage) := '0'; Protect := false; Status(5) := '1'; Status(0) := '1'; END IF; DEF_OTP_in <= '0'; END IF; IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; Protect := false; DEF_OTP_in <= '0'; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; -- read status END IF; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN CBSY => IF firstFlag THEN Status(6) := '0'; firstFlag := false; CWrPage := WrPage; END IF; IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data=16#FF# THEN DBSY_in <= '0'; DBSY1_in <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF CLE='1' AND ALE='0' AND Data=16#70# THEN STAT_ACT <= '1'; -- read status END IF; ELSIF DBSY_out'event AND DBSY_out = '1' THEN IF WPNeg /= '0' AND NOT(WriteProtect) THEN IF OTPOverlay AND WrBlck = 0 THEN IF CWrPage <= 7 THEN IF ProtStatus(CWrPage) = '1' THEN FOR i IN 0 TO PageSize LOOP IF CashBuffData(i) /= -1 THEN OTP_Area(CWrPage)(i) := -1; END IF; END LOOP; END IF; END IF; ELSE FOR i IN 0 TO PageSize LOOP IF CashBuffData(i) /= -1 THEN Mem(CWrPage)(i):= -1; END IF; END LOOP; END IF; END IF; PRG_ACT <= '1'; PROG1_in <= '1' ; Tmp := SegProgSt(3 DOWNTO 0) OR SegProgSt(7 DOWNTO 4); tmp_cnt := 0; FOR i IN 0 TO 3 LOOP IF Tmp(i) = '1' THEN tmp_cnt := tmp_cnt + 1; END IF; END LOOP; IF tmp_cnt = 4 THEN prog_time := page_prog_time; ELSIF tmp_cnt = 0 THEN prog_time := 0 ns; ELSE prog_time := tmp_cnt * seg_prog_time; END IF; Status(6) := '1'; Status(5) := '0'; RY_zd <= '1'; DBSY_in <= '0'; Status(6) := '1'; ProgPage := CWrPage; ProgBlck := WrBlck; WrBuffData := CashBuffData; CashSegForProg := SegForProg; ELSIF DBSY1_out'event AND DBSY1_out = '1' THEN IF WPNeg /= '0' AND NOT(WriteProtect) THEN IF OTPOverlay AND WrBlck = 0 THEN IF CWrPage <= 7 THEN IF ProtStatus(CWrPage) = '1' THEN FOR i IN 0 TO PageSize LOOP IF CashBuffData(i) /= -1 THEN OTP_Area(CWrPage)(i) := -1; END IF; END LOOP; END IF; END IF; ELSE FOR i IN 0 TO PageSize LOOP IF CashBuffData(i) /= -1 THEN Mem(CWrPage)(i):= -1; END IF; END LOOP; END IF; END IF; PRG_ACT <= '1'; PROG1_in <= '1' ; Tmp := SegProgSt(3 DOWNTO 0) OR SegProgSt(7 DOWNTO 4); tmp_cnt := 0; FOR i IN 0 TO 3 LOOP IF Tmp(i) = '1' THEN tmp_cnt := tmp_cnt + 1; END IF; END LOOP; IF tmp_cnt = 4 THEN prog_time := page_prog_time; ELSIF tmp_cnt = 0 THEN prog_time := 0 ns; ELSE prog_time := tmp_cnt * seg_prog_time; END IF; Status(6) := '1'; Status(5) := '0'; RY_zd <= '1'; DBSY1_in <= '0'; Status(6) := '1'; ProgPage := CWrPage; ProgBlck := WrBlck; WrBuffData := CashBuffData; CashSegForProg := SegForProg; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN RDY_PRG => IF falling_edge(write) THEN IF CLE='1' AND ALE='0' AND Data = 16#70# THEN STAT_ACT <= '1'; ELSIF CLE='1' AND ALE='0' AND Data = 16#80# THEN STAT_ACT <= '0'; ELSIF CLE='1' AND ALE='0' AND Data=16#FF# THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; PROG_in <= '0'; PROG1_in <= '0'; PROG2_in <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSE STAT_ACT <= '0'; END IF; ELSIF PROG1_out'event AND PROG1_out = '1' THEN RY_zd <= '1'; Status(5) := '1'; END IF; IF rising_edge(PROG_out) OR rising_edge(PROG1_out) OR rising_edge(PROG2_out) THEN EndProgramming; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN PREL_ERS => IF falling_edge(write) THEN IF ALE = '1' THEN RowAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A1_ERS => IF falling_edge(write) THEN IF ALE = '1' THEN RowAddr(15 DOWNTO 8) := AddrCom; RowAddr(23 DOWNTO 16) := X"00"; ELSIF CLE = '1' AND Data = 16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A2_ERS => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ESUSP_ACT='0' THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ELSIF ALE = '0' AND CLE = '1'AND Data = 16#D0# AND WPNeg /= '0' AND NOT(WriteProtect)THEN IF ESUSP_ACT = '0' THEN getPage(RowAddr); ErsBlck := TmpBlck; IF OTPOverlay AND ErsBlck = 0 THEN IF ProtStatus(7 DOWNTO 0) = "11111111" THEN FOR i IN 0 TO 7 LOOP OTP_Area(i) := (OTHERS => -1); OTPProgramedFlag(i) := (OTHERS => '0'); END LOOP; END IF; ELSE FOR i IN ErsBlck * PageNumInBl TO (ErsBlck*PageNumInBl)+BlockSize LOOP Mem(i) := (OTHERS => -1); ProgramedFlag(i) := (OTHERS => '0'); END LOOP; END IF; ESTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ERS_PRESUS_in <= '1'; ELSE RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1) := '0'; Status(0) := '0'; ESUSP_ACT <= '0'; ERES <= '1', '0' AFTER 1 ns; ERS_PRESUS_in <= '1'; END IF; END IF; END IF; WHEN ERS_EXEC => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# AND ERS_PRESUS_in='0' THEN ERS_SUSP_in <= '1'; STAT_ACT <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN STAT_ACT <= '1'; END IF; ELSIF rising_edge(EDONE) THEN IF OTPOverlay AND ErsBlck = 0 THEN IF ProtStatus(7 DOWNTO 0) = "11111111" THEN FOR i IN 0 TO 7 LOOP OTP_Area(i) := (OTHERS => MaxData); OTPProgramedFlag(i) := (OTHERS => '0'); END LOOP; END IF; ELSE FOR i IN ErsBlck * PageNumInBl TO (ErsBlck*PageNumInBl)+BlockSize LOOP Mem(i) := (OTHERS => MaxData); ProgramedFlag(i) := (OTHERS => '0'); END LOOP; END IF; RY_zd <= '1'; ERS_PRESUS_in <= '0'; Status(6 DOWNTO 5) := "11"; Status(1 DOWNTO 0) := "00"; IF OTPDefault = Overlaid THEN OTPOverlay := true; ELSE OTPOverlay := false; END IF; ELSIF rising_edge(ERS_PRESUS_out) THEN ERS_PRESUS_in <= '0'; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN ERS_SUSP => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; STAT_ACT <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; ERS_SUSP_in <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#70# THEN STAT_ACT <= '1'; END IF; ELSIF ERS_SUSP_out'event AND ERS_SUSP_out = '1' THEN ESUSP <= '1', '0' AFTER 1 ns; ESUSP_ACT <= '1'; ERS_SUSP_in <= '0'; Status(6 DOWNTO 5) := "11"; Status(1 DOWNTO 0) := "11"; RY_zd <= '1'; END IF; IF oe THEN IF STAT_ACT = '1' THEN Dout_zd <= Status; END IF; END IF; WHEN PGD_PREL => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A0_PGD => IF falling_edge(write) THEN IF ALE='1' THEN ColAddr(15 DOWNTO 8) := AddrCom; getAddress(ColAddr); WrAddr := AddrWithinPage; WrSeg := TmpSegm; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A1_PGD => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(7 DOWNTO 0) := AddrCom; ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A2_PGD => IF falling_edge(write) THEN IF ALE='1' THEN RowAddr(15 DOWNTO 8) := AddrCom; RowAddr(23 DOWNTO 16):= X"00"; getPage(RowAddr); WrPage := TmpPage; WrBlck := TmpBlck; CashBuffData := PDBuffer; SegForProg := (OTHERS => '1'); SegProgSt := (OTHERS => '1'); ELSIF CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN A3_PGD => IF falling_edge(write) THEN IF ALE='0' AND CLE='0' AND WrAddr <= PageSize THEN getSegment(WrAddr,WrSeg); IF ProgramedFlag(WrPage)(WrSeg) = '0' THEN CashBuffData(WrAddr) := Data; END IF; SegForProg(WrSeg) := '1'; WrAddr := WrAddr+1; ELSIF ALE='0'AND CLE='1' AND Data=16#10# AND ((ESUSP_ACT = '1' AND WrBlck /= ErsBlck) OR ESUSP_ACT = '0') THEN prog_time := page_prog_time + tpd_WENeg_RY(tr10); PRG_ACT <= '1'; PROG_in <= '1'; RY_zd <= '0'; Status(5) := '0'; firstFlag := true; ELSIF ALE='0' AND CLE='1' AND Data=16#FF# AND ESUSP_ACT='0' THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN PREL_OTP => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#00# THEN OTPOverlay := true; OTP_in <= '1'; RY_zd <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#01# THEN OTPOverlay := false; OTP_in <= '1'; RY_zd <= '0'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#02# THEN OTP_STAT_ACT <= '1'; FirstByte := true; WAIT_OTP_in <= '1'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#03# THEN DEF_OTP_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#04# THEN DEF_OTP_in <= '1'; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#05# THEN WAIT_OTP_in <= '1'; ELSIF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; END IF; WHEN WAIT_STATE => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF WAIT_OTP_out'event AND WAIT_OTP_out = '1' THEN WAIT_OTP_in <= '0'; END IF; WHEN WAIT_STATE_1 => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF WAIT_OTP_out'event AND WAIT_OTP_out = '1' THEN WAIT_OTP_in <= '0'; Protect := true; OTPOverlay := true; END IF; WHEN WAIT_STATE_2 => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF OTP_out'event AND OTP_out = '1' THEN OTP_in <= '0'; RY_zd <= '1'; END IF; WHEN DEF_OVER => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN DEF_OTP_in <= '0'; IF NOT(SetDefault) THEN SetDefault := true; OTPDefault := Overlaid; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(0) := '0'; ELSE RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(0) := '1'; END IF; END IF; WHEN DEF_REM => IF falling_edge(write) THEN IF CLE = '1' AND ALE = '0' AND Data = 16#FF# THEN STAT_ACT <= '0'; RSTSTART <= '1', '0' AFTER 1 ns; RY_zd <= '0'; Status(6 DOWNTO 5) := "00"; Status(1 DOWNTO 0) := "00"; END IF; ELSIF DEF_OTP_out'event AND DEF_OTP_out = '1' THEN DEF_OTP_in <= '0'; IF NOT(SetDefault) THEN SetDefault := true; OTPDefault := Removed; RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(0) := '0'; ELSE RY_zd <= '1'; Status(6 DOWNTO 5) := "11"; Status(0) := '1'; END IF; END IF; WHEN OTHERS => NULL; END CASE; END IF; IF RENeg = '1' OR CENeg='1' THEN DOut_zd <= (OTHERS => 'Z'); END IF; END PROCESS Functional; pr1_buff: PROCESS (PROG1_in) IS BEGIN -- PROCESS dypr_buff IF PROG1_in'event AND PROG1_in = '1' THEN PROG1_out <= '1' AFTER prog_time; ELSIF PROG1_in'event AND PROG1_in='0' THEN PROG1_out <= '0'; END IF; END PROCESS pr1_buff; pr2_buff: PROCESS (PROG2_in) IS BEGIN -- PROCESS dypr_buff IF PROG2_in'event AND PROG2_in='1' THEN PROG2_out <= '1' AFTER prog_time; ELSIF PROG2_in'event AND PROG2_in='0' THEN PROG2_out <= '0'; END IF; END PROCESS pr2_buff; Normal_Prog: PROCESS (PROG_in) IS BEGIN IF rising_edge(PROG_in) THEN PROG_out <= '1' AFTER prog_time; ELSIF falling_edge (PROG_in) THEN PROG_out <= '0'; END IF; END PROCESS Normal_Prog; OTPDefault_Prog: PROCESS (DEF_OTP_in) IS BEGIN IF rising_edge(DEF_OTP_in) THEN DEF_OTP_out <= '1' AFTER tdevice_OTPD + tpd_WENeg_RY(tr10); ELSIF falling_edge (DEF_OTP_in) THEN DEF_OTP_out <= '0'; END IF; END PROCESS OTPDefault_Prog; WAIT_OTP_prot: PROCESS (WAIT_OTP_in) IS BEGIN IF rising_edge(WAIT_OTP_in) THEN WAIT_OTP_out <= '1' AFTER tpd_WENeg_RY(tr10); ELSIF falling_edge (WAIT_OTP_in) THEN WAIT_OTP_out <= '0'; END IF; END PROCESS WAIT_OTP_prot; WAIT_OTP: PROCESS (OTP_in) IS BEGIN IF rising_edge(OTP_in) THEN OTP_out <= '1' AFTER tdevice_OTP + tpd_WENeg_RY(tr10); ELSIF falling_edge (OTP_in) THEN OTP_out <= '0'; END IF; END PROCESS WAIT_OTP; Page_Read: PROCESS (TR_in) IS BEGIN IF rising_edge(TR_in) THEN IF (Long_Timming = TRUE) THEN TR_out <= '0','1' AFTER tdevice_TR; ELSE TR_out <= '0','1' AFTER tdevice_TR/5; END IF; ELSE TR_out <= '0'; END IF; END PROCESS Page_Read; Partial_Read: PROCESS (TRP_in) IS BEGIN IF rising_edge(TRP_in) THEN IF (Long_Timming = TRUE) THEN TRP_out <= '0','1' AFTER tdevice_TRP; ELSE TRP_out <= '0','1' AFTER tdevice_TRP/1; END IF; ELSE TRP_out <= '0'; END IF; END PROCESS Partial_Read; Pipeline_Read: PROCESS (TPT_in) IS BEGIN IF rising_edge(TPT_in) THEN IF (Long_Timming = TRUE) THEN TPT_out <= '0','1' AFTER tdevice_TPT; ELSE TPT_out <= '0','1' AFTER tdevice_TPT/5; END IF; ELSE TPT_out <= '0'; END IF; END PROCESS Pipeline_Read; DBSYTime: PROCESS (DBSY_in) IS BEGIN IF rising_edge(DBSY_in) THEN IF (Long_Timming = TRUE) THEN DBSY_out <= '0','1' AFTER (tdevice_DBSY+tpd_WENeg_RY(tr10)); ELSE DBSY_out <= '0','1' AFTER (tdevice_DBSY+tpd_WENeg_RY(tr10))/1; END IF; ELSE DBSY_out <= '0'; END IF; END PROCESS DBSYTime; DBSY1Time: PROCESS (DBSY1_in) IS BEGIN IF rising_edge(DBSY1_in) THEN IF (Long_Timming = TRUE) THEN DBSY1_out <= '0','1' AFTER (tdevice_DBSY+tpd_WENeg_RY(tr10)); ELSE DBSY1_out <= '0','1' AFTER (tdevice_DBSY+tpd_WENeg_RY(tr10))/1; END IF; ELSE DBSY1_out <= '0'; END IF; END PROCESS DBSY1Time; SuspendTime: PROCESS (ERS_SUSP_in) IS BEGIN IF rising_edge(ERS_SUSP_in) THEN IF (Long_Timming = TRUE) THEN ERS_SUSP_out <= '0','1' AFTER tdevice_SUSP; ELSE ERS_SUSP_out <= '0','1' AFTER tdevice_SUSP/1; END IF; ELSE ERS_SUSP_out <= '0'; END IF; END PROCESS SuspendTime; PreSuspendTime: PROCESS (ERS_PRESUS_in) IS BEGIN IF rising_edge(ERS_PRESUS_in) THEN IF (Long_Timming = TRUE) THEN ERS_PRESUS_out <= '0','1' AFTER tdevice_PRESUS + tpd_WENeg_RY(tr10); ELSE ERS_PRESUS_out <= '0','1' AFTER tdevice_PRESUS/1 + tpd_WENeg_RY(tr10); END IF; ELSE ERS_PRESUS_out <= '0'; END IF; END PROCESS PreSuspendTime; PRETime: PROCESS (TPRE_in) IS BEGIN IF rising_edge(TPRE_in) THEN IF (Long_Timming = TRUE) THEN TPRE_out <= '0','1' AFTER (tdevice_TPRE - 10 us); ELSE TPRE_out <= '0','1' AFTER (tdevice_TPRE - 10 us)/20; END IF; ELSE TPRE_out <= '0'; END IF; END PROCESS PRETime; IDPreload: PROCESS (PoweredUp) IS BEGIN -- PROCESS IDPreload IF PoweredUp='1' THEN IDArray(0) := 16#01#; IDArray(1) := 16#91#; IDArray(2) := 16#01#; IDArray(3) := 16#00#; IDArray(4) := 16#22#; IDArray(5) := 16#00#; END IF; END PROCESS IDPreload; -- purpose: Memory preload process -- inputs : PoweredUp MemPreload: PROCESS (PoweredUp) -- text file input variable FILE mem_file : text IS mem_file_name; FILE OTP_file : text IS OTP_file_name; FILE protOTP_file : text IS protOTP_file_name; VARIABLE buf : line; VARIABLE i : natural; VARIABLE ind : natural; VARIABLE pind : natural; VARIABLE index : natural; VARIABLE p_data : NATURAL; VARIABLE segment : NATURAL; VARIABLE over : BOOLEAN; BEGIN -- PROCESS MemPreload IF PoweredUp = '1' THEN ProgramedFlag := (OTHERS => (OTHERS => '0')); OTPProgramedFlag := (OTHERS => (OTHERS => '0')); Mem := (OTHERS => (OTHERS => MaxData)); OTP_Area := (OTHERS => (OTHERS => MaxData)); ProtStatus := "0000000011111111"; ------------------------------------------------------------------- -- Memory preload file format for s30ms ------------------------------------------------------------------- -- / - comment -- @aaaaaaaa - stands for page address and address within -- first 1056 words of a page -- dddd - is word to be written at Mem(Page)(offset++) -- page is div 1056 -- offset is mod 1056 -- offset is incremented on every write ------------------------------------------------------------------- IF mem_file_name /= "none" THEN ind := 0; WHILE (NOT ENDFILE (mem_file)) LOOP READLINE(mem_file,buf); IF buf(1)='/' THEN next; ELSIF buf(1) = '@' THEN ind := h(buf(2 TO 8)); ELSE p_data := h(buf(1 TO 4)); IF ind = 0 THEN pind := 0; index := 0; ELSIF ind <= PageSize THEN pind := 0; index := ind; ELSE pind := natural(ind/(PageSize+1)); index := ind - pind * (PageSize+1); END IF; IF pind <= PageNum AND index <= PageSize THEN IF p_data /= 16#FFFF# THEN Mem(pind)(index) := h(buf(1 TO 4)); END IF; getSegment(index,segment); ProgramedFlag(pind)(segment) := '1'; ind := ind + 1; ELSE REPORT "Memory address out of range"; END IF; END IF; END LOOP; END IF; ------------------------------------------------------------------- -- Memory preload file format for s30ms ------------------------------------------------------------------- -- / - comment -- @aaaa - stands for page address and address within -- first 1056 words of a page -- dddd - is word to be written at Mem(Page)(offset++) -- page is div 1056 -- offset is mod 1056 -- offset is incremented on every write ------------------------------------------------------------------- IF OTP_file_name /= "none" THEN ind := 0; WHILE (NOT ENDFILE (OTP_file)) LOOP READLINE(OTP_file,buf); IF buf(1)='/' THEN next; ELSIF buf(1) = '@' THEN ind := h(buf(2 TO 5)); ELSE p_data := h(buf(1 TO 4)); IF ind = 0 THEN pind := 0; index := 0; ELSIF ind <= PageSize THEN pind := 0; index := ind; ELSE pind := natural(ind/(PageSize+1)); index := ind - pind * (PageSize+1); END IF; IF pind <= OTPPageNum AND index <= PageSize THEN IF p_data /= 16#FFFF# THEN OTP_Area(pind)(index) := h(buf(1 TO 4)); END IF; getSegment(index,segment); OTPProgramedFlag(pind)(segment) := '1'; ind := ind + 1; ELSE REPORT "Memory address out of range"; END IF; END IF; END LOOP; END IF; IF protOTP_file_name /= "none" THEN ind := 0; WHILE (not ENDFILE (protOTP_file) AND not over) LOOP READLINE (protOTP_file, buf); IF buf(1) = '/' THEN --comment NEXT; ELSIF buf(1) = '@' THEN --sector number ind := h(buf(2 TO 2)); ELSE IF (buf(1) = '1') THEN IF ind <= OTPPageNum THEN ProtStatus(ind) := '0'; END IF; END IF; IF ind < OTPPageNum THEN ind := ind + 1; ELSE over := true; END IF; END IF; END LOOP; END IF; END IF; END PROCESS MemPreload; RPassTrough: PROCESS (RY_zd) IS BEGIN -- PROCESS RPassTrough IF RY_zd = '0' THEN RY_Pass <= '0'; ELSE RY_Pass <= 'Z'; END IF; END PROCESS RPassTrough; --------------------------------------------------------------------------- -- Path delay section --------------------------------------------------------------------------- PROCESS (RY_Pass) VARIABLE RY_GlitchData : VitalGlitchDataType; BEGIN -- PROCESS VitalPathDelay01( OutSignal => RY, OutSignalName => "RY", OutTemp => RY_Pass, GlitchData => RY_GlitchData, Mode => VitalTransport, Paths => ( 0 =>(InputChangeTime => WENeg'LAST_EVENT, PathDelay => tpd_WENeg_RY, PathCondition => true) ) ); END PROCESS; D_Out_Path_Gen : FOR i IN 0 TO 15 GENERATE BEGIN -- GENERATE D_Out_Path_Gen PROCESS (DOut_zd(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; BEGIN -- PROCESS VitalPathDelay01Z( OutSignal => DOut(i), OutSignalName => "DOut", OutTemp => DOut_zd(i), GlitchData => D0_GlitchData, Mode => VitalTransport, Paths => ( 0 => (InputChangeTime => RENeg'LAST_EVENT, PathDelay => tpd_RENeg_IO0, PathCondition => true), 1 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_IO0, PathCondition => true) ) ); END PROCESS; END GENERATE D_Out_Path_Gen; END BLOCK Behavior; END ARCHITECTURE vhdl_behavioral_static_memory_allocation;