|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
各位大神门好!!
小弟最近在做基于FPGA的nor FLASh 控制器的设计,用的flash芯片是AMD的AM29LV400B, 老师要求用VHDL语言来编写,最近一直在网上找这方面的资料。下面这是我网上找的一个FLASH控制器程序,总觉得思路不够清晰!还有一点就是这个好像用的是EPP并口,我们实验室用的是rs232的串口,还望大神们给看看!指点指点!如何修改,非常感谢您的帮助!!谢谢!!
这个是控制器程序: 如果感觉长,我在最下面又上传了这个程序的附件,及这个flash芯片的介绍(datasheet),谢谢!!
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--This is a simplified version of Flash Control. Only a subset of flash control is implemented.
--The following operation are supported:
entity FlashCtrl is
generic(ADDRESS_WIDTH : integer range 0 to 32 := 24;
DATA_WIDTH : integer range 0 to 16 := 8;
READ_CYCLES : integer range 0 to 15 := 9);
port(
reset : in std_logic; --reset signal.
clk : in std_logic; --60MHz Clock
--Computer Interface:
--In 8 bit flash control, the command is 16bit, thus we need 2 wrCmdByte operation to send one command
CS : in std_logic;
wrCmdByte : in std_logic;
CmdByte : in std_logic_vector(7 downto 0);
--test pins:
wrEPPCmdOut : out std_logic;
EPPCmdWordOut : out std_logic_vector(15 downto 0);
--
--Return value to computer
DataToEPP : out std_logic_vector(7 downto 0);
--LookupTable Interface:
rdLUT : in std_logic;
LUTAddr : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
LUTData : out std_logic_vector(DATA_WIDTH-1 downto 0);
--Flash Memory Interface
FlashAddr : out std_logic_vector(ADDRESS_WIDTH-1 downto 0);
FlashDQ : inout std_logic_vector(DATA_WIDTH-1 downto 0);
CENeg : OUT std_ulogic := 'U';
OENeg : OUT std_ulogic := 'U';
WENeg : OUT std_ulogic := 'U';
RESETNeg : OUT std_ulogic := 'U';
WPNeg : OUT std_ulogic := 'U'; --WP#/ACC
BYTENeg : OUT std_ulogic := 'U';
RY : IN std_ulogic := 'U' --RY/BY#
);
end entity FlashCtrl;
architecture arch1 of FlashCtrl is
component dffsr is --synchronous reset
port(
clk: in std_logic;
sreset : in std_logic;
d: in std_logic;
q: out std_logic);
end component;
component lpm_fifo16x16 IS
PORT
(
aclr : IN STD_LOGIC ;
clock : IN STD_LOGIC ;
data : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
rdreq : IN STD_LOGIC ;
wrreq : IN STD_LOGIC ;
empty : OUT STD_LOGIC ;
full : OUT STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
usedw : OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
);
END component;
--Signals for store command from EPP
signal CmdFlag: std_logic; --This is the flag to show wich byte of EPPCmdWord is to be written
signal EPPCmdWord : std_Logic_vector(15 downto 0); --This is the command get from EPP, all the other operation are controlled by this
--it can be split to two part: ControlByte(7 downto 0) and DataByte(7 downto 0):
signal ControlByte, DataByte : std_logic_vector(7 downto 0);
signal wrEPPCmd : std_logic;
--Fifos: Here we need two fifo, Read Fifo and Write Fifo:
--1. WriteFifo:
signal WriteFifoAclr, WriteFifoClock, WriteFifoRdReq, WriteFifoWrreq, WriteFifoEmpty, WriteFifoFull: std_logic;
signal WriteFifoUsedw: std_logic_vector(3 downto 0);
signal WriteFifoData, WriteFifoQ : std_logic_vector(15 downto 0);
signal WriteFifoStatus : std_logic_vector(5 downto 0);
--2. ReadFifo:
signal ReadFifoAclr, ReadFifoClock, ReadFifoRdreq, ReadFifoWrreq, ReadFifoEmpty, ReadFifoFull : std_logic;
signal ReadFifoUsedw: std_logic_vector(3 downto 0);
signal ReadFifoData, ReadFifoQ : std_logic_vector(15 downto 0);
signal ReadFifoStatus : std_logic_vector(5 downto 0);
--Flash Memory Control Statemachine
type FlashCtrlStateTYPE is(IDLE, SingleRead, BlockRead, BlockWrite, SECTORERASE, CHIPERASE, CHIPRESET);
signal FlashState : FlashCtrlStateTYPE;
signal FlashStateStatus : std_logic_vector(7 downto 0);
--Signal for READ Flash Memroy(both SingleRead and BlockRead):
signal ReadFlashTimer : integer range 0 to 15;
signal ReadFlashCounter : integer range 0 to 16;
signal TargetFlashMemPageAddr : std_logic_vector(ADDRESS_WIDTH-1 downto 0); --This is the Flash Memory Page Address that will be operated,
--Page address means that the lower 4bit is '0';
--Signal for Write Flash Memory
signal WriteTimer : integer range 0 to 511;
signal SingleWriteTimer : integer range 0 to 15;
signal WriteFlashCounter: integer range 0 to 16;
signal TargetFlashMemSectorAddr : std_logic_vector(ADDRESS_WIDTH-1 downto 0); -- This is the Sector Address that is needed for BlockWrite
--SECTORERASE and CHIPERASE operation
begin
wrEPPCmdOut <= wrEPPCmd;
EPPCmdWordOut <= EPPCmdWord;
---------------------------------------------------------------------------------------------------------
--get Command from EPPInterface
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
--get Command from EPPInterface
---------------------------------------------------------------------------------------------------------
gen_EPPCmdWord: process(reset,clk)
begin
if reset='1' then
CmdFlag <= '0';
EPPCmdWord <= (others => '0');
wrEPPCmd <= '0';
elsif clk'event and clk='1' then
if CS = '1' and wrCmdByte = '1' then
CmdFlag <= not CmdFlag;
if CmdFlag = '1' then
wrEPPCmd <= '1';
else
wrEPPCmd <= '0';
end if;
case CmdFlag is
when '0' => EPPCmdWord(7 downto 0) <= CmdByte;
when '1' => EPPCmdWord(15 downto 8) <= CmdByte;
when others =>
end case;
else
wrEPPCmd <= '0';
end if;
end if;
end process;
ControlByte(7 downto 0) <= EPPCmdWord(15 downto 8);
DataByte(7 downto 0) <= EPPCmdWord(7 downto 0);
---------------------------------------------------------------------------------------------------------
--WriteFifo Control
--WriteFifo use ControlByte address space 0x50~0x5F
---------------------------------------------------------------------------------------------------------
WriteFifo: lpm_fifo16x16
port map(
aclr => WriteFifoAclr,
clock => WriteFifoClock,
data => WriteFifoData,
rdreq => WriteFifoRdreq,
wrreq => WriteFifoWrreq,
empty => WriteFifoEmpty,
full => WriteFifoFull,
q => WriteFifoQ,
usedw => WriteFifoUsedw);
WriteFifoClock <= clk;
WriteFifoStatus <= WriteFifoEmpty & WriteFifoFull & WriteFifoUsedw;
gen_WriteFifoAclr: process(reset,clk)
begin
if reset = '1' then
WriteFifoAclr <= '1';
elsif clk'event and clk='1' then
if wrEPPCmd='1' and ControlByte = X"50" then
WriteFifoAclr <= '1';
else
WriteFifoAclr <= '0';
end if;
end if;
end process;
gen_WriteFifoData : process(reset,clk)
begin
if reset = '1' then
WriteFifoWrreq <= '0';
WriteFifoData <= (others => '0');
elsif clk'event and clk = '1' then
--wrEPPCmd is a one clock cycle wide pulse, thus the width of WriteFifoWrreq will be 1 clock cycle
if wrEPPCmd = '1' then
case ControlByte is
when X"51" =>
WriteFifoData(7 downto 0) <= DataByte;
when X"52" =>
WriteFifoWrreq <= '1';
WriteFifoData(15 downto 8) <= DataByte;
when others =>
WriteFifoWrreq <= '0';
end case;
else
WriteFifoWrreq <= '0';
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------------
--ReadFifo Control
--ReadFifo uses ControlByte address space 0x60~0x6F
---------------------------------------------------------------------------------------------------------
ReadFifo: lpm_fifo16x16
port map(
aclr => ReadFifoAclr,
clock => ReadFifoClock,
data => ReadFifoData,
rdreq => ReadFifoRdreq,
wrreq => ReadFifoWrreq,
empty => ReadFifoEmpty,
full => ReadFifoFull,
q => ReadFifoQ,
usedw => ReadFifoUsedw);
ReadFifoClock <= clk;
ReadFifoStatus <= ReadFifoEmpty & ReadFifoFull & ReadFifoUsedw;
gen_ReadFifoAclk : process(reset,clk)
begin
if reset = '1' then
ReadFifoAclr <= '1';
elsif clk'event and clk='1' then
if wrEPPCmd = '1' and ControlByte <= X"60" then
ReadFifoAclr <= '1';
else
ReadFifoAclr <= '0';
end if;
end if;
end process;
gen_ReadFifoRdreq : process(reset,clk)
begin
if reset = '1' then
ReadFifoRdreq <= '0';
elsif clk'event and clk='1' then
if wrEPPCmd = '1' and ControlByte <= X"61" then
ReadFifoRdreq <= '1';
else
ReadFifoRdreq <= '0';
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------------
--Target Address:
--TargetFlashMemPageAddr and TargetFlashMemSectorAddr
---------------------------------------------------------------------------------------------------------
gen_TargetFlashAddr : process(reset,clk)
begin
if reset = '1' then
TargetFlashMemPageAddr <= (others => '0');
TargetFlashMemSectorAddr <= (others => '0');
elsif clk'event and clk='1' then
if wrEPPCmd = '1' then
case ControlByte is
when X"19" => TargetFlashMemPageAddr(7 downto 0) <= DataByte;
when X"1A" => TargetFlashMemPageAddr(15 downto 8) <= DataByte;
when X"1B" => TargetFlashMemPageAddr(23 downto 16) <= DataByte;
when X"1C" => TargetFlashMemSectorAddr(7 downto 0) <= DataByte;
when X"1D" => TargetFlashMemSectorAddr(15 downto 8) <= DataByte;
when X"1E" => TargetFlashMemSectorAddr(23 downto 16) <= DataByte;
when others =>
end case;
end if;
end if;
end process;
----------------------------------------------------------------------------------------------------------
--ReadOut
----------------------------------------------------------------------------------------------------------
gen_DataToEPP: process(reset,clk)
begin
if reset = '1' then
DataToEPP <= (others => '0');
elsif clk'event and clk = '1' then
if wrEPPCmd = '1' then
case ControlByte is
when X"53" => --Status of WriteFifo
DataToEPP(5 downto 0) <= WriteFifoStatus(5 downto 0);
DataToEPP(7 downto 6) <= (others => '0');
when X"62" =>
DataToEPP <= ReadFifoQ(7 downto 0);
when X"63" =>
DataToEPP <= ReadFifoQ(15 downto 8); --Even for 8bit operation, since we use 16bit Fifo, still we have ReadFifoQ(15 downto 8),
--it will be X"00" in 8 bit mode;
when X"64" => --Status of ReadFifo
DataToEPP(5 downto 0) <= ReadFifoStatus(5 downto 0);
DataToEPP(7 downto 6) <= (others => '0');
when X"17" => --FlashStateStatus
DataToEPP <= FlashStateStatus;
when others =>
end case;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------------
--State Machine:
---------------------------------------------------------------------------------------------------------
genFlashState: process(reset,clk)
begin
if reset = '1' then
FlashState <= IDLE;
CENeg <= '1';
WENeg <= '1';
OENeg <= '1';
RESETNeg <= '1';
--Sig for rdLUT:
ReadFlashTimer <= 0;
ReadFlashCounter <= 0;
--Sig for Write and ERASE
WriteTimer <= 0;
SingleWriteTimer <= 0;
WriteFlashCounter <= 0;
LUTData <= (others => 'Z');
FlashAddr <= (others => '0');
ReadFifoData <= (others => '0');
WriteFifoRdReq <= '0';
ReadFifoWrreq <= '0';
FlashDQ <= (others => 'Z');
FlashStateStatus <= X"00";
elsif clk'event and clk='1' then
case FlashState is
when IDLE =>
CENeg <= '1';
WENeg <= '1';
OENeg <= '1';
RESETNeg <= '1';
ReadFlashTimer <= 0;
ReadFlashCounter <= 0;
WriteTimer <= 0;
SingleWriteTimer <= 0;
WriteFlashCounter <= 0;
LUTData <= (others => 'Z');
FlashAddr <= (others => '0');
FlashDQ <= (others => 'Z');
if wrEPPCmd = '1' then
case ControlByte is
when X"11" =>
FlashState <= SingleRead;
when X"12" =>
FlashState <= BlockRead;
when X"13" =>
FlashState <= BlockWrite;
when X"14" =>
FlashState <= SECTORERASE;
when X"15" =>
FlashState <= CHIPERASE;
when X"16" =>
FlashState <= CHIPRESET;
when others =>
end case;
end if;
FlashStateStatus <= X"01";
when SingleRead =>
--This state is for lookup table
CENeg <= '0';
if wrEPPCmd = '1' and ControlByte = X"10" then
FlashState <= IDLE;
else
case ReadFlashTimer is
when 0 =>
if rdLUT = '1' then
ReadFlashTimer <= 1;
FlashAddr <= LUTAddr;
end if;
when 1 =>
ReadFlashTimer <= 2;
OENeg <= '0';
when 9 =>
LUTData <= FlashDQ;
OENeg <= '1';
ReadFlashTimer <= 0;
when others =>
ReadFlashTimer <= ReadFlashTimer + 1;
end case;
end if;
FlashStateStatus <= X"02";
when BlockRead =>
CENeg <= '0';
case ReadFlashTimer is
when 0 => --In this state, the TargeFlashMemAddr(3 downto 0) should be "0000" because this is a page address
FlashAddr <= TargetFlashMemPageAddr+conv_std_logic_vector(ReadFlashCounter, ADDRESS_WIDTH);
ReadFifoWrreq <= '0';
when 1 =>
OENeg <= '0';
when 9 => --Data is ready, write it to the Flash Memory
OENeg <= '1';
ReadFifoWrreq <= '1';
ReadFifoData(DATA_WIDTH-1 downto 0) <= FlashDQ;
when others =>
end case;
if ReadFlashTimer = 9 then
ReadFlashTimer <= 0;
ReadFlashCounter <= ReadFlashCounter + 1;
else
ReadFlashTimer <= ReadFlashTimer+1;
end if;
if ReadFlashCounter = 16 then
FlashState <= IDLE;
end if;
FlashStateStatus <= X"03";
when BlockWrite => -- use "Write Buffer Programming"
CENeg <= '0';
if WriteTimer < 255 then
WriteTimer <= WriteTimer + 1;
end if;
case WriteTimer is
--1 0x555, 0xAA
when 1 =>
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"555";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"AA";
when 2 =>
WENeg <= '0';
when 6 =>
WENeg <= '1';
--2 0x2AA, 0x55
when 9 =>
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"2AA";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"55";
when 10 =>
WENeg <= '0';
when 14 =>
WENeg <= '1';
--3 SA, 0x25
when 17 =>
FlashAddr <=TargetFlashMemSectorAddr;
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"25";
when 18 =>
WENeg <= '0';
when 22 =>
WENeg <= '1';
--4 SA, WC(Number of Word - 1)
when 25 =>
FlashAddr <= TargetFlashMemSectorAddr;
FlashDQ <= conv_std_logic_vector(15, DATA_WIDTH);
when 26 =>
WENeg <= '0';
when 30 =>
WENeg <= '1';
--Program Buffer to flash:
when 220 =>
FlashAddr <=TargetFlashMemSectorAddr;
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"29";
when 221 =>
WENeg <= '0';
when 225 =>
WENeg <= '1';
--Wait for RY valid
when 255 =>
if RY = '1' then
FlashState <= IDLE;
WriteTimer <= 0;
end if;
when others =>
end case;
--when time is between 40 and 400, we begin to program the data from verify fifo into flash fifo
if (WriteTimer > 40) and (WriteFlashCounter < 16) then
if SingleWriteTimer = 9 then
SingleWriteTimer <= 0;
else
SingleWriteTimer <= SingleWriteTimer + 1;
end if;
case SingleWriteTimer is
when 0 =>
WriteFifoRdreq <= '1';
when 1 =>
WriteFifoRdreq <= '0';
FlashAddr <= TargetFlashMemPageAddr + conv_std_logic_vector(WriteFlashCounter, ADDRESS_WIDTH);
FlashDQ <= WriteFifoQ(DATA_WIDTH-1 downto 0);
when 2 =>
WENeg <= '0';
when 6 =>
WENeg <= '1';
when 9 =>
WriteFlashCounter <= WriteFlashCounter + 1;
when others =>
end case;
end if;
FlashStateStatus <= X"04";
when SECTORERASE => --When the system send this command, the sector address need to be sent
--at the same time.
CENeg <= '0';
if WriteTimer < 63 then
WriteTimer <= WriteTimer+1;
end if;
case WriteTimer is
--1 0x555, 0xAA
when 1 =>
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"555";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"AA";
when 2 =>
WENeg <= '0';
when 6 =>
WENeg <= '1';
--2 0x2AA, 0x55
when 9 =>
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"2AA";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"55";
when 10 =>
WENeg <= '0';
when 14 =>
WENeg <= '1';
--3 0x555, 0x80
when 17 =>
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"555";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"80";
when 18 =>
WENeg <= '0';
when 22 =>
WENeg <= '1';
--4 0x555, 0xAA
when 25 =>
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"555";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"AA";
when 26 =>
WENeg <= '0';
when 30 =>
WENeg <= '1';
--5 0x2AA, 0x55
when 33 =>
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"2AA";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"55";
when 34 =>
WENeg <= '0';
when 38 =>
WENeg <= '1';
--6 SA, 0x30
when 41 =>
FlashAddr <= TargetFlashMemSectorAddr;
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"30";
when 42 =>
WENeg <= '0';
when 46 =>
WENeg <= '1';
when 63 => --Check the status of RY, if '1', the erase complete, return to IDLE
if RY = '1' then
FlashState <= IDLE;
end if;
when others =>
end case;
FlashStateStatus <= X"05";
when CHIPERASE => --When the system send this command, the sector address need to be sent
--at the same time.
if WriteTimer < 63 then
WriteTimer <= WriteTimer+1;
end if;
case WriteTimer is
--1 0x555, 0xAA
when 1 =>
CENeg <= '0';
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"555";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"AA";
when 2 =>
WENeg <= '0';
when 6 =>
WENeg <= '1';
CENeg <= '1';
--2 0x2AA, 0x55
when 9 =>
CENeg <= '0';
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"2AA";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"55";
when 10 =>
WENeg <= '0';
when 14 =>
CENeg <= '1';
WENeg <= '1';
--3 0x555, 0x80
when 17 =>
CENeg <= '0';
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"555";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"80";
when 18 =>
WENeg <= '0';
when 22 =>
CENeg <= '1';
WENeg <= '1';
--4 0x555, 0xAA
when 25 =>
CENeg <= '0';
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"555";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"AA";
when 26 =>
WENeg <= '0';
when 30 =>
CENeg <= '1';
WENeg <= '1';
--5 0x2AA, 0x55
when 33 =>
CENeg <= '0';
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"2AA";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"55";
when 34 =>
WENeg <= '0';
when 38 =>
CENeg <= '1';
WENeg <= '1';
--6 SA, 0x30
when 41 =>
CENeg <= '0';
FlashAddr(ADDRESS_WIDTH-1 downto 12) <= (others => '0');
FlashAddr(11 downto 0) <= X"555";
FlashDQ(DATA_WIDTH-1 downto 8) <= (others => '0');
FlashDQ(7 downto 0) <= X"10";
when 42 =>
WENeg <= '0';
when 46 =>
CENeg <= '1';
WENeg <= '1';
when 63 => --Check the status of RY, if '1', the erase complete, return to IDLE
CENeg <= '0';
if RY = '1' then
FlashState <= IDLE;
end if;
when others =>
end case;
FlashStateStatus <= X"06";
when CHIPRESET =>
-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------
--Chip Reset Timing Control:
--CHIPRESET: This state is to keep the CHIPRESETNeg for 1us(Because the manual requires at least 500ns), then wait for
--40us(tREADY, 20us min During Embedded Algorithm, 500ns min not during embedded algorithm, we consider
--the worst case), and return to IDLE state.
-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------
CENeg <= '1';
if WriteTimer < 255 then
WriteTimer <= WriteTimer + 1;
end if;
case WriteTimer is
when 0 =>
ResetNeg <= '0';
when 100 =>
ResetNeg <= '1';
when others =>
end case;
if((RY='1') and (WriteTimer > 200)) then
FlashState <= IDLE;
end if;
FlashStateStatus <= X"07";
end case;
end if;
end process;
end architecture arch1;
这个是程序附件及芯片资料:为了方便,我放在了一个压缩包里,
AM29LV400B程序及芯片资料.rar
(756.63 KB, 下载次数: 92 )
|
|