------------------------------------------------------------------------------- -- This is the property of PERFTRENDS TECHNOLOGIES PRIVATE LIMITED and -- possession or use of file has to be with the written LICENCE AGGREMENT -- from PERFTRENDS TECHNOLOGIES PRIVATE LIMITED. -- ------------------------------------------------------------------------------- -- -- Project : Atmel DataFlash model ------------------------------------------------------------------------------- -- File : $RCSfile: DataFlash2.1.vhd,v $ -- Path : $Source: /home/cvs/atmel_flash_dev/design/DataFlash2.1.vhd,v $ -- Author : E.MAGESH -- Created on : 20-06-06 -- Revision : $Revision: 1.1 $ -- Last modified by : $Author: magesh $ -- Last modified on : $Date: 2006/07/19 13:54:54 $ ------------------------------------------------------------------------------- -- Module : FlashMemory -- Description : -- -- ------------------------------------------------------------------------------- -- -- Design hierarchy : -- Instantiated Modules : ------------------------------------------------------------------------------- -- Revision history : -- $Log: DataFlash2.1.vhd,v $ -- Revision 1.1 2006/07/19 13:54:54 magesh -- *** empty log message *** -- -- Revision 1.5 2006/06/29 12:34:49 magesh -- *** empty log message *** -- -- Revision 1.4 2006/06/27 12:05:42 magesh -- *** empty log message *** -- -- Revision 1.3 2006/06/21 14:24:03 magesh -- *** empty log message *** -- -- Revision 1.2 2006/06/20 13:34:01 magesh -- *** empty log message *** -- ------------------------------------------------------------------------------- library std; use std.textio.all; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_textio.all; use ieee.std_logic_arith.all; use IEEE.Std_logic_unsigned.all; use IEEE.numeric_std.all; ---entity declarations-------------- entity DataFlash is generic( flashmemory : string := "memory.txt"; Rapid_interface : boolean := true; fsck : integer := 66; DEVICE : string(1 to 10) := "AT45DB011D"; Tsck : Time := 13.6 ns); port( SI : in std_logic; -- Data SPI CSB : in std_logic; -- Chip Select SPI SCK : in std_logic; -- Clock SPI WPB : in std_logic; -- Hard Ware Page Write protecteds Pin RESETB : in std_logic; -- Reset Pin SO : out std_logic; -- Serial Output RDYBSY : out std_logic -- Ready Busy pin ); end DataFlash; ----architecture declarations------ architecture design of DataFlash is constant t_buffer : integer := 2; signal binary_page : std_logic := '0'; signal status2 : std_logic := '1'; signal status3 : std_logic; signal status4 : std_logic; signal status5 : std_logic; constant TFP : TIME := 14000000 ns; constant TCE : TIME := 400000000 ns; -- TBD Spec. time is 5s constant TVCSL : TIME := 30000 ns; -- ?? constant TPUW : TIME := 10000000 ns; -- ?? ---- Input Times check constant Tcar1 : Time := Tsck; constant Tcar2 : Time := 30 ns; -- 33 Mhz operation constant Twh : TIME := Tsck / 2; -- SCK High Time constant Twl : TIME := Tsck / 2; -- SCK Low Time constant Tcs : TIME := 50 ns; -- Minimum CS! High Time constant Tcss : TIME := 5 ns; -- CS! setup Time constant Tcsh : TIME := 5 ns; -- CS! Hold Time constant Tcsb : TIME := 100 ns; -- Max constant Tsu : TIME := 2 ns; -- Data in Setup Time constant Th : TIME := 3 ns; -- Data in Hold Time ---- Outup delay constant Tho : TIME := 0 ns; -- Output Hold Time constant Tdis : TIME := 8 ns; -- Output Disable Time constant Tv : TIME := 8 ns; -- Output Valid constant Twpe : TIME := 1 ns; -- constant Twpd : TIME := 1 ns; -- constant Tedpd : TIME := 3 us; constant Trdpd : TIME := 30 us; ---- Processing Time constant Txfr : TIME := 400 us; -- Page to Buffer Transfer_Compare Time constant Tcomp : TIME := 400 us; constant Tep : TIME := 40 ms; -- Page Erase and Programming Time constant Tp : TIME := 6 ms; -- Page Programming Time constant Tpe : TIME := 35 ms; constant Tbe : TIME := 100 ms; constant Tse : TIME := 5000 ms; -- Spec. time is 5s constant Trst : TIME := 10 us; -- Reset Pulse Width constant Trec : TIME := 1 us; -- Reset Recovery Time ------------------------------------------------ signal TsckRp, TsckRw, TsckF, TcsR, TcsF, Tsckm, Tsim, TsckRh : time := 0 ns; ------------- global signal declarations--------- -----opcode enable signal--------- signal MMCAR : std_logic; constant binary_opt : std_logic := '1'; signal buffer2read : std_logic; signal MMPTB1T : std_logic; signal MMPTB2T : std_logic; signal MMPTB1C : std_logic; signal MMPTB2C : std_logic; signal B1W : std_logic; signal B2W : std_logic; signal B1TMMPPWBIE : std_logic; signal B2TMMPPWBIE : std_logic; signal B1TMMPPWOBIE : std_logic; signal B2TMMPPWOBIE : std_logic; signal PE : std_logic; signal BE : std_logic; signal SE : std_logic; signal CE : std_logic; signal MMPPB1 : std_logic; signal MMPPB2 : std_logic; signal APRB1 : std_logic; signal APRB2 : std_logic; signal OP3D : std_logic; signal BPS : std_logic; signal PRE : std_logic; signal PRP : std_logic; signal LRP : std_logic; signal SPE : std_logic; signal SPD : std_logic; signal PRR : std_logic; signal LRR : std_logic; signal OP9B : std_logic; signal SRP : std_logic; signal security_flag : std_logic := '0'; signal soft_prot_enabled : std_logic := '0'; signal tmp_reg1 : std_logic_vector(7 downto 0); signal tmp_reg2 : std_logic_vector(7 downto 0); signal less_than_33mhz : std_logic; --signal less_than_20Mhz : std_logic; signal locked : std_logic; signal protecteds : std_logic; signal protection : bit_vector(511 downto 0) := (others => '1'); signal lockdown : bit_vector(511 downto 0) := (others => '0'); signal security : bit_vector(511 downto 0) := (others => '1'); signal factory : bit_vector(511 downto 0) := (others => '1'); function device_Sel1(DEVICE : in string(1 to 10) ) return std_logic is variable status3 : std_logic; begin if (DEVICE = "AT45DB041D") then status3 := '1'; elsif (DEVICE = "AT45DB081D") then status3 := '0'; elsif (DEVICE = "AT45DB161D") then status3 := '1'; elsif (DEVICE = "AT45DB321D") then status3 := '0'; elsif (DEVICE = "AT45DB642D") then status3 := '1'; elsif (DEVICE = "AT45DB011D") then status3 := '1'; elsif (DEVICE = "AT45DB021D") then status3 := '1'; else status3 := '1'; end if; return status3; end device_sel1; function device_Sel2(DEVICE : in string(1 to 10) ) return std_logic is variable status4 : std_logic; begin if (DEVICE = "AT45DB041D") then status4 := '1'; elsif (DEVICE = "AT45DB081D") then status4 := '0'; elsif (DEVICE = "AT45DB161D") then status4 := '0'; elsif (DEVICE = "AT45DB321D") then status4 := '1'; elsif (DEVICE = "AT45DB642D") then status4 := '1'; elsif (DEVICE = "AT45DB011D") then status4 := '0'; elsif (DEVICE = "AT45DB021D") then status4 := '1'; else status4 := '1'; end if; return status4; end device_sel2; function device_Sel3(DEVICE : in string(1 to 10) ) return std_logic is variable status5 : std_logic; begin if (DEVICE = "AT45DB041D") then status5 := '0'; elsif (DEVICE = "AT45DB081D") then status5 := '1'; elsif (DEVICE = "AT45DB161D") then status5 := '1'; elsif (DEVICE = "AT45DB321D") then status5 := '1'; elsif (DEVICE = "AT45DB642D") then status5 := '1'; elsif (DEVICE = "AT45DB011D") then status5 := '0'; elsif (DEVICE = "AT45DB021D") then status5 := '0'; else status5 := '0'; end if; return status5; end device_sel3; function page_cal(DEVICE : in string(1 to 10) ) return integer is variable pages : integer range 1 to 8192 := 2048; begin case DEVICE is when "AT45DB041D" => pages := 2048; when "AT45DB081D" => pages := 4096; when "AT45DB161D" => pages := 4096; when "AT45DB321D" => pages := 8192; when "AT45DB642D" => pages := 8192; when "AT45DB011D" => pages := 512; when "AT45DB021D" => pages := 1024; when OTHERS => pages := 2048; end case; return pages; end page_cal; function pageper_sector(DEVICE : in string(1 to 10) ) return integer is variable page_per_sector : integer range 1 to 256 := 256; begin case DEVICE is when "AT45DB041D" => page_per_sector := 256; when "AT45DB081D" => page_per_sector := 256; when "AT45DB161D" => page_per_sector := 256; when "AT45DB321D" => page_per_sector := 128; when "AT45DB642D" => page_per_sector := 256; when "AT45DB011D" => page_per_sector := 128; when "AT45DB021D" => page_per_sector := 128; when OTHERS => page_per_sector := 256; end case; return page_per_sector; end pageper_sector; function sec_tors(DEVICE : in string(1 to 10) ) return integer is variable sectors : integer range 1 to 64 := 8; begin case DEVICE is when "AT45DB041D" => sectors := 8; when "AT45DB081D" => sectors := 16; when "AT45DB161D" => sectors := 16; when "AT45DB321D" => sectors := 64; when "AT45DB642D" => sectors := 32; when "AT45DB011D" => sectors := 4; when "AT45DB021D" => sectors := 8; when OTHERS => sectors := 8; end case; return sectors; end sec_tors; function pagesize_forbuffer(DEVICE : in string(1 to 10) ) return integer is variable page_size : integer range 1 to 1056 := 264; begin case DEVICE is when "AT45DB041D" => page_size := 264; when "AT45DB081D" => page_size := 264; when "AT45DB161D" => page_size := 528; when "AT45DB321D" => page_size := 528; when "AT45DB642D" => page_size := 1056; when "AT45DB011D" => page_size := 264; when "AT45DB021D" => page_size := 264; when OTHERS => page_size := 264; end case; return page_size; end pagesize_forbuffer; function pagesize(DEVICE : in string(1 to 10); signal binary_page : in std_logic ) return integer is variable page_size : integer range 1 to 1056 := 264; begin case DEVICE is when "AT45DB041D" => page_size := (264 - (conv_integer(BINARY_page) * 8)); when "AT45DB081D" => page_size := (264 - (conv_integer(BINARY_page) * 8)); when "AT45DB161D" => page_size := (528 - (conv_integer(BINARY_page) * 16)); when "AT45DB321D" => page_size := (528 - (conv_integer(BINARY_page) * 16)); when "AT45DB642D" => page_size := (1056 - (conv_integer(BINARY_page) * 32)); when "AT45DB011D" => page_size := (264 - (conv_integer(BINARY_page) * 8)); when "AT45DB021D" => page_size := (264 - (conv_integer(BINARY_page) * 8)); when OTHERS => page_size := (264 - (conv_integer(BINARY_page) * 8)); end case; return page_size; end pagesize; function memsize(page_size : in integer range 1 to 1056; pages : in integer range 1 to 8192 ) return integer is variable mem_size : integer range 1 to 69206016; begin mem_size := page_size * pages; return mem_size; end memsize; function b_address(DEVICE : in string(1 to 10); signal binary_page : in std_logic ) return integer is variable baddress : integer range 1 to 11 := 9; begin case DEVICE is when "AT45DB041D" => baddress := (9 - (conv_integer(BINARY_page) * 1)); when "AT45DB081D" => baddress := (9 - (conv_integer(BINARY_page) * 1)); when "AT45DB161D" => baddress := (10 - (conv_integer(BINARY_page) * 1)); when "AT45DB321D" => baddress := (10 - (conv_integer(BINARY_page) * 1)); when "AT45DB642D" => baddress := (11 - (conv_integer(BINARY_page) * 1)); when "AT45DB011D" => baddress := (9 - (conv_integer(BINARY_page) * 1)); when "AT45DB021D" => baddress := (9 - (conv_integer(BINARY_page) * 1)); when OTHERS => baddress := (9 - (conv_integer(BINARY_page) * 1)); end case; return baddress; end b_address; function p_address(DEVICE : in string(1 to 10) ) return integer is variable paddress : integer range 1 to 14 := 11; begin case DEVICE is when "AT45DB041D" => paddress := 11; when "AT45DB081D" => paddress := 12; when "AT45DB161D" => paddress := 12; when "AT45DB321D" => paddress := 13; when "AT45DB642D" => paddress := 13; when "AT45DB011D" => paddress := 9; when "AT45DB021D" => paddress := 10; when OTHERS => paddress := 11; end case; return paddress; end p_address; function s_address(DEVICE : in string(1 to 10) ) return integer is variable saddress : integer range 1 to 6 := 3; begin case DEVICE is when "AT45DB041D" => saddress := 3; when "AT45DB081D" => saddress := 4; when "AT45DB161D" => saddress := 4; when "AT45DB321D" => saddress := 6; when "AT45DB642D" => saddress := 5; when "AT45DB011D" => saddress := 2; when "AT45DB021D" => saddress := 3; when OTHERS => saddress := 3; end case; return saddress; end s_address; function manid(DEVICE : in string(1 to 10) ) return std_logic_vector is variable man_id : std_logic_vector(31 downto 0); begin case DEVICE is when "AT45DB041D" => man_id := X"1F_24_00_00"; when "AT45DB081D" => man_id := X"1F_25_00_00"; when "AT45DB161D" => man_id := X"1F_26_00_00"; when "AT45DB321D" => man_id := X"1F_27_00_00"; when "AT45DB642D" => man_id := X"1F_28_00_00"; when "AT45DB011D" => man_id := X"1F_22_00_00"; when "AT45DB021D" => man_id := X"1F_23_00_00"; when OTHERS => man_id := X"1F_24_01_00"; end case; return man_id; end manid; --------------timing task implementation-------- procedure checkSetupCS( signal CsSignal : in std_logic; CsSignalName : in string; signal TriggerSignal : in std_logic; TriggerSignalName : in string; ExpectedDelay : in time; ExpectedDelayName : in string; signal LastCsFall : inout time; FullPathName : in string; CheckEnabled : in boolean ) is variable ln : Line; begin if (CsSignal'event and CsSignal = '0') then LastCsFall <= now; end if; if TriggerSignal'event and (now - LastCsFall < ExpectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (lastCsFall /= 0 ns) and checkEnabled then write(ln, string'("Error on ")); write(ln, fullPathName); write(ln, string'(": '")); write(ln, string'(CsSignalName)); write(ln, string'("' to '")); write(ln, string'(TriggerSignalName)); write(ln, string'("' Setup violation at: ")); write(ln, now); write(ln, string'(", ")); write(ln, string'(ExpectedDelayName)); write(ln, string'(" expected: ")); write(ln, expectedDelay); write(ln, string'(", ")); write(ln, string'(ExpectedDelayName)); write(ln, string'(" actual: ")); write(ln, now - LastCsFall); writeline(output, ln); end if; end checkSetupCs; -------------------------------------------------------------------------- -- CsSignal __________/-------- -- TriggerSignal ======x============ -- <---> procedure checkHoldCS( signal CsSignal : in std_logic; CsSignalName : in string; signal TriggerSignal : in std_logic; TriggerSignalName : in string; ExpectedDelay : in time; ExpectedDelayName : in string; signal LastTriggerEdge : inout time; FullPathName : in string; CheckEnabled : in boolean ) is variable ln : Line; begin if triggerSignal'event then LastTriggerEdge <= now; end if; if CsSignal'event and CsSignal = '1' and (now - LastTriggerEdge < ExpectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (LastTriggerEdge /= 0 ns) and checkEnabled then write(ln, string'("Error on ")); write(ln, fullPathName); write(ln, string'(": '")); write(ln, string'(CsSignalName)); write(ln, string'("' to '")); write(ln, string'(triggerSignalName)); write(ln, string'("' Hold violation at: ")); write(ln, now); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" expected: ")); write(ln, expectedDelay); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" actual: ")); write(ln, now - LastTriggerEdge); writeline(output, ln); end if; end checkHoldCs; ----------------------------------------------------------------------- -- Trigger ___________/--------- -- Reference =====x=============== -- <-----> procedure checkSetupRise( signal ReferenceSignal : in std_logic; ReferenceSignalName : in string; signal TriggerSignal : in std_logic; TriggerSignalName : in string; ExpectedDelay : in time; ExpectedDelayName : in string; signal LastReferenceMove : inout time; FullPathName : in string; CheckEnabled : in boolean ) is variable ln : Line; begin if referenceSignal'Event then LastReferenceMove <= now; end if; if triggerSignal'event and triggerSignal = '1' and (now - LastReferenceMove < expectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (LastReferenceMove /= 0 ns) and checkEnabled then write(ln, string'("Error on ")); write(ln, fullPathName); write(ln, string'(": '")); write(ln, string'(referenceSignalName)); write(ln, string'("' to '")); write(ln, string'(triggerSignalName)); write(ln, string'("' Setup violation at: ")); write(ln, now); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" expected: ")); write(ln, expectedDelay); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" actual: ")); write(ln, now - LastReferenceMove); writeline(output, ln); end if; end checkSetupRise; ----------------------------------------------------------------- -- Trigger __________/---------- -- Reference ================x==== -- <-----> procedure checkHoldRise( signal ReferenceSignal : in std_logic; ReferenceSignalName : in string; signal TriggerSignal : in std_logic; TriggerSignalName : in string; ExpectedDelay : in time; ExpectedDelayName : in string; signal LastTriggerRise : inout time; FullPathName : in string; CheckEnabled : in boolean ) is variable ln : Line; begin if TriggerSignal'event and TriggerSignal = '1' then LastTriggerRise <= now; end if; if ReferenceSignal'event and (now - LastTriggerRise < expectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (LastTriggerRise /= 0 ns) and checkEnabled then write(ln, string'("Error on ")); write(ln, fullPathName); write(ln, string'(": '")); write(ln, string'(referenceSignalName)); write(ln, string'("' to '")); write(ln, string'(triggerSignalName)); write(ln, string'("' Hold violation at: ")); write(ln, now); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" expected: ")); write(ln, expectedDelay); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" actual: ")); write(ln, now - LastTriggerRise); writeline(output, ln); end if; end checkHoldRise; ------------------------------------------------------------------------------ -- Signal ____/------\_______/---- -- <--------------> procedure checkPeriod( signal TestSignal : in std_logic; TestSignalName : in string; expectedDelay : in time; expectedDelayName : in string; signal LastSignalRise : inout time; fullPathName : in string; checkEnabled : in boolean ) is variable ln : Line; begin if (TestSignal'event and TestSignal = '1') then if (now - lastSignalRise < expectedDelay) and (lastSignalRise /= 0 ns) and (now > 0 ns) and (expectedDelay /= 0 ns) and checkEnabled then write(ln, string'("Error on ")); write(ln, fullPathName); write(ln, string'(": '")); write(ln, string'(TestSignalName)); write(ln, string'("' Periode violation at: ")); write(ln, now); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" expected: ")); write(ln, expectedDelay); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" actual: ")); write(ln, now - lastSignalRise); writeline(output, ln); end if; LastSignalRise <= now; end if; end checkPeriod; ---------------------------------------------------------------------- -- Signal ____/---------\____ -- <---------> procedure checkWidth1( signal TestSignal : in std_logic; TestSignalName : in string; ExpectedDelay : in time; ExpectedDelayName : in string; signal LastSignalRise : inout time; FullPathName : in string; CheckEnabled : in boolean ) is variable ln : Line; begin if (TestSignal'event and TestSignal = '1') then LastSignalRise <= now; end if; if (TestSignal'event and TestSignal = '0') and (now - lastSignalRise < expectedDelay) and (now > 0 ns) and (expectedDelay /= 0 ns) and (lastSignalRise /= 0 ns) and checkEnabled then write(ln, string'("Error on ")); write(ln, fullPathName); write(ln, string'(": '")); write(ln, string'(TestSignalName)); write(ln, string'("' Pulse Width violation at: ")); write(ln, now); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" expected: ")); write(ln, expectedDelay); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" actual: ")); write(ln, now - lastSignalRise); writeline(output, ln); end if; end checkWidth1; ---------------------------------------------------------------------- -- Signal ----\_________/----- -- <---------> procedure checkWidth0( signal TestSignal : in std_logic; TestSignalName : in string; ExpectedDelay : in time; ExpectedDelayName : in string; signal LastSignalFall : inout time; fullPathName : in string; checkEnabled : in boolean ) is variable ln : Line; begin if (TestSignal'event and TestSignal = '0') then lastSignalFall <= now; end if; if (TestSignal'event and TestSignal = '1') and (now - lastSignalFall < expectedDelay) and (lastSignalFall /= 0 ns) and (now > 0 ns) and (expectedDelay /= 0 ns) and checkEnabled then write(ln, string'("Error on ")); write(ln, fullPathName); write(ln, string'(": '")); write(ln, string'(TestSignalName)); write(ln, string'("' Pulse Width violation at: ")); write(ln, now); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" expected: ")); write(ln, expectedDelay); write(ln, string'(", ")); write(ln, string'(expectedDelayName)); write(ln, string'(" actual: ")); write(ln, now - lastSignalFall); writeline(output, ln); end if; end checkWidth0; ------------------------------------------------------------------- ------------------------------------------------------------------- ------------------------------------------------------------------- FUNCTION integer_to_bit_vector(VAL, width : INTEGER) RETURN BIT_VECTOR IS VARIABLE result : BIT_VECTOR(width - 1 downto 0) := (OTHERS => '0'); VARIABLE bits : INTEGER := width; BEGIN IF (bits > 31) THEN -- Avoid overflow errors. bits := 31; ELSE ASSERT 2 ** bits > VAL REPORT "Value too big FOR BIT_VECTOR width" SEVERITY WARNING; END IF; FOR i IN 0 TO bits - 1 LOOP IF ((val / (2 ** i)) MOD 2 = 1) THEN result(i) := '1'; END IF; END LOOP; RETURN (result); END integer_to_bit_vector; PROCEDURE removespace(VARIABLE l : IN line; pos : OUT integer) IS BEGIN pos := l'low; FOR i IN l'low TO l'high LOOP CASE l(i) IS WHEN ' ' | ht => pos := i + 1; WHEN OTHERS => EXIT; END CASE; END LOOP; END; PROCEDURE removeline(l : INOUT line; pos : integer) IS VARIABLE tmpl : line; BEGIN tmpl := l; l := NEW string'(tmpl(pos TO tmpl'high)); deallocate(tmpl); END; PROCEDURE hexa_to_bit_vector(l : INOUT line; u : in integer; value : OUT bit_vector) IS CONSTANT not_digit : integer := -999; FUNCTION digit_value(c : character) RETURN integer IS BEGIN IF (c >= '0') AND (c <= '9') THEN RETURN (character'pos(c) - character'pos('0')); ELSIF (c >= 'a') AND (c <= 'f') THEN RETURN (character'pos(c) - character'pos('a') + 10); ELSIF (c >= 'A') AND (c <= 'F') THEN RETURN (character'pos(c) - character'pos('A') + 10); ELSE RETURN not_digit; END IF; END; VARIABLE digit : bit_vector(4 downto 1); VARIABLE digit1 : bit_vector(u downto 1); VARIABLE digitx : integer; VARIABLE pos : integer; VARIABLE t : integer := u / 4; BEGIN removespace(l, pos); FOR i IN pos TO l'right LOOP digitx := digit_value(l(i)); EXIT WHEN (digitx = not_digit) OR (digitx >= 16); digit := integer_to_bit_vector(digitx, 4); if t >= 1 then digit1 := digit1(u - 4 downto 1) & digit; t := t - 1; else end if; pos := i + 1; END LOOP; value := digit1; removeline(l, pos); END; --******************************************--- --******************************************-- signal page_status : std_logic_vector(page_cal(device) - 1 downto 0); signal temp_page_status : std_logic; signal page : std_logic_vector(p_address(device) - 1 downto 0); signal temp_reg2 : std_logic_vector(7 downto 0); signal temp_page : std_logic_vector(p_address(device) - 1 downto 0); signal byte : std_logic_vector(b_address(device, binary_page) - 1 downto 0); ---protecteds/locked status reg----- signal prot_status : std_logic_vector(sec_tors(device) downto 0); signal sector : std_logic_vector(s_address(device) - 1 downto 0); type buffer1 is array (pagesize_forbuffer(device) - 1 downto 0) of bit_vector(7 downto 0); signal tbuffer1 : buffer1; type buffer2 is array (pagesize_forbuffer(device) - 1 downto 0) of bit_vector(7 downto 0); signal tbuffer2 : buffer2; --memory initalization-- constant N : integer range 1 to 69206016 := memsize(pagesize_forbuffer(device), page_cal(DEVICE)); constant M : integer := 8; type memtype is array (N - 1 downto 0) of bit_vector(7 downto 0); signal memory : memtype; --protection initialization--- constant p : integer := sec_tors(device); type prot_type is array (p - 1 downto 0) of bit_vector(7 downto 0); signal prot_reg : prot_type; --lock initialization-- type lock_type is array (p - 1 downto 0) of bit_vector(7 downto 0); signal lock_reg : lock_type; --factory security --- type factory_type is array (63 downto 0) of bit_vector(7 downto 0); signal factory_reg : factory_type; --security reg-- type security_type is array (63 downto 0) of bit_vector(7 downto 0); signal security_reg : security_type; --in security register 0 to 63 byte one time user programmable ---64 to 127 byte factory programmable by atmel-- ----------------------op3d------ signal op3d_tmp_reg : std_logic_vector(7 downto 0) := "00000000"; ----------------------opc7------ signal opc7_tmp_reg : std_logic_vector(7 downto 0) := "00000000"; ----------------------MMPPB1----------- signal MMPPB1_temp_page : std_logic_vector(p_address(device) - 1 downto 0); signal MMPPB1_page : std_logic_vector(p_address(device) - 1 downto 0); signal MMPPB1_byte : std_logic_vector(b_address(device, binary_page) - 1 downto 0); signal MMPPB1_tmp_reg : std_logic_vector(7 downto 0) := "00000000"; signal MMPPB1_tmp_reg1 : std_logic_vector(7 downto 0) := "00000000"; signal MMPPB1_tmp_reg2 : std_logic_vector(7 downto 0) := "00000000"; ----------------------MMPPB2----------- signal MMPPB2_temp_page : std_logic_vector(p_address(device) - 1 downto 0); signal MMPPB2_page : std_logic_vector(p_address(device) - 1 downto 0); signal MMPPB2_byte : std_logic_vector(b_address(device, binary_page) - 1 downto 0); signal MMPPB2_tmp_reg1 : std_logic_vector(7 downto 0) := "00000000"; signal MMPPB2_tmp_reg2 : std_logic_vector(7 downto 0) := "00000000"; --------------------- --------------comp page address function implementation--------------- function comp_page_addr(paddress : in integer range 1 to 14; signal binary_page : in std_logic; signal page_addr0 : in std_logic_vector(7 downto 0); signal page_addr1 : in std_logic_vector(7 downto 0); man_id : in std_logic_vector(31 downto 0) ) return std_logic_vector is variable page1 : std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0); begin case (PADDRESS) is --when 14 => --if(binary_page='1') then --page := (page_addr0(7 downto 0)) & (page_addr1(7 downto 2)); --else --4 address bytes --page := temp_reg2(0) & page_addr0(7 downto 0) & page_addr1(7 downto 2); --end if; when 13 => --64mb-- if (MAN_ID = X"1F280000") then if (binary_page = '1') then page1 := page_addr0(6 downto 0) & page_addr1(7 downto 2); else page1 := page_addr0(7 downto 0) & page_addr1(7 downto 3); end if; end if; --32 mb-- if (MAN_ID = X"1F270100") then if (binary_page = '1') then page1 := page_addr0(5 downto 0) & page_addr1(7 downto 1); else page1 := page_addr0(6 downto 0) & page_addr1(7 downto 2); end if; end if; when 12 => ---16mb---- if (MAN_ID = X"1F260000") then if (binary_page = '1') then page1 := page_addr0(4 downto 0) & page_addr1(7 downto 1); else page1 := page_addr0(5 downto 0) & page_addr1(7 downto 2); end if; end if; --8mb-- if (MAN_ID = X"1F250000") then if (binary_page = '1') then page1 := page_addr0(3 downto 0) & page_addr1(7 downto 0); else page1 := page_addr0(4 downto 0) & page_addr1(7 downto 1); end if; end if; ---4 mb--- when 11 => if (binary_page = '1') then page1 := page_addr0(2 downto 0) & page_addr1(7 downto 0); else page1 := page_addr0(3 downto 0) & page_addr1(7 downto 1); end if; --2mb--- when 10 => if (binary_page = '1') then page1 := page_addr0(1 downto 0) & page_addr1(7 downto 0); else page1 := page_addr0(2 downto 0) & page_addr1(7 downto 1); end if; --1mb--- when 9 => if (binary_page = '1') then page1 := page_addr0(0) & page_addr1(7 downto 0); else page1 := page_addr0(1 downto 0) & page_addr1(7 downto 1); end if; when others => end case; return page1; end comp_page_addr; ----------------function compute_sector addr------- function comp_sector_addr(paddress : in integer range 1 to 14; page1 : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0) --signal sector : in std_logic_vector((S_ADDRESS(device))-1 DOWNTO 0); ) return std_logic_vector is variable sector1 : std_logic_vector((S_ADDRESS(device)) - 1 DOWNTO 0); begin sector1 := page1(P_ADDRESS(device) - 1 downto P_ADDRESS(device) - S_ADDRESS(device)); return sector1; end comp_sector_addr; procedure compute_sector_address( paddress : in integer range 1 to 14; signal page : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0); signal sector : out std_logic_vector((S_ADDRESS(device)) - 1 downto 0) ) is begin sector <= page(P_ADDRESS(device) - 1 downto P_ADDRESS(device) - S_ADDRESS(device)); end compute_sector_address; ---------------------------- function comp_byte_addr(baddress : integer range 1 to 11; signal page_addr1 : in std_logic_vector(7 downto 0); signal byte_addr : in std_logic_vector(7 downto 0); signal binary_page : in std_logic ) return std_logic_vector is variable byte : std_logic_vector((b_address(device, binary_page)) - 1 DOWNTO 0); begin report " entered into comp_byte_addr"; case (baddress) is when 11 => byte := page_addr1(2 downto 0) & byte_addr; --b"00000000" ; when 10 => byte := page_addr1(1 downto 0) & byte_addr; --b"00000000" ; when 9 => byte := page_addr1(0) & byte_addr; --b"00000000" ; when others => byte := byte_addr; end case; return byte; end comp_byte_addr; procedure compute_address(page : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0); page_size : in integer range 1 to 1056; byte : in std_logic_vector((b_address(device, binary_page)) - 1 DOWNTO 0); page_boundary_low : out integer; page_boundary_high : out integer; current_address : out integer; mem_no : out integer; signal binary_page : in std_logic ) is variable temp_low : integer; begin report "entered into compute_address"; temp_low := (conv_integer(page) * pagesize(device, binary_page)); page_boundary_low := temp_low; page_boundary_high := temp_low + (pagesize(device, binary_page) - 1); report "entered into byte"; current_address := temp_low + conv_integer(byte); --memno 10 is for memory access--- mem_no := 10; end compute_address; procedure read_out(signal SCK, CSB : in std_logic; page_boundary_low : in integer; page_boundary_high : in integer; current_address : inout integer; mem_no : in integer; signal buf1 : in buffer1; signal buf2 : in buffer2; signal memory : in memtype; --signal temp_reg1 :inout std_logic_vector(7 downto 0); signal so_reg : out std_logic; signal so_on1 : out std_logic ) is variable t_reg : std_logic_vector(7 downto 0); begin report " Read loop entered "; if (mem_no = 1) then t_reg := to_stdlogicvector(buf1(current_address)); elsif (mem_no = 2) then t_reg := to_stdlogicvector(buf2(current_address)); elsif (mem_no = 10) then t_reg := to_stdlogicvector(memory(current_address)); else end if; read_loop : loop for i in 7 downto 0 loop wait until (SCK'EVENT and SCK = '0') or (CSB'EVENT and CSB = '1'); report " entered into for loop of read_out"; exit read_loop when (CSB = '1'); wait for Tv; SO_reg <= t_reg(i); so_on1 <= '1'; end loop; current_address := current_address + 1; report "comes out from for loop of read_out--------------------"; if (current_address > page_boundary_high) then current_address := page_boundary_low; end if; if (mem_no = 1) then t_reg := to_stdlogicvector(buf1(current_address)); elsif (mem_no = 2) then t_reg := to_stdlogicvector(buf2(current_address)); elsif (mem_no = 10) then t_reg := to_stdlogicvector(memory(current_address)); end if; end loop; wait for Tdis; SO_reg <= '0'; so_on1 <= '0'; report " Read loop exited"; end read_out; procedure read_out_x(signal CSB, sck : in std_logic; signal so_reg, so_on1 : out std_logic ) is begin report " Readx loop entered "; so_on1 <= '0'; read_loopx : loop wait until (SCK'EVENT and SCK = '0') or (CSB'EVENT and CSB = '1'); exit read_loopx when (CSB = '1'); wait for Tv; SO_reg <= 'X'; so_on1 <= '1'; end loop; wait for Tdis; SO_reg <= '0'; so_on1 <= '0'; report " Readx loop exited"; end read_out_x; procedure read_out_array(signal SCK, CSB : in std_logic; page_size : in integer range 1 to 1056; mem_size : in integer range 1 to 69206016; page_boundary_low : in integer; page_boundary_high : in integer; current_address : in integer; signal memory : in memtype; signal so_reg : out std_logic; signal so_on1 : out std_logic ) is variable t_reg_array : std_logic_vector(7 downto 0); variable temp_high : integer; variable temp_low : integer; variable temp_add : integer; begin report " Read_array loop entered "; temp_high := page_boundary_high; temp_low := page_boundary_low; temp_add := current_address; t_reg_array := to_stdlogicvector(memory(temp_add)); read_array_loop : loop for i in 7 downto 0 loop wait until (SCK'EVENT and SCK = '0') or (CSB'EVENT and CSB = '1'); exit read_array_loop when (CSB = '1'); wait for Tv; SO_reg <= t_reg_array(i); so_on1 <= '1'; end loop; report "read_array procedure----------------------------------------------------"; temp_add := temp_add + 1; if (temp_add >= N) then temp_add := 0; --Note that rollover occurs at end of memory, temp_high := pagesize(device, binary_page) - 1; -- and not at the end of the page temp_low := 0; end if; if (temp_add > temp_high) then -- going to next page temp_high := temp_high + pagesize(device, binary_page); temp_low := temp_low + pagesize(device, binary_page); end if; t_reg_array := to_stdlogicvector(memory(temp_add)); end loop; wait for Tdis; SO_reg <= '0'; so_on1 <= '0'; report " Read_array loop exited "; end read_out_array; procedure transfer_to_buffer( buf_type : in integer; page_boundary_low : in integer; signal memory : in memtype; signal buf1 : inout buffer1; signal buf2 : inout buffer2 ) is begin report " transfer to buffer entered "; if (buf_type = 1) then for i in 0 to pagesize(device, binary_page) - 1 LOOP buf1(i) <= memory(page_boundary_low + i); end loop; elsif (buf_type = 2) then for i in 0 to pagesize(device, binary_page) - 1 loop buf2(i) <= memory(page_boundary_low + i); end loop; else report "Int Error 2. This message should never appear"; end if; report " transfer to buffer exited "; end transfer_to_buffer; procedure compare_with_buffer(buf_type : in integer; page_boundary_low : in integer; signal memory : in memtype; signal buf1 : in buffer1; signal buf2 : in buffer2; signal status : out std_logic ) is variable tmp1, tmp2 : bit_vector(7 downto 0); begin report " compare with buf entered "; status <= '0'; if (buf_type = 1) then for i in 0 to pagesize(device, binary_page) - 1 loop tmp1 := memory(page_boundary_low + i); tmp2 := buf1(i); for k in 0 to 7 loop if (tmp1(k) /= tmp2(k)) then status <= '1'; exit; end if; end loop; end loop; elsif (buf_type = 2) then for i in 0 to pagesize(device, binary_page) - 1 loop tmp1 := memory(page_boundary_low + i); tmp2 := buf2(i); for k in 0 to 7 loop if (tmp1(k) /= tmp2(k)) then status <= '1'; exit; end if; end loop; end loop; else report "Int error 3. This message should never appear"; end if; report " compare with exited "; end compare_with_buffer; -----------write_data------------ procedure write_data(current_address : inout integer; page_boundary_low : in integer; page_boundary_high : in integer; signal buf1 : inout buffer1; signal buf2 : inout buffer2; buf_type : in integer; signal CSB, SCK, SI : in std_logic ) is variable buf_temp_reg : std_logic_vector(7 downto 0); variable temp : std_logic := '0'; begin report "first time entering "; write_loop : loop if (CSB = '0') then for i in 7 downto 0 loop wait until (SCK'EVENT and SCK = '1') or (CSB'EVENT and CSB = '1'); exit write_loop when (CSB = '1'); buf_temp_reg(i) := SI; end loop; if (buf_type = 1) then buf1(current_address) <= To_bitvector(buf_temp_reg, '0'); elsif (buf_type = 2) then buf2(current_address) <= To_bitvector(buf_temp_reg, '0'); end if; current_address := current_address + 1; wait for 1 ps; if (current_address > page_boundary_high) then current_address := page_boundary_low; wait for 1 ps; end if; end if; end loop; report " loop exited"; end write_data; ------------------check_protection------------- function check_protect( page1 : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0); page_per_sector : in integer; signal prot_status : in std_logic_vector(sec_tors(device) downto 0); sector : in std_logic_vector(s_address(device) - 1 downto 0); WPB, soft_prot_enabled : in std_logic ) return std_logic is variable protecteds : std_logic; begin protecteds := '0'; if ((WPB = '0') or (soft_prot_enabled = '1')) then if (conv_integer(page1) < 8) then protecteds := prot_status(0); elsif (page1 < PAGE_PER_SECTOR) then protecteds := prot_status(1); else protecteds := prot_status(conv_integer(sector) + 1); end if; end if; return protecteds; end check_protect; --------------check lock down--------- function check_lockd( page1 : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0); page_per_sector : in integer; signal lock_status : in std_logic_vector(sec_tors(device) downto 0); sector : in std_logic_vector(s_address(device) - 1 downto 0) ) return std_logic is variable locked : std_logic; begin locked := '0'; if (page1 < 8) then locked := lock_status(0); elsif (page1 < PAGE_PER_SECTOR) then locked := lock_status(1); else locked := lock_status(conv_integer(sector) + 1); end if; return locked; end check_lockd; ----------write_to_memory---------- procedure write_to_memory(buf_type : in integer; page : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0); page_size : in integer range 1 to 1056; signal buf1 : in buffer1; signal buf2 : in buffer2; page_boundary_low : in integer; signal memory : inout memtype ) is begin report " write to memory entered "; if (buf_type = 1) then for i in 0 to page_size - 1 loop memory(page_boundary_low + i) <= buf1(i); end loop; elsif (buf_type = 2) then for i in 0 to page_size - 1 loop memory(page_boundary_low + i) <= buf2(i); end loop; end if; report " write to memory exited "; end write_to_memory; procedure erase_page( page : in std_logic_vector((P_ADDRESS(device)) - 1 DOWNTO 0); page_size : in integer range 1 to 1056; page_boundary_low : in integer; signal memory : inout memtype; signal page_status : out std_logic ) is variable buf1 : buffer1; variable buf2 : buffer2; variable mem : memtype; begin report " erase page entered "; for i in 0 to pagesize(device, binary_page) - 1 loop memory(page_boundary_low + i) <= (others => '1'); page_status <= '0'; end loop; report " erase page exited "; end erase_page; ----------read_out_reg-------- procedure read_out_reg(reg_type : in integer; add : in integer; high : in integer; signal prot_reg : in prot_type; signal lock_reg : in lock_type; signal security_reg : in security_type; signal CSB, SCK : in std_logic; signal so_reg : out std_logic; signal so_on1 : out std_logic ) is variable temp_add : integer; variable t_reg1 : std_logic_vector(7 downto 0); begin report " Read out reg loop entered "; temp_add := add; if (reg_type = 21) then t_reg1 := to_stdlogicvector(prot_reg(temp_add)); elsif (reg_type = 22) then t_reg1 := to_stdlogicvector(lock_reg(temp_add)); elsif (reg_type = 23) then t_reg1 := to_stdlogicvector(security_reg(temp_add)); end if; read_out_reg_loop : loop for i in 7 downto 0 loop wait until (SCK'EVENT and SCK = '0') or (CSB'EVENT and CSB = '1'); exit read_out_reg_loop when (CSB = '1'); wait for Tv; so_reg <= t_reg1(i); so_on1 <= '1'; end loop; temp_add := temp_add + 1; if (temp_add > high) then t_reg1 := (others => 'X'); else if (reg_type = 21) then t_reg1 := to_stdlogicvector(prot_reg(temp_add)); elsif (reg_type = 22) then t_reg1 := to_stdlogicvector(lock_reg(temp_add)); elsif (reg_type = 23) then if (temp_add < 64) then t_reg1 := to_stdlogicvector(security_reg(temp_add)); else t_reg1 := to_stdlogicvector(factory_reg(temp_add - 64)); end if; end if; end if; end loop; wait for Tdis; so_reg <= '0'; so_on1 <= '0'; report " Read out reg loop exited "; end read_out_reg; function getbyte( signal IP : in bit_vector(511 downto 0); byte_num : in integer ) return bit_vector is variable temp : bit_vector(7 downto 0); begin for i in 0 to 7 loop report "entering into getbyte"; temp(i) := IP((byte_num - 1) * 8 + i); end loop; report "getbyte exited"; return temp; end getbyte; --******************************************--- --******************************************-- ------shared variable declarations----------- shared variable buf_temp_reg1 : std_logic_vector(7 downto 0); shared variable message : string(1 to 21); shared variable message2 : string(1 to 30); shared variable current_address : integer; shared variable page_boundary_low : integer; shared variable page_boundary_high : integer; shared variable mem_no : integer; signal temp_prot_status_program : bit_vector(sec_tors(device) - 2 downto 0); signal temp_reg1 : std_logic_vector(7 downto 0); signal reset_sig : std_logic := '0'; signal skip : std_logic := '1'; signal skip_be : std_logic := '0'; signal skip_end : std_logic := '0'; signal opcode_temp : std_logic_vector(7 downto 0) := "00000000"; signal page_addr0 : std_logic_vector(7 downto 0) := "00000000"; signal page_addr1 : std_logic_vector(7 downto 0) := "00000000"; signal byte_addr : std_logic_vector(7 downto 0) := "00000000"; signal t : std_logic_vector(31 downto 0) := "00000000000000000000000000000000"; signal prot_temp_reg : std_logic_vector(7 downto 0); signal lock_temp_reg : std_logic_vector(7 downto 0); signal rd_data1 : std_logic_vector(7 downto 0); signal less_than_60mhz : std_logic := '0'; signal buffer1read : std_logic := '0'; signal oPC7 : std_logic; signal arr_rd_dummybyte : integer := 0; signal buff_rd_dummybyte : integer := 0; signal RDPD : std_logic := '0'; signal EDPD : std_logic := '0'; signal MMPR : std_logic := '0'; signal updating_buffer1 : std_logic := '0'; signal updating_buffer2 : std_logic := '0'; ---------------UPDATING MEMORY----------- signal updating_memory : std_logic := '0'; signal comparing : std_logic := '0'; signal erasing_page : std_logic := '0'; signal erasing_block : std_logic := '0'; signal erasing_sector : std_logic := '0'; signal erasing_chip : std_logic := '0'; signal fast_mode : std_logic := '0'; signal IntCSb : std_logic; constant valid : Boolean := TRUE; signal MIR : std_logic := '0'; signal SRR : std_logic := '0'; signal mem_initialized : std_logic; signal deep_power_down : std_logic := '0'; signal SR : std_logic := '0'; signal RDYBSY_reg : std_logic := '1'; signal foreground_op_enable : std_logic := '0'; signal background_op_enable : std_logic := '0'; signal status_read : std_logic := '0'; signal so_reg : std_logic := '1'; signal so_on : std_logic := '0'; signal so_reg1 : std_logic := '1'; signal so_on1 : std_logic := '0'; signal so_reg2 : std_logic := '1'; signal so_on2 : std_logic := '0'; signal so_reg3 : std_logic := '1'; signal so_on3 : std_logic := '0'; signal status : std_logic_vector(7 downto 0) := ('1' & '0' & Device_sel3(DEVICE) & Device_sel2(DEVICE) & Device_sel1(DEVICE) & '1' & '0' & '0'); -----------status signal------------- signal status_B1C_s6 : std_logic; signal status_B2C_s6 : std_logic; --------- signal lock_status : std_logic_vector(sec_tors(device) downto 0); --**************** begin of Architecture **************--- begin --comparing the opcodes-- process(SCK, SI, CSB) begin if (CSB = '1') then t <= "00000000000000000000000000000000"; rd_data1 <= "00000000"; elsif (SCK = '1' and SCK'event) then t(0) <= '1'; t(1) <= t(0); t(2) <= t(1); t(3) <= t(2); t(4) <= t(3); t(5) <= t(4); t(6) <= t(5); t(7) <= t(6); -- t(6) == 1 and t(7) ==0 opcode t(8) <= t(7); t(9) <= t(8); t(10) <= t(9); t(11) <= t(10); t(12) <= t(11); t(13) <= t(12); t(14) <= t(13); t(15) <= t(14); -- t(14) == 1 and t(15) ==0 page address t(16) <= t(15); t(17) <= t(16); t(18) <= t(17); t(19) <= t(18); t(20) <= t(19); t(21) <= t(20); t(22) <= t(21); t(23) <= t(22); -- t(22) == 1 and t(23) ==0 page address t(24) <= t(23); t(25) <= t(24); t(26) <= t(25); t(27) <= t(26); t(28) <= t(27); t(29) <= t(28); t(30) <= t(29); t(31) <= t(30); -- t(30) == 1 and t(31) == 0 byte address rd_data1(0) <= SI; rd_data1(1) <= rd_data1(0); rd_data1(2) <= rd_data1(1); rd_data1(3) <= rd_data1(2); rd_data1(4) <= rd_data1(3); rd_data1(5) <= rd_data1(4); rd_data1(6) <= rd_data1(5); rd_data1(7) <= rd_data1(6); end if; end process; opcode_temp <= rd_data1(6) & rd_data1(5) & rd_data1(4) & rd_data1(3) & rd_data1(2) & rd_data1(1) & rd_data1(0) & SI; process(SCK, opcode_temp, t) begin if (CSB = '1') then page_addr0 <= "00000000"; page_addr1 <= "00000000"; byte_addr <= "00000000"; elsif ((SCK = '1' and SCK'event)) then if (t(14) = '1' and t(15) = '0') then page_addr0 <= opcode_temp; end if; if (t(22) = '1' and t(23) = '0') then page_addr1 <= opcode_temp; end if; if (t(30) = '1' and t(31) = '0') then byte_addr <= opcode_temp; end if; end if; end process; process(SCK, opcode_temp, t) begin if (CSB = '1') then skip <= '1'; arr_rd_dummybyte <= 0; --not used in their code buff_rd_dummybyte <= 0; MMPR <= '0'; MMCAR <= '0'; EDPD <= '0'; buffer1read <= '0'; --buffer1read legacy command buffer2read <= '0'; --buffer 2 read for low frequency MMPTB1T <= '0'; --Main Memory Page To Buffer 1 Transfer MMPTB2T <= '0'; --Main Memory Page To Buffer 2 Transfer MMPTB1C <= '0'; --Main Memory Page To Buffer 1 Compare MMPTB2C <= '0'; --Main Memory Page To Buffer 2 Compare B1W <= '0'; -- Buffer 1 Write B2W <= '0'; B1TMMPPWBIE <= '0'; --Buffer 1 To Main Memory Page Prog With Built-In Erase fast_mode <= '0'; B2TMMPPWBIE <= '0'; --Buffer 2 To Main Memory Page Prog With Built-In Erase B1TMMPPWOBIE <= '0'; --Buffer 1 To Main Memory Page Prog Without Built-In Erase B2TMMPPWOBIE <= '0'; --Buffer 2 To Main Memory Page Prog Without Built-In Erase PE <= '0'; -- Page Erase BE <= '0'; -- Block Erase SE <= '0'; -- Sector Erase oPC7 <= '0'; -- 4-byte command starting with C7 MMPPB1 <= '0'; -- Main Memory Page Prog. Through Buffer 1 MMPPB2 <= '0'; -- Main Memory Page Prog. Through Buffer 2 APRB1 <= '0'; -- Auto Page Rewrite Through Buffer 1 APRB2 <= '0'; -- Auto Page Rewrite Through Buffer 2 SR <= '0'; -- Status Register Read MIR <= '0'; -- Manufecturing ID Read oP3D <= '0'; -- 4-Byte Opcode Starting From 3d PRR <= '0'; -- Protection Register Read LRR <= '0'; -- Lock_down Register Read SRR <= '0'; -- Security Register Read OP9B <= '0'; -- 4-Byte Opcode Starting From 9B RDPD <= '0'; elsif (SCK = '1' and SCK'event) then if (t(6) = '1' and t(7) = '0') then if (foreground_op_enable = '0') then message := "opcode is not allowed"; elsif (deep_power_down = '1') then if (opcode_temp = X"AB") then RDPD <= '1'; else message := "opcode is not allowed"; end if; else for i in 0 to 7 loop report "OPCODE = " & std_logic'image(opcode_temp(i)) severity note; end loop; case opcode_temp is when X"D2" => if (RDYBSY_reg = '1') then skip <= '0'; arr_rd_dummybyte <= 4; MMPR <= '1'; end if; when X"52" => if (RDYBSY_reg = '1') then skip <= '0'; arr_rd_dummybyte <= 4; MMPR <= '1'; end if; when X"03" => if (RDYBSY_reg = '1') then skip <= '0'; arr_rd_dummybyte <= 0; MMCAR <= '1'; end if; when X"0B" => if (RDYBSY_reg = '1') then skip <= '0'; arr_rd_dummybyte <= 1; MMCAR <= '1'; end if; when X"E8" => if (RDYBSY_reg = '1') then skip <= '0'; arr_rd_dummybyte <= 4; MMCAR <= '1'; end if; when X"68" => if (RDYBSY_reg = '1') then skip <= '0'; arr_rd_dummybyte <= 4; MMCAR <= '1'; end if; when X"54" => skip <= '0'; arr_rd_dummybyte <= 0; buffer1read <= '1'; --buffer1read legacy command when X"D1" => buff_rd_dummybyte <= 0; skip <= '0'; buffer1read <= '1'; --buffer1read with low frequency when X"D4" => skip <= '0'; buff_rd_dummybyte <= 1; buffer1read <= '1'; when X"56" => buffer2read <= '1'; when X"D3" => skip <= '0'; buffer2read <= '1'; --buffer 2 read for low frequency buff_rd_dummybyte <= 0; when X"D6" => skip <= '0'; buff_rd_dummybyte <= 1; buffer2read <= '1'; when X"53" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else MMPTB1T <= '1'; --Main Memory Page To Buffer 1 Transfer end if; when X"55" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else MMPTB2T <= '1'; --Main Memory Page To Buffer 2 Transfer end if; when X"60" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else MMPTB1C <= '1'; --Main Memory Page To Buffer 1 Compare end if; when X"61" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else MMPTB2C <= '1'; --Main Memory Page To Buffer 2 Compare end if; when X"84" => B1W <= '1'; -- Buffer 1 Write when X"87" => B2W <= '1'; -- Buffer 2 Write when X"83" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else B1TMMPPWBIE <= '1'; --Buffer 1 To Main Memory Page Prog With Built-In Erase end if; when X"93" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else fast_mode <= '1'; B1TMMPPWBIE <= '1'; --Buffer 1 To Main Memory Page Prog With Built-In Erase end if; -- t(14) == 1 and t(15) ==0 page address when X"86" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else B2TMMPPWBIE <= '1'; -- t(14) == 1 and t(15) ==0 page address --Buffer 2 To -- Main Memory Page Prog With Built-In Erase end if; when X"96" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else fast_mode <= '1'; -- t(14) == 1 and t(15) ==0 page address B2TMMPPWBIE <= '1'; --Buffer 2 To Main Memory Page Prog With Built-In Erase end if; when X"88" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else B1TMMPPWOBIE <= '1'; --- t(14) == 1 and t(15) ==0 page address -Buffer 1 To --Main Memory Page Prog Without Built-In Erase end if; when X"98" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then -- t(14) == 1 and t(15) ==0 page address hen message := "opcode is not allowed"; else fast_mode <= '1'; B1TMMPPWOBIE <= '1'; --Buffer 1 To Main Memory Page Prog Without Built-In Erase -- t(14) == 1 and t(15) ==0 page address -- not in document end if; when X"89" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else fast_mode <= '1'; B2TMMPPWOBIE <= '1'; --Buffer 2 To Main Memory Page Prog Without Built-In Erase end if; when X"99" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else B2TMMPPWOBIE <= '1'; --Buffer 2 To Main Memory Page Prog Without Built-In Erase -- not in document end if; when X"81" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else PE <= '1'; -- Page Erase end if; when X"50" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else BE <= '1'; -- Block Erase end if; when X"7C" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else SE <= '1'; -- Sector Erase end if; when X"C7" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else oPC7 <= '1'; -- 4-byte command starting with C7 end if; when X"82" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else MMPPB1 <= '1'; -- Main Memory Page Prog. Through Buffer 1 end if; when X"92" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else fast_mode <= '1'; MMPPB1 <= '1'; -- Main Memory Page Prog. Through Buffer 1 end if; when X"85" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else MMPPB2 <= '1'; -- Main Memory Page Prog. Through Buffer 2 end if; when X"95" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else fast_mode <= '1'; MMPPB2 <= '1'; -- Main Memory Page Prog. Through Buffer 2 end if; when X"58" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else APRB1 <= '1'; -- Auto Page Rewrite Through Buffer 1 end if; when X"59" => if (background_op_enable = '0') then message := "opcode is not allowed"; elsif (RDYBSY_reg = '0') then message := "opcode is not allowed"; else APRB2 <= '1'; -- Auto Page Rewrite Through Buffer 2 end if; when X"57" => SR <= '1'; -- Status Register Read when X"D7" => skip <= '0'; SR <= '1'; -- Status Register Read when X"9F" => report "IDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" severity note; skip <= '0'; MIR <= '1'; -- Manufecturing ID Read when X"3D" => if (background_op_enable = '0') then message := "opcode is not allowed"; else oP3D <= '1'; -- 4-Byte Opcode Starting From 3d end if; when X"32" => if (RDYBSY_reg = '1') then PRR <= '1'; -- Protection Register Read end if; when X"35" => if (RDYBSY_reg = '1') then LRR <= '1'; -- Lock_down Register Read end if; when X"77" => if (RDYBSY_reg = '1') then SRR <= '1'; -- Security Register Read end if; when X"9B" => if (background_op_enable = '0') then message := "opcode is not allowed"; else oP9B <= '1'; -- 4-Byte Opcode Starting From 9B end if; when X"B9" => if (background_op_enable = '0') then message := "opcode is not allowed"; else EDPD <= '1'; -- enable deep power down end if; when others => message := "Unrecognized opcode "; end case; end if; end if; end if; end process; process(SCK, CSB) begin if (CSB = '0' and CSB'event) then if (SCK = '0') then skip_be <= '1'; else skip_be <= '0'; end if; end if; end process; skip_end <= skip_be and skip; background_op_enable <= '1' after tPUW; reset_sig <= '0', '1' after 1 ns; process variable inbuf : line; variable outbuf : line; --file LOAD_FILE1 : text open read_mode is "./memory.txt"; file LOAD_FILE1 : text open read_mode is flashmemory; file OUT_FILE : text open write_mode is "./memory_out.txt"; variable numword : integer := 0; variable word : string(1 to 8); variable mem : memtype; variable i : integer; variable value : bit_vector(7 downto 0); ---------- variable inbuf1 : line; --file LOAD_FILE2 : text open read_mode is "protection.txt"; --file LOAD_FILE2 : text open read_mode is protection; variable numword1 : integer := 0; variable value1 : bit_vector(7 downto 0); variable protect : prot_type; variable jerase : integer; variable temp_prot : bit_vector(sec_tors(device) downto 0); --------------- variable inbuf2 : line; variable outbuf12 : line; --file LOAD_FILE3 : text open read_mode is "lockdown.txt"; --file LOAD_FILE3 : text open read_mode is lockdown; variable numword2 : integer := 0; variable value2 : bit_vector(7 downto 0); --------------------- variable inbuf3 : line; --file LOAD_FILE4 : text open read_mode is "factory.txt"; --file LOAD_FILE4 : text open read_mode is factory; variable numword3 : integer := 0; variable value3 : bit_vector(7 downto 0); ------------------ variable locked : std_logic := '0'; variable protecteds : std_logic := '0'; variable MMPPB1_mem_page : std_logic_vector(p_address(device) - 1 downto 0); variable MMPPB1_buf_page : std_logic_vector(p_address(device) - 1 downto 0); variable MMPPB2_mem_page : std_logic_vector(p_address(device) - 1 downto 0); variable MMPPB2_buf_page : std_logic_vector(p_address(device) - 1 downto 0); variable temp_lock : bit_vector(sec_tors(device) downto 0); variable temp_lock_reg : lock_type; begin if (foreground_op_enable = '0') then ---- Enable foreground op_codes wait on reset_sig; report " initialization"; wait for 1 ps; for i in 0 to (memsize(pagesize(device, binary_page), page_cal(device)) - 1) loop memory(i) <= (others => '1'); end loop; mem_initialized <= '0'; wait for 1 ps; while not ENDFILE(LOAD_FILE1) loop report " memory initialization"; READLINE(LOAD_FILE1, inbuf); hexa_to_bit_vector(inbuf, 8, value); memory(numword) <= value; WRITE(outbuf, memory(numword)); WRITELINE(OUT_FILE, outbuf); numword := numword + 1; if (numword = (N - 1)) then exit; end if; mem_initialized <= '1'; end loop; wait for 1 ps; if (mem_initialized = '1') then for j in 0 to page_cal(device) - 1 loop page_status(j) <= '1'; -- memory was initialized, so, Pages are Not Erased. end loop; else for j in 0 to page_cal(device) - 1 loop page_status(j) <= '0'; end loop; end if; wait for 1 ps; ------------initialization of protection reg------------- --while not ENDFILE(LOAD_FILE2) loop --report " protection reg initialization"; --READLINE(LOAD_FILE2,inbuf1); --hexa_to_bit_vector(inbuf1, 8, value1); --prot_reg(numword1) <= value1; --numword1 := numword1 + 1; --if(numword1 > (p-1)) then --exit; --end if; --end loop; for i in 0 to SEC_TORS(device) - 1 loop report "protection intialization"; prot_reg(i) <= getbyte(protection, i + 1); report "lockdown initialization"; lock_reg(i) <= getbyte(lockdown, i + 1); end loop; wait for 1 ps; prot_temp_reg <= To_stdlogicvector(prot_reg(0)); prot_status(0) <= prot_temp_reg(7) and prot_temp_reg(6); prot_status(1) <= prot_temp_reg(5) and prot_temp_reg(4); for j in 1 to SEC_TORS(device) - 1 loop temp_prot(j + 1) := prot_reg(j)(0) and prot_reg(j)(1) and prot_reg(j)(2) and prot_reg(j)(3) and prot_reg(j)(4) and prot_reg(j)(5) and prot_reg(j)(6) and prot_reg(j)(7); end loop; prot_status <= To_stdlogicvector(temp_prot); wait for 10 ps; -------------initialization of lock reg----------- --while not ENDFILE(LOAD_FILE3) loop --report " lock reg initialization"; --READLINE(LOAD_FILE3,inbuf2); --hexa_to_bit_vector(inbuf2, 8, value2); --lock_reg(numword2) <= value2; --numword2 := numword2 + 1; --if(numword2 > (p-1)) then --exit; --end if; --end loop; wait for 1 ps; lock_temp_reg <= To_stdlogicvector(lock_reg(0)); lock_status(0) <= lock_temp_reg(7) and lock_temp_reg(6); lock_status(1) <= lock_temp_reg(5) and lock_temp_reg(4); for j in 1 to SEC_TORS(device) - 1 loop temp_lock(j + 1) := lock_reg(j)(0) and lock_reg(j)(1) and lock_reg(j)(2) and lock_reg(j)(3) and lock_reg(j)(4) and lock_reg(j)(5) and lock_reg(j)(6) and lock_reg(j)(7); end loop; lock_status <= To_stdlogicvector(temp_lock); ---------------initialization of factory reg------------ wait for 1 ps; --while not ENDFILE(LOAD_FILE4) loop --report " factory initialization"; --READLINE(LOAD_FILE4,inbuf3); --hexa_to_bit_vector(inbuf3, 8, value3); --factory_reg(numword3) <= value3; --numword3 := numword3 + 1; --if(numword3 > 64) then --exit; --end if; --end loop; for j in 0 to 63 loop factory_reg(j) <= getbyte(factory, j + 1); security_reg(j) <= getbyte(security, j + 1); wait for 1 ps; security_flag <= '0'; if (security_reg(j) /= X"FF") then security_flag <= '1'; end if; end loop; wait for 1 ps; --************************** wait for tVCSL; foreground_op_enable <= '1'; ---- Enable foreground op_codes report " forground enable"; end if; --************************** wait on t(31); report " t31 asserted"; if (MMPR = '1' and t(31) = '1') then report "entered into MMPR "; message := "opcodeFis not allowed"; if (Rapid_interface = false and fsck > 50) then report "WARNING: Frequency should be less than 50MHz for SPI interface type . Main Memory Page Read is not allowed"; end if; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); -- pass by 32 cycles or 4 bytes in the case of serial interface wait for (Twl + Twl) * 32; if (Rapid_interface = false and fsck > 50) then read_out_x(CSB, SCK, so_reg, so_on); else read_out(SCK, CSB, page_boundary_low, page_boundary_high, current_address, mem_no, tbuffer1, tbuffer2, memory, so_reg, so_on); end if; report "MMPR is exited "; elsif (MMCAR = '1' and t(31) = '1') then report "entered into MMCAR "; if ((Rapid_interface = false) and (fSCK > 50) and (arr_rd_dummybyte /= 0)) then report "WARNING: Frequency should be less than 50MHz for SPI interface type . Main Memory Page Read is not allowed"; end if; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); if (((arr_rd_dummybyte = 0) and (fSCK >= 20)) or ((Rapid_interface = false) and (fSCK > 50) and (arr_rd_dummybyte /= 0))) then read_out_x(CSB, SCK, so_reg, so_on); elsif (arr_rd_dummybyte = 1) then wait for (Twl + Twh) * 8; read_out_array(SCK, CSB, pagesize(device, binary_page), memsize(pagesize(device, binary_page), page_cal(device)), page_boundary_low, page_boundary_high, current_address, memory, so_reg, so_on); else wait for (Twl + Twh) * 32; read_out_array(SCK, CSB, pagesize(device, binary_page), memsize(pagesize(device, binary_page), page_cal(device)), page_boundary_low, page_boundary_high, current_address, memory, so_reg, so_on); end if; report "MMCAR is exited "; elsif (buffer1read = '1' and t(31) = '1') then report "entered into buffer1read"; if ((Rapid_interface = false) and (fSCK > 50) and (buff_rd_dummybyte /= 0)) then report "WARNING: Frequency should be less than 50MHz for SPI interface type . Buffer1 Read is not allowed"; end if; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); --if(buff_rd_dummybyte = 0 and less_than_33mhz ='0')then if (((buff_rd_dummybyte = 0) and (fSCK >= 20)) or ((Rapid_interface = false) and (fSCK > 50) and (buff_rd_dummybyte /= 0))) then read_out_x(CSB, SCK, so_reg, so_on); else -- pass by 8 cycles or one serial byte wait for (Twl + Twh) * 8; read_out(SCK, CSB, page_boundary_low, page_boundary_high, current_address, 1, tbuffer1, tbuffer2, memory, so_reg, so_on); end if; report "buffer1read exited"; elsif (buffer2read = '1' and t(31) = '1') then report "entered into buffer2read"; if ((Rapid_interface = false) and (fSCK > 50) and (buff_rd_dummybyte /= 0)) then report "WARNING: Frequency should be less than 50MHz for SPI interface type . Buffer1 Read is not allowed"; end if; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); --if(buff_rd_dummybyte = 0 and less_than_33mhz ='0')then if (((buff_rd_dummybyte = 0) and (fSCK >= 20)) or ((Rapid_interface = false) and (fSCK > 50) and (buff_rd_dummybyte /= 0))) then read_out_x(CSB, SCK, so_reg, so_on); else -- pass by 8 cycles wait for (Twl + Twh) * 8; read_out(SCK, CSB, page_boundary_low, page_boundary_high, current_address, 2, tbuffer1, tbuffer2, memory, so_reg, so_on); end if; report "buffer2read exited"; elsif (MMPTB1T = '1' and t(31) = '1') then report " entered into MMPTB1T"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; transfer_to_buffer(1, page_boundary_low, memory, tbuffer1, tbuffer2); updating_buffer1 <= '1'; wait for Txfr; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; updating_buffer1 <= '0'; report " MMPTB1T exited"; elsif (MMPTB2T = '1' and t(31) = '1') then report " entered into MMPTB2T"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; transfer_to_buffer(2, page_boundary_low, memory, tbuffer1, tbuffer2); updating_buffer2 <= '1'; wait for Txfr; RDYBSY_reg <= '1'; -- after tXFR ; -- device is now ready status(7) <= '1'; updating_buffer2 <= '0'; report " MMPTB2T exited"; elsif (MMPTB1C = '1' and t(31) = '1') then report " entered in to MMPTB1C"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; compare_with_buffer(1, page_boundary_low, memory, tbuffer1, tbuffer2, status_B1C_s6); comparing <= '1'; wait for tXFR; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; status(6) <= status_B1C_s6; comparing <= '0'; report " MMPTB1C is exited"; elsif (MMPTB2C = '1') then report " entered in to MMPTB2C"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; compare_with_buffer(2, page_boundary_low, memory, tbuffer1, tbuffer2, status_B2C_s6); comparing <= '1'; wait for tXFR; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; status(6) <= status_B2C_s6; comparing <= '0'; report " MMPTB2C is exited"; elsif (B1W = '1' and t(31) = '1') then report "B1write"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 1, CSB, sck, SI); report "B1write end"; elsif (B2W = '1' and t(31) = '1') then compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); report "B2write"; write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 2, CSB, sck, SI); elsif (B1TMMPPWBIE = '1' and t(31) = '1') then report "B1TMMPPWBIE"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); locked := check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))); protecteds := check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled); if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then wait until CSB = '1'; RDYBSY_reg <= '0'; -- device is busy status(7) <= '0'; write_to_memory(1, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory); page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= '1'; message2 := "weCan write page is not locked"; updating_memory <= '1'; wait for tEP; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; updating_memory <= '0'; else wait until CSB = '1'; message2 := "Cannot write page is protecteds"; end if; else wait until CSB = '1'; message2 := " Cannot write page is Locked "; end if; elsif (B2TMMPPWBIE = '1' and t(31) = '1') then report "B2TMMPPWBIE"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); locked := check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))); protecteds := check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled); if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; -- device is busy status(7) <= '0'; write_to_memory(2, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory); page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= '1'; updating_memory <= '1'; wait for tEP; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; message2 := "weCan write page is not locked"; updating_memory <= '0'; else wait until CSB'event and CSB = '1'; message2 := " Cannot write page isprotecteds"; end if; else wait until CSB'event and CSB = '1'; message2 := " Cannot write page is Locked "; end if; elsif (B1TMMPPWOBIE = '1' and t(31) = '1') then report "B1TMMPPW0BIE"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then wait until CSB'event and CSB = '1'; if (page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then --page is already erased RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; updating_memory <= '1'; write_to_memory(1, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory); page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= '1'; if (fast_mode = '0') then wait for tP; RDYBSY_reg <= '1'; status(7) <= '1'; updating_memory <= '0'; else wait for tFP; RDYBSY_reg <= '1'; status(7) <= '1'; updating_memory <= '0'; end if; else message := "TryingtowriteintoPage"; end if; else wait until CSB'event and CSB = '1'; message2 := " Cannot write page isprotecteds"; end if; else wait until CSB'event and CSB = '1'; message2 := " Cannot write page is Locked "; end if; report "B1TMMPPW0BIE is exited"; elsif (B2TMMPPWOBIE = '1' and t(31) = '1') then report " entered into B2TMMPPW0BIE"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then wait until CSB'event and CSB = '1'; if (page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then --page is already erased RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; updating_memory <= '1'; write_to_memory(2, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory); page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= '1'; if (fast_mode = '0') then wait for tP; RDYBSY_reg <= '1'; status(7) <= '1'; updating_memory <= '0'; else wait for tFP; RDYBSY_reg <= '1'; status(7) <= '1'; updating_memory <= '0'; end if; else message := "TryingtowriteintoPage"; end if; else wait until CSB'event and CSB = '1'; message2 := " Cannot write page isprotecteds"; end if; else wait until CSB'event and CSB = '1'; message2 := " Cannot write page is Locked "; end if; report "B2TMMPPW0BIE is exited"; elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"A9") then report "entered into enable sector protection "; SPE <= '1'; wait until CSB'event and CSB = '1'; soft_prot_enabled <= '1'; status(1) <= '1'; SPE <= '0'; report "enable sector protection is exited"; elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"9A") then report "entered into disable sector protection "; SPD <= '1'; wait until CSB'event and CSB = '1'; if (WPB = '1') then soft_prot_enabled <= '0'; status(1) <= '0'; end if; SPD <= '0'; elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"CF") then report "entered into erase sector protection register PRE"; PRE <= '1'; wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; prot_reg(0) <= (others => '1'); prot_status(0) <= '1'; prot_status(1) <= '1'; wait for 1 ps; for j in 1 to sec_tors(device) - 1 loop prot_reg(j) <= (others => '1'); prot_status(j + 1) <= '1'; end loop; wait for Tpe; RDYBSY_reg <= '1'; status(7) <= '1'; PRE <= '0'; elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"FC") then report "program sector protection register PRP "; report "entered into PRP "; PRP <= '1'; current_address := 0; page_boundary_low := 0; page_boundary_high := sec_tors(device); write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 1, CSB, sck, SI); RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; wait for 1 ps; for j in 0 to sec_tors(device) - 1 loop prot_reg(j) <= (prot_reg(j) and tbuffer1(j)); end loop; wait for 1 ps; temp_reg1 <= To_stdlogicvector(prot_reg(0)); wait for 1 ps; for j in 0 to sec_tors(device) - 2 loop temp_prot_status_program(j) <= prot_reg(j)(0) and prot_reg(j)(1) and prot_reg(j)(2) and prot_reg(j)(3) and prot_reg(j)(4) and prot_reg(j)(5) and prot_reg(j)(6) and prot_reg(j)(7); end loop; wait for 1 ps; prot_status <= (To_stdlogicvector(temp_prot_status_program)) & (temp_reg1(5) and temp_reg1(4)) & (temp_reg1(7) and temp_reg1(6)); wait for Tp; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; wait for 1 ps; PRP <= '0'; report "PRP is exited "; elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"7F" and byte_addr = X"30") then report "entered into program sector lockdown register LRP "; LRP <= '1'; wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; -- device is busy status(7) <= '0'; if (conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))) < 8) then case (lock_status(1)) is when '0' => lock_reg(0) <= X"C0"; -- Sector 0a locked, 0b unlocked when '1' => lock_reg(0) <= X"F0"; -- Sectors 0a, 0b locked when others => message2 := "Thismessage shouldnever appear"; end case; lock_status(0) <= '1'; elsif (conv_integer(page) < PAGEPER_SECTOR(device)) then case (lock_status(0)) is when '0' => lock_reg(0) <= X"30"; --Sector 0a unlocked, 0b locked when '1' => lock_reg(0) <= X"F0"; -- Sectors 0a, 0b locked when others => message2 := "Thismessage shouldnever appear"; end case; lock_status(1) <= '1'; else lock_reg(sec_tors(device) - 1) <= (others => '1'); lock_status(sec_tors(device)) <= '1'; end if; wait for Tp; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; LRP <= '0'; report "LRP is exited "; elsif (oP3D = '1' and t(31) = '1' and page_addr0 = X"2A" and page_addr1 = X"80" and byte_addr = X"A6") then report "entered binary page setup"; BPS <= '1'; wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; -- device is busy status(7) <= '0'; binary_page <= '1'; wait for Tp; RDYBSY_reg <= '1'; --device is now ready status(7) <= '1'; status(0) <= '1'; BPS <= '0'; report "binary page setup exited"; elsif (MMPPB1 = '1' and t(31) = '1' and RDYBSY_reg = '1') then report "MMPPB1"; MMPPB1_mem_page := comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)); -- page value has been stored for main memory page program MMPPB1_buf_page := (others => '0'); --buffer has zero pages compute_address(MMPPB1_buf_page, pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 1, CSB, sck, SI); -- this will write to buffer -- it will proceed to next step, when, posedge of CSB. -- This is complicated, and, hence, explained here: -- At posedge of CSB, the write_data will get disabled. -- At this time, writing to buffer needs to stop, and, -- writing into memory should start. if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then compute_address(MMPPB1_mem_page, pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); RDYBSY_reg <= '0'; -- device is busy status(7) <= '0'; write_to_memory(1, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory); page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= '1'; updating_memory <= '1'; wait for Tep; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; updating_memory <= '0'; else message2 := " Cannot write page is proted "; end if; else message2 := " Cannot write page is Locked "; end if; report " MMPPB1 exited"; elsif (MMPPB2 = '1' and t(31) = '1' and RDYBSY_reg = '1') then report "MMPPB2"; MMPPB2_mem_page := comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)); -- page value has been stored for main memory page program MMPPB2_buf_page := (others => '0'); --buffer has zero pages compute_address(MMPPB2_buf_page, pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 2, CSB, sck, SI); -- this will write to buffer -- it will proceed to next step, when, posedge of CSB. -- This is complicated, and, hence, explained here: -- At posedge of CSB, the write_data will get disabled. -- At this time, writing to buffer needs to stop, and, -- writing into memory should start. if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then compute_address(MMPPB2_mem_page, pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); RDYBSY_reg <= '0'; -- device is busy status(7) <= '0'; write_to_memory(2, comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), tbuffer1, tbuffer2, page_boundary_low, memory); page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= '1'; updating_memory <= '1'; wait for Tep; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; updating_memory <= '0'; else message2 := " Cannot write page is proted "; end if; else message2 := " Cannot write page is Locked "; end if; elsif (APRB1 = '1' and t(31) = '1') then report "ARPB1"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; transfer_to_buffer(1, page_boundary_low, memory, tbuffer1, tbuffer2); updating_buffer1 <= '1'; if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then updating_memory <= '1'; RDYBSY_reg <= '0'; status(7) <= '0'; wait for Tep; RDYBSY_reg <= '1'; status(7) <= '1'; updating_buffer1 <= '0'; updating_memory <= '0'; else message2 := " Cannot write page is proted "; end if; else message2 := " Cannot write page is Locked "; end if; -- NOTE: -- We dont need to rewrite the data back into main-memory, as the -- data is already available in the main-memory -- This task was exactly same as MMPTB1T, except the delay-value -- We could have easily used the same code as MMPTB1T, using -- an if condition for delay-selection. However, still doing -- this way, so that the code for each opcode is independent -- of anything else. report "APRB1 auto page rewrite is exited"; elsif (APRB2 = '1' and t(31) = '1') then report "entered into auto page rewrite through buffer 2 ARPB2"; compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; transfer_to_buffer(2, page_boundary_low, memory, tbuffer1, tbuffer2); updating_buffer1 <= '1'; if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then updating_memory <= '1'; RDYBSY_reg <= '0'; status(7) <= '0'; wait for Tep; RDYBSY_reg <= '1'; status(7) <= '1'; updating_buffer1 <= '0'; updating_memory <= '0'; else message2 := " Cannot write page is proted "; end if; else message2 := " Cannot write page is Locked "; end if; -- NOTE: -- We dont need to rewrite the data back into main-memory, as the -- data is already available in the main-memory -- This task was exactly same as MMPTB1T, except the delay-value -- We could have easily used the same code as MMPTB1T, using -- an if condition for delay-selection. However, still doing -- this way, so that the code for each opcode is independent -- of anything else. report " auto page rewrite through buffer 2 is exited"; ----------------page erase------------------ elsif (PE = '1') then report "entered into page erase"; if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), page_boundary_low, memory, temp_page_status); erasing_page <= '1'; page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; wait for Tpe; RDYBSY_reg <= '1'; --device is now ready status(7) <= '1'; erasing_page <= '0'; else message2 := " Cannot erase page is proted "; end if; else message2 := " Cannot erase page is locked "; end if; report "page erase exited"; --------------------------Block Erase------------------------- elsif (BE = '1') then report "entered into block erase"; if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; jerase := page_boundary_low; loop_erase : loop if (jerase < page_boundary_low + (8 * pagesize(device, binary_page))) then erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); --erase 8 pages, i.e. a block page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; jerase := jerase + pagesize(device, binary_page); else report "--------------------------Block Eraseexit -------------------------"; exit loop_erase; end if; end loop; for j in 0 to 7 loop --erase_page will only change the status of one-page page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))) + j) <= '0'; end loop; erasing_block <= '1'; wait for Tbe; RDYBSY_reg <= '1'; --device is now ready status(7) <= '1'; erasing_block <= '0'; else message2 := " Cannot erase bloc is proted "; end if; else message2 := " Cannot erase bloc is locked "; end if; report "block erase exited"; ---------------------------Sector Erase ----------------------------- elsif (SE = '1') then if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then compute_address(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), comp_byte_addr(b_address(device, binary_page), page_addr1, byte_addr, binary_page), page_boundary_low, page_boundary_high, current_address, mem_no, binary_page); wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; --******************************-- if (conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))) < 8) then page_boundary_low := 0; jerase := page_boundary_low; loop_sectorerase : loop if (jerase < page_boundary_low + 8 * pagesize(device, binary_page)) then erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); -- erase 8 pages, i.e. a block page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; jerase := jerase + pagesize(device, binary_page); else report "--------------------------sector Eraseexit -------------------------"; exit loop_sectorerase; end if; end loop; for j in 0 to 7 loop -- erase_page will only change the status of one-page page_status(j) <= '0'; end loop; --************************************---- elsif (comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)) < pageper_sector(device)) then page_boundary_low := 8 * pagesize(device, binary_page); jerase := page_boundary_low; loop_sector1erase : loop if (jerase < page_boundary_low + ((pageper_sector(device) - 8) * pagesize(device, binary_page))) then erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); --erase 248/120 pages, i.e. a block page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; jerase := jerase + pagesize(device, binary_page); else report "--------------------------sector1 Eraseexit -------------------------"; exit loop_sector1erase; end if; end loop; for j in 8 to pageper_sector(device) - 1 loop --erase_page will only change the status of one-page page_status(j) <= '0'; end loop; --**************************** else page((p_address(DEVICE) - s_address(DEVICE)) - 1) <= '0'; page_boundary_low := conv_integer(page) * pagesize(device, binary_page); jerase := page_boundary_low; loop_sector2erase : loop if (jerase < page_boundary_low + (pageper_sector(device) * pagesize(device, binary_page))) then jerase := jerase + pagesize(device, binary_page); erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); --erase 256/128 pages, i.e. a block page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; jerase := jerase + pagesize(device, binary_page); else report "--------------------------sector2 Eraseexit -------------------------"; exit loop_sector2erase; end if; end loop; for j in 0 to pageper_sector(device) - 1 loop page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))) + j) <= '0'; end loop; erasing_sector <= '1'; wait for Tse; RDYBSY_reg <= '1'; --device is now ready status(7) <= '1'; erasing_sector <= '0'; end if; else message2 := " Cannot erase sect is proted "; end if; else message2 := " Cannot erase sect is locked "; end if; ----------------------------------Chip Erase------------------------------------------- elsif (oPC7 = '1' and t(31) = '1') then report "enabling chip erase"; if (page_addr0 = X"94" and page_addr1 = X"80" and byte_addr = X"9A") then wait until CSB'event and CSB = '1'; RDYBSY_reg <= '0'; -- device is busy status(7) <= '0'; --sector x0A page <= (others => '0'); -- erase sector 0A sector <= (others => '0'); compute_address(page => page, page_size => pagesize(device, binary_page), byte => byte, page_boundary_low => page_boundary_low, page_boundary_high => page_boundary_high, current_address => current_address, mem_no => mem_no, binary_page => binary_page); if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then jerase := page_boundary_low; loop_chiperase : loop if (jerase < page_boundary_low + 8 * pagesize(device, binary_page)) then erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); -- erase 8 pages, i.e. a block page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; jerase := jerase + pagesize(device, binary_page); else report "--------------------------chip Eraseexit -------------------------"; exit loop_chiperase; end if; end loop; for j in 0 to 7 loop -- erase_page will only change the status of one-page page_status(j) <= '0'; end loop; end if; end if; -- second sector x0B page <= conv_std_logic_vector(8, p_address(DEVICE)); sector <= (others => '0'); compute_address(page => page, page_size => pagesize(device, binary_page), byte => byte, page_boundary_low => page_boundary_low, page_boundary_high => page_boundary_high, current_address => current_address, mem_no => mem_no, binary_page => binary_page); --Check if sector is locked if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then --Check if sector is protecteds----------------------- if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then jerase := page_boundary_low; loop_chip_0berase : loop if (jerase < page_boundary_low + ((pageper_sector(device) - 8) * pagesize(device, binary_page))) then erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); -- erase 8 pages, i.e. a block page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; jerase := jerase + pagesize(device, binary_page); else report "--------------------------chip0b Eraseexit -------------------------"; exit loop_chip_0berase; end if; end loop; for j in 0 to 7 loop -- erase_page will only change the status of one-page page_status(j) <= '0'; end loop; end if; end if; sector <= (others => '1'); for page in pageper_sector(device) to (PAGE_cal(device) - pageper_sector(device)) - 1 loop --Check if sector is locked if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then --Check if sector is protecteds----------------------- if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then jerase := page_boundary_low; loop_chip_0cerase : loop if (jerase < page_boundary_low + (pageper_sector(device) * pagesize(device, binary_page))) then erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; jerase := jerase + pagesize(device, binary_page); else report "--------------------------chip 0cEraseexit -------------------------"; exit loop_chip_0cerase; end if; end loop; for j in 0 to pageper_sector(device) - 1 loop page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))) + j) <= '0'; end loop; end if; else message2 := "Cannot erase:Sector is Locked"; sector <= sector + 1; end if; end loop; page <= ((conv_Std_Logic_Vector(PAGE_cal(device), p_address(device))) - (conv_Std_Logic_Vector(pageper_sector(device), p_address(device)))); sector <= conv_std_logic_vector((SEC_TORS(device) - 1), S_address(device)); compute_address(page => page, page_size => pagesize(device, binary_page), byte => byte, page_boundary_low => page_boundary_low, page_boundary_high => page_boundary_high, current_address => current_address, mem_no => mem_no, binary_page => binary_page); --Check if sector is locked if (check_lockd(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), lock_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) = '0') then --Check if sector is protecteds----------------------- if (check_protect(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pageper_sector(device), prot_status, comp_sector_addr(p_address(device), comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))), WPB, soft_prot_enabled) = '0') then jerase := page_boundary_low; loop_chip_0derase : loop if (jerase < page_boundary_low + (pageper_sector(device) * pagesize(device, binary_page))) then erase_page(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)), pagesize(device, binary_page), jerase, memory, temp_page_status); page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device)))) <= temp_page_status; jerase := jerase + pagesize(device, binary_page); else report "--------------------------chip0d Eraseexit -------------------------"; exit loop_chip_0derase; end if; end loop; for j in 0 to pageper_sector(device) - 1 loop page_status(conv_integer(comp_page_addr(p_address(device), binary_page, page_addr0, page_addr1, manid(device))) + j) <= '0'; end loop; else message2 := "Cannot erase:Sectorisprotecteds"; end if; else message2 := "Cannot erase:Sector is Locked "; end if; erasing_chip <= '1'; wait for Tce; RDYBSY_reg <= '1'; -- device is now ready status(7) <= '1'; erasing_chip <= '0'; report "chip erase complete"; end if; elsif (SRR = '1' and t(31) = '1') then report "SRR entered"; if ((Rapid_interface = false) and (fSCK > 50)) then report "WARNING: Frequency should be less than 50MHz for SPI interface type. Security Register Read is not allowed."; end if; if (rapid_interface = false and fsck > 50) then read_out_x(CSB, SCK, so_reg, so_on); else read_out_reg(23, 0, 127, prot_reg, lock_reg, security_reg, CSB, SCK, so_reg, so_on); end if; report " SRR exited"; elsif (PRR = '1' and t(31) = '1') then report "PRR entered"; if ((Rapid_interface = false) and (fSCK > 50)) then report "WARNING: Frequency should be less than 50MHz for SPI interface type. protection Register Read is not allowed."; end if; if (rapid_interface = false and fsck > 50) then read_out_x(CSB, SCK, so_reg, so_on); else read_out_reg(21, 0, (sec_tors(device) - 1), prot_reg, lock_reg, security_reg, CSB, SCK, so_reg, so_on); end if; report " PRR exited"; elsif (LRR = '1' and t(31) = '1') then report " LRR entered"; if ((Rapid_interface = false) and (fSCK > 50)) then report "WARNING: Frequency should be less than 50MHz for SPI interface type. Lockdown Register Read is not allowed."; end if; if (rapid_interface = false and fsck > 50) then read_out_x(CSB, SCK, so_reg, so_on); else read_out_reg(22, 0, (sec_tors(device) - 1), prot_reg, lock_reg, security_reg, CSB, SCK, so_reg, so_on); end if; report "LRR exited"; elsif (oP9B = '1' and t(31) = '1' and page_addr0 = X"00" and page_addr1 = X"00" and byte_addr = X"00") then report " entered program security register"; SRP <= '1'; current_address := 0; page_boundary_low := 0; page_boundary_high := 63; write_data(current_address, page_boundary_low, page_boundary_high, tbuffer1, tbuffer2, 1, CSB, sck, SI); -- this will write to buffer -- it will proceed to next step, when, posedge of CSB. -- This is complicated, and, hence, explained here: -- At posedge of CSB, the write_data will get disabled. -- At this time, writing to buffer needs to stop, and, -- writing into memory should start. RDYBSY_reg <= '0'; --device is busy status(7) <= '0'; --writing in to security_reg if (security_flag = '0') then --Security Register has not been programmed before for j in 0 to 63 loop security_reg(j) <= tbuffer1(j); end loop; security_flag <= '1'; wait for Tp; RDYBSY_reg <= '1'; --device is now ready status(7) <= '1'; else wait for 2000 ns; RDYBSY_reg <= '1'; --device is now ready status(7) <= '1'; end if; end if; report "last of processd"; end process; ----------------deep power down and resume deep power down---------------- process begin wait on EDPD, RDPD; if (EDPD = '1') then wait until CSB'event and CSB = '1'; wait for Tedpd; deep_power_down <= '1'; end if; if (RDPD = '1') then wait until CSB'event and CSB = '1'; wait for Trdpd; deep_power_down <= '0'; end if; end process; -----------------------status register read-------- process variable j_tmp : integer := 8; begin wait on SR; if (SR = '1') then report "SR"; if ((Rapid_interface = false) and (fSCK > 50)) then report "WARNING: Frequency should be less than 50MHz for SPI interface type. Status Register Read is not allowed."; end if; status_read <= '1'; --reading status reg if (fsck >= 33) then for i in 0 to 7 loop wait until SCK'event and SCK = '0'; wait for tv; so_reg1 <= 'X'; so_on1 <= '1'; end loop; end if; status_loop : loop wait until ((SCK'event and SCK = '0') or (CSB'event and CSB = '1')); exit status_loop when CSB = '1'; if (j_tmp > 0) then j_tmp := j_tmp - 1; else j_tmp := 7; end if; if ((Rapid_interface = false) and (fSCK > 50)) then read_out_x(CSB, SCK, so_reg1, so_on1); else wait for tV; so_reg1 <= status(j_tmp); so_on1 <= '1'; end if; end loop; report "status register read loop exited"; wait for tDIS; so_on1 <= '0'; status_read <= '0'; end if; end process; ------------manufacturing ID----------- process --(MIR)--,MANID(device)) variable j : integer := 32; variable m_id : std_logic_vector(31 downto 0) := manid(device); begin wait on MIR; if (MIR = '1') then report "MIR"; if ((Rapid_interface = false) and (fSCK > 50)) then report "WARNING: Frequency should be less than 50MHz for SPI interface type. Manufacture ID Register Read is not allowed."; end if; MIR_loop : loop wait until ((SCK'event and SCK = '0') or (CSB'event and CSB = '1')); exit MIR_loop when CSB = '1'; wait for Tv; if (J > 0) then SO_reg2 <= m_id(j - 1); so_on2 <= '1'; J := J - 1; if ((Rapid_interface = false) and (fSCK > 50)) then read_out_x(CSB, SCK, so_reg2, so_on2); end if; elsif (j = 0) then So_on2 <= '1'; So_reg2 <= 'X'; -- only if the cs extends more than available man ID end if; end loop; wait for Tdis; so_on2 <= '0'; So_reg2 <= '0'; end if; end process; --------------------------- IntCSb <= CSb or not Resetb; ------------------------ SCK check --checkPeriod ( SCK , "SCk" , Tsck , "Tsck" , TsckRp , "SCK Frequency" , valid ) ; --checkWidth1 ( SCK , "SCK" , Twh , "Twh" , TsckRw , "SCK High Time" , valid ) ; --checkWidth0 ( SCK , "SCK" , Twl , "Twl" , TsckF , "SCK Low Time" , valid ) ; -- ------------------------ IntCSb chec --checkWidth1 ( IntCSb , "IntCSb" , Tcs , "Tcs" , TcsR , "Minimum CS High Time", valid ) ; --checkSetupCS ( IntCSb , "IntCSb" , SCK , "SCK" , Tcss , "Tcss" , TcsF , "IntCSb setup Time" , valid ) ; --checkHoldCS ( IntCSb , "IntCSb" , SCK , "SCK" , Tcsh , "Tcsh" , Tsckm , "IntCSb Hold Time" , valid ) ; -- ------------------------ SI check --checkSetupRise ( SI , "SI" , SCK , "SCK" , Tsu , "Tsu" , Tsim , "Data in Setup Time" , valid ) ; --checkHoldRise ( SI , "SI" , SCK , "SCK" , Th , "Th" , TsckRh, "Data in Hold Time" , valid ) ; process(so_on1, so_reg1, so_on2, so_reg2, so_reg, so_on) begin if (so_on1 = '1') then so <= so_reg1; elsif (so_on2 = '1') then so <= so_reg2; elsif (so_on = '1') then so <= so_reg; else so <= 'Z'; end if; end process; process(RDYBSY_reg) begin if (RDYBSY_reg = '1') then RDYBSY <= '1'; else RDYBSY <= '0'; end if; end process; --less_than_33mhz <= lthan_66mhz & lthan_33mhz; end design;