Acceso a la memoria flash PCM en una placa Nexys 3

¿Cómo accedo a la memoria flash PCM en una placa Nexys3 FPGA?

Tengo un proyecto central de CPU T80 (Z80) simple que funciona con un módulo ROM Core Generator, pero no tengo suerte con el flash ram. El Manual de referencia de Nexys 3 sugiere usar los Diseños de referencia del sitio web de Digilent, pero en realidad no hay uno para la placa Nexys 3. Le pregunté a Digilent y dicen que solo hay uno para Nexys 2, que he revisado. . También he leído la mayor parte de la hoja de datos del chip flash: Micron NP8P128A13T1760E, pero no puedo hacerlo funcionar.

Así que armé el proyecto más mínimo que se me ocurrió: una máquina de estado simple que intenta leer la primera palabra de la memoria RAM y mostrar el byte más bajo en los 8 LED de la placa. Consulte el VHDL a continuación. Estoy cargando la memoria flash usando la utilidad de memoria Adept, pero siempre parece que aparece su 0xFF.

(Actualización, acabo de descubrir que si presiono el botón que tengo conectado para restablecerlo, muestra 0x06, pero eso no es lo que se ha puesto en flash)

Mi comprensión de cómo debería funcionar es:

  1. Configure FlashRP = 1, FlashCS = 1, MemOE = 1, MemWR = 1,
  2. Establezca la dirección en MemAdr (la he codificado en 0)
  3. Habilitar flash - FlashCS = 0
  4. Habilitar salida - FlashOE = 0
  5. Leer desde MemDB

Mi proyecto de prueba ejecuta estos pasos en un reloj de 3.375 Mhz (ya que es a lo que se ejecutará el T80).

Una cosa de la que no estoy seguro es que el Manual de referencia de Nexys3 se refiere a algunas otras señales que son comunes a la RAM y al Flash, a saber, CLK, ADV y WAIT, pero no he podido correlacionarlas con la hoja de datos para el chip flash.

¿Qué me estoy perdiendo?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity Top is
    Port ( clock : in  STD_LOGIC;
           reset : in  STD_LOGIC;
              led : out STD_LOGIC_VECTOR (7 downto 0);
              MemOE : out STD_LOGIC;
              MemWR : out STD_LOGIC;
              FlashCS : out STD_LOGIC;
              FlashRP : out STD_LOGIC;
              MemAdr : out STD_LOGIC_VECTOR(26 downto 1);
              MemDB : inout STD_LOGIC_VECTOR(15 downto 0)
              );
end Top;

architecture Behavioral of Top is
    signal slow_clock : STD_LOGIC;
    signal led_reg : STD_LOGIC_VECTOR(7 downto 0);
    signal state : unsigned(3 downto 0) := "0000";
    signal state_next : unsigned(3 downto 0);
begin

    led <= led_reg;

    -- Clock Generation
    clock_core : entity work.ClockCore
        PORT MAP 
        (
            clock => clock,
            clock_3375 => slow_clock,       -- 3.375 Mhz clock
            RESET  => reset
        );

    process (slow_clock, reset)
    begin
        if (reset='1') then
            state <= "0000";
            led_reg <= "00000000";
        elsif (slow_clock'event and slow_clock='1') then
            state <= state_next;
            if (state = "1110") then
                led_reg <= MemDB(7 downto 0);
            end if;
        end if;
    end process;

    MemAdr <= "00000000000000000000000000";
    MemDB <= "ZZZZZZZZZZZZZZZZ";
    MemWR <= '1';
    FlashRP <= NOT reset;

    process (state)
    begin
        case state is
            when "0000" =>
                -- initialize
                FlashCS <= '1';
                MemOE <= '1';
            when "0001" =>
                -- enable flash
                FlashCS <= '0';
                MemOE <= '1';
            when "0010" =>
                -- enable flash output
                FlashCS <= '0';
                MemOE <= '0';   
            when others =>
                -- hold steady
                FlashCS <= '0';
                MemOE <= '0';   
        end case;
    end process;

    state_next <= "1111" when (state="1111") else state + 1;

end Behavioral;

Aquí está el material de referencia que he estado usando:

¿Qué valor esperas en lugar de 06?
Bueno, lo que sea que esté almacenado en el primer byte de la memoria flash, que es mi caso, es 0x20, pero podría ser cualquier cosa. Ciertamente no estoy esperando 0x06.
Aferrándose a pajitas, tal vez se intercambiaron los bits / mordiscos :) De manera más constructiva, ¿está el tiempo dentro de las especificaciones (medido por un osciloscopio)? ¿Ha vuelto a sincronizar los datos con su reloj interno? ¿Puede mostrar el código donde captura los datos? ¿Ha revisado el archivo de pines para asegurarse de que los pines son los correctos?
Comprobaré lo del intercambio de bits, pero lo dudo. No tiene osciloscopio, por lo que es difícil de verificar, pero es la razón de los ciclos de retraso adicionales. Los datos no se capturan, solo los escribe allí la utilidad de PC de la placa (adept) y se leen correctamente usando la misma utilidad. Incluso he escrito algo para ram y los dos chips flash solo para asegurarme de que no estoy leyendo desde el chip equivocado. Las impresiones que estoy usando son del archivo maestro de UFC suministrado por digilent, pero las revisaré dos veces.
Por "impresiones" en realidad me refiero a "pinouts". :)
Por "capturado", me refiero al bit de código que toma los datos de las líneas de datos flash y los copia en los LED.
@MartinThompson. Vea mi respuesta publicada a continuación. Me gustaría darte la recompensa... publica una respuesta para que pueda hacerlo.

Respuestas (3)

Finalmente me di cuenta de esto... y no tenía nada de malo con el VHDL que funciona perfectamente. El problema era exactamente como lo sugirió el comentario de Martin Thompson, un problema de pin-out.

Aunque verifiqué las conexiones de los pines del archivo UCF muchas veces, solo estaba revisando las etiquetas correctas de los pines, no es que estuvieran todas presentes y me hubiera perdido el pin MemOE, que por supuesto es esencial para que esto funcione.

Algunas notas:

  1. La cadena de herramientas de Xilinx no proporciona ningún mensaje de advertencia para un pin de salida desconectado como en este caso.
  2. La lectura de MemDB parecía proporcionar datos consistentes pero incorrectos según el modo en el que configuré el chip flash. En el modo de matriz de lectura, siempre devolvía 0xFF en el byte bajo. En identificador de lectura, 0x86. Datos totalmente sin sentido, pero la consistencia me engañó haciéndome pensar que tenía los pinouts correctos.

Lección aprendida.

verifique este proyecto Nexys 3 Tiene algunas cosas buenas para iniciar un proyecto y escribir en la RAM celular de Nexys 3. Sin embargo, no contiene código pcm.

Algunas cosas para comprobar:

  • ¿Se intercambian los bits/bytes/nibbles en alguna parte?
  • ¿Está el tiempo dentro de las especificaciones (medido por un osciloscopio)?
  • ¿Ha vuelto a sincronizar los datos con su reloj interno? ¿Puede mostrar el código donde captura los datos?
  • ¿Ha comprobado el archivo de pines para asegurarse de que los pines son los correctos?