------------------------------------------------------------------------------- -- File name : hy27us16121m.vhd ------------------------------------------------------------------------------- -- Copyright (C) 2004 Free Model Foundry; http://www.FreeModelFoundry.com -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License version 2 as -- published by the Free Software Foundation. -- -- MODIFICATION HISTORY : -- -- version: | author: | mod date: | changes made: -- v1.0 N.Makljenovic 04 Oct 18 initial version ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: Library AMD -- Technology: Nand Technology Flash memory -- Part: hy27us16121m -- -- Description: 512Mbit (32M x16-Bit) NAND Flash Memory ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- 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 FOR hy27us16121m ------------------------------------------------------------------------------- ENTITY hy27us16121m IS GENERIC ( tipd_IO0 : VitalDelayType01 := VitalZeroDelay01; tipd_IO1 : VitalDelayType01 := VitalZeroDelay01; tipd_IO2 : VitalDelayType01 := VitalZeroDelay01; tipd_IO3 : VitalDelayType01 := VitalZeroDelay01; tipd_IO4 : VitalDelayType01 := VitalZeroDelay01; tipd_IO5 : VitalDelayType01 := VitalZeroDelay01; tipd_IO6 : VitalDelayType01 := VitalZeroDelay01; tipd_IO7 : VitalDelayType01 := VitalZeroDelay01; tipd_IO8 : VitalDelayType01 := VitalZeroDelay01; tipd_IO9 : VitalDelayType01 := VitalZeroDelay01; tipd_IO10 : VitalDelayType01 := VitalZeroDelay01; tipd_IO11 : VitalDelayType01 := VitalZeroDelay01; tipd_IO12 : VitalDelayType01 := VitalZeroDelay01; tipd_IO13 : VitalDelayType01 := VitalZeroDelay01; tipd_IO14 : VitalDelayType01 := VitalZeroDelay01; tipd_IO15 : VitalDelayType01 := VitalZeroDelay01; tipd_ALE : VitalDelayType01 := VitalZeroDelay01; tipd_CLE : 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; tpd_RENeg_IO0 : VitalDelayType01Z := UnitDelay01Z; tpd_RENeg_RBNeg : VitalDelayType01Z := UnitDelay01Z; tpd_WENeg_RBNeg : VitalDelayType01Z := UnitDelay01Z; -- tsetup delays tsetup_IO0_WENeg : VitalDelayType := UnitDelay; tsetup_ALE_WENeg : VitalDelayType := UnitDelay; tsetup_CLE_WENeg : VitalDelayType := UnitDelay; tsetup_CENeg_WENeg : VitalDelayType := UnitDelay; tsetup_RENeg_WENeg : VitalDelayType := UnitDelay; tsetup_ALE_RENeg_noedge_RD_ES_EQ_0 : VitalDelayType := UnitDelay; tsetup_ALE_RENeg_noedge_RD_ES_EQ_1 : VitalDelayType := UnitDelay; tsetup_CLE_RENeg : VitalDelayType := UnitDelay; --thold delays thold_IO0_WENeg : VitalDelayType := UnitDelay; thold_ALE_WENeg : VitalDelayType := UnitDelay; thold_CLE_WENeg : VitalDelayType := UnitDelay; thold_CENeg_WENeg : VitalDelayType := UnitDelay; thold_RENeg_WENeg : VitalDelayType := UnitDelay; thold_RENeg_RBNeg : VitalDelayType := UnitDelay; --tpw values tpw_WENeg_negedge : VitalDelayType := UnitDelay; tpw_WENeg_posedge : VitalDelayType := UnitDelay; tpw_RENeg_negedge : VitalDelayType := UnitDelay; tpw_RENeg_posedge : VitalDelayType := UnitDelay; tpw_CENeg_posedge : VitalDelayType := UnitDelay; -- tdevice values: values for internal delays tdevice_TRDone : VitalDelayType := 12 us; tdevice_TWDone : VitalDelayType := 500 us; tdevice_TEDone : VitalDelayType := 3 ms; tdevice_TCDone : VitalDelayType := 3 us; tdevice_TRReset : VitalDelayType := 5 us; tdevice_TWReset : VitalDelayType := 10 us; tdevice_TEReset : VitalDelayType := 500 us; -- 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"; bbl_file_name : STRING := "none"; LongTiming : BOOLEAN := TRUE; UserPreload : BOOLEAN := TRUE; SeqRow_en : 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'; IO11 : INOUT std_ulogic := 'U'; 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'; IO3 : INOUT std_ulogic := 'U'; IO2 : INOUT std_ulogic := 'U'; IO1 : INOUT std_ulogic := 'U'; IO0 : INOUT std_ulogic := 'U'; CENeg : IN std_ulogic := 'U'; ALE : IN std_ulogic := 'U'; RENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; CLE : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; RBNeg : OUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of hy27us16121m : ENTITY IS TRUE; END hy27us16121m; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of hy27us16121m IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "hy27us16121m"; CONSTANT MaxData : NATURAL := 16#FFFF#; CONSTANT BlMSize : NATURAL := 8192; -- block Memory size CONSTANT BlSSize : NATURAL := 256; -- block Spare size CONSTANT BlNum : NATURAL := 4096; CONSTANT PgNum : NATURAL := 32; CONSTANT PgMSize : NATURAL := 256; CONSTANT PgSSize : NATURAL := 8; -- 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 CENeg_ipd : std_ulogic := 'U'; SIGNAL RENeg_ipd : std_ulogic := 'U'; SIGNAL WENeg_ipd : std_ulogic := 'U'; SIGNAL ALE_ipd : std_ulogic := 'U'; SIGNAL CLE_ipd : std_ulogic := 'U'; SIGNAL WPNeg_ipd : std_ulogic := 'U'; --- internal delays SIGNAL RDone_in : std_ulogic := '0'; SIGNAL RDone : std_ulogic := '0'; -- Device Read Buffer done SIGNAL WDone_in : std_ulogic := '0'; SIGNAL WDone : std_ulogic := '0'; -- Device Page write done SIGNAL EDone_in : std_ulogic := '0'; SIGNAL EDone : std_ulogic := '0'; -- Device Block erase SIGNAL RReset_in : std_ulogic := '0'; SIGNAL RReset : std_ulogic := '0'; -- Device reset during write SIGNAL WReset_in : std_ulogic := '0'; -- read buffer SIGNAL WReset : std_ulogic := '0'; -- Device reset during program SIGNAL EReset_in : std_ulogic := '0'; SIGNAL EReset : std_ulogic := '0'; -- Device reset during erase SIGNAL Cache_in : std_ulogic := '0'; SIGNAL Cache : std_ulogic := '0'; SIGNAL CDone_in : std_ulogic := '0'; SIGNAL CDone : std_ulogic := '0'; -- Device Cache Done SIGNAL PWrite_in : std_ulogic := '0'; SIGNAL PWrite : std_ulogic := '0'; -- write period SIGNAL BErase_in : std_ulogic := '0'; SIGNAL BErase : std_ulogic := '0'; -- erase period SHARED VARIABLE tdevice_Cache : VitalDelayType := 0 us; SHARED VARIABLE tdevice_Write : VitalDelayType := 0 us; SHARED VARIABLE tdevice_Erase : VitalDelayType := 0 us; BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays TEDone :VitalBuf(EDone, EDone_in, (tdevice_TEDone ,UnitDelay)); TWDone :VitalBuf(WDone, WDone_in, (tdevice_TWDone ,UnitDelay)); TRDone :VitalBuf(RDone, RDone_in, (tdevice_TRDone ,UnitDelay)); TCDone :VitalBuf(CDone, CDone_in, (tdevice_TCDone ,UnitDelay)); TEReset :VitalBuf(EReset, EReset_in, (tdevice_TEReset ,UnitDelay)); TWReset :VitalBuf(WReset, WReset_in, (tdevice_TWReset ,UnitDelay)); TRReset :VitalBuf(RReset, RReset_in, (tdevice_TRReset ,UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN 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 (RENeg_ipd, RENeg, tipd_RENeg); w_18 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_19 : VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg); w_20 : VitalWireDelay (ALE_ipd, ALE, tipd_ALE); w_21 : VitalWireDelay (CLE_ipd, CLE, tipd_CLE); w_22 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg); END BLOCK; --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK PORT ( IOin : IN std_logic_vector(15 DOWNTO 0) := (OTHERS => 'U'); IOOut : OUT std_logic_vector(15 DOWNTO 0) := (OTHERS => 'Z'); CENeg : IN std_ulogic := 'U'; ALE : IN std_ulogic := 'U'; RENeg : IN std_ulogic := 'U'; WENeg : IN std_ulogic := 'U'; WPNeg : IN std_ulogic := 'U'; CLE : IN std_ulogic := 'U'; RBNeg : OUT std_ulogic := 'U' ); PORT MAP ( IOin(15) => IO15_ipd, IOin(14) => IO14_ipd, IOin(13) => IO13_ipd, IOin(12) => IO12_ipd, IOin(11) => IO11_ipd, IOin(10) => IO10_ipd, IOin(9) => IO9_ipd, IOin(8) => IO8_ipd, IOin(7) => IO7_ipd, IOin(6) => IO6_ipd, IOin(5) => IO5_ipd, IOin(4) => IO4_ipd, IOin(3) => IO3_ipd, IOin(2) => IO2_ipd, IOin(1) => IO1_ipd, IOin(0) => IO0_ipd, IOOut(15) => IO15, IOOut(14) => IO14, IOOut(13) => IO13, IOOut(12) => IO12, IOOut(11) => IO11, IOOut(10) => IO10, IOOut(9) => IO9, IOOut(8) => IO8, IOOut(7) => IO7, IOOut(6) => IO6, IOOut(5) => IO5, IOOut(4) => IO4, IOOut(3) => IO3, IOOut(2) => IO2, IOOut(1) => IO1, IOOut(0) => IO0, CENeg => CENeg_ipd, ALE => ALE_ipd, RENeg => RENeg_ipd, WENeg => WENeg_ipd, WPNeg => WPNeg_ipd, CLE => CLE, RBNeg => RBNeg ); TYPE Bus_Type IS (CommandState_Input, Address_Input, Data_Input, Data_Output, Write_Protect, Standby); SHARED VARIABLE BusCycle : Bus_Type; TYPE CommandState_type IS (POWER_UP, PROGRAM_START, ERASE, PAGE_PROGRAM, COPY_BACK_PROGRAM, COPY_BACK, CACHE_PROGRAM, CACHE_START, BLOCK_ERASE, RESET); TYPE ReadState_type IS ( READ_A, READ_C, READ_ELECTRONIC, READ_STATUS, RESET); SIGNAL CommandState : CommandState_type; SHARED VARIABLE LastState : CommandState_type; SIGNAL ReadState : ReadState_type; TYPE PageMArray IS ARRAY (0 TO PgMSize-1) OF INTEGER; TYPE PageSArray IS ARRAY (0 TO PgSSize-1) OF INTEGER; TYPE BlockMArray IS ARRAY (0 TO PgNum-1) OF PageMArray; TYPE BlockSprMemArray IS ARRAY (0 TO PgNum-1) OF PageSArray; TYPE MemArray IS ARRAY (0 TO BlNum-1) OF BlockMArray; TYPE SprMemArray IS ARRAY (0 TO BlNum-1) OF BlockSprMemArray; TYPE ReadType IS (MemorySp, SpareSp); TYPE BadPageArray IS ARRAY(0 TO BlNum-1) OF std_logic_vector(31 DOWNTO 0); -- Mem SHARED VARIABLE Mem : MemArray := (OTHERS => (OTHERS => (OTHERS => MaxData))); SHARED VARIABLE SprMem : SprMemArray := (OTHERS => (OTHERS => (OTHERS => MaxData))); SHARED VARIABLE PageMBuf : PageMArray := (OTHERS => MaxData); SHARED VARIABLE PageSBuf : PageSArray := (OTHERS => MaxData); SHARED VARIABLE TempMBuf : PageMArray := (OTHERS => MaxData); SHARED VARIABLE TempSBuf : PageSArray := (OTHERS => MaxData); SHARED VARIABLE BadPage : BadPageArray := (OTHERS => (OTHERS => '0')); SIGNAL ProgMPag : BadPageArray := (OTHERS => (OTHERS => '0')); SIGNAL ProgSPag : BadPageArray := (OTHERS => (OTHERS => '0')); -- powerup SIGNAL PoweredUp : std_logic := '0'; --zero delay signals SIGNAL IOOut_zd : std_logic_vector(15 DOWNTO 0) := (OTHERS =>'Z'); SIGNAL RBNeg_zd : std_logic := '1'; SIGNAL IOOut_pass : std_logic_vector(15 DOWNTO 0); -- Write Commnad Signal SIGNAL WCmd : std_logic := '0'; -- Write Address Signal SIGNAL WAddr : std_logic := '0'; -- Write Data Signal SIGNAL WData : std_logic := '0'; -- Read Data Signal SIGNAL RData : std_logic := '0'; SIGNAL read_busy : std_logic := '0'; SIGNAL page_busy : std_logic := '0'; SIGNAL rd_start : std_logic := '0'; SIGNAL ready_reset : std_logic := '0'; --Address SHARED VARIABLE Address : NATURAL :=0; SHARED VARIABLE Bla : NATURAL :=0; SHARED VARIABLE Bla_cb : NATURAL :=0; SHARED VARIABLE Page : NATURAL :=0; SHARED VARIABLE addr_cnt : NATURAL := 0; SHARED VARIABLE Address_tmp : std_logic_vector(24 DOWNTO 0) := (OTHERS => '0'); SIGNAL addr_ev : std_logic := '0'; SIGNAL viol : std_logic := '0'; SIGNAL Status_reg : std_logic_vector(7 DOWNTO 0) := (OTHERS => '0'); SHARED VARIABLE PointMain : BOOLEAN := TRUE; -- temp RBNeg signal SIGNAL RBNeg_sig : std_logic; SHARED VARIABLE FROMOE,FROMCE, OPENLATCH : boolean; SHARED VARIABLE tpd_from_OE : BOOLEAN := FALSE; SHARED VARIABLE tpd_from_CE : BOOLEAN := FALSE; SHARED VARIABLE Open3state : BOOLEAN := FALSE; BEGIN --------------------------------------------------------------------------- --Power Up time 100 ns; --------------------------------------------------------------------------- PoweredUp <= '1' AFTER 100 ns; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck: PROCESS(CENeg, ALE, WENeg, RENeg, CLE, RBNeg_sig, IOin) --Setup/Hold checks variables VARIABLE Tviol_IO0_WENeg : X01 := '0'; VARIABLE Tviol_ALE_WENeg_ST : X01 := '0'; VARIABLE Tviol_ALE_WENeg_HD : X01 := '0'; VARIABLE Tviol_CLE_WENeg_ST : X01 := '0'; VARIABLE Tviol_CLE_WENeg_HD : X01 := '0'; VARIABLE Tviol_CENeg_WENeg_ST : X01 := '0'; VARIABLE Tviol_CENeg_WENeg_HD : X01 := '0'; VARIABLE Tviol_RENeg_WENeg : X01 := '0'; VARIABLE Tviol_ALE_RENeg_RD_ES_0 : X01 := '0'; VARIABLE Tviol_ALE_RENeg_RD_ES_1 : X01 := '0'; VARIABLE Tviol_CLE_RENeg : X01 := '0'; VARIABLE Tviol_RENeg_RBNeg : X01 := '0'; VARIABLE TD_IO0_WENeg : VitalTimingDataType; VARIABLE TD_ALE_WENeg_ST : VitalTimingDataType; VARIABLE TD_ALE_WENeg_HD : VitalTimingDataType; VARIABLE TD_CLE_WENeg_ST : VitalTimingDataType; VARIABLE TD_CLE_WENeg_HD : VitalTimingDataType; VARIABLE TD_CENeg_WENeg_ST : VitalTimingDataType; VARIABLE TD_CENeg_WENeg_HD : VitalTimingDataType; VARIABLE TD_RENeg_WENeg : VitalTimingDataType; VARIABLE TD_ALE_RENeg_RD_ES_0 : VitalTimingDataType; VARIABLE TD_ALE_RENeg_RD_ES_1 : VitalTimingDataType; VARIABLE TD_CLE_RENeg : VitalTimingDataType; VARIABLE TD_RENeg_RBNeg : VitalTimingDataType; -- Pulse width cheks variables VARIABLE Pviol_WENeg : X01 := '0'; VARIABLE Pviol_RENeg : X01 := '0'; VARIABLE Pviol_CENeg : X01 := '0'; VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_RENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE PD_CENeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01; BEGIN IF TimingChecksOn THEN Violation := '0'; VitalSetupHoldCheck ( TestSignal => IOin, TestSignalName => "IO", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_IO0_WENeg, SetupLow => tsetup_IO0_WENeg, HoldHigh => thold_IO0_WENeg, HoldLow => thold_IO0_WENeg, CheckEnabled => ALE = '0' OR CLE = '0', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_IO0_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_IO0_WENeg ); VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_ALE_WENeg, SetupHigh => tsetup_ALE_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_ALE_WENeg_ST, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_ALE_WENeg_ST ); VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => WENeg, RefSignalName => "WENeg", HoldLow => thold_ALE_WENeg, HoldHigh => thold_ALE_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_ALE_WENeg_HD, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_ALE_WENeg_HD ); VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => WENeg, RefSignalName => "WENeg", SetupHigh => tsetup_CLE_WENeg, SetupLow => tsetup_CLE_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_CLE_WENeg_ST, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CLE_WENeg_ST ); VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => WENeg, RefSignalName => "WENeg", HoldHigh => thold_CLE_WENeg, HoldLow => thold_CLE_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CLE_WENeg_HD, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CLE_WENeg_HD ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", SetupLow => tsetup_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_WENeg_ST, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_WENeg_ST ); VitalSetupHoldCheck ( TestSignal => CENeg, TestSignalName => "CENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldLow => thold_CENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CENeg_WENeg_HD, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CENeg_WENeg_HD ); VitalSetupHoldCheck ( TestSignal => RENeg, TestSignalName => "RENeg", RefSignal => WENeg, RefSignalName => "WENeg", HoldHigh => thold_RENeg_WENeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_RENeg_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_RENeg_WENeg ); VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => RENeg, RefSignalName => "RENeg", SetupLow => tsetup_ALE_RENeg_noedge_RD_ES_EQ_0, CheckEnabled => CommandState = RESET, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_ALE_RENeg_RD_ES_0, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_ALE_RENeg_RD_ES_0 ); VitalSetupHoldCheck ( TestSignal => ALE, TestSignalName => "ALE", RefSignal => RENeg, RefSignalName => "RENeg", SetupLow => tsetup_ALE_RENeg_noedge_RD_ES_EQ_1, CheckEnabled => ReadState = READ_ELECTRONIC, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_ALE_RENeg_RD_ES_1, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_ALE_RENeg_RD_ES_1 ); VitalSetupHoldCheck ( TestSignal => CLE, TestSignalName => "CLE", RefSignal => RENeg, RefSignalName => "RENeg", SetupLow => tsetup_CLE_RENeg, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_CLE_RENeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CLE_RENeg ); VitalSetupHoldCheck ( TestSignal => RENeg, TestSignalName => "RENeg", RefSignal => RBNeg_sig, RefSignalName => "RBNeg", HoldHigh => thold_RENeg_RBNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_RENeg_RBNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_RENeg_RBNeg ); VitalPeriodPulseCheck ( TestSignal => WENeg, TestSignalName => "WENeg", PulseWidthLow => tpw_WENeg_negedge, PulseWidthHigh => tpw_WENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_WENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_WENeg ); VitalPeriodPulseCheck ( TestSignal => RENeg, TestSignalName => "RENeg", PulseWidthLow => tpw_RENeg_negedge, PulseWidthHigh => tpw_RENeg_posedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, PeriodData => PD_RENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_RENeg ); VitalPeriodPulseCheck ( TestSignal => CENeg, TestSignalName => "CENeg", PulseWidthHigh => tpw_CENeg_posedge, CheckEnabled => ALE='0' AND CLE='0', HeaderMsg => InstancePath & PartID, PeriodData => PD_CENeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CENeg ); Violation := Tviol_IO0_WENeg OR Tviol_ALE_WENeg_ST OR Tviol_ALE_WENeg_HD OR Tviol_CLE_WENeg_ST OR Tviol_CLE_WENeg_HD OR Tviol_CENeg_WENeg_ST OR Tviol_CENeg_WENeg_HD OR Tviol_RENeg_WENeg OR Tviol_ALE_RENeg_RD_ES_0 OR Tviol_ALE_RENeg_RD_ES_1 OR Tviol_CLE_RENeg OR Tviol_RENeg_RBNeg OR Pviol_WENeg OR Pviol_RENeg OR Pviol_CENeg; ASSERT Violation = '0' REPORT InstancePath & partID & " simulation may be inaccurate due to timing violations" SEVERITY WARNING; viol <= violation; END IF; END PROCESS VITALTimingCheck; --------------------------------------------------------------------------- -- --------------------------------------------------------------------------- BusDecodeCycle : PROCESS(IOin, WENeg, CENeg, ALE, CLE, RENeg) VARIABLE Addr_latch : BOOLEAN := FALSE; BEGIN IF rising_edge(WENeg) THEN IF (CENeg = '0' AND ALE = '0' AND CLE = '1' AND RENeg = '1') THEN BusCycle := CommandState_Input; WCmd <= '1', '0' AFTER 1 ns; ELSIF (CENeg = '0' AND ALE = '1' AND CLE = '0' AND RENeg = '1') THEN BusCycle := Address_Input; WAddr <= '1', '0' AFTER 1 ns; ELSIF (CENeg = '0' AND ALE = '0' AND CLE = '0' AND RENeg = '1') THEN BusCycle := Data_Input; WData <= '1', '0' AFTER 1 ns; END IF; ELSIF ((falling_edge(RENeg) AND CENeg = '0') OR (falling_edge(CENeg) AND RENeg = '0')) AND (ALE = '0' AND CLE = '0' AND WENeg = '1') THEN BusCycle := Data_Output; RData <= '1', '0' AFTER 1 ns; END IF; END PROCESS BusDecodeCycle; AddressDecode : PROCESS(WAddr, WCmd) FUNCTION command_valid ( SIGNAL CommandState : CommandState_type; SIGNAL ReadState : ReadState_type; DataIn : NATURAL) RETURN BOOLEAN IS VARIABLE CommandData : NATURAL; BEGIN CommandData := DataIn; IF CommandData = 16#FF# THEN RETURN TRUE; ELSIF (CommandState = RESET OR CommandState = POWER_UP) AND (CommandData = 16#00# OR CommandData = 16#50# OR CommandData = 16#90# OR CommandData = 16#70# OR CommandData = 16#60# OR CommandData = 16#80# OR (CommandData = 16#8A# AND ReadState = READ_A)) THEN RETURN TRUE; ELSIF (CommandState = COPY_BACK AND CommandData = 16#10#) OR ((CommandState=PROGRAM_START OR CommandState=PROGRAM_START) AND (CommandData = 16#10# OR CommandData = 16#15#)) OR (CommandState = CACHE_PROGRAM AND CommandData = 16#80#) OR (CommandState = ERASE AND CommandData = 16#D0#) THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END FUNCTION command_valid; VARIABLE DataIn : NATURAL; BEGIN IF rising_edge(WCmd) THEN DataIn := to_nat(IOin(7 DOWNTO 0)); END IF; IF (rising_edge(WCmd) AND command_valid(CommandState,ReadState,DataIn)) OR (rising_edge(WAddr) AND CommandState = RESET AND addr_cnt = 4) THEN addr_cnt := 0; END IF; IF rising_edge(WAddr) AND RBNeg_zd /= '0' THEN IF addr_cnt = 0 THEN Address_tmp(7 DOWNTO 0) := IOin(7 DOWNTO 0); ELSIF addr_cnt = 1 THEN Address_tmp(15 DOWNTO 8) := IOin(7 DOWNTO 0); ELSIF addr_cnt = 2 THEN Address_tmp(23 DOWNTO 16) := IOin(7 DOWNTO 0); ELSIF addr_cnt = 3 THEN Address_tmp(24) := IOin(0); IF ReadState = READ_A OR ReadState = READ_C THEN rd_start <= '1', '0' AFTER 1 ns; END IF; END IF; addr_cnt := addr_cnt+1; addr_ev <= '1', '0' AFTER 1 ns; END IF; END PROCESS AddressDecode; SetAddrProc : PROCESS(addr_ev) BEGIN IF CommandState = RESET AND addr_cnt = 4 THEN -- set address for read Bla := to_nat(Address_tmp(24 DOWNTO 13)); Page := to_nat(Address_tmp(12 DOWNTO 8)); Address := to_nat(Address_tmp(7 DOWNTO 0)); ELSIF addr_cnt = 3 AND (CommandState = ERASE OR CommandState = COPY_BACK OR CommandState = CACHE_START OR CommandState = PROGRAM_START) THEN -- set address for erase Bla := to_nat(Address_tmp(16 DOWNTO 5)); Page := to_nat(Address_tmp(4 DOWNTO 0)); END IF; END PROCESS; CommandStateDecode : PROCESS(WCmd, PWrite, BErase, Cache) VARIABLE addr_cnt : NATURAL; VARIABLE CommandData : NATURAL; BEGIN IF rising_edge(WCmd) THEN CommandData := to_nat(IOin); IF WPNEG = '0' AND ((CommandState = ERASE AND CommandData = 16#D0#) OR ((CommandState = PROGRAM_START OR CommandState = CACHE_START) AND (CommandData = 16#10# OR CommandData = 16#15#))) THEN CommandData := 16#FF#; END IF; END IF; IF (RReset_in = '0' AND WReset_in = '0' AND EReset_in = '0') THEN IF rising_edge(WCmd) AND CommandData = 16#FF# THEN IF CommandState = RESET THEN ready_reset <= '1', '0' AFTER 1 ns; END IF; CommandState <= RESET; ReadState <= RESET; ELSE CASE CommandState IS WHEN RESET | POWER_UP => IF rising_edge(WCmd) AND RBNeg_zd /= '0' THEN IF CommandData = 16#00# THEN ReadState <= READ_A; CommandState <= RESET; END IF; IF CommandData = 16#50# THEN ReadState <= READ_C; CommandState <= RESET; END IF; IF CommandData = 16#90# THEN ReadState <= READ_ELECTRONIC; CommandState <= RESET; END IF; IF CommandData = 16#60# THEN CommandState <= ERASE; ReadState <= RESET; END IF; IF CommandData = 16#80# THEN CommandState <= PROGRAM_START; ReadState <= RESET; END IF; IF CommandData = 16#8A# AND ReadState = READ_A THEN CommandState <= COPY_BACK; ReadState <= RESET; END IF; END IF; IF rising_edge(WCmd) AND CommandData = 16#70# THEN ReadState <= READ_STATUS; CommandState <= RESET; END IF; WHEN COPY_BACK => IF rising_edge(WCmd) AND CommandData = 16#10# THEN IF 2*Bla_cb/BLNum=2*Bla/BLNum THEN CommandState <= COPY_BACK_PROGRAM; ELSE CommandState <= RESET; END IF; END IF; WHEN COPY_BACK_PROGRAM => IF rising_edge(WCmd) AND CommandData = 16#70# THEN ReadState <= READ_STATUS; ELSIF rising_edge(PWrite) THEN CommandState <= RESET; END IF; WHEN PROGRAM_START => IF rising_edge(WCmd) THEN IF CommandData = 16#10# THEN CommandState <= PAGE_PROGRAM; ELSIF CommandData = 16#15# THEN CommandState <= CACHE_PROGRAM; END IF; END IF; WHEN PAGE_PROGRAM => IF rising_edge(WCmd) AND CommandData = 16#70# THEN ReadState <= READ_STATUS; ELSIF (rising_edge(PWrite) AND Cache_in = '0') OR (rising_edge(Cache) AND PWrite_in = '0') THEN CommandState <= RESET; END IF; WHEN CACHE_PROGRAM => IF rising_edge(WCmd) AND CommandData = 16#70# THEN ReadState <= READ_STATUS; ELSIF rising_edge(WCmd) AND Cache_in = '0' AND CommandData = 16#80# THEN CommandState <= CACHE_START; ReadState <= RESET; ELSIF (rising_edge(PWrite) AND Cache_in = '0') OR (rising_edge(Cache) AND PWrite_in = '0') THEN CommandState <= RESET; END IF; WHEN CACHE_START => IF rising_edge(WCmd) THEN IF CommandData = 16#10# THEN CommandState <= PAGE_PROGRAM; ELSIF CommandData = 16#15# THEN CommandState <= CACHE_PROGRAM; END IF; END IF; WHEN ERASE => IF rising_edge(WCmd) AND CommandData = 16#D0# THEN CommandState <= BLOCK_ERASE; END IF; WHEN BLOCK_ERASE => IF rising_edge(WCmd) AND CommandData = 16#70# THEN ReadState <= READ_STATUS; ELSIF rising_edge(BErase) THEN CommandState <= RESET; END IF; END CASE; END IF; END IF; END PROCESS CommandStateDecode; ReadDecode : PROCESS(IOin, RData, RENeg, WENeg, CENeg, ReadState) VARIABLE addr_cnt : NATURAL; VARIABLE Address_mem : NATURAL; VARIABLE Address_SprMem : NATURAl; VARIABLE oe : BOOLEAN := FALSE; VARIABLE ReadSpace : ReadType; PROCEDURE ReadMem (VARIABLE ReadSpace : ReadType := MemorySp) IS BEGIN IF ReadSpace = MemorySp THEN IF Mem(Bla)(Page)(Address)=-1 THEN IOOut_zd(15 DOWNTO 0) <= (OTHERS => 'X'); ELSE IOOut_zd(15 DOWNTO 0) <= to_slv(Mem(Bla)(Page)(Address),16); END IF; ELSE IF SprMem(Bla)(Page)(Address MOD PgSSize)=-1 THEN IOOut_zd(15 DOWNTO 0) <= (OTHERS => 'X'); ELSE IOOut_zd(15 DOWNTO 0) <= to_slv(SprMem(Bla)(Page)(Address MOD PgSSize),16); END IF; END IF; END PROCEDURE ReadMem; PROCEDURE Rd_elect_sig IS BEGIN IF Address MOD PgMSize = 16#00# THEN IOOut_zd <= X"00AD"; Address := Address + 1; ELSIF Address MOD PgMSize = 16#01# THEN IOOut_zd <= X"0056"; Address := Address + 1; ELSE IOOut_zd <= (OTHERS => 'X'); END IF; END PROCEDURE Rd_elect_sig; PROCEDURE Read_ST IS BEGIN IOOut_zd <= "ZZZZZZZZ" & Status_reg; END PROCEDURE Read_ST; PROCEDURE SetAddress (VARIABLE ReadSpace : INOUT ReadType) IS BEGIN Address := Address + 1; IF Address MOD PgMSize = 0 AND ReadSpace=MemorySp THEN ReadSpace := SpareSp; Address := 0; ELSIF Address MOD PgSSize = 0 AND ReadSpace=SpareSp THEN ReadSpace := MemorySp; Address := 0; END IF; END PROCEDURE SetAddress; BEGIN IF ReadState'event THEN IF ReadState = READ_A THEN ReadSpace := MemorySp; PointMain := TRUE; ELSIF ReadState = READ_C THEN ReadSpace := SpareSp; Address := Address MOD PgSSize; PointMain := FALSE; ELSIF ReadState = READ_ELECTRONIC THEN Address := to_nat(Address_tmp(7 DOWNTO 0)); END IF; END IF; IF rising_edge(RData) THEN IF ReadState = READ_A AND RBNeg_zd /= '0' THEN ReadMem(ReadSpace); SetAddress(ReadSpace); ELSIF ReadState = READ_C AND RBNeg_zd /= '0' THEN ReadMem(ReadSpace); Address := (Address + 1) MOD PgSSize; ELSIF ReadState = READ_ELECTRONIC THEN Rd_elect_sig; ELSIF ReadState = READ_STATUS THEN Read_ST; END IF; ELSIF (RENeg = '1' OR WENeg = '0' OR CENeg = '1') THEN IOOut_zd <= (OTHERS => 'Z'); END IF; -- set busy signal during read IF (rising_edge(RENeg) AND CENeg = '0' AND WENeg = '1') THEN IF Address = 0 AND ((ReadState = READ_A AND ReadSpace=MemorySp) OR ReadState = READ_C) THEN page_busy <= '1', '0' AFTER 1 ns; END IF; END IF; END PROCESS ReadDecode; read_busy <= rd_start OR page_busy; SeqRowCount : PROCESS(page_busy, RDone, CENeg) VARIABLE AutoSeq : BOOLEAN := FALSE; BEGIN IF rising_edge(page_busy) AND SeqRow_en AND CENeg = '0' THEN AutoSeq := TRUE; ELSIF rising_edge(RDone) THEN IF AutoSeq THEN IF Page + 1 = PgNum AND CommandState = POWER_UP THEN Page := 0; Bla := Bla +1 MOD BlNum; ELSE Page := (Page + 1) MOD PgNum; END IF; END IF; AutoSeq := FALSE; ELSIF rising_edge(CENeg) THEN AutoSeq := FALSE; END IF; END PROCESS SeqRowCount; RB_gen : PROCESS(read_busy, CommandState, ReadState, RDone, PWrite, BErase, Cache, RReset, WReset, EReset, PoweredUp, ready_reset) VARIABLE Prog_cont : BOOLEAN := FALSE; VARIABLE StateTmp : CommandState_type; BEGIN IF rising_edge(read_busy) OR rising_edge(PoweredUp) THEN RDone_in <= '1'; RBNeg_zd <= '0'; END IF; IF CommandState'event THEN LastState := StateTmp; StateTmp := CommandState; CASE CommandState IS WHEN PAGE_PROGRAM | COPY_BACK_PROGRAM => IF LastState = CACHE_START THEN tdevice_Cache := tdevice_TCDone + 2*tdevice_Write - PWrite_in'LAST_EVENT * to_nat(PWrite_in); Prog_cont := TRUE; Cache_in <= '1'; ELSE PWrite_in <= '1'; END IF; RBNeg_zd <= '0'; WHEN BLOCK_ERASE => BErase_in <= '1'; RBNeg_zd <= '0'; WHEN CACHE_PROGRAM => IF LastState = PROGRAM_START THEN tdevice_Cache := tdevice_TCDone; PWrite_in <= '1'; ELSE tdevice_Cache := tdevice_TCDone + tdevice_Write - PWrite_in'LAST_EVENT * to_nat(PWrite_in); Prog_cont := TRUE; END IF; Cache_in <= '1'; RBNeg_zd <= '0'; WHEN RESET => IF PWrite_in = '1' THEN PWrite_in <= '0'; Cache_in <= '0'; WReset_in <= '1'; RBNeg_zd <= '0'; ELSIF BErase_in = '1' THEN BErase_in <= '0'; EReset_in <= '1'; RBNeg_zd <= '0'; END IF; WHEN OTHERS => END CASE; END IF; IF rising_edge(ready_reset) THEN Rdone_in <= '0'; RReset_in <= '1'; RBNeg_zd <= '0'; END IF; IF (RDone'event AND RDone = '1') OR (BErase'event AND BErase = '1') OR rising_edge(RReset) OR rising_edge(WReset) OR rising_edge(EReset) THEN EReset_in <= '0'; RReset_in <= '0'; WReset_in <= '0'; Cache_in <= '0'; BErase_in <= '0'; RDone_in <= '0'; PWrite_in <= '0'; RBNeg_zd <= '1'; END IF; IF rising_edge(Cache) THEN EReset_in <= '0'; RReset_in <= '0'; WReset_in <= '0'; Cache_in <= '0'; BErase_in <= '0'; RDone_in <= '0'; RBNeg_zd <= '1'; END IF; IF rising_edge(PWrite) THEN EReset_in <= '0'; RReset_in <= '0'; WReset_in <= '0'; BErase_in <= '0'; RDone_in <= '0'; IF Cache_in = '1' THEN IF Prog_cont THEN PWrite_in <= '0', '1' AFTER 1 ns; Prog_cont := FALSE; ELSE PWrite_in <= '0'; END IF; ELSE PWrite_in <= '0'; RBNeg_zd <= '1'; END IF; END IF; END PROCESS RB_gen; StatusGen : PROCESS(RBNeg_zd, WPNeg, PWrite, PWrite_in, EReset_in, WReset_in , RReset_in, CommandState, BErase_in) VARIABLE Last_st : std_logic; BEGIN Status_reg(7) <= WPNeg; Status_reg(6) <= RBNeg_zd; Status_reg(5) <= RBNeg_zd; IF rising_edge(BErase_in) THEN Status_reg(0) <= '0'; FOR i IN 0 TO PgNum-1 LOOP IF BadPage(Bla)(i) = '1' THEN Status_reg(0) <= '1'; END IF; END LOOP; END IF; IF rising_edge(PWrite_in) THEN Last_st := Status_reg(0); Status_reg(0) <= BadPage(Bla)(Page); END IF; IF (CommandState = CACHE_PROGRAM OR CommandState = CACHE_START) THEN Status_reg(5) <= NOT PWrite_in; Status_reg(1) <= Last_st; END IF; IF EReset_in = '1' OR WReset_in = '1' OR RReset_in = '1' THEN Status_reg(6) <= '1'; Status_reg(0) <= '1'; END IF; END PROCESS StatusGen; Functional :PROCESS(CommandState, PWrite, BErase, WData) VARIABLE Prog_cont : BOOLEAN := FALSE; VARIABLE buf_cnt : NATURAL := 0; VARIABLE buf_pcnt : NATURAL := 0; VARIABLE Bla_er : NATURAL := 0; VARIABLE Bla_wr : NATURAL := 0; VARIABLE Page_wr : NATURAL := 0; PROCEDURE write_c( VARIABLE Bla : NATURAL; VARIABLE Page : NATURAL; VARIABLE i : IN INTEGER :=0) IS BEGIN IF ProgSPag(Bla)(Page) /= '1' THEN SprMem(Bla)(Page) := PageSBuf; ProgSPag(Bla)(Page) <= '1'; IF ProgSPag(Bla)(Page) = '0' THEN ProgSPag(Bla)(Page) <= 'H'; ELSE ProgSPag(Bla)(Page) <= '1'; END IF; END IF; END PROCEDURE write_c; PROCEDURE write_page( VARIABLE Bla : NATURAL; VARIABLE Page : NATURAL; VARIABLE buf_cnt : NATURAL) IS VARIABLE i_t : INTEGER :=0; BEGIN IF BadPage(Bla)(Page) = '0' THEN IF PointMain THEN IF ProgMPag(Bla)(Page) /= '1' THEN Mem(Bla)(Page) := PageMBuf; ProgMPag(Bla)(Page) <= '1'; END IF; IF PgMSize < buf_cnt THEN write_c(Bla, Page); END IF; ELSE write_c(Bla, Page); END IF; END IF; END PROCEDURE write_page ; BEGIN CASE CommandState IS WHEN COPY_BACK => IF CommandState'event THEN PageMBuf := Mem(Bla)(Page); PageSBuf := SprMem(Bla)(Page); Bla_cb := Bla; END IF; WHEN COPY_BACK_PROGRAM => IF CommandState'event THEN Mem(Bla)(Page) := (OTHERS => -1); SprMem(Bla)(Page) := (OTHERS => -1); Bla_wr := Bla; Page_wr := Page; buf_cnt := PgMSize + PgSSize - 1; END IF; IF rising_edge(PWrite) THEN write_page(Bla_wr, Page_wr, buf_cnt); END IF; WHEN BLOCK_ERASE => IF CommandState'event THEN Mem(Bla) := (OTHERS => (OTHERS => -1)); SprMem(Bla) := (OTHERS => (OTHERS => -1)); ProgMPag(Bla) <= (OTHERS => '1'); ProgSPag(Bla) <= (OTHERS => '1'); Bla_er := Bla; END IF; IF rising_edge(BErase) THEN FOR i IN 0 TO PgNum-1 LOOP IF BadPage(Bla_er)(i) = '0' THEN Mem(Bla_er)(i) := (OTHERS => MaxData); SprMem(Bla_er)(i) := (OTHERS => MaxData); ProgMPag(Bla_er)(i) <= '0'; ProgSPag(Bla_er)(i) <= '0'; END IF; END LOOP; END IF; WHEN PROGRAM_START | CACHE_START=> IF rising_edge(WData) THEN IF buf_pcnt <= PgMSize - 1 AND PointMain THEN TempMBuf(buf_pcnt) := to_nat(IOin); buf_pcnt := buf_pcnt + 1; ELSIF buf_pcnt <= PgMSize + PgSSize - 1 AND PointMain THEN TempSBuf(buf_pcnt-PgMSize) := to_nat(IOin); buf_pcnt := buf_pcnt + 1; ELSIF buf_pcnt <= PgSSize - 1 AND NOT PointMain THEN TempSBuf(buf_pcnt) := to_nat(IOin); buf_pcnt := buf_pcnt + 1; END IF; ELSIF rising_edge(PWrite) THEN write_page(Bla_wr, Page_wr, buf_cnt); ELSIF CommandState'Event THEN Prog_cont := TRUE; buf_pcnt := 0; TempMBuf := (OTHERS => MaxData); TempSBuf := (OTHERS => MaxData); END IF; WHEN PAGE_PROGRAM | CACHE_PROGRAM => IF rising_edge(PWrite) THEN write_page(Bla_wr, Page_wr, buf_cnt); END IF; IF (CommandState'event AND PWrite_in = '0') OR (LastState = CACHE_START AND rising_edge(PWrite) AND Prog_cont) THEN IF PointMain THEN Mem(Bla)(Page) := (OTHERS => -1); IF PgMSize < buf_pcnt THEN SprMem(Bla)(Page):=(OTHERS => -1); END IF; ELSE SprMem(Bla)(Page) :=(OTHERS => -1); END IF; Bla_wr := Bla; Page_wr := Page; buf_cnt := buf_pcnt; PageMBuf := TempMBuf; PageSBuf := TempSBuf; Prog_cont := FALSE; END IF; WHEN OTHERS => END CASE; END PROCESS Functional; TimingP : PROCESS(PoweredUp) BEGIN IF LongTiming THEN tdevice_Write := tdevice_TWDone; tdevice_Erase := tdevice_TEDone; ELSE tdevice_Write := tdevice_TWDone/2; tdevice_Erase := tdevice_TEDone/1000; END IF; END PROCESS TimingP; TPWrite : PROCESS(PWrite_in) BEGIN IF rising_edge(PWrite_in) THEN PWrite <= '1' AFTER tdevice_Write; ELSE PWrite <= '0' AFTER 1 ns; END IF; END PROCESS TPWrite; TBErase : PROCESS(BErase_in) BEGIN IF rising_edge(BErase_in) THEN BErase <= '1' AFTER tdevice_Erase; ELSE BErase <= '0' AFTER 1 ns; END IF; END PROCESS TBErase; TRCache : PROCESS(Cache_in) BEGIN IF rising_edge(Cache_in) THEN Cache <= '1' AFTER tdevice_Cache; ELSE Cache <= '0' AFTER 1 ns; END IF; END PROCESS TRCache; --------------------------------------------------------------------------- ---- File read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_f : text is mem_file_name; FILE bbl_f : text is bbl_file_name; VARIABLE addr_ind : NATURAL; VARIABLE Bla_ind : NATURAL; VARIABLE page_ind : NATURAL; VARIABLE offset : NATURAL; VARIABLE ind : NATURAL; VARIABLE buf : line; VARIABLE sect : NATURAL; VARIABLE report_err : BOOLEAN := FALSE; BEGIN ----------------------------------------------------------------------- -- Preload Control -- hy27ss16121 memory file -- / - comment -- @aaaa - stands for address -- dd -
is word to be written at Mem(aaaa++) -- (aaaa is incremented at every load) -- only first 1-8 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! ----------------------------------------------------------------------- IF UserPreload AND (mem_file_name /= "none" ) THEN addr_ind := 0; WHILE (not ENDFILE (mem_f)) LOOP READLINE (mem_f, buf); IF buf(1)='/' THEN --comment NEXT; ELSIF buf(1)='@' THEN --address addr_ind := h(buf(2 to 8)); Bla_ind := addr_ind / BlMSize; offset := addr_ind - (Bla_ind * BlMSize); page_ind := offset / PgMSize; offset := offset - (page_ind * PgMSize); ELSE IF addr_ind <= BlNum*BlMSize THEN Mem(Bla_ind)(page_ind)(offset):= h(buf(1 to 4)); addr_ind := (addr_ind + 1); Bla_ind := addr_ind / BlMSize; offset := addr_ind - (Bla_ind * BlMSize); page_ind := offset / PgMSize; offset := offset - (page_ind * PgMSize); ELSE IF report_err = FALSE THEN REPORT "Memory file:"&mem_file_name&"Addr range error" SEVERITY warning; report_err := TRUE; END IF; END IF; END IF; END LOOP; END IF; --------------------------------------------------------------------------- -- hy27ss16121 bad block file -- / - comment -- @aaaa - stands for address without last -- 8 bits (inter-page address) -- d - is bit that sign in bad page memory(aaaa++) and -- value different form FFFF in appropriate location of spare memory -- (aaaa is incremented at every load) -- only first 1-6 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! --------------------------------------------------------------------------- IF UserPreload AND (bbl_file_name /= "none" ) THEN addr_ind := 0; WHILE (not ENDFILE (bbl_f)) LOOP READLINE (bbl_f, buf); IF buf(1)='/' THEN --comment NEXT; ELSIF buf(1)='@' THEN --address addr_ind := h(buf(2 to 6)); Bla_ind := addr_ind / PgNum; offset := addr_ind - (Bla_ind * PgNum); page_ind := offset; ELSE IF addr_ind <= BlNum*PgNum THEN IF (buf(1) = '1') THEN BadPage(Bla_ind)(page_ind) := '1'; IF page_ind /= 0 THEN SprMem(Bla_ind)(0)(0) := 0; ELSE SprMem(Bla_ind)(1)(0) := 0; END IF; END IF; addr_ind := (addr_ind + 1); Bla_ind := addr_ind / PgNum; offset := addr_ind - (Bla_ind * PgNum); page_ind := offset ; ELSE IF report_err = FALSE THEN REPORT "Memory file:"&mem_file_name&"Addr. range error" SEVERITY warning; report_err := TRUE; END IF; END IF; END IF; END LOOP; END IF; WAIT; END PROCESS; ----------------------------------------------------------------------- -- Path Delay Section ----------------------------------------------------------------------- IOOutPassThrough : PROCESS(IOOut_zd) VARIABLE tOD : time := 0 ns; VARIABLE tCD : time := 0 ns; BEGIN IF IOOut_zd(0) /= 'Z' THEN tpd_from_OE := FALSE; tpd_from_CE := FALSE; Open3state := TRUE; tOD := -RENeg'LAST_EVENT + tpd_RENeg_IO0(trz1); tCD := -CENeg'LAST_EVENT + tpd_CENeg_IO0(trz1); IF tOD >= tCD THEN tpd_from_OE := TRUE; ELSE tpd_from_CE := TRUE; END IF; IOOut_pass <= IOOut_zd; ELSE tpd_from_OE := TRUE; tpd_from_CE := TRUE; IF RENeg'LAST_EVENT = CENeg'LAST_EVENT THEN tpd_from_OE := FALSE; END IF; Open3state := FALSE; IOOut_Pass <= IOOut_zd; END IF; END PROCESS IOOutPassThrough; RBNeg_OUT: PROCESS(RBNeg_zd) VARIABLE RBNeg_GlitchData : VitalGlitchDataType; VARIABLE RBData : std_logic := '1'; BEGIN IF RBNeg_zd = '1' THEN RBData := 'Z'; ELSE RBDATA := '0'; END IF; VitalPathDelay01Z( OutSignal => RBNeg_sig, OutSignalName => "RBNeg", OutTemp => RBData, Mode => VitalTransport, GlitchData => RBNeg_GlitchData, Paths => ( 0 => (InputChangeTime => RENeg'LAST_EVENT, PathDelay => tpd_RENeg_RBNeg, PathCondition => TRUE), 1 => (InputChangeTime => WENeg'LAST_EVENT, PathDelay => tpd_WENeg_RBNeg, PathCondition => TRUE)) ); END PROCESS RBNeg_Out; RBNeg <= RBNeg_sig; --------------------------------------------------------------------------- -- Path Delay Section for IOOut signal --------------------------------------------------------------------------- D_Out_PathDelay_Gen : FOR i IN 0 TO 15 GENERATE --IOOut_zd'RANGE GENERATE PROCESS(IOOut_pass(i)) VARIABLE D0_GlitchData : VitalGlitchDataType; VARIABLE OE :boolean := false; BEGIN VitalPathDelay01Z( OutSignal => IOOut(i), OutSignalName => "IOOut", OutTemp => IOOut_pass(i), GlitchData => D0_GlitchData, IgnoreDefaultDelay => TRUE, Mode => VitalTransport, RejectFastPath => false, Paths => ( 0 => (InputChangeTime => RENeg'LAST_EVENT, PathDelay => tpd_RENeg_IO0, PathCondition => tpd_from_OE), 1 => (InputChangeTime => CENeg'LAST_EVENT, PathDelay => tpd_CENeg_IO0, PathCondition => tpd_from_CE) ) ); END PROCESS; END GENERATE D_Out_PathDelay_Gen; END BLOCK behavior; END vhdl_behavioral;