-------------------------------------------------------------------------------
-- This is the property of PERFTRENDS TECHNOLOGIES PRIVATE LIMITED and
-- possession or use of file has to be with the written LICENCE AGGREMENT
-- from PERFTRENDS TECHNOLOGIES PRIVATE LIMITED.
--    
-------------------------------------------------------------------------------
--
--    Project              : Atmel DataFlash model
-------------------------------------------------------------------------------
--    File                 : $RCSfile: DataFlash2.1.vhd,v $
--    Path                 : $Source: /home/cvs/atmel_flash_dev/design/DataFlash2.1.vhd,v $  	
--    Author               : E.MAGESH
--    Created on           : 20-06-06
--    Revision             : $Revision: 1.1 $
--    Last modified by     : $Author: magesh $
--    Last modified on     : $Date: 2006/07/19 13:54:54 $
-------------------------------------------------------------------------------
--    Module               : FlashMemory
--    Description          :
--
--
-------------------------------------------------------------------------------
--
--    Design hierarchy     : 
--    Instantiated Modules : 
-------------------------------------------------------------------------------
--    Revision history :
--    $Log: DataFlash2.1.vhd,v $
--    Revision 1.1  2006/07/19 13:54:54  magesh
--    *** empty log message ***
--
--    Revision 1.5  2006/06/29 12:34:49  magesh
--    *** empty log message ***
--
--    Revision 1.4  2006/06/27 12:05:42  magesh
--    *** empty log message ***
--
--    Revision 1.3  2006/06/21 14:24:03  magesh
--    *** empty log message ***
--
--    Revision 1.2  2006/06/20 13:34:01  magesh
--    *** empty log message ***
--
-------------------------------------------------------------------------------


library std;
use std.textio.all;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_textio.all;
use ieee.std_logic_arith.all;
use IEEE.Std_logic_unsigned.all;
use IEEE.numeric_std.all;
---entity declarations--------------
entity DataFlash is
	generic(
		flashmemory     : string          := "memory.txt";
		Rapid_interface : boolean         := true;
		fsck            : integer         := 66;
		DEVICE          : string(1 to 10) := "AT45DB011D";
		Tsck            : Time            := 13.6 ns);
	port(
		SI     : in  std_logic;         -- Data SPI
		CSB    : in  std_logic;         -- Chip Select SPI
		SCK    : in  std_logic;         -- Clock SPI
		WPB    : in  std_logic;         -- Hard Ware Page Write protecteds Pin
		RESETB : in  std_logic;         -- Reset Pin		
		SO     : out std_logic;         -- Serial Output
		RDYBSY : out std_logic          -- Ready Busy pin
	);
end DataFlash;

