------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
-- File name : testbench_640.vhd
|
-- File name : testbench_640.vhd
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Copyright (C) 2003 AMD.
|
-- Copyright (C) 2003 AMD.
|
--
|
--
|
-- MODIFICATION HISTORY :
|
-- MODIFICATION HISTORY :
|
--
|
--
|
-- version: | author: | mod date: | changes made:
|
-- version: | author: | mod date: | changes made:
|
-- V0.1 M.Marinkovic 11 July 03 Initial
|
-- V0.1 M.Marinkovic 11 July 03 Initial
|
-- v0.2 M.Marinkovic 28 Aug 03 Changed protected sector selection
|
-- v0.2 M.Marinkovic 28 Aug 03 Changed protected sector selection
|
--
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- PART DESCRIPTION:
|
-- PART DESCRIPTION:
|
--
|
--
|
-- Description:
|
-- Description:
|
-- Generic test enviroment for verification of AMD flash memory
|
-- Generic test enviroment for verification of AMD flash memory
|
-- VITAL models.my_mem
|
-- VITAL models.my_mem
|
--
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Note: VHDL code formating not done
|
-- Note: VHDL code formating not done
|
-- For High/Low sector protection selection change:
|
-- For High/Low sector protection selection change:
|
-- TimingModel constant and TimingModel generic value
|
-- TimingModel constant and TimingModel generic value
|
--
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
LIBRARY IEEE;
|
LIBRARY IEEE;
|
USE IEEE.std_logic_1164.ALL;
|
USE IEEE.std_logic_1164.ALL;
|
--USE IEEE.VITAL_timing.ALL;
|
--USE IEEE.VITAL_timing.ALL;
|
--USE IEEE.VITAL_primitives.ALL;
|
--USE IEEE.VITAL_primitives.ALL;
|
USE STD.textio.ALL;
|
USE STD.textio.ALL;
|
|
|
LIBRARY VITAL2000;
|
LIBRARY VITAL2000;
|
USE VITAL2000.vital_timing.ALL;
|
USE VITAL2000.vital_timing.ALL;
|
USE VITAL2000.vital_primitives.ALL;
|
USE VITAL2000.vital_primitives.ALL;
|
|
|
LIBRARY FMF;
|
LIBRARY FMF;
|
USE FMF.gen_utils.ALL;
|
USE FMF.gen_utils.ALL;
|
USE FMF.conversions.ALL;
|
USE FMF.conversions.ALL;
|
|
|
|
|
LIBRARY work;
|
LIBRARY work;
|
USE work.amd_tc_pkg.ALL;
|
USE work.amd_tc_pkg.ALL;
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- ENTITY DECLARATION
|
-- ENTITY DECLARATION
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
ENTITY testbench_640 IS
|
ENTITY testbench_640 IS
|
END testbench_640;
|
END testbench_640;
|
|
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- ARCHITECTURE DECLARATION
|
-- ARCHITECTURE DECLARATION
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
ARCHITECTURE vhdl_behavioral of testbench_640 IS
|
ARCHITECTURE vhdl_behavioral of testbench_640 IS
|
COMPONENT my_mem
|
COMPONENT my_mem
|
GENERIC (
|
GENERIC (
|
-- tipd delays: interconnect path delays
|
-- tipd delays: interconnect path delays
|
tipd_A0 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A0 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A1 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A1 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A2 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A2 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A3 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A3 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A4 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A4 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A5 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A5 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A6 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A6 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A7 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A7 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A8 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A8 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A9 : VitalDelayType01 := VitalZeroDelay01; --address
|
tipd_A9 : VitalDelayType01 := VitalZeroDelay01; --address
|
tipd_A10 : VitalDelayType01 := VitalZeroDelay01; --lines
|
tipd_A10 : VitalDelayType01 := VitalZeroDelay01; --lines
|
tipd_A11 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A11 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A12 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A12 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A13 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A13 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A14 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A14 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A15 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A15 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A16 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A16 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A17 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A17 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A18 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A18 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A19 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A19 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A20 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A20 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A21 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_A21 : VitalDelayType01 := VitalZeroDelay01; --
|
|
|
tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; -- data
|
tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; -- data
|
tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; -- lines
|
tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; -- lines
|
tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; --
|
tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; --
|
|
|
tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; -- DQ15/A-1
|
tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; -- DQ15/A-1
|
|
|
tipd_CENeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_CENeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_OENeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_OENeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_WENeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_WENeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_RESETNeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; --WP#/ACC
|
tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01; --WP#/ACC
|
tipd_BYTENeg : VitalDelayType01 := VitalZeroDelay01;
|
tipd_BYTENeg : VitalDelayType01 := VitalZeroDelay01;
|
|
|
-- tpd delays
|
-- tpd delays
|
tpd_A0_DQ0 : VitalDelayType01 := UnitDelay01;--tACC
|
tpd_A0_DQ0 : VitalDelayType01 := UnitDelay01;--tACC
|
tpd_A0_DQ1 : VitalDelayType01 := UnitDelay01;--tPACC
|
tpd_A0_DQ1 : VitalDelayType01 := UnitDelay01;--tPACC
|
tpd_CENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z;
|
tpd_CENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z;
|
--(tCE,tCE,tDF,-,tDF,-)
|
--(tCE,tCE,tDF,-,tDF,-)
|
tpd_OENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z;
|
tpd_OENeg_DQ0 : VitalDelayType01Z := UnitDelay01Z;
|
--(tOE,tOE,tDF,-,tDF,-)
|
--(tOE,tOE,tDF,-,tDF,-)
|
tpd_RESETNeg_DQ0 : VitalDelayType01Z := UnitDelay01Z;
|
tpd_RESETNeg_DQ0 : VitalDelayType01Z := UnitDelay01Z;
|
--(-,-,0,-,0,-)
|
--(-,-,0,-,0,-)
|
tpd_CENeg_RY : VitalDelayType01 := UnitDelay01; --tBUSY
|
tpd_CENeg_RY : VitalDelayType01 := UnitDelay01; --tBUSY
|
tpd_WENeg_RY : VitalDelayType01 := UnitDelay01; --tBUSY
|
tpd_WENeg_RY : VitalDelayType01 := UnitDelay01; --tBUSY
|
|
|
--tsetup values
|
--tsetup values
|
tsetup_A0_CENeg : VitalDelayType := UnitDelay; --tAS edge \
|
tsetup_A0_CENeg : VitalDelayType := UnitDelay; --tAS edge \
|
tsetup_A0_OENeg : VitalDelayType := UnitDelay; --tASO edge \
|
tsetup_A0_OENeg : VitalDelayType := UnitDelay; --tASO edge \
|
tsetup_DQ0_CENeg : VitalDelayType := UnitDelay; --tDS edge /
|
tsetup_DQ0_CENeg : VitalDelayType := UnitDelay; --tDS edge /
|
|
|
--thold values
|
--thold values
|
thold_CENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH edge /
|
thold_CENeg_RESETNeg: VitalDelayType := UnitDelay; --tRH edge /
|
thold_OENeg_WENeg : VitalDelayType := UnitDelay; --tOEH edge /
|
thold_OENeg_WENeg : VitalDelayType := UnitDelay; --tOEH edge /
|
thold_A0_CENeg : VitalDelayType := UnitDelay; --tAH edge \
|
thold_A0_CENeg : VitalDelayType := UnitDelay; --tAH edge \
|
thold_A0_OENeg : VitalDelayType := UnitDelay; --tAHT edge \
|
thold_A0_OENeg : VitalDelayType := UnitDelay; --tAHT edge \
|
thold_DQ0_CENeg : VitalDelayType := UnitDelay; --tDH edge /
|
thold_DQ0_CENeg : VitalDelayType := UnitDelay; --tDH edge /
|
thold_WENeg_OENeg : VitalDelayType := UnitDelay; --tGHWL edge /
|
thold_WENeg_OENeg : VitalDelayType := UnitDelay; --tGHWL edge /
|
|
|
--tpw values: pulse width
|
--tpw values: pulse width
|
tpw_RESETNeg_negedge: VitalDelayType := UnitDelay; --tRP
|
tpw_RESETNeg_negedge: VitalDelayType := UnitDelay; --tRP
|
tpw_OENeg_posedge : VitalDelayType := UnitDelay; --tOEPH
|
tpw_OENeg_posedge : VitalDelayType := UnitDelay; --tOEPH
|
tpw_WENeg_negedge : VitalDelayType := UnitDelay; --tWP
|
tpw_WENeg_negedge : VitalDelayType := UnitDelay; --tWP
|
tpw_WENeg_posedge : VitalDelayType := UnitDelay; --tWPH
|
tpw_WENeg_posedge : VitalDelayType := UnitDelay; --tWPH
|
tpw_CENeg_negedge : VitalDelayType := UnitDelay; --tCP
|
tpw_CENeg_negedge : VitalDelayType := UnitDelay; --tCP
|
tpw_CENeg_posedge : VitalDelayType := UnitDelay; --tCEPH
|
tpw_CENeg_posedge : VitalDelayType := UnitDelay; --tCEPH
|
tpw_A0_negedge : VitalDelayType := UnitDelay; --tWC tRC
|
tpw_A0_negedge : VitalDelayType := UnitDelay; --tWC tRC
|
|
|
|
|
-- tdevice values: values for internal delays
|
-- tdevice values: values for internal delays
|
--Effective Write Buffer Program Operation tWHWH1
|
--Effective Write Buffer Program Operation tWHWH1
|
tdevice_WBPB : VitalDelayType := 11 us;
|
tdevice_WBPB : VitalDelayType := 11 us;
|
--Program Operation
|
--Program Operation
|
tdevice_POB : VitalDelayType := 100 us;
|
tdevice_POB : VitalDelayType := 100 us;
|
--Sector Erase Operation tWHWH2
|
--Sector Erase Operation tWHWH2
|
tdevice_SEO : VitalDelayType := 500 ms;
|
tdevice_SEO : VitalDelayType := 500 ms;
|
--Timing Limit Exceeded
|
--Timing Limit Exceeded
|
tdevice_HANG : VitalDelayType := 400 ms; --?
|
tdevice_HANG : VitalDelayType := 400 ms; --?
|
--program/erase suspend timeout
|
--program/erase suspend timeout
|
tdevice_START_T1 : VitalDelayType := 5 us;
|
tdevice_START_T1 : VitalDelayType := 5 us;
|
--sector erase command sequence timeout
|
--sector erase command sequence timeout
|
tdevice_CTMOUT : VitalDelayType := 50 us;
|
tdevice_CTMOUT : VitalDelayType := 50 us;
|
--device ready after Hardware reset(during embeded algorithm)
|
--device ready after Hardware reset(during embeded algorithm)
|
tdevice_READY : VitalDelayType := 20 us; --tReady
|
tdevice_READY : VitalDelayType := 20 us; --tReady
|
|
|
-- generic control parameters
|
-- generic control parameters
|
InstancePath : STRING := DefaultInstancePath;
|
InstancePath : STRING := DefaultInstancePath;
|
TimingChecksOn : BOOLEAN := DefaultTimingChecks;
|
TimingChecksOn : BOOLEAN := DefaultTimingChecks;
|
MsgOn : BOOLEAN := DefaultMsgOn;
|
MsgOn : BOOLEAN := DefaultMsgOn;
|
XOn : BOOLEAN := DefaultXon;
|
XOn : BOOLEAN := DefaultXon;
|
-- memory file to be loaded
|
-- memory file to be loaded
|
mem_file_name : STRING ;--:= "am29lv640m.mem";
|
mem_file_name : STRING ;--:= "am29lv640m.mem";
|
prot_file_name : STRING ;--:= "am29lv640m_prot.mem";
|
prot_file_name : STRING ;--:= "am29lv640m_prot.mem";
|
secsi_file_name : STRING ;--:= "am29lv_secsi.mem";
|
secsi_file_name : STRING ;--:= "am29lv_secsi.mem";
|
|
|
UserPreload : BOOLEAN ;--:= TRUE;
|
UserPreload : BOOLEAN ;--:= TRUE;
|
LongTimming : BOOLEAN ;--:= TRUE;
|
LongTimming : BOOLEAN ;--:= TRUE;
|
|
|
-- For FMF SDF technology file usage
|
-- For FMF SDF technology file usage
|
TimingModel : STRING --:= "AM29LV640MH90R"
|
TimingModel : STRING --:= "AM29LV640MH90R"
|
);
|
);
|
PORT (
|
PORT (
|
A21 : IN std_logic := 'U'; --
|
A21 : IN std_logic := 'U'; --
|
A20 : IN std_logic := 'U'; --
|
A20 : IN std_logic := 'U'; --
|
A19 : IN std_logic := 'U'; --
|
A19 : IN std_logic := 'U'; --
|
A18 : IN std_logic := 'U'; --
|
A18 : IN std_logic := 'U'; --
|
A17 : IN std_logic := 'U'; --
|
A17 : IN std_logic := 'U'; --
|
A16 : IN std_logic := 'U'; --
|
A16 : IN std_logic := 'U'; --
|
A15 : IN std_logic := 'U'; --
|
A15 : IN std_logic := 'U'; --
|
A14 : IN std_logic := 'U'; --
|
A14 : IN std_logic := 'U'; --
|
A13 : IN std_logic := 'U'; --address
|
A13 : IN std_logic := 'U'; --address
|
A12 : IN std_logic := 'U'; --lines
|
A12 : IN std_logic := 'U'; --lines
|
A11 : IN std_logic := 'U'; --
|
A11 : IN std_logic := 'U'; --
|
A10 : IN std_logic := 'U'; --
|
A10 : IN std_logic := 'U'; --
|
A9 : IN std_logic := 'U'; --
|
A9 : IN std_logic := 'U'; --
|
A8 : IN std_logic := 'U'; --
|
A8 : IN std_logic := 'U'; --
|
A7 : IN std_logic := 'U'; --
|
A7 : IN std_logic := 'U'; --
|
A6 : IN std_logic := 'U'; --
|
A6 : IN std_logic := 'U'; --
|
A5 : IN std_logic := 'U'; --
|
A5 : IN std_logic := 'U'; --
|
A4 : IN std_logic := 'U'; --
|
A4 : IN std_logic := 'U'; --
|
A3 : IN std_logic := 'U'; --
|
A3 : IN std_logic := 'U'; --
|
A2 : IN std_logic := 'U'; --
|
A2 : IN std_logic := 'U'; --
|
A1 : IN std_logic := 'U'; --
|
A1 : IN std_logic := 'U'; --
|
A0 : IN std_logic := 'U'; --
|
A0 : IN std_logic := 'U'; --
|
|
|
DQ15 : INOUT std_logic := 'U'; -- DQ15/A-1
|
DQ15 : INOUT std_logic := 'U'; -- DQ15/A-1
|
DQ14 : INOUT std_logic := 'U'; --
|
DQ14 : INOUT std_logic := 'U'; --
|
DQ13 : INOUT std_logic := 'U'; --
|
DQ13 : INOUT std_logic := 'U'; --
|
DQ12 : INOUT std_logic := 'U'; --
|
DQ12 : INOUT std_logic := 'U'; --
|
DQ11 : INOUT std_logic := 'U'; --
|
DQ11 : INOUT std_logic := 'U'; --
|
DQ10 : INOUT std_logic := 'U'; --
|
DQ10 : INOUT std_logic := 'U'; --
|
DQ9 : INOUT std_logic := 'U'; -- data
|
DQ9 : INOUT std_logic := 'U'; -- data
|
DQ8 : INOUT std_logic := 'U'; -- lines
|
DQ8 : INOUT std_logic := 'U'; -- lines
|
DQ7 : INOUT std_logic := 'U'; --
|
DQ7 : INOUT std_logic := 'U'; --
|
DQ6 : INOUT std_logic := 'U'; --
|
DQ6 : INOUT std_logic := 'U'; --
|
DQ5 : INOUT std_logic := 'U'; --
|
DQ5 : INOUT std_logic := 'U'; --
|
DQ4 : INOUT std_logic := 'U'; --
|
DQ4 : INOUT std_logic := 'U'; --
|
DQ3 : INOUT std_logic := 'U'; --
|
DQ3 : INOUT std_logic := 'U'; --
|
DQ2 : INOUT std_logic := 'U'; --
|
DQ2 : INOUT std_logic := 'U'; --
|
DQ1 : INOUT std_logic := 'U'; --
|
DQ1 : INOUT std_logic := 'U'; --
|
DQ0 : INOUT std_logic := 'U'; --
|
DQ0 : INOUT std_logic := 'U'; --
|
|
|
CENeg : IN std_logic := 'U';
|
CENeg : IN std_logic := 'U';
|
OENeg : IN std_logic := 'U';
|
OENeg : IN std_logic := 'U';
|
WENeg : IN std_logic := 'U';
|
WENeg : IN std_logic := 'U';
|
RESETNeg : IN std_logic := 'U';
|
RESETNeg : IN std_logic := 'U';
|
WPNeg : IN std_logic := 'U'; --WP#/ACC
|
WPNeg : IN std_logic := 'U'; --WP#/ACC
|
BYTENeg : IN std_logic := 'U';
|
BYTENeg : IN std_logic := 'U';
|
RY : OUT std_logic := 'U' --RY/BY#
|
RY : OUT std_logic := 'U' --RY/BY#
|
);
|
);
|
END COMPONENT;
|
END COMPONENT;
|
|
|
FOR ALL: my_mem USE ENTITY WORK.my_mem(VHDL_BEHAVIORAL);
|
FOR ALL: my_mem USE ENTITY WORK.my_mem(VHDL_BEHAVIORAL);
|
|
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
--memory configuration
|
--memory configuration
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
CONSTANT MaxData : NATURAL := 16#FF#; --255;
|
CONSTANT MaxData : NATURAL := 16#FF#; --255;
|
CONSTANT SecSize : NATURAL := 16#FFFF#; --65535
|
CONSTANT SecSize : NATURAL := 16#FFFF#; --65535
|
CONSTANT SecSiSize : NATURAL := 255;
|
CONSTANT SecSiSize : NATURAL := 255;
|
CONSTANT SecNum : NATURAL := 127;
|
CONSTANT SecNum : NATURAL := 127;
|
CONSTANT HiAddrBit : NATURAL := 21;
|
CONSTANT HiAddrBit : NATURAL := 21;
|
--Address of the Protected Sector
|
--Address of the Protected Sector
|
-- CONSTANT ProtSecNum : NATURAL := SecNum;
|
-- CONSTANT ProtSecNum : NATURAL := SecNum;
|
|
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
--model configuration
|
--model configuration
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
CONSTANT mem_file : STRING := "am29lv640m.mem";
|
CONSTANT mem_file : STRING := "am29lv640m.mem";
|
CONSTANT prot_file : STRING := "am29lv640m_prot.mem";
|
CONSTANT prot_file : STRING := "am29lv640m_prot.mem";
|
CONSTANT secsi_file : STRING := "am29lv_secsi.mem";
|
CONSTANT secsi_file : STRING := "am29lv_secsi.mem";
|
|
|
CONSTANT UserPreload : boolean := TRUE;
|
CONSTANT UserPreload : boolean := TRUE;
|
CONSTANT DebugInfo : boolean := FALSE;
|
CONSTANT DebugInfo : boolean := FALSE;
|
CONSTANT LongTimming : boolean := TRUE;
|
CONSTANT LongTimming : boolean := TRUE;
|
CONSTANT TimingModel : STRING := "MY_MEM";
|
CONSTANT TimingModel : STRING := "MY_MEM";
|
-- "AM29LV640MH90R";--High sect prot.
|
-- "AM29LV640MH90R";--High sect prot.
|
-- "AM29LV128ML93R";--Low sect. prot.
|
-- "AM29LV128ML93R";--Low sect. prot.
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
SIGNAL ProtSecNum : NATURAL := SecNum ;
|
SIGNAL ProtSecNum : NATURAL := SecNum ;
|
|
|
--Flash Memory Array
|
--Flash Memory Array
|
TYPE SecType IS ARRAY (0 TO SecSize) OF
|
TYPE SecType IS ARRAY (0 TO SecSize) OF
|
INTEGER RANGE -1 TO MaxData;
|
INTEGER RANGE -1 TO MaxData;
|
TYPE MemArray IS ARRAY (0 TO SecNum) OF
|
TYPE MemArray IS ARRAY (0 TO SecNum) OF
|
SecType;
|
SecType;
|
|
|
--Common Flash Interface Query codes
|
--Common Flash Interface Query codes
|
TYPE CFItype IS ARRAY (16#10# TO 16#50#) OF
|
TYPE CFItype IS ARRAY (16#10# TO 16#50#) OF
|
NATURAL RANGE 0 TO 16#FF#;
|
NATURAL RANGE 0 TO 16#FF#;
|
|
|
--SecSi Sector
|
--SecSi Sector
|
TYPE SecSiType IS ARRAY ( 0 TO SecSiSize) OF
|
TYPE SecSiType IS ARRAY ( 0 TO SecSiSize) OF
|
INTEGER RANGE -1 TO MaxData;
|
INTEGER RANGE -1 TO MaxData;
|
|
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
-- memory declaration
|
-- memory declaration
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
-- -- Mem(SecAddr)(Address)....
|
-- -- Mem(SecAddr)(Address)....
|
SHARED VARIABLE Mem : MemArray := (OTHERS => (OTHERS=> MaxData));
|
SHARED VARIABLE Mem : MemArray := (OTHERS => (OTHERS=> MaxData));
|
SHARED VARIABLE CFI_array : CFItype :=(OTHERS=>0);
|
SHARED VARIABLE CFI_array : CFItype :=(OTHERS=>0);
|
SHARED VARIABLE SecSi : SecSiType :=(OTHERS=>0);
|
SHARED VARIABLE SecSi : SecSiType :=(OTHERS=>0);
|
|
|
--command sequence
|
--command sequence
|
SHARED VARIABLE cmd_seq : cmd_seq_type;
|
SHARED VARIABLE cmd_seq : cmd_seq_type;
|
|
|
SIGNAL status : status_type := none;
|
SIGNAL status : status_type := none;
|
SIGNAL sts_check : std_logic_vector(7 downto 0);
|
SIGNAL sts_check : std_logic_vector(7 downto 0);
|
|
|
|
|
SIGNAL check_err : std_logic := '0';
|
SIGNAL check_err : std_logic := '0';
|
SIGNAL ErrorInTest : std_logic := '0'; --
|
SIGNAL ErrorInTest : std_logic := '0'; --
|
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
--Personality module:
|
--Personality module:
|
--
|
--
|
-- instanciates the DUT module and adapts generic test signals to it
|
-- instanciates the DUT module and adapts generic test signals to it
|
-- TBD: block port
|
-- TBD: block port
|
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
--DUT port
|
--DUT port
|
SIGNAL T_DQ : std_logic_vector(15 downto 0) := (OTHERS=>'U');
|
SIGNAL T_DQ : std_logic_vector(15 downto 0) := (OTHERS=>'U');
|
SIGNAL T_A : std_logic_vector(HiAddrBit downto 0) := (OTHERS=>'U');
|
SIGNAL T_A : std_logic_vector(HiAddrBit downto 0) := (OTHERS=>'U');
|
SIGNAL T_RESETNeg : std_logic := 'U';
|
SIGNAL T_RESETNeg : std_logic := 'U';
|
SIGNAL T_CENeg : std_logic := 'U';
|
SIGNAL T_CENeg : std_logic := 'U';
|
SIGNAL T_WENeg : std_logic := 'U';
|
SIGNAL T_WENeg : std_logic := 'U';
|
SIGNAL T_OENeg : std_logic := 'U';
|
SIGNAL T_OENeg : std_logic := 'U';
|
SIGNAL T_WPNeg : std_logic := 'U';
|
SIGNAL T_WPNeg : std_logic := 'U';
|
SIGNAL T_BYTENeg : std_logic := 'U';
|
SIGNAL T_BYTENeg : std_logic := 'U';
|
SIGNAL T_RY : std_logic := 'U';
|
SIGNAL T_RY : std_logic := 'U';
|
|
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
--
|
--
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
--SecSi ProtectionStatus
|
--SecSi ProtectionStatus
|
SHARED VARIABLE FactoryProt : std_logic := '1';
|
SHARED VARIABLE FactoryProt : std_logic := '1';
|
--Sector Protection Status
|
--Sector Protection Status
|
SHARED VARIABLE Sec_Prot : std_logic_vector (SecNum downto 0) :=
|
SHARED VARIABLE Sec_Prot : std_logic_vector (SecNum downto 0) :=
|
(OTHERS => '0');
|
(OTHERS => '0');
|
SHARED VARIABLE Sect : NATURAL RANGE 0 TO SecNum := 0;
|
SHARED VARIABLE Sect : NATURAL RANGE 0 TO SecNum := 0;
|
SHARED VARIABLE Addr : NATURAL RANGE 0 TO SecSize := 0;
|
SHARED VARIABLE Addr : NATURAL RANGE 0 TO SecSize := 0;
|
SHARED VARIABLE WriteData : NATURAL RANGE 0 TO MaxData := 0;
|
SHARED VARIABLE WriteData : NATURAL RANGE 0 TO MaxData := 0;
|
|
|
|
|
--CONSTANT
|
--CONSTANT
|
--timming parameters
|
--timming parameters
|
CONSTANT RESETNeg_pw : time := 500 ns; --tRP
|
CONSTANT RESETNeg_pw : time := 500 ns; --tRP
|
|
|
SIGNAL pwron : std_logic := '0';
|
SIGNAL pwron : std_logic := '0';
|
|
|
SIGNAL Tseries : NATURAL;
|
SIGNAL Tseries : NATURAL;
|
SIGNAL Tcase : NATURAL;
|
SIGNAL Tcase : NATURAL;
|
|
|
SHARED VARIABLE ts_cnt : NATURAL RANGE 1 TO 30:=1; -- testseries counter
|
SHARED VARIABLE ts_cnt : NATURAL RANGE 1 TO 30:=1; -- testseries counter
|
SHARED VARIABLE tc_cnt : NATURAL RANGE 0 TO 10:=0; -- testcase counter
|
SHARED VARIABLE tc_cnt : NATURAL RANGE 0 TO 10:=0; -- testcase counter
|
|
|
|
|
BEGIN
|
BEGIN
|
DUT : my_mem
|
DUT : my_mem
|
GENERIC MAP (
|
GENERIC MAP (
|
-- tipd delays: interconnect path delays
|
-- tipd delays: interconnect path delays
|
tipd_A0 => VitalZeroDelay01, --
|
tipd_A0 => VitalZeroDelay01, --
|
tipd_A1 => VitalZeroDelay01, --
|
tipd_A1 => VitalZeroDelay01, --
|
tipd_A2 => VitalZeroDelay01, --
|
tipd_A2 => VitalZeroDelay01, --
|
tipd_A3 => VitalZeroDelay01, --
|
tipd_A3 => VitalZeroDelay01, --
|
tipd_A4 => VitalZeroDelay01, --
|
tipd_A4 => VitalZeroDelay01, --
|
tipd_A5 => VitalZeroDelay01, --
|
tipd_A5 => VitalZeroDelay01, --
|
tipd_A6 => VitalZeroDelay01, --
|
tipd_A6 => VitalZeroDelay01, --
|
tipd_A7 => VitalZeroDelay01, --
|
tipd_A7 => VitalZeroDelay01, --
|
tipd_A8 => VitalZeroDelay01, --
|
tipd_A8 => VitalZeroDelay01, --
|
tipd_A9 => VitalZeroDelay01, --address
|
tipd_A9 => VitalZeroDelay01, --address
|
tipd_A10 => VitalZeroDelay01, --lines
|
tipd_A10 => VitalZeroDelay01, --lines
|
tipd_A11 => VitalZeroDelay01, --
|
tipd_A11 => VitalZeroDelay01, --
|
tipd_A12 => VitalZeroDelay01, --
|
tipd_A12 => VitalZeroDelay01, --
|
tipd_A13 => VitalZeroDelay01, --
|
tipd_A13 => VitalZeroDelay01, --
|
tipd_A14 => VitalZeroDelay01, --
|
tipd_A14 => VitalZeroDelay01, --
|
tipd_A15 => VitalZeroDelay01, --
|
tipd_A15 => VitalZeroDelay01, --
|
tipd_A16 => VitalZeroDelay01, --
|
tipd_A16 => VitalZeroDelay01, --
|
tipd_A17 => VitalZeroDelay01, --
|
tipd_A17 => VitalZeroDelay01, --
|
tipd_A18 => VitalZeroDelay01, --
|
tipd_A18 => VitalZeroDelay01, --
|
tipd_A19 => VitalZeroDelay01, --
|
tipd_A19 => VitalZeroDelay01, --
|
tipd_A20 => VitalZeroDelay01, --
|
tipd_A20 => VitalZeroDelay01, --
|
tipd_A21 => VitalZeroDelay01, --
|
tipd_A21 => VitalZeroDelay01, --
|
|
|
tipd_DQ0 => VitalZeroDelay01, --
|
tipd_DQ0 => VitalZeroDelay01, --
|
tipd_DQ1 => VitalZeroDelay01, --
|
tipd_DQ1 => VitalZeroDelay01, --
|
tipd_DQ2 => VitalZeroDelay01, --
|
tipd_DQ2 => VitalZeroDelay01, --
|
tipd_DQ3 => VitalZeroDelay01, --
|
tipd_DQ3 => VitalZeroDelay01, --
|
tipd_DQ4 => VitalZeroDelay01, --
|
tipd_DQ4 => VitalZeroDelay01, --
|
tipd_DQ5 => VitalZeroDelay01, --
|
tipd_DQ5 => VitalZeroDelay01, --
|
tipd_DQ6 => VitalZeroDelay01, -- data
|
tipd_DQ6 => VitalZeroDelay01, -- data
|
tipd_DQ7 => VitalZeroDelay01, -- lines
|
tipd_DQ7 => VitalZeroDelay01, -- lines
|
tipd_DQ8 => VitalZeroDelay01, --
|
tipd_DQ8 => VitalZeroDelay01, --
|
tipd_DQ9 => VitalZeroDelay01, --
|
tipd_DQ9 => VitalZeroDelay01, --
|
tipd_DQ10 => VitalZeroDelay01, --
|
tipd_DQ10 => VitalZeroDelay01, --
|
tipd_DQ11 => VitalZeroDelay01, --
|
tipd_DQ11 => VitalZeroDelay01, --
|
tipd_DQ12 => VitalZeroDelay01, --
|
tipd_DQ12 => VitalZeroDelay01, --
|
tipd_DQ13 => VitalZeroDelay01, --
|
tipd_DQ13 => VitalZeroDelay01, --
|
tipd_DQ14 => VitalZeroDelay01, --
|
tipd_DQ14 => VitalZeroDelay01, --
|
|
|
tipd_DQ15 => VitalZeroDelay01, -- DQ15/A-1
|
tipd_DQ15 => VitalZeroDelay01, -- DQ15/A-1
|
|
|
tipd_CENeg => VitalZeroDelay01,
|
tipd_CENeg => VitalZeroDelay01,
|
tipd_OENeg => VitalZeroDelay01,
|
tipd_OENeg => VitalZeroDelay01,
|
tipd_WENeg => VitalZeroDelay01,
|
tipd_WENeg => VitalZeroDelay01,
|
tipd_RESETNeg => VitalZeroDelay01,
|
tipd_RESETNeg => VitalZeroDelay01,
|
tipd_WPNeg => VitalZeroDelay01,--WP#/ACC
|
tipd_WPNeg => VitalZeroDelay01,--WP#/ACC
|
tipd_BYTENeg => VitalZeroDelay01,
|
tipd_BYTENeg => VitalZeroDelay01,
|
|
|
-- tpd delays
|
-- tpd delays
|
tpd_A0_DQ0 => UnitDelay01,--tACC
|
tpd_A0_DQ0 => UnitDelay01,--tACC
|
tpd_A0_DQ1 => UnitDelay01,--tPACC
|
tpd_A0_DQ1 => UnitDelay01,--tPACC
|
tpd_CENeg_DQ0 => UnitDelay01Z,
|
tpd_CENeg_DQ0 => UnitDelay01Z,
|
--(tCE,tCE,tDF,-,tDF
|
--(tCE,tCE,tDF,-,tDF
|
tpd_OENeg_DQ0 => UnitDelay01Z,
|
tpd_OENeg_DQ0 => UnitDelay01Z,
|
--(tOE,tOE,tDF,-,tDF
|
--(tOE,tOE,tDF,-,tDF
|
tpd_RESETNeg_DQ0 => UnitDelay01Z,
|
tpd_RESETNeg_DQ0 => UnitDelay01Z,
|
--(-,-,0,-,0,-)
|
--(-,-,0,-,0,-)
|
tpd_CENeg_RY => UnitDelay01, --tBUSY
|
tpd_CENeg_RY => UnitDelay01, --tBUSY
|
tpd_WENeg_RY => UnitDelay01, --tBUSY
|
tpd_WENeg_RY => UnitDelay01, --tBUSY
|
|
|
--tsetup values
|
--tsetup values
|
tsetup_A0_CENeg => UnitDelay, --tAS edge \
|
tsetup_A0_CENeg => UnitDelay, --tAS edge \
|
tsetup_A0_OENeg => UnitDelay, --tASO edge \
|
tsetup_A0_OENeg => UnitDelay, --tASO edge \
|
tsetup_DQ0_CENeg => UnitDelay, --tDS edge /
|
tsetup_DQ0_CENeg => UnitDelay, --tDS edge /
|
|
|
--thold values
|
--thold values
|
thold_CENeg_RESETNeg=> UnitDelay, --tRH edge /
|
thold_CENeg_RESETNeg=> UnitDelay, --tRH edge /
|
thold_OENeg_WENeg => UnitDelay, --tOEH edge /
|
thold_OENeg_WENeg => UnitDelay, --tOEH edge /
|
thold_A0_CENeg => UnitDelay, --tAH edge \
|
thold_A0_CENeg => UnitDelay, --tAH edge \
|
thold_A0_OENeg => UnitDelay, --tAHT edge \
|
thold_A0_OENeg => UnitDelay, --tAHT edge \
|
thold_DQ0_CENeg => UnitDelay, --tDH edge /
|
thold_DQ0_CENeg => UnitDelay, --tDH edge /
|
thold_WENeg_OENeg => UnitDelay, --tGHVL edge /
|
thold_WENeg_OENeg => UnitDelay, --tGHVL edge /
|
|
|
--tpw values: pulse width
|
--tpw values: pulse width
|
tpw_RESETNeg_negedge=> UnitDelay, --tRP
|
tpw_RESETNeg_negedge=> UnitDelay, --tRP
|
tpw_OENeg_posedge => UnitDelay, --tOEPH
|
tpw_OENeg_posedge => UnitDelay, --tOEPH
|
tpw_WENeg_negedge => UnitDelay, --tWP
|
tpw_WENeg_negedge => UnitDelay, --tWP
|
tpw_WENeg_posedge => UnitDelay, --tWPH
|
tpw_WENeg_posedge => UnitDelay, --tWPH
|
tpw_CENeg_negedge => UnitDelay, --tCP
|
tpw_CENeg_negedge => UnitDelay, --tCP
|
tpw_CENeg_posedge => UnitDelay, --tCEPH
|
tpw_CENeg_posedge => UnitDelay, --tCEPH
|
tpw_A0_negedge => UnitDelay, --tWC tRC
|
tpw_A0_negedge => UnitDelay, --tWC tRC
|
-- tdevice values: values for internal delays
|
-- tdevice values: values for internal delays
|
--Effective Write Buffer Program Operation tWHWH1
|
--Effective Write Buffer Program Operation tWHWH1
|
tdevice_WBPB => 11 us,
|
tdevice_WBPB => 11 us,
|
--Program Operation
|
--Program Operation
|
tdevice_POB => 100 us,
|
tdevice_POB => 100 us,
|
--Sector Erase Operation tWHWH2
|
--Sector Erase Operation tWHWH2
|
tdevice_SEO => 500 ms,
|
tdevice_SEO => 500 ms,
|
--Timing Limit Exceeded
|
--Timing Limit Exceeded
|
tdevice_HANG => 400 ms, --?
|
tdevice_HANG => 400 ms, --?
|
--program/erase suspend timeout
|
--program/erase suspend timeout
|
tdevice_START_T1 => 5 us,
|
tdevice_START_T1 => 5 us,
|
--sector erase command sequence timeout
|
--sector erase command sequence timeout
|
tdevice_CTMOUT => 50 us,
|
tdevice_CTMOUT => 50 us,
|
--device ready after Hardware reset(during embeded algorithm)
|
--device ready after Hardware reset(during embeded algorithm)
|
tdevice_READY => 20 us, --tReady
|
tdevice_READY => 20 us, --tReady
|
|
|
-- generic control parameters
|
-- generic control parameters
|
InstancePath => DefaultInstancePath,
|
InstancePath => DefaultInstancePath,
|
TimingChecksOn => TRUE,--DefaultTimingChecks,
|
TimingChecksOn => TRUE,--DefaultTimingChecks,
|
MsgOn => DefaultMsgOn,
|
MsgOn => DefaultMsgOn,
|
XOn => DefaultXon,
|
XOn => DefaultXon,
|
-- memory file to be loaded
|
-- memory file to be loaded
|
mem_file_name => mem_file,
|
mem_file_name => mem_file,
|
prot_file_name => prot_file ,
|
prot_file_name => prot_file ,
|
secsi_file_name => secsi_file,
|
secsi_file_name => secsi_file,
|
|
|
UserPreload => UserPreload,
|
UserPreload => UserPreload,
|
LongTimming => LongTimming,
|
LongTimming => LongTimming,
|
-- For FMF SDF technology file usage
|
-- For FMF SDF technology file usage
|
TimingModel => "AM29LV640MH90R" -- TimingModel
|
TimingModel => "AM29LV640MH90R" -- TimingModel
|
)
|
)
|
PORT MAP(
|
PORT MAP(
|
A21 => T_A(21), --
|
A21 => T_A(21), --
|
A20 => T_A(20), --
|
A20 => T_A(20), --
|
A19 => T_A(19), --
|
A19 => T_A(19), --
|
A18 => T_A(18), --
|
A18 => T_A(18), --
|
A17 => T_A(17), --
|
A17 => T_A(17), --
|
A16 => T_A(16), --
|
A16 => T_A(16), --
|
A15 => T_A(15), --
|
A15 => T_A(15), --
|
A14 => T_A(14), --
|
A14 => T_A(14), --
|
A13 => T_A(13), --address
|
A13 => T_A(13), --address
|
A12 => T_A(12), --lines
|
A12 => T_A(12), --lines
|
A11 => T_A(11), --
|
A11 => T_A(11), --
|
A10 => T_A(10), --
|
A10 => T_A(10), --
|
A9 => T_A(9), --
|
A9 => T_A(9), --
|
A8 => T_A(8), --
|
A8 => T_A(8), --
|
A7 => T_A(7), --
|
A7 => T_A(7), --
|
A6 => T_A(6), --
|
A6 => T_A(6), --
|
A5 => T_A(5),--
|
A5 => T_A(5),--
|
A4 => T_A(4),--
|
A4 => T_A(4),--
|
A3 => T_A(3), --
|
A3 => T_A(3), --
|
A2 => T_A(2), --
|
A2 => T_A(2), --
|
A1 => T_A(1), --
|
A1 => T_A(1), --
|
A0 => T_A(0), --
|
A0 => T_A(0), --
|
|
|
DQ15 => T_DQ(15), -- DQ15/A-1
|
DQ15 => T_DQ(15), -- DQ15/A-1
|
DQ14 => T_DQ(14), --
|
DQ14 => T_DQ(14), --
|
DQ13 => T_DQ(13), --
|
DQ13 => T_DQ(13), --
|
DQ12 => T_DQ(12), --
|
DQ12 => T_DQ(12), --
|
DQ11 => T_DQ(11), --
|
DQ11 => T_DQ(11), --
|
DQ10 => T_DQ(10), --
|
DQ10 => T_DQ(10), --
|
DQ9 => T_DQ(9), -- data
|
DQ9 => T_DQ(9), -- data
|
DQ8 => T_DQ(8), -- lines
|
DQ8 => T_DQ(8), -- lines
|
DQ7 => T_DQ(7), --
|
DQ7 => T_DQ(7), --
|
DQ6 => T_DQ(6), --
|
DQ6 => T_DQ(6), --
|
DQ5 => T_DQ(5), --
|
DQ5 => T_DQ(5), --
|
DQ4 => T_DQ(4), --
|
DQ4 => T_DQ(4), --
|
DQ3 => T_DQ(3), --
|
DQ3 => T_DQ(3), --
|
DQ2 => T_DQ(2), --
|
DQ2 => T_DQ(2), --
|
DQ1 => T_DQ(1), --
|
DQ1 => T_DQ(1), --
|
DQ0 => T_DQ(0), --
|
DQ0 => T_DQ(0), --
|
|
|
CENeg => T_CENeg,
|
CENeg => T_CENeg,
|
OENeg => T_OENeg,
|
OENeg => T_OENeg,
|
WENeg => T_WENeg,
|
WENeg => T_WENeg,
|
RESETNeg => T_RESETNeg,
|
RESETNeg => T_RESETNeg,
|
WPNeg => T_WPNeg, --WP#/ACC
|
WPNeg => T_WPNeg, --WP#/ACC
|
BYTENeg => T_BYTENeg,
|
BYTENeg => T_BYTENeg,
|
RY => T_RY --RY/BY#
|
RY => T_RY --RY/BY#
|
);
|
);
|
|
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
--protected sector
|
--protected sector
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
ProtSecNum <= SecNum WHEN TimingModel(11) = 'H' ELSE
|
ProtSecNum <= SecNum WHEN TimingModel(11) = 'H' ELSE
|
0 ;-- WHEN TimingModel = "AM29LV128ML93R"
|
0 ;-- WHEN TimingModel = "AM29LV128ML93R"
|
|
|
pwron <= '0', '1' after 1 ns;
|
pwron <= '0', '1' after 1 ns;
|
|
|
--At the end of the simulation, if ErrorInTest='0' there were no errors
|
--At the end of the simulation, if ErrorInTest='0' there were no errors
|
err_ctrl : PROCESS ( check_err )
|
err_ctrl : PROCESS ( check_err )
|
BEGIN
|
BEGIN
|
IF check_err = '1' THEN
|
IF check_err = '1' THEN
|
ErrorInTest <= '1';
|
ErrorInTest <= '1';
|
END IF;
|
END IF;
|
END PROCESS err_ctrl;
|
END PROCESS err_ctrl;
|
|
|
tb :PROCESS
|
tb :PROCESS
|
|
|
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
--= PROCEDURE to select TC
|
--= PROCEDURE to select TC
|
-- can be modified to read TC list from file, or to generate random list
|
-- can be modified to read TC list from file, or to generate random list
|
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
PROCEDURE Pick_TC
|
PROCEDURE Pick_TC
|
(Model : IN STRING := "AM29LV640MH90R" )
|
(Model : IN STRING := "AM29LV640MH90R" )
|
IS
|
IS
|
BEGIN
|
BEGIN
|
IF TC_cnt < tc(TS_cnt) THEN
|
IF TC_cnt < tc(TS_cnt) THEN
|
TC_cnt := TC_cnt+1;
|
TC_cnt := TC_cnt+1;
|
ELSE
|
ELSE
|
TC_cnt:=1;
|
TC_cnt:=1;
|
IF TS_cnt<30 THEN
|
IF TS_cnt<30 THEN
|
TS_cnt := TS_cnt+1;
|
TS_cnt := TS_cnt+1;
|
ELSE
|
ELSE
|
-- end test
|
-- end test
|
IF ErrorInTest='0' THEN
|
IF ErrorInTest='0' THEN
|
REPORT "Test Ended without errors"
|
REPORT "Test Ended without errors"
|
SEVERITY note;
|
SEVERITY note;
|
ELSE
|
ELSE
|
REPORT "There were errors in test"
|
REPORT "There were errors in test"
|
SEVERITY note;
|
SEVERITY note;
|
END IF;
|
END IF;
|
WAIT;
|
WAIT;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END PROCEDURE Pick_TC;
|
END PROCEDURE Pick_TC;
|
|
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
--bus commands, device specific implementation
|
--bus commands, device specific implementation
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
TYPE bus_type IS (bus_idle,
|
TYPE bus_type IS (bus_idle,
|
bus_standby, --CE# deasseretd, others are don't care
|
bus_standby, --CE# deasseretd, others are don't care
|
bus_enable, --CE# asserted, others deasserted
|
bus_enable, --CE# asserted, others deasserted
|
bus_output_disable,
|
bus_output_disable,
|
bus_reset,
|
bus_reset,
|
bus_write,
|
bus_write,
|
bus_read);
|
bus_read);
|
|
|
--bus drive for specific command sequence cycle
|
--bus drive for specific command sequence cycle
|
PROCEDURE bus_cycle(
|
PROCEDURE bus_cycle(
|
bus_cmd :IN bus_type := bus_idle;
|
bus_cmd :IN bus_type := bus_idle;
|
byte :IN boolean ;
|
byte :IN boolean ;
|
data :IN INTEGER RANGE -2 TO MaxData := -2; -- -1 for all Z
|
data :IN INTEGER RANGE -2 TO MaxData := -2; -- -1 for all Z
|
dataHi :IN INTEGER RANGE -2 TO MaxData := -2; -- -2 for ignore
|
dataHi :IN INTEGER RANGE -2 TO MaxData := -2; -- -2 for ignore
|
sector :IN INTEGER RANGE -1 TO SecNum := -1; -- -1 for ignore addr
|
sector :IN INTEGER RANGE -1 TO SecNum := -1; -- -1 for ignore addr
|
address :IN NATURAL RANGE 0 TO SecSize := 0;
|
address :IN NATURAL RANGE 0 TO SecSize := 0;
|
disable :IN boolean := false;
|
disable :IN boolean := false;
|
violate :IN boolean := false;
|
violate :IN boolean := false;
|
tm :IN TIME := 10 ns)
|
tm :IN TIME := 10 ns)
|
IS
|
IS
|
|
|
VARIABLE tmp : std_logic_vector(15 downto 0);
|
VARIABLE tmp : std_logic_vector(15 downto 0);
|
BEGIN
|
BEGIN
|
|
|
IF data=-1 THEN -- HiZ
|
IF data=-1 THEN -- HiZ
|
T_DQ(7 downto 0) <= (OTHERS => 'Z');
|
T_DQ(7 downto 0) <= (OTHERS => 'Z');
|
END IF;
|
END IF;
|
|
|
IF (NOT byte)THEN --word access
|
IF (NOT byte)THEN --word access
|
IF dataHi=-1 THEN -- HiZ
|
IF dataHi=-1 THEN -- HiZ
|
T_DQ(15 downto 8) <= (OTHERS => 'Z');
|
T_DQ(15 downto 8) <= (OTHERS => 'Z');
|
END IF;
|
END IF;
|
T_BYTENeg <= '1';
|
T_BYTENeg <= '1';
|
ELSE --byte access
|
ELSE --byte access
|
T_BYTENeg <= '0';
|
T_BYTENeg <= '0';
|
T_DQ(14 downto 8) <= (OTHERS => 'Z');
|
T_DQ(14 downto 8) <= (OTHERS => 'Z');
|
END IF;
|
END IF;
|
|
|
IF sector > -1 THEN
|
IF sector > -1 THEN
|
T_A(HiAddrBit downto 15) <= to_slv(sector, HiAddrbit-14);
|
T_A(HiAddrBit downto 15) <= to_slv(sector, HiAddrbit-14);
|
tmp := to_slv(address, 16);
|
tmp := to_slv(address, 16);
|
IF byte THEN
|
IF byte THEN
|
T_A(14 downto 0) <= tmp(15 downto 1);
|
T_A(14 downto 0) <= tmp(15 downto 1);
|
T_DQ(15) <= tmp(0);
|
T_DQ(15) <= tmp(0);
|
ELSE
|
ELSE
|
T_A(14 downto 0) <= tmp(14 downto 0);
|
T_A(14 downto 0) <= tmp(14 downto 0);
|
END IF;
|
END IF;
|
|
|
END IF;
|
END IF;
|
|
|
wait for 1 ns;
|
wait for 1 ns;
|
|
|
CASE bus_cmd IS
|
CASE bus_cmd IS
|
WHEN bus_output_disable =>
|
WHEN bus_output_disable =>
|
T_OENeg <= '1';
|
T_OENeg <= '1';
|
WAIT FOR 20 ns;
|
WAIT FOR 20 ns;
|
|
|
WHEN bus_idle =>
|
WHEN bus_idle =>
|
T_RESETNeg <= '1';
|
T_RESETNeg <= '1';
|
T_WENeg <= '1';
|
T_WENeg <= '1';
|
T_CENeg <= '1';
|
T_CENeg <= '1';
|
T_OENeg <= '1';
|
T_OENeg <= '1';
|
IF disable THEN
|
IF disable THEN
|
T_WPNeg <= '0';
|
T_WPNeg <= '0';
|
ELSE
|
ELSE
|
T_WPNeg <= '1';
|
T_WPNeg <= '1';
|
END IF;
|
END IF;
|
WAIT FOR 30 ns;
|
WAIT FOR 30 ns;
|
|
|
WHEN bus_standby =>
|
WHEN bus_standby =>
|
T_CENeg <= '1';
|
T_CENeg <= '1';
|
WAIT FOR 30 ns;
|
WAIT FOR 30 ns;
|
|
|
WHEN bus_reset =>
|
WHEN bus_reset =>
|
T_RESETNeg <= '0', '1' AFTER tm ;
|
T_RESETNeg <= '0', '1' AFTER tm ;
|
-- WAIT FOR 500 ns should follow this bus cmd for reset to
|
-- WAIT FOR 500 ns should follow this bus cmd for reset to
|
--complete
|
--complete
|
WAIT FOR 30 ns;
|
WAIT FOR 30 ns;
|
|
|
WHEN bus_enable =>
|
WHEN bus_enable =>
|
T_WENeg <= '1' AFTER 50 ns; ---
|
T_WENeg <= '1' AFTER 50 ns; ---
|
T_CENeg <= '0' AFTER 50 ns; ---
|
T_CENeg <= '0' AFTER 50 ns; ---
|
T_OENeg <= '1' AFTER 30 ns; ---
|
T_OENeg <= '1' AFTER 30 ns; ---
|
|
|
WAIT FOR tm ;
|
WAIT FOR tm ;
|
|
|
WHEN bus_write =>
|
WHEN bus_write =>
|
T_OENeg <= '1' ;-- AFTER 5 ns;
|
T_OENeg <= '1' ;-- AFTER 5 ns;
|
T_CENeg <= '0' AFTER 10 ns ;
|
T_CENeg <= '0' AFTER 10 ns ;
|
T_WENeg <= '0' AFTER 20 ns;
|
T_WENeg <= '0' AFTER 20 ns;
|
|
|
IF data>-1 THEN
|
IF data>-1 THEN
|
T_DQ(7 downto 0) <= to_slv(data,8);
|
T_DQ(7 downto 0) <= to_slv(data,8);
|
END IF;
|
END IF;
|
IF NOT byte THEN
|
IF NOT byte THEN
|
IF dataHi>-1 THEN
|
IF dataHi>-1 THEN
|
T_DQ(15 downto 8) <= to_slv(dataHi,8);
|
T_DQ(15 downto 8) <= to_slv(dataHi,8);
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
|
|
IF violate THEN
|
IF violate THEN
|
T_WENeg <= '1';
|
T_WENeg <= '1';
|
WAIT FOR 50 ns;
|
WAIT FOR 50 ns;
|
T_WENeg <= '0', '1' AFTER tm;
|
T_WENeg <= '0', '1' AFTER tm;
|
WAIT FOR 50 ns;
|
WAIT FOR 50 ns;
|
ELSE
|
ELSE
|
WAIT FOR 100 ns;
|
WAIT FOR 100 ns;
|
END IF;
|
END IF;
|
|
|
WHEN bus_read =>
|
WHEN bus_read =>
|
|
|
T_CENeg <= '0' ;
|
T_CENeg <= '0' ;
|
T_WENeg <= '1'AFTER 10 ns;
|
T_WENeg <= '1'AFTER 10 ns;
|
IF NOT disable THEN
|
IF NOT disable THEN
|
T_OENeg <= '0' AFTER 15 ns;
|
T_OENeg <= '0' AFTER 15 ns;
|
ELSE
|
ELSE
|
T_OENeg <= '1';
|
T_OENeg <= '1';
|
END IF;
|
END IF;
|
|
|
IF NOT byte THEN
|
IF NOT byte THEN
|
T_DQ(15 downto 8) <= (OTHERS => 'Z');
|
T_DQ(15 downto 8) <= (OTHERS => 'Z');
|
END IF;
|
END IF;
|
T_DQ(7 downto 0) <= (OTHERS => 'Z');
|
T_DQ(7 downto 0) <= (OTHERS => 'Z');
|
|
|
WAIT FOR 100 ns;
|
WAIT FOR 100 ns;
|
|
|
-- T_OENeg <= '1' ; -----------
|
-- T_OENeg <= '1' ; -----------
|
|
|
END CASE;
|
END CASE;
|
|
|
|
|
END PROCEDURE;
|
END PROCEDURE;
|
|
|
|
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
--procedure to decode commands into specific bus command sequence
|
--procedure to decode commands into specific bus command sequence
|
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
PROCEDURE cmd_dc
|
PROCEDURE cmd_dc
|
( command : IN cmd_rec )
|
( command : IN cmd_rec )
|
IS
|
IS
|
VARIABLE D_hi : NATURAL ;--RANGE 0 to MaxData;
|
VARIABLE D_hi : NATURAL ;--RANGE 0 to MaxData;
|
VARIABLE D_lo : NATURAL RANGE 0 to MaxData;
|
VARIABLE D_lo : NATURAL RANGE 0 to MaxData;
|
VARIABLE Addr : NATURAL RANGE 0 to SecSize :=0;
|
VARIABLE Addr : NATURAL RANGE 0 to SecSize :=0;
|
VARIABLE Addrfix : NATURAL RANGE 0 to SecSize/2:=0;
|
VARIABLE Addrfix : NATURAL RANGE 0 to SecSize/2:=0;
|
VARIABLE Sect : INTEGER RANGE -1 to SecNum :=0;
|
VARIABLE Sect : INTEGER RANGE -1 to SecNum :=0;
|
VARIABLE slv_1, slv_2 : std_logic_vector(7 downto 0);
|
VARIABLE slv_1, slv_2 : std_logic_vector(7 downto 0);
|
VARIABLE byte : boolean;
|
VARIABLE byte : boolean;
|
VARIABLE i : NATURAL;
|
VARIABLE i : NATURAL;
|
BEGIN
|
BEGIN
|
CASE command.cmd IS
|
CASE command.cmd IS
|
WHEN idle =>
|
WHEN idle =>
|
bus_cycle(bus_cmd => bus_idle,
|
bus_cycle(bus_cmd => bus_idle,
|
byte => command.byte,
|
byte => command.byte,
|
disable => command.aux=disable);
|
disable => command.aux=disable);
|
|
|
WHEN h_reset =>
|
WHEN h_reset =>
|
bus_cycle(bus_cmd => bus_reset,
|
bus_cycle(bus_cmd => bus_reset,
|
byte => command.byte,
|
byte => command.byte,
|
tm => command.wtime);
|
tm => command.wtime);
|
|
|
WHEN rd =>
|
WHEN rd =>
|
bus_cycle(bus_cmd => bus_enable,
|
bus_cycle(bus_cmd => bus_enable,
|
byte => command.byte,
|
byte => command.byte,
|
data => -1,
|
data => -1,
|
sector => command.sect,
|
sector => command.sect,
|
address => command.addr,
|
address => command.addr,
|
tm => 90 ns);
|
tm => 90 ns);
|
|
|
bus_cycle(bus_cmd => bus_read,
|
bus_cycle(bus_cmd => bus_read,
|
byte => command.byte,
|
byte => command.byte,
|
data => -1,
|
data => -1,
|
dataHi => -1,
|
dataHi => -1,
|
sector => command.sect,
|
sector => command.sect,
|
address => command.addr,
|
address => command.addr,
|
disable => command.aux=disable);
|
disable => command.aux=disable);
|
|
|
bus_cycle(bus_cmd => bus_output_disable,
|
bus_cycle(bus_cmd => bus_output_disable,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
WHEN rd_page =>
|
WHEN rd_page =>
|
bus_cycle(bus_cmd => bus_enable,
|
bus_cycle(bus_cmd => bus_enable,
|
byte => command.byte,
|
byte => command.byte,
|
data => -1,
|
data => -1,
|
sector => 0,
|
sector => 0,
|
address => 0,
|
address => 0,
|
tm => 90 ns);
|
tm => 90 ns);
|
|
|
Addr := command.addr;
|
Addr := command.addr;
|
Sect := command.sect;
|
Sect := command.sect;
|
byte := command.byte;
|
byte := command.byte;
|
---- 08July----
|
---- 08July----
|
WAIT FOR 10 ns;
|
WAIT FOR 10 ns;
|
--------------
|
--------------
|
i := 0;
|
i := 0;
|
WHILE i < command.d_hi LOOP
|
WHILE i < command.d_hi LOOP
|
|
|
IF command.wtime > 0 ns THEN
|
IF command.wtime > 0 ns THEN
|
|
|
bus_cycle(bus_cmd => bus_output_disable, ----
|
bus_cycle(bus_cmd => bus_output_disable, ----
|
byte => byte); ----
|
byte => byte); ----
|
|
|
--byte toggle mode
|
--byte toggle mode
|
bus_cycle(bus_cmd => bus_enable,
|
bus_cycle(bus_cmd => bus_enable,
|
byte => byte,
|
byte => byte,
|
data => -1,
|
data => -1,
|
sector => -1,
|
sector => -1,
|
tm => 10 ns);
|
tm => 10 ns);
|
byte := false;
|
byte := false;
|
bus_cycle(bus_cmd => bus_enable,
|
bus_cycle(bus_cmd => bus_enable,
|
byte => byte,
|
byte => byte,
|
data => -1,
|
data => -1,
|
sector => -1,
|
sector => -1,
|
tm => 10 ns);
|
tm => 10 ns);
|
Addrfix := Addr /2;
|
Addrfix := Addr /2;
|
IF Addr < SecSize THEN
|
IF Addr < SecSize THEN
|
Addr := Addr+1;
|
Addr := Addr+1;
|
ELSE
|
ELSE
|
Addr := 0;
|
Addr := 0;
|
IF Sect < SecNum THEN
|
IF Sect < SecNum THEN
|
Sect := Sect+1;
|
Sect := Sect+1;
|
ELSE
|
ELSE
|
REPORT "No more locations to read !!!"
|
REPORT "No more locations to read !!!"
|
SEVERITY warning;
|
SEVERITY warning;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
--word read;
|
--word read;
|
bus_cycle(bus_cmd => bus_read,
|
bus_cycle(bus_cmd => bus_read,
|
byte => byte,
|
byte => byte,
|
data => -1,
|
data => -1,
|
dataHi => -1,
|
dataHi => -1,
|
sector => Sect,
|
sector => Sect,
|
address => Addrfix);
|
address => Addrfix);
|
|
|
bus_cycle(bus_cmd => bus_output_disable, ----
|
bus_cycle(bus_cmd => bus_output_disable, ----
|
byte => byte); ----
|
byte => byte); ----
|
|
|
bus_cycle(bus_cmd => bus_enable,
|
bus_cycle(bus_cmd => bus_enable,
|
byte => byte,
|
byte => byte,
|
data => -1,
|
data => -1,
|
sector => -1,
|
sector => -1,
|
tm => 10 ns);
|
tm => 10 ns);
|
byte := true;
|
byte := true;
|
bus_cycle(bus_cmd => bus_enable,
|
bus_cycle(bus_cmd => bus_enable,
|
byte => byte,
|
byte => byte,
|
data => -1,
|
data => -1,
|
sector => -1,
|
sector => -1,
|
tm => 30 ns);
|
tm => 30 ns);
|
|
|
--first byte read
|
--first byte read
|
bus_cycle(bus_cmd => bus_read,
|
bus_cycle(bus_cmd => bus_read,
|
byte => byte,
|
byte => byte,
|
data => -1,
|
data => -1,
|
dataHi => -1,
|
dataHi => -1,
|
sector => Sect,
|
sector => Sect,
|
address => Addr);
|
address => Addr);
|
|
|
bus_cycle(bus_cmd => bus_output_disable, ----
|
bus_cycle(bus_cmd => bus_output_disable, ----
|
byte => byte); ----
|
byte => byte); ----
|
|
|
IF Addr < SecSize THEN
|
IF Addr < SecSize THEN
|
Addr := Addr+1;
|
Addr := Addr+1;
|
ELSE
|
ELSE
|
Addr := 0;
|
Addr := 0;
|
IF Sect < SecNum THEN
|
IF Sect < SecNum THEN
|
Sect := Sect+1;
|
Sect := Sect+1;
|
ELSE
|
ELSE
|
REPORT "No more locations to read !!!"
|
REPORT "No more locations to read !!!"
|
SEVERITY warning;
|
SEVERITY warning;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
i := i +3;
|
i := i +3;
|
wait for 10 ns; -------
|
wait for 10 ns; -------
|
ELSE
|
ELSE
|
byte := command.byte;
|
byte := command.byte;
|
END IF;
|
END IF;
|
--second byte read in byte toggle mode
|
--second byte read in byte toggle mode
|
bus_cycle(bus_cmd => bus_read,
|
bus_cycle(bus_cmd => bus_read,
|
byte => byte,
|
byte => byte,
|
data => -1,
|
data => -1,
|
dataHi => -1,
|
dataHi => -1,
|
sector => Sect,
|
sector => Sect,
|
address => Addr);
|
address => Addr);
|
|
|
|
|
IF Addr < SecSize THEN
|
IF Addr < SecSize THEN
|
Addr := Addr+1;
|
Addr := Addr+1;
|
ELSE
|
ELSE
|
Addr := 0;
|
Addr := 0;
|
IF Sect < SecNum THEN
|
IF Sect < SecNum THEN
|
Sect := Sect+1;
|
Sect := Sect+1;
|
ELSE
|
ELSE
|
REPORT "No more locations to read !!!"
|
REPORT "No more locations to read !!!"
|
SEVERITY warning;
|
SEVERITY warning;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
i := i +1;
|
i := i +1;
|
WAIT FOR 10 ns;
|
WAIT FOR 10 ns;
|
END LOOP;
|
END LOOP;
|
bus_cycle(bus_cmd => bus_output_disable,
|
bus_cycle(bus_cmd => bus_output_disable,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
|
|
|
|
WHEN w_cycle =>
|
WHEN w_cycle =>
|
|
|
D_lo := 16#AA# ; --first command data
|
D_lo := 16#AA# ; --first command data
|
Addr := 16#AAA#; --first command byte address
|
Addr := 16#AAA#; --first command byte address
|
D_hi := 16#55#; --second command data
|
D_hi := 16#55#; --second command data
|
Addrfix := 16#555#; --second command byte address
|
Addrfix := 16#555#; --second command byte address
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
--if word addressing
|
--if word addressing
|
Addr := 16#555#; --first command byte address
|
Addr := 16#555#; --first command byte address
|
Addrfix := 16#2AA#; --second command byte address
|
Addrfix := 16#2AA#; --second command byte address
|
END IF;
|
END IF;
|
|
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => D_lo,
|
data => D_lo,
|
dataHi => 0,
|
dataHi => 0,
|
sector => 0,
|
sector => 0,
|
address => Addr,
|
address => Addr,
|
violate => command.aux=violate,
|
violate => command.aux=violate,
|
tm => command.wtime);
|
tm => command.wtime);
|
|
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => D_hi,
|
data => D_hi,
|
dataHi => 0,
|
dataHi => 0,
|
sector => 0,
|
sector => 0,
|
address => Addrfix);
|
address => Addrfix);
|
|
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
|
|
WHEN w_reset | w_prog | w_erase | w_unlock |
|
WHEN w_reset | w_prog | w_erase | w_unlock |
|
w_autoselect | w_enter_sec =>
|
w_autoselect | w_enter_sec =>
|
Addr := 16#AAA#;
|
Addr := 16#AAA#;
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
--if word addressing
|
--if word addressing
|
Addr := 16#555#; --first command byte address
|
Addr := 16#555#; --first command byte address
|
END IF;
|
END IF;
|
|
|
CASE command.cmd IS
|
CASE command.cmd IS
|
WHEN w_reset =>
|
WHEN w_reset =>
|
d_lo := 16#F0#;
|
d_lo := 16#F0#;
|
WHEN w_prog =>
|
WHEN w_prog =>
|
d_lo := 16#A0#;
|
d_lo := 16#A0#;
|
WHEN w_erase =>
|
WHEN w_erase =>
|
d_lo := 16#80#;
|
d_lo := 16#80#;
|
WHEN w_unlock =>
|
WHEN w_unlock =>
|
d_lo := 16#20#;
|
d_lo := 16#20#;
|
WHEN w_autoselect =>
|
WHEN w_autoselect =>
|
d_lo := 16#90#;
|
d_lo := 16#90#;
|
WHEN w_enter_sec =>
|
WHEN w_enter_sec =>
|
d_lo := 16#88#;
|
d_lo := 16#88#;
|
WHEN OTHERS =>
|
WHEN OTHERS =>
|
d_lo := 0;
|
d_lo := 0;
|
END CASE;
|
END CASE;
|
|
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => d_lo,
|
data => d_lo,
|
dataHi => 0,
|
dataHi => 0,
|
sector => 0,
|
sector => 0,
|
address => Addr);
|
address => Addr);
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
|
|
|
|
WHEN w_unlock_reset =>
|
WHEN w_unlock_reset =>
|
Addr := 16#AAA#; --first command byte address
|
Addr := 16#AAA#; --first command byte address
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
--if word addressing
|
--if word addressing
|
Addr := 16#555#; --first command byte address
|
Addr := 16#555#; --first command byte address
|
END IF;
|
END IF;
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => 16#90#,
|
data => 16#90#,
|
dataHi => 0,
|
dataHi => 0,
|
sector => 0,
|
sector => 0,
|
address => Addr);
|
address => Addr);
|
|
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => 16#F0#,
|
data => 16#F0#,
|
dataHi => 0,
|
dataHi => 0,
|
sector => 0,
|
sector => 0,
|
address => Addr);
|
address => Addr);
|
|
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
WHEN w_chip_ers =>
|
WHEN w_chip_ers =>
|
Addr := 16#AAA#; --first command byte address
|
Addr := 16#AAA#; --first command byte address
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
--if word addressing
|
--if word addressing
|
Addr := 16#555#; --first command byte address
|
Addr := 16#555#; --first command byte address
|
END IF;
|
END IF;
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => 16#10#,
|
data => 16#10#,
|
dataHi => 0,
|
dataHi => 0,
|
sector => 0,
|
sector => 0,
|
Address => Addr);
|
Address => Addr);
|
FOR i IN 0 TO SecNum LOOP
|
FOR i IN 0 TO SecNum LOOP
|
IF Sec_Prot(i)/='1' THEN
|
IF Sec_Prot(i)/='1' THEN
|
mem(i) := (OTHERS=>16#FF#);
|
mem(i) := (OTHERS=>16#FF#);
|
END IF;
|
END IF;
|
END LOOP;
|
END LOOP;
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
|
|
WHEN w_cfi =>
|
WHEN w_cfi =>
|
Addr := 16#AA#; --first command byte address
|
Addr := 16#AA#; --first command byte address
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
--if word addressing
|
--if word addressing
|
Addr := 16#55#; --first command byte address
|
Addr := 16#55#; --first command byte address
|
END IF;
|
END IF;
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => 16#98#,
|
data => 16#98#,
|
dataHi => 0,
|
dataHi => 0,
|
sector => 0,
|
sector => 0,
|
Address => Addr);
|
Address => Addr);
|
|
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
|
|
|
|
WHEN w_suspend =>
|
WHEN w_suspend =>
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => 16#B0#,
|
data => 16#B0#,
|
dataHi => 0,
|
dataHi => 0,
|
sector => -1);
|
sector => -1);
|
|
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
WHEN w_resume =>
|
WHEN w_resume =>
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => 16#30#,
|
data => 16#30#,
|
dataHi => 0,
|
dataHi => 0,
|
sector => -1);
|
sector => -1);
|
|
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
|
|
WHEN w_data =>
|
WHEN w_data =>
|
|
|
D_hi := command.d_hi MOD 16#100#;
|
D_hi := command.d_hi MOD 16#100#;
|
D_lo := command.d_lo ;
|
D_lo := command.d_lo ;
|
Addr := command.addr;
|
Addr := command.addr;
|
Sect := command.sect;
|
Sect := command.sect;
|
|
|
bus_cycle(bus_cmd => bus_write,
|
bus_cycle(bus_cmd => bus_write,
|
byte => command.byte,
|
byte => command.byte,
|
data => D_lo,
|
data => D_lo,
|
dataHi => D_hi,
|
dataHi => D_hi,
|
sector => Sect,
|
sector => Sect,
|
address => Addr);
|
address => Addr);
|
|
|
bus_cycle(bus_cmd => bus_standby,
|
bus_cycle(bus_cmd => bus_standby,
|
byte => command.byte);
|
byte => command.byte);
|
|
|
|
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
Addr := Addr*2;
|
Addr := Addr*2;
|
END IF;
|
END IF;
|
|
|
--write value(s) in default mem
|
--write value(s) in default mem
|
IF status = erase_active AND Sec_Prot(Sect)/='1'THEN
|
IF status = erase_active AND Sec_Prot(Sect)/='1'THEN
|
--sector should be erased
|
--sector should be erased
|
mem(Sect) := (OTHERS=>16#FF#);
|
mem(Sect) := (OTHERS=>16#FF#);
|
|
|
ELSIF status = erase_na AND Sec_Prot(Sect)/='1'THEN
|
ELSIF status = erase_na AND Sec_Prot(Sect)/='1'THEN
|
--sector erase terminated = data integrity violated
|
--sector erase terminated = data integrity violated
|
mem(Sect) := (OTHERS=>-1);
|
mem(Sect) := (OTHERS=>-1);
|
|
|
ELSIF status = readX AND Sec_Prot(Sect)/='1' THEN
|
ELSIF status = readX AND Sec_Prot(Sect)/='1' THEN
|
mem(Sect)(Addr) := -1;
|
mem(Sect)(Addr) := -1;
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
mem(Sect)(Addr+1) := -1;
|
mem(Sect)(Addr+1) := -1;
|
END IF;
|
END IF;
|
|
|
-- Write to Secure Silicon Sector Region
|
-- Write to Secure Silicon Sector Region
|
ELSIF status = rd_SecSi AND FactoryProt/='1' THEN
|
ELSIF status = rd_SecSi AND FactoryProt/='1' THEN
|
slv_1 := to_slv(d_lo,8);
|
slv_1 := to_slv(d_lo,8);
|
IF SecSi(Addr)>-1 THEN
|
IF SecSi(Addr)>-1 THEN
|
slv_2 := to_slv(SecSi(Addr),8);
|
slv_2 := to_slv(SecSi(Addr),8);
|
ELSE
|
ELSE
|
slv_2 := (OTHERS=>'X');
|
slv_2 := (OTHERS=>'X');
|
END IF;
|
END IF;
|
|
|
FOR i IN 0 to 7 LOOP
|
FOR i IN 0 to 7 LOOP
|
IF slv_2(i)='0' THEN
|
IF slv_2(i)='0' THEN
|
slv_1(i):='0';
|
slv_1(i):='0';
|
END IF;
|
END IF;
|
END LOOP;
|
END LOOP;
|
SecSi(Addr) := to_nat(slv_1);
|
SecSi(Addr) := to_nat(slv_1);
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
slv_1 := to_slv(d_hi,8);
|
slv_1 := to_slv(d_hi,8);
|
IF SecSi(Addr+1)>-1 THEN
|
IF SecSi(Addr+1)>-1 THEN
|
slv_2 := to_slv(SecSi(Addr+1),8);
|
slv_2 := to_slv(SecSi(Addr+1),8);
|
ELSE
|
ELSE
|
slv_2 := (OTHERS=>'X');
|
slv_2 := (OTHERS=>'X');
|
END IF;
|
END IF;
|
FOR i IN 0 to 7 LOOP
|
FOR i IN 0 to 7 LOOP
|
IF slv_2(i)='0' THEN
|
IF slv_2(i)='0' THEN
|
slv_1(i):='0';
|
slv_1(i):='0';
|
END IF;
|
END IF;
|
END LOOP;
|
END LOOP;
|
SecSi(Addr+1) := to_nat(slv_1);
|
SecSi(Addr+1) := to_nat(slv_1);
|
END IF;
|
END IF;
|
|
|
ELSIF status=buff_wr_busy THEN
|
ELSIF status=buff_wr_busy THEN
|
--Write to Buffer command cycle
|
--Write to Buffer command cycle
|
null;
|
null;
|
|
|
ELSIF status=erase_na THEN
|
ELSIF status=erase_na THEN
|
--sector erase command sequence violation
|
--sector erase command sequence violation
|
null;
|
null;
|
|
|
-- Write to Flash Memory Array
|
-- Write to Flash Memory Array
|
ELSIF status /= err AND Sec_Prot(Sect)/='1'THEN
|
ELSIF status /= err AND Sec_Prot(Sect)/='1'THEN
|
slv_1 := to_slv(d_lo,8);
|
slv_1 := to_slv(d_lo,8);
|
IF mem(Sect)(Addr)>-1 THEN
|
IF mem(Sect)(Addr)>-1 THEN
|
slv_2 := to_slv(mem(Sect)(Addr),8);
|
slv_2 := to_slv(mem(Sect)(Addr),8);
|
ELSE
|
ELSE
|
slv_2 := (OTHERS=>'X');
|
slv_2 := (OTHERS=>'X');
|
END IF;
|
END IF;
|
|
|
FOR i IN 0 to 7 LOOP
|
FOR i IN 0 to 7 LOOP
|
IF slv_2(i)='0' THEN
|
IF slv_2(i)='0' THEN
|
slv_1(i):='0';
|
slv_1(i):='0';
|
END IF;
|
END IF;
|
END LOOP;
|
END LOOP;
|
mem(Sect)(Addr) := to_nat(slv_1);
|
mem(Sect)(Addr) := to_nat(slv_1);
|
IF NOT command.byte THEN
|
IF NOT command.byte THEN
|
slv_1 := to_slv(d_hi,8);
|
slv_1 := to_slv(d_hi,8);
|
IF mem(Sect)(Addr+1)>-1 THEN
|
IF mem(Sect)(Addr+1)>-1 THEN
|
slv_2 := to_slv(mem(Sect)(Addr+1),8);
|
slv_2 := to_slv(mem(Sect)(Addr+1),8);
|
ELSE
|
ELSE
|
slv_2 := (OTHERS=>'X');
|
slv_2 := (OTHERS=>'X');
|
END IF;
|
END IF;
|
FOR i IN 0 to 7 LOOP
|
FOR i IN 0 to 7 LOOP
|
IF slv_2(i)='0' THEN
|
IF slv_2(i)='0' THEN
|
slv_1(i):='0';
|
slv_1(i):='0';
|
END IF;
|
END IF;
|
END LOOP;
|
END LOOP;
|
mem(Sect)(Addr+1) := to_nat(slv_1);
|
mem(Sect)(Addr+1) := to_nat(slv_1);
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
|
|
|
|
WHEN wt =>
|
WHEN wt =>
|
WAIT FOR command.wtime;
|
WAIT FOR command.wtime;
|
|
|
WHEN wt_rdy =>
|
WHEN wt_rdy =>
|
IF T_RY/='1' THEN
|
IF T_RY/='1' THEN
|
WAIT UNTIL rising_edge(T_RY) FOR command.wtime;
|
WAIT UNTIL rising_edge(T_RY) FOR command.wtime;
|
END IF;
|
END IF;
|
|
|
WHEN wt_bsy =>
|
WHEN wt_bsy =>
|
IF T_RY='1' THEN
|
IF T_RY='1' THEN
|
WAIT UNTIL falling_edge(T_RY) FOR command.wtime;
|
WAIT UNTIL falling_edge(T_RY) FOR command.wtime;
|
END IF;
|
END IF;
|
|
|
WHEN OTHERS => null;
|
WHEN OTHERS => null;
|
END CASE;
|
END CASE;
|
END PROCEDURE;
|
END PROCEDURE;
|
|
|
|
|
VARIABLE cmd_cnt : NATURAL;
|
VARIABLE cmd_cnt : NATURAL;
|
VARIABLE command : cmd_rec; --
|
VARIABLE command : cmd_rec; --
|
|
|
BEGIN
|
BEGIN
|
Pick_TC (Model => "AM29LV640MH90R" );
|
Pick_TC (Model => "AM29LV640MH90R" );
|
|
|
Tseries <= ts_cnt ;
|
Tseries <= ts_cnt ;
|
Tcase <= tc_cnt ;
|
Tcase <= tc_cnt ;
|
|
|
Generate_TC
|
Generate_TC
|
(Model => "AM29LV640MH90R" ,
|
(Model => "AM29LV640MH90R" ,
|
Series => ts_cnt,
|
Series => ts_cnt,
|
TestCase => tc_cnt,
|
TestCase => tc_cnt,
|
command_seq => cmd_seq);
|
command_seq => cmd_seq);
|
|
|
|
|
cmd_cnt := 1;
|
cmd_cnt := 1;
|
WHILE cmd_seq(cmd_cnt).cmd/=done LOOP
|
WHILE cmd_seq(cmd_cnt).cmd/=done LOOP
|
command:= cmd_seq(cmd_cnt);
|
command:= cmd_seq(cmd_cnt);
|
IF command.sect = -1 THEN
|
IF command.sect = -1 THEN
|
command.sect := ProtSecNum;
|
command.sect := ProtSecNum;
|
END IF;
|
END IF;
|
status <= command.status;
|
status <= command.status;
|
sts_check<= to_slv(command.d_lo,8); --used only for toggle/status check
|
sts_check<= to_slv(command.d_lo,8); --used only for toggle/status check
|
cmd_dc(command);
|
cmd_dc(command);
|
cmd_cnt :=cmd_cnt +1;
|
cmd_cnt :=cmd_cnt +1;
|
|
|
END LOOP;
|
END LOOP;
|
|
|
END PROCESS tb;
|
END PROCESS tb;
|
|
|
--process to monitor WP#
|
--process to monitor WP#
|
PROCESS(T_WPNeg)
|
PROCESS(T_WPNeg)
|
VARIABLE reg : std_logic;
|
VARIABLE reg : std_logic;
|
BEGIN
|
BEGIN
|
IF falling_edge(T_WPNeg) THEN
|
IF falling_edge(T_WPNeg) THEN
|
reg := Sec_Prot(ProtSecNum);
|
reg := Sec_Prot(ProtSecNum);
|
Sec_Prot(ProtSecNum) := '1';
|
Sec_Prot(ProtSecNum) := '1';
|
ELSIF rising_edge(T_WPNeg) THEN
|
ELSIF rising_edge(T_WPNeg) THEN
|
Sec_Prot(ProtSecNum) := reg;
|
Sec_Prot(ProtSecNum) := reg;
|
END IF;
|
END IF;
|
END PROCESS;
|
END PROCESS;
|
|
|
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
-- Checker process,
|
-- Checker process,
|
-- Bus transition extractor: when bus cycle is read samples addr and data
|
-- Bus transition extractor: when bus cycle is read samples addr and data
|
-- Transition checker : verifies correct read data using default memory
|
-- Transition checker : verifies correct read data using default memory
|
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
checker: PROCESS
|
checker: PROCESS
|
VARIABLE RAddr : NATURAL;
|
VARIABLE RAddr : NATURAL;
|
VARIABLE RSect : NATURAL;
|
VARIABLE RSect : NATURAL;
|
VARIABLE longread : boolean;
|
VARIABLE longread : boolean;
|
VARIABLE shortread : boolean;
|
VARIABLE shortread : boolean;
|
VARIABLE toggle : boolean:=false;
|
VARIABLE toggle : boolean:=false;
|
VARIABLE toggle_sts : std_logic_vector(7 downto 0);
|
VARIABLE toggle_sts : std_logic_vector(7 downto 0);
|
|
|
BEGIN
|
BEGIN
|
-- Transition extractor
|
-- Transition extractor
|
IF (T_CENeg='0'AND T_OENeg='0'AND T_WENeg='1') THEN
|
IF (T_CENeg='0'AND T_OENeg='0'AND T_WENeg='1') THEN
|
IF T_BYTENeg='1' THEN
|
IF T_BYTENeg='1' THEN
|
RAddr := to_nat(T_A(14 downto 0)&'0');
|
RAddr := to_nat(T_A(14 downto 0)&'0');
|
ELSE
|
ELSE
|
RAddr := to_nat(T_A(14 downto 0)&T_DQ(15));
|
RAddr := to_nat(T_A(14 downto 0)&T_DQ(15));
|
END IF;
|
END IF;
|
RSect := to_nat(T_A(HiAddrBit downto 15));
|
RSect := to_nat(T_A(HiAddrBit downto 15));
|
|
|
shortread:= false;
|
shortread:= false;
|
longread := false;
|
longread := false;
|
|
|
--DUT specific timing
|
--DUT specific timing
|
IF (T_CENeg'EVENT OR T_WENeg'EVENT OR T_A(HiAddrBit downto 2)'EVENT)AND --
|
IF (T_CENeg'EVENT OR T_WENeg'EVENT OR T_A(HiAddrBit downto 2)'EVENT)AND --
|
(status=read OR status=rd_cfi OR status=rd_secsi) THEN --OR status=readX)
|
(status=read OR status=rd_cfi OR status=rd_secsi) THEN --OR status=readX)
|
longread := true;
|
longread := true;
|
CASE TimingModel IS
|
CASE TimingModel IS
|
WHEN "AM29LV640MH90R" |
|
WHEN "AM29LV640MH90R" |
|
"AM29LV640ML90R" => WAIT FOR 95 ns;
|
"AM29LV640ML90R" => WAIT FOR 95 ns;
|
-- WHEN "AM29LV640MH101" |
|
-- WHEN "AM29LV640MH101" |
|
-- "AM29LV640ML101" => WAIT FOR 105 ns;
|
-- "AM29LV640ML101" => WAIT FOR 105 ns;
|
-- WHEN "AM29LV640MH101R" |
|
-- WHEN "AM29LV640MH101R" |
|
-- "AM29LV640ML101R" => WAIT FOR 105 ns;
|
-- "AM29LV640ML101R" => WAIT FOR 105 ns;
|
-- WHEN "AM29LV640MH112" |
|
-- WHEN "AM29LV640MH112" |
|
-- "AM29LV640ML112" => WAIT FOR 115 ns;
|
-- "AM29LV640ML112" => WAIT FOR 115 ns;
|
-- WHEN "AM29LV640MH112R" |
|
-- WHEN "AM29LV640MH112R" |
|
-- "AM29LV640ML112R" => WAIT FOR 115 ns;
|
-- "AM29LV640ML112R" => WAIT FOR 115 ns;
|
-- WHEN "AM29LV640MH120" |
|
-- WHEN "AM29LV640MH120" |
|
-- "AM29LV640ML120" => WAIT FOR 125 ns;
|
-- "AM29LV640ML120" => WAIT FOR 125 ns;
|
-- WHEN "AM29LV640MH120R" |
|
-- WHEN "AM29LV640MH120R" |
|
-- "AM29LV640ML120R" => WAIT FOR 125 ns;
|
-- "AM29LV640ML120R" => WAIT FOR 125 ns;
|
WHEN OTHERS =>
|
WHEN OTHERS =>
|
REPORT "Timing model NOT supported : "&TimingModel
|
REPORT "Timing model NOT supported : "&TimingModel
|
SEVERITY error;
|
SEVERITY error;
|
END CASE;
|
END CASE;
|
|
|
ELSIF T_A(1 downto 0)'EVENT OR
|
ELSIF T_A(1 downto 0)'EVENT OR
|
(T_DQ(15)'EVENT AND T_BYTENeg='0')OR
|
(T_DQ(15)'EVENT AND T_BYTENeg='0')OR
|
(T_BYTENeg'EVENT) OR
|
(T_BYTENeg'EVENT) OR
|
T_OENeg'EVENT OR
|
T_OENeg'EVENT OR
|
(status/=read AND status/=rd_cfi AND
|
(status/=read AND status/=rd_cfi AND
|
status/=rd_secsi) THEN --AND status/=readX)
|
status/=rd_secsi) THEN --AND status/=readX)
|
shortread:=true;
|
shortread:=true;
|
CASE TimingModel IS
|
CASE TimingModel IS
|
WHEN "AM29LV640MH90R" |
|
WHEN "AM29LV640MH90R" |
|
"AM29LV640ML90R" => WAIT FOR 30 ns;
|
"AM29LV640ML90R" => WAIT FOR 30 ns;
|
-- WHEN "AM29LV640MH101" |
|
-- WHEN "AM29LV640MH101" |
|
-- "AM29LV640ML101" => WAIT FOR 40 ns;
|
-- "AM29LV640ML101" => WAIT FOR 40 ns;
|
-- WHEN "AM29LV640MH101R" |
|
-- WHEN "AM29LV640MH101R" |
|
-- "AM29LV640ML101R" => WAIT FOR 40 ns;
|
-- "AM29LV640ML101R" => WAIT FOR 40 ns;
|
-- WHEN "AM29LV640MH112" |
|
-- WHEN "AM29LV640MH112" |
|
-- "AM29LV640ML112" => WAIT FOR 45 ns;
|
-- "AM29LV640ML112" => WAIT FOR 45 ns;
|
-- WHEN "AM29LV640MH112R" |
|
-- WHEN "AM29LV640MH112R" |
|
-- "AM29LV640ML112R" => WAIT FOR 45 ns;
|
-- "AM29LV640ML112R" => WAIT FOR 45 ns;
|
-- WHEN "AM29LV640MH120" |
|
-- WHEN "AM29LV640MH120" |
|
-- "AM29LV640ML120" => WAIT FOR 45 ns;
|
-- "AM29LV640ML120" => WAIT FOR 45 ns;
|
-- WHEN "AM29LV640MH120R" |
|
-- WHEN "AM29LV640MH120R" |
|
-- "AM29LV640ML120R" => WAIT FOR 45 ns;
|
-- "AM29LV640ML120R" => WAIT FOR 45 ns;
|
WHEN OTHERS =>
|
WHEN OTHERS =>
|
REPORT "Timing model NOT supported : "&TimingModel
|
REPORT "Timing model NOT supported : "&TimingModel
|
SEVERITY error;
|
SEVERITY error;
|
END CASE;
|
END CASE;
|
|
|
END IF;
|
END IF;
|
|
|
|
|
|
|
--Checker
|
--Checker
|
IF longread OR shortread THEN
|
IF longread OR shortread THEN
|
|
|
CASE status IS
|
CASE status IS
|
WHEN none =>
|
WHEN none =>
|
toggle := false;
|
toggle := false;
|
|
|
-- read memory array data
|
-- read memory array data
|
WHEN read =>
|
WHEN read =>
|
toggle := false;
|
toggle := false;
|
Check_read (
|
Check_read (
|
DQ => T_DQ,
|
DQ => T_DQ,
|
D_lo => mem(RSect)(RAddr),
|
D_lo => mem(RSect)(RAddr),
|
D_hi => mem(RSect)(RAddr+1),
|
D_hi => mem(RSect)(RAddr+1),
|
Byte => T_BYTENeg,
|
Byte => T_BYTENeg,
|
check_err=> check_err);
|
check_err=> check_err);
|
|
|
-- read secure silicon region
|
-- read secure silicon region
|
WHEN rd_secsi =>
|
WHEN rd_secsi =>
|
toggle := false;
|
toggle := false;
|
Check_SecSi (
|
Check_SecSi (
|
DQ => T_DQ,
|
DQ => T_DQ,
|
D_lo => SecSi(RAddr),
|
D_lo => SecSi(RAddr),
|
D_hi => SecSi(RAddr+1),
|
D_hi => SecSi(RAddr+1),
|
Byte => T_BYTENeg,
|
Byte => T_BYTENeg,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
|
|
--read CFI query codes
|
--read CFI query codes
|
WHEN rd_cfi =>
|
WHEN rd_cfi =>
|
RAddr := to_nat(T_A(14 downto 0)); --x16 addressing
|
RAddr := to_nat(T_A(14 downto 0)); --x16 addressing
|
toggle := false;
|
toggle := false;
|
Check_CFI (
|
Check_CFI (
|
DQ => T_DQ,
|
DQ => T_DQ,
|
D_lo => CFI_array(RAddr) ,
|
D_lo => CFI_array(RAddr) ,
|
D_hi => 0 ,
|
D_hi => 0 ,
|
Byte => T_BYTENeg,
|
Byte => T_BYTENeg,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
|
|
|
|
-- read Autoselect codes
|
-- read Autoselect codes
|
WHEN rd_AS =>
|
WHEN rd_AS =>
|
RAddr := to_nat(T_A(14 downto 0)); --x16 addressing
|
RAddr := to_nat(T_A(14 downto 0)); --x16 addressing
|
toggle := false;
|
toggle := false;
|
Check_AS (
|
Check_AS (
|
DQ => T_DQ,
|
DQ => T_DQ,
|
addr => RAddr,
|
addr => RAddr,
|
ProtSecNum=>ProtSecNum,
|
ProtSecNum=>ProtSecNum,
|
secProt => Sec_Prot(RSect),
|
secProt => Sec_Prot(RSect),
|
FactoryProt=>FactoryProt ,
|
FactoryProt=>FactoryProt ,
|
Byte => T_BYTENeg,
|
Byte => T_BYTENeg,
|
AS_E => to_slv(16#0C#,8),
|
AS_E => to_slv(16#0C#,8),
|
AS_F => to_slv(1,8),
|
AS_F => to_slv(1,8),
|
|
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
|
|
WHEN rd_HiZ =>
|
WHEN rd_HiZ =>
|
toggle:=false;
|
toggle:=false;
|
Check_Z (
|
Check_Z (
|
DQ => T_DQ,
|
DQ => T_DQ,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
|
|
|
|
WHEN readX =>
|
WHEN readX =>
|
toggle:=false;
|
toggle:=false;
|
Check_X (
|
Check_X (
|
DQ => T_DQ,
|
DQ => T_DQ,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
|
|
WHEN erase_na | erase_active =>
|
WHEN erase_na | erase_active =>
|
IF toggle THEN
|
IF toggle THEN
|
Check_Erase (
|
Check_Erase (
|
DQ => T_DQ(7 downto 0),
|
DQ => T_DQ(7 downto 0),
|
sts => status,
|
sts => status,
|
toggle => toggle_sts,
|
toggle => toggle_sts,
|
sts_check=>sts_check,
|
sts_check=>sts_check,
|
RY => T_RY,
|
RY => T_RY,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
END IF;
|
END IF;
|
|
|
WHEN ers_susp_e =>
|
WHEN ers_susp_e =>
|
IF toggle THEN
|
IF toggle THEN
|
Check_Ers_Susp (
|
Check_Ers_Susp (
|
DQ => T_DQ(7 downto 0),
|
DQ => T_DQ(7 downto 0),
|
sts => status,
|
sts => status,
|
toggle => toggle_sts,
|
toggle => toggle_sts,
|
sts_check=>sts_check,
|
sts_check=>sts_check,
|
RY => T_RY,
|
RY => T_RY,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
|
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
END IF;
|
END IF;
|
|
|
--
|
--
|
|
|
WHEN ers_susp_prog_na | ers_susp_prog =>
|
WHEN ers_susp_prog_na | ers_susp_prog =>
|
IF toggle THEN
|
IF toggle THEN
|
Check_Ers_Susp_Prog (
|
Check_Ers_Susp_Prog (
|
DQ => T_DQ(7 downto 0),
|
DQ => T_DQ(7 downto 0),
|
sts => status,
|
sts => status,
|
toggle => toggle_sts,
|
toggle => toggle_sts,
|
sts_check=>sts_check,
|
sts_check=>sts_check,
|
RY => T_RY,
|
RY => T_RY,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
END IF;
|
END IF;
|
|
|
--
|
--
|
|
|
WHEN prog_na | prog_active =>
|
WHEN prog_na | prog_active =>
|
IF toggle THEN
|
IF toggle THEN
|
Check_Progr (
|
Check_Progr (
|
DQ => T_DQ(7 downto 0),
|
DQ => T_DQ(7 downto 0),
|
sts => status,
|
sts => status,
|
toggle => toggle_sts,
|
toggle => toggle_sts,
|
sts_check=>sts_check,
|
sts_check=>sts_check,
|
RY => T_RY,
|
RY => T_RY,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
END IF;
|
END IF;
|
|
|
WHEN buff_wr_busy | buff_wr_N_busy =>
|
WHEN buff_wr_busy | buff_wr_N_busy =>
|
IF toggle THEN
|
IF toggle THEN
|
Check_Buff_Busy (
|
Check_Buff_Busy (
|
DQ => T_DQ(7 downto 0),
|
DQ => T_DQ(7 downto 0),
|
sts => status,
|
sts => status,
|
toggle => toggle_sts,
|
toggle => toggle_sts,
|
sts_check=>sts_check,
|
sts_check=>sts_check,
|
RY => T_RY,
|
RY => T_RY,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
END IF;
|
END IF;
|
|
|
WHEN buff_abort =>
|
WHEN buff_abort =>
|
IF toggle THEN
|
IF toggle THEN
|
Check_Abort (
|
Check_Abort (
|
DQ => T_DQ(7 downto 0),
|
DQ => T_DQ(7 downto 0),
|
sts => status,
|
sts => status,
|
toggle => toggle_sts,
|
toggle => toggle_sts,
|
sts_check=>sts_check,
|
sts_check=>sts_check,
|
RY => T_RY,
|
RY => T_RY,
|
check_err=>check_err);
|
check_err=>check_err);
|
|
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
toggle_sts := T_DQ(7 downto 0); --update toggle check
|
END IF;
|
END IF;
|
WHEN OTHERS => null;
|
WHEN OTHERS => null;
|
END CASE;
|
END CASE;
|
|
|
-- get firs data for toggle check
|
-- get firs data for toggle check
|
CASE status IS
|
CASE status IS
|
WHEN prog_active | prog_na |
|
WHEN prog_active | prog_na |
|
erase_active | erase_na |
|
erase_active | erase_na |
|
ers_susp_e |
|
ers_susp_e |
|
ers_susp_prog | ers_susp_prog_na |
|
ers_susp_prog | ers_susp_prog_na |
|
buff_wr_busy | buff_wr_N_busy |
|
buff_wr_busy | buff_wr_N_busy |
|
buff_abort | get_toggle =>
|
buff_abort | get_toggle =>
|
|
|
IF (NOT toggle) OR (status=get_toggle) THEN
|
IF (NOT toggle) OR (status=get_toggle) THEN
|
toggle:=true;
|
toggle:=true;
|
toggle_sts := T_DQ(7 downto 0);
|
toggle_sts := T_DQ(7 downto 0);
|
END IF;
|
END IF;
|
|
|
WHEN OTHERS => null;
|
WHEN OTHERS => null;
|
END CASE;
|
END CASE;
|
|
|
|
|
END IF;
|
END IF;
|
|
|
END IF;
|
END IF;
|
|
|
WAIT ON T_A, T_CENeg, T_OENeg, T_WENeg, T_DQ(15), T_BYTENeg;
|
WAIT ON T_A, T_CENeg, T_OENeg, T_WENeg, T_DQ(15), T_BYTENeg;
|
|
|
END PROCESS checker;
|
END PROCESS checker;
|
|
|
|
|
default: PROCESS
|
default: PROCESS
|
-- text file input variables
|
-- text file input variables
|
FILE mem_f : text is mem_file;
|
FILE mem_f : text is mem_file;
|
FILE prot_f : text is prot_file;
|
FILE prot_f : text is prot_file;
|
FILE secsi_f : text is secsi_file;
|
FILE secsi_f : text is secsi_file;
|
|
|
VARIABLE S_ind : NATURAL RANGE 0 TO SecNum:= 0;
|
VARIABLE S_ind : NATURAL RANGE 0 TO SecNum:= 0;
|
VARIABLE ind : NATURAL RANGE 0 TO SecSize:= 0;
|
VARIABLE ind : NATURAL RANGE 0 TO SecSize:= 0;
|
VARIABLE buf : line;
|
VARIABLE buf : line;
|
|
|
BEGIN
|
BEGIN
|
--Preload Control
|
--Preload Control
|
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
-- File Read Section
|
-- File Read Section
|
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
IF UserPreload THEN
|
IF UserPreload THEN
|
--- Sector protection preload
|
--- Sector protection preload
|
IF (prot_file /= "none" ) THEN
|
IF (prot_file /= "none" ) THEN
|
ind := 0;
|
ind := 0;
|
FactoryProt := '0';
|
FactoryProt := '0';
|
Sec_Prot := (OTHERS => '0');
|
Sec_Prot := (OTHERS => '0');
|
WHILE (not ENDFILE (prot_f)) LOOP
|
WHILE (not ENDFILE (prot_f)) LOOP
|
READLINE (prot_f, buf);
|
READLINE (prot_f, buf);
|
IF buf(1) = '/' THEN
|
IF buf(1) = '/' THEN
|
NEXT;
|
NEXT;
|
ELSIF buf(1) = '@' THEN
|
ELSIF buf(1) = '@' THEN
|
ind := h(buf(2 to 3)); --address
|
ind := h(buf(2 to 3)); --address
|
ELSE
|
ELSE
|
IF ind > SecNum THEN
|
IF ind > SecNum THEN
|
--SecSi Factory protect preload
|
--SecSi Factory protect preload
|
IF buf(1)='1' THEN
|
IF buf(1)='1' THEN
|
FactoryProt := '1';
|
FactoryProt := '1';
|
END IF;
|
END IF;
|
ELSE
|
ELSE
|
-- Standard Sector prload
|
-- Standard Sector prload
|
IF buf(1)='1' THEN
|
IF buf(1)='1' THEN
|
Sec_Prot(ind):= '1';
|
Sec_Prot(ind):= '1';
|
END IF;
|
END IF;
|
ind := ind + 1;
|
ind := ind + 1;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END LOOP;
|
END LOOP;
|
END IF;
|
END IF;
|
|
|
-- Secure Silicon Sector Region preload
|
-- Secure Silicon Sector Region preload
|
IF (SecSi_file /= "none" ) THEN
|
IF (SecSi_file /= "none" ) THEN
|
SecSi := (OTHERS => MaxData);
|
SecSi := (OTHERS => MaxData);
|
ind := 0;
|
ind := 0;
|
WHILE (not ENDFILE (SecSi_f)) LOOP
|
WHILE (not ENDFILE (SecSi_f)) LOOP
|
READLINE (SecSi_f, buf);
|
READLINE (SecSi_f, buf);
|
IF buf(1) = '/' THEN
|
IF buf(1) = '/' THEN
|
NEXT;
|
NEXT;
|
ELSIF buf(1) = '@' THEN
|
ELSIF buf(1) = '@' THEN
|
ind := h(buf(2 to 3)); --address
|
ind := h(buf(2 to 3)); --address
|
ELSE
|
ELSE
|
IF ind <= SecSiSize THEN
|
IF ind <= SecSiSize THEN
|
SecSi(ind) := h(buf(1 TO 2));
|
SecSi(ind) := h(buf(1 TO 2));
|
ind := ind + 1;
|
ind := ind + 1;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END LOOP;
|
END LOOP;
|
END IF;
|
END IF;
|
|
|
--- Memory Preload
|
--- Memory Preload
|
IF (mem_file /= "none" ) THEN
|
IF (mem_file /= "none" ) THEN
|
ind := 0;
|
ind := 0;
|
Mem := (OTHERS => (OTHERS => MaxData));
|
Mem := (OTHERS => (OTHERS => MaxData));
|
-- load sector 0
|
-- load sector 0
|
WHILE (not ENDFILE (mem_f)) LOOP
|
WHILE (not ENDFILE (mem_f)) LOOP
|
READLINE (mem_f, buf);
|
READLINE (mem_f, buf);
|
IF buf(1) = '/' THEN
|
IF buf(1) = '/' THEN
|
NEXT;
|
NEXT;
|
ELSIF buf(1) = '@' THEN
|
ELSIF buf(1) = '@' THEN
|
ind := h(buf(2 to 5)); --address
|
ind := h(buf(2 to 5)); --address
|
ELSE
|
ELSE
|
IF ind <= SecSize THEN
|
IF ind <= SecSize THEN
|
Mem(0)(ind) := h(buf(1 to 2));
|
Mem(0)(ind) := h(buf(1 to 2));
|
ind := ind + 1;
|
ind := ind + 1;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END LOOP;
|
END LOOP;
|
-- load other sectors
|
-- load other sectors
|
FOR i IN 1 TO SecNum LOOP
|
FOR i IN 1 TO SecNum LOOP
|
Mem(i) := Mem(0);
|
Mem(i) := Mem(0);
|
END LOOP;
|
END LOOP;
|
END IF;
|
END IF;
|
|
|
END IF;
|
END IF;
|
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
--CFI array data / AM29LV640MH90R !!! DEVICE SPECIFIC
|
--CFI array data / AM29LV640MH90R !!! DEVICE SPECIFIC
|
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
--CFI query identification string
|
--CFI query identification string
|
-- !!!!!! WORD ADDRESSES (x16) - for x8 addressing double addr
|
-- !!!!!! WORD ADDRESSES (x16) - for x8 addressing double addr
|
--CFI query identification string
|
--CFI query identification string
|
CFI_array(16#10#) := 16#51#;
|
CFI_array(16#10#) := 16#51#;
|
CFI_array(16#11#) := 16#52#;
|
CFI_array(16#11#) := 16#52#;
|
CFI_array(16#12#) := 16#59#;
|
CFI_array(16#12#) := 16#59#;
|
CFI_array(16#13#) := 16#02#;
|
CFI_array(16#13#) := 16#02#;
|
CFI_array(16#14#) := 16#00#;
|
CFI_array(16#14#) := 16#00#;
|
CFI_array(16#15#) := 16#40#;
|
CFI_array(16#15#) := 16#40#;
|
CFI_array(16#16#) := 16#00#;
|
CFI_array(16#16#) := 16#00#;
|
CFI_array(16#17#) := 16#00#;
|
CFI_array(16#17#) := 16#00#;
|
CFI_array(16#18#) := 16#00#;
|
CFI_array(16#18#) := 16#00#;
|
CFI_array(16#19#) := 16#00#;
|
CFI_array(16#19#) := 16#00#;
|
CFI_array(16#1A#) := 16#00#;
|
CFI_array(16#1A#) := 16#00#;
|
--system interface string
|
--system interface string
|
CFI_array(16#1B#) := 16#27#;
|
CFI_array(16#1B#) := 16#27#;
|
CFI_array(16#1C#) := 16#36#;
|
CFI_array(16#1C#) := 16#36#;
|
CFI_array(16#1D#) := 16#00#;
|
CFI_array(16#1D#) := 16#00#;
|
CFI_array(16#1E#) := 16#00#;
|
CFI_array(16#1E#) := 16#00#;
|
CFI_array(16#1F#) := 16#07#;
|
CFI_array(16#1F#) := 16#07#;
|
CFI_array(16#20#) := 16#07#;
|
CFI_array(16#20#) := 16#07#;
|
CFI_array(16#21#) := 16#0A#;
|
CFI_array(16#21#) := 16#0A#;
|
CFI_array(16#22#) := 16#00#;
|
CFI_array(16#22#) := 16#00#;
|
CFI_array(16#23#) := 16#01#;
|
CFI_array(16#23#) := 16#01#;
|
CFI_array(16#24#) := 16#05#;
|
CFI_array(16#24#) := 16#05#;
|
CFI_array(16#25#) := 16#04#;
|
CFI_array(16#25#) := 16#04#;
|
CFI_array(16#26#) := 16#00#;
|
CFI_array(16#26#) := 16#00#;
|
--device geometry definition
|
--device geometry definition
|
CFI_array(16#27#) := 16#17#;
|
CFI_array(16#27#) := 16#17#;
|
CFI_array(16#28#) := 16#02#;
|
CFI_array(16#28#) := 16#02#;
|
CFI_array(16#29#) := 16#00#;
|
CFI_array(16#29#) := 16#00#;
|
CFI_array(16#2A#) := 16#05#;
|
CFI_array(16#2A#) := 16#05#;
|
CFI_array(16#2B#) := 16#00#;
|
CFI_array(16#2B#) := 16#00#;
|
CFI_array(16#2C#) := 16#01#;
|
CFI_array(16#2C#) := 16#01#;
|
CFI_array(16#2D#) := 16#7F#;
|
CFI_array(16#2D#) := 16#7F#;
|
CFI_array(16#2E#) := 16#00#;
|
CFI_array(16#2E#) := 16#00#;
|
CFI_array(16#2F#) := 16#00#;
|
CFI_array(16#2F#) := 16#00#;
|
CFI_array(16#30#) := 16#01#;
|
CFI_array(16#30#) := 16#01#;
|
CFI_array(16#31#) := 16#00#;
|
CFI_array(16#31#) := 16#00#;
|
CFI_array(16#32#) := 16#00#;
|
CFI_array(16#32#) := 16#00#;
|
CFI_array(16#33#) := 16#00#;
|
CFI_array(16#33#) := 16#00#;
|
CFI_array(16#34#) := 16#00#;
|
CFI_array(16#34#) := 16#00#;
|
CFI_array(16#35#) := 16#00#;
|
CFI_array(16#35#) := 16#00#;
|
CFI_array(16#36#) := 16#00#;
|
CFI_array(16#36#) := 16#00#;
|
CFI_array(16#37#) := 16#00#;
|
CFI_array(16#37#) := 16#00#;
|
CFI_array(16#38#) := 16#00#;
|
CFI_array(16#38#) := 16#00#;
|
CFI_array(16#39#) := 16#00#;
|
CFI_array(16#39#) := 16#00#;
|
CFI_array(16#3A#) := 16#00#;
|
CFI_array(16#3A#) := 16#00#;
|
CFI_array(16#3B#) := 16#00#;
|
CFI_array(16#3B#) := 16#00#;
|
CFI_array(16#3C#) := 16#00#;
|
CFI_array(16#3C#) := 16#00#;
|
--primary vendor-specific extended query
|
--primary vendor-specific extended query
|
CFI_array(16#40#) := 16#50#;
|
CFI_array(16#40#) := 16#50#;
|
CFI_array(16#41#) := 16#52#;
|
CFI_array(16#41#) := 16#52#;
|
CFI_array(16#42#) := 16#49#;
|
CFI_array(16#42#) := 16#49#;
|
CFI_array(16#43#) := 16#31#;
|
CFI_array(16#43#) := 16#31#;
|
CFI_array(16#44#) := 16#33#;
|
CFI_array(16#44#) := 16#33#;
|
CFI_array(16#45#) := 16#08#;
|
CFI_array(16#45#) := 16#08#;
|
CFI_array(16#46#) := 16#02#;
|
CFI_array(16#46#) := 16#02#;
|
CFI_array(16#47#) := 16#01#;
|
CFI_array(16#47#) := 16#01#;
|
CFI_array(16#48#) := 16#01#;
|
CFI_array(16#48#) := 16#01#;
|
CFI_array(16#49#) := 16#04#;
|
CFI_array(16#49#) := 16#04#;
|
CFI_array(16#4A#) := 16#00#;
|
CFI_array(16#4A#) := 16#00#;
|
CFI_array(16#4B#) := 16#00#;
|
CFI_array(16#4B#) := 16#00#;
|
CFI_array(16#4C#) := 16#01#;
|
CFI_array(16#4C#) := 16#01#;
|
CFI_array(16#4D#) := 16#B5#;
|
CFI_array(16#4D#) := 16#B5#;
|
CFI_array(16#4E#) := 16#C5#;
|
CFI_array(16#4E#) := 16#C5#;
|
IF TimingModel(11) = 'L' THEN
|
IF TimingModel(11) = 'L' THEN
|
CFI_array(16#4F#) := 16#04#;
|
CFI_array(16#4F#) := 16#04#;
|
ELSE
|
ELSE
|
CFI_array(16#4F#) := 16#05#; --uniform sectors top protect
|
CFI_array(16#4F#) := 16#05#; --uniform sectors top protect
|
END IF;
|
END IF;
|
CFI_array(16#50#) := 16#01#;
|
CFI_array(16#50#) := 16#01#;
|
|
|
WAIT;
|
WAIT;
|
|
|
END PROCESS default;
|
END PROCESS default;
|
|
|
|
|
|
|
END vhdl_behavioral;
|
END vhdl_behavioral;
|
|
|
|
|