mor1kx-bemicrocv/devicemodels/dataflash2.1.vhd

3488 lines
124 KiB
VHDL
Raw Normal View History

2016-08-04 19:22:38 +02:00
-------------------------------------------------------------------------------
-- 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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
---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
2016-08-04 19:22:38 +02:00
);
end DataFlash;
2016-08-04 19:22:38 +02:00
----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';
2016-08-04 19:22:38 +02:00
else
status3 := '1';
2016-08-04 19:22:38 +02:00
end if;
2016-08-04 19:22:38 +02:00
return status3;
2016-08-04 19:22:38 +02:00
end device_sel1;
2016-08-04 19:22:38 +02:00
function device_Sel2(DEVICE : in string(1 to 10)
) return std_logic is
variable status4 : std_logic;
begin
if (DEVICE = "AT45DB041D") then
status4 := '1';
2016-08-04 19:22:38 +02:00
elsif (DEVICE = "AT45DB081D") then
status4 := '0';
2016-08-04 19:22:38 +02:00
elsif (DEVICE = "AT45DB161D") then
status4 := '0';
2016-08-04 19:22:38 +02:00
elsif (DEVICE = "AT45DB321D") then
status4 := '1';
2016-08-04 19:22:38 +02:00
elsif (DEVICE = "AT45DB642D") then
status4 := '1';
2016-08-04 19:22:38 +02:00
elsif (DEVICE = "AT45DB011D") then
status4 := '0';
2016-08-04 19:22:38 +02:00
elsif (DEVICE = "AT45DB021D") then
status4 := '1';
2016-08-04 19:22:38 +02:00
else
status4 := '1';
2016-08-04 19:22:38 +02:00
end if;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
return page_size;
2016-08-04 19:22:38 +02:00
end pagesize_forbuffer;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
return page_size;
2016-08-04 19:22:38 +02:00
end pagesize;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
end if;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
LastSignalRise <= now;
end if;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
when others =>
end case;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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));
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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";
2016-08-04 19:22:38 +02:00
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";
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
end loop;
2016-08-04 19:22:38 +02:00
report " loop exited";
2016-08-04 19:22:38 +02:00
end write_data;
2016-08-04 19:22:38 +02:00
------------------check_protection-------------
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
return protecteds;
end check_protect;
2016-08-04 19:22:38 +02:00
--------------check lock down---------
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
end if;
end loop;
2016-08-04 19:22:38 +02:00
wait for Tdis;
so_reg <= '0';
so_on1 <= '0';
report " Read out reg loop exited ";
end read_out_reg;
2016-08-04 19:22:38 +02:00
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 **************---
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
end if;
2016-08-04 19:22:38 +02:00
end if;
2016-08-04 19:22:38 +02:00
end if;
end process;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
wait for 1 ps;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
end if;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
wait for 1 ps;
--**************************
wait for tVCSL;
foreground_op_enable <= '1'; ---- Enable foreground op_codes
report " forground enable";
2016-08-04 19:22:38 +02:00
end if;
--**************************
2016-08-04 19:22:38 +02:00
wait on t(31);
report " t31 asserted";
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
report "MMPR is exited ";
elsif (MMCAR = '1' and t(31) = '1') then
report "entered into MMCAR ";
2016-08-04 19:22:38 +02:00
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";
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
report "MMCAR is exited ";
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
--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";
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
--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";
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
wait for Txfr;
RDYBSY_reg <= '1'; -- device is now ready
status(7) <= '1';
updating_buffer1 <= '0';
2016-08-04 19:22:38 +02:00
report " MMPTB1T exited";
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
wait for Txfr;
RDYBSY_reg <= '1'; -- after tXFR ; -- device is now ready
status(7) <= '1';
updating_buffer2 <= '0';
2016-08-04 19:22:38 +02:00
report " MMPTB2T exited";
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
else
wait until CSB = '1';
message2 := "Cannot write page is protecteds";
end if;
2016-08-04 19:22:38 +02:00
else
wait until CSB = '1';
message2 := " Cannot write page is Locked ";
end if;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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";
2016-08-04 19:22:38 +02:00
end if;
else
wait until CSB'event and CSB = '1';
message2 := " Cannot write page is Locked ";
end if;
report "B2TMMPPW0BIE is exited";
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
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 ";
2016-08-04 19:22:38 +02:00
end if;
else
message2 := " Cannot write page is Locked ";
end if;
2016-08-04 19:22:38 +02:00
-- 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.
2016-08-04 19:22:38 +02:00
report "APRB1 auto page rewrite is exited";
2016-08-04 19:22:38 +02:00
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);
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
else
message2 := " Cannot write page is proted ";
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
else
message2 := " Cannot erase page is proted ";
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
else
message2 := " Cannot erase bloc is proted ";
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
else
message2 := " Cannot erase sect is proted ";
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
else
message2 := "Cannot erase:Sector is Locked ";
2016-08-04 19:22:38 +02:00
end if;
erasing_chip <= '1';
2016-08-04 19:22:38 +02:00
wait for Tce;
RDYBSY_reg <= '1'; -- device is now ready
status(7) <= '1';
erasing_chip <= '0';
report "chip erase complete";
end if;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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";
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
if (rapid_interface = false and fsck > 50) then
read_out_x(CSB, SCK, so_reg, so_on);
2016-08-04 19:22:38 +02:00
else
read_out_reg(21, 0, (sec_tors(device) - 1), prot_reg, lock_reg, security_reg, CSB, SCK, so_reg, so_on);
2016-08-04 19:22:38 +02:00
end if;
report " PRR exited";
2016-08-04 19:22:38 +02:00
elsif (LRR = '1' and t(31) = '1') then
report " LRR entered";
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
report "last of processd";
2016-08-04 19:22:38 +02:00
end process;
2016-08-04 19:22:38 +02:00
----------------deep power down and resume deep power down----------------
2016-08-04 19:22:38 +02:00
process
begin
wait on EDPD, RDPD;
if (EDPD = '1') then
2016-08-04 19:22:38 +02:00
wait until CSB'event and CSB = '1';
wait for Tedpd;
deep_power_down <= '1';
2016-08-04 19:22:38 +02:00
end if;
if (RDPD = '1') then
wait until CSB'event and CSB = '1';
wait for Trdpd;
deep_power_down <= '0';
2016-08-04 19:22:38 +02:00
end if;
end process;
2016-08-04 19:22:38 +02:00
-----------------------status register read--------
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
end if;
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
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";
2016-08-04 19:22:38 +02:00
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';
2016-08-04 19:22:38 +02:00
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;
2016-08-04 19:22:38 +02:00
--less_than_33mhz <= lthan_66mhz & lthan_33mhz;
end design;