----architecture declarations------
architecture design of DataFlash is
	constant t_buffer  : integer   := 2;
	signal binary_page : std_logic := '0';
	signal status2     : std_logic := '1';
	signal status3     : std_logic;
	signal status4     : std_logic;
	signal status5     : std_logic;

	constant TFP   : TIME := 14000000 ns;
	constant TCE   : TIME := 400000000 ns; -- TBD Spec. time is 5s
	constant TVCSL : TIME := 30000 ns;  -- ?? 
	constant TPUW  : TIME := 10000000 ns; -- ??

	---- Input Times check
	constant Tcar1 : Time := Tsck;
	constant Tcar2 : Time := 30 ns;     -- 33 Mhz operation

	constant Twh  : TIME := Tsck / 2;   -- SCK High Time
	constant Twl  : TIME := Tsck / 2;   -- SCK Low Time
	constant Tcs  : TIME := 50 ns;      -- Minimum CS! High Time
	constant Tcss : TIME := 5 ns;       -- CS! setup Time
	constant Tcsh : TIME := 5 ns;       -- CS! Hold Time
	constant Tcsb : TIME := 100 ns;     -- Max 
	constant Tsu  : TIME := 2 ns;       -- Data in Setup Time
	constant Th   : TIME := 3 ns;       -- Data in Hold Time

	---- Outup delay
	constant Tho   : TIME := 0 ns;      -- Output Hold Time
	constant Tdis  : TIME := 8 ns;      -- Output Disable Time
	constant Tv    : TIME := 8 ns;      -- Output Valid
	constant Twpe  : TIME := 1 ns;      -- 
	constant Twpd  : TIME := 1 ns;      -- 
	constant Tedpd : TIME := 3 us;
	constant Trdpd : TIME := 30 us;

	---- Processing Time 
	constant Txfr  : TIME := 400 us;    -- Page to Buffer Transfer_Compare Time
	constant Tcomp : TIME := 400 us;
	constant Tep   : TIME := 40 ms;     -- Page Erase and Programming Time
	constant Tp    : TIME := 6 ms;      -- Page Programming Time
	constant Tpe   : TIME := 35 ms;
	constant Tbe   : TIME := 100 ms;
	constant Tse   : TIME := 5000 ms;   -- Spec. time is 5s
	constant Trst  : TIME := 10 us;     -- Reset Pulse Width
	constant Trec  : TIME := 1 us;      -- Reset Recovery Time

	------------------------------------------------ 
	signal TsckRp, TsckRw, TsckF, TcsR, TcsF, Tsckm, Tsim, TsckRh : time := 0 ns;

	------------- global signal declarations---------

	-----opcode enable signal---------


	signal MMCAR        : std_logic;
	constant binary_opt : std_logic := '1';
	signal buffer2read  : std_logic;
	signal MMPTB1T      : std_logic;
	signal MMPTB2T      : std_logic;
	signal MMPTB1C      : std_logic;
	signal MMPTB2C      : std_logic;
	signal B1W          : std_logic;
	signal B2W          : std_logic;
	signal B1TMMPPWBIE  : std_logic;
	signal B2TMMPPWBIE  : std_logic;
	signal B1TMMPPWOBIE : std_logic;
	signal B2TMMPPWOBIE : std_logic;
	signal PE           : std_logic;
	signal BE           : std_logic;
	signal SE           : std_logic;

	signal CE     : std_logic;
	signal MMPPB1 : std_logic;
	signal MMPPB2 : std_logic;
	signal APRB1  : std_logic;
	signal APRB2  : std_logic;

	signal OP3D : std_logic;
	signal BPS  : std_logic;
	signal PRE  : std_logic;
	signal PRP  : std_logic;
	signal LRP  : std_logic;
	signal SPE  : std_logic;
	signal SPD  : std_logic;
	signal PRR  : std_logic;
	signal LRR  : std_logic;
	signal OP9B : std_logic;
	signal SRP  : std_logic;

	signal security_flag     : std_logic := '0';
	signal soft_prot_enabled : std_logic := '0';
	signal tmp_reg1          : std_logic_vector(7 downto 0);
	signal tmp_reg2          : std_logic_vector(7 downto 0);

	signal less_than_33mhz : std_logic;
	--signal less_than_20Mhz : std_logic;
	signal locked          : std_logic;
	signal protecteds      : std_logic;

	signal protection : bit_vector(511 downto 0) := (others => '1');
	signal lockdown   : bit_vector(511 downto 0) := (others => '0');
	signal security   : bit_vector(511 downto 0) := (others => '1');
	signal factory    : bit_vector(511 downto 0) := (others => '1');

	function device_Sel1(DEVICE : in string(1 to 10)
		) return std_logic is
		variable status3 : std_logic;
	begin
		if (DEVICE = "AT45DB041D") then
			status3 := '1';

		elsif (DEVICE = "AT45DB081D") then
			status3 := '0';

		elsif (DEVICE = "AT45DB161D") then
			status3 := '1';

		elsif (DEVICE = "AT45DB321D") then
			status3 := '0';

		elsif (DEVICE = "AT45DB642D") then
			status3 := '1';

		elsif (DEVICE = "AT45DB011D") then
			status3 := '1';

		elsif (DEVICE = "AT45DB021D") then
			status3 := '1';

		else
			status3 := '1';

		end if;

		return status3;

	end device_sel1;

	function device_Sel2(DEVICE : in string(1 to 10)
		) return std_logic is
		variable status4 : std_logic;
	begin
		if (DEVICE = "AT45DB041D") then
			status4 := '1';

		elsif (DEVICE = "AT45DB081D") then
			status4 := '0';

		elsif (DEVICE = "AT45DB161D") then
			status4 := '0';

		elsif (DEVICE = "AT45DB321D") then
			status4 := '1';

		elsif (DEVICE = "AT45DB642D") then
			status4 := '1';

		elsif (DEVICE = "AT45DB011D") then
			status4 := '0';

		elsif (DEVICE = "AT45DB021D") then
			status4 := '1';

		else
			status4 := '1';

		end if;

		return status4;

	end device_sel2;

	function device_Sel3(DEVICE : in string(1 to 10)
		) return std_logic is
		variable status5 : std_logic;
	begin
		if (DEVICE = "AT45DB041D") then
			status5 := '0';
		elsif (DEVICE = "AT45DB081D") then
			status5 := '1';

		elsif (DEVICE = "AT45DB161D") then
			status5 := '1';
		elsif (DEVICE = "AT45DB321D") then
			status5 := '1';
		elsif (DEVICE = "AT45DB642D") then
			status5 := '1';
		elsif (DEVICE = "AT45DB011D") then
			status5 := '0';
		elsif (DEVICE = "AT45DB021D") then
			status5 := '0';
		else
			status5 := '0';
		end if;
		return status5;

	end device_sel3;

	function page_cal(DEVICE : in string(1 to 10)
		) return integer is
		variable pages : integer range 1 to 8192 := 2048;
	begin
		case DEVICE is
			when "AT45DB041D" =>
				pages := 2048;
			when "AT45DB081D" =>
				pages := 4096;
			when "AT45DB161D" =>
				pages := 4096;
			when "AT45DB321D" =>
				pages := 8192;
			when "AT45DB642D" =>
				pages := 8192;
			when "AT45DB011D" =>
				pages := 512;
			when "AT45DB021D" =>
				pages := 1024;
			when OTHERS =>
				pages := 2048;
		end case;

		return pages;

	end page_cal;

	function pageper_sector(DEVICE : in string(1 to 10)
		) return integer is
		variable page_per_sector : integer range 1 to 256 := 256;

	begin
		case DEVICE is
			when "AT45DB041D" =>
				page_per_sector := 256;
			when "AT45DB081D" =>
				page_per_sector := 256;
			when "AT45DB161D" =>
				page_per_sector := 256;
			when "AT45DB321D" =>
				page_per_sector := 128;
			when "AT45DB642D" =>
				page_per_sector := 256;
			when "AT45DB011D" =>
				page_per_sector := 128;
			when "AT45DB021D" =>
				page_per_sector := 128;
			when OTHERS =>
				page_per_sector := 256;
		end case;

		return page_per_sector;

	end pageper_sector;

	function sec_tors(DEVICE : in string(1 to 10)
		) return integer is
		variable sectors : integer range 1 to 64 := 8;

	begin
		case DEVICE is
			when "AT45DB041D" =>
				sectors := 8;
			when "AT45DB081D" =>
				sectors := 16;
			when "AT45DB161D" =>
				sectors := 16;
			when "AT45DB321D" =>
				sectors := 64;
			when "AT45DB642D" =>
				sectors := 32;
			when "AT45DB011D" =>
				sectors := 4;
			when "AT45DB021D" =>
				sectors := 8;
			when OTHERS =>
				sectors := 8;
		end case;

		return sectors;

	end sec_tors;

	function pagesize_forbuffer(DEVICE : in string(1 to 10)
		) return integer is
		variable page_size : integer range 1 to 1056 := 264;

	begin
		case DEVICE is
			when "AT45DB041D" =>
				page_size := 264;
			when "AT45DB081D" =>
				page_size := 264;
			when "AT45DB161D" =>
				page_size := 528;
			when "AT45DB321D" =>
				page_size := 528;
			when "AT45DB642D" =>
				page_size := 1056;
			when "AT45DB011D" =>
				page_size := 264;
			when "AT45DB021D" =>
				page_size := 264;
			when OTHERS =>
				page_size := 264;
		end case;

		return page_size;

	end pagesize_forbuffer;

	function pagesize(DEVICE             : in string(1 to 10);
			          signal binary_page : in std_logic
		) return integer is
		variable page_size : integer range 1 to 1056 := 264;

	begin
		case DEVICE is
			when "AT45DB041D" =>
				page_size := (264 - (conv_integer(BINARY_page) * 8));
			when "AT45DB081D" =>
				page_size := (264 - (conv_integer(BINARY_page) * 8));
			when "AT45DB161D" =>
				page_size := (528 - (conv_integer(BINARY_page) * 16));
			when "AT45DB321D" =>
				page_size := (528 - (conv_integer(BINARY_page) * 16));
			when "AT45DB642D" =>
				page_size := (1056 - (conv_integer(BINARY_page) * 32));
			when "AT45DB011D" =>
				page_size := (264 - (conv_integer(BINARY_page) * 8));
			when "AT45DB021D" =>
				page_size := (264 - (conv_integer(BINARY_page) * 8));
			when OTHERS =>
				page_size := (264 - (conv_integer(BINARY_page) * 8));
		end case;

		return page_size;

	end pagesize;

	function memsize(page_size : in integer range 1 to 1056;
			         pages     : in integer range 1 to 8192
		) return integer is
		variable mem_size : integer range 1 to 69206016;
	begin
		mem_size := page_size * pages;
		return mem_size;

	end memsize;

	function b_address(DEVICE             : in string(1 to 10);
			           signal binary_page : in std_logic
		) return integer is
		variable baddress : integer range 1 to 11 := 9;
	begin
		case DEVICE is
			when "AT45DB041D" =>
				baddress := (9 - (conv_integer(BINARY_page) * 1));
			when "AT45DB081D" =>
				baddress := (9 - (conv_integer(BINARY_page) * 1));
			when "AT45DB161D" =>
				baddress := (10 - (conv_integer(BINARY_page) * 1));
			when "AT45DB321D" =>
				baddress := (10 - (conv_integer(BINARY_page) * 1));
			when "AT45DB642D" =>
				baddress := (11 - (conv_integer(BINARY_page) * 1));
			when "AT45DB011D" =>
				baddress := (9 - (conv_integer(BINARY_page) * 1));
			when "AT45DB021D" =>
				baddress := (9 - (conv_integer(BINARY_page) * 1));
			when OTHERS =>
				baddress := (9 - (conv_integer(BINARY_page) * 1));
		end case;

		return baddress;

	end b_address;

	function p_address(DEVICE : in string(1 to 10)
		) return integer is
		variable paddress : integer range 1 to 14 := 11;
	begin
		case DEVICE is
			when "AT45DB041D" =>
				paddress := 11;
			when "AT45DB081D" =>
				paddress := 12;
			when "AT45DB161D" =>
				paddress := 12;
			when "AT45DB321D" =>
				paddress := 13;
			when "AT45DB642D" =>
				paddress := 13;
			when "AT45DB011D" =>
				paddress := 9;
			when "AT45DB021D" =>
				paddress := 10;
			when OTHERS =>
				paddress := 11;
		end case;

		return paddress;

	end p_address;

	function s_address(DEVICE : in string(1 to 10)
		) return integer is
		variable saddress : integer range 1 to 6 := 3;
	begin
		case DEVICE is
			when "AT45DB041D" =>
				saddress := 3;
			when "AT45DB081D" =>
				saddress := 4;
			when "AT45DB161D" =>
				saddress := 4;
			when "AT45DB321D" =>
				saddress := 6;
			when "AT45DB642D" =>
				saddress := 5;
			when "AT45DB011D" =>
				saddress := 2;
			when "AT45DB021D" =>
				saddress := 3;
			when OTHERS =>
				saddress := 3;
		end case;

		return saddress;

	end s_address;

	function manid(DEVICE : in string(1 to 10)
		) return std_logic_vector is
		variable man_id : std_logic_vector(31 downto 0);
	begin
		case DEVICE is
			when "AT45DB041D" =>
				man_id := X"1F_24_00_00";
			when "AT45DB081D" =>
				man_id := X"1F_25_00_00";
			when "AT45DB161D" =>
				man_id := X"1F_26_00_00";
			when "AT45DB321D" =>
				man_id := X"1F_27_00_00";
			when "AT45DB642D" =>
				man_id := X"1F_28_00_00";
			when "AT45DB011D" =>
				man_id := X"1F_22_00_00";
			when "AT45DB021D" =>
				man_id := X"1F_23_00_00";
			when OTHERS =>
				man_id := X"1F_24_01_00";
		end case;

		return man_id;

	end manid;
	--------------timing task implementation--------

	procedure checkSetupCS(
			signal CsSignal      : in    std_logic;
			CsSignalName         : in    string;
			signal TriggerSignal : in    std_logic;
			TriggerSignalName    : in    string;
			ExpectedDelay        : in    time;
			ExpectedDelayName    : in    string;
			signal LastCsFall    : inout time;
			FullPathName         : in    string;
			CheckEnabled         : in    boolean
		) is
		variable ln : Line;
	begin
		if (CsSignal'event and CsSignal = '0') then
			LastCsFall <= now;
		end if;

		if TriggerSignal'event and (now - LastCsFall < ExpectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (lastCsFall /= 0 ns) and checkEnabled then
			write(ln, string'("Error on "));
			write(ln, fullPathName);
			write(ln, string'(": '"));
			write(ln, string'(CsSignalName));
			write(ln, string'("' to '"));
			write(ln, string'(TriggerSignalName));
			write(ln, string'("' Setup violation at: "));
			write(ln, now);
			write(ln, string'(", "));
			write(ln, string'(ExpectedDelayName));
			write(ln, string'(" expected: "));
			write(ln, expectedDelay);
			write(ln, string'(", "));
			write(ln, string'(ExpectedDelayName));
			write(ln, string'(" actual: "));
			write(ln, now - LastCsFall);

			writeline(output, ln);
		end if;

	end checkSetupCs;

	--------------------------------------------------------------------------
	-- CsSignal		__________/--------
	-- TriggerSignal	======x============
	-- 			      <--->	

	procedure checkHoldCS(
			signal CsSignal        : in    std_logic;
			CsSignalName           : in    string;
			signal TriggerSignal   : in    std_logic;
			TriggerSignalName      : in    string;
			ExpectedDelay          : in    time;
			ExpectedDelayName      : in    string;
			signal LastTriggerEdge : inout time;
			FullPathName           : in    string;
			CheckEnabled           : in    boolean
		) is
		variable ln : Line;
	begin
		if triggerSignal'event then
			LastTriggerEdge <= now;
		end if;

		if CsSignal'event and CsSignal = '1' and (now - LastTriggerEdge < ExpectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (LastTriggerEdge /= 0 ns) and checkEnabled then
			write(ln, string'("Error on "));
			write(ln, fullPathName);
			write(ln, string'(": '"));
			write(ln, string'(CsSignalName));
			write(ln, string'("' to '"));
			write(ln, string'(triggerSignalName));
			write(ln, string'("' Hold violation at: "));
			write(ln, now);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" expected: "));
			write(ln, expectedDelay);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" actual: "));
			write(ln, now - LastTriggerEdge);

			writeline(output, ln);
		end if;

	end checkHoldCs;

	-----------------------------------------------------------------------
	-- Trigger		___________/---------
	-- Reference		=====x===============
	-- 			     <----->

	procedure checkSetupRise(
			signal ReferenceSignal   : in    std_logic;
			ReferenceSignalName      : in    string;
			signal TriggerSignal     : in    std_logic;
			TriggerSignalName        : in    string;
			ExpectedDelay            : in    time;
			ExpectedDelayName        : in    string;
			signal LastReferenceMove : inout time;
			FullPathName             : in    string;
			CheckEnabled             : in    boolean
		) is
		variable ln : Line;

	begin
		if referenceSignal'Event then
			LastReferenceMove <= now;
		end if;

		if triggerSignal'event and triggerSignal = '1' and (now - LastReferenceMove < expectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (LastReferenceMove /= 0 ns) and checkEnabled then
			write(ln, string'("Error on "));
			write(ln, fullPathName);
			write(ln, string'(": '"));
			write(ln, string'(referenceSignalName));
			write(ln, string'("' to '"));
			write(ln, string'(triggerSignalName));
			write(ln, string'("' Setup violation at: "));
			write(ln, now);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" expected: "));
			write(ln, expectedDelay);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" actual: "));
			write(ln, now - LastReferenceMove);

			writeline(output, ln);

		end if;

	end checkSetupRise;

	-----------------------------------------------------------------
	-- Trigger		__________/----------
	-- Reference		================x====
	-- 			  	  <----->


	procedure checkHoldRise(
			signal ReferenceSignal : in    std_logic;
			ReferenceSignalName    : in    string;
			signal TriggerSignal   : in    std_logic;
			TriggerSignalName      : in    string;
			ExpectedDelay          : in    time;
			ExpectedDelayName      : in    string;
			signal LastTriggerRise : inout time;
			FullPathName           : in    string;
			CheckEnabled           : in    boolean
		) is
		variable ln : Line;
	begin
		if TriggerSignal'event and TriggerSignal = '1' then
			LastTriggerRise <= now;
		end if;
		if ReferenceSignal'event and (now - LastTriggerRise < expectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (LastTriggerRise /= 0 ns) and checkEnabled then
			write(ln, string'("Error on "));
			write(ln, fullPathName);
			write(ln, string'(": '"));
			write(ln, string'(referenceSignalName));
			write(ln, string'("' to '"));
			write(ln, string'(triggerSignalName));
			write(ln, string'("' Hold violation at: "));
			write(ln, now);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" expected: "));
			write(ln, expectedDelay);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" actual: "));
			write(ln, now - LastTriggerRise);

			writeline(output, ln);
		end if;

	end checkHoldRise;

	------------------------------------------------------------------------------
	-- Signal 		____/------\_______/----
	-- 			    <-------------->

	procedure checkPeriod(
			signal TestSignal     : in    std_logic;
			TestSignalName        : in    string;
			expectedDelay         : in    time;
			expectedDelayName     : in    string;
			signal LastSignalRise : inout time;
			fullPathName          : in    string;
			checkEnabled          : in    boolean
		) is
		variable ln : Line;
	begin
		if (TestSignal'event and TestSignal = '1') then
			if (now - lastSignalRise < expectedDelay) and (lastSignalRise /= 0 ns) and (now > 0 ns) and (expectedDelay /= 0 ns) and checkEnabled then
				write(ln, string'("Error on "));
				write(ln, fullPathName);
				write(ln, string'(": '"));
				write(ln, string'(TestSignalName));
				write(ln, string'("' Periode violation at: "));
				write(ln, now);
				write(ln, string'(", "));
				write(ln, string'(expectedDelayName));
				write(ln, string'(" expected: "));
				write(ln, expectedDelay);
				write(ln, string'(", "));
				write(ln, string'(expectedDelayName));
				write(ln, string'(" actual: "));
				write(ln, now - lastSignalRise);

				writeline(output, ln);
			end if;

			LastSignalRise <= now;
		end if;

	end checkPeriod;

	----------------------------------------------------------------------
	-- Signal 		____/---------\____
	-- 			    <--------->


	procedure checkWidth1(
			signal TestSignal     : in    std_logic;
			TestSignalName        : in    string;
			ExpectedDelay         : in    time;
			ExpectedDelayName     : in    string;
			signal LastSignalRise : inout time;
			FullPathName          : in    string;
			CheckEnabled          : in    boolean
		) is
		variable ln : Line;
	begin
		if (TestSignal'event and TestSignal = '1') then
			LastSignalRise <= now;
		end if;

		if (TestSignal'event and TestSignal = '0') and (now - lastSignalRise < expectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (lastSignalRise /= 0 ns) and checkEnabled then
			write(ln, string'("Error on "));
			write(ln, fullPathName);
			write(ln, string'(": '"));
			write(ln, string'(TestSignalName));
			write(ln, string'("' Pulse Width violation at: "));
			write(ln, now);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" expected: "));
			write(ln, expectedDelay);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" actual: "));
			write(ln, now - lastSignalRise);

			writeline(output, ln);
		end if;

	end checkWidth1;

	----------------------------------------------------------------------
	-- Signal 		----\_________/-----
	-- 			    <--------->

	procedure checkWidth0(
			signal TestSignal     : in    std_logic;
			TestSignalName        : in    string;
			ExpectedDelay         : in    time;
			ExpectedDelayName     : in    string;
			signal LastSignalFall : inout time;
			fullPathName          : in    string;
			checkEnabled          : in    boolean
		) is
		variable ln : Line;
	begin
		if (TestSignal'event and TestSignal = '0') then
			lastSignalFall <= now;
		end if;

		if (TestSignal'event and TestSignal = '1') and (now - lastSignalFall < expectedDelay) and (lastSignalFall /= 0 ns) and (now > 0 ns) and (expectedDelay /= 0 ns) and checkEnabled then
			write(ln, string'("Error on "));
			write(ln, fullPathName);
			write(ln, string'(": '"));
			write(ln, string'(TestSignalName));
			write(ln, string'("' Pulse Width violation at: "));
			write(ln, now);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" expected: "));
			write(ln, expectedDelay);
			write(ln, string'(", "));
			write(ln, string'(expectedDelayName));
			write(ln, string'(" actual: "));
			write(ln, now - lastSignalFall);

			writeline(output, ln);
		end if;

	end checkWidth0;
	-------------------------------------------------------------------
	-------------------------------------------------------------------
	-------------------------------------------------------------------
	FUNCTION integer_to_bit_vector(VAL, width : INTEGER) RETURN BIT_VECTOR IS
		VARIABLE result : BIT_VECTOR(width - 1 downto 0) := (OTHERS => '0');
		VARIABLE bits   : INTEGER                        := width;
	BEGIN
		IF (bits > 31) THEN             --  Avoid overflow errors.
			bits := 31;
		ELSE
			ASSERT 2 ** bits > VAL REPORT "Value too big FOR BIT_VECTOR width"
				SEVERITY WARNING;
		END IF;

		FOR i IN 0 TO bits - 1 LOOP
			IF ((val / (2 ** i)) MOD 2 = 1) THEN
				result(i) := '1';
			END IF;

		END LOOP;

		RETURN (result);
	END integer_to_bit_vector;
	PROCEDURE removespace(VARIABLE l : IN line; pos : OUT integer) IS
	BEGIN
		pos := l'low;
		FOR i IN l'low TO l'high LOOP
			CASE l(i) IS
				WHEN ' ' | ht =>
					pos := i + 1;
				WHEN OTHERS =>
					EXIT;
			END CASE;
		END LOOP;
	END;
	PROCEDURE removeline(l : INOUT line; pos : integer) IS
		VARIABLE tmpl : line;
	BEGIN
		tmpl := l;
		l    := NEW string'(tmpl(pos TO tmpl'high));
		deallocate(tmpl);
	END;
	PROCEDURE hexa_to_bit_vector(l : INOUT line; u : in integer; value : OUT bit_vector) IS
		CONSTANT not_digit : integer := -999;
		FUNCTION digit_value(c : character) RETURN integer IS
		BEGIN
			IF (c >= '0') AND (c <= '9') THEN
				RETURN (character'pos(c) - character'pos('0'));
			ELSIF (c >= 'a') AND (c <= 'f') THEN
				RETURN (character'pos(c) - character'pos('a') + 10);
			ELSIF (c >= 'A') AND (c <= 'F') THEN
				RETURN (character'pos(c) - character'pos('A') + 10);
			ELSE
				RETURN not_digit;
			END IF;
		END;
		VARIABLE digit  : bit_vector(4 downto 1);
		VARIABLE digit1 : bit_vector(u downto 1);
		VARIABLE digitx : integer;
		VARIABLE pos    : integer;
		VARIABLE t      : integer := u / 4;
	BEGIN
		removespace(l, pos);
		FOR i IN pos TO l'right LOOP
			digitx := digit_value(l(i));
			EXIT WHEN (digitx = not_digit) OR (digitx >= 16);
			digit := integer_to_bit_vector(digitx, 4);
			if t >= 1 then
				digit1 := digit1(u - 4 downto 1) & digit;
				t      := t - 1;
			else
			end if;
			pos := i + 1;
		END LOOP;
		value := digit1;
		removeline(l, pos);
	END;

	--******************************************---
	--******************************************--

	signal page_status      : std_logic_vector(page_cal(device) - 1 downto 0);
	signal temp_page_status : std_logic;
	signal page             : std_logic_vector(p_address(device) - 1 downto 0);
	signal temp_reg2        : std_logic_vector(7 downto 0);

	signal temp_page : std_logic_vector(p_address(device) - 1 downto 0);

	signal byte : std_logic_vector(b_address(device, binary_page) - 1 downto 0);

	---protecteds/locked status reg-----
	signal prot_status : std_logic_vector(sec_tors(device) downto 0);
	signal sector      : std_logic_vector(s_address(device) - 1 downto 0);

	type buffer1 is array (pagesize_forbuffer(device) - 1 downto 0) of bit_vector(7 downto 0);
	signal tbuffer1 : buffer1;

	type buffer2 is array (pagesize_forbuffer(device) - 1 downto 0) of bit_vector(7 downto 0);
	signal tbuffer2 : buffer2;

	--memory initalization--
	constant N : integer range 1 to 69206016 := memsize(pagesize_forbuffer(device), page_cal(DEVICE));
	constant M : integer                     := 8;

	type memtype is array (N - 1 downto 0) of bit_vector(7 downto 0);
	signal memory : memtype;

	--protection initialization---  
	constant p : integer := sec_tors(device);
	type prot_type is array (p - 1 downto 0) of bit_vector(7 downto 0);
	signal prot_reg : prot_type;

	--lock initialization--
	type lock_type is array (p - 1 downto 0) of bit_vector(7 downto 0);
	signal lock_reg : lock_type;

	--factory security ---
	type factory_type is array (63 downto 0) of bit_vector(7 downto 0);
	signal factory_reg : factory_type;

	--security reg--
	type security_type is array (63 downto 0) of bit_vector(7 downto 0);
	signal security_reg : security_type;
	--in security register 0 to 63 byte one time user programmable
	---64 to 127 byte factory programmable by atmel--


	----------------------op3d------
	signal op3d_tmp_reg     : std_logic_vector(7 downto 0) := "00000000";
	----------------------opc7------
	signal opc7_tmp_reg     : std_logic_vector(7 downto 0) := "00000000";
	----------------------MMPPB1-----------
	signal MMPPB1_temp_page : std_logic_vector(p_address(device) - 1 downto 0);
	signal MMPPB1_page      : std_logic_vector(p_address(device) - 1 downto 0);
	signal MMPPB1_byte      : std_logic_vector(b_address(device, binary_page) - 1 downto 0);
	signal MMPPB1_tmp_reg   : std_logic_vector(7 downto 0) := "00000000";
	signal MMPPB1_tmp_reg1  : std_logic_vector(7 downto 0) := "00000000";
	signal MMPPB1_tmp_reg2  : std_logic_vector(7 downto 0) := "00000000";

	----------------------MMPPB2-----------
	signal MMPPB2_temp_page : std_logic_vector(p_address(device) - 1 downto 0);
	signal MMPPB2_page      : std_logic_vector(p_address(device) - 1 downto 0);
	signal MMPPB2_byte      : std_logic_vector(b_address(device, binary_page) - 1 downto 0);
	signal MMPPB2_tmp_reg1  : std_logic_vector(7 downto 0) := "00000000";
	signal MMPPB2_tmp_reg2  : std_logic_vector(7 downto 0) := "00000000";

	---------------------


	--------------comp page address function implementation---------------
	function comp_page_addr(paddress           : in integer range 1 to 14;
			                signal binary_page : in std_logic;
			                signal page_addr0  : in std_logic_vector(7 downto 0);
			                signal page_addr1  : in std_logic_vector(7 downto 0);
			                man_id             : in std_logic_vector(31 downto 0)
		) return std_logic_vector is
		variable page1 : std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0);
	begin
		case (PADDRESS) is
			--when 14 => 
			--if(binary_page='1') then
			--page := (page_addr0(7 downto 0)) & (page_addr1(7 downto 2));
			--else	  --4 address bytes
			--page := temp_reg2(0) & page_addr0(7 downto 0) & page_addr1(7 downto 2);
			--end if;
			when 13 =>
				--64mb--
				if (MAN_ID = X"1F280000") then
					if (binary_page = '1') then
						page1 := page_addr0(6 downto 0) & page_addr1(7 downto 2);
					else
						page1 := page_addr0(7 downto 0) & page_addr1(7 downto 3);
					end if;
				end if;
				--32 mb--
				if (MAN_ID = X"1F270100") then
					if (binary_page = '1') then
						page1 := page_addr0(5 downto 0) & page_addr1(7 downto 1);
					else
						page1 := page_addr0(6 downto 0) & page_addr1(7 downto 2);
					end if;
				end if;
			when 12 =>
				---16mb----
				if (MAN_ID = X"1F260000") then
					if (binary_page = '1') then
						page1 := page_addr0(4 downto 0) & page_addr1(7 downto 1);
					else
						page1 := page_addr0(5 downto 0) & page_addr1(7 downto 2);
					end if;
				end if;
				--8mb--
				if (MAN_ID = X"1F250000") then
					if (binary_page = '1') then
						page1 := page_addr0(3 downto 0) & page_addr1(7 downto 0);
					else
						page1 := page_addr0(4 downto 0) & page_addr1(7 downto 1);
					end if;
				end if;
			---4 mb---
			when 11 =>
				if (binary_page = '1') then
					page1 := page_addr0(2 downto 0) & page_addr1(7 downto 0);
				else
					page1 := page_addr0(3 downto 0) & page_addr1(7 downto 1);
				end if;
			--2mb---
			when 10 =>
				if (binary_page = '1') then
					page1 := page_addr0(1 downto 0) & page_addr1(7 downto 0);
				else
					page1 := page_addr0(2 downto 0) & page_addr1(7 downto 1);
				end if;
			--1mb---
			when 9 =>
				if (binary_page = '1') then
					page1 := page_addr0(0) & page_addr1(7 downto 0);
				else
					page1 := page_addr0(1 downto 0) & page_addr1(7 downto 1);
				end if;

			when others =>
		end case;

		return page1;
	end comp_page_addr;

	----------------function compute_sector addr-------

	function comp_sector_addr(paddress : in integer range 1 to 14;
			                  page1    : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0)
		--signal sector : in std_logic_vector((S_ADDRESS(device))-1 DOWNTO 0);
		) return std_logic_vector is
		variable sector1 : std_logic_vector((S_ADDRESS(device)) - 1 DOWNTO 0);
	begin
		sector1 := page1(P_ADDRESS(device) - 1 downto P_ADDRESS(device) - S_ADDRESS(device));

		return sector1;
	end comp_sector_addr;

	procedure compute_sector_address(
			paddress      : in  integer range 1 to 14;
			signal page   : in  std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0);
			signal sector : out std_logic_vector((S_ADDRESS(device)) - 1 downto 0)
		) is
	begin
		sector <= page(P_ADDRESS(device) - 1 downto P_ADDRESS(device) - S_ADDRESS(device));

	end compute_sector_address;

	----------------------------
	function comp_byte_addr(baddress           : integer range 1 to 11;
			                signal page_addr1  : in std_logic_vector(7 downto 0);
			                signal byte_addr   : in std_logic_vector(7 downto 0);
			                signal binary_page : in std_logic
		) return std_logic_vector is
		variable byte : std_logic_vector((b_address(device, binary_page)) - 1 DOWNTO 0);
	begin
		report " entered into comp_byte_addr";
		case (baddress) is
			when 11 =>
				byte := page_addr1(2 downto 0) & byte_addr; --b"00000000" ;
			when 10 =>
				byte := page_addr1(1 downto 0) & byte_addr; --b"00000000" ;
			when 9 =>
				byte := page_addr1(0) & byte_addr; --b"00000000" ;
			when others =>
				byte := byte_addr;
		end case;

		return byte;
	end comp_byte_addr;

	procedure compute_address(page               : in  std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0);
			                  page_size          : in  integer range 1 to 1056;
			                  byte               : in  std_logic_vector((b_address(device, binary_page)) - 1 DOWNTO 0);
			                  page_boundary_low  : out integer;
			                  page_boundary_high : out integer;
			                  current_address    : out integer;
			                  mem_no             : out integer;
			                  signal binary_page : in  std_logic
		) is
		variable temp_low : integer;
	begin
		report "entered into compute_address";

		temp_low           := (conv_integer(page) * pagesize(device, binary_page));
		page_boundary_low  := temp_low;
		page_boundary_high := temp_low + (pagesize(device, binary_page) - 1);
		report "entered into byte";
		current_address := temp_low + conv_integer(byte);
		--memno 10 is for memory access---
		mem_no          := 10;

	end compute_address;

	procedure read_out(signal SCK, CSB    : in    std_logic;
			           page_boundary_low  : in    integer;
			           page_boundary_high : in    integer;
			           current_address    : inout integer;
			           mem_no             : in    integer;
			           signal buf1        : in    buffer1;
			           signal buf2        : in    buffer2;
			           signal memory      : in    memtype;
			           --signal temp_reg1 :inout std_logic_vector(7 downto 0);
			           signal so_reg      : out   std_logic;
			           signal so_on1      : out   std_logic
		) is
		variable t_reg : std_logic_vector(7 downto 0);
	begin
		report " Read loop entered ";
		if (mem_no = 1) then
			t_reg := to_stdlogicvector(buf1(current_address));
		elsif (mem_no = 2) then
			t_reg := to_stdlogicvector(buf2(current_address));
		elsif (mem_no = 10) then
			t_reg := to_stdlogicvector(memory(current_address));
		else
		end if;

		read_loop : loop
			for i in 7 downto 0 loop
				wait until (SCK'EVENT and SCK = '0') or (CSB'EVENT and CSB = '1');
				report " entered into for loop of read_out";
				exit read_loop when (CSB = '1');
				wait for Tv;
				SO_reg <= t_reg(i);
				so_on1 <= '1';
			end loop;

			current_address := current_address + 1;
			report "comes out from for loop of read_out--------------------";
			if (current_address > page_boundary_high) then
				current_address := page_boundary_low;
			end if;
			if (mem_no = 1) then
				t_reg := to_stdlogicvector(buf1(current_address));
			elsif (mem_no = 2) then
				t_reg := to_stdlogicvector(buf2(current_address));
			elsif (mem_no = 10) then
				t_reg := to_stdlogicvector(memory(current_address));
			end if;
		end loop;
		wait for Tdis;
		SO_reg <= '0';
		so_on1 <= '0';

		report " Read loop exited";
	end read_out;

	procedure read_out_x(signal CSB, sck       : in  std_logic;
			             signal so_reg, so_on1 : out std_logic
		) is
	begin
		report " Readx loop entered ";
		so_on1 <= '0';
		read_loopx : loop
			wait until (SCK'EVENT and SCK = '0') or (CSB'EVENT and CSB = '1');
			exit read_loopx when (CSB = '1');
			wait for Tv;
			SO_reg <= 'X';
			so_on1 <= '1';
		end loop;
		wait for Tdis;
		SO_reg <= '0';
		so_on1 <= '0';

		report " Readx loop exited";
	end read_out_x;

	procedure read_out_array(signal SCK, CSB    : in  std_logic;
			                 page_size          : in  integer range 1 to 1056;
			                 mem_size           : in  integer range 1 to 69206016;
			                 page_boundary_low  : in  integer;
			                 page_boundary_high : in  integer;
			                 current_address    : in  integer;
			                 signal memory      : in  memtype;
			                 signal so_reg      : out std_logic;
			                 signal so_on1      : out std_logic
		) is
		variable t_reg_array : std_logic_vector(7 downto 0);
		variable temp_high   : integer;
		variable temp_low    : integer;
		variable temp_add    : integer;

	begin
		report " Read_array loop entered ";

		temp_high := page_boundary_high;
		temp_low  := page_boundary_low;
		temp_add  := current_address;

		t_reg_array := to_stdlogicvector(memory(temp_add));

		read_array_loop : loop
			for i in 7 downto 0 loop
				wait until (SCK'EVENT and SCK = '0') or (CSB'EVENT and CSB = '1');
				exit read_array_loop when (CSB = '1');
				wait for Tv;
				SO_reg <= t_reg_array(i);
				so_on1 <= '1';
			end loop;
			report "read_array procedure----------------------------------------------------";
			temp_add := temp_add + 1;
			if (temp_add >= N) then
				temp_add  := 0;         --Note that rollover occurs at end of memory,
				temp_high := pagesize(device, binary_page) - 1; -- and not at the end of the page
				temp_low  := 0;
			end if;

			if (temp_add > temp_high) then -- going to next page
				temp_high := temp_high + pagesize(device, binary_page);
				temp_low  := temp_low + pagesize(device, binary_page);
			end if;
			t_reg_array := to_stdlogicvector(memory(temp_add));
		end loop;
		wait for Tdis;
		SO_reg <= '0';
		so_on1 <= '0';

		report " Read_array loop exited ";
	end read_out_array;

	procedure transfer_to_buffer(
			buf_type          : in    integer;
			page_boundary_low : in    integer;
			signal memory     : in    memtype;
			signal buf1       : inout buffer1;
			signal buf2       : inout buffer2
		) is
	begin
		report " transfer to buffer entered ";
		if (buf_type = 1) then
			for i in 0 to pagesize(device, binary_page) - 1 LOOP
				buf1(i) <= memory(page_boundary_low + i);
			end loop;
		elsif (buf_type = 2) then
			for i in 0 to pagesize(device, binary_page) - 1 loop
				buf2(i) <= memory(page_boundary_low + i);
			end loop;
		else
			report "Int Error 2. This message should never appear";

		end if;
		report " transfer to buffer exited ";
	end transfer_to_buffer;

	procedure compare_with_buffer(buf_type          : in  integer;
			                      page_boundary_low : in  integer;
			                      signal memory     : in  memtype;
			                      signal buf1       : in  buffer1;
			                      signal buf2       : in  buffer2;
			                      signal status     : out std_logic
		) is
		variable tmp1, tmp2 : bit_vector(7 downto 0);
	begin
		report " compare with buf entered ";
		status <= '0';
		if (buf_type = 1) then
			for i in 0 to pagesize(device, binary_page) - 1 loop
				tmp1 := memory(page_boundary_low + i);
				tmp2 := buf1(i);
				for k in 0 to 7 loop
					if (tmp1(k) /= tmp2(k)) then
						status <= '1';
						exit;
					end if;
				end loop;
			end loop;
		elsif (buf_type = 2) then
			for i in 0 to pagesize(device, binary_page) - 1 loop
				tmp1 := memory(page_boundary_low + i);
				tmp2 := buf2(i);
				for k in 0 to 7 loop
					if (tmp1(k) /= tmp2(k)) then
						status <= '1';
						exit;
					end if;
				end loop;
			end loop;
		else
			report "Int error 3. This message should never appear";

		end if;
		report " compare with exited ";
	end compare_with_buffer;

	-----------write_data------------
	procedure write_data(current_address     : inout integer;
			             page_boundary_low   : in    integer;
			             page_boundary_high  : in    integer;
			             signal buf1         : inout buffer1;
			             signal buf2         : inout buffer2;
			             buf_type            : in    integer;
			             signal CSB, SCK, SI : in    std_logic
		) is
		variable buf_temp_reg : std_logic_vector(7 downto 0);
		variable temp         : std_logic := '0';
	begin
		report "first time entering ";

		write_loop : loop
			if (CSB = '0') then
				for i in 7 downto 0 loop
					wait until (SCK'EVENT and SCK = '1') or (CSB'EVENT and CSB = '1');
					exit write_loop when (CSB = '1');
					buf_temp_reg(i) := SI;
				end loop;

				if (buf_type = 1) then
					buf1(current_address) <= To_bitvector(buf_temp_reg, '0');
				elsif (buf_type = 2) then
					buf2(current_address) <= To_bitvector(buf_temp_reg, '0');
				end if;
				current_address := current_address + 1;
				wait for 1 ps;
				if (current_address > page_boundary_high) then
					current_address := page_boundary_low;
					wait for 1 ps;
				end if;
			end if;

		end loop;

		report " loop exited";

	end write_data;

	------------------check_protection-------------	


	function check_protect(
			page1                  : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0);
			page_per_sector        : in integer;
			signal prot_status     : in std_logic_vector(sec_tors(device) downto 0);
			sector                 : in std_logic_vector(s_address(device) - 1 downto 0);
			WPB, soft_prot_enabled : in std_logic
		) return std_logic is
		variable protecteds : std_logic;
	begin
		protecteds := '0';

		if ((WPB = '0') or (soft_prot_enabled = '1')) then
			if (conv_integer(page1) < 8) then
				protecteds := prot_status(0);
			elsif (page1 < PAGE_PER_SECTOR) then
				protecteds := prot_status(1);
			else
				protecteds := prot_status(conv_integer(sector) + 1);
			end if;
		end if;

		return protecteds;
	end check_protect;

	--------------check lock down---------


	function check_lockd(
			page1              : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0);
			page_per_sector    : in integer;
			signal lock_status : in std_logic_vector(sec_tors(device) downto 0);
			sector             : in std_logic_vector(s_address(device) - 1 downto 0)
		) return std_logic is
		variable locked : std_logic;
	begin
		locked := '0';

		if (page1 < 8) then
			locked := lock_status(0);
		elsif (page1 < PAGE_PER_SECTOR) then
			locked := lock_status(1);
		else
			locked := lock_status(conv_integer(sector) + 1);
		end if;
		return locked;
	end check_lockd;

	----------write_to_memory----------


	procedure write_to_memory(buf_type          : in    integer;
			                  page              : in    std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0);
			                  page_size         : in    integer range 1 to 1056;
			                  signal buf1       : in    buffer1;
			                  signal buf2       : in    buffer2;
			                  page_boundary_low : in    integer;
			                  signal memory     : inout memtype
		) is
	begin
		report " write to memory entered ";
		if (buf_type = 1) then
			for i in 0 to page_size - 1 loop
				memory(page_boundary_low + i) <= buf1(i);
			end loop;
		elsif (buf_type = 2) then
			for i in 0 to page_size - 1 loop
				memory(page_boundary_low + i) <= buf2(i);
			end loop;
		end if;

		report " write to memory exited ";
	end write_to_memory;

	procedure erase_page(
			page               : in    std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0);
			page_size          : in    integer range 1 to 1056;
			page_boundary_low  : in    integer;
			signal memory      : inout memtype;
			signal page_status : out   std_logic
		) is
		variable buf1 : buffer1;
		variable buf2 : buffer2;
		variable mem  : memtype;

	begin
		report " erase page entered ";
		for i in 0 to pagesize(device, binary_page) - 1 loop
			memory(page_boundary_low + i) <= (others => '1');
			page_status                   <= '0';
		end loop;
		report " erase page exited ";
	end erase_page;

	----------read_out_reg--------
	procedure read_out_reg(reg_type            : in  integer;
			               add                 : in  integer;
			               high                : in  integer;
			               signal prot_reg     : in  prot_type;
			               signal lock_reg     : in  lock_type;
			               signal security_reg : in  security_type;
			               signal CSB, SCK     : in  std_logic;
			               signal so_reg       : out std_logic;
			               signal so_on1       : out std_logic
		) is
		variable temp_add : integer;
		variable t_reg1   : std_logic_vector(7 downto 0);
	begin
		report " Read out reg  loop entered ";
		temp_add := add;
		if (reg_type = 21) then
			t_reg1 := to_stdlogicvector(prot_reg(temp_add));
		elsif (reg_type = 22) then
			t_reg1 := to_stdlogicvector(lock_reg(temp_add));
		elsif (reg_type = 23) then
			t_reg1 := to_stdlogicvector(security_reg(temp_add));
		end if;

		read_out_reg_loop : loop
			for i in 7 downto 0 loop
				wait until (SCK'EVENT and SCK = '0') or (CSB'EVENT and CSB = '1');
				exit read_out_reg_loop when (CSB = '1');
				wait for Tv;
				so_reg <= t_reg1(i);
				so_on1 <= '1';
			end loop;
			temp_add := temp_add + 1;
			if (temp_add > high) then
				t_reg1 := (others => 'X');
			else
				if (reg_type = 21) then
					t_reg1 := to_stdlogicvector(prot_reg(temp_add));
				elsif (reg_type = 22) then
					t_reg1 := to_stdlogicvector(lock_reg(temp_add));
				elsif (reg_type = 23) then
					if (temp_add < 64) then
						t_reg1 := to_stdlogicvector(security_reg(temp_add));
					else
						t_reg1 := to_stdlogicvector(factory_reg(temp_add - 64));
					end if;
				end if;
			end if;
		end loop;
		wait for Tdis;
		so_reg <= '0';
		so_on1 <= '0';
		report " Read out reg  loop exited ";
	end read_out_reg;

	function getbyte(
			signal IP : in bit_vector(511 downto 0);
			byte_num  : in integer
		) return bit_vector is
		variable temp : bit_vector(7 downto 0);
	begin
		for i in 0 to 7 loop
			report "entering into getbyte";
			temp(i) := IP((byte_num - 1) * 8 + i);
		end loop;
		report "getbyte exited";
		return temp;

	end getbyte;

	--******************************************---
	--******************************************--
	------shared variable declarations-----------

	shared variable buf_temp_reg1      : std_logic_vector(7 downto 0);
	shared variable message            : string(1 to 21);
	shared variable message2           : string(1 to 30);
	shared variable current_address    : integer;
	shared variable page_boundary_low  : integer;
	shared variable page_boundary_high : integer;
	shared variable mem_no             : integer;

	signal temp_prot_status_program : bit_vector(sec_tors(device) - 2 downto 0);
	signal temp_reg1                : std_logic_vector(7 downto 0);

	signal reset_sig       : std_logic                     := '0';
	signal skip            : std_logic                     := '1';
	signal skip_be         : std_logic                     := '0';
	signal skip_end        : std_logic                     := '0';
	signal opcode_temp     : std_logic_vector(7 downto 0)  := "00000000";
	signal page_addr0      : std_logic_vector(7 downto 0)  := "00000000";
	signal page_addr1      : std_logic_vector(7 downto 0)  := "00000000";
	signal byte_addr       : std_logic_vector(7 downto 0)  := "00000000";
	signal t               : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
	signal prot_temp_reg   : std_logic_vector(7 downto 0);
	signal lock_temp_reg   : std_logic_vector(7 downto 0);
	signal rd_data1        : std_logic_vector(7 downto 0);
	signal less_than_60mhz : std_logic                     := '0';

	signal buffer1read : std_logic := '0';

	signal oPC7 : std_logic;

	signal arr_rd_dummybyte  : integer := 0;
	signal buff_rd_dummybyte : integer := 0;

	signal RDPD : std_logic := '0';
	signal EDPD : std_logic := '0';
	signal MMPR : std_logic := '0';

	signal updating_buffer1 : std_logic := '0';
	signal updating_buffer2 : std_logic := '0';
	---------------UPDATING MEMORY-----------
	signal updating_memory  : std_logic := '0';

	signal comparing       : std_logic := '0';
	signal erasing_page    : std_logic := '0';
	signal erasing_block   : std_logic := '0';
	signal erasing_sector  : std_logic := '0';
	signal erasing_chip    : std_logic := '0';
	signal fast_mode       : std_logic := '0';
	signal IntCSb          : std_logic;
	constant valid         : Boolean   := TRUE;
	signal MIR             : std_logic := '0';
	signal SRR             : std_logic := '0';
	signal mem_initialized : std_logic;
	signal deep_power_down : std_logic := '0';
	signal SR              : std_logic := '0';
	signal RDYBSY_reg      : std_logic := '1';

	signal foreground_op_enable : std_logic := '0';
	signal background_op_enable : std_logic := '0';

	signal status_read : std_logic                    := '0';
	signal so_reg      : std_logic                    := '1';
	signal so_on       : std_logic                    := '0';
	signal so_reg1     : std_logic                    := '1';
	signal so_on1      : std_logic                    := '0';
	signal so_reg2     : std_logic                    := '1';
	signal so_on2      : std_logic                    := '0';
	signal so_reg3     : std_logic                    := '1';
	signal so_on3      : std_logic                    := '0';
	signal status      : std_logic_vector(7 downto 0) := ('1' & '0' & Device_sel3(DEVICE) & Device_sel2(DEVICE) & Device_sel1(DEVICE) & '1' & '0' & '0');

	-----------status signal-------------

	signal status_B1C_s6 : std_logic;
	signal status_B2C_s6 : std_logic;

	---------
	signal lock_status : std_logic_vector(sec_tors(device) downto 0);

--**************** begin of Architecture **************---


begin

	--comparing the opcodes--
	process(SCK, SI, CSB)
	begin
		if (CSB = '1') then
			t        <= "00000000000000000000000000000000";
			rd_data1 <= "00000000";
		elsif (SCK = '1' and SCK'event) then		
			t(0)        <= '1';
			t(1)        <= t(0);
			t(2)        <= t(1);
			t(3)        <= t(2);
			t(4)        <= t(3);
			t(5)        <= t(4);
			t(6)        <= t(5);
			t(7)        <= t(6);        -- t(6) == 1 and t(7) ==0 opcode
			t(8)        <= t(7);
			t(9)        <= t(8);
			t(10)       <= t(9);
			t(11)       <= t(10);
			t(12)       <= t(11);
			t(13)       <= t(12);
			t(14)       <= t(13);
			t(15)       <= t(14);       -- t(14) == 1 and t(15) ==0 page address 
			t(16)       <= t(15);
			t(17)       <= t(16);
			t(18)       <= t(17);
			t(19)       <= t(18);
			t(20)       <= t(19);
			t(21)       <= t(20);
			t(22)       <= t(21);
			t(23)       <= t(22);       -- t(22) == 1 and t(23) ==0 page address 
			t(24)       <= t(23);
			t(25)       <= t(24);
			t(26)       <= t(25);
			t(27)       <= t(26);
			t(28)       <= t(27);
			t(29)       <= t(28);
			t(30)       <= t(29);
			t(31)       <= t(30);       -- t(30) == 1 and t(31) == 0  byte address 
			rd_data1(0) <= SI;
			rd_data1(1) <= rd_data1(0);
			rd_data1(2) <= rd_data1(1);
			rd_data1(3) <= rd_data1(2);
			rd_data1(4) <= rd_data1(3);
			rd_data1(5) <= rd_data1(4);
			rd_data1(6) <= rd_data1(5);
			rd_data1(7) <= rd_data1(6);

		end if;
	end process;

	opcode_temp <= rd_data1(6) & rd_data1(5) & rd_data1(4) & rd_data1(3) & rd_data1(2) & rd_data1(1) & rd_data1(0) & SI;
	process(SCK, opcode_temp, t)
	begin
		if (CSB = '1') then
			page_addr0 <= "00000000";
			page_addr1 <= "00000000";
			byte_addr  <= "00000000";

		elsif ((SCK = '1' and SCK'event)) then
			if (t(14) = '1' and t(15) = '0') then
				page_addr0 <= opcode_temp;
			end if;
			if (t(22) = '1' and t(23) = '0') then
				page_addr1 <= opcode_temp;
			end if;
			if (t(30) = '1' and t(31) = '0') then
				byte_addr <= opcode_temp;
			end if;
		end if;
	end process;

	process(SCK, opcode_temp, t)
	begin
		if (CSB = '1') then
			skip              <= '1';
			arr_rd_dummybyte  <= 0;     --not used in their code
			buff_rd_dummybyte <= 0;
			MMPR              <= '0';
			MMCAR             <= '0';
			EDPD              <= '0';
			buffer1read       <= '0';   --buffer1read legacy command
			buffer2read       <= '0';   --buffer 2 read for low frequency
			MMPTB1T           <= '0';   --Main Memory Page To Buffer 1 Transfer
			MMPTB2T           <= '0';   --Main Memory Page To Buffer 2 Transfer
			MMPTB1C           <= '0';   --Main Memory Page To Buffer 1 Compare
			MMPTB2C           <= '0';   --Main Memory Page To Buffer 2 Compare
			B1W               <= '0';   -- Buffer 1 Write
			B2W               <= '0';
			B1TMMPPWBIE       <= '0';   --Buffer 1 To Main Memory Page Prog With Built-In Erase
			fast_mode         <= '0';
			B2TMMPPWBIE       <= '0';   --Buffer 2 To Main Memory Page Prog With Built-In Erase
			B1TMMPPWOBIE      <= '0';   --Buffer 1 To Main Memory Page Prog Without Built-In Erase
			B2TMMPPWOBIE      <= '0';   --Buffer 2 To Main Memory Page Prog Without Built-In Erase
			PE                <= '0';   -- Page Erase
			BE                <= '0';   -- Block Erase
			SE                <= '0';   -- Sector Erase
			oPC7              <= '0';   -- 4-byte command starting with C7
			MMPPB1            <= '0';   -- Main Memory Page Prog. Through Buffer 1
			MMPPB2            <= '0';   -- Main Memory Page Prog. Through Buffer 2
			APRB1             <= '0';   -- Auto Page Rewrite Through Buffer 1
			APRB2             <= '0';   -- Auto Page Rewrite Through Buffer 2
			SR                <= '0';   -- Status Register Read
			MIR               <= '0';   -- Manufecturing ID Read
			oP3D              <= '0';   -- 4-Byte Opcode Starting From 3d
			PRR               <= '0';   -- Protection Register Read
			LRR               <= '0';   -- Lock_down Register Read
			SRR               <= '0';   -- Security Register Read
			OP9B              <= '0';   -- 4-Byte Opcode Starting From 9B
			RDPD              <= '0';
		elsif (SCK = '1' and SCK'event) then
			if (t(6) = '1' and t(7) = '0') then				
				if (foreground_op_enable = '0') then
					message := "opcode is not allowed";
				elsif (deep_power_down = '1') then
					if (opcode_temp = X"AB") then
						RDPD <= '1';
					else
						message := "opcode is not allowed";
					end if;
				else
					for i in 0 to 7 loop
						report "OPCODE = " & std_logic'image(opcode_temp(i)) severity note;	
					end loop;
					
					case opcode_temp is
						when X"D2" =>
							if (RDYBSY_reg = '1') then
								skip             <= '0';
								arr_rd_dummybyte <= 4;
								MMPR             <= '1';
							end if;

						when X"52" =>
							if (RDYBSY_reg = '1') then
								skip             <= '0';
								arr_rd_dummybyte <= 4;
								MMPR             <= '1';
							end if;

						when X"03" =>
							if (RDYBSY_reg = '1') then
								skip             <= '0';
								arr_rd_dummybyte <= 0;
								MMCAR            <= '1';
							end if;
						when X"0B" =>
							if (RDYBSY_reg = '1') then
								skip             <= '0';
								arr_rd_dummybyte <= 1;
								MMCAR            <= '1';
							end if;
						when X"E8" =>
							if (RDYBSY_reg = '1') then
								skip             <= '0';
								arr_rd_dummybyte <= 4;
								MMCAR            <= '1';
							end if;
						when X"68" =>
							if (RDYBSY_reg = '1') then
								skip             <= '0';
								arr_rd_dummybyte <= 4;
								MMCAR            <= '1';
							end if;
						when X"54" =>
							skip             <= '0';
							arr_rd_dummybyte <= 0;
							buffer1read      <= '1'; --buffer1read legacy command
						when X"D1" =>
							buff_rd_dummybyte <= 0;
							skip              <= '0';
							buffer1read       <= '1'; --buffer1read with low frequency 
						when X"D4" =>
							skip              <= '0';
							buff_rd_dummybyte <= 1;
							buffer1read       <= '1';
						when X"56" =>
							buffer2read <= '1';
						when X"D3" =>
							skip              <= '0';
							buffer2read       <= '1'; --buffer 2 read for low frequency
							buff_rd_dummybyte <= 0;
						when X"D6" =>
							skip              <= '0';
							buff_rd_dummybyte <= 1;
							buffer2read       <= '1';
						when X"53" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								MMPTB1T <= '1'; --Main Memory Page To Buffer 1 Transfer
							end if;
						when X"55" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								MMPTB2T <= '1'; --Main Memory Page To Buffer 2 Transfer
							end if;
						when X"60" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								MMPTB1C <= '1'; --Main Memory Page To Buffer 1 Compare
							end if;
						when X"61" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								MMPTB2C <= '1'; --Main Memory Page To Buffer 2 Compare
							end if;
						when X"84" =>
							B1W <= '1'; -- Buffer 1 Write
						when X"87" =>
							B2W <= '1'; -- Buffer 2 Write
						when X"83" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								B1TMMPPWBIE <= '1'; --Buffer 1 To Main Memory Page Prog With Built-In Erase
							end if;
						when X"93" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								fast_mode   <= '1';
								B1TMMPPWBIE <= '1'; --Buffer 1 To Main Memory Page Prog With Built-In Erase
							end if;     -- t(14) == 1 and t(15) ==0 page address 
						when X"86" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								B2TMMPPWBIE <= '1'; -- t(14) == 1 and t(15) ==0 page address --Buffer 2 To
							-- Main Memory Page Prog With Built-In Erase
							end if;
						when X"96" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								fast_mode   <= '1'; -- t(14) == 1 and t(15) ==0 page address 
								B2TMMPPWBIE <= '1'; --Buffer 2 To Main Memory Page Prog With Built-In Erase
							end if;

						when X"88" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								B1TMMPPWOBIE <= '1'; --- t(14) == 1 and t(15) ==0 page address -Buffer 1 To 
							--Main Memory Page Prog Without Built-In Erase
							end if;
						when X"98" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then -- t(14) == 1 and t(15) ==0 page address hen 
								message := "opcode is not allowed";
							else
								fast_mode    <= '1';
								B1TMMPPWOBIE <= '1'; --Buffer 1 To Main Memory Page Prog Without Built-In Erase
							-- t(14) == 1 and t(15) ==0 page address              -- not in document
							end if;
						when X"89" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								fast_mode    <= '1';
								B2TMMPPWOBIE <= '1'; --Buffer 2 To Main Memory Page Prog Without Built-In Erase
							end if;
						when X"99" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								B2TMMPPWOBIE <= '1'; --Buffer 2 To Main Memory Page Prog Without Built-In Erase
							-- not in document
							end if;
						when X"81" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								PE <= '1'; -- Page Erase
							end if;
						when X"50" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								BE <= '1'; -- Block Erase
							end if;
						when X"7C" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								SE <= '1'; -- Sector Erase
							end if;
						when X"C7" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								oPC7 <= '1'; -- 4-byte command starting with C7
							end if;
						when X"82" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								MMPPB1 <= '1'; -- Main Memory Page Prog. Through Buffer 1
							end if;
						when X"92" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								fast_mode <= '1';
								MMPPB1    <= '1'; -- Main Memory Page Prog. Through Buffer 1

							end if;
						when X"85" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								MMPPB2 <= '1'; -- Main Memory Page Prog. Through Buffer 2
							end if;
						when X"95" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								fast_mode <= '1';
								MMPPB2    <= '1'; -- Main Memory Page Prog. Through Buffer 2
							end if;
						when X"58" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								APRB1 <= '1'; -- Auto Page Rewrite Through Buffer 1
							end if;
						when X"59" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							elsif (RDYBSY_reg = '0') then
								message := "opcode is not allowed";
							else
								APRB2 <= '1'; -- Auto Page Rewrite Through Buffer 2
							end if;
						when X"57" =>							
							SR <= '1';  -- Status Register Read

						when X"D7" =>
							skip <= '0';
							SR   <= '1'; -- Status Register Read
						when X"9F" =>
							report "IDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" severity note;
							skip <= '0';
							MIR  <= '1'; -- Manufecturing ID Read
						when X"3D" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							else
								oP3D <= '1'; -- 4-Byte Opcode Starting From 3d
							end if;
						when X"32" =>
							if (RDYBSY_reg = '1') then
								PRR <= '1'; -- Protection Register Read
							end if;
						when X"35" =>
							if (RDYBSY_reg = '1') then
								LRR <= '1'; -- Lock_down Register Read
							end if;
						when X"77" =>
							if (RDYBSY_reg = '1') then
								SRR <= '1'; -- Security Register Read
							end if;
						when X"9B" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							else
								oP9B <= '1'; -- 4-Byte Opcode Starting From 9B
							end if;
						when X"B9" =>
							if (background_op_enable = '0') then
								message := "opcode is not allowed";
							else
								EDPD <= '1'; -- enable deep power down 
							end if;
						when others =>
							message := "Unrecognized opcode  ";
					end case;

				end if;

			end if;

		end if;
	end process;

	process(SCK, CSB)
	begin
		if (CSB = '0' and CSB'event) then
			if (SCK = '0') then
				skip_be <= '1';
			else
				skip_be <= '0';
			end if;
		end if;
	end process;

	skip_end <= skip_be and skip;

	background_op_enable <= '1' after tPUW;

	reset_sig <= '0', '1' after 1 ns;

	process
		variable inbuf  : line;
		variable outbuf : line;
		--file LOAD_FILE1 : text open read_mode is "./memory.txt";
		file LOAD_FILE1 : text open read_mode is flashmemory;
		file OUT_FILE : text open write_mode is "./memory_out.txt";
		variable numword  : integer := 0;
		variable word     : string(1 to 8);
		variable mem      : memtype;
		variable i        : integer;
		variable value    : bit_vector(7 downto 0);
		----------
		variable inbuf1   : line;
		--file LOAD_FILE2 : text open read_mode is "protection.txt";
		--file LOAD_FILE2 : text open read_mode is protection;
		variable numword1 : integer := 0;
		variable value1   : bit_vector(7 downto 0);
		variable protect  : prot_type;

		variable jerase    : integer;
		variable temp_prot : bit_vector(sec_tors(device) downto 0);
		---------------
		variable inbuf2    : line;
		variable outbuf12  : line;
		--file LOAD_FILE3 : text open read_mode is "lockdown.txt";
		--file LOAD_FILE3 : text open read_mode is lockdown;
		variable numword2  : integer := 0;
		variable value2    : bit_vector(7 downto 0);
		---------------------

		variable inbuf3   : line;
		--file LOAD_FILE4 : text open read_mode is "factory.txt";
		--file LOAD_FILE4 : text open read_mode is factory;
		variable numword3 : integer := 0;
		variable value3   : bit_vector(7 downto 0);
		------------------

		variable locked          : std_logic := '0';
		variable protecteds      : std_logic := '0';
		variable MMPPB1_mem_page : std_logic_vector(p_address(device) - 1 downto 0);
		variable MMPPB1_buf_page : std_logic_vector(p_address(device) - 1 downto 0);
		variable MMPPB2_mem_page : std_logic_vector(p_address(device) - 1 downto 0);
		variable MMPPB2_buf_page : std_logic_vector(p_address(device) - 1 downto 0);
		variable temp_lock       : bit_vector(sec_tors(device) downto 0);
		variable temp_lock_reg   : lock_type;

	begin
		if (foreground_op_enable = '0') then ---- Enable foreground op_codes
			wait on reset_sig;
			report " initialization";
			wait for 1 ps;
			for i in 0 to (memsize(pagesize(device, binary_page), page_cal(device)) - 1) loop
				memory(i) <= (others => '1');
			end loop;
			mem_initialized <= '0';

			wait for 1 ps;

			while not ENDFILE(LOAD_FILE1) loop
				report " memory initialization";
				READLINE(LOAD_FILE1, inbuf);
				hexa_to_bit_vector(inbuf, 8, value);
				memory(numword) <= value;
				WRITE(outbuf, memory(numword));
				WRITELINE(OUT_FILE, outbuf);
				numword := numword + 1;
				if (numword = (N - 1)) then
					exit;
				end if;
				mem_initialized <= '1';
			end loop;

			wait for 1 ps;

			if (mem_initialized = '1') then
				for j in 0 to page_cal(device) - 1 loop
					page_status(j) <= '1'; -- memory was initialized, so, Pages are Not Erased.
				end loop;
			else
				for j in 0 to page_cal(device) - 1 loop
					page_status(j) <= '0';
				end loop;

			end if;

			wait for 1 ps;
			------------initialization of protection reg-------------
			--while not ENDFILE(LOAD_FILE2) loop
			--report " protection reg initialization";  
			--READLINE(LOAD_FILE2,inbuf1);
			--hexa_to_bit_vector(inbuf1, 8, value1);
			--prot_reg(numword1) <= value1;
			--numword1 := numword1 + 1;
			--if(numword1 > (p-1)) then
			--exit;
			--end if;
			--end loop;


			for i in 0 to SEC_TORS(device) - 1 loop
				report "protection intialization";
				prot_reg(i) <= getbyte(protection, i + 1);
				report "lockdown initialization";
				lock_reg(i) <= getbyte(lockdown, i + 1);
			end loop;

			wait for 1 ps;
			prot_temp_reg <= To_stdlogicvector(prot_reg(0));

			prot_status(0) <= prot_temp_reg(7) and prot_temp_reg(6);
			prot_status(1) <= prot_temp_reg(5) and prot_temp_reg(4);
			for j in 1 to SEC_TORS(device) - 1 loop
				temp_prot(j + 1) := prot_reg(j)(0) and prot_reg(j)(1) and prot_reg(j)(2) and prot_reg(j)(3) and prot_reg(j)(4) and prot_reg(j)(5) and prot_reg(j)(6) and prot_reg(j)(7);
			end loop;

			prot_status <= To_stdlogicvector(temp_prot);

			wait for 10 ps;
			-------------initialization of lock reg-----------

			--while not ENDFILE(LOAD_FILE3) loop
			--report " lock reg initialization";  
			--READLINE(LOAD_FILE3,inbuf2);
			--hexa_to_bit_vector(inbuf2, 8, value2);
			--lock_reg(numword2) <= value2;
			--numword2 := numword2 + 1;
			--if(numword2 > (p-1)) then
			--exit;
			--end if;
			--end loop;


			wait for 1 ps;
			lock_temp_reg  <= To_stdlogicvector(lock_reg(0));
			lock_status(0) <= lock_temp_reg(7) and lock_temp_reg(6);
			lock_status(1) <= lock_temp_reg(5) and lock_temp_reg(4);
			for j in 1 to SEC_TORS(device) - 1 loop
				temp_lock(j + 1) := lock_reg(j)(0) and lock_reg(j)(1) and lock_reg(j)(2) and lock_reg(j)(3) and lock_reg(j)(4) and lock_reg(j)(5) and lock_reg(j)(6) and lock_reg(j)(7);
			end loop;

			lock_status <= To_stdlogicvector(temp_lock);
			---------------initialization of factory reg------------

			wait for 1 ps;
			--while not ENDFILE(LOAD_FILE4) loop
			--report " factory initialization";  
			--READLINE(LOAD_FILE4,inbuf3);
			--hexa_to_bit_vector(inbuf3, 8, value3);
			--factory_reg(numword3) <= value3;
			--numword3 := numword3 + 1;
			--if(numword3 > 64) then
			--exit;
			--end if;
			--end loop;

			for j in 0 to 63 loop
				factory_reg(j)  <= getbyte(factory, j + 1);
				security_reg(j) <= getbyte(security, j + 1);
				wait for 1 ps;
				security_flag <= '0';
				if (security_reg(j) /= X"FF") then
					security_flag <= '1';
				end if;
			end loop;

			wait for 1 ps;
			--**************************
			wait for tVCSL;
			foreground_op_enable <= '1'; ---- Enable foreground op_codes
			report " forground enable";

		end if;
		--**************************

		wait on t(31);
		report " t31 asserted";

		if (MMPR = '1' and t(31) = '1') then
			report "entered into MMPR ";
			message := "opcodeFis not allowed";
			if (Rapid_interface = false and fsck > 50) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type . Main Memory Page Read is not allowed";
			end if;
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high,
				current_address, mem_no, binary_page);
			-- pass by 32 cycles  or 4 bytes in the case of serial interface
			wait for (Twl + Twl) * 32;
			if (Rapid_interface = false and fsck > 50) then
				read_out_x(CSB, SCK, so_reg, so_on);
			else
				read_out(SCK, CSB, page_boundary_low, page_boundary_high, current_address, mem_no, tbuffer1,
					     tbuffer2, memory, so_reg, so_on);
			end if;

			report "MMPR is exited ";
		elsif (MMCAR = '1' and t(31) = '1') then
			report "entered into MMCAR ";

			if ((Rapid_interface = false) and (fSCK > 50) and (arr_rd_dummybyte /= 0)) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type . Main Memory Page Read is not allowed";

			end if;
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high,
				current_address, mem_no, binary_page);

			if (((arr_rd_dummybyte = 0) and (fSCK >= 20)) or ((Rapid_interface = false) and (fSCK > 50) and (arr_rd_dummybyte /= 0))) then
				read_out_x(CSB, SCK, so_reg, so_on);
			elsif (arr_rd_dummybyte = 1) then
				wait for (Twl + Twh) * 8;
				read_out_array(SCK, CSB, pagesize(device, binary_page), memsize(pagesize(device, binary_page), page_cal(device)), page_boundary_low,
					page_boundary_high, current_address, memory, so_reg, so_on);

			else
				wait for (Twl + Twh) * 32;
				read_out_array(SCK, CSB, pagesize(device, binary_page), memsize(pagesize(device, binary_page), page_cal(device)), page_boundary_low,
					page_boundary_high, current_address, memory, so_reg, so_on);
			end if;

			report "MMCAR is exited ";

		elsif (buffer1read = '1' and t(31) = '1') then
			report "entered into buffer1read";
			if ((Rapid_interface = false) and (fSCK > 50) and (buff_rd_dummybyte /= 0)) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type . Buffer1 Read is not allowed";
			end if;
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			--if(buff_rd_dummybyte = 0 and less_than_33mhz ='0')then
			if (((buff_rd_dummybyte = 0) and (fSCK >= 20)) or ((Rapid_interface = false) and (fSCK > 50) and (buff_rd_dummybyte /= 0))) then
				read_out_x(CSB, SCK, so_reg, so_on);
			else
				-- pass by 8 cycles or one serial byte
				wait for (Twl + Twh) * 8;
				read_out(SCK, CSB, page_boundary_low, page_boundary_high, current_address, 1,
					     tbuffer1, tbuffer2, memory, so_reg, so_on);
			end if;
			report "buffer1read  exited";

		elsif (buffer2read = '1' and t(31) = '1') then
			report "entered into buffer2read";
			if ((Rapid_interface = false) and (fSCK > 50) and (buff_rd_dummybyte /= 0)) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type . Buffer1 Read is not allowed";
			end if;
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			--if(buff_rd_dummybyte = 0 and less_than_33mhz ='0')then
			if (((buff_rd_dummybyte = 0) and (fSCK >= 20)) or ((Rapid_interface = false) and (fSCK > 50) and (buff_rd_dummybyte /= 0))) then
				read_out_x(CSB, SCK, so_reg, so_on);
			else
				-- pass by 8 cycles
				wait for (Twl + Twh) * 8;
				read_out(SCK, CSB, page_boundary_low, page_boundary_high, current_address, 2, tbuffer1,
					     tbuffer2, memory, so_reg, so_on);
			end if;
			report "buffer2read  exited";

		elsif (MMPTB1T = '1' and t(31) = '1') then
			report " entered into MMPTB1T";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			wait until CSB'event and CSB = '1';
			RDYBSY_reg <= '0';          --device is busy
			status(7)  <= '0';
			transfer_to_buffer(1, page_boundary_low, memory, tbuffer1, tbuffer2);
			updating_buffer1 <= '1';

			wait for Txfr;
			RDYBSY_reg       <= '1';    -- device is now ready
			status(7)        <= '1';
			updating_buffer1 <= '0';

			report " MMPTB1T exited";

		elsif (MMPTB2T = '1' and t(31) = '1') then
			report " entered into MMPTB2T";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			wait until CSB'event and CSB = '1';
			RDYBSY_reg <= '0';          --device is busy
			status(7)  <= '0';
			transfer_to_buffer(2, page_boundary_low, memory, tbuffer1, tbuffer2);
			updating_buffer2 <= '1';

			wait for Txfr;
			RDYBSY_reg       <= '1';    -- after tXFR ; -- device is now ready
			status(7)        <= '1';
			updating_buffer2 <= '0';

			report " MMPTB2T exited";

		elsif (MMPTB1C = '1' and t(31) = '1') then
			report " entered in to MMPTB1C";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			wait until CSB'event and CSB = '1';
			RDYBSY_reg <= '0';          --device is busy
			status(7)  <= '0';
			compare_with_buffer(1, page_boundary_low, memory, tbuffer1, tbuffer2, status_B1C_s6);
			comparing <= '1';

			wait for tXFR;
			RDYBSY_reg <= '1';          -- device is now ready
			status(7)  <= '1';
			status(6)  <= status_B1C_s6;
			comparing  <= '0';
			report " MMPTB1C is exited";

		elsif (MMPTB2C = '1') then
			report " entered in to MMPTB2C";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			wait until CSB'event and CSB = '1';
			RDYBSY_reg <= '0';          --device is busy
			status(7)  <= '0';
			compare_with_buffer(2, page_boundary_low, memory, tbuffer1, tbuffer2, status_B2C_s6);
			comparing <= '1';

			wait for tXFR;
			RDYBSY_reg <= '1';          -- device is now ready
			status(7)  <= '1';
			status(6)  <= status_B2C_s6;
			comparing  <= '0';
			report " MMPTB2C is exited";

		elsif (B1W = '1' and t(31) = '1') then
			report "B1write";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 1, CSB, sck, SI);
			report "B1write end";

		elsif (B2W = '1' and t(31) = '1') then
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);
			report "B2write";
			write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 2, CSB, sck, SI);

		elsif (B1TMMPPWBIE = '1' and t(31) = '1') then
			report "B1TMMPPWBIE";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			locked := check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page,
							page_addr0, page_addr1, manid(device))));
			protecteds := check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
							binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled);

			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
							binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
								binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then
					wait until CSB = '1';
					RDYBSY_reg <= '0';  -- device is busy
					status(7)  <= '0';
					write_to_memory(1, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory);

					page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
								page_addr0, page_addr1, manid(device)))) <= '1';

					message2        := "weCan write page is not locked";
					updating_memory <= '1';

					wait for tEP;
					RDYBSY_reg      <= '1'; -- device is now ready
					status(7)       <= '1';
					updating_memory <= '0';

				else
					wait until CSB = '1';
					message2 := "Cannot write page is protecteds";
				end if;

			else
				wait until CSB = '1';
				message2 := " Cannot write page is Locked  ";
			end if;

		elsif (B2TMMPPWBIE = '1' and t(31) = '1') then
			report "B2TMMPPWBIE";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high,
				current_address, mem_no, binary_page);

			locked := check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page,
							page_addr0, page_addr1, manid(device))));

			protecteds := check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
							binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled);

			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
							binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
								binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then
					wait until CSB'event and CSB = '1';
					RDYBSY_reg <= '0';  -- device is busy
					status(7)  <= '0';
					write_to_memory(2, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory);

					page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
								page_addr0, page_addr1, manid(device)))) <= '1';
					updating_memory                                      <= '1';

					wait for tEP;
					RDYBSY_reg      <= '1'; -- device is now ready
					status(7)       <= '1';
					message2        := "weCan write page is not locked";
					updating_memory <= '0';
				else
					wait until CSB'event and CSB = '1';
					message2 := " Cannot write page isprotecteds";
				end if;
			else
				wait until CSB'event and CSB = '1';
				message2 := " Cannot write page is Locked  ";
			end if;

		elsif (B1TMMPPWOBIE = '1' and t(31) = '1') then
			report "B1TMMPPW0BIE";

			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
				comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high,
				current_address, mem_no, binary_page);

			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status,
					comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0,
							page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), prot_status,
						comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))),
						WPB, soft_prot_enabled) = '0') then
					wait until CSB'event and CSB = '1';
					if (page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0,
									page_addr1, manid(device)))) = '0') then --page is already erased
						RDYBSY_reg      <= '0'; --device is busy
						status(7)       <= '0';
						updating_memory <= '1';
						write_to_memory(1, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
							pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory);

						page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
									page_addr0, page_addr1, manid(device)))) <= '1';

						if (fast_mode = '0') then
							wait for tP;
							RDYBSY_reg      <= '1';
							status(7)       <= '1';
							updating_memory <= '0';
						else
							wait for tFP;
							RDYBSY_reg      <= '1';
							status(7)       <= '1';
							updating_memory <= '0';
						end if;

					else
						message := "TryingtowriteintoPage";
					end if;

				else
					wait until CSB'event and CSB = '1';
					message2 := " Cannot write page isprotecteds";
				end if;

			else
				wait until CSB'event and CSB = '1';
				message2 := " Cannot write page is Locked  ";
			end if;
			report "B1TMMPPW0BIE is exited";

		elsif (B2TMMPPWOBIE = '1' and t(31) = '1') then
			report " entered into B2TMMPPW0BIE";

			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
				pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high,
				current_address, mem_no, binary_page);

			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status,
					comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0,
							page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), prot_status,
						comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))),
						WPB, soft_prot_enabled) = '0') then
					wait until CSB'event and CSB = '1';
					if (page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0,
									page_addr1, manid(device)))) = '0') then --page is already erased
						RDYBSY_reg      <= '0'; --device is busy
						status(7)       <= '0';
						updating_memory <= '1';
						write_to_memory(2, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
							pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory);

						page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
									page_addr0, page_addr1, manid(device)))) <= '1';

						if (fast_mode = '0') then
							wait for tP;
							RDYBSY_reg      <= '1';
							status(7)       <= '1';
							updating_memory <= '0';
						else
							wait for tFP;
							RDYBSY_reg      <= '1';
							status(7)       <= '1';
							updating_memory <= '0';
						end if;

					else
						message := "TryingtowriteintoPage";
					end if;

				else
					wait until CSB'event and CSB = '1';
					message2 := " Cannot write page isprotecteds";
				end if;

			else
				wait until CSB'event and CSB = '1';
				message2 := " Cannot write page is Locked  ";
			end if;
			report "B2TMMPPW0BIE is exited";

		elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"A9") then
			report "entered into enable sector protection ";
			SPE <= '1';
			wait until CSB'event and CSB = '1';
			soft_prot_enabled <= '1';
			status(1)         <= '1';
			SPE               <= '0';
			report "enable sector protection  is exited";

		elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"9A") then
			report "entered into disable sector protection ";
			SPD <= '1';
			wait until CSB'event and CSB = '1';
			if (WPB = '1') then
				soft_prot_enabled <= '0';
				status(1)         <= '0';
			end if;
			SPD <= '0';

		elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"CF") then
			report "entered into erase sector protection register  PRE";
			PRE <= '1';
			wait until CSB'event and CSB = '1';
			RDYBSY_reg     <= '0';      --device is busy
			status(7)      <= '0';
			prot_reg(0)    <= (others => '1');
			prot_status(0) <= '1';
			prot_status(1) <= '1';
			wait for 1 ps;
			for j in 1 to sec_tors(device) - 1 loop
				prot_reg(j)        <= (others => '1');
				prot_status(j + 1) <= '1';
			end loop;

			wait for Tpe;
			RDYBSY_reg <= '1';
			status(7)  <= '1';
			PRE        <= '0';

		elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"FC") then
			report "program sector protection register PRP ";
			report "entered into PRP ";
			PRP                <= '1';
			current_address    := 0;
			page_boundary_low  := 0;
			page_boundary_high := sec_tors(device);
			write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 1, CSB, sck, SI);

			RDYBSY_reg <= '0';          --device is busy
			status(7)  <= '0';
			wait for 1 ps;
			for j in 0 to sec_tors(device) - 1 loop
				prot_reg(j) <= (prot_reg(j) and tbuffer1(j));
			end loop;
			wait for 1 ps;
			temp_reg1 <= To_stdlogicvector(prot_reg(0));
			wait for 1 ps;

			for j in 0 to sec_tors(device) - 2 loop
				temp_prot_status_program(j) <= prot_reg(j)(0) and prot_reg(j)(1) and prot_reg(j)(2) and prot_reg(j)(3) and prot_reg(j)(4) and prot_reg(j)(5) and prot_reg(j)(6) and prot_reg(j)(7);
			end loop;
			wait for 1 ps;

			prot_status <= (To_stdlogicvector(temp_prot_status_program)) & (temp_reg1(5) and temp_reg1(4)) & (temp_reg1(7) and temp_reg1(6));
			wait for Tp;
			RDYBSY_reg <= '1';          -- device is now ready
			status(7)  <= '1';
			wait for 1 ps;
			PRP <= '0';
			report "PRP is exited ";

		elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"30") then
			report "entered into program sector lockdown register LRP ";
			LRP <= '1';
			wait until CSB'event and CSB = '1';
			RDYBSY_reg <= '0';          -- device is busy
			status(7)  <= '0';

			if (conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))) < 8) then
				case (lock_status(1)) is
					when '0'    => lock_reg(0) <= X"C0"; -- Sector 0a locked, 0b unlocked
					when '1'    => lock_reg(0) <= X"F0"; -- Sectors 0a, 0b locked
					when others => message2 := "Thismessage shouldnever appear";
				end case;
				lock_status(0) <= '1';
			elsif (conv_integer(page) < PAGEPER_SECTOR(device)) then
				case (lock_status(0)) is
					when '0'    => lock_reg(0) <= X"30"; --Sector 0a unlocked, 0b locked
					when '1'    => lock_reg(0) <= X"F0"; -- Sectors 0a, 0b locked
					when others => message2 := "Thismessage shouldnever appear";
				end case;
				lock_status(1) <= '1';
			else
				lock_reg(sec_tors(device) - 1) <= (others => '1');
				lock_status(sec_tors(device))  <= '1';
			end if;
			wait for Tp;
			RDYBSY_reg <= '1';          -- device is now ready
			status(7)  <= '1';
			LRP        <= '0';
			report "LRP is exited ";

		elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"80" and byte_addr = X"A6") then
			report "entered binary page setup";
			BPS <= '1';
			wait until CSB'event and CSB = '1';
			RDYBSY_reg  <= '0';         -- device is busy
			status(7)   <= '0';
			binary_page <= '1';

			wait for Tp;
			RDYBSY_reg <= '1';          --device is now ready
			status(7)  <= '1';
			status(0)  <= '1';
			BPS        <= '0';
			report "binary page setup exited";

		elsif (MMPPB1 = '1' and t(31) = '1' and RDYBSY_reg = '1') then
			report "MMPPB1";
			MMPPB1_mem_page := comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device));
			-- page value has been stored for main memory page program
			MMPPB1_buf_page := (others => '0'); --buffer has zero pages

			compute_address(MMPPB1_buf_page, pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page),
					page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);
			write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 1, CSB, sck, SI);
			-- this will write to buffer
			-- it will proceed to next step, when, posedge of CSB.
			-- This is complicated, and, hence, explained here:
			-- At posedge of CSB, the write_data will get disabled.
			-- At this time, writing to buffer needs to stop, and,
			-- writing into memory should start.
			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device),
					lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0,
							page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page,
								page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then
					compute_address(MMPPB1_mem_page, pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page),
							page_addr1, byte_addr, binary_page), page_boundary_low,
						page_boundary_high, current_address, mem_no, binary_page);
					RDYBSY_reg <= '0';  -- device is busy
					status(7)  <= '0';
					write_to_memory(1, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory);
					page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
								page_addr0, page_addr1, manid(device)))) <= '1';

					updating_memory <= '1';

					wait for Tep;
					RDYBSY_reg      <= '1'; -- device is now ready
					status(7)       <= '1';
					updating_memory <= '0';
				else
					message2 := " Cannot write page is proted  ";
				end if;
			else
				message2 := " Cannot write page is Locked  ";
			end if;

			report " MMPPB1 exited";

		elsif (MMPPB2 = '1' and t(31) = '1' and RDYBSY_reg = '1') then
			report "MMPPB2";

			MMPPB2_mem_page := comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device));
			-- page value has been stored for main memory page program
			MMPPB2_buf_page := (others => '0'); --buffer has zero pages

			compute_address(MMPPB2_buf_page, pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page),
					page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

			write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 2, CSB, sck, SI);
			-- this will write to buffer
			-- it will proceed to next step, when, posedge of CSB.
			-- This is complicated, and, hence, explained here:
			-- At posedge of CSB, the write_data will get disabled.
			-- At this time, writing to buffer needs to stop, and,
			-- writing into memory should start.

			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status,
					comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), prot_status,
						comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))),
						WPB, soft_prot_enabled) = '0') then
					compute_address(MMPPB2_mem_page, pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page),
							page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);
					RDYBSY_reg <= '0';  -- device is busy
					status(7)  <= '0';
					write_to_memory(2, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory);
					page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
								page_addr0, page_addr1, manid(device)))) <= '1';
					updating_memory                                      <= '1';

					wait for Tep;
					RDYBSY_reg      <= '1'; -- device is now ready
					status(7)       <= '1';
					updating_memory <= '0';
				else
					message2 := " Cannot write page is proted  ";
				end if;
			else
				message2 := " Cannot write page is Locked  ";
			end if;

		elsif (APRB1 = '1' and t(31) = '1') then
			report "ARPB1";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
				pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high,
				current_address, mem_no, binary_page);

			wait until CSB'event and CSB = '1';
			transfer_to_buffer(1, page_boundary_low, memory, tbuffer1, tbuffer2);
			updating_buffer1 <= '1';

			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status,
					comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), prot_status,
						comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))),
						WPB, soft_prot_enabled) = '0') then
					updating_memory <= '1';
					RDYBSY_reg      <= '0';
					status(7)       <= '0';
					wait for Tep;
					RDYBSY_reg       <= '1';
					status(7)        <= '1';
					updating_buffer1 <= '0';
					updating_memory  <= '0';
				else
					message2 := " Cannot write page is proted  ";

				end if;
			else
				message2 := " Cannot write page is Locked  ";
			end if;

			-- NOTE:
			-- We dont need to rewrite the data back into main-memory, as the 
			--        data is already available in the main-memory
			-- This task was exactly same as MMPTB1T, except the delay-value
			--      We could have easily used the same code as MMPTB1T, using 
			--      an if condition for delay-selection. However, still doing
			--      this way, so that the code for each opcode is independent
			--      of anything else.

			report "APRB1  auto page rewrite is exited";

		elsif (APRB2 = '1' and t(31) = '1') then
			report "entered into auto page rewrite through buffer 2 ARPB2";
			compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
				pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
				page_boundary_low, page_boundary_high,
				current_address, mem_no, binary_page);

			wait until CSB'event and CSB = '1';
			transfer_to_buffer(2, page_boundary_low, memory, tbuffer1, tbuffer2);
			updating_buffer1 <= '1';

			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status,
					comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), prot_status,
						comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))),
						WPB, soft_prot_enabled) = '0') then
					updating_memory <= '1';
					RDYBSY_reg      <= '0';
					status(7)       <= '0';
					wait for Tep;
					RDYBSY_reg       <= '1';
					status(7)        <= '1';
					updating_buffer1 <= '0';
					updating_memory  <= '0';
				else
					message2 := " Cannot write page is proted  ";

				end if;
			else
				message2 := " Cannot write page is Locked  ";
			end if;

			-- NOTE:
			-- We dont need to rewrite the data back into main-memory, as the 
			--        data is already available in the main-memory
			-- This task was exactly same as MMPTB1T, except the delay-value
			--      We could have easily used the same code as MMPTB1T, using 
			--      an if condition for delay-selection. However, still doing
			--      this way, so that the code for each opcode is independent
			--      of anything else.

			report " auto page rewrite through buffer 2 is exited";

		----------------page erase------------------

		elsif (PE = '1') then
			report "entered into page erase";
			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device),
					lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0,
							page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status,
						comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))),
						WPB, soft_prot_enabled) = '0') then
					compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
						comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high,
						current_address, mem_no, binary_page);

					wait until CSB'event and CSB = '1';
					RDYBSY_reg <= '0';  --device is busy
					status(7)  <= '0';
					erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pagesize(device, binary_page), page_boundary_low, memory, temp_page_status);
					erasing_page <= '1';
					page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
								page_addr0, page_addr1, manid(device)))) <= temp_page_status;

					wait for Tpe;
					RDYBSY_reg   <= '1'; --device is now ready
					status(7)    <= '1';
					erasing_page <= '0';
				else
					message2 := " Cannot erase page is proted  ";
				end if;
			else
				message2 := " Cannot erase page is locked  ";
			end if;

			report "page erase exited";
		--------------------------Block Erase-------------------------

		elsif (BE = '1') then
			report "entered into block erase";
			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
					pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
							binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1,
							manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device),
							comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))),
						WPB, soft_prot_enabled) = '0') then
					compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1,
							manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page),
						page_boundary_low, page_boundary_high, current_address, mem_no, binary_page);

					wait until CSB'event and CSB = '1';
					RDYBSY_reg <= '0';  --device is busy
					status(7)  <= '0';

					jerase := page_boundary_low;
					loop_erase : loop
						if (jerase < page_boundary_low + (8 * pagesize(device, binary_page))) then
							erase_page(comp_page_addr(p_address(device), binary_page, page_addr0,
									page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); --erase 8 pages, i.e. a block

							page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
										page_addr0, page_addr1, manid(device)))) <= temp_page_status;

							jerase := jerase + pagesize(device, binary_page);
						else
							report "--------------------------Block Eraseexit -------------------------";
							exit loop_erase;
						end if;
					end loop;

					for j in 0 to 7 loop --erase_page will only change the status of one-page 
						page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
									page_addr0, page_addr1, manid(device))) + j) <= '0';
					end loop;
					erasing_block <= '1';
					wait for Tbe;
					RDYBSY_reg    <= '1'; --device is now ready
					status(7)     <= '1';
					erasing_block <= '0';
				else
					message2 := " Cannot erase bloc is proted  ";
				end if;
			else
				message2 := " Cannot erase bloc is locked  ";
			end if;

			report "block erase exited";

		---------------------------Sector Erase -----------------------------

		elsif (SE = '1') then
			if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device),
					lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
							binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
				if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device),
						prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
								binary_page, page_addr0, page_addr1, manid(device))),
						WPB, soft_prot_enabled) = '0') then
					compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page),
						comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low,
						page_boundary_high, current_address, mem_no, binary_page);

					wait until CSB'event and CSB = '1';
					RDYBSY_reg <= '0';  --device is busy
					status(7)  <= '0';
					--******************************--
					if (conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0,
								page_addr1, manid(device))) < 8) then
						page_boundary_low := 0;

						jerase := page_boundary_low;
						loop_sectorerase : loop
							if (jerase < page_boundary_low + 8 * pagesize(device, binary_page)) then
								erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
									pagesize(device, binary_page), jerase, memory, temp_page_status); -- erase 8 pages, i.e. a block

								page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
											page_addr0, page_addr1, manid(device)))) <= temp_page_status;

								jerase := jerase + pagesize(device, binary_page);
							else
								report "--------------------------sector Eraseexit -------------------------";
								exit loop_sectorerase;
							end if;
						end loop;

						for j in 0 to 7 loop -- erase_page will only change the status of one-page 
							page_status(j) <= '0';
						end loop;
					--************************************----
					elsif (comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)) < pageper_sector(device)) then
						page_boundary_low := 8 * pagesize(device, binary_page);
						jerase            := page_boundary_low;
						loop_sector1erase : loop
							if (jerase < page_boundary_low + ((pageper_sector(device) - 8) * pagesize(device, binary_page))) then
								erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
									pagesize(device, binary_page), jerase, memory, temp_page_status); --erase 248/120 pages, i.e. a block
								page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
											page_addr0, page_addr1, manid(device)))) <= temp_page_status;

								jerase := jerase + pagesize(device, binary_page);
							else
								report "--------------------------sector1 Eraseexit -------------------------";
								exit loop_sector1erase;
							end if;
						end loop;

						for j in 8 to pageper_sector(device) - 1 loop --erase_page will only change the status of one-page 
							page_status(j) <= '0';
						end loop;

					--**************************** 
					else
						page((p_address(DEVICE) - s_address(DEVICE)) - 1) <= '0';
						page_boundary_low                                 := conv_integer(page) * pagesize(device, binary_page);
						jerase                                            := page_boundary_low;
						loop_sector2erase : loop
							if (jerase < page_boundary_low + (pageper_sector(device) * pagesize(device, binary_page))) then
								jerase := jerase + pagesize(device, binary_page);
								erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
									pagesize(device, binary_page), jerase, memory, temp_page_status); --erase 256/128 pages, i.e. a block
								page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
											page_addr0, page_addr1, manid(device)))) <= temp_page_status;
								jerase                                               := jerase + pagesize(device, binary_page);
							else
								report "--------------------------sector2 Eraseexit -------------------------";
								exit loop_sector2erase;

							end if;
						end loop;

						for j in 0 to pageper_sector(device) - 1 loop
							page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))) + j) <= '0';
						end loop;
						erasing_sector <= '1';

						wait for Tse;
						RDYBSY_reg     <= '1'; --device is now ready
						status(7)      <= '1';
						erasing_sector <= '0';
					end if;

				else
					message2 := " Cannot erase sect is proted  ";
				end if;
			else
				message2 := " Cannot erase sect is locked  ";
			end if;

		----------------------------------Chip Erase-------------------------------------------


		elsif (oPC7 = '1' and t(31) = '1') then
			report "enabling chip erase";
			if (page_addr0 = X"94" and page_addr1 = X"80" and byte_addr = X"9A") then
				wait until CSB'event and CSB = '1';
				RDYBSY_reg <= '0';      -- device is busy
				status(7)  <= '0';
				--sector x0A
				page       <= (others => '0'); -- erase sector 0A
				sector     <= (others => '0');
				compute_address(page => page, page_size => pagesize(device, binary_page), byte => byte, page_boundary_low => page_boundary_low,
					page_boundary_high => page_boundary_high, current_address => current_address, mem_no => mem_no, binary_page => binary_page);

				if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
						pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
								binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
					if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
							pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
									binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then
						jerase := page_boundary_low;
						loop_chiperase : loop
							if (jerase < page_boundary_low + 8 * pagesize(device, binary_page)) then
								erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
									pagesize(device, binary_page), jerase, memory, temp_page_status); -- erase 8 pages, i.e. a block
								page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
											page_addr0, page_addr1, manid(device)))) <= temp_page_status;

								jerase := jerase + pagesize(device, binary_page);
							else
								report "--------------------------chip Eraseexit -------------------------";
								exit loop_chiperase;
							end if;
						end loop;

						for j in 0 to 7 loop -- erase_page will only change the status of one-page 
							page_status(j) <= '0';
						end loop;
					end if;
				end if;

				-- second sector x0B
				page   <= conv_std_logic_vector(8, p_address(DEVICE));
				sector <= (others => '0');
				compute_address(page => page, page_size => pagesize(device, binary_page), byte => byte, page_boundary_low => page_boundary_low,
					page_boundary_high => page_boundary_high, current_address => current_address, mem_no => mem_no, binary_page => binary_page);
				--Check if sector is locked
				if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device),
						lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
								binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
					--Check if sector is protecteds-----------------------
					if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
							pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
									binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then
						jerase := page_boundary_low;
						loop_chip_0berase : loop
							if (jerase < page_boundary_low + ((pageper_sector(device) - 8) * pagesize(device, binary_page))) then
								erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
									pagesize(device, binary_page), jerase, memory, temp_page_status); -- erase 8 pages, i.e. a block

								page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
											page_addr0, page_addr1, manid(device)))) <= temp_page_status;

								jerase := jerase + pagesize(device, binary_page);
							else
								report "--------------------------chip0b Eraseexit -------------------------";
								exit loop_chip_0berase;
							end if;
						end loop;

						for j in 0 to 7 loop -- erase_page will only change the status of one-page 
							page_status(j) <= '0';
						end loop;
					end if;
				end if;

				sector <= (others => '1');
				for page in pageper_sector(device) to (PAGE_cal(device) - pageper_sector(device)) - 1 loop
					--Check if sector is locked
					if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
							pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
									binary_page, page_addr0, page_addr1, manid(device)))) = '0') then
						--Check if sector is protecteds-----------------------
						if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
								pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device),
										binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then
							jerase := page_boundary_low;

							loop_chip_0cerase : loop
								if (jerase < page_boundary_low + (pageper_sector(device) * pagesize(device, binary_page))) then
									erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
										pagesize(device, binary_page), jerase, memory, temp_page_status);

									page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
												page_addr0, page_addr1, manid(device)))) <= temp_page_status;

									jerase := jerase + pagesize(device, binary_page);
								else
									report "--------------------------chip 0cEraseexit -------------------------";
									exit loop_chip_0cerase;
								end if;
							end loop;
							for j in 0 to pageper_sector(device) - 1 loop
								page_status(conv_integer(comp_page_addr(p_address(device),
											binary_page, page_addr0, page_addr1, manid(device))) + j) <= '0';
							end loop;
						end if;
					else
						message2 := "Cannot erase:Sector is  Locked";
						sector   <= sector + 1;
					end if;

				end loop;

				page <= ((conv_Std_Logic_Vector(PAGE_cal(device), p_address(device))) - (conv_Std_Logic_Vector(pageper_sector(device), p_address(device))));

				sector <= conv_std_logic_vector((SEC_TORS(device) - 1), S_address(device));

				compute_address(page => page, page_size => pagesize(device, binary_page), byte => byte, page_boundary_low => page_boundary_low,
					page_boundary_high => page_boundary_high, current_address => current_address, mem_no => mem_no, binary_page => binary_page);
				--Check if sector is locked
				if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device),
						lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page,
								page_addr0, page_addr1, manid(device)))) = '0') then
					--Check if sector is protecteds-----------------------
					if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device),
							prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page,
									page_addr0, page_addr1, manid(device))),
							WPB, soft_prot_enabled) = '0') then
						jerase := page_boundary_low;

						loop_chip_0derase : loop
							if (jerase < page_boundary_low + (pageper_sector(device) * pagesize(device, binary_page))) then
								erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)),
									pagesize(device, binary_page), jerase, memory, temp_page_status);

								page_status(conv_integer(comp_page_addr(p_address(device), binary_page,
											page_addr0, page_addr1, manid(device)))) <= temp_page_status;

								jerase := jerase + pagesize(device, binary_page);

							else
								report "--------------------------chip0d Eraseexit -------------------------";
								exit loop_chip_0derase;
							end if;

						end loop;

						for j in 0 to pageper_sector(device) - 1 loop
							page_status(conv_integer(comp_page_addr(p_address(device),
										binary_page, page_addr0, page_addr1, manid(device))) + j) <= '0';
						end loop;

					else
						message2 := "Cannot erase:Sectorisprotecteds";
					end if;
				else
					message2 := "Cannot erase:Sector is Locked ";
				end if;

				erasing_chip <= '1';

				wait for Tce;
				RDYBSY_reg   <= '1';    -- device is now ready
				status(7)    <= '1';
				erasing_chip <= '0';
				report "chip erase complete";
			end if;

		elsif (SRR = '1' and t(31) = '1') then
			report "SRR entered";
			if ((Rapid_interface = false) and (fSCK > 50)) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type. Security Register Read is not allowed.";
			end if;

			if (rapid_interface = false and fsck > 50) then
				read_out_x(CSB, SCK, so_reg, so_on);
			else
				read_out_reg(23, 0, 127, prot_reg, lock_reg, security_reg, CSB, SCK, so_reg, so_on);
			end if;
			report " SRR exited";

		elsif (PRR = '1' and t(31) = '1') then
			report "PRR entered";
			if ((Rapid_interface = false) and (fSCK > 50)) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type. protection Register Read is not allowed.";
			end if;

			if (rapid_interface = false and fsck > 50) then
				read_out_x(CSB, SCK, so_reg, so_on);
			else
				read_out_reg(21, 0, (sec_tors(device) - 1), prot_reg, lock_reg, security_reg, CSB, SCK, so_reg, so_on);
			end if;
			report " PRR exited";

		elsif (LRR = '1' and t(31) = '1') then
			report " LRR entered";

			if ((Rapid_interface = false) and (fSCK > 50)) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type. Lockdown Register Read is not allowed.";
			end if;

			if (rapid_interface = false and fsck > 50) then
				read_out_x(CSB, SCK, so_reg, so_on);
			else
				read_out_reg(22, 0, (sec_tors(device) - 1), prot_reg, lock_reg, security_reg, CSB, SCK, so_reg, so_on);
			end if;

			report "LRR exited";

		elsif (oP9B = '1' and t(31) = '1' and page_addr0 = X"00" and page_addr1 = X"00" and byte_addr = X"00") then
			report " entered program security register";
			SRP                <= '1';
			current_address    := 0;
			page_boundary_low  := 0;
			page_boundary_high := 63;
			write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 1, CSB, sck, SI);

			-- this will write to buffer
			-- it will proceed to next step, when, posedge of CSB.
			-- This is complicated, and, hence, explained here:
			-- At posedge of CSB, the write_data will get disabled.
			-- At this time, writing to buffer needs to stop, and,
			-- writing into memory should start.
			RDYBSY_reg <= '0';          --device is busy
			status(7)  <= '0';
			--writing in to security_reg
			if (security_flag = '0') then --Security Register has not been programmed before
				for j in 0 to 63 loop
					security_reg(j) <= tbuffer1(j);
				end loop;
				security_flag <= '1';
				wait for Tp;
				RDYBSY_reg <= '1';      --device is now ready
				status(7)  <= '1';
			else
				wait for 2000 ns;
				RDYBSY_reg <= '1';      --device is now ready
				status(7)  <= '1';
			end if;

		end if;

		report "last of processd";

	end process;

	----------------deep power down and resume deep power down----------------

	process
	begin
		wait on EDPD, RDPD;
		if (EDPD = '1') then
			wait until CSB'event and CSB = '1';
			wait for Tedpd;
			deep_power_down <= '1';
		end if;
		if (RDPD = '1') then
			wait until CSB'event and CSB = '1';
			wait for Trdpd;
			deep_power_down <= '0';
		end if;
	end process;

	-----------------------status register read--------

	process
		variable j_tmp : integer := 8;
	begin
		wait on SR;
		if (SR = '1') then
			report "SR";
			if ((Rapid_interface = false) and (fSCK > 50)) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type. Status Register Read is not allowed.";
			end if;
			status_read <= '1';         --reading status reg
			if (fsck >= 33) then
				for i in 0 to 7 loop
					wait until SCK'event and SCK = '0';
					wait for tv;
					so_reg1 <= 'X';
					so_on1  <= '1';
				end loop;
			end if;
			status_loop : loop
				wait until ((SCK'event and SCK = '0') or (CSB'event and CSB = '1'));
				exit status_loop when CSB = '1';
				if (j_tmp > 0) then
					j_tmp := j_tmp - 1;
				else
					j_tmp := 7;

				end if;

				if ((Rapid_interface = false) and (fSCK > 50)) then
					read_out_x(CSB, SCK, so_reg1, so_on1);
				else
					wait for tV;
					so_reg1 <= status(j_tmp);
					so_on1  <= '1';
				end if;

			end loop;
			report "status register read loop exited";
			wait for tDIS;
			so_on1      <= '0';
			status_read <= '0';
		end if;

	end process;
	------------manufacturing ID-----------
	process                             --(MIR)--,MANID(device))
		variable j    : integer                       := 32;
		variable m_id : std_logic_vector(31 downto 0) := manid(device);
	begin
		wait on MIR;
		if (MIR = '1') then
			report "MIR";
			if ((Rapid_interface = false) and (fSCK > 50)) then
				report "WARNING: Frequency should be less than 50MHz for SPI interface type. Manufacture ID Register Read is not allowed.";
			end if;
			MIR_loop : loop
				wait until ((SCK'event and SCK = '0') or (CSB'event and CSB = '1'));
				exit MIR_loop when CSB = '1';
				wait for Tv;
				if (J > 0) then
					SO_reg2 <= m_id(j - 1);
					so_on2  <= '1';
					J       := J - 1;
					if ((Rapid_interface = false) and (fSCK > 50)) then
						read_out_x(CSB, SCK, so_reg2, so_on2);
					end if;
				elsif (j = 0) then
					So_on2  <= '1';
					So_reg2 <= 'X';     -- only if the cs extends more than available man ID
				end if;
			end loop;
			wait for Tdis;
			so_on2  <= '0';
			So_reg2 <= '0';

		end if;

	end process;

	---------------------------
	IntCSb <= CSb or not Resetb;
	------------------------ SCK check
	--checkPeriod	( SCK  , "SCk"  		, Tsck , "Tsck" , TsckRp , "SCK Frequency"   	, valid ) ;
	--checkWidth1	( SCK  , "SCK"  		, Twh  , "Twh"  , TsckRw , "SCK High Time"   	, valid ) ;
	--checkWidth0	( SCK  , "SCK"  		, Twl  , "Twl"  , TsckF , "SCK Low Time"     	, valid ) ;
	--		------------------------ IntCSb chec
	--checkWidth1	( IntCSb  , "IntCSb"  		, Tcs  , "Tcs"  , TcsR 	, "Minimum CS High Time", valid ) ;
	--checkSetupCS 	( IntCSb  , "IntCSb"  , SCK  , "SCK"  , Tcss , "Tcss" , TcsF	, "IntCSb setup Time"  	, valid ) ;
	--checkHoldCS  	( IntCSb  , "IntCSb"  , SCK  , "SCK"  , Tcsh , "Tcsh" , Tsckm	, "IntCSb Hold Time"    	, valid	) ;
	--		------------------------ SI check
	--checkSetupRise	( SI   ,  "SI"   , SCK  , "SCK" , Tsu  , "Tsu"  , Tsim 	, "Data in Setup Time"  , valid ) ;
	--checkHoldRise 	( SI   ,  "SI"   , SCK  , "SCK" , Th   , "Th"   , TsckRh, "Data in Hold Time"   , valid ) ;


	process(so_on1, so_reg1, so_on2, so_reg2, so_reg, so_on)
	begin
		if (so_on1 = '1') then
			so <= so_reg1;
		elsif (so_on2 = '1') then
			so <= so_reg2;
		elsif (so_on = '1') then
			so <= so_reg;
		else
			so <= 'Z';
		end if;
	end process;

	process(RDYBSY_reg)
	begin
		if (RDYBSY_reg = '1') then
			RDYBSY <= '1';
		else
			RDYBSY <= '0';
		end if;
	end process;

--less_than_33mhz <= lthan_66mhz & lthan_33mhz;


end design;
