------------------------------------------------------------------------------- -- 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 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" => 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;