SPI EEPROM 25LC1024 VHDL question

Thread Starter

mos_6502

Joined Dec 11, 2017
66
Hi to all,
I wrote a code for read a 25LC1024 EEPROM (Datasheet).


I use this code:
EEPROM VHDL read:
-- THIS IS THE VHDL CODE FOR READ 25LC1024 EEPROM.
-- CLAUDIO LA ROSA

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;

ENTITY EEPROM25LC1024 IS

  PORT(
    clock               : IN     STD_LOGIC;                             --system clock
    reset_n                 : IN     STD_LOGIC;                             --asynchronous reset
   
     ADDRESS                : IN    STD_LOGIC_VECTOR(23 downto 0);
     START_READ                : IN     STD_LOGIC;
     SCLK                   : OUT STD_LOGIC;
      DATA_OUT               : out std_logic_vector(7 downto 0);
     CS_n                   : OUT STD_LOGIC := '1';
     MOSI                   : out std_logic;
     MISO                   : IN std_logic;
     EEPROM_Busy            : OUT STD_LOGIC;
     DATA_AVAILABLE            : OUT STD_LOGIC
   
    );
   
END EEPROM25LC1024;

ARCHITECTURE rtl OF EEPROM25LC1024 IS

  TYPE machine IS(s_start, s_command, s_read_data);                           --state machine data type
  SIGNAL state       : machine;                              --current state





   
    signal COMMAND : std_logic_vector(7 downto 0) ;
    signal s_ADDRESS_READ : std_logic_vector(23 downto 0) ;
   
    signal DUMMY     : std_logic_vector(7 downto 0);
    signal s_RX_DATA : std_logic_vector(7 downto 0);
   
    signal index : integer := 0;
    signal MOSI_internal :std_logic;
   
     ------- Clock divider process for SPI devices clock
        signal count_clock: integer:=1;
        signal tmp_clock : std_logic := '0';
       
BEGIN
        ------ Clock divider for SPI devices clock
        process(clock,reset_n)
        begin
            if(reset_n='0') then
                count_clock<=1;
                tmp_clock<='0';
            elsif(clock'event and clock='1') then
                count_clock <= count_clock+1;
                if (count_clock = 200) then
                    tmp_clock <= NOT tmp_clock;
                    count_clock <= 1;
                end if;
            end if;
            SCLK <= tmp_clock;
        end process;
       


PROCESS(tmp_clock, reset_n, start_read)

  BEGIN

     IF(start_read = '1') THEN        --reset system
        CS_n <= '1';                --deselect EEprom
        state <= s_start;
        COMMAND <= "00000110";    --READ (this currently works, but the correct sequence is "00000011"!!)
        s_ADDRESS_READ  <= ADDRESS;
        DUMMY        <= "01111110";    --Dummy data
        EEPROM_BUSY <= '0';
     
       
     ELSIF rising_edge(tmp_clock)  then --(tmp_clock'EVENT AND tmp_clock = '1') THEN      --rising edge of system clock
 
      CASE state IS
        WHEN s_start =>
                EEPROM_BUSY <= '1';
                data_available <= '0';
                CS_n <= '0';
                state <= s_command;
                index <= 0;
   
        WHEN s_command =>
           if index <= 7 then
              mosi <= COMMAND(7);
              COMMAND <= COMMAND(6 downto 0) & '0';
            elsif (index > 7 AND index <=31) then
                  mosi <= s_ADDRESS_READ(23);
                  s_ADDRESS_READ <= s_ADDRESS_READ(22 downto 0) & '0';
                --DUMMY
            elsif (index > 31 AND index <=39) then
                  mosi <= DUMMY(7);
                  DUMMY <= DUMMY(6 downto 0) & '0';  
                  s_rx_DATA <= s_rx_DATA(6 DOWNTO 0) & MISO; --shift in received bit
            elsif index > 39 then
                state <= s_read_data;
                CS_n <= '0';
            end if;
            index <= index + 1;
           
        WHEN s_read_data =>
                CS_n <= '1';
                index <= 0;
                EEPROM_Busy <= '0';
                data_available <= '1';
               
        END CASE;
   
     end if;
End Process;

    DATA_OUT <= s_RX_DATA;
END rtl;
This code work not well.
I only use this for READ data from EEPROM. The command for read is "0000 0011" but, if I use this sequence, it do not work.
I should be to shift left the command and it now is "0000 0110". This work but I have others problem.
I think that my code do not ceck the SPI mode for this EEPROM (mode 1 or mode 3) but I'm not sure about this and I wouldn't even know how to adapt it well to the correct SPI mode.
Could you give me some advice?
 

drjohsmith

Joined Dec 13, 2021
852
ok, I'll jump in,
Your code is terrible,
the rising_edge is a touch stone of mine,
any book, site or lecturer that says to use clk'event as oposed to rising_edge( clk) should be .... ignored...
your making a counter, that outputs a pulse,
that pulse will have glitches on it,
these you then putting into a state machine as the clock,
each glitch is going to move the state machine on
only use the one clock, and use the counter to enable the state machine,
wheres the simlation ?
if you have not simulated, then you ALWAYS need to do simulatoin first, and only once your simulation passes move to chip
good luck
 
Top