Files
vhdl/lib/models/memory/flash/serial/S25fl128s/model/s25fl128s.vhd
T
jens 2edaa4d7cb - added models
git-svn-id: http://moon:8086/svn/vhdl/trunk@1290 cc03376c-175c-47c8-b038-4cd826a8556b
2015-06-10 19:27:35 +00:00

7180 lines
341 KiB
VHDL

-------------------------------------------------------------------------------
-- File Name: s25fl128s.vhd
-------------------------------------------------------------------------------
-- Copyright (C) 2012 Spansion, LLC.
--
-- MODIFICATION HISTORY:
--
-- version: | author: | mod date: | changes made:
-- V1.0 V.Mancev 09 Nov 25 Inital Release
-- V1.1 V.Mancev 10 Feb 24 addr_cnt for second read in
-- high performance read continuous
-- mode can change its value only
-- when CSNeg = '0'
-- V1.2 V.Mancev 10 July 29 During the QUAD mode HOLD# input
-- is not monitored for its normal
-- function
-- V1.3 B.Colakovic 10 Aug 24 All redundant signals are removed from
-- BusCycle process
-- V1.4 R.Prokopovic 10 Oct 21 Latest datasheet aligned
-- V.Mancev
-- V1.5 R.Prokopovic 10 Oct 22 Read Configuration register added for any
-- V.Mancev state. Hybrid configuration added
-- V1.6 R.Prokopovic 10 Nov 12 QUAD Program operation during Erase
-- V.Mancev Suspend is added. Warning for Resume to
-- Suspend time is added. During Erase
-- Suspend, after Program operation is
-- completed, WEL bit is cleared.
-- Implemetation of Software Reset is
-- changed.
-- V1.7 V. Mancev 11 May 11 Condition for CS# High Time
-- (Program/Erase) is fixed
-- V1.8 V. Mancev 11 July 01 Latest datasheet aligned
-- V1.9 V. Mancev 11 Nov 16 Time tHO is changed to 1 ns
-- (customer's request)
-- BRWR instruction is corrected
-- V1.10 S.Petrovic 12 Aug 28 QPP Instruction is allowed on
-- previously programmed page
--
-------------------------------------------------------------------------------
-- PART DESCRIPTION:
--
-- Library: FLASH
-- Technology: FLASH MEMORY
-- Part: S25FL128S
--
-- Description: 128 Megabit Serial Flash Memory
--
-------------------------------------------------------------------------------
-- Comments :
-- For correct simulation, simulator resolution should be set to 1 ps
-- A device ordering (trim) option determines whether a feature is enabled
-- or not, or provide relevant parameters:
-- -15th character in TimingModel determines if enhanced high
-- performance option is available
-- (0,2,3,R,A,B,C,D) EHPLC
-- (Y,Z,S,T,K,L) Security EHPLC
-- (4,6,7,8,9,Q) HPLC
-- -15th character in TimingModel determines if RESET# input
-- is available
-- (R,A,B,C,D,Q.6,7,K,L,S,T,M,N,U,V) RESET# is available
-- (0,2,3,4,8,9,Y.Z.W,X) RESET# is tied to the inactive
-- state,inside the package.
-- -16th character in TimingModel determines Sector and Page Size:
-- (0) Sector Size = 64 kB; Page Size = 256 bytes
-- Hybrid Top/Bottom sector size architecture
-- (1) Sector Size = 256 kB; Page Size = 512 bytes
-- Uniform sector size architecture
--
-------------------------------------------------------------------------------
-- Known Bugs:
--
-------------------------------------------------------------------------------
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL;
USE STD.textio.ALL;
USE IEEE.VITAL_timing.ALL;
USE IEEE.VITAL_primitives.ALL;
LIBRARY FMF; USE FMF.gen_utils.ALL;
USE FMF.conversions.ALL;
-------------------------------------------------------------------------------
-- ENTITY DECLARATION
-------------------------------------------------------------------------------
ENTITY s25fl128s IS
GENERIC (
---------------------------------------------------------------------------
-- TIMING GENERICS:
---------------------------------------------------------------------------
-- tipd delays: interconnect path delays (delay between components)
-- There should be one for each IN or INOUT pin in the port list
-- They are given default values of zero delay.
tipd_SCK : VitalDelayType01 := VitalZeroDelay01;
tipd_SI : VitalDelayType01 := VitalZeroDelay01;
tipd_SO : VitalDelayType01 := VitalZeroDelay01;
tipd_CSNeg : VitalDelayType01 := VitalZeroDelay01;
tipd_HOLDNeg : VitalDelayType01 := VitalZeroDelay01;
tipd_WPNeg : VitalDelayType01 := VitalZeroDelay01;
tipd_RSTNeg : VitalDelayType01 := VitalZeroDelay01;
-- tpd delays: propagation delays (pin-to-pin delay within a component)
tpd_SCK_SO_normal : VitalDelayType01Z := UnitDelay01Z; -- tV, tHO
tpd_CSNeg_SO : VitalDelayType01Z := UnitDelay01Z; -- tDIS
tpd_HOLDNeg_SO : VitalDelayType01Z := UnitDelay01Z;--
tpd_RSTNeg_SO : VitalDelayType01Z := UnitDelay01Z;--
-- DDR operation values
tpd_SCK_SO_DDR : VitalDelayType01Z := UnitDelay01Z;--tV(66MHz)
-- tsetup values: setup times
-- setup time is minimum time before the referent signal edge the
-- input should be stable
tsetup_CSNeg_SCK_normal_noedge_posedge
: VitalDelayType := UnitDelay; -- tCSS /
tsetup_CSNeg_SCK_DDR_noedge_posedge
: VitalDelayType := UnitDelay; -- tCSS /
tsetup_SI_SCK_normal_noedge_posedge: VitalDelayType
:= UnitDelay; -- tSU:DAT /
tsetup_WPNeg_CSNeg : VitalDelayType := UnitDelay; -- tWPS \
tsetup_HOLDNeg_SCK : VitalDelayType := UnitDelay;
tsetup_RSTNeg_CSNeg : VitalDelayType := UnitDelay; -- tRP
-- DDR operation values
tsetup_SI_SCK_DDR_noedge_posedge: VitalDelayType
:= UnitDelay; -- tSU /
tsetup_SI_SCK_DDR_noedge_negedge: VitalDelayType
:= UnitDelay; -- tSU \
-- thold values: hold times
-- hold time is minimum time the input should be present stable
-- after the referent signal edge
thold_CSNeg_SCK_normal_noedge_posedge
: VitalDelayType := UnitDelay; -- tCSH /
thold_CSNeg_SCK_DDR_noedge_posedge
: VitalDelayType := UnitDelay; -- tCSH /
thold_SI_SCK_normal_noedge_posedge: VitalDelayType
:= UnitDelay; -- tHD:DAT /
thold_WPNeg_CSNeg : VitalDelayType := UnitDelay; -- tWPH /
thold_HOLDNeg_SCK : VitalDelayType := UnitDelay; --
thold_CSNeg_RSTNeg : VitalDelayType := UnitDelay; -- tRPH
-- DDR operation values
thold_SI_SCK_DDR_noedge_posedge: VitalDelayType
:= UnitDelay; -- tHD /
thold_SI_SCK_DDR_noedge_negedge: VitalDelayType
:= UnitDelay; -- tHD \
--tpw values: pulse width
tpw_SCK_serial_posedge : VitalDelayType := UnitDelay; -- tWH
tpw_SCK_dual_posedge : VitalDelayType := UnitDelay; -- tWH
tpw_SCK_fast_posedge : VitalDelayType := UnitDelay; -- tWH
tpw_SCK_quadpg_posedge : VitalDelayType := UnitDelay; -- tWH
tpw_SCK_serial_negedge : VitalDelayType := UnitDelay; -- tWL
tpw_SCK_dual_negedge : VitalDelayType := UnitDelay; -- tWL
tpw_SCK_fast_negedge : VitalDelayType := UnitDelay; -- tWL
tpw_SCK_quadpg_negedge : VitalDelayType := UnitDelay; -- tWL
tpw_CSNeg_read_posedge : VitalDelayType := UnitDelay; -- tCS
tpw_CSNeg_pgers_posedge : VitalDelayType := UnitDelay; -- tCS
tpw_RSTNeg_negedge : VitalDelayType := UnitDelay; -- tRP
tpw_RSTNeg_posedge : VitalDelayType := UnitDelay; -- tRS
-- DDR operation values
tpw_SCK_DDR_posedge : VitalDelayType := UnitDelay; -- tWH(66MHz)
tpw_SCK_DDR_negedge : VitalDelayType := UnitDelay; -- tWL(66Hz)
-- tperiod min (calculated as 1/max freq)
tperiod_SCK_serial_rd : VitalDelayType := UnitDelay; --fSCK=50MHz
tperiod_SCK_fast_rd : VitalDelayType := UnitDelay; --fSCK=133MHz
tperiod_SCK_dual_rd : VitalDelayType := UnitDelay; --fSCK=104MHz
tperiod_SCK_quadpg : VitalDelayType := UnitDelay; --fSCK=80MHz
-- DDR operation values
tperiod_SCK_DDR_rd : VitalDelayType := UnitDelay; --fSCK=66MHz
-- tdevice values: values for internal delays
--timing values that are internal to the model and not associated
--with any port.
-- Page Program Operation (Page Size 256)
tdevice_PP256 : VitalDelayType := 550 us; --tPP
-- Page Program Operation (Page Size 512)
tdevice_PP512 : VitalDelayType := 750 us; --tPP
-- Typical Byte Programming Time
tdevice_BP : VitalDelayType := 400 us; --tBP
-- Sector Erase Operation(256KB Sectors)
tdevice_SE256 : VitalDelayType := 1875 ms; --tSE
-- Sector Erase Operation(64KB Sectors)
tdevice_SE64 : VitalDelayType := 650 ms; --tSE
-- Bulk Erase Operation
tdevice_BE : VitalDelayType := 165 sec; --tBE
-- WRR Cycle Time
tdevice_WRR : VitalDelayType := 200 ms; --tW
-- Erase Suspend/Erase Resume Time
tdevice_ERSSUSP : VitalDelayType := 40 us; --tESL
-- Program Suspend/Program Resume Time
tdevice_PRGSUSP : VitalDelayType := 40 us; --
-- VCC (min) to CS# Low
tdevice_PU : VitalDelayType := 300 us; --tPU
-- PPB Erase Time
tdevice_PPBERASE :VitalDelayType := 15 ms; --
-- Password Unlock Time
tdevice_PASSULCK :VitalDelayType := 1 us; --
-- Password Unlock Time
tdevice_PASSACC :VitalDelayType := 100 us;
---------------------------------------------------------------------------
-- CONTROL GENERICS:
---------------------------------------------------------------------------
-- generic control parameters
InstancePath : STRING := DefaultInstancePath;
TimingChecksOn : BOOLEAN := DefaultTimingChecks;
MsgOn : BOOLEAN := DefaultMsgOn;
XOn : BOOLEAN := DefaultXon;
-- memory file to be loaded
mem_file_name : STRING := "s25fl128s.mem";
otp_file_name : STRING := "s25fl128sOTP.mem";
UserPreload : BOOLEAN := FALSE; --TRUE;
LongTimming : BOOLEAN := TRUE;
-- For FMF SDF technology file usage
TimingModel : STRING
);
PORT (
-- Data Inputs/Outputs
SI : INOUT std_ulogic := 'U'; -- serial data input/IO0
SO : INOUT std_ulogic := 'U'; -- serial data output/IO1
-- Controls
SCK : IN std_ulogic := 'U'; -- serial clock input
CSNeg : IN std_ulogic := 'U'; -- chip select input
RSTNeg : IN std_ulogic := 'U'; -- hardware reset pin
WPNeg : INOUT std_ulogic := 'U'; -- write protect input/IO2
HOLDNeg : INOUT std_ulogic := 'U' -- hold input/IO3
);
ATTRIBUTE VITAL_LEVEL0 of s25fl128s : ENTITY IS TRUE;
END s25fl128s;
-------------------------------------------------------------------------------
-- ARCHITECTURE DECLARATION
-------------------------------------------------------------------------------
ARCHITECTURE vhdl_behavioral of s25fl128s IS
ATTRIBUTE VITAL_LEVEL0 OF vhdl_behavioral : ARCHITECTURE IS TRUE;
---------------------------------------------------------------------------
-- CONSTANT AND SIGNAL DECLARATION
---------------------------------------------------------------------------
--Declaration of constants - memory characteristics
-- The constant declared here are used to enable the creation of models
-- of memories within a family with a minimum amount of editing
CONSTANT PartID : STRING := "s25fl128s";
CONSTANT MaxData : NATURAL := 16#FF#; --255;
CONSTANT MemSize : NATURAL := 16#FFFFFF#;
CONSTANT SecSize256 : NATURAL := 16#3FFFF#; --256KB
CONSTANT SecSize64 : NATURAL := 16#FFFF#; --64KB
CONSTANT SecSize4 : NATURAL := 16#FFF#; --4KB
CONSTANT SecNum64 : NATURAL := 285;
CONSTANT SecNum256 : NATURAL := 63;
CONSTANT PageNum64 : NATURAL := 16#1FFFF#;
CONSTANT PageNum256 : NATURAL := 16#7FFF#;
CONSTANT AddrRANGE : NATURAL := 16#0FFFFFF#;
CONSTANT HiAddrBit : NATURAL := 31;
CONSTANT OTPSize : NATURAL := 1023;
CONSTANT OTPLoAddr : NATURAL := 16#000#;
CONSTANT OTPHiAddr : NATURAL := 16#3FF#;
CONSTANT BYTE : NATURAL := 8;
--Manufacturer Identification
CONSTANT Manuf_ID : NATURAL := 16#01#;
CONSTANT DeviceID : NATURAL := 16#17#;
--Electronic Signature
CONSTANT ESignature : NATURAL := 16#17#;
--Device ID
--Manufacturer Identification && Memory Type && Memory Capacity
CONSTANT Jedec_ID : NATURAL := 16#01#; -- first byte of Device ID
CONSTANT DeviceID1 : NATURAL := 16#20#;
CONSTANT DeviceID2 : NATURAL := 16#18#;
CONSTANT ExtendedBytes : NATURAL := 16#4D#;
CONSTANT ExtendedID64 : NATURAL := 16#01#;
CONSTANT ExtendedID256 : NATURAL := 16#00#;
CONSTANT DieRev : NATURAL := 16#03#;
CONSTANT MaskRev : NATURAL := 16#00#;
-- Declaration of signals that will hold the delayed values of ports
SIGNAL SI_ipd : std_ulogic := 'U';
SIGNAL SO_ipd : std_ulogic := 'U';
SIGNAL SCK_ipd : std_ulogic := 'U';
SIGNAL CSNeg_ipd : std_ulogic := 'U';
SIGNAL RSTNeg_ipd : std_ulogic := 'U';
SIGNAL WPNeg_ipd : std_ulogic := 'U';
SIGNAL HOLDNeg_ipd : std_ulogic := 'U';
SIGNAL HOLDNeg_pullup : std_ulogic := 'U';
SIGNAL WPNeg_pullup : std_ulogic := 'U';
SIGNAL RSTNeg_pullup : std_ulogic := 'U';
-- internal delays
SIGNAL PP256_in : std_ulogic := '0';
SIGNAL PP256_out : std_ulogic := '0';
SIGNAL PP512_in : std_ulogic := '0';
SIGNAL PP512_out : std_ulogic := '0';
SIGNAL BP_in : std_ulogic := '0';
SIGNAL BP_out : std_ulogic := '0';
SIGNAL SE64_in : std_ulogic := '0';
SIGNAL SE64_out : std_ulogic := '0';
SIGNAL SE256_in : std_ulogic := '0';
SIGNAL SE256_out : std_ulogic := '0';
SIGNAL BE_in : std_ulogic := '0';
SIGNAL BE_out : std_ulogic := '0';
SIGNAL WRR_in : std_ulogic := '0';
SIGNAL WRR_out : std_ulogic := '0';
SIGNAL ERSSUSP_in : std_ulogic := '0';
SIGNAL ERSSUSP_out : std_ulogic := '0';
SIGNAL PRGSUSP_in : std_ulogic := '0';
SIGNAL PRGSUSP_out : std_ulogic := '0';
SIGNAL PU_in : std_ulogic := '0';
SIGNAL PU_out : std_ulogic := '0';
SIGNAL RST_in : std_ulogic := '0';-- Hardware Reset Timeout
SIGNAL RST_out : std_ulogic := '1';--
SIGNAL PPBERASE_in : std_ulogic := '0';
SIGNAL PPBERASE_out : std_ulogic := '0';
SIGNAL PASSULCK_in : std_ulogic := '0';
SIGNAL PASSULCK_out : std_ulogic := '0';
SIGNAL PASSACC_in : std_ulogic := '0';
SIGNAL PASSACC_out : std_ulogic := '0';
FUNCTION ReturnSectorIDRdPswdMd(TBPROT : std_logic) RETURN NATURAL IS
VARIABLE result : NATURAL;
BEGIN
IF TBPROT = '0' THEN
result := 0;
ELSE
IF (TimingModel(16) = '1') THEN
result := SecNum256;
ELSE
result := 255;
END IF;
END IF;
RETURN result;
END ReturnSectorIDRdPswdMd;
BEGIN
---------------------------------------------------------------------------
-- Internal Delays
---------------------------------------------------------------------------
-- Artificial VITAL primitives to incorporate internal delays
-- Because a tdevice generics is used, there must be a VITAL_primitives
-- assotiated with them
PP256 :VitalBuf(PP256_out, PP256_in, (tdevice_PP256 ,UnitDelay));
PP512 :VitalBuf(PP512_out, PP512_in, (tdevice_PP512 ,UnitDelay));
BP :VitalBuf(BP_out, BP_in, (tdevice_BP ,UnitDelay));
SE64 :VitalBuf(SE64_out, SE64_in, (tdevice_SE64 ,UnitDelay));
SE256 :VitalBuf(SE256_out, SE256_in, (tdevice_SE256 ,UnitDelay));
BE :VitalBuf(BE_out, BE_in, (tdevice_BE ,UnitDelay));
WRR :VitalBuf(WRR_out, WRR_in, (tdevice_WRR ,UnitDelay));
ERSSUSP :VitalBuf(ERSSUSP_out, ERSSUSP_in, (tdevice_ERSSUSP ,UnitDelay));
PRGSUSP :VitalBuf(PRGSUSP_out, PRGSUSP_in, (tdevice_PRGSUSP ,UnitDelay));
PU :VitalBuf(PU_out, PU_in, (tdevice_PU ,UnitDelay));
PPBERASE :VitalBuf(PPBERASE_out,PPBERASE_in,(tdevice_PPBERASE,UnitDelay));
PASSULCK :VitalBuf(PASSULCK_out,PASSULCK_in,(tdevice_PASSULCK,UnitDelay));
PASSACC :VitalBuf(PASSACC_out, PASSACC_in, (tdevice_PASSACC ,UnitDelay));
---------------------------------------------------------------------------
-- Wire Delays
---------------------------------------------------------------------------
WireDelay : BLOCK
BEGIN
w_1 : VitalWireDelay (SI_ipd, SI, tipd_SI);
w_2 : VitalWireDelay (SO_ipd, SO, tipd_SO);
w_3 : VitalWireDelay (SCK_ipd, SCK, tipd_SCK);
w_4 : VitalWireDelay (CSNeg_ipd, CSNeg, tipd_CSNeg);
w_5 : VitalWireDelay (RSTNeg_ipd, RSTNeg, tipd_RSTNeg);
w_6 : VitalWireDelay (WPNeg_ipd, WPNeg, tipd_WPNeg);
w_7 : VitalWireDelay (HOLDNeg_ipd, HOLDNeg, tipd_HOLDNeg);
END BLOCK;
---------------------------------------------------------------------------
-- Main Behavior Block
---------------------------------------------------------------------------
Behavior: BLOCK
PORT (
SIIn : IN std_ulogic := 'U';
SIOut : OUT std_ulogic := 'U';
SOIn : IN std_logic := 'U';
SOut : OUT std_logic := 'U';
SCK : IN std_ulogic := 'U';
CSNeg : IN std_ulogic := 'U';
RSTNeg : IN std_ulogic := 'U';
HOLDNegIn : IN std_ulogic := 'U';
HOLDNegOut : OUT std_ulogic := 'U';
WPNegIn : IN std_ulogic := 'U';
WPNegOut : OUT std_ulogic := 'U'
);
PORT MAP (
SIIn => SI_ipd,
SIOut => SI,
SOIn => SO_ipd,
SOut => SO,
SCK => SCK_ipd,
CSNeg => CSNeg_ipd,
RSTNeg => RSTNeg_ipd,
HOLDNegIn => HOLDNeg_ipd,
HOLDNegOut => HOLDNeg,
WPNegIn => WPNeg_ipd,
WPNegOut => WPNeg
);
-- State Machine : State_Type
TYPE state_type IS (IDLE,
RESET_STATE,
AUTOBOOT,
WRITE_SR,
PAGE_PG,
OTP_PG,
PG_SUSP,
SECTOR_ERS,
BULK_ERS,
ERS_SUSP,
ERS_SUSP_PG,
ERS_SUSP_PG_SUSP,
PASS_PG,
PASS_UNLOCK,
PPB_PG,
PPB_ERS,
AUTOBOOT_PG,
ASP_PG,
PLB_PG,
DYB_PG,
NVDLR_PG
);
-- Instruction Type
TYPE instruction_type IS ( NONE,
WREN, -- Write Enable
WRDI, -- Write Disable
WRR, -- Write Register
READ, -- Read Normal (3Byte Address)
RD4, -- Read Normal (4Byte +)
OTPR, -- OTP Read
RDSR, -- Read Status Register 1
RDSR2, -- Read Status Register 2
RDCR, -- Read Configuration Register 1
REMS, -- Read ID (SST)
RDID, -- Read ID JEDEC
RES, -- Read ID
FSTRD, -- Fast Read (3Byte Address)
FSTRD4, -- Fast Read (4Byte +)
DDRFR, -- Fast Read DDR (3Byte Address)
DDRFR4, -- Fast Read DDR (4Byte +)
DOR, -- Read Dual Out (3Byte Address)
DOR4, -- Read Dual Out (4Byte +)
DIOR, -- Read Dual I/O (3Byte Address)
DIOR4, -- Read Dual I/O (4Byte +)
DDRDIOR, -- Read DDR Dual I/O (3Byte)
DDRDIOR4, -- Read DDR Dual I/O (4Byte +)
QOR, -- Read Quad Out (3Byte Address)
QOR4, -- Read Quad Out (4Byte +)
QIOR, -- Read Quad I/O (3Byte Address)
QIOR4, -- Read Quad I/O (4Byte +)
DDRQIOR, -- Read DDR Quad I/O (3Byte)
DDRQIOR4, -- Read DDR Quad I/O (4Byte +)
PP, -- Program Page (3Byte Address)
PP4, -- Program Page (4Byte +)
QPP, -- Quad Page Program (3Byte)
QPP4, -- Quad Page Program (4Byte +)
OTPP, -- OTP Program
PGSP, -- Program Suspend
PGRS, -- Program Resume
BE, -- Bulk Erase
SE, -- Erase 128/256KB (3Byte)
SE4, -- Erase 128/256KB (4Byte +)
P4E, -- 4KB-sector Erase (3Byte Addr)
P4E4, -- 4KB-sector Erase (4Byte Addr)
ERSP, -- Erase Suspend
ERRS, -- Erase Resume
ABRD, -- AutoBoot Register Read
ABWR, -- AutoBoot Register Write
BRRD, -- Bank Register Read
BRWR, -- Bank Register Write
BRAC, -- Bank Register Access
DLPRD, -- Read Data Learning Pattern
PNVDLR, -- Program NVDLP Reg
WVDLR, -- Write Volatile DLP Reg
ASPRD, -- ASP Read
ASPP, -- ASP Program
DYBRD, -- DYB Read
DYBWR, -- DYB Write
PPBRD, -- PPB Read
PPBP, -- PPB Program
PPBERS, -- PPB Erase
PLBWR, -- PPB Lock Bit Write
PLBRD, -- PPB Lock Bit Read
PASSRD, -- Password Read
PASSP, -- Password Program
PASSU, -- Password Unlock
RESET, -- Reset
MBR, -- Mode Bit Reset
MPM, -- Multi-I/O-High Perf Mode
CLSR -- Clear Status Register
);
TYPE WByteType IS ARRAY (0 TO 511) OF INTEGER RANGE -1 TO MaxData;
-- Flash Memory Array
TYPE MemArray IS ARRAY (0 TO AddrRANGE) OF INTEGER RANGE -1 TO MaxData;
-- OTP Memory Array
TYPE OTPArray IS ARRAY (OTPLoAddr TO OTPHiAddr) OF INTEGER
RANGE -1 TO MaxData;
--CFI Array (Common Flash Interface Query codes)
TYPE CFItype IS ARRAY (16#00# TO 16#55#) OF
INTEGER RANGE -1 TO 16#FF#;
-----------------------------------------------------------------------
-- memory declaration
-----------------------------------------------------------------------
-- Memory
SHARED VARIABLE Mem : MemArray := (OTHERS => MaxData);
-- OTP Sector
SHARED VARIABLE OTPMem : OTPArray := (OTHERS => MaxData);
--CFI Array
SHARED VARIABLE CFI_array : CFItype := (OTHERS => 0);
-- Programming Buffer
SIGNAL WByte : WByteType := (OTHERS => MaxData);
-- states
SIGNAL current_state : state_type;
SIGNAL next_state : state_type;
SIGNAL Instruct : instruction_type;
--zero delay signal
SIGNAL SOut_zd : std_logic := 'Z';
SIGNAL SIOut_zd : std_logic := 'Z';
SIGNAL HOLDNegOut_zd : std_logic := 'Z';
SIGNAL WPNegOut_zd : std_logic := 'Z';
--HOLD delay on output data
SIGNAL SOut_z : std_logic := 'Z';
SIGNAL SIOut_z : std_logic := 'Z';
-- powerup
SIGNAL PoweredUp : std_logic := '0';
-----------------------------------------------------------------------
-- Registers
-----------------------------------------------------------------------
-- *** Status Register 1 ***
SHARED VARIABLE Status_reg1 : std_logic_vector(7 downto 0)
:= (others => '0');
SIGNAL Status_reg1_in : std_logic_vector(7 downto 0)
:= (others => '0');
-- Status Register Write Disable Bit
ALIAS SRWD :std_logic IS Status_reg1(7);
-- Status Register Programming Error Bit
ALIAS P_ERR :std_logic IS Status_reg1(6);
-- Status Register Erase Error Bit
ALIAS E_ERR :std_logic IS Status_reg1(5);
-- Status Register Block Protection Bits
ALIAS BP2 :std_logic IS Status_reg1(4);
ALIAS BP1 :std_logic IS Status_reg1(3);
ALIAS BP0 :std_logic IS Status_reg1(2);
-- Status Register Write Enable Latch Bit
ALIAS WEL :std_logic IS Status_reg1(1);
-- Status Register Write In Progress Bit
ALIAS WIP :std_logic IS Status_reg1(0);
-- *** Status Register 2 ***
SHARED VARIABLE Status_reg2 : std_logic_vector(7 downto 0)
:= (others => '0');
SIGNAL Status_reg2_in : std_logic_vector(7 downto 0)
:= (others => '0');
-- Status Register Write Enable Latch Bit
ALIAS ES :std_logic IS Status_reg2(1);
-- Status Register Write In Progress Bit
ALIAS PS :std_logic IS Status_reg2(0);
-- *** Configuration Register 1 ***
SHARED VARIABLE Config_reg1 : std_logic_vector(7 downto 0)
:= (others => '0');
SIGNAL Config_reg1_in : std_logic_vector(7 downto 0)
:= (others => '0');
-- Latency code
ALIAS LC1 :std_logic IS Config_reg1(7);
ALIAS LC0 :std_logic IS Config_reg1(6);
-- Configuration Register TBPROT bit
ALIAS TBPROT :std_logic IS Config_reg1(5);
-- Configuration Register LOCK bit
ALIAS LOCK :std_logic IS Config_reg1(4);
-- Configuration Register BPNV bit
ALIAS BPNV :std_logic IS Config_reg1(3);
-- Configuration Register TBPARM bit
ALIAS TBPARM :std_logic IS Config_reg1(2);
-- Configuration Register QUAD bit
ALIAS QUAD :std_logic IS Config_reg1(1);
-- Configuration Register FREEZE bit
ALIAS FREEZE :std_logic IS Config_reg1(0);
-- *** VDLR Register ***
SHARED VARIABLE VDLR_reg : std_logic_vector(7 downto 0)
:= (others => '0');
SIGNAL VDLR_reg_in : std_logic_vector(7 downto 0)
:= (others => '0');
-- *** NVDLR Register ***
SHARED VARIABLE NVDLR_reg : std_logic_vector(7 downto 0)
:= (others => '0');
SIGNAL NVDLR_reg_in : std_logic_vector(7 downto 0)
:= (others => '0');
-- *** AutoBoot Register ***
SHARED VARIABLE AutoBoot_reg : std_logic_vector(31 downto 0)
:= (others => '0');
SIGNAL AutoBoot_reg_in : std_logic_vector(31 downto 0)
:= (others => '0');
--AutoBoot Enable Bit
ALIAS ABE :std_logic IS AutoBoot_reg(0);
-- *** Bank Address Register ***
SHARED VARIABLE Bank_Addr_reg : std_logic_vector(7 downto 0)
:= (others => '0');
SIGNAL Bank_Addr_reg_in : std_logic_vector(7 downto 0)
:= (others => '0');
--Bank Address Register EXTADD bit
ALIAS EXTADD :std_logic IS Bank_Addr_reg(7);
-- *** ASP Register ***
SHARED VARIABLE ASP_reg : std_logic_vector(15 downto 0);
SIGNAL ASP_reg_in : std_logic_vector(15 downto 0)
:= (others => '1');
--Read Password Mode Enable Bit
ALIAS RPME :std_logic IS ASP_reg(5);
--PPB OTP Bit
ALIAS PPBOTP :std_logic IS ASP_reg(3);
-- Password Protection Mode Lock Bit
ALIAS PWDMLB :std_logic IS ASP_reg(2);
--Persistent Protection Mode Lock Bit
ALIAS PSTMLB :std_logic IS ASP_reg(1);
-- *** Password Register ***
SHARED VARIABLE Password_reg : std_logic_vector(63 downto 0)
:= (others => '1');
SIGNAL Password_reg_in : std_logic_vector(63 downto 0)
:= (others => '1');
-- *** PPB Lock Register ***
SHARED VARIABLE PPBL : std_logic_vector(7 downto 0)
:= (others => '0');
SIGNAL PPBL_in : std_logic_vector(7 downto 0)
:= (others => '0');
--Persistent Protection Mode Lock Bit
ALIAS PPB_LOCK : std_logic IS PPBL(0);
SIGNAL PPB_LOCK_temp : std_ulogic := '0';
-- *** PPB Access Register ***
SHARED VARIABLE PPBAR : std_logic_vector(7 downto 0)
:= (others => '1');
SIGNAL PPBAR_in : std_logic_vector(7 downto 0)
:= (others => '1');
-- PPB_bits(Sec)
SHARED VARIABLE PPB_bits : std_logic_vector(SecNum64 downto 0)
:= (OTHERS => '1');
-- *** DYB Access Register ***
SHARED VARIABLE DYBAR : std_logic_vector(7 downto 0)
:= (others => '1');
SIGNAL DYBAR_in : std_logic_vector(7 downto 0)
:= (others => '1');
-- DYB(Sec)
SHARED VARIABLE DYB_bits : std_logic_vector(SecNum64 downto 0);
-- The Lock Protection Registers for OTP Memory space
SHARED VARIABLE LOCK_BYTE1 :std_logic_vector(7 downto 0);
SHARED VARIABLE LOCK_BYTE2 :std_logic_vector(7 downto 0);
SHARED VARIABLE LOCK_BYTE3 :std_logic_vector(7 downto 0);
SHARED VARIABLE LOCK_BYTE4 :std_logic_vector(7 downto 0);
--Command Register
SIGNAL write : std_logic := '0';
SIGNAL cfg_write : std_logic := '0';
SIGNAL read_out : std_logic := '0';
SIGNAL rd : boolean := false;
SIGNAL dual : boolean := false;
SIGNAL fast_rd : boolean := true;
SIGNAL ddr : boolean := false;
SIGNAL any_read : boolean := false;
SIGNAL quadpg : boolean := false;
SIGNAL oe : boolean := false;
SIGNAL oe_z : boolean := false;
SHARED VARIABLE hold_mode : boolean := false;
-- Memory Array Configuration
SIGNAL BottomBoot : boolean := false;
SIGNAL TopBoot : boolean := false;
SIGNAL UniformSec : boolean := false;
--FSM control signals
SIGNAL PDONE : std_logic := '1'; --Page Prog. Done
SIGNAL PSTART : std_logic := '0'; --Start Page Programming
SIGNAL PGSUSP : std_logic := '0'; --Suspend Program
SIGNAL PGRES : std_logic := '0'; --Resume Program
SIGNAL RES_TO_SUSP_MIN_TIME : std_logic := '0';--Resume to Suspend Flag
SIGNAL RES_TO_SUSP_TYP_TIME : std_logic := '0';--Resume to Suspend Flag
SIGNAL WDONE : std_logic := '1'; --Write operation Done
SIGNAL WSTART : std_logic := '0'; --Start Write operation
SIGNAL ESTART : std_logic := '0'; --Start Erase operation
SIGNAL EDONE : std_logic := '1'; --Erase operation Done
SIGNAL ESUSP : std_logic := '0'; --Suspend Erase
SIGNAL ERES : std_logic := '0'; --Resume Erase
SIGNAL ERS_SUSP_PG_SUSP_ACT: std_logic := '0'; --During Erase Suspend
--Program Suspend
--is Active
--reset timing
SIGNAL RST : std_logic := '0';
SIGNAL Reseted : std_logic := '0'; --Reset Timing Control
--Lock Bit is enabled for customer programming
SIGNAL WRLOCKENABLE : BOOLEAN := TRUE;
--Flag that mark if ASP Register is allready programmed
SIGNAL ASPOTPFLAG : BOOLEAN := FALSE;
SIGNAL ASP_INIT : NATURAL RANGE 0 TO 1;
SIGNAL INITIAL_CONFIG : std_logic := '0';
SHARED VARIABLE PageSize : NATURAL := 0 ;
SHARED VARIABLE PageNum : NATURAL := 0 ;
SHARED VARIABLE SecNum : NATURAL := 0 ;
SHARED VARIABLE SecNumMax : NATURAL := 0 ;
SHARED VARIABLE SecSize : NATURAL := 0 ;
SHARED VARIABLE b_act : NATURAL := 0 ;
SHARED VARIABLE ASP_ProtSE : NATURAL := 0;
SHARED VARIABLE Sec_ProtSE : NATURAL := 0;
SHARED VARIABLE SecAddr : NATURAL RANGE 0 TO SecNum64:= 0;
SHARED VARIABLE Sec_addr : NATURAL := 0;
SHARED VARIABLE Page_addr : NATURAL;
SHARED VARIABLE pgm_page : NATURAL;
--Flag for Password unlock command
SIGNAL PASS_UNLOCKED : boolean := FALSE;
SIGNAL PASS_TEMP : std_logic_vector(63 downto 0)
:= (others => '1');
SHARED VARIABLE DOUBLE : BOOLEAN := FALSE;
SHARED VARIABLE EHP : BOOLEAN := FALSE;
SHARED VARIABLE read_cnt : NATURAL := 0;
SHARED VARIABLE byte_cnt : NATURAL := 1;
SHARED VARIABLE read_addr : NATURAL RANGE 0 TO AddrRANGE ;
SHARED VARIABLE read_addr_tmp : NATURAL RANGE 0 TO AddrRANGE ;
SHARED VARIABLE start_delay : NATURAL RANGE 0 TO 7;
SHARED VARIABLE ABSD : NATURAL RANGE 0 TO 7;
SIGNAL start_autoboot : std_logic := '0';
SIGNAL change_addr : std_logic := '0';
SIGNAL Address : NATURAL RANGE 0 TO AddrRANGE := 0;
SIGNAL SectorSuspend : NATURAL RANGE 0 TO SecNum64 := 0;
-- Sector address
SIGNAL SA : NATURAL RANGE 0 TO SecNum64 := 0;
-- Sector is protect if Sec_Prot(SecNum) = '1'
SHARED VARIABLE Sec_Prot : std_logic_vector(SecNum64 downto 0) :=
(OTHERS => '0');
SIGNAL change_TBPARM : std_logic := '0';
SIGNAL change_BP : std_logic := '0';
SHARED VARIABLE BP_bits : std_logic_vector(2 downto 0) := "000";
SHARED VARIABLE CFI_array_tmp : std_logic_vector(647 downto 0);
SIGNAL Byte_number : NATURAL RANGE 0 TO 511 := 0;
TYPE bus_cycle_type IS (STAND_BY,
OPCODE_BYTE,
ADDRESS_BYTES,
DUMMY_BYTES,
MODE_BYTE,
DATA_BYTES
);
SHARED VARIABLE bus_cycle_state : bus_cycle_type;
-- switch between Data bytes and Dummy bytes
SHARED VARIABLE DummyBytes_act : X01 := '0';
SIGNAL dummy_cnt_act_temp : NATURAL := 0;
SIGNAL dummy_cnt_act : NATURAL := 0;
--Read Password Protection Mode Active flag
SIGNAL RdPswdProtMode : std_ulogic := '0';
--Read Password Protection Mode Support flag
SIGNAL RdPswdProtEnable : std_ulogic := '0';
SIGNAL BAR_ACC : std_ulogic := '0';
SHARED VARIABLE Latency_code : NATURAL RANGE 0 TO 7;
SHARED VARIABLE opcode_cnt : NATURAL := 0;
SHARED VARIABLE addr_cnt : NATURAL := 0;
SHARED VARIABLE mode_cnt : NATURAL := 0;
SHARED VARIABLE dummy_cnt : NATURAL := 0;
SHARED VARIABLE data_cnt : NATURAL := 0;
SHARED VARIABLE PARAM_REGION : BOOLEAN := FALSE;
-- timing check violation
SIGNAL Viol : X01 := '0';
PROCEDURE ADDRHILO_SEC(
VARIABLE AddrLOW : INOUT NATURAL RANGE 0 to ADDRRange;
VARIABLE AddrHIGH : INOUT NATURAL RANGE 0 to ADDRRange;
VARIABLE Addr : NATURAL) IS
VARIABLE sector : NATURAL RANGE 0 TO 285;
BEGIN
IF (TimingModel(16) = '0') THEN
IF TBPARM = '0' THEN
IF Addr/(SecSize64+1) <= 1 AND
(Instruct = P4E OR Instruct = P4E4) THEN --4KB Sectors
sector := Addr/(SecSize4+1);
AddrLOW := sector*(SecSize4+1);
AddrHIGH := sector*(SecSize4+1) + SecSize4;
ELSE
sector := Addr/(SecSize64+1);
AddrLOW := sector*(SecSize64+1);
AddrHIGH := sector*(SecSize64+1) + SecSize64;
END IF;
ELSE
IF Addr/(SecSize64+1) >= 254 AND
(Instruct = P4E OR Instruct = P4E4) THEN --4KB Sectors
sector := 254 + (Addr-(SecSize64+1)*254)/(SecSize4+1);
AddrLOW := 254*(SecSize64+1)+(sector-254)*(SecSize4+1);
AddrHIGH := 254*(SecSize64+1)+(sector-254)*(SecSize4+1)
+ SecSize4;
ELSE
sector := Addr/(SecSize64+1);
AddrLOW := sector*(SecSize64+1);
AddrHIGH := sector*(SecSize64+1) + SecSize64;
END IF;
END IF;
ELSE
sector := Addr/(SecSize256+1);
AddrLOW := sector*(SecSize256+1);
AddrHIGH := sector*(SecSize256+1) + SecSize256;
END IF;
END ADDRHILO_SEC;
PROCEDURE ADDRHILO_PG(
VARIABLE AddrLOW : INOUT NATURAL RANGE 0 to AddrRANGE;
VARIABLE AddrHIGH : INOUT NATURAL RANGE 0 to AddrRANGE;
VARIABLE Addr : NATURAL) IS
VARIABLE page : NATURAL RANGE 0 TO PageNum;
BEGIN
page := Addr/PageSize;
AddrLOW := Page*PageSize;
AddrHIGH := Page*PageSize + (PageSize-1);
END AddrHILO_PG;
PROCEDURE ReturnSectorID(
VARIABLE result : INOUT NATURAL;
SIGNAL ADDR : NATURAL RANGE 0 TO AddrRANGE) IS
VARIABLE conv : NATURAL;
BEGIN
IF (TimingModel(16) = '0') THEN
conv := ADDR / (SecSize64+1);
IF BottomBoot = TRUE THEN
IF conv <= 1 THEN --4KB Sectors
result := ADDR/(SecSize4+1);
ELSE
result := conv + 30;
END IF;
ELSIF TopBoot = TRUE THEN
IF conv >= 254 THEN --4KB Sectors
result := 254 + (ADDR-(SecSize64+1)*254)/(SecSize4+1);
ELSE
result := conv;
END IF;
END IF;
ELSE
result := ADDR/(SecSize256+1);
END IF;
END ReturnSectorID;
BEGIN
---------------------------------------------------------------------------
--Power Up time
---------------------------------------------------------------------------
PoweredUp <= '1' AFTER tdevice_PU;
---------------------------------------------------------------------------
--sector structure
---------------------------------------------------------------------------
UniformSec <= TRUE WHEN (TimingModel(16) = '1')
ELSE FALSE;
TimingModelSel: PROCESS
BEGIN
IF TimingModel(16) = '1' THEN
-- Sector Number/Sector Size
SecNumMax:= SecNum256;
SecNum := SecNum256;
SecSize := SecSize256;
-- 256B/512B Page Size
PageSize := 512;
PageNum := 16#FFFF#;
ELSE
-- Sector Number/Sector Size
SecNumMax:= SecNum64;
SecNum := 255;
SecSize := SecSize64;
-- 256B/512B Page Size
PageSize := 256;
PageNum := 16#1FFFF#;
END IF;
--Enhanced High Performance Flag
IF (TimingModel(15) = '0' OR TimingModel(15) = '2' OR
TimingModel(15) = '3' OR TimingModel(15) = 'R' OR
TimingModel(15) = 'A' OR TimingModel(15) = 'B' OR
TimingModel(15) = 'C' OR TimingModel(15) = 'D' OR
TimingModel(15) = 'Y' OR TimingModel(15) = 'Z' OR
TimingModel(15) = 'S' OR TimingModel(15) = 'T' OR
TimingModel(15) = 'K' OR TimingModel(15) = 'L') THEN
EHP := TRUE;
IF (TimingModel(15) = 'Y' OR TimingModel(15) = 'Z' OR
TimingModel(15) = 'S' OR TimingModel(15) = 'T' OR
TimingModel(15) = 'K' OR TimingModel(15) = 'L') THEN
RdPswdProtEnable <= '1';
END IF;
ELSIF (TimingModel(15) = '4' OR TimingModel(15) = '6' OR
TimingModel(15) = '7' OR TimingModel(15) = '8' OR
TimingModel(15) = '9' OR TimingModel(15) = 'Q') THEN
EHP := FALSE;
END IF;
IF (TimingModel(15) ='0' OR TimingModel(15) ='2' OR
TimingModel(15) ='3' OR TimingModel(15) ='R' OR
TimingModel(15) ='A' OR TimingModel(15) ='B' OR
TimingModel(15) ='C' OR TimingModel(15) ='D' OR
TimingModel(15) ='4' OR TimingModel(15) ='6' OR
TimingModel(15) ='7' OR TimingModel(15) ='8' OR
TimingModel(15) ='9' OR TimingModel(15) ='Q') THEN
ASP_INIT <= 1;
ELSIF (TimingModel(15) ='Y' OR TimingModel(15) ='Z' OR
TimingModel(15) ='S' OR TimingModel(15) ='T' OR
TimingModel(15) ='K' OR TimingModel(15) ='L') THEN
ASP_INIT <= 0;
END IF;
WAIT;
END PROCESS;
RSTtiming: PROCESS(RSTNeg_pullup,Instruct)
BEGIN
IF falling_edge(RSTNeg_pullup) THEN
RST <= '1', '0' AFTER 200 ns;
ELSIF Instruct = RESET THEN
Reseted <= '0', '1' AFTER 10 ns;
END IF;
END PROCESS;
DUMMYcnt: PROCESS(dummy_cnt_act_temp)
BEGIN
dummy_cnt_act <= dummy_cnt_act_temp;
END PROCESS;
ReadPasswordProtectionMode: PROCESS(PPB_LOCK_temp,
ASP_reg_in(2), ASP_reg_in(5))
BEGIN
IF (PPB_LOCK = '0' AND PWDMLB = '0' AND RPME = '0' AND
RdPswdProtEnable = '1') THEN
RdPswdProtMode <= '1';
ABE := '0';
ELSE
RdPswdProtMode <= '0';
END IF;
END PROCESS;
---------------------------------------------------------------------------
-- autoboot control logic
---------------------------------------------------------------------------
AutoBootControl: PROCESS(SCK_ipd, current_state)
BEGIN
IF (current_state = AUTOBOOT) THEN
IF rising_edge(SCK_ipd) THEN
IF (start_delay > 0) THEN
start_delay := start_delay - 1;
END IF;
END IF;
IF (start_delay = 0) THEN
start_autoboot <= '1';
ELSE
start_autoboot <= '0';
END IF;
END IF;
END PROCESS;
---------------------------------------------------------------------------
-- VITAL Timing Checks Procedures
---------------------------------------------------------------------------
VITALTimingCheck: PROCESS(SIIn, SOIn, SCK_ipd, CSNeg_ipd, RSTNeg_ipd,
HOLDNegIn, WPNegIn)
-- Timing Check Variables
-- Setup/Hold Checks variables
VARIABLE Tviol_CSNeg_SCK_normal : X01 := '0';
VARIABLE TD_CSNeg_SCK_normal : VitalTimingDataType;
VARIABLE Tviol_CSNeg_SCK_DDR : X01 := '0';
VARIABLE TD_CSNeg_SCK_DDR : VitalTimingDataType;
VARIABLE Tviol_CSNeg_RSTNeg : X01 := '0';
VARIABLE TD_CSNeg_RSTNeg : VitalTimingDataType;
VARIABLE Tviol_SI_SCK : X01 := '0';
VARIABLE TD_SI_SCK : VitalTimingDataType;
VARIABLE Tviol_WPNeg_CSNeg_setup : X01 := '0';
VARIABLE TD_WPNeg_CSNeg_setup : VitalTimingDataType;
VARIABLE Tviol_WPNeg_CSNeg_hold : X01 := '0';
VARIABLE TD_WPNeg_CSNeg_hold : VitalTimingDataType;
VARIABLE Tviol_HOLDNeg_SCK : X01 := '0';
VARIABLE TD_HOLDNeg_SCK : VitalTimingDataType;
VARIABLE Tviol_SI_SCK_DDR_R : X01 := '0';
VARIABLE TD_SI_SCK_DDR_R : VitalTimingDataType;
VARIABLE Tviol_SI_SCK_DDR_F : X01 := '0';
VARIABLE TD_SI_SCK_DDR_F : VitalTimingDataType;
VARIABLE Tviol_RSTNeg_CSNeg : X01 := '0';
VARIABLE TD_RSTNeg_CSNeg : VitalTimingDataType;
--Pulse Width and Period Check Variables
VARIABLE Pviol_SCK_serial : X01 := '0';
VARIABLE PD_SCK_serial : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_SCK_dual : X01 := '0';
VARIABLE PD_SCK_dual : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_SCK_fast : X01 := '0';
VARIABLE PD_SCK_fast : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_SCK_quadpg : X01 := '0';
VARIABLE PD_SCK_quadpg : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_SCK_DDR : X01 := '0';
VARIABLE PD_SCK_DDR : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_CSNeg_read : X01 := '0';
VARIABLE PD_CSNeg_read : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_CSNeg_pgers : X01 := '0';
VARIABLE PD_CSNeg_pgers : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_RSTNeg : X01 := '0';
VARIABLE PD_RSTNeg : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_SCK_serial_rd : X01 := '0';
VARIABLE PD_SCK_serial_rd : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_SCK_fast_rd : X01 := '0';
VARIABLE PD_SCK_fast_rd : VitalPeriodDataType:=VitalPeriodDataInit;
VARIABLE Pviol_SCK_dual_rd : X01 := '0';
VARIABLE PD_SCK_dual_rd : VitalPeriodDataType:=VitalPeriodDataInit;
VARIABLE Pviol_SCK_DDR_rd : X01 := '0';
VARIABLE PD_SCK_DDR_rd : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Pviol_SCK_quad_pg : X01 := '0';
VARIABLE PD_SCK_quad_pg : VitalPeriodDataType:= VitalPeriodDataInit;
VARIABLE Violation : X01 := '0';
BEGIN
---------------------------------------------------------------------------
-- Timing Check Section
---------------------------------------------------------------------------
IF (TimingChecksOn) THEN
-- Setup/Hold Check between CS# and SCK
VitalSetupHoldCheck (
TestSignal => CSNeg_ipd,
TestSignalName => "CS#",
RefSignal => SCK_ipd,
RefSignalName => "SCK",
SetupHigh => tsetup_CSNeg_SCK_normal_noedge_posedge,
SetupLow => tsetup_CSNeg_SCK_normal_noedge_posedge,
HoldHigh => thold_CSNeg_SCK_normal_noedge_posedge,
HoldLow => thold_CSNeg_SCK_normal_noedge_posedge,
CheckEnabled => ddr = false,
RefTransition => '/',
HeaderMsg => InstancePath & PartID,
TimingData => TD_CSNeg_SCK_normal,
Violation => Tviol_CSNeg_SCK_normal
);
-- Setup/Hold Check between CS# and SCK
VitalSetupHoldCheck (
TestSignal => CSNeg_ipd,
TestSignalName => "CS#",
RefSignal => SCK_ipd,
RefSignalName => "SCK",
SetupHigh => tsetup_CSNeg_SCK_DDR_noedge_posedge,
SetupLow => tsetup_CSNeg_SCK_DDR_noedge_posedge,
HoldHigh => thold_CSNeg_SCK_DDR_noedge_posedge,
HoldLow => thold_CSNeg_SCK_DDR_noedge_posedge,
CheckEnabled => ddr,
RefTransition => '/',
HeaderMsg => InstancePath & PartID,
TimingData => TD_CSNeg_SCK_DDR,
Violation => Tviol_CSNeg_SCK_DDR
);
-- Hold Check between CSNeg and RSTNeg
VitalSetupHoldCheck (
TestSignal => CSNeg,
TestSignalName => "CSNeg",
RefSignal => RSTNeg,
RefSignalName => "RSTNeg",
HoldHigh => thold_CSNeg_RSTNeg,
CheckEnabled => TRUE,
RefTransition => '\',
HeaderMsg => InstancePath & PartID,
TimingData => TD_CSNeg_RSTNeg,
Violation => Tviol_CSNeg_RSTNeg
);
-- Setup/Hold Check between SI and SCK, serial mode
VitalSetupHoldCheck (
TestSignal => SIIn,
TestSignalName => "SI",
RefSignal => SCK_ipd,
RefSignalName => "SCK",
SetupHigh => tsetup_SI_SCK_normal_noedge_posedge,
SetupLow => tsetup_SI_SCK_normal_noedge_posedge,
HoldHigh => thold_SI_SCK_normal_noedge_posedge,
HoldLow => thold_SI_SCK_normal_noedge_posedge,
CheckEnabled => NOT(DOUBLE) AND SIOut_z /= SIIn ,
RefTransition => '/',
HeaderMsg => InstancePath & PartID,
TimingData => TD_SI_SCK,
Violation => Tviol_SI_SCK
);
-- Setup Check between WP# and CS# \
VitalSetupHoldCheck (
TestSignal => WPNegIn,
TestSignalName => "WP#",
RefSignal => CSNeg_ipd,
RefSignalName => "CS#",
SetupHigh => tsetup_WPNeg_CSNeg,
CheckEnabled => true,
RefTransition => '\',
HeaderMsg => InstancePath & PartID,
TimingData => TD_WPNeg_CSNeg_setup,
Violation => Tviol_WPNeg_CSNeg_setup
);
-- Hold Check between WP# and CS# /
VitalSetupHoldCheck (
TestSignal => WPNegIn,
TestSignalName => "WP#",
RefSignal => CSNeg_ipd,
RefSignalName => "CS#",
HoldHigh => thold_WPNeg_CSNeg,
CheckEnabled => SRWD = '1' AND WEL = '1',
RefTransition => '/',
HeaderMsg => InstancePath & PartID,
TimingData => TD_WPNeg_CSNeg_hold,
Violation => Tviol_WPNeg_CSNeg_hold
);
-- Setup/Hold Check between HOLD# and SCK /
VitalSetupHoldCheck (
TestSignal => HOLDNegIn,
TestSignalName => "HOLD#",
RefSignal => SCK_ipd,
RefSignalName => "SCK",
SetupLow => tsetup_HOLDNeg_SCK,
SetupHigh => tsetup_HOLDNeg_SCK,
HoldLow => thold_HOLDNeg_SCK,
HoldHigh => thold_HOLDNeg_SCK,
CheckEnabled => QUAD = '0'
AND HOLDNegOut_zd /= HOLDNegIn,
RefTransition => '/',
HeaderMsg => InstancePath & PartID,
TimingData => TD_HOLDNeg_SCK,
Violation => Tviol_HOLDNeg_SCK
);
-- Setup/Hold Check between SI and SCK, DDR mode
VitalSetupHoldCheck (
TestSignal => SIIn,
TestSignalName => "SI",
RefSignal => SCK_ipd,
RefSignalName => "SCK",
SetupHigh => tsetup_SI_SCK_DDR_noedge_posedge,
SetupLow => tsetup_SI_SCK_DDR_noedge_posedge,
HoldHigh => thold_SI_SCK_DDR_noedge_posedge,
HoldLow => thold_SI_SCK_DDR_noedge_posedge,
CheckEnabled => DOUBLE AND dual = false
AND SIOut_z /= SIIn,
RefTransition => '/',
HeaderMsg => InstancePath & PartID,
TimingData => TD_SI_SCK_DDR_R,
Violation => Tviol_SI_SCK_DDR_R
);
-- Setup/Hold Check between SI and SCK, DDR mode
VitalSetupHoldCheck (
TestSignal => SIIn,
TestSignalName => "SI",
RefSignal => SCK_ipd,
RefSignalName => "SCK",
SetupHigh => tsetup_SI_SCK_DDR_noedge_negedge,
SetupLow => tsetup_SI_SCK_DDR_noedge_negedge,
HoldHigh => thold_SI_SCK_DDR_noedge_negedge,
HoldLow => thold_SI_SCK_DDR_noedge_negedge,
CheckEnabled => ddr AND dual = false
AND SIOut_z /= SIIn ,
RefTransition => '\',
HeaderMsg => InstancePath & PartID,
TimingData => TD_SI_SCK_DDR_F,
Violation => Tviol_SI_SCK_DDR_F
);
-- Setup Check between RSTNeg and SCK, DDR fast mode
VitalSetupHoldCheck (
TestSignal => RSTNeg,
TestSignalName => "RSTNeg",
RefSignal => CSNeg,
RefSignalName => "CSNeg",
SetupHigh => tsetup_RSTNeg_CSNeg,
CheckEnabled => TRUE,
RefTransition => '\',
HeaderMsg => InstancePath & PartID,
TimingData => TD_RSTNeg_CSNeg,
Violation => Tviol_RSTNeg_CSNeg
);
--Pulse Width and Period Check Variables
-- Pulse Width Check SCK for READ, serial mode
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
PulseWidthLow => tpw_SCK_serial_negedge,
PulseWidthHigh => tpw_SCK_serial_posedge,
PeriodData => PD_SCK_serial,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_serial,
HeaderMsg => InstancePath & PartID,
CheckEnabled => rd);
-- Pulse Width Check SCK for DUAL_READ, serial mode
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
PulseWidthLow => tpw_SCK_dual_negedge,
PulseWidthHigh => tpw_SCK_dual_posedge,
PeriodData => PD_SCK_dual,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_dual,
HeaderMsg => InstancePath & PartID,
CheckEnabled => dual);
-- Pulse Width Check SCK for FAST_READ, serial mode
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
PulseWidthLow => tpw_SCK_fast_negedge,
PulseWidthHigh => tpw_SCK_fast_posedge,
PeriodData => PD_SCK_fast,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_fast,
HeaderMsg => InstancePath & PartID,
CheckEnabled => fast_rd );
-- Pulse Width Check SCK for QPP
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
PulseWidthLow => tpw_SCK_quadpg_negedge,
PulseWidthHigh => tpw_SCK_quadpg_posedge,
PeriodData => PD_SCK_quadpg,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_quadpg,
HeaderMsg => InstancePath & PartID,
CheckEnabled => quadpg);
-- Pulse Width Check CS# for READ, serial mode
VitalPeriodPulseCheck (
TestSignal => CSNeg_ipd,
TestSignalName => "CS#",
PulseWidthHigh => tpw_CSNeg_read_posedge,
PeriodData => PD_CSNeg_read,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_CSNeg_read,
HeaderMsg => InstancePath & PartID,
CheckEnabled => any_read );
-- Pulse Width Check CS# for Program/Erase, serial mode
VitalPeriodPulseCheck (
TestSignal => CSNeg_ipd,
TestSignalName => "CS#",
PulseWidthHigh => tpw_CSNeg_pgers_posedge,
PeriodData => PD_CSNeg_pgers,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_CSNeg_pgers,
HeaderMsg => InstancePath & PartID,
CheckEnabled => NOT(any_read));
-- Pulse Width Check RSTNeg
VitalPeriodPulseCheck (
TestSignal => RSTNeg_ipd,
TestSignalName => "RSTNeg",
PulseWidthLow => tpw_RSTNeg_negedge,
PulseWidthHigh => tpw_RSTNeg_posedge,
CheckEnabled => TRUE,
HeaderMsg => InstancePath & PartID,
PeriodData => PD_RSTNeg,
Violation => Pviol_RSTNeg
);
-- Pulse Width Check SCK for DDR READ
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
PulseWidthLow => tpw_SCK_DDR_negedge,
PulseWidthHigh => tpw_SCK_DDR_posedge,
PeriodData => PD_SCK_DDR,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_DDR,
HeaderMsg => InstancePath & PartID,
CheckEnabled => ddr);
-- Period Check SCK for READ, serial mode
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
Period => tperiod_SCK_serial_rd,
PeriodData => PD_SCK_serial_rd,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_serial_rd,
HeaderMsg => InstancePath & PartID,
CheckEnabled => rd );
-- Period Check SCK for FAST READ, serial mode
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
Period => tperiod_SCK_fast_rd,
PeriodData => PD_SCK_fast_rd,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_fast_rd,
HeaderMsg => InstancePath & PartID,
CheckEnabled => fast_rd );
-- Period Check SCK for DUAL READ, serial mode
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
Period => tperiod_SCK_dual_rd,
PeriodData => PD_SCK_dual_rd,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_dual_rd,
HeaderMsg => InstancePath & PartID,
CheckEnabled => dual );
-- Period Check SCK for QPP
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
Period => tperiod_SCK_quadpg,
PeriodData => PD_SCK_quad_pg,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_quad_pg,
HeaderMsg => InstancePath & PartID,
CheckEnabled => quadpg );
-- Period Check SCK for DDR READ
VitalPeriodPulseCheck (
TestSignal => SCK_ipd,
TestSignalName => "SCK",
Period => tperiod_SCK_DDR_rd,
PeriodData => PD_SCK_DDR_rd,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_SCK_DDR_rd,
HeaderMsg => InstancePath & PartID,
CheckEnabled => ddr );
Violation := Tviol_CSNeg_SCK_normal OR
Tviol_CSNeg_SCK_DDR OR
Tviol_CSNeg_RSTNeg OR
Tviol_SI_SCK OR
Tviol_WPNeg_CSNeg_setup OR
Tviol_WPNeg_CSNeg_hold OR
Tviol_HOLDNeg_SCK OR
Tviol_SI_SCK_DDR_R OR
Tviol_SI_SCK_DDR_F OR
Tviol_RSTNeg_CSNeg OR
Pviol_SCK_serial OR
Pviol_SCK_dual OR
Pviol_SCK_fast OR
Pviol_SCK_quadpg OR
Pviol_CSNeg_read OR
Pviol_CSNeg_pgers OR
Pviol_SCK_DDR OR
Pviol_SCK_serial_rd OR
Pviol_SCK_fast_rd OR
Pviol_SCK_dual_rd OR
Pviol_SCK_quad_pg OR
Pviol_SCK_DDR_rd;
Viol <= Violation;
ASSERT Violation = '0'
REPORT InstancePath & partID & ": simulation may be" &
" inaccurate due to timing violations"
SEVERITY WARNING;
END IF;
END PROCESS VITALTimingCheck;
----------------------------------------------------------------------------
-- sequential process for FSM state transition
----------------------------------------------------------------------------
StateTransition : PROCESS(next_state, RST, PoweredUp, RST_out)
BEGIN
IF PoweredUp = '1' THEN
IF RSTNeg_pullup = '1' and RST_out= '1' THEN
IF next_state'EVENT THEN
current_state <= next_state;
END IF;
ELSIF RSTNeg_pullup = '0' AND falling_edge(RST) THEN
--no state transition while RESET# low
current_state <= RESET_STATE;
RST_in <= '1', '0' AFTER 1 ns;
END IF;
END IF;
END PROCESS StateTransition;
Threset : PROCESS(RST_in)
BEGIN
IF rising_edge(RST_in) THEN
RST_out <= '0', '1' AFTER (thold_CSNeg_RSTNeg-200 ns);
END IF;
END PROCESS Threset;
---------------------------------------------------------------------------
-- Write cycle decode
---------------------------------------------------------------------------
BusCycleDecode : PROCESS(SCK_ipd, CSNeg_ipd, HOLDNeg_pullup, SIIn, RST_out,
WPNeg_pullup)
TYPE quad_data_type IS ARRAY (0 TO 1023) OF INTEGER RANGE 0 TO 15;
VARIABLE bit_cnt : NATURAL := 0;
VARIABLE Data_in : std_logic_vector(4095 downto 0)
:= (others => '0');
VARIABLE opcode : std_logic_vector(7 downto 0);
VARIABLE opcode_in : std_logic_vector(7 downto 0);
VARIABLE addr_bytes : std_logic_vector(31 downto 0);
VARIABLE hiaddr_bytes : std_logic_vector(31 downto 0);
VARIABLE Address_in : std_logic_vector(31 downto 0);
VARIABLE mode_bytes : std_logic_vector(7 downto 0);
VARIABLE mode_in : std_logic_vector(7 downto 0);
VARIABLE quad_data_in : quad_data_type;
VARIABLE quad_nybble : std_logic_vector(3 downto 0);
VARIABLE Quad_slv : std_logic_vector(3 downto 0);
VARIABLE Byte_slv : std_logic_vector(7 downto 0);
VARIABLE CLK_PER : time;
VARIABLE LAST_CLK : time;
VARIABLE Check_freq : boolean := FALSE;
BEGIN
IF rising_edge(CSNeg_ipd) AND NOT(bus_cycle_state = DATA_BYTES)
AND NOT(bus_cycle_state = DUMMY_BYTES) THEN
bus_cycle_state := STAND_BY;
ELSE
CASE bus_cycle_state IS
WHEN STAND_BY =>
IF falling_edge(CSNeg_ipd) THEN
Instruct <= NONE;
write <= '1';
cfg_write <= '0';
opcode_cnt:= 0;
addr_cnt := 0;
mode_cnt := 0;
dummy_cnt := 0;
dummy_cnt_act_temp <= dummy_cnt;
data_cnt := 0;
DOUBLE := FALSE;
CLK_PER := 0 ns;
LAST_CLK := 0 ns;
IF current_state = AUTOBOOT THEN
bus_cycle_state := DATA_BYTES;
ELSE
bus_cycle_state := OPCODE_BYTE;
END IF;
END IF;
WHEN OPCODE_BYTE =>
IF rising_edge(SCK_ipd) THEN
Latency_code := to_nat(LC1 & LC0);
CLK_PER := NOW - LAST_CLK;
LAST_CLK := NOW;
IF Check_freq THEN
IF (CLK_PER < 20 ns AND Latency_code = 3) OR
(CLK_PER < 12.5 ns AND Latency_code = 0) OR
(CLK_PER < 11.1 ns AND Latency_code = 1) OR
(CLK_PER < 9.6 ns AND Latency_code = 2) THEN
ASSERT FALSE
REPORT "More wait states are required for " &
"this clock frequency value"
SEVERITY warning;
END IF;
END IF;
Check_freq := FALSE;
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1') THEN
--One-byte of instruction opcode is shifted into the
--device on the SI serial input pin with the most
--significant bit (MSB) first.Each bit input on the
--SI serial input pin is latched on the rising edge of
--the SCK serial clock signal.
opcode_in(opcode_cnt) := SIIn;
opcode_cnt := opcode_cnt + 1;
IF opcode_cnt = BYTE THEN
--MSB first
FOR I IN 7 DOWNTO 0 LOOP
opcode(i) := opcode_in(7-i);
END LOOP;
CASE opcode IS
WHEN "00000110" => --06h
Instruct <= WREN;
bus_cycle_state := DATA_BYTES;
WHEN "00000100" => --04h
Instruct <= WRDI;
bus_cycle_state := DATA_BYTES;
WHEN "00000001" => --01h
Instruct <= WRR;
bus_cycle_state := DATA_BYTES;
WHEN "00000011" => --03h
Instruct <= READ;
bus_cycle_state := ADDRESS_BYTES;
WHEN "00010011" => --13h
Instruct <= RD4;
bus_cycle_state := ADDRESS_BYTES;
WHEN "01001011" => --4Bh
Instruct <= OTPR;
bus_cycle_state := ADDRESS_BYTES;
WHEN "00000101" => --05h
Instruct <= RDSR;
bus_cycle_state := DATA_BYTES;
WHEN "00000111" => --07h
Instruct <= RDSR2;
bus_cycle_state := DATA_BYTES;
WHEN "00110101" => --35h
Instruct <= RDCR;
bus_cycle_state := DATA_BYTES;
WHEN "10010000" => --90h
Instruct <= REMS;
bus_cycle_state := ADDRESS_BYTES;
WHEN "10011111" => --9Fh
Instruct <= RDID;
bus_cycle_state := DATA_BYTES;
WHEN "10101011" => --ABh
Instruct <= RES;
bus_cycle_state := DUMMY_BYTES;
WHEN "00001011" => --0Bh
Instruct <= FSTRD;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "00001100" => --0Ch
Instruct <= FSTRD4;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "00001101" => --0Dh
Instruct <= DDRFR;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "00001110" => --0Eh
Instruct <= DDRFR4;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "00111011" => --3Bh
Instruct <= DOR;
Check_freq := TRUE;
bus_cycle_state := ADDRESS_BYTES;
WHEN "00111100" => --3Ch
Instruct <= DOR4;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "10111011" => --BBh
Instruct <= DIOR;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "10111100" => --BCh
Instruct <= DIOR4;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "10111101" => --BDh
Instruct <= DDRDIOR;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "10111110" => --BEh
Instruct <= DDRDIOR4;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "01101011" => --6Bh
Instruct <= QOR;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "01101100" => --6Ch
Instruct <= QOR4;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "11101011" => --EBh
Instruct <= QIOR;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "11101100" => --ECh
Instruct <= QIOR4;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "11101101" => --EDh
Instruct <= DDRQIOR;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "11101110" => --EEh
Instruct <= DDRQIOR4;
bus_cycle_state := ADDRESS_BYTES;
Check_freq := TRUE;
WHEN "00000010" => --02h
Instruct <= PP;
bus_cycle_state := ADDRESS_BYTES;
WHEN "00010010" => --12h
Instruct <= PP4;
bus_cycle_state := ADDRESS_BYTES;
WHEN "00110010" => --32h
Instruct <= QPP;
bus_cycle_state := ADDRESS_BYTES;
quadpg <= TRUE;
WHEN "00111000" => --38h
Instruct <= QPP;
bus_cycle_state := ADDRESS_BYTES;
quadpg <= TRUE;
WHEN "00110100" => --34h
Instruct <= QPP4;
bus_cycle_state := ADDRESS_BYTES;
quadpg <= TRUE;
WHEN "01000010" => --42h
Instruct <= OTPP;
bus_cycle_state := ADDRESS_BYTES;
WHEN "10000101" => --85h
Instruct <= PGSP;
bus_cycle_state := DATA_BYTES;
WHEN "10001010" => --8Ah
Instruct <= PGRS;
bus_cycle_state := DATA_BYTES;
WHEN "11000111" => --C7h
Instruct <= BE;
bus_cycle_state := DATA_BYTES;
WHEN "01100000" => --60h
Instruct <= BE;
bus_cycle_state := DATA_BYTES;
WHEN "11011000" => --D8h
Instruct <= SE;
bus_cycle_state := ADDRESS_BYTES;
WHEN "11011100" => --DCh
Instruct <= SE4;
bus_cycle_state := ADDRESS_BYTES;
WHEN "00100000" => --20h
Instruct <= P4E;
bus_cycle_state := ADDRESS_BYTES;
WHEN "00100001" => --21h
Instruct <= P4E4;
bus_cycle_state := ADDRESS_BYTES;
WHEN "01110101" => --75h
Instruct <= ERSP;
bus_cycle_state := DATA_BYTES;
WHEN "01111010" => --7Ah
Instruct <= ERRS;
bus_cycle_state := DATA_BYTES;
WHEN "00010100" => --14h
Instruct <= ABRD;
bus_cycle_state := DATA_BYTES;
WHEN "00010101" => --15h
Instruct <= ABWR;
bus_cycle_state := DATA_BYTES;
WHEN "00010110" => --16h
Instruct <= BRRD;
bus_cycle_state := DATA_BYTES;
WHEN "00010111" => --17h
Instruct <= BRWR;
bus_cycle_state := DATA_BYTES;
WHEN "10111001" => --B9h
Instruct <= BRAC;
bus_cycle_state := DATA_BYTES;
WHEN "00101011" => --2Bh
Instruct <= ASPRD;
bus_cycle_state := DATA_BYTES;
WHEN "00101111" => --2Fh
Instruct <= ASPP;
bus_cycle_state := DATA_BYTES;
WHEN "11100000" => --E0h
Instruct <= DYBRD;
bus_cycle_state := ADDRESS_BYTES;
WHEN "11100001" => --E1h
Instruct <= DYBWR;
bus_cycle_state := ADDRESS_BYTES;
WHEN "11100010" => --E2h
Instruct <= PPBRD;
bus_cycle_state := ADDRESS_BYTES;
WHEN "11100011" => --E3h
Instruct <= PPBP;
bus_cycle_state := ADDRESS_BYTES;
WHEN "11100100" => --E4h
Instruct <= PPBERS;
bus_cycle_state := DATA_BYTES;
WHEN "10100110" => --A6h
Instruct <= PLBWR;
bus_cycle_state := DATA_BYTES;
WHEN "10100111" => --A7h
Instruct <= PLBRD;
bus_cycle_state := DATA_BYTES;
WHEN "11100111" => --E7h
Instruct <= PASSRD;
bus_cycle_state := DATA_BYTES;
WHEN "11101000" => --E8h
Instruct <= PASSP;
bus_cycle_state := DATA_BYTES;
WHEN "11101001" => --E9h
Instruct <= PASSU;
bus_cycle_state := DATA_BYTES;
WHEN "11110000" => --F0h
Instruct <= RESET;
bus_cycle_state := DATA_BYTES;
WHEN "11111111" => --FFh
Instruct <= MBR;
bus_cycle_state := MODE_BYTE;
WHEN "01000001" => -- 41h
Instruct <= DLPRD;
bus_cycle_state := DATA_BYTES;
WHEN "01000011" => -- 43h
Instruct <= PNVDLR;
bus_cycle_state := DATA_BYTES;
WHEN "01001010" => -- 4Ah
Instruct <= WVDLR;
bus_cycle_state := DATA_BYTES;
WHEN "00110000" => --30h
Instruct <= CLSR;
bus_cycle_state := DATA_BYTES;
WHEN others =>
null;
END CASE;
END IF;
END IF;
END IF;
WHEN ADDRESS_BYTES =>
IF Instruct= DDRFR OR Instruct= DDRFR4 OR Instruct= DDRDIOR
OR Instruct = DDRDIOR4 OR Instruct = DDRQIOR OR
Instruct = DDRQIOR4 THEN
DOUBLE := TRUE;
ELSE
DOUBLE := FALSE;
END IF;
IF (rising_edge(SCK_ipd) AND NOT(DOUBLE) AND
(CSNeg_ipd= '0')) THEN
IF (((Instruct=FSTRD AND EXTADD= '0' )
OR (Instruct=DOR AND EXTADD= '0')
OR Instruct=OTPR) AND
((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1'))
OR (Instruct=QOR AND QUAD= '1' AND EXTADD='0') THEN
--Instruction + 3 Bytes Address + Dummy Byte
Address_in(addr_cnt) := SIIn;
addr_cnt := addr_cnt + 1;
IF addr_cnt = 3*BYTE THEN
FOR I IN 23 DOWNTO 0 LOOP
addr_bytes(23-i) := Address_in(i);
END LOOP;
addr_bytes(31 downto 24) := "00000000";
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
IF (Instruct=FSTRD OR Instruct=DOR OR
Instruct=QOR) THEN
IF (Latency_code = 3) THEN
bus_cycle_state := DATA_BYTES;
ELSE
bus_cycle_state := DUMMY_BYTES;
END IF;
ELSE
bus_cycle_state := DUMMY_BYTES;
END IF;
END IF;
ELSIF ((((Instruct=FSTRD4) OR (Instruct=DOR4) OR
((Instruct=FSTRD) AND EXTADD= '1') OR
((Instruct=DOR) AND EXTADD= '1')) AND
((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1')) OR
((Instruct=QOR4) AND QUAD='1') OR
((Instruct=QOR) AND QUAD='1' AND EXTADD='1')) THEN
--Instruction + 4 Bytes Address + Dummy Byte
Address_in(addr_cnt) := SIIn;
addr_cnt := addr_cnt + 1;
IF addr_cnt = 4*BYTE THEN
FOR I IN 31 DOWNTO 0 LOOP
hiaddr_bytes(31-i) := Address_in(i);
END LOOP;
Address <= to_nat(hiaddr_bytes);
change_addr <= '1','0' AFTER 1 ns;
IF Latency_code = 3 THEN
bus_cycle_state := DATA_BYTES;
ELSE
bus_cycle_state := DUMMY_BYTES;
IF (DOUBLE AND NOT(hold_mode) AND
VDLR_reg /= "00000000") THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
END IF;
END IF;
ELSIF Instruct = DIOR AND EXTADD= '0' AND
((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1') THEN
-- DUAL I/O High Performance Read (3Bytes Address)
IF SOIn /= 'Z' THEN
Address_in(2*addr_cnt) := SOIn;
Address_in(2*addr_cnt+1) := SIIn;
read_cnt := 0;
addr_cnt := addr_cnt + 1;
IF addr_cnt = (3*BYTE) / 2 THEN
addr_cnt := 0;
FOR I IN 23 DOWNTO 0 LOOP
addr_bytes(23-i) := Address_in(i);
END LOOP;
addr_bytes(31 downto 24) := "00000000";
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
IF EHP THEN
bus_cycle_state := MODE_BYTE;
ELSE
bus_cycle_state := DUMMY_BYTES;
END IF;
END IF;
ELSE
bus_cycle_state := STAND_BY;
END IF;
ELSIF ((Instruct = DIOR4 OR
(Instruct = DIOR AND EXTADD= '1')) AND
((HOLDNeg_pullup = '1' AND QUAD = '0') OR
QUAD = '1')) THEN
-- DUAL I/O High Performance Read (4Bytes Address)
IF SOIn /= 'Z' THEN
Address_in(2*addr_cnt) := SOIn;
Address_in(2*addr_cnt+1) := SIIn;
read_cnt := 0;
addr_cnt := addr_cnt + 1;
IF addr_cnt = (4*BYTE) / 2 THEN
addr_cnt := 0;
FOR I IN 31 DOWNTO 0 LOOP
hiaddr_bytes(31-i) := Address_in(i);
END LOOP;
Address <= to_nat(hiaddr_bytes);
change_addr <= '1','0' AFTER 1 ns;
IF EHP THEN
bus_cycle_state := MODE_BYTE;
ELSE
bus_cycle_state := DUMMY_BYTES;
END IF;
END IF;
ELSE
bus_cycle_state := STAND_BY;
END IF;
ELSIF (Instruct = QIOR AND EXTADD= '0') THEN
-- QUAD I/O High Performance Read (3Bytes Address)
IF QUAD = '1' THEN
IF SOIn /= 'Z' THEN
Address_in(4*addr_cnt) := HOLDNegIn;
Address_in(4*addr_cnt+1) := WPNegIn;
Address_in(4*addr_cnt+2) := SOIn;
Address_in(4*addr_cnt+3) := SIIn;
read_cnt := 0;
addr_cnt := addr_cnt + 1;
IF addr_cnt = (3*BYTE) / 4 THEN
addr_cnt := 0;
FOR I IN 23 DOWNTO 0 LOOP
addr_bytes(23-i) := Address_in(i);
END LOOP;
addr_bytes(31 downto 24) := "00000000";
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
bus_cycle_state := MODE_BYTE;
END IF;
END IF;
ELSE
bus_cycle_state := STAND_BY;
END IF;
ELSIF (Instruct = QIOR4 OR
(Instruct = QIOR AND EXTADD= '1')) THEN
-- QUAD I/O High Performance Read (4Bytes Address)
IF QUAD = '1' THEN
IF SOIn /= 'Z' THEN
Address_in(4*addr_cnt) := HOLDNegIn;
Address_in(4*addr_cnt+1) := WPNegIn;
Address_in(4*addr_cnt+2) := SOIn;
Address_in(4*addr_cnt+3) := SIIn;
read_cnt := 0;
addr_cnt := addr_cnt + 1;
IF addr_cnt = (4*BYTE) / 4 THEN
addr_cnt := 0;
FOR I IN 31 DOWNTO 0 LOOP
hiaddr_bytes(31-i)
:= Address_in(i);
END LOOP;
Address <= to_nat(hiaddr_bytes);
change_addr <= '1','0' AFTER 1 ns;
bus_cycle_state := MODE_BYTE;
END IF;
END IF;
ELSE
bus_cycle_state := STAND_BY;
END IF;
ELSIF (((Instruct = RD4 OR Instruct = PP4 OR
Instruct = SE4 OR Instruct = PPBRD OR
Instruct = DYBRD OR Instruct = DYBWR OR
Instruct = PPBP OR Instruct = P4E4 OR
(Instruct = READ AND EXTADD= '1' ) OR
(Instruct = PP AND EXTADD= '1' ) OR
(Instruct = SE AND EXTADD= '1' )) AND
((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1'))
OR (QUAD ='1' AND (Instruct=QPP4 OR
(Instruct = QPP AND EXTADD= '1' ))))THEN
Address_in(addr_cnt) := SIIn;
addr_cnt := addr_cnt + 1;
IF addr_cnt = 4*BYTE THEN
FOR I IN 31 DOWNTO 0 LOOP
hiaddr_bytes(31-i) := Address_in(i);
END LOOP;
Address <= to_nat(hiaddr_bytes);
change_addr <= '1','0' AFTER 1 ns;
bus_cycle_state := DATA_BYTES;
END IF;
ELSIF (((HOLDNeg_pullup='1' AND QUAD='0')
OR QUAD='1') AND EXTADD= '0') THEN
Address_in(addr_cnt) := SIIn;
addr_cnt := addr_cnt + 1;
IF addr_cnt = 3*BYTE THEN
FOR I IN 23 DOWNTO 0 LOOP
addr_bytes(23-i) := Address_in(i);
END LOOP;
addr_bytes(31 downto 24) := "00000000";
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
bus_cycle_state := DATA_BYTES;
END IF;
END IF;
ELSIF (SCK_ipd'EVENT AND DOUBLE AND addr_cnt /= 0 ) OR
(rising_edge(SCK_ipd) AND DOUBLE AND addr_cnt = 0 ) THEN
IF (Instruct=DDRFR AND EXTADD= '0' ) THEN
--Fast DDR Read Mode
Address_in(addr_cnt) := SIIn;
addr_cnt := addr_cnt + 1;
read_cnt := 0;
IF addr_cnt = 3*BYTE THEN
addr_cnt := 0;
FOR I IN 23 DOWNTO 0 LOOP
addr_bytes(23-i) := Address_in(i);
END LOOP;
addr_bytes(31 downto 24) := "00000000";
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
IF EHP THEN
bus_cycle_state := MODE_BYTE;
ELSE
bus_cycle_state := DUMMY_BYTES;
END IF;
END IF;
ELSIF (Instruct=DDRFR4 OR
(Instruct=DDRFR AND EXTADD= '1' )) THEN
Address_in(addr_cnt) := SIIn;
addr_cnt := addr_cnt + 1;
read_cnt := 0;
IF addr_cnt = 4*BYTE THEN
addr_cnt := 0;
FOR I IN 31 DOWNTO 0 LOOP
addr_bytes(31-i) := Address_in(i);
END LOOP;
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
IF EHP THEN
bus_cycle_state := MODE_BYTE;
ELSE
bus_cycle_state := DUMMY_BYTES;
IF ((DOUBLE AND NOT(hold_mode)) AND
VDLR_reg /= "00000000") THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
END IF;
END IF;
ELSIF (Instruct= DDRDIOR AND EXTADD= '0' ) THEN
--Dual I/O DDR Read Mode
Address_in(2*addr_cnt) := SOIn;
Address_in(2*addr_cnt+1):= SIIn;
addr_cnt := addr_cnt + 1;
read_cnt := 0;
IF addr_cnt = (3*BYTE)/2 THEN
addr_cnt := 0;
FOR I IN 23 DOWNTO 0 LOOP
addr_bytes(23-i) := Address_in(i);
END LOOP;
addr_bytes(31 downto 24) := "00000000";
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
IF EHP THEN
bus_cycle_state := MODE_BYTE;
ELSE
bus_cycle_state := DUMMY_BYTES;
END IF;
END IF;
ELSIF (Instruct=DDRDIOR4 OR
(Instruct=DDRDIOR AND EXTADD= '1' )) THEN
--Dual I/O DDR Read Mode
Address_in(2*addr_cnt) := SOIn;
Address_in(2*addr_cnt+1) := SIIn;
addr_cnt := addr_cnt + 1;
read_cnt := 0;
IF addr_cnt = (4*BYTE)/2 THEN
addr_cnt := 0;
FOR I IN 31 DOWNTO 0 LOOP
addr_bytes(31-i) := Address_in(i);
END LOOP;
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
IF EHP THEN
bus_cycle_state := MODE_BYTE;
ELSE
bus_cycle_state := DUMMY_BYTES;
IF ((DOUBLE AND NOT(hold_mode)) AND
VDLR_reg /= "00000000") THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
END IF;
END IF;
ELSIF (Instruct=DDRQIOR AND EXTADD= '0' ) AND
QUAD = '1' THEN
--Quad I/O DDR Read Mode
Address_in(4*addr_cnt) := HOLDNegIn;
Address_in(4*addr_cnt+1) := WPNegIn;
Address_in(4*addr_cnt+2) := SOIn;
Address_in(4*addr_cnt+3) := SIIn;
addr_cnt := addr_cnt + 1;
read_cnt := 0;
IF addr_cnt = (3*BYTE)/4 THEN
addr_cnt := 0;
FOR I IN 23 DOWNTO 0 LOOP
addr_bytes(23-i) := Address_in(i);
END LOOP;
addr_bytes(31 downto 24) := "00000000";
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 5 ns;
bus_cycle_state := MODE_BYTE;
END IF;
ELSIF QUAD = '1' AND (Instruct=DDRQIOR4 OR
(Instruct=DDRQIOR AND EXTADD= '1' )) THEN
Address_in(4*addr_cnt) := HOLDNegIn;
Address_in(4*addr_cnt+1) := WPNegIn;
Address_in(4*addr_cnt+2) := SOIn;
Address_in(4*addr_cnt+3) := SIIn;
addr_cnt := addr_cnt + 1;
read_cnt := 0;
IF addr_cnt = (4*BYTE)/4 THEN
addr_cnt := 0;
FOR I IN 31 DOWNTO 0 LOOP
addr_bytes(31-i) := Address_in(i);
END LOOP;
Address <= to_nat(addr_bytes);
change_addr <= '1','0' AFTER 1 ns;
bus_cycle_state := MODE_BYTE;
END IF;
END IF;
END IF;
WHEN MODE_BYTE =>
IF rising_edge(SCK_ipd) THEN
IF ((Instruct=DIOR OR Instruct = DIOR4) AND
((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1')) THEN
mode_in(2*mode_cnt) := SOIn;
mode_in(2*mode_cnt+1) := SIIn;
mode_cnt := mode_cnt + 1;
IF mode_cnt = BYTE/2 THEN
mode_cnt := 0;
FOR I IN 7 DOWNTO 0 LOOP
mode_bytes(i) := mode_in(7-i);
END LOOP;
IF Latency_code = 0 OR Latency_code = 3 THEN
bus_cycle_state := DATA_BYTES;
ELSE
bus_cycle_state := DUMMY_BYTES;
END IF;
END IF;
ELSIF (Instruct=QIOR OR Instruct = QIOR4)
AND QUAD = '1' THEN
mode_in(4*mode_cnt) := HOLDNegIn;
mode_in(4*mode_cnt+1) := WPNegIn;
mode_in(4*mode_cnt+2) := SOIn;
mode_in(4*mode_cnt+3) := SIIn;
mode_cnt := mode_cnt + 1;
IF mode_cnt = BYTE/4 THEN
mode_cnt := 0;
FOR I IN 7 DOWNTO 0 LOOP
mode_bytes(i) := mode_in(7-i);
END LOOP;
bus_cycle_state := DUMMY_BYTES;
END IF;
ELSIF Instruct=DDRFR OR Instruct = DDRFR4 THEN
mode_in(2*mode_cnt) := SIIn;
ELSIF Instruct=DDRDIOR OR Instruct = DDRDIOR4 THEN
mode_in(4*mode_cnt) := SOIn;
mode_in(4*mode_cnt+1) := SIIn;
ELSIF (Instruct=DDRQIOR OR Instruct = DDRQIOR4)
AND QUAD = '1' THEN
mode_in(0) := HOLDNegIn;
mode_in(1) := WPNegIn;
mode_in(2) := SOIn;
mode_in(3) := SIIn;
END IF;
dummy_cnt := 0;
dummy_cnt_act_temp <= dummy_cnt;
ELSIF falling_edge(SCK_ipd) THEN
IF Instruct=DDRFR OR Instruct = DDRFR4 THEN
mode_in(2*mode_cnt+1) := SIIn;
mode_cnt := mode_cnt + 1;
IF mode_cnt = BYTE/2 THEN
mode_cnt := 0;
FOR I IN 7 DOWNTO 0 LOOP
mode_bytes(i) := mode_in(7-i);
END LOOP;
bus_cycle_state := DUMMY_BYTES;
IF ((DOUBLE AND NOT(hold_mode)) AND
VDLR_reg /= "00000000") THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
END IF;
ELSIF Instruct=DDRDIOR OR Instruct = DDRDIOR4 THEN
mode_in(4*mode_cnt+2) := SOIn;
mode_in(4*mode_cnt+3) := SIIn;
mode_cnt := mode_cnt + 1;
IF mode_cnt = BYTE/4 THEN
mode_cnt := 0;
FOR I IN 7 DOWNTO 0 LOOP
mode_bytes(i) := mode_in(7-i);
END LOOP;
bus_cycle_state := DUMMY_BYTES;
IF ((DOUBLE AND NOT(hold_mode)) AND
VDLR_reg /= "00000000") THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
END IF;
ELSIF (Instruct=DDRQIOR OR Instruct = DDRQIOR4)
AND QUAD = '1' THEN
mode_in(4) := HOLDNegIn;
mode_in(5) := WPNegIn;
mode_in(6) := SOIn;
mode_in(7) := SIIn;
FOR I IN 7 DOWNTO 0 LOOP
mode_bytes(i) := mode_in(7-i);
END LOOP;
bus_cycle_state := DUMMY_BYTES;
IF ((DOUBLE AND NOT(hold_mode)) AND
VDLR_reg /= "00000000") THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
END IF;
END IF;
WHEN DUMMY_BYTES =>
IF rising_edge(SCK_ipd) THEN
IF ((DOUBLE AND NOT(hold_mode)) AND
VDLR_reg /= "00000000") THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
IF (((Instruct=FSTRD OR Instruct=FSTRD4 OR
Instruct=DOR OR Instruct=DOR4 OR
Instruct=OTPR) AND
((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1')) OR
((Instruct = QOR OR Instruct = QOR4) AND
QUAD = '1'))THEN
dummy_cnt := dummy_cnt + 1;
dummy_cnt_act_temp <= dummy_cnt;
IF dummy_cnt = BYTE THEN
bus_cycle_state := DATA_BYTES;
END IF;
ELSIF (Instruct=DDRFR OR Instruct=DDRFR4) THEN
dummy_cnt := dummy_cnt + 1;
dummy_cnt_act_temp <= dummy_cnt;
IF EHP THEN
IF ((Latency_code = 3 AND dummy_cnt=1) OR
(Latency_code = 0 AND dummy_cnt=2) OR
(Latency_code = 1 AND dummy_cnt=4) OR
(Latency_code = 2 AND dummy_cnt=5)) THEN
DummyBytes_act := '1';
bus_cycle_state := DATA_BYTES;
END IF;
ELSE
IF ((Latency_code = 3 AND dummy_cnt = 4) OR
(Latency_code = 0 AND dummy_cnt = 5) OR
(Latency_code = 1 AND dummy_cnt = 6) OR
(Latency_code = 2 AND dummy_cnt = 7)) THEN
DummyBytes_act := '1';
bus_cycle_state := DATA_BYTES;
END IF;
END IF;
ELSIF Instruct=RES THEN
dummy_cnt := dummy_cnt + 1;
dummy_cnt_act_temp <= dummy_cnt;
IF dummy_cnt = 3*BYTE THEN
bus_cycle_state := DATA_BYTES;
END IF;
ELSIF (Instruct = DIOR OR Instruct = DIOR4) AND
((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1') THEN
dummy_cnt := dummy_cnt + 1;
dummy_cnt_act_temp <= dummy_cnt;
IF EHP THEN
IF ((Latency_code = 1 AND dummy_cnt = 1) OR
(Latency_code = 2 AND dummy_cnt = 2)) THEN
DummyBytes_act := '1';
bus_cycle_state := DATA_BYTES;
END IF;
ELSE
IF ((Latency_code = 3 AND dummy_cnt = 4) OR
(Latency_code = 0 AND dummy_cnt = 4) OR
(Latency_code = 1 AND dummy_cnt = 5) OR
(Latency_code = 2 AND dummy_cnt = 6)) THEN
DummyBytes_act := '1';
bus_cycle_state := DATA_BYTES;
END IF;
END IF;
ELSIF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
dummy_cnt := dummy_cnt + 1;
dummy_cnt_act_temp <= dummy_cnt;
IF EHP THEN
IF ((Latency_code = 3 AND dummy_cnt = 2) OR
(Latency_code = 0 AND dummy_cnt = 4) OR
(Latency_code = 1 AND dummy_cnt = 5) OR
(Latency_code = 2 AND dummy_cnt = 6)) THEN
DummyBytes_act := '1';
bus_cycle_state := DATA_BYTES;
END IF;
ELSE
IF ((Latency_code = 3 AND dummy_cnt = 4) OR
(Latency_code = 0 AND dummy_cnt = 6) OR
(Latency_code = 1 AND dummy_cnt = 7) OR
(Latency_code = 2 AND dummy_cnt = 8)) THEN
DummyBytes_act := '1';
bus_cycle_state := DATA_BYTES;
END IF;
END IF;
ELSIF ((Instruct = QIOR OR Instruct = QIOR4) AND
QUAD = '1') THEN
dummy_cnt := dummy_cnt + 1;
dummy_cnt_act_temp <= dummy_cnt;
IF ((Latency_code = 3 AND dummy_cnt = 1) OR
(Latency_code = 0 AND dummy_cnt = 4) OR
(Latency_code = 1 AND dummy_cnt = 4) OR
(Latency_code = 2 AND dummy_cnt = 5)) THEN
DummyBytes_act := '1';
bus_cycle_state := DATA_BYTES;
END IF;
ELSIF (Instruct = DDRQIOR OR Instruct = DDRQIOR4)
AND QUAD = '1' THEN
dummy_cnt := dummy_cnt + 1;
dummy_cnt_act_temp <= dummy_cnt;
IF ((Latency_code = 3 AND dummy_cnt = 3) OR
(Latency_code = 0 AND dummy_cnt = 6) OR
(Latency_code = 1 AND dummy_cnt = 7) OR
(Latency_code = 2 AND dummy_cnt = 8)) THEN
DummyBytes_act := '1';
bus_cycle_state := DATA_BYTES;
END IF;
END IF;
ELSIF falling_edge(SCK_ipd) THEN
IF NOT(hold_mode) THEN
IF (DOUBLE AND VDLR_reg /= "00000000") THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
END IF;
END IF;
WHEN DATA_BYTES =>
IF rising_edge(CSNeg_ipd) THEN
IF ((mode_bytes(7 downto 4) = "1010" AND
(Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = QIOR OR Instruct = QIOR4)) OR
((mode_bytes(7 downto 4) =
NOT(mode_bytes(3 downto 0))) AND
(Instruct = DDRFR OR Instruct = DDRFR4 OR
Instruct = DDRDIOR OR Instruct = DDRDIOR4 OR
Instruct = DDRQIOR OR Instruct = DDRQIOR4))) THEN
bus_cycle_state := ADDRESS_BYTES;
ELSE
bus_cycle_state := STAND_BY;
END IF;
END IF;
IF falling_edge(SCK_ipd) AND CSNeg_ipd = '0' AND
NOT(DOUBLE) THEN
IF ((Instruct = READ OR Instruct=RD4 OR
Instruct = FSTRD OR Instruct = FSTRD4 OR
Instruct = RDSR OR Instruct = RDSR2 OR
Instruct = RDCR OR Instruct = OTPR OR
Instruct = DOR OR Instruct = DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = ABRD OR Instruct = BRRD OR
Instruct = ASPRD OR Instruct = DYBRD OR
Instruct = PPBRD OR
Instruct = PASSRD OR Instruct = RDID OR
Instruct = RES OR Instruct = REMS OR
Instruct = PLBRD OR Instruct = DLPRD)
AND ((HOLDNeg_pullup='1' AND QUAD='0') OR QUAD='1'))
OR (current_state = AUTOBOOT AND start_delay = 0)OR
((Instruct=QOR OR Instruct=QIOR OR Instruct=QOR4
OR Instruct= QIOR4) AND QUAD = '1') THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
ELSIF SCK_ipd'EVENT AND CSNeg_ipd = '0' AND DOUBLE THEN
read_out <= '1', '0' AFTER 1 ns;
END IF;
IF rising_edge(SCK_ipd) THEN
IF QUAD = '1' AND (Instruct=QPP OR Instruct = QPP4)THEN
quad_nybble := HOLDNegIn & WPNegIn & SOIn & SIIn;
IF data_cnt > (PageSize*2-1) THEN
--In case of quad mode and QPP,
--if more than 512 bytes are sent to the device
FOR I IN 0 TO (PageSize*2-2) LOOP
quad_data_in(i) := quad_data_in(i+1);
END LOOP;
quad_data_in((PageSize*2-1)) :=
to_nat(quad_nybble);
data_cnt := data_cnt +1;
ELSE
IF quad_nybble /= "ZZZZ" THEN
quad_data_in(data_cnt) :=
to_nat(quad_nybble);
END IF;
data_cnt := data_cnt +1;
END IF;
ELSIF ((HOLDNeg_pullup='1' AND QUAD='0')
OR QUAD='1') THEN
IF data_cnt > (PageSize*8-1) THEN
--In case of serial mode and PP,
-- if more than 512 bytes are sent to the device
-- previously latched data are discarded and last
-- 512 data bytes are guaranteed to be programmed
-- correctly within the same page.
IF bit_cnt = 0 THEN
FOR I IN 0 TO ((PageSize-1)*BYTE - 1) LOOP
Data_in(i) := Data_in(i+8);
END LOOP;
END IF;
Data_in((PageSize-1)*BYTE + bit_cnt) := SIIn;
bit_cnt := bit_cnt + 1;
IF bit_cnt = 8 THEN
bit_cnt := 0;
END IF;
data_cnt := data_cnt + 1;
ELSE
Data_in(data_cnt) := SIIn;
data_cnt := data_cnt + 1;
bit_cnt := 0;
END IF;
END IF;
END IF;
IF rising_edge(CSNeg_ipd) THEN
CASE Instruct IS
WHEN WREN | WRDI | BE | SE | SE4 | CLSR | RESET |
PPBP | PPBERS | PGSP | PGRS | ERSP | BRAC |
ERRS | P4E | P4E4 | PLBWR =>
IF ((HOLDNeg_pullup='1' AND QUAD='0')
OR QUAD='1') THEN
IF data_cnt = 0 THEN
write <= '0';
END IF;
END IF;
WHEN WRR =>
IF ((HOLDNeg_pullup='1' AND QUAD='0')
OR QUAD='1') THEN
IF ((data_cnt mod 8) = 0 AND data_cnt > 0) THEN
IF data_cnt = 8 THEN
--If CS# is driven high after eight
--cycle,only the Status Register is
--written to.
write <= '0';
FOR i IN 0 TO 7 LOOP
Status_reg1_in(i) <= Data_in(7-i);
END LOOP;
ELSIF data_cnt = 16 THEN
--After the 16th cycle both the
--Status and Configuration Registers
--are written to.
write <= '0';
cfg_write <= '1';
FOR i IN 0 TO 7 LOOP
Status_reg1_in(i) <= Data_in(7-i);
Config_reg1_in(i) <= Data_in(15-i);
END LOOP;
END IF;
END IF;
END IF;
WHEN PP | PP4 | OTPP =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt > 0 THEN
IF (data_cnt mod 8) = 0 THEN
write <= '0';
FOR I IN 0 TO (PageSize-1) LOOP
FOR J IN 7 DOWNTO 0 LOOP
IF Data_in((i*8) + (7-j))
/= 'X' THEN
Byte_slv(j) :=
Data_in((i*8) + (7-j));
END IF;
END LOOP;
WByte(i) <=
to_nat(Byte_slv);
END LOOP;
IF data_cnt > PageSize*BYTE THEN
Byte_number <= PageSize-1;
ELSE
Byte_number <= data_cnt/8-1;
END IF;
END IF;
END IF;
END IF;
WHEN QPP | QPP4=>
IF data_cnt > 0 THEN
IF data_cnt mod 2 = 0 THEN
quadpg <= FALSE;
write <= '0';
FOR I IN 0 TO (PageSize-1) LOOP
FOR J IN 1 DOWNTO 0 LOOP
Quad_slv :=
to_slv(quad_data_in((i*2) +
(1-j)),4);
Byte_slv(4*j+3 DOWNTO 4*j) :=
Quad_slv;
END LOOP;
WByte(i) <= to_nat(Byte_slv);
END LOOP;
IF data_cnt > PageSize*2 THEN
Byte_number <= PageSize-1;
ELSE
Byte_number <= data_cnt/2-1;
END IF;
END IF;
END IF;
WHEN ABWR =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt = 32 THEN
write <= '0';
FOR J IN 0 TO 31 LOOP
AutoBoot_reg_in(J) <=
Data_in(31-J);
END LOOP;
END IF;
END IF;
WHEN BRWR =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt = 8 THEN
write <= '0';
FOR J IN 0 TO 7 LOOP
Bank_Addr_reg_in(J) <=
Data_in(7-J);
END LOOP;
END IF;
END IF;
WHEN ASPP =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt = 16 THEN
write <= '0';
FOR J IN 0 TO 15 LOOP
ASP_reg_in(J) <=
Data_in(15-J);
END LOOP;
END IF;
END IF;
WHEN DYBWR =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt = 8 THEN
write <= '0';
FOR J IN 0 TO 7 LOOP
DYBAR_in(J) <=
Data_in(7-J);
END LOOP;
END IF;
END IF;
WHEN PNVDLR =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt = 8 THEN
write <= '0';
FOR J IN 0 TO 7 LOOP
NVDLR_reg_in(J) <= Data_in(7-J);
END LOOP;
END IF;
END IF;
WHEN WVDLR =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt = 8 THEN
write <= '0';
FOR J IN 0 TO 7 LOOP
VDLR_reg_in(J) <= Data_in(7-J);
END LOOP;
END IF;
END IF;
WHEN PASSP =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt = 64 THEN
write <= '0';
FOR J IN 1 TO 8 LOOP
FOR K IN 1 TO 8 LOOP
Password_reg_in(J*8-K) <=
Data_in(8*(J-1)+K-1);
END LOOP;
END LOOP;
END IF;
END IF;
WHEN PASSU =>
IF ((HOLDNeg_pullup='1' AND QUAD='0') OR
QUAD='1') THEN
IF data_cnt = 64 THEN
write <= '0';
FOR J IN 1 TO 8 LOOP
FOR K IN 1 TO 8 LOOP
PASS_TEMP(J*8-K) <=
Data_in(8*(J-1)+K-1);
END LOOP;
END LOOP;
END IF;
END IF;
WHEN others =>
null;
END CASE;
END IF;
END CASE;
END IF;
END PROCESS BusCycleDecode;
---------------------------------------------------------------------------
-- Timing control for the Page Program
---------------------------------------------------------------------------
ProgTime : PROCESS(PSTART, PGSUSP, PGRES, RST, Reseted)
VARIABLE pob : time;
VARIABLE elapsed : time;
VARIABLE start : time;
VARIABLE duration : time;
BEGIN
IF rising_edge(PSTART) AND PDONE = '1' THEN
IF Instruct = PP OR Instruct = PP4 OR Instruct = OTPP OR
Instruct = QPP OR Instruct = QPP4 THEN
IF PageSize = 256 THEN
pob := tdevice_PP256;
ELSE
pob := tdevice_PP512;
END IF;
ELSE
pob := tdevice_BP;
END IF;
elapsed := 0 ns;
start := NOW;
PDONE <= '0', '1' AFTER pob;
ELSIF PGSUSP'EVENT AND PGSUSP = '1' AND PDONE /= '1' THEN
elapsed := NOW - start;
duration := pob - elapsed;
PDONE <= '0';
ELSIF PGRES'EVENT AND PGRES = '1' AND PDONE /= '1'THEN
start := NOW;
PDONE <= '0', '1' AFTER duration;
END IF;
IF (RST'EVENT AND RST = '0') THEN
PDONE <= '1'; -- reset done, programing terminated
ELSIF rising_edge(Reseted) THEN
PDONE <= '1'; -- reset done, programing terminated
END IF;
END PROCESS ProgTime;
---------------------------------------------------------------------------
-- Timing control for the Write Status Register
---------------------------------------------------------------------------
WriteTime : PROCESS(WSTART)
VARIABLE wob : time;
BEGIN
IF LongTimming THEN
wob := tdevice_WRR;
ELSE
wob := tdevice_WRR / 100;
END IF;
IF rising_edge(WSTART) AND WDONE = '1' THEN
WDONE <= '0', '1' AFTER wob;
END IF;
IF (RST'EVENT AND RST = '0') THEN
WDONE <= '1'; -- reset done, programing terminated
ELSIF rising_edge(Reseted) THEN
WDONE <= '1'; -- reset done, programing terminated
END IF;
END PROCESS WriteTime;
---------------------------------------------------------------------------
-- Timing control for the Bulk Erase
---------------------------------------------------------------------------
ErsTime : PROCESS(ESTART, ESUSP, ERES, RST, Reseted)
VARIABLE seo : time;
VARIABLE beo : time;
VARIABLE elapsed : time;
VARIABLE start : time;
VARIABLE duration : time;
BEGIN
IF LongTimming THEN
IF UniformSec THEN
seo := tdevice_SE256;
ELSE
seo := tdevice_SE64;
END IF;
beo := tdevice_BE;
ELSE
IF UniformSec THEN
seo := tdevice_SE256 / 1000;
ELSE
seo := tdevice_SE64 / 100;
END IF;
beo := tdevice_BE / 1000;
END IF;
IF rising_edge(ESTART) AND EDONE = '1' THEN
IF Instruct = BE THEN
duration := beo;
ELSE --Instruct = SE OR SE4 OR P4E OR P4E4
duration := seo;
END IF;
elapsed := 0 ns;
EDONE <= '0', '1' AFTER duration;
start := NOW;
ELSIF ESUSP'EVENT AND ESUSP = '1' AND EDONE /= '1' THEN
elapsed := NOW - start;
duration := duration - elapsed;
EDONE <= '0';
ELSIF ERES'EVENT AND ERES = '1' AND EDONE /= '1' THEN
start := NOW;
EDONE <= '0', '1' AFTER duration;
END IF;
IF (RST'EVENT AND RST = '0') THEN
EDONE <= '1'; -- reset done, eras terminated
ELSIF rising_edge(Reseted) THEN
EDONE <= '1'; -- reset done, erase terminated
END IF;
END PROCESS ErsTime;
CheckCEOnPowerUP :PROCESS(CSNeg_ipd)
BEGIN
IF (PoweredUp = '0' AND falling_edge(CSNeg_ipd)) THEN
REPORT InstancePath & partID &
": Device is selected during Power Up"
SEVERITY WARNING;
END IF;
END PROCESS;
---------------------------------------------------------------------------
-- Main Behavior Process
-- combinational process for next state generation
---------------------------------------------------------------------------
StateGen :PROCESS(PoweredUp, write, CSNeg_ipd, RSTNeg_pullup, WDONE, PDONE,
ERSSUSP_out, PRGSUSP_out, EDONE, RST_out, PPBERASE_in,
PASSULCK_in)
VARIABLE sect : NATURAL RANGE 0 TO SecNum64;
BEGIN
IF rising_edge(PoweredUp) THEN
IF ABE = '1' AND RPME /= '0' THEN
--Autoboot is enabled and The Read Password feature is not enabled
next_state <= AUTOBOOT;
read_cnt := 0;
byte_cnt := 1;
read_addr := to_nat(AutoBoot_reg(31 DOWNTO 9)&"000000000");
start_delay := to_nat(AutoBoot_reg(8 DOWNTO 1));
ABSD := to_nat(AutoBoot_reg(8 DOWNTO 1));
ELSE
next_state <= IDLE;
END IF;
ELSE
IF RST_out= '0' then
next_state <= current_state;
ELSIF falling_edge(write) AND Instruct = RESET THEN
IF ABE = '1' AND RPME /= '0' THEN
read_cnt := 0;
byte_cnt := 1;
read_addr := to_nat(AutoBoot_reg(31 DOWNTO 9)&
"000000000");
start_delay:= to_nat(AutoBoot_reg(8 DOWNTO 1));
ABSD := to_nat(AutoBoot_reg(8 DOWNTO 1));
next_state <= AUTOBOOT;
ELSE
next_state <= IDLE;
END IF;
ELSE
CASE current_state IS
WHEN RESET_STATE =>
IF rising_edge(RST_out) THEN
IF ABE = '1' AND RPME /= '0'
AND RdPswdProtMode = '0' THEN
next_state <= AUTOBOOT;
read_cnt := 0;
byte_cnt := 1;
read_addr := to_nat(AutoBoot_reg(31 DOWNTO 9)&
"000000000");
start_delay := to_nat(AutoBoot_reg(8 DOWNTO 1));
ABSD := to_nat(AutoBoot_reg(8 DOWNTO 1));
ELSE
next_state <= IDLE;
END IF;
END IF;
WHEN IDLE =>
IF falling_edge(write) AND RdPswdProtMode = '0' THEN
IF (Instruct = WRR AND WEL = '1' AND BAR_ACC = '0') THEN
IF ((not(SRWD = '1' AND WPNeg_pullup = '0') AND
QUAD = '0') OR QUAD = '1') THEN
-- can not execute if HPM is entered
-- or if WEL bit is zero
IF ((TBPROT='1' AND Config_reg1_in(5)='0') OR
(TBPARM='1' AND Config_reg1_in(2)='0') OR
(BPNV ='1' AND Config_reg1_in(3)='0')) AND
cfg_write = '1' THEN
ASSERT cfg_write = '0'
REPORT "Changing value of Configuration " &
"Register OTP bit from 1 to 0 is " &
"not allowed!!!"
SEVERITY WARNING;
ELSE
next_state <= WRITE_SR;
END IF;
END IF;
ELSIF (Instruct = WRR AND BAR_ACC = '1') THEN
-- Write to the lower address bits of the BAR
IF (P_ERR = '0' AND E_ERR = '0')THEN
REPORT "WARNING: Changing values of " &
"Bank Address Register RFU bits" &
" are not allowed!!!"
SEVERITY WARNING;
END IF;
ELSIF (Instruct = PP OR Instruct = QPP OR
Instruct = PP4 OR Instruct = QPP4) AND
WEL = '1' THEN
ReturnSectorID(sect,Address);
pgm_page := Address/(PageSize+1);
IF (Sec_Prot(sect) = '0' AND
PPB_bits(sect)='1' AND DYB_bits(sect)='1') THEN
next_state <= PAGE_PG;
END IF;
ELSIF Instruct=OTPP AND WEL = '1' AND FREEZE = '0' THEN
IF ((((Address >= 16#10# AND Address <= 16#13#) OR
(Address >= 16#20# AND Address <= 16#FF#))
AND LOCK_BYTE1(Address/32) = '1') OR
((Address >= 16#100# AND Address <= 16#1FF#)
AND LOCK_BYTE2((Address-16#100#)/32) = '1') OR
((Address >= 16#200# AND Address <= 16#2FF#)
AND LOCK_BYTE3((Address-16#200#)/32) = '1') OR
((Address >= 16#300# AND Address <= 16#3FF#)
AND LOCK_BYTE4((Address-16#300#)/32) = '1')) AND
(Address + Byte_number <= OTPHiAddr) THEN
next_state <= OTP_PG;
END IF;
ELSIF (Instruct= SE OR Instruct= SE4) AND WEL= '1' THEN
ReturnSectorID(sect,Address);
IF UniformSec = TRUE OR
(TopBoot = TRUE AND sect < 254) OR
(BottomBoot = TRUE AND sect > 31) THEN
IF (Sec_Prot(sect) = '0' AND PPB_bits(sect)='1'
AND DYB_bits(sect)='1') THEN
next_state <= SECTOR_ERS;
END IF;
ELSIF (TopBoot = TRUE AND sect >= 254) OR
(BottomBoot = TRUE AND sect <= 31) THEN
IF Sec_ProtSE = 32 AND ASP_ProtSE = 32 THEN
--Sector erase command is applied to a 64 KB
--range that includes 4 KB sectors.
next_state <= SECTOR_ERS;
END IF;
END IF;
ELSIF (Instruct=P4E OR Instruct=P4E4) AND WEL='1' THEN
ReturnSectorID(sect,Address);
IF UniformSec = TRUE OR
(TopBoot = TRUE AND sect < 254) OR
(BottomBoot = TRUE AND sect > 31) THEN
--A P4E instruction applied to a sector that
--is larger than 4 KB will not be executed
--and will not set the E_ERR status.
REPORT "The instruction is applied to a "&
"sector that is larger than 4 KB. "&
"Instruction is ignored!!!"
SEVERITY warning;
ELSE
IF Sec_Prot(sect) = '0' AND PPB_bits(sect)='1'
AND DYB_bits(sect)='1' THEN
next_state <= SECTOR_ERS;
END IF;
END IF;
ELSIF Instruct = BE AND WEL = '1' AND
(BP0='0' AND BP1='0' AND BP2='0') THEN
next_state <= BULK_ERS;
ELSIF Instruct = ABWR AND WEL = '1' THEN
--Autoboot Register Write Command
next_state <= AUTOBOOT_PG;
ELSIF Instruct = BRWR THEN
--Bank Register Write Command
next_state <= IDLE;
ELSIF Instruct = ASPP AND WEL = '1' THEN
--ASP Register Program Command
IF not(ASPOTPFLAG) THEN
next_state <= ASP_PG;
END IF;
ELSIF Instruct = PLBWR AND WEL = '1' AND
RdPswdProtEnable = '0' THEN
next_state <= PLB_PG;
ELSIF Instruct = PASSP AND WEL = '1' THEN
IF not(PWDMLB='0' AND PSTMLB='1') THEN
next_state <= PASS_PG;
END IF;
ELSIF Instruct = PASSU AND WEL= '1' AND WIP= '0' THEN
next_state <= PASS_UNLOCK;
ELSIF Instruct = PPBP AND WEL = '1' THEN
next_state <= PPB_PG;
ELSIF (Instruct=PPBERS AND WEL='1' AND PPBOTP='1') THEN
next_state <= PPB_ERS;
ELSIF Instruct = DYBWR AND WEL = '1' THEN
next_state <= DYB_PG;
ELSIF Instruct = PNVDLR AND WEL = '1' THEN
next_state <= NVDLR_PG;
ELSE
next_state <= IDLE;
END IF;
END IF;
IF falling_edge(write) AND RdPswdProtMode = '1' AND
WIP = '0' THEN
IF Instruct = PASSU THEN
next_state <= PASS_UNLOCK;
END IF;
END IF;
WHEN AUTOBOOT =>
IF rising_edge(CSNeg_ipd) THEN
next_state <= IDLE;
END IF;
WHEN WRITE_SR =>
IF rising_edge(WDONE) THEN
next_state <= IDLE;
END IF;
WHEN PAGE_PG =>
IF PRGSUSP_out'EVENT AND PRGSUSP_out = '1' THEN
next_state <= PG_SUSP;
ELSIF rising_edge(PDONE) THEN
next_state <= IDLE;
END IF;
WHEN PG_SUSP =>
IF falling_edge(write) THEN
IF Instruct = BRWR THEN
next_state <= PG_SUSP;
ELSIF Instruct = PGRS THEN
next_state <= PAGE_PG;
END IF;
ELSE
next_state <= PG_SUSP;
END IF;
WHEN OTP_PG =>
IF rising_edge(PDONE) THEN
next_state <= IDLE;
END IF;
WHEN BULK_ERS =>
IF rising_edge(EDONE) THEN
next_state <= IDLE;
END IF;
WHEN SECTOR_ERS =>
IF ERSSUSP_out'EVENT AND ERSSUSP_out = '1' THEN
next_state <= ERS_SUSP;
ELSIF rising_edge(EDONE) THEN
next_state <= IDLE;
END IF;
WHEN ERS_SUSP =>
IF falling_edge(write) THEN
IF (Instruct = PP OR Instruct = QPP OR
Instruct = PP4 OR Instruct = QPP4) AND
WEL = '1' THEN
IF (PARAM_REGION = TRUE AND
SectorSuspend /= Address/(SecSize+1)) OR
(PARAM_REGION = FALSE AND
SectorSuspend/=Address/(SecSize+1)+30*b_act) THEN
ReturnSectorID(sect,Address);
pgm_page := Address / (PageSize+1);
IF PPB_bits(sect)='1' AND
DYB_bits(sect)='1' THEN
next_state <= ERS_SUSP_PG;
END IF;
END IF;
ELSIF Instruct = BRWR THEN
next_state <= ERS_SUSP;
ELSIF (Instruct = DYBWR AND WEL = '1') THEN
next_state <= DYB_PG;
ELSIF Instruct = ERRS THEN
next_state <= SECTOR_ERS;
END IF;
ELSE
next_state <= ERS_SUSP;
END IF;
WHEN ERS_SUSP_PG =>
IF PRGSUSP_out'EVENT AND PRGSUSP_out = '1' THEN
next_state <= ERS_SUSP_PG_SUSP;
ELSIF rising_edge(PDONE) THEN
next_state <= ERS_SUSP;
END IF;
WHEN ERS_SUSP_PG_SUSP =>
IF falling_edge(write) THEN
IF Instruct = BRWR THEN
next_state <= ERS_SUSP_PG_SUSP;
ELSIF Instruct = PGRS THEN
next_state <= ERS_SUSP_PG;
END IF;
ELSE
next_state <= ERS_SUSP_PG_SUSP;
END IF;
WHEN PASS_PG =>
IF rising_edge(PDONE) THEN
next_state <= IDLE;
END IF;
WHEN PASS_UNLOCK =>
IF falling_edge(PASSULCK_in) THEN
next_state <= IDLE;
END IF;
WHEN PPB_PG =>
IF rising_edge(PDONE) THEN
next_state <= IDLE;
END IF;
WHEN PPB_ERS =>
IF falling_edge(PPBERASE_in) THEN
next_state <= IDLE;
END IF;
WHEN AUTOBOOT_PG =>
IF rising_edge(PDONE) THEN
next_state <= IDLE;
END IF;
WHEN PLB_PG =>
IF rising_edge(PDONE) THEN
next_state <= IDLE;
END IF;
WHEN DYB_PG =>
IF rising_edge(PDONE) THEN
IF ES = '1' THEN
next_state <= ERS_SUSP;
ELSE
next_state <= IDLE;
END IF;
END IF;
WHEN ASP_PG =>
IF rising_edge(PDONE) THEN
next_state <= IDLE;
END IF;
WHEN NVDLR_PG =>
IF rising_edge(PDONE) THEN
next_state <= IDLE;
END IF;
END CASE;
END IF;
END IF;
END PROCESS StateGen;
ReadEnable: PROCESS (read_out)
BEGIN
oe_z <= rising_edge(read_out) AND PoweredUp = '1';
IF read_out'EVENT AND read_out = '0' AND PoweredUp = '1' THEN
oe <= TRUE, FALSE AFTER 1 ns;
END IF;
END PROCESS ReadEnable;
---------------------------------------------------------------------------
--FSM Output generation and general funcionality
---------------------------------------------------------------------------
Functional : PROCESS(write,current_state,start_autoboot,CSNeg_ipd,
HOLDNeg_pullup, Instruct, Address, WByte,change_addr,
PoweredUp, WPNeg_pullup, WDONE, PDONE, EDONE,
PRGSUSP_out,ERSSUSP_out, PASSACC_out, oe, oe_z)
VARIABLE WData : WByteType:= (OTHERS => MaxData);
VARIABLE AddrLo : NATURAL;
VARIABLE AddrHi : NATURAL;
VARIABLE Addr : NATURAL;
VARIABLE Addr_tmp : NATURAL;
VARIABLE data_out : std_logic_vector(7 downto 0);
VARIABLE ident_out : std_logic_vector(647 downto 0);
VARIABLE ExtendedID : NATURAL;
VARIABLE old_bit : std_logic_vector(7 downto 0);
VARIABLE new_bit : std_logic_vector(7 downto 0);
VARIABLE old_int : INTEGER RANGE -1 to MaxData;
VARIABLE new_int : INTEGER RANGE -1 to MaxData;
VARIABLE old_pass : std_logic_vector(63 downto 0);
VARIABLE new_pass : std_logic_vector(63 downto 0);
VARIABLE wr_cnt : NATURAL RANGE 0 TO 511;
--Data Learning Pattern Enable
VARIABLE dlp_act : BOOLEAN := FALSE;
VARIABLE sect : NATURAL RANGE 0 TO SecNum64;
VARIABLE cnt : NATURAL RANGE 0 TO 512 := 0;
VARIABLE sec_tmp : NATURAL RANGE 0 TO SecNum64;
BEGIN
-----------------------------------------------------------------------
-- Functionality Section
-----------------------------------------------------------------------
IF Instruct'EVENT THEN
read_cnt := 0;
byte_cnt := 1;
fast_rd <= true;
dual <= false;
rd <= false;
any_read <= false;
END IF;
IF PASSACC_out'EVENT AND PASSACC_out = '1' THEN
WIP := '0';
PASSACC_in <= '0';
END IF;
IF rising_edge(PoweredUp) THEN
--the default condition after power-up
--The Bank Address Register is loaded to all zeroes
Bank_Addr_reg := (others => '0');
--The Configuration Register FREEZE bit is cleared.
FREEZE := '0';
--The WEL bit is cleared.
WEL := '0';
--When BPNV is set to '1'. the BP2-0 bits in Status Register are
--volatile and will be reset binary 111 after power-on reset
IF BPNV = '1' AND LOCK='0' AND FREEZE = '0' THEN
BP0 := '1';
BP1 := '1';
BP2 := '1';
BP_bits := BP2 & BP1 & BP0;
change_BP <= '1', '0' AFTER 1 ns;
END IF;
--As shipped from the factory, all devices default ASP to the
--Persistent Protection mode, with all sectors unprotected,
--when power is applied. The device programmer or host system must
--then choose which sector protection method to use.
--For Persistent Protection mode, PPBLOCK defaults to "1"
PPB_LOCK := '1';
PPB_LOCK_temp <= '1';
DYB_bits := (OTHERS => '1');
END IF;
IF falling_edge(write) AND Instruct = RESET THEN
--The Configuration Register is set for Address mode
Bank_Addr_reg := (others => '0');
--P_ERR bit is cleared
P_ERR := '0';
--E_ERR bit is cleared
E_ERR := '0';
--The WEL bit is cleared.
WEL := '0';
--The WIP bit is cleared.
WIP := '0';
--The ES bit is cleared.
ES := '0';
--The PS bit is cleared.
PS := '0';
DummyBytes_act := '0';
--When BPNV is set to '1'. the BP2-0 bits in Status
--Register are volatile and will be reseted after
--reset command
IF BPNV = '1' AND LOCK='0' AND FREEZE = '0' THEN
BP0 := '1';
BP1 := '1';
BP2 := '1';
BP_bits := BP2 & BP1 & BP0;
change_BP <= '1', '0' AFTER 1 ns;
END IF;
END IF;
IF change_addr'EVENT THEN
read_addr := Address;
END IF;
CASE current_state IS
WHEN IDLE =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
ASP_ProtSE := 0;
Sec_ProtSE := 0;
PARAM_REGION := false;
IF falling_edge(write) AND RdPswdProtMode = '1' THEN
IF Instruct = PASSU THEN
IF WIP = '0' THEN
PASSULCK_in <= '1';
ELSE
REPORT "The PASSU command cannot be accepted"&
" any faster than once every 100us"
SEVERITY WARNING;
END IF;
ELSIF Instruct = CLSR THEN
--The Clear Status Register Command resets bit SR1[5]
--(Erase Fail Flag) and bit SR1[6] (Program Fail Flag)
E_ERR := '0';
P_ERR := '0';
END IF;
END IF;
IF BottomBoot = TRUE THEN
FOR J IN 31 DOWNTO 0 LOOP
IF (PPB_bits(J)='1' AND DYB_bits(J)='1') THEN
ASP_ProtSE := ASP_ProtSE + 1;
END IF;
IF (Sec_Prot(J)='0') THEN
Sec_ProtSE := Sec_ProtSE + 1;
END IF;
END LOOP;
ELSIF TopBoot = TRUE THEN
FOR J IN 285 DOWNTO 254 LOOP
IF (PPB_bits(J)='1' AND DYB_bits(J)='1') THEN
ASP_ProtSE := ASP_ProtSE + 1;
END IF;
IF (Sec_Prot(J)='0') THEN
Sec_ProtSE := Sec_ProtSE + 1;
END IF;
END LOOP;
END IF;
IF falling_edge(write) AND RdPswdProtMode = '0' THEN
read_cnt := 0;
byte_cnt := 1;
IF Instruct = WREN THEN
WEL := '1';
ELSIF Instruct = WRDI THEN
WEL := '0';
ELSIF Instruct = WRR AND WEL = '1' AND BAR_ACC = '0' THEN
IF (not(SRWD = '1' AND WPNeg_pullup = '0') AND
QUAD ='0') OR QUAD ='1' THEN
-- can not execute if Hardware Protection Mode
-- is entered or if WEL bit is zero
IF ((TBPROT='1' AND Config_reg1_in(5)='0') OR
(TBPARM='1' AND Config_reg1_in(2)='0') OR
(BPNV ='1' AND Config_reg1_in(3)='0')) AND
cfg_write = '1' THEN
P_ERR := '1';
ELSE
WSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
END IF;
ELSE
WEL := '0';
END IF;
ELSIF (Instruct = PP OR Instruct = PP4) AND WEL = '1' THEN
ReturnSectorID(sect,Address);
Addr := Address;
IF (Sec_Prot(sect) = '0' AND
PPB_bits(sect)='1' AND DYB_bits(sect)='1') THEN
PSTART <= '1', '0' AFTER 5 ns;
PGSUSP <= '0';
PGRES <= '0';
INITIAL_CONFIG <= '1';
WIP := '1';
SA <= sect;
Addr := Address;
Addr_tmp := Address;
wr_cnt := Byte_number;
FOR I IN wr_cnt DOWNTO 0 LOOP
IF Viol /= '0' THEN
WData(i) := -1;
ELSE
WData(i) := WByte(i);
END IF;
END LOOP;
ELSE
P_ERR := '1';
WEL := '0';
END IF;
ELSIF (Instruct = QPP OR Instruct = QPP4) AND WEL = '1' THEN
ReturnSectorID(sect,Address);
Addr := Address;
pgm_page := Address/(PageSize+1);
IF (Sec_Prot(sect)= '0' AND
PPB_bits(sect)='1' AND DYB_bits(sect)='1') THEN
PSTART <= '1', '0' AFTER 5 ns;
PGSUSP <= '0';
PGRES <= '0';
INITIAL_CONFIG <= '1';
WIP := '1';
SA <= sect;
Addr := Address;
Addr_tmp := Address;
wr_cnt := Byte_number;
FOR I IN wr_cnt DOWNTO 0 LOOP
IF Viol /= '0' THEN
WData(i) := -1;
ELSE
WData(i) := WByte(i);
END IF;
END LOOP;
ELSE
P_ERR := '1';
WEL := '0';
END IF;
ELSIF Instruct = OTPP AND WEL = '1' THEN
-- As long as the FREEZE bit remains cleared to a logic '0'
--the OTP address space is programmable.
IF FREEZE = '0' THEN
IF ((((Address >= 16#0010# AND Address <= 16#13#)OR
(Address >= 16#0020# AND Address <= 16#FF#))
AND LOCK_BYTE1(Address/32) = '1') OR
((Address >= 16#100# AND Address <= 16#1FF#)
AND LOCK_BYTE2((Address-16#100#)/32) = '1') OR
((Address >= 16#200# AND Address <= 16#2FF#)
AND LOCK_BYTE3((Address-16#200#)/32) = '1') OR
((Address >= 16#300# AND Address <= 16#3FF#)
AND LOCK_BYTE4((Address-16#300#)/32) = '1')) AND
(Address + Byte_number <= OTPHiAddr) THEN
PSTART <= '1', '0' AFTER 1 ns;
WIP := '1';
Addr := Address;
Addr_tmp := Address;
wr_cnt := Byte_number;
FOR I IN wr_cnt DOWNTO 0 LOOP
IF Viol /= '0' THEN
WData(i) := -1;
ELSE
WData(i) := WByte(i);
END IF;
END LOOP;
ELSIF (Address < 16#0010# OR (Address > 16#0013# AND
Address < 16#0020#) OR Address > 16#3FF# ) THEN
P_ERR := '1';
WEL := '0';
IF Address < 16#0020# THEN
ASSERT false
REPORT "Given address is in" &
"reserved address range"
SEVERITY warning;
ELSIF Address > 16#3FF# THEN
ASSERT false
REPORT "Given address is out of" &
"OTP address range"
SEVERITY warning;
END IF;
ELSE
WEL := '0';
P_ERR := '1';
END IF;
ELSE
WEL := '0';
P_ERR := '1';
END IF;
ELSIF (Instruct = SE OR Instruct = SE4) AND WEL = '1' THEN
ReturnSectorID(sect,Address);
IF UniformSec = TRUE OR
(TopBoot = TRUE AND sect < 254) OR
(BottomBoot = TRUE AND sect > 31) THEN
SectorSuspend <= sect;
PARAM_REGION := FALSE;
IF (Sec_Prot(sect) = '0' AND
PPB_bits(sect)='1' AND DYB_bits(sect)='1') THEN
ESTART <= '1', '0' AFTER 5 ns;
ESUSP <= '0';
ERES <= '0';
INITIAL_CONFIG <= '1';
WIP := '1';
Addr := Address;
ELSE
E_ERR := '1';
WEL := '0';
END IF;
ELSIF (TopBoot = TRUE AND sect >= 254) OR
(BottomBoot = TRUE AND sect <= 31) THEN
IF Sec_ProtSE = 32 AND ASP_ProtSE = 32 THEN
--Sector erase command is applied to a 64 KB range
--that includes 4 KB sectors
IF TopBoot = TRUE THEN
SectorSuspend <= 254 + (285 - sect)/16;
ELSE
SectorSuspend <= sect/16;
END IF;
PARAM_REGION := TRUE;
ESTART <= '1', '0' AFTER 5 ns;
ESUSP <= '0';
ERES <= '0';
INITIAL_CONFIG <= '1';
WIP := '1';
Addr := Address;
ELSE
E_ERR := '1';
WEL := '0';
END IF;
END IF;
ELSIF (Instruct = P4E OR Instruct = P4E4) AND WEL = '1' THEN
ReturnSectorID(sect,Address);
IF UniformSec = TRUE OR
(TopBoot = TRUE AND sect < 254) OR
(BottomBoot = TRUE AND sect > 31) THEN
WEL := '0';
ELSE
IF (Sec_Prot(sect) = '0' AND
PPB_bits(sect)='1' AND DYB_bits(sect)='1') THEN
--A P4E instruction applied to a sector
--that has been Write Protected through the
--Block Protect Bits or ASP will not be
--executed and will set the E_ERR status
ESTART <= '1', '0' AFTER 5 ns;
ESUSP <= '0';
ERES <= '0';
INITIAL_CONFIG <= '1';
WIP := '1';
Addr := Address;
ELSE
E_ERR := '1';
WEL := '0';
END IF;
END IF;
ELSIF Instruct = BE AND WEL = '1' THEN
IF (BP0='0' AND BP1='0' AND BP2='0') THEN
ESTART <= '1', '0' AFTER 5 ns;
ESUSP <= '0';
ERES <= '0';
INITIAL_CONFIG <= '1';
WIP := '1';
ELSE
--The Bulk Erase command will not set E_ERR if a
--protected sector is found during the command
--execution.
WEL := '0';
END IF;
ELSIF Instruct = PASSP AND WEL = '1' THEN
IF not(PWDMLB='0' AND PSTMLB='1') THEN
PSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
ELSE
REPORT "Password programming is not allowed" &
" in Password Protection Mode."
SEVERITY warning;
END IF;
ELSIF Instruct = PASSU AND WEL = '1' THEN
PASSULCK_in <= '1';
ELSIF Instruct = BRWR THEN
Bank_Addr_reg(7) := Bank_Addr_reg_in(7);
ELSIF Instruct = ASPP AND WEL = '1' THEN
IF not(ASPOTPFLAG) THEN
PSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
ELSE
WEL := '0';
P_ERR := '1';
REPORT "Once the Protection Mode is selected," &
"no further changes to the ASP register" &
"is allowed."
SEVERITY warning;
END IF;
ELSIF Instruct = ABWR AND WEL = '1' THEN
PSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
ELSIF Instruct = PPBP AND WEL = '1' THEN
ReturnSectorID(sect,Address);
Addr := Address;
pgm_page := Address/(PageSize+1);
PSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
ELSIF Instruct = PPBERS AND WEL = '1' THEN
IF PPBOTP = '1' THEN
PPBERASE_in <= '1';
WIP := '1';
ELSE
E_ERR := '1';
END IF;
ELSIF Instruct = PLBWR AND WEL = '1' AND
RdPswdProtEnable = '0' THEN
PSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
ELSIF Instruct = DYBWR AND WEL = '1' THEN
ReturnSectorID(sect,Address);
Addr := Address;
pgm_page := Address/(PageSize+1);
PSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
ELSIF Instruct = PNVDLR AND WEL = '1' THEN
PSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
ELSIF Instruct = WVDLR AND WEL = '1' THEN
VDLR_reg := VDLR_reg_in;
WEL := '0';
ELSIF Instruct = CLSR THEN
--The Clear Status Register Command resets bit SR1[5]
--(Erase Fail Flag) and bit SR1[6] (Program Fail Flag)
E_ERR := '0';
P_ERR := '0';
END IF;
IF Instruct = BRAC AND P_ERR = '0' AND E_ERR = '0' THEN
BAR_ACC <= '1';
ELSE
BAR_ACC <= '0';
END IF;
ELSIF oe_z THEN
IF Instruct = READ OR Instruct = RD4 OR
Instruct = RES OR Instruct = DLPRD THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
ELSIF Instruct = DDRFR OR Instruct = DDRFR4 THEN
fast_rd <= false;
rd <= false;
dual <= false;
ddr <= true;
ELSIF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSIF Instruct = DOR OR Instruct=DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = QOR OR Instruct=QOR4 OR
Instruct = QIOR OR Instruct= QIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
ELSIF Instruct = DDRQIOR OR Instruct = DDRQIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
END IF;
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
ELSIF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = READ OR Instruct = RD4 OR
Instruct = FSTRD OR Instruct = FSTRD4 OR
Instruct = DDRFR OR Instruct = DDRFR4 THEN
--Read Memory array
IF Instruct = READ OR Instruct = RD4 THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
ELSIF Instruct = DDRFR OR Instruct = DDRFR4 THEN
fast_rd <= false;
rd <= false;
dual <= false;
ddr <= true;
ELSE
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
END IF;
IF ((bus_cycle_state = DUMMY_BYTES OR
DummyBytes_act='1') AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF (Instruct = DDRFR OR Instruct = DDRFR4) THEN
IF EHP THEN
IF Latency_code = 1 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3 OR
Latency_code = 0) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
dlp_act := FALSE;
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF Latency_code = 3 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 0 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
read_addr_tmp := read_addr;
SecAddr := read_addr/(SecSize+1);
Sec_addr := read_addr - SecAddr*(SecSize+1);
SecAddr := ReturnSectorIDRdPswdMd(TBPROT);
read_addr := Sec_addr + SecAddr*(SecSize+1);
IF RdPswdProtMode = '0' THEN
read_addr := read_addr_tmp;
END IF;
IF Mem(read_addr) /= -1 THEN
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-read_cnt);
ELSE
SOut_zd <= 'U';
END IF;
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF Instruct = DOR OR Instruct=DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
--Read Memory array
IF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
END IF;
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF (Instruct = DDRDIOR OR Instruct = DDRDIOR4) THEN
IF EHP THEN
IF Latency_code = 0 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF Latency_code = 3 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 0 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
read_addr_tmp := read_addr;
SecAddr := read_addr/(SecSize+1);
Sec_addr := read_addr - SecAddr*(SecSize+1);
SecAddr := ReturnSectorIDRdPswdMd(TBPROT);
read_addr := Sec_addr + SecAddr*(SecSize+1);
IF RdPswdProtMode = '0' THEN
read_addr := read_addr_tmp;
END IF;
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-2*read_cnt);
SIOut_zd <= data_out(6-2*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 4 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF (Instruct = QOR OR Instruct=QOR4 OR
Instruct = QIOR OR Instruct= QIOR4 OR
Instruct = DDRQIOR OR Instruct= DDRQIOR4)
AND QUAD = '1' THEN
--Read Memory array
IF Instruct = DDRQIOR OR Instruct = DDRQIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
END IF;
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF ((Instruct = DDRQIOR OR Instruct = DDRQIOR4) AND
QUAD = '1') THEN
IF EHP THEN
IF (Latency_code = 0 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
HOLDNegOut_zd <= data_out(7-read_cnt);
WPNegOut_zd <= data_out(7-read_cnt);
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF (Latency_code = 0 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
HOLDNegOut_zd <= data_out(7-read_cnt);
WPNegOut_zd <= data_out(7-read_cnt);
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
read_addr_tmp := read_addr;
SecAddr := read_addr/(SecSize+1);
Sec_addr := read_addr - SecAddr*(SecSize+1);
SecAddr := ReturnSectorIDRdPswdMd(TBPROT);
read_addr := Sec_addr + SecAddr*(SecSize+1);
IF RdPswdProtMode = '0' THEN
read_addr := read_addr_tmp;
END IF;
data_out := to_slv(Mem(read_addr),8);
HOLDNegOut_zd <= data_out(7-4*read_cnt);
WPNegOut_zd <= data_out(6-4*read_cnt);
SOut_zd <= data_out(5-4*read_cnt);
SIOut_zd <= data_out(4-4*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 2 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF Instruct = OTPR THEN
IF (read_addr>=OTPLoAddr) AND
(read_addr<=OTPHiAddr) AND RdPswdProtMode = '0' THEN
--Read OTP Memory array
fast_rd <= true;
rd <= false;
data_out := to_slv(OTPMem(read_addr),8);
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
read_addr := read_addr + 1;
END IF;
ELSIF (read_addr > OTPHiAddr)
OR RdPswdProtMode = '1' THEN
--OTP Read operation will not wrap to the
--starting address after the OTP address is at
--its maximum or Read Password Protection Mode
--is selected; instead, the data beyond the
--maximum OTP address will be undefined.
SOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF Instruct = REMS THEN
--Read Manufacturer and Device ID
IF read_addr MOD 2 = 0 THEN
data_out := to_slv(Manuf_ID,8);
SOut_zd <= data_out(7 - read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
read_addr := read_addr + 1;
END IF;
ELSE
data_out := to_slv(DeviceID,8);
SOut_zd <= data_out(7 - read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
read_addr := 0;
END IF;
END IF;
ELSIF Instruct = RDID THEN
IF UniformSec THEN
ExtendedID := ExtendedID256;
ELSE
ExtendedID := ExtendedID64;
END IF;
ident_out := CFI_array_tmp;
IF read_cnt < 648 THEN
SOut_zd <= ident_out(647-read_cnt);
read_cnt := read_cnt + 1;
ELSE
--Continued shifting of output beyond the end of
--the defined ID-CFI address space will provide
--undefined data.
SOut_zd <= 'U';
END IF;
ELSIF Instruct = RES THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
data_out := to_slv(ESignature,8);
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = DLPRD THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
SOut_zd <= VDLR_reg(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = ABRD THEN
--Read AutoBoot register
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
SOut_zd <= AutoBoot_reg(31-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 32 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = BRRD THEN
--Read Bank Address Register
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
SOut_zd <= Bank_Addr_reg(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = ASPRD THEN
--Read ASP Register
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
SOut_zd <= ASP_reg(15-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 16 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = PASSRD THEN
--Read Password Register
IF not (PWDMLB='0' AND PSTMLB='1') THEN
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
SOut_zd <= Password_reg((8*byte_cnt-1)-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
byte_cnt := byte_cnt + 1;
IF byte_cnt = 9 THEN
byte_cnt := 1;
END IF;
END IF;
ELSE
SOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 64 THEN
read_cnt := 0;
END IF;
IF read_cnt = 0 THEN
ASSERT false
REPORT "Verification of password is not " &
" allowed in Password Protection Mode."
SEVERITY warning;
END IF;
END IF;
ELSIF Instruct = PLBRD THEN
--Read PPB Lock Register
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
SOut_zd <= PPBL(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = DYBRD THEN
--Read DYB Access Register
ReturnSectorID(sect,Address);
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
DYBAR(7 downto 0) := "UUUUUUUU";
IF RdPswdProtMode = '0' THEN
IF DYB_bits(sect) = '1' THEN
DYBAR(7 downto 0) := "11111111";
ELSE
DYBAR(7 downto 0) := "00000000";
END IF;
END IF;
SOut_zd <= DYBAR(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = PPBRD THEN
--Read PPB Access Register
ReturnSectorID(sect,Address);
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
PPBAR(7 downto 0) := "UUUUUUUU";
IF RdPswdProtMode = '0' THEN
IF PPB_bits(sect) = '1' THEN
PPBAR(7 downto 0) := "11111111";
ELSE
PPBAR(7 downto 0) := "00000000";
END IF;
END IF;
SOut_zd <= PPBAR(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
WHEN AUTOBOOT =>
IF start_autoboot = '1' THEN
IF (oe) THEN
any_read <= true;
IF QUAD = '1' THEN
IF ABSD > 0 THEN --If ABSD > 0,
fast_rd <= false; --max SCK frequency is 104MHz
rd <= false;
dual <= true;
ddr <= false;
ELSE -- If ABSD = 0, max SCK frequency is 50 MHz
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
END IF;
data_out := to_slv(Mem(read_addr),8);
HOLDNegOut_zd <= data_out(7-4*read_cnt);
WPNegOut_zd <= data_out(6-4*read_cnt);
SOut_zd <= data_out(5-4*read_cnt);
SIOut_zd <= data_out(4-4*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 2 THEN
read_cnt := 0;
read_addr := read_addr + 1;
END IF;
ELSE
IF ABSD > 0 THEN --If ABSD > 0,
fast_rd <= true; --max SCK frequency is 133MHz
rd <= false;
dual <= false;
ddr <= false;
ELSE -- If ABSD = 0, max SCK frequency is 50 MHz
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
END IF;
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
read_addr := read_addr + 1;
END IF;
END IF;
ELSIF oe_z THEN
IF QUAD = '1' THEN
IF ABSD > 0 THEN --If ABSD > 0,
fast_rd <= false; --max SCK frequency is 104MHz
rd <= false;
dual <= true;
ddr <= false;
ELSE -- If ABSD = 0, max SCK frequency is 50 MHz
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
END IF;
ELSE
IF ABSD > 0 THEN --If ABSD > 0,
fast_rd <= true; --max SCK frequency is 133MHz
rd <= false;
dual <= false;
ddr <= false;
ELSE -- If ABSD = 0, max SCK frequency is 50 MHz
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
END IF;
END IF;
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
END IF;
WHEN WRITE_SR =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF WDONE = '1' THEN
WIP := '0';
WEL := '0';
SRWD := Status_reg1_in(7);--MSB first
IF LOCK='0' THEN
IF FREEZE='0' THEN
--The Freeze Bit, when set to 1, locks the current
--state of the BP2-0 bits in Status Register,
--the TBPROT and TBPARM bits in the Config Register
--As long as the FREEZE bit remains cleared to logic
--'0', the other bits of the Configuration register
--including FREEZE are writeable.
BP2 := Status_reg1_in(4);
BP1 := Status_reg1_in(3);
BP0 := Status_reg1_in(2);
BP_bits := BP2 & BP1 & BP0;
IF TBPROT = '0' AND INITIAL_CONFIG = '0' THEN
TBPROT := Config_reg1_in(5);
END IF;
IF (TBPARM = '0' AND INITIAL_CONFIG = '0' AND
TimingModel(16) = '0') THEN
TBPARM := Config_reg1_in(2);
change_TBPARM <= '1', '0' AFTER 1 ns;
END IF;
change_BP <= '1', '0' AFTER 1 ns;
LC1 := Config_reg1_in(7);
LC0 := Config_reg1_in(6);
QUAD := Config_reg1_in(1);
IF FREEZE = '0' THEN
FREEZE := Config_reg1_in(0);
END IF;
IF WRLOCKENABLE AND LOCK = '0' THEN
LOCK := Config_reg1_in(4);
WRLOCKENABLE <= false;
END IF;
IF BPNV = '0' THEN
BPNV := Config_reg1_in(3);
END IF;
END IF;
END IF;
END IF;
WHEN PAGE_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF falling_edge(PDONE) THEN
ADDRHILO_PG(AddrLo, AddrHi, Addr);
cnt := 0;
FOR i IN 0 TO wr_cnt LOOP
new_int := WData(i);
old_int := Mem(Addr + i - cnt);
IF new_int > -1 THEN
new_bit := to_slv(new_int,8);
IF old_int > -1 THEN
old_bit := to_slv(old_int,8);
FOR j IN 0 TO 7 LOOP
IF old_bit(j) = '0' THEN
new_bit(j) := '0';
END IF;
END LOOP;
new_int := to_nat(new_bit);
END IF;
WData(i) := new_int;
ELSE
WData(i) := -1;
END IF;
Mem(Addr + i - cnt) := -1;
IF (Addr + i) = AddrHi THEN
Addr := AddrLo;
cnt := i + 1;
END IF;
END LOOP;
cnt :=0;
END IF;
IF PDONE = '1' THEN
WIP := '0';
WEL := '0';
FOR i IN 0 TO wr_cnt LOOP
Mem(Addr_tmp + i - cnt) := WData(i);
IF (Addr_tmp + i) = AddrHi THEN
Addr_tmp := AddrLo;
cnt := i + 1;
END IF;
END LOOP;
ELSIF Instruct = PGSP AND PRGSUSP_in = '0' THEN
IF RES_TO_SUSP_MIN_TIME = '0' THEN
PGSUSP <= '1', '0' AFTER 1 ns;
PRGSUSP_in <= '1';
ASSERT RES_TO_SUSP_TYP_TIME = '0'
REPORT "Typical periods are needed for " &
"Program to progress to completion"
SEVERITY warning;
ELSE
ASSERT FALSE
REPORT "Minimum for tPRS is not satisfied! " &
"PGSP command is ignored"
SEVERITY warning;
END IF;
END IF;
WHEN PG_SUSP =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF PRGSUSP_out = '1' AND PRGSUSP_in = '1' THEN
PRGSUSP_in <= '0';
--The RDY/BSY bit in the Status Register will indicate that
--the device is ready for another operation.
WIP := '0';
--The Program Suspend (PS) bit in the Status Register will
--be set to the logical “1” state to indicate that the
--program operation has been suspended.
PS := '1';
END IF;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = BRRD THEN
--Read Bank Address Register
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
SOut_zd <= Bank_Addr_reg(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
--Read Array Operations
ELSIF Instruct = READ OR Instruct = RD4 OR
Instruct = FSTRD OR Instruct = FSTRD4 OR
Instruct = DDRFR OR Instruct = DDRFR4 THEN
--Read Memory array
IF Instruct = READ OR Instruct = RD4 THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
ELSIF Instruct = DDRFR OR Instruct = DDRFR4 THEN
fast_rd <= false;
rd <= false;
dual <= false;
ddr <= true;
ELSE
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
END IF;
IF pgm_page /= read_addr/(PageSize+1) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF (Instruct=DDRFR OR Instruct=DDRFR4) THEN
IF EHP THEN
IF Latency_code = 1 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3 OR
Latency_code = 0) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is
-- enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out:= VDLR_reg;
SOut_zd <=data_out(7-read_cnt);
read_cnt:=read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF Latency_code = 3 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 0 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
END IF;
-- Data Learning Pattern (DLP) is
-- enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
SOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF Instruct =DOR OR Instruct=DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
--Read Memory array
IF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
END IF;
IF pgm_page /= read_addr/(PageSize+1) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF (Instruct=DDRDIOR OR Instruct=DDRDIOR4) THEN
IF EHP THEN
IF Latency_code = 0 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency"&
" is set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP)
-- is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out:=VDLR_reg;
SOut_zd <=data_out(7-read_cnt);
SIOut_zd<=data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF Latency_code = 3 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 0 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
END IF;
-- Data Learning Pattern (DLP)
-- is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-2*read_cnt);
SIOut_zd <= data_out(6-2*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 4 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
SOut_zd <= 'U';
SIOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 4 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF (Instruct = QOR OR Instruct=QOR4 OR
Instruct = QIOR OR Instruct= QIOR4 OR
Instruct = DDRQIOR OR Instruct= DDRQIOR4)
AND QUAD = '1' THEN
--Read Memory array
IF Instruct = DDRQIOR OR Instruct = DDRQIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
END IF;
IF pgm_page /= read_addr/(PageSize+1) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF EHP THEN
IF (Latency_code=0
AND dummy_cnt_act>=2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
HOLDNegOut_zd <= data_out(7-read_cnt);
WPNegOut_zd <= data_out(7-read_cnt);
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF (Latency_code=0
AND dummy_cnt_act>=2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
HOLDNegOut_zd <= data_out(7-read_cnt);
WPNegOut_zd <= data_out(7-read_cnt);
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
HOLDNegOut_zd <= data_out(7-4*read_cnt);
WPNegOut_zd <= data_out(6-4*read_cnt);
SOut_zd <= data_out(5-4*read_cnt);
SIOut_zd <= data_out(4-4*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 2 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
HOLDNegOut_zd <= 'U';
WPNegOut_zd <= 'U';
SOut_zd <= 'U';
SIOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 2 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
END IF;
ELSIF oe_z THEN
IF Instruct = READ OR Instruct = RD4 THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
ELSIF Instruct = DDRFR OR Instruct = DDRFR4 THEN
fast_rd <= false;
rd <= false;
dual <= false;
ddr <= true;
ELSIF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSIF Instruct =DOR OR Instruct=DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = QOR OR Instruct=QOR4 OR
Instruct = QIOR OR Instruct= QIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
ELSIF Instruct = DDRQIOR OR Instruct = DDRQIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
END IF;
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
ELSIF Instruct = BRWR THEN
Bank_Addr_reg(7) := Bank_Addr_reg_in(7);
ELSIF Instruct = WRR AND BAR_ACC = '1' THEN
-- Write to the lower address bits of the BAR
IF (P_ERR = '0' AND E_ERR = '0')THEN
REPORT "WARNING: Changing values of " &
"Bank Address Register RFU bits" &
" are not allowed!!!"
SEVERITY WARNING;
END IF;
ELSIF Instruct = PGRS THEN
PGRES <= '1', '0' AFTER 5 ns;
PS := '0';
WIP := '1';
RES_TO_SUSP_MIN_TIME <= '1', '0' AFTER 60 ns;
RES_TO_SUSP_TYP_TIME <= '1', '0' AFTER 100 us;
END IF;
IF Instruct = BRAC AND P_ERR = '0' AND E_ERR = '0' AND
RdPswdProtMode = '0' THEN
BAR_ACC <= '1';
ELSE
BAR_ACC <= '0';
END IF;
WHEN ERS_SUSP_PG_SUSP =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF PRGSUSP_out = '1' AND PRGSUSP_in = '1' THEN
PRGSUSP_in <= '0';
--The RDY/BSY bit in the Status Register will indicate that
--the device is ready for another operation.
WIP := '0';
--The Program Suspend (PS) bit in the Status Register will
--be set to the logical “1” state to indicate that the
--program operation has been suspended.
PS := '1';
END IF;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = BRRD THEN
--Read Bank Address Register
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
SOut_zd <= Bank_Addr_reg(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
--Read Array Operations
ELSIF Instruct = READ OR Instruct = RD4 OR
Instruct = FSTRD OR Instruct = FSTRD4 OR
Instruct = DDRFR OR Instruct = DDRFR4 THEN
--Read Memory array
IF Instruct = READ OR Instruct = RD4 THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
ELSIF Instruct = DDRFR OR Instruct = DDRFR4 THEN
fast_rd <= false;
rd <= false;
dual <= false;
ddr <= true;
ELSE
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
END IF;
IF (SectorSuspend /= read_addr/(SecSize+1)+30*b_act AND
pgm_page /= read_addr/(PageSize+1)) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF (Instruct=DDRFR OR Instruct=DDRFR4) THEN
IF EHP THEN
IF Latency_code = 1 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3 OR
Latency_code = 0) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is
-- enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out:= VDLR_reg;
SOut_zd <=data_out(7-read_cnt);
read_cnt:=read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF Latency_code = 3 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 0 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
END IF;
-- Data Learning Pattern (DLP) is
-- enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
SOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF Instruct =DOR OR Instruct=DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
--Read Memory array
IF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
END IF;
IF (SectorSuspend /= read_addr/(SecSize+1)+30*b_act AND
pgm_page /= read_addr/(PageSize+1)) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF (Instruct=DDRDIOR OR Instruct=DDRDIOR4) THEN
IF EHP THEN
IF Latency_code = 0 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency"&
" is set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP)
-- is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out:=VDLR_reg;
SOut_zd <=data_out(7-read_cnt);
SIOut_zd<=data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF Latency_code = 3 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 0 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
END IF;
-- Data Learning Pattern (DLP)
-- is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-2*read_cnt);
SIOut_zd <= data_out(6-2*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 4 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
SOut_zd <= 'U';
SIOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 4 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF (Instruct = QOR OR Instruct=QOR4 OR
Instruct = QIOR OR Instruct= QIOR4 OR
Instruct = DDRQIOR OR Instruct= DDRQIOR4)
AND QUAD = '1' THEN
--Read Memory array
IF Instruct = DDRQIOR OR Instruct = DDRQIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
END IF;
IF (SectorSuspend /= read_addr/(SecSize+1)+30*b_act AND
pgm_page /= read_addr/(PageSize+1)) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF EHP THEN
IF (Latency_code=0
AND dummy_cnt_act>=2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
HOLDNegOut_zd <= data_out(7-read_cnt);
WPNegOut_zd <= data_out(7-read_cnt);
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF (Latency_code=0
AND dummy_cnt_act>=2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
HOLDNegOut_zd <= data_out(7-read_cnt);
WPNegOut_zd <= data_out(7-read_cnt);
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
HOLDNegOut_zd <= data_out(7-4*read_cnt);
WPNegOut_zd <= data_out(6-4*read_cnt);
SOut_zd <= data_out(5-4*read_cnt);
SIOut_zd <= data_out(4-4*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 2 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
HOLDNegOut_zd <= 'U';
WPNegOut_zd <= 'U';
SOut_zd <= 'U';
SIOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 2 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
END IF;
ELSIF oe_z THEN
IF Instruct = READ OR Instruct = RD4 THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
ELSIF Instruct = DDRFR OR Instruct = DDRFR4 THEN
fast_rd <= false;
rd <= false;
dual <= false;
ddr <= true;
ELSIF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSIF Instruct =DOR OR Instruct=DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = QOR OR Instruct=QOR4 OR
Instruct = QIOR OR Instruct= QIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
ELSIF Instruct = DDRQIOR OR Instruct = DDRQIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
END IF;
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
ELSIF Instruct = BRWR THEN
Bank_Addr_reg(7) := Bank_Addr_reg_in(7);
ELSIF Instruct = WRR AND BAR_ACC = '1' THEN
-- Write to the lower address bits of the BAR
IF (P_ERR = '0' AND E_ERR = '0')THEN
REPORT "WARNING: Changing values of " &
"Bank Address Register RFU bits" &
" are not allowed!!!"
SEVERITY WARNING;
END IF;
ELSIF Instruct = PGRS THEN
PGRES <= '1', '0' AFTER 5 ns;
PS := '0';
WIP := '1';
RES_TO_SUSP_MIN_TIME <= '1', '0' AFTER 60 ns;
RES_TO_SUSP_TYP_TIME <= '1', '0' AFTER 100 us;
END IF;
IF Instruct = BRAC AND P_ERR = '0' AND E_ERR = '0' AND
RdPswdProtMode = '0' THEN
BAR_ACC <= '1';
ELSE
BAR_ACC <= '0';
END IF;
WHEN OTP_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF Address + wr_cnt <= OTPHiAddr THEN
FOR i IN 0 TO wr_cnt LOOP
new_int := WData(i);
old_int := OTPMem(Addr + i);
IF new_int > -1 THEN
new_bit := to_slv(new_int,8);
IF old_int > -1 THEN
old_bit := to_slv(old_int,8);
FOR j IN 0 TO 7 LOOP
IF old_bit(j) = '0' THEN
new_bit(j) := '0';
END IF;
END LOOP;
new_int := to_nat(new_bit);
END IF;
WData(i) := new_int;
ELSE
WData(i) := -1;
END IF;
OTPMem(Addr + i) := -1;
END LOOP;
ELSE
ASSERT false
REPORT "Programming will reach over address limit"&
" of OTP array"
SEVERITY warning;
END IF;
IF PDONE = '1' THEN
WIP := '0';
WEL := '0';
FOR i IN 0 TO wr_cnt LOOP
OTPMem(Addr_tmp + i) := WData(i);
END LOOP;
LOCK_BYTE1 := to_slv(OTPMem(16#10#),8);
LOCK_BYTE2 := to_slv(OTPMem(16#11#),8);
LOCK_BYTE3 := to_slv(OTPMem(16#12#),8);
LOCK_BYTE4 := to_slv(OTPMem(16#13#),8);
END IF;
WHEN SECTOR_ERS =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
ADDRHILO_SEC(AddrLo, AddrHi, Addr);
FOR i IN AddrLo TO AddrHi LOOP
Mem(i) := -1;
END LOOP;
IF EDONE = '1' THEN
WIP := '0';
WEL := '0';
FOR i IN AddrLo TO AddrHi LOOP
Mem(i) := MaxData;
END LOOP;
ELSIF Instruct = ERSP AND ERSSUSP_in = '0' THEN
ESUSP <= '1', '0' AFTER 10 ns;
ERSSUSP_in <= '1';
ASSERT RES_TO_SUSP_TYP_TIME = '0'
REPORT "Typical periods are needed for " &
"Program to progress to completion"
SEVERITY warning;
END IF;
WHEN BULK_ERS =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF falling_edge(EDONE) THEN
FOR i IN 0 TO AddrRANGE LOOP
-- Sector ID calculation
IF TimingModel(16) = '0' THEN
sec_tmp := i / (SecSize64+1);
IF BottomBoot THEN
IF sec_tmp <= 1 THEN --4KB Sectors
sect := i/(SecSize4+1);
ELSE
sect := sec_tmp + 30;
END IF;
ELSIF TopBoot THEN
IF sec_tmp >= 254 THEN --4KB Sectors
sect :=
254+(i-(SecSize64+1)*254)/(SecSize4+1);
ELSE
sect := sec_tmp;
END IF;
END IF;
ELSE
sect := i/(SecSize256+1);
END IF;
IF PPB_bits(sect) = '1' AND DYB_bits(sect) = '1' THEN
Mem(i) := -1;
END IF;
END LOOP;
END IF;
IF EDONE = '1' THEN
WIP := '0';
WEL := '0';
FOR i IN 0 TO AddrRANGE LOOP
-- Sector ID calculation
IF TimingModel(16) = '0' THEN
sec_tmp := i / (SecSize64+1);
IF BottomBoot THEN
IF sec_tmp <= 1 THEN --4KB Sectors
sect := i/(SecSize4+1);
ELSE
sect := sec_tmp + 30;
END IF;
ELSIF TopBoot THEN
IF sec_tmp >= 254 THEN --4KB Sectors
sect :=
254+(i-(SecSize64+1)*254)/(SecSize4+1);
ELSE
sect := sec_tmp;
END IF;
END IF;
ELSE
sect := i/(SecSize256+1);
END IF;
IF PPB_bits(sect) = '1' AND DYB_bits(sect) = '1' THEN
Mem(i) := MaxData;
END IF;
END LOOP;
END IF;
WHEN ERS_SUSP =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF ERSSUSP_out = '1' THEN
ERSSUSP_in <= '0';
--The Erase Suspend (ES) bit in the Status Register will
--be set to the logical “1” state to indicate that the
--erase operation has been suspended.
ES := '1';
--The WIP bit in the Status Register will indicate that
--the device is ready for another operation.
WIP := '0';
END IF;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = DYBRD THEN
--Read DYB Access Register
ReturnSectorID(sect,Address);
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF DYB_bits(sect) = '1' THEN
DYBAR(7 downto 0) := "11111111";
ELSE
DYBAR(7 downto 0) := "00000000";
END IF;
SOut_zd <= DYBAR(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = BRRD THEN
--Read Bank Address Register
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
SOut_zd <= Bank_Addr_reg(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = PPBRD THEN
--Read PPB Access Register
ReturnSectorID(sect,Address);
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
PPBAR(7 downto 0) := "UUUUUUUU";
IF RdPswdProtMode = '0' THEN
IF PPB_bits(sect) = '1' THEN
PPBAR(7 downto 0) := "11111111";
ELSE
PPBAR(7 downto 0) := "00000000";
END IF;
END IF;
SOut_zd <= PPBAR(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
--Read Array Operations
ELSIF Instruct = READ OR Instruct = RD4 OR
Instruct = FSTRD OR Instruct = FSTRD4 OR
Instruct = DDRFR OR Instruct = DDRFR4 THEN
--Read Memory array
IF Instruct = READ OR Instruct = RD4 THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
ELSIF Instruct = DDRFR OR Instruct = DDRFR4 THEN
fast_rd <= false;
rd <= false;
dual <= false;
ddr <= true;
ELSE
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
END IF;
IF (PARAM_REGION = TRUE AND
SectorSuspend /= read_addr/(SecSize+1)) OR
(PARAM_REGION = FALSE AND
SectorSuspend /= read_addr/(SecSize+1)+30*b_act) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF (Instruct=DDRFR OR Instruct=DDRFR4) THEN
IF EHP THEN
IF Latency_code = 1 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3 OR
Latency_code = 0) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is
-- enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out:= VDLR_reg;
SOut_zd <=data_out(7-read_cnt);
read_cnt:=read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF Latency_code = 3 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 0 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
END IF;
-- Data Learning Pattern (DLP) is
-- enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
SOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF Instruct =DOR OR Instruct=DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
--Read Memory array
IF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
END IF;
IF (PARAM_REGION = TRUE AND
SectorSuspend /= read_addr/(SecSize+1)) OR
(PARAM_REGION = FALSE AND
SectorSuspend /= read_addr/(SecSize+1)+30*b_act) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF (Instruct=DDRDIOR OR Instruct=DDRDIOR4) THEN
IF EHP THEN
IF Latency_code = 0 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 1) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency"&
" is set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP)
-- is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out:=VDLR_reg;
SOut_zd <=data_out(7-read_cnt);
SIOut_zd<=data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF Latency_code = 3 THEN
dlp_act := TRUE;
ELSIF (Latency_code = 0 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
END IF;
-- Data Learning Pattern (DLP)
-- is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND
dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
SOut_zd <= data_out(7-2*read_cnt);
SIOut_zd <= data_out(6-2*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 4 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
SOut_zd <= 'U';
SIOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 4 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSIF (Instruct = QOR OR Instruct=QOR4 OR
Instruct = QIOR OR Instruct= QIOR4 OR
Instruct = DDRQIOR OR Instruct= DDRQIOR4)
AND QUAD = '1' THEN
--Read Memory array
IF Instruct = DDRQIOR OR Instruct = DDRQIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
END IF;
IF (PARAM_REGION = TRUE AND
SectorSuspend /= read_addr/(SecSize+1)) OR
(PARAM_REGION = FALSE AND
SectorSuspend /= read_addr/(SecSize+1)+30*b_act) THEN
IF ((bus_cycle_state = DUMMY_BYTES
OR DummyBytes_act = '1')
AND VDLR_reg /= "00000000") THEN
DummyBytes_act := '0';
IF EHP THEN
IF (Latency_code=0
AND dummy_cnt_act>=2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
HOLDNegOut_zd <= data_out(7-read_cnt);
WPNegOut_zd <= data_out(7-read_cnt);
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSE
IF (Latency_code = 0 AND
dummy_cnt_act >= 2) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 1 AND
dummy_cnt_act >= 3) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 2 AND
dummy_cnt_act >= 4) THEN
dlp_act := TRUE;
ELSIF (Latency_code = 3) THEN
dlp_act := FALSE;
REPORT "Inappropriate latency is"&
" set during DPL mode"
SEVERITY WARNING;
END IF;
-- Data Learning Pattern (DLP) is enabled
-- Optional DLP
IF (VDLR_reg/="00000000" AND dlp_act) THEN
dlp_act := FALSE;
data_out := VDLR_reg;
HOLDNegOut_zd <= data_out(7-read_cnt);
WPNegOut_zd <= data_out(7-read_cnt);
SOut_zd <= data_out(7-read_cnt);
SIOut_zd <= data_out(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
END IF;
ELSE
data_out := to_slv(Mem(read_addr),8);
HOLDNegOut_zd <= data_out(7-4*read_cnt);
WPNegOut_zd <= data_out(6-4*read_cnt);
SOut_zd <= data_out(5-4*read_cnt);
SIOut_zd <= data_out(4-4*read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 2 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
ELSE
HOLDNegOut_zd <= 'U';
WPNegOut_zd <= 'U';
SOut_zd <= 'U';
SIOut_zd <= 'U';
read_cnt := read_cnt + 1;
IF read_cnt = 2 THEN
read_cnt := 0;
IF read_addr = AddrRANGE THEN
read_addr := 0;
ELSE
read_addr := read_addr + 1;
END IF;
END IF;
END IF;
END IF;
ELSIF oe_z THEN
IF Instruct = READ OR Instruct = RD4 THEN
fast_rd <= false;
rd <= true;
dual <= false;
ddr <= false;
ELSIF Instruct = DDRFR OR Instruct = DDRFR4 THEN
fast_rd <= false;
rd <= false;
dual <= false;
ddr <= true;
ELSIF Instruct = DDRDIOR OR Instruct = DDRDIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSIF Instruct =DOR OR Instruct=DOR4 OR
Instruct = DIOR OR Instruct = DIOR4 OR
Instruct = QOR OR Instruct=QOR4 OR
Instruct = QIOR OR Instruct= QIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= false;
ELSIF Instruct = DDRQIOR OR Instruct = DDRQIOR4 THEN
fast_rd <= false;
rd <= false;
dual <= true;
ddr <= true;
ELSE
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
END IF;
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF falling_edge(write) THEN
IF (Instruct = PP OR Instruct = PP4) AND WEL = '1' THEN
IF (PARAM_REGION = TRUE AND
SectorSuspend /= Address/(SecSize+1)) OR
(PARAM_REGION = FALSE AND
SectorSuspend/=Address/(SecSize+1)+30*b_act) THEN
ReturnSectorID(sect,Address);
Addr := Address;
pgm_page := Address/(PageSize+1);
IF (Sec_Prot(sect) = '0' AND
PPB_bits(sect)='1' AND DYB_bits(sect)='1') THEN
PSTART <= '1', '0' AFTER 5 ns;
PGSUSP <= '0';
PGRES <= '0';
WIP := '1' ;
SA <= sect;
Addr := Address;
Addr_tmp := Address;
wr_cnt := Byte_number;
FOR I IN wr_cnt DOWNTO 0 LOOP
IF Viol /= '0' THEN
WData(i) := -1;
ELSE
WData(i) := WByte(i);
END IF;
END LOOP;
ELSE
WEL := '0';
P_ERR := '1';
END IF;
ELSE
WEL := '0';
P_ERR := '1';
END IF;
ELSIF (Instruct = QPP OR Instruct = QPP4) AND WEL = '1' THEN
IF (PARAM_REGION = TRUE AND
SectorSuspend /= Address/(SecSize+1)) OR
(PARAM_REGION = FALSE AND
SectorSuspend/=Address/(SecSize+1)+30*b_act) THEN
ReturnSectorID(sect,Address);
Addr := Address;
pgm_page := Address/(PageSize+1);
IF (Sec_Prot(sect)='0' AND
PPB_bits(sect)='1' AND DYB_bits(sect)='1') THEN
PSTART <= '1', '0' AFTER 5 ns;
PGSUSP <= '0';
PGRES <= '0';
WIP := '1' ;
SA <= sect;
Addr := Address;
Addr_tmp := Address;
wr_cnt := Byte_number;
FOR I IN wr_cnt DOWNTO 0 LOOP
IF Viol /= '0' THEN
WData(i) := -1;
ELSE
WData(i) := WByte(i);
END IF;
END LOOP;
ELSE
WEL := '0';
P_ERR := '1';
END IF;
ELSE
WEL := '0';
P_ERR := '1';
END IF;
ELSIF Instruct = WREN THEN
WEL := '1';
ELSIF Instruct = CLSR THEN
--The Clear Status Register Command resets bit SR1[5]
--(Erase Fail Flag) and bit SR1[6] (Program Fail Flag)
E_ERR := '0';
P_ERR := '0';
ELSIF Instruct = BRWR THEN
Bank_Addr_reg(7) := Bank_Addr_reg_in(7);
ELSIF Instruct = WRR AND BAR_ACC = '1' THEN
-- Write to the lower address bits of the BAR
IF (P_ERR = '0' AND E_ERR = '0')THEN
REPORT "WARNING: Changing values of " &
"Bank Address Register RFU bits" &
" are not allowed!!!"
SEVERITY WARNING;
END IF;
ELSIF Instruct = DYBWR AND WEL = '1' THEN
ReturnSectorID(sect,Address);
PSTART <= '1', '0' AFTER 5 ns;
WIP := '1';
ELSIF Instruct = ERRS THEN
ERES <= '1', '0' AFTER 5 ns;
ES := '0';
WIP := '1';
IF BottomBoot = TRUE THEN
IF PARAM_REGION = TRUE THEN
Addr := SectorSuspend*(SecSize+1);
ELSE
Addr := (SectorSuspend-30)*(SecSize+1);
END IF;
ELSE
Addr := SectorSuspend*(SecSize+1);
END IF;
ADDRHILO_SEC(AddrLo, AddrHi, Addr);
RES_TO_SUSP_TYP_TIME <= '1', '0' AFTER 100 us;
END IF;
IF Instruct = BRAC AND P_ERR = '0' AND E_ERR = '0' AND
RdPswdProtMode = '0' THEN
BAR_ACC <= '1';
ELSE
BAR_ACC <= '0';
END IF;
END IF;
WHEN ERS_SUSP_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
ADDRHILO_PG(AddrLo, AddrHi, Addr);
cnt := 0;
FOR i IN 0 TO wr_cnt LOOP
new_int := WData(i);
old_int := Mem(Addr + i - cnt);
IF new_int > -1 THEN
new_bit := to_slv(new_int,8);
IF old_int > -1 THEN
old_bit := to_slv(old_int,8);
FOR j IN 0 TO 7 LOOP
IF old_bit(j) = '0' THEN
new_bit(j) := '0';
END IF;
END LOOP;
new_int := to_nat(new_bit);
END IF;
WData(i) := new_int;
ELSE
WData(i) := -1;
END IF;
IF (Addr + i) = AddrHi THEN
Addr := AddrLo;
cnt := i + 1;
END IF;
END LOOP;
cnt :=0;
IF PDONE = '1' THEN
WIP := '0';
WEL := '0';
FOR i IN 0 TO wr_cnt LOOP
Mem(Addr_tmp + i - cnt) := WData(i);
IF (Addr_tmp + i) = AddrHi THEN
Addr_tmp := AddrLo;
cnt := i + 1;
END IF;
END LOOP;
ELSIF Instruct = PGSP AND PRGSUSP_in = '0' THEN
PGSUSP <= '1', '0' AFTER 1 ns;
PRGSUSP_in <= '1';
END IF;
WHEN PASS_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
new_pass := Password_reg_in;
old_pass := Password_reg;
FOR j IN 0 TO 63 LOOP
IF old_pass(j) = '0' THEN
new_pass(j) := '0';
END IF;
END LOOP;
IF PDONE = '1' THEN
Password_reg := new_pass;
WIP := '0';
WEL := '0';
END IF;
WHEN PASS_UNLOCK =>
WIP := '1';
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF PASS_TEMP = Password_reg THEN
PASS_UNLOCKED <= TRUE;
ELSE
PASS_UNLOCKED <= FALSE;
END IF;
IF PASSULCK_out = '1' THEN
IF PASS_UNLOCKED AND PWDMLB = '0' THEN
PPB_LOCK := '1';
PPB_LOCK_temp <= '1';
WIP := '0';
ELSE
P_ERR := '1';
REPORT "Incorrect Password!"
SEVERITY warning;
PASSACC_in <= '1';
END IF;
WEL := '0';
PASSULCK_in <= '0';
END IF;
WHEN PPB_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF PDONE = '1' THEN
IF PPB_LOCK /= '0' THEN
PPB_bits(sect):= '0';
WIP := '0';
WEL := '0';
ELSE
P_ERR := '0';
WIP := '0';
WEL := '0';
END IF;
END IF;
WHEN PPB_ERS =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF PPBERASE_out = '1' THEN
IF PPB_LOCK /= '0' AND PPBOTP = '1' THEN
PPB_bits:= (OTHERS => '1');
ELSE
E_ERR := '1';
END IF;
WIP := '0';
WEL := '0';
PPBERASE_in <= '0';
END IF;
WHEN AUTOBOOT_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF PDONE = '1' THEN
AutoBoot_reg := AutoBoot_reg_in;
WIP := '0';
WEL := '0';
END IF;
WHEN PLB_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF PDONE = '1' THEN
PPB_LOCK := '0';
PPB_LOCK_temp <= '0';
WIP := '0';
WEL := '0';
END IF;
WHEN DYB_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF PDONE = '1' THEN
DYBAR := DYBAR_in;
IF DYBAR = "11111111" THEN
DYB_bits(sect):= '1';
ELSIF DYBAR = "00000000" THEN
DYB_bits(sect):= '0';
ELSE
P_ERR := '1';
END IF;
WIP := '0';
WEL := '0';
END IF;
WHEN ASP_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF PDONE = '1' THEN
IF (RPME = '0' AND ASP_reg_in(5) = '1') THEN
P_ERR := '1';
REPORT "RPME bit is allready programmed"
SEVERITY warning;
ELSE
RPME := ASP_reg_in(5);
END IF;
IF (PPBOTP = '0' AND ASP_reg_in(3) ='1') THEN
P_ERR := '1';
REPORT "PPBOTP bit is allready programmed"
SEVERITY warning;
ELSE
PPBOTP := ASP_reg_in(3);
END IF;
IF (PWDMLB = '1' AND PSTMLB = '1') THEN
IF (ASP_reg_in(2) = '0' AND ASP_reg_in(1) = '0') THEN
REPORT "ASPR[2:1] = 00 Illegal condition"
SEVERITY warning;
P_ERR := '1';
ELSE
IF (ASP_reg_in(2) /= '1' OR
ASP_reg_in(1) /= '1') THEN
ASPOTPFLAG <= TRUE;
END IF;
PWDMLB := ASP_reg_in(2);
PSTMLB := ASP_reg_in(1);
END IF;
END IF;
WIP := '0';
WEL := '0';
END IF;
WHEN NVDLR_PG =>
fast_rd <= true;
rd <= false;
dual <= false;
ddr <= false;
IF oe THEN
any_read <= true;
IF Instruct = RDSR THEN
--Read Status Register 1
SOut_zd <= Status_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDSR2 THEN
--Read Status Register 2
SOut_zd <= Status_reg2(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
ELSIF Instruct = RDCR THEN
--Read Configuration Register 1
SOut_zd <= Config_reg1(7-read_cnt);
read_cnt := read_cnt + 1;
IF read_cnt = 8 THEN
read_cnt := 0;
END IF;
END IF;
ELSIF oe_z THEN
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
SIOut_zd <= 'Z';
END IF;
IF PDONE = '1' THEN
IF NVDLR_reg = "00000000" THEN
NVDLR_reg :=NVDLR_reg_in;
VDLR_reg := NVDLR_reg_in;
WIP := '0';
WEL := '0';
ELSE
WIP := '0';
WEL := '0';
P_ERR := '1';
REPORT "NVDLR is allready programmed"
SEVERITY warning;
END IF;
END IF;
WHEN RESET_STATE =>
--the default condition hardware reset
--The Bank Address Register is loaded to all zeroes
Bank_Addr_reg := (others => '0');
IF BPNV = '1' AND LOCK='0' AND FREEZE = '0' THEN
BP0 := '1';
BP1 := '1';
BP2 := '1';
BP_bits := BP2 & BP1 & BP0;
change_BP <= '1', '0' AFTER 1 ns;
END IF;
--Resets the Status register 1
P_ERR := '0';
E_ERR := '0';
WEL := '0';
WIP := '0';
--Resets the Status register 2
ES := '0';
PS := '0';
--Resets the Configuration register 1
FREEZE := '0';
--On reset cycles the data pattern reverts back
--to what is in the NVDLR
VDLR_reg := NVDLR_reg;
dlp_act := FALSE;
--Loads the Program Buffer with all ones
WData := (OTHERS => MaxData);
IF PWDMLB = '0' THEN
PPB_LOCK := '0';
PPB_LOCK_temp <= '0';
ELSE
PPB_LOCK := '1';
PPB_LOCK_temp <= '1';
END IF;
END CASE;
--Output Disable Control
IF (CSNeg_ipd = '1') THEN
SIOut_zd <= 'Z';
HOLDNegOut_zd <= 'Z';
WPNegOut_zd <= 'Z';
SOut_zd <= 'Z';
END IF;
END PROCESS Functional;
---------------------------------------------------------------------------
-- CFI Process
---------------------------------------------------------------------------
CFIPreload: PROCESS
BEGIN
------------------------------------------------------------------------
--CFI array data
------------------------------------------------------------------------
-- Manufacturer and Device ID
CFI_array(16#00#) := 16#01#;
CFI_array(16#01#) := 16#20#;
CFI_array(16#02#) := 16#18#;
CFI_array(16#03#) := 16#00#;
IF TimingModel(16) = '0' THEN
CFI_array(16#04#) := 16#01#;--256B page
ELSIF TimingModel(16) = '1' THEN
CFI_array(16#04#) := 16#00#;--512B page
END IF;
CFI_array(16#05#) := 16#80#;
CFI_array(16#06#) := 16#00#;
CFI_array(16#07#) := 16#00#;
CFI_array(16#08#) := 16#00#;
CFI_array(16#09#) := 16#00#;
CFI_array(16#0A#) := 16#00#;
CFI_array(16#0B#) := 16#00#;
CFI_array(16#0C#) := 16#00#;
CFI_array(16#0D#) := 16#00#;
CFI_array(16#0E#) := 16#00#;
CFI_array(16#0F#) := 16#00#;
--CFI Query Identification String
CFI_array(16#10#) := 16#51#;
CFI_array(16#11#) := 16#52#;
CFI_array(16#12#) := 16#59#;
CFI_array(16#13#) := 16#02#;
CFI_array(16#14#) := 16#00#;
CFI_array(16#15#) := 16#40#;
CFI_array(16#16#) := 16#00#;
CFI_array(16#17#) := 16#53#;
CFI_array(16#18#) := 16#46#;
CFI_array(16#19#) := 16#51#;
CFI_array(16#1A#) := 16#00#;
--CFI system interface string
CFI_array(16#1B#) := 16#27#;
CFI_array(16#1C#) := 16#36#;
CFI_array(16#1D#) := 16#00#;
CFI_array(16#1E#) := 16#00#;
CFI_array(16#1F#) := 16#06#;
IF TimingModel(16) = '0' THEN
CFI_array(16#20#) := 16#08#;--256B page
CFI_array(16#21#) := 16#08#;--64KB
ELSIF TimingModel(16) = '1' THEN
CFI_array(16#20#) := 16#09#;--512B page
CFI_array(16#21#) := 16#09#;--256KB
END IF;
CFI_array(16#22#) := 16#0F#;
CFI_array(16#23#) := 16#02#;
CFI_array(16#24#) := 16#02#;
CFI_array(16#25#) := 16#03#;
CFI_array(16#26#) := 16#03#;
--Device Geometry Definition
CFI_array(16#27#) := 16#18#;
CFI_array(16#28#) := 16#02#;
CFI_array(16#29#) := 16#01#;
IF TimingModel(16) = '0' THEN
CFI_array(16#2A#) := 16#08#;--256B page
ELSIF TimingModel(16) = '1' THEN
CFI_array(16#2A#) := 16#09#;--512B page
END IF;
CFI_array(16#2B#) := 16#00#;
IF TimingModel(16) = '1' THEN
CFI_array(16#2C#) := 16#01#; --Uniform Device
CFI_array(16#2D#) := 16#3F#;
CFI_array(16#2E#) := 16#00#;
CFI_array(16#2F#) := 16#00#;
CFI_array(16#30#) := 16#04#;
CFI_array(16#31#) := 16#FF#;
CFI_array(16#32#) := 16#FF#;
CFI_array(16#33#) := 16#FF#;
CFI_array(16#34#) := 16#FF#;
ELSE
CFI_array(16#2C#) := 16#02#; --Boot device
IF TBPARM = '1' THEN
CFI_array(16#2D#) := 16#FD#;
CFI_array(16#2E#) := 16#00#;
CFI_array(16#2F#) := 16#00#;
CFI_array(16#30#) := 16#01#;
CFI_array(16#31#) := 16#1F#;
CFI_array(16#32#) := 16#00#;
CFI_array(16#33#) := 16#10#;
CFI_array(16#34#) := 16#00#;
ELSE
CFI_array(16#2D#) := 16#1F#;
CFI_array(16#2E#) := 16#00#;
CFI_array(16#2F#) := 16#10#;
CFI_array(16#30#) := 16#00#;
CFI_array(16#31#) := 16#FD#;
CFI_array(16#32#) := 16#00#;
CFI_array(16#33#) := 16#00#;
CFI_array(16#34#) := 16#01#;
END IF;
END IF;
CFI_array(16#35#) := 16#FF#;
CFI_array(16#36#) := 16#FF#;
CFI_array(16#37#) := 16#FF#;
CFI_array(16#38#) := 16#FF#;
CFI_array(16#39#) := 16#FF#;
CFI_array(16#3A#) := 16#FF#;
CFI_array(16#3B#) := 16#FF#;
CFI_array(16#3C#) := 16#FF#;
CFI_array(16#3D#) := 16#FF#;
CFI_array(16#3E#) := 16#FF#;
CFI_array(16#3F#) := 16#FF#;
--CFI Primary Vendor-Specific Extended Query
CFI_array(16#40#) := 16#50#;
CFI_array(16#41#) := 16#52#;
CFI_array(16#42#) := 16#49#;
CFI_array(16#43#) := 16#31#;
CFI_array(16#44#) := 16#33#;
CFI_array(16#45#) := 16#21#;
CFI_array(16#46#) := 16#02#;
CFI_array(16#47#) := 16#01#;
CFI_array(16#48#) := 16#00#;
CFI_array(16#49#) := 16#08#;
CFI_array(16#4A#) := 16#00#;
CFI_array(16#4B#) := 16#01#;
CFI_array(16#4C#) := 16#00#;
CFI_array(16#4D#) := 16#00#;
CFI_array(16#4E#) := 16#00#;
CFI_array(16#4F#) := 16#07#;
CFI_array(16#50#) := 16#01#;
CFI_array(16#51#) := 16#41#;
CFI_array(16#52#) := 16#4C#;
CFI_array(16#53#) := 16#54#;
CFI_array(16#54#) := 16#32#;
CFI_array(16#55#) := 16#30#;
CFI_array_tmp :=to_slv(CFI_array(16#00#), 8) &
to_slv(CFI_array(16#01#), 8) &
to_slv(CFI_array(16#02#), 8) &
to_slv(CFI_array(16#03#), 8) &
to_slv(CFI_array(16#04#), 8) &
to_slv(CFI_array(16#05#), 8) &
to_slv(CFI_array(16#06#), 8) &
to_slv(CFI_array(16#07#), 8) &
to_slv(CFI_array(16#08#), 8) &
to_slv(CFI_array(16#09#), 8) &
to_slv(CFI_array(16#0A#), 8) &
to_slv(CFI_array(16#0B#), 8) &
to_slv(CFI_array(16#0C#), 8) &
to_slv(CFI_array(16#0D#), 8) &
to_slv(CFI_array(16#0E#), 8) &
to_slv(CFI_array(16#0F#), 8) &
to_slv(CFI_array(16#10#), 8) &
to_slv(CFI_array(16#11#), 8) &
to_slv(CFI_array(16#12#), 8) &
to_slv(CFI_array(16#13#), 8) &
to_slv(CFI_array(16#14#), 8) &
to_slv(CFI_array(16#15#), 8) &
to_slv(CFI_array(16#16#), 8) &
to_slv(CFI_array(16#17#), 8) &
to_slv(CFI_array(16#18#), 8) &
to_slv(CFI_array(16#19#), 8) &
to_slv(CFI_array(16#1A#), 8) &
to_slv(CFI_array(16#1B#), 8) &
to_slv(CFI_array(16#1C#), 8) &
to_slv(CFI_array(16#1D#), 8) &
to_slv(CFI_array(16#1E#), 8) &
to_slv(CFI_array(16#1F#), 8) &
to_slv(CFI_array(16#20#), 8) &
to_slv(CFI_array(16#21#), 8) &
to_slv(CFI_array(16#22#), 8) &
to_slv(CFI_array(16#23#), 8) &
to_slv(CFI_array(16#24#), 8) &
to_slv(CFI_array(16#25#), 8) &
to_slv(CFI_array(16#26#), 8) &
to_slv(CFI_array(16#27#), 8) &
to_slv(CFI_array(16#28#), 8) &
to_slv(CFI_array(16#29#), 8) &
to_slv(CFI_array(16#2A#), 8) &
to_slv(CFI_array(16#2B#), 8) &
to_slv(CFI_array(16#2C#), 8) &
to_slv(CFI_array(16#2D#), 8) &
to_slv(CFI_array(16#2E#), 8) &
to_slv(CFI_array(16#2F#), 8) &
to_slv(CFI_array(16#30#), 8) &
to_slv(CFI_array(16#31#), 8) &
to_slv(CFI_array(16#32#), 8) &
to_slv(CFI_array(16#33#), 8) &
to_slv(CFI_array(16#34#), 8) &
to_slv(CFI_array(16#35#), 8) &
to_slv(CFI_array(16#36#), 8) &
to_slv(CFI_array(16#37#), 8) &
to_slv(CFI_array(16#38#), 8) &
to_slv(CFI_array(16#39#), 8) &
to_slv(CFI_array(16#3A#), 8) &
to_slv(CFI_array(16#3B#), 8) &
to_slv(CFI_array(16#3C#), 8) &
to_slv(CFI_array(16#3D#), 8) &
to_slv(CFI_array(16#3E#), 8) &
to_slv(CFI_array(16#3F#), 8) &
to_slv(CFI_array(16#40#), 8) &
to_slv(CFI_array(16#41#), 8) &
to_slv(CFI_array(16#42#), 8) &
to_slv(CFI_array(16#43#), 8) &
to_slv(CFI_array(16#44#), 8) &
to_slv(CFI_array(16#45#), 8) &
to_slv(CFI_array(16#46#), 8) &
to_slv(CFI_array(16#47#), 8) &
to_slv(CFI_array(16#48#), 8) &
to_slv(CFI_array(16#49#), 8) &
to_slv(CFI_array(16#4A#), 8) &
to_slv(CFI_array(16#4B#), 8) &
to_slv(CFI_array(16#4C#), 8) &
to_slv(CFI_array(16#4D#), 8) &
to_slv(CFI_array(16#4E#), 8) &
to_slv(CFI_array(16#4F#), 8) &
to_slv(CFI_array(16#50#), 8);
WAIT;
END PROCESS CFIPreload;
AspRegInit: PROCESS(ASP_INIT)
BEGIN
IF ASP_INIT = 0 THEN
ASP_reg := to_slv(16#FE4F#,16);
ELSE
ASP_reg := to_slv(16#FE7F#,16);
END IF;
END PROCESS AspRegInit;
TopBottom: PROCESS(change_TBPARM, PoweredUp)
BEGIN
IF (TimingModel(16)= '0') THEN
IF TBPARM = '0' THEN
BottomBoot <= TRUE;
b_act := 1;
ELSE
TopBoot <= TRUE;
BottomBoot <= FALSE;
b_act := 0;
END IF;
END IF;
END PROCESS TopBottom;
Protect : PROCESS(change_BP)
BEGIN
IF rising_edge(change_BP) THEN
CASE BP_bits IS
WHEN "000" =>
Sec_Prot := (OTHERS => '0');
WHEN "001" =>
IF TBPROT = '0' THEN
Sec_Prot(SecNumMax downto ((SecNum+1)*63/64+30*b_act))
:= (OTHERS => '1');
Sec_Prot(((SecNum+1)*63/64 + 30*b_act) - 1 downto 0)
:= (OTHERS => '0');
ELSE
Sec_Prot((SecNum+1)/64 + 30*b_act - 1 downto 0)
:= (OTHERS => '1');
Sec_Prot(SecNumMax downto (SecNum+1)/64 + 30*b_act)
:= (OTHERS => '0');
END IF;
WHEN "010" =>
IF TBPROT = '0' THEN
Sec_Prot(SecNumMax downto ((SecNum+1)*31/32+30*b_act))
:= (OTHERS => '1');
Sec_Prot(((SecNum+1)*31/32+30*b_act) - 1 downto 0)
:= (OTHERS => '0');
ELSE
Sec_Prot((SecNum+1)/32 + 30*b_act - 1 downto 0)
:= (others => '1');
Sec_Prot(SecNumMax downto (SecNum+1)/32 + 30*b_act)
:= (OTHERS => '0');
END IF;
WHEN "011" =>
IF TBPROT = '0' THEN
Sec_Prot(SecNumMax downto ((SecNum+1)*15/16+30*b_act))
:= (OTHERS => '1');
Sec_Prot(((SecNum+1)*15/16 + 30*b_act) - 1 downto 0)
:= (OTHERS => '0');
ELSE
Sec_Prot((SecNum+1)/16 + 30*b_act - 1 downto 0)
:= (OTHERS => '1');
Sec_Prot(SecNumMax downto (SecNum+1)/16 + 30*b_act)
:= (OTHERS => '0');
END IF;
WHEN "100" =>
IF TBPROT = '0' THEN
Sec_Prot(SecNumMax downto ((SecNum+1)*7/8 + 30*b_act))
:= (OTHERS => '1');
Sec_Prot(((SecNum+1)*7/8 + 30*b_act) - 1 downto 0)
:= (OTHERS => '0');
ELSE
Sec_Prot((SecNum+1)/8 + 30*b_act - 1 downto 0)
:= (OTHERS => '1');
Sec_Prot(SecNumMax downto (SecNum+1)/8 + 30*b_act)
:= (OTHERS => '0');
END IF;
WHEN "101" =>
IF TBPROT = '0' THEN
Sec_Prot(SecNumMax downto ((SecNum+1)*3/4 + 30*b_act))
:= (OTHERS => '1');
Sec_Prot(((SecNum+1)*3/4 + 30*b_act) - 1 downto 0)
:= (OTHERS => '0');
ELSE
Sec_Prot((SecNum+1)/4 + 30*b_act - 1 downto 0)
:= (OTHERS => '1');
Sec_Prot(SecNumMax downto (SecNum+1)/4 + 30*b_act)
:= (OTHERS => '0');
END IF;
WHEN "110" =>
IF TBPROT = '0' THEN
Sec_Prot(SecNumMax downto ((SecNum+1)/2 + 30*b_act))
:= (OTHERS => '1');
Sec_Prot(((SecNum+1)/2 + 30*b_act) - 1 downto 0)
:= (OTHERS => '0');
ELSE
Sec_Prot((SecNum+1)/2 + 30*b_act - 1 downto 0)
:= (OTHERS => '1');
Sec_Prot(SecNumMax downto (SecNum+1)/2 + 30*b_act)
:= (OTHERS => '0');
END IF;
WHEN OTHERS =>
Sec_Prot := (OTHERS => '1');
END CASE;
END IF;
END PROCESS Protect;
HOLD_FRAME_ON_PO_ZD : PROCESS(SOut_zd, SIOut_zd, HOLDNeg_pullup)
BEGIN
IF (HOLDNeg_pullup = '0' AND QUAD /= '1') THEN
hold_mode := TRUE;
SIOut_z <= 'Z';
SOut_z <= 'Z';
ELSE
IF hold_mode THEN
SIOut_z <= SIOut_zd AFTER tpd_HOLDNeg_SO(trz0);
SOut_z <= SOut_zd AFTER tpd_HOLDNeg_SO(trz0);
hold_mode := FALSE;
ELSE
SIOut_z <= SIOut_zd;
SOut_z <= SOut_zd;
hold_mode := FALSE;
END IF;
END IF;
END PROCESS HOLD_FRAME_ON_PO_ZD;
HOLD_PULL_UP : PROCESS(HOLDNegIn)
BEGIN
IF (QUAD = '0') THEN
IF (HOLDNegIn = 'Z') THEN
HOLDNeg_pullup <= '1';
ELSE
HOLDNeg_pullup <= HOLDNegIn;
END IF;
END IF;
END PROCESS HOLD_PULL_UP;
WP_PULL_UP : PROCESS(WPNegIn)
BEGIN
IF (QUAD = '0') THEN
IF (WPNegIn = 'Z') THEN
WPNeg_pullup <= '1';
ELSE
WPNeg_pullup <= WPNegIn;
END IF;
END IF;
END PROCESS WP_PULL_UP;
RST_PULL_UP : PROCESS(RSTNeg)
BEGIN
IF (RSTNeg = 'Z') THEN
RSTNeg_pullup <= '1';
ELSE
RSTNeg_pullup <= RSTNeg;
END IF;
END PROCESS RST_PULL_UP;
---------------------------------------------------------------------------
---- File Read Section - Preload Control
---------------------------------------------------------------------------
MemPreload : PROCESS
-- text file input variables
FILE mem_file : text is mem_file_name;
FILE otp_file : text is otp_file_name;
VARIABLE ind : NATURAL RANGE 0 TO AddrRANGE := 0;
VARIABLE otp_ind : NATURAL RANGE 16#000# TO 16#3FF# := 16#000#;
VARIABLE buf : line;
BEGIN
---------------------------------------------------------------------------
--s25fl128s memory preload file format
-----------------------------------
---------------------------------------------------------------------------
-- / - comment
-- @aaaaaa - <aaaaaa> stands for address
-- dd - <dd> is byte to be written at Mem(aaaaaa++)
-- (aaaaaa is incremented at every load)
-- only first 1-7 columns are loaded. NO empty lines !!!!!!!!!!!!!!!!
---------------------------------------------------------------------------
-- memory preload
IF (mem_file_name /= "none" AND UserPreload) THEN
ind := 0;
Mem := (OTHERS => MaxData);
WHILE (not ENDFILE (mem_file)) LOOP
READLINE (mem_file, buf);
IF buf(1) = '/' THEN
NEXT;
ELSIF buf(1) = '@' THEN
IF ind > AddrRANGE THEN
ASSERT false
REPORT "Given preload address is out of" &
"memory address range"
SEVERITY warning;
ELSE
ind := h(buf(2 to 7)); --address
END IF;
ELSE
Mem(ind) := h(buf(1 to 2));
IF ind < AddrRANGE THEN
ind := ind + 1;
END IF;
END IF;
END LOOP;
END IF;
---------------------------------------------------------------------------
--s25fl128s_otp memory preload file format
---------------------------------------------------------------------------
-- / - comment
-- @aaa - <aaa> stands for address
-- dd - <dd> is byte to be written at OTPMem(aaa++)
-- (aaa is incremented at every load)
-- only first 1-4 columns are loaded. NO empty lines !!!!!!!!!!!!!!!!
---------------------------------------------------------------------------
-- memory preload
IF (otp_file_name /= "none" AND UserPreload) THEN
otp_ind := 16#000#;
OTPMem := (OTHERS => MaxData);
WHILE (not ENDFILE (otp_file)) LOOP
READLINE (otp_file, buf);
IF buf(1) = '/' THEN
NEXT;
ELSIF buf(1) = '@' THEN
IF otp_ind > 16#3FF# OR otp_ind < 16#000# THEN
ASSERT false
REPORT "Given preload address is out of" &
"OTP address range"
SEVERITY warning;
ELSE
otp_ind := h(buf(2 to 4)); --address
END IF;
ELSE
OTPMem(otp_ind) := h(buf(1 to 2));
otp_ind := otp_ind + 1;
END IF;
END LOOP;
END IF;
LOCK_BYTE1 := to_slv(OTPMem(16#10#),8);
LOCK_BYTE2 := to_slv(OTPMem(16#11#),8);
LOCK_BYTE3 := to_slv(OTPMem(16#12#),8);
LOCK_BYTE4 := to_slv(OTPMem(16#13#),8);
WAIT;
END PROCESS MemPreload;
----------------------------------------------------------------------------
-- Path Delay Section
----------------------------------------------------------------------------
S_Out_PathDelay_Gen : PROCESS(SOut_z)
VARIABLE SO_GlitchData : VitalGlitchDataType;
BEGIN
VitalPathDelay01Z (
OutSignal => SOut,
OutSignalName => "SO",
OutTemp => SOut_z,
Mode => VitalTransport,
GlitchData => SO_GlitchData,
Paths => (
0 => (InputChangeTime => SCK_ipd'LAST_EVENT,
PathDelay => VitalExtendtofillDelay(tpd_SCK_SO_normal),
PathCondition => NOT(ddr)),
1 => (InputChangeTime => SCK_ipd'LAST_EVENT,
PathDelay => VitalExtendtofillDelay(tpd_SCK_SO_DDR),
PathCondition => (ddr OR fast_rd)),
2 => (InputChangeTime => CSNeg_ipd'LAST_EVENT,
PathDelay => tpd_CSNeg_SO,
PathCondition => CSNeg_ipd = '1'),
3 => (InputChangeTime => HOLDNegIn'LAST_EVENT,
PathDelay => tpd_HOLDNeg_SO,
PathCondition => QUAD = '0')
)
);
END PROCESS;
SI_Out_PathDelay : PROCESS(SIOut_z)
VARIABLE SI_GlitchData : VitalGlitchDataType;
BEGIN
VitalPathDelay01Z (
OutSignal => SIOut,
OutSignalName => "SI",
OutTemp => SIOut_z,
Mode => VitalTransport,
GlitchData => SI_GlitchData,
Paths => (
0 => (InputChangeTime => SCK_ipd'LAST_EVENT,
PathDelay => VitalExtendtofillDelay(tpd_SCK_SO_normal),
PathCondition => dual AND NOT(ddr)),
1 => (InputChangeTime => SCK_ipd'LAST_EVENT,
PathDelay => VitalExtendtofillDelay(tpd_SCK_SO_DDR),
PathCondition => dual AND ddr),
2 => (InputChangeTime => CSNeg_ipd'LAST_EVENT,
PathDelay => tpd_CSNeg_SO,
PathCondition => CSNeg_ipd = '1'),
3 => (InputChangeTime => HOLDNegIn'LAST_EVENT,
PathDelay => tpd_HOLDNeg_SO,
PathCondition => dual AND QUAD = '0')
)
);
END PROCESS;
HOLD_Out_PathDelay : PROCESS(HOLDNegOut_zd)
VARIABLE HOLD_GlitchData : VitalGlitchDataType;
BEGIN
VitalPathDelay01Z (
OutSignal => HOLDNegOut,
OutSignalName => "HOLDNeg",
OutTemp => HOLDNegOut_zd,
Mode => VitalTransport,
GlitchData => HOLD_GlitchData,
Paths => (
0 => (InputChangeTime => SCK_ipd'LAST_EVENT,
PathDelay => VitalExtendtofillDelay(tpd_SCK_SO_normal),
PathCondition => dual AND not(ddr) AND QUAD = '1'),
1 => (InputChangeTime => SCK_ipd'LAST_EVENT,
PathDelay => VitalExtendtofillDelay(tpd_SCK_SO_DDR),
PathCondition => ddr AND QUAD = '1'),
2 => (InputChangeTime => CSNeg_ipd'LAST_EVENT,
PathDelay => tpd_CSNeg_SO,
PathCondition => CSNeg_ipd = '1' AND
HOLDNegOut_zd = 'Z' AND QUAD = '1')
)
);
END PROCESS;
WP_Out_PathDelay : PROCESS(WPNegOut_zd)
VARIABLE WP_GlitchData : VitalGlitchDataType;
BEGIN
VitalPathDelay01Z (
OutSignal => WPNegOut,
OutSignalName => "WPNeg",
OutTemp => WPNegOut_zd,
Mode => VitalTransport,
GlitchData => WP_GlitchData,
Paths => (
0 => (InputChangeTime => SCK_ipd'LAST_EVENT,
PathDelay => VitalExtendtofillDelay(tpd_SCK_SO_normal),
PathCondition => dual AND not(ddr) AND QUAD = '1'),
1 => (InputChangeTime => SCK_ipd'LAST_EVENT,
PathDelay => VitalExtendtofillDelay(tpd_SCK_SO_DDR),
PathCondition => ddr AND QUAD = '1'),
2 => (InputChangeTime => CSNeg_ipd'LAST_EVENT,
PathDelay => tpd_CSNeg_SO,
PathCondition => CSNeg_ipd = '1' AND
WPNegOut_zd = 'Z' AND QUAD = '1')
)
);
END PROCESS;
END BLOCK behavior;
END vhdl_behavioral;