在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 6742|回复: 9

[求助] 最近在做基于FPGA的nor FLASh 控制器设计,有点问题还望指点!

[复制链接]
发表于 2012-4-21 16:40:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

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 )
 楼主| 发表于 2012-4-23 11:05:48 | 显示全部楼层
哎。。。一个帮忙的都没有。。!!!
发表于 2012-4-23 16:03:22 | 显示全部楼层
唉,你贴这么长的代码,再加个datasheet,如果不是做过这个的,基本不会有精力帮你看完。
如果想要提高,建议你自己把 操作流程图 、 电路结构图 都画出来,完成以后思路就清晰了。
文档 到 代码, 代码 到 文档的转换是同向高手的必由之路。
 楼主| 发表于 2012-4-23 16:42:46 | 显示全部楼层
回复 3# jackertja


    谢谢您的提醒,!!
发表于 2012-7-14 10:30:58 | 显示全部楼层
flash的读取包括reset、读ID、读数据等等,是个规律性事件。你写的也就是个接口模块,从某个接口到flash,根据datasheet写好状态机和时序控制模块就行了
发表于 2012-7-15 20:27:23 | 显示全部楼层
1不看vhdl代码
2.太长,聚焦不到核心问题
发表于 2013-3-10 10:27:22 | 显示全部楼层
洗下来看看
发表于 2013-10-23 16:50:11 | 显示全部楼层
回复 1# 醉恋秋枫


   支持一下,目前正在做存储器测试
发表于 2013-10-23 22:33:37 | 显示全部楼层
norflash控制还算简单吧。。。。输入命令序列,然后执行操作,就完了啊
发表于 2017-7-28 09:38:10 | 显示全部楼层
下载下来看一下!!!!!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-25 07:59 , Processed in 0.123571 second(s), 11 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表