Hola a todos en el foro....
Estoy tratando de hacer un controlador de la memoria flash m29w320db la que viene incluida en la tarjeta de evaluacion de Nuhorizons, la idea es poder leer y grabar datos en principio, luego implementar otras funciones de la misma. A pesar de seguir los pasos de la hoja de datos, no tengo exito en poder grabar dato alguno, cada vez que grabo algun dato y lo leo siempre me sale FF (y eso que antes de grabar siempre borro todo el bloque de memoria....

) en el display.
Si alguien ya tuvo alguna experiencia con este tipo de memorias a ver si me puede dar algun consejo, incluyo abajo el codigo vhdl que trato de implementar, las hojas tecnicas estan en
http://www.st.com/stonline/books/pdf/docs/7876.pdf quisiera adjuntarlos como archivos pero la pagina web no lo permite (Nota para el webmaster...)
El codigo hace lo siguiente:
- captura un dato del teclado y lo muestra en el LCD y lo guarda en una memoria temporal "prueba"
- al ejecutar "reset" borra el bloque 35 de la memoria cuyo referente es la direccion 200000h
- al presionar "grabar" se ejecuta la maquina de estados y lo que estaba en memoria temporal "prueba " debería grabarse en la posicion de memoria elejida dentro del bloque 35.
-al presionar granbar deberia desplegar el dato grabado. (pero sigue saliendo FF)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--use IEEE.STD_LOGIC_SIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity fff is
port(
--para la memoria flash
memf_dir:out std_logic_vector(20 downto 0);
memf_w:out std_logic:="1";
memf_e:out std_logic:="1";
memf_g:out std_logic:="0";
memf_rp:out std_logic:="1";
memf_wp:out std_logic:="1";
memf_data:inout std_logic_vector(7 downto 0);
memf_dq15A:out std_logic;
memf_rb:in std_logic;
------------------------
-- para el lcd
rs: out std_logic;
rw:out std_logic;
en:out std_logic;
lcd:out std_logic_vector (7 downto 0);
--para los leds
leds:out std_logic_vector (7 downto 0);
------------------------
reset:in std_logic;
-- bot_graba: in std_logic;
-- bot_lee: in std_logic;
teclado:in std_logic_vector (4 downto 0);
clk: in std_logic
);
end fff;
architecture behabioral of fff is
--señales para el clock
signal clkout: std_logic:="0";
signal count1: integer:=0;
--señales para el lcd y teclado
signal letra_e:std_logic:="0";
--signal letra_ee:std_logic:="0";
signal letra_m:std_logic:="0";
signal letra:std_logic_vector (7 downto 0):=X"00";
signal letra_mm: std_logic_vector (7 downto 0):=X"00";
signal token_lcd:std_logic:="0";
--señales varias
signal lee_sdram: std_logic:="0"; --se pulso del teclado leer sdram
signal graba_sdram:std_logic:="0";--se pulso del teclado grabar
signal dir_int:integer;
signal inc_dir_sdram:std_logic;
signal dec_dir_sdram:std_logic;
signal direccion:integer:=0;
signal proc_init:std_logic;
signal dir_e:std_logic;
--cambiar en lo futuro por variables internas
signal count3: integer range 0 to 12:=0;
signal count5: integer range 0 to 22:=0;
signal count4: integer range 0 to 32:=0;
signal countram :integer:=0;
signal count: integer range 0 to 19;
signal countbuf: integer range 0 to 18;
-- señales de conversion de datos
signal token_read:std_logic:="0";
signal token_write:std_logic:="0";
signal prueba:std_logic_vector(7 downto 0);
signal prueba1:std_logic_vector(7 downto 0);
signal direccion_std:std_logic_vector(20 downto 0);
signal muxflashlcd:std_logic;
begin
----------------------------------------------------------
memf_rp<="1";
memf_wp<="1";
----------------------------------------------------------
--inicializacion de la SDRAM
----------------------------------------------------------
iniSDRAM:process (clkout,reset)
begin
if reset = "0" then
count4 <= 0;
elsif (clkout"event and clkout ="1") then
--para borrar un bloque de la flash al resetear (solo por prueba)
if count4 = 32 then
count4<=32;
else
count4 <= count4+1;
end if;
case count4 is
when 0 => memf_dir<= "000000000001010101010";
memf_dq15A<="1"; --AAA
prueba1<=X"AA";
muxflashlcd<= "1";
token_write <= "1";
when 1 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 2 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 3 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 4 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 5 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 6 => memf_dir<= "000000000010101010101";
memf_dq15A<="0"; --555
prueba1<=X"55";
when 7 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 8 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 9 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 10 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 11 => memf_dir<= "000000000001010101010";
memf_dq15A<="1"; --AAA,80
prueba1<=X"80";
when 12 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 13 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 14 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 15 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 16 => memf_dir<= "000000000001010101010";
memf_dq15A<="1"; --AAA
prueba1<=X"AA";
muxflashlcd<= "1";
token_write <= "1";
when 17 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 18 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 19 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 20 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 21=> memf_dir<= "000000000010101010101";
memf_dq15A<="0"; --555
prueba1<=X"55";
when 22 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 23 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 24 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 25 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 26=> memf_dir<= "000000000000000000000";
memf_dq15A<="1"; --BA 30
prueba1<=X"30";
muxflashlcd<= "1";
when 27 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 28 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 29 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 30 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 31=> token_write <="0";
when 32=> null;
end case;
--maquina de estados para leer la flash
if lee_sdram="1" then
if count3 = 12 then
count3 <= 12;
else
count3<= count3 +1; --aumenta estado
case count3 is
when 0=> prueba1<=X"F0";
muxflashlcd<= "1";
when 1 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 2 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 3 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 4 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 5 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 6 => null;
when 7 => memf_dir<=direccion_std;
memf_dq15A<="1";
when 8 => memf_e<="0";
memf_g<="0";
memf_w<="1";
when 9 => memf_e<="0";
memf_g<="0";
memf_w<="1";
when 10 => token_read<="1";
when 11 => memf_e<="1";
memf_g<="1";
memf_w<="1";
token_read<="0";
when 12 => null;
end case;
end if;
elsif lee_sdram = "0" then
count3 <= 0;
end if;
--para grabar datos en la flash
if graba_sdram = "1" then
if count5 = 22 then
count5 <= 22;
else
count5 <= count5 +1;
end if;
case count5 is
when 0 => memf_dir<= "000000000001010101010";
memf_dq15A<="1"; --AAA
prueba1<=X"AA"; --AA
muxflashlcd<= "1";
token_write <= "1";
when 1 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 2 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 3 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 4 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 5 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 6 => memf_dir<= "000000000010101010101";
memf_dq15A<="0"; --555
prueba1<=X"55";
when 7 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 8 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 9 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 10 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 11=> memf_dir<= "000000000001010101010";
memf_dq15A<="1"; --AAA,A0
prueba1<=X"A0";
when 12 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 13 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 14 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 15 => memf_e<="1";
memf_g<="1";
memf_w<="1";
when 16=> memf_dir <= direccion_std;
memf_dq15A<="1"; --direccion
muxflashlcd<= "0";
when 17 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 18 => memf_e<="0";
memf_g<="1";
memf_w<="0";
when 19 => memf_e<="0";
memf_g<="1";
memf_w<="1";
when 20 => memf_e<="1";
memf_g<="1";
memf_w<="1";
-- when 13=> prueba1<=X"F0";
-- muxflashlcd<= "1";
-- when 14 =>memf_e<="0";
-- memf_g<="1";
-- memf_w<="0";
-- when 15 =>memf_e<="1";
-- memf_g<="1";
-- memf_w<="1";
when 21=> token_write <="0";
when 22 => null;
end case;
elsif graba_sdram ="0" then
count5 <= 0;
end if;
end if; --clk
end process;
----------------------------------------------------------
-- incrementar o decrementar las direcicones d ela flash
----------------------------------------------------------
indecsdram:process (inc_dir_sdram,dec_dir_sdram)
variable countpulsador:integer range 0 to 2:=0;
begin
if clkout"event and clkout = "1" then
if countpulsador = 0 then
if dir_e = "1" then
countpulsador:= 1;
else
countpulsador:=0;
end if;
elsif countpulsador = 2 then
countpulsador:= countpulsador;
else
countpulsador:= countpulsador +1;
end if;
case countpulsador is
when 0 => countpulsador:= 0;
when 1 => if inc_dir_sdram = "1" then
direccion <= direccion +1;
elsif dec_dir_sdram = "1" then
direccion <= direccion -1;
end if;
when 2 => if dir_e = "1" then
countpulsador:=2;
elsif dir_e = "0" then
countpulsador:=0;
end if;
end case;
direccion_std <= CONV_STD_LOGIC_VECTOR(direccion,21);
leds<=CONV_STD_LOGIC_VECTOR(direccion,8);
end if;
end process;
----------------------------------------------------------
--proceso de captura e insercion de datos en la flash de
--acuerdo al control de las señales.
----------------------------------------------------------
SDRAM_flanco_up:process (token_read, token_write,muxflashlcd,prueba1,prueba)
begin
--if (clkout"event and clkout="1") then
if token_read = "1" then
letra_mm <= memf_data;
else
if token_write = "1" then
if muxflashlcd = "1" then
memf_data<=prueba1;
else
memf_data <= prueba;
-- leds<= prueba;
end if;
else
memf_data<= (others => "Z");
end if;
end if;
--end if;
end process;
----------------------------------------------------------
-- controlador de ack rec de la memoria y el LCD
----------------------------------------------------------
lcd_memo:process (token_read,token_lcd)
begin
if token_read = "1" then
if token_lcd = "0" then
letra_m <= "1";
else
letra_m <="0";
end if;
end if;
end process;
------------------------------------------------------------------
-- codificador del teclado
------------------------------------------------------------------
codif_gab: process (teclado)
begin
case teclado is
when "00001" => letra <= X"30"; --0
letra_e <= "1";
dir_e <= "0";
when "00010" => letra <= X"31"; --1
letra_e <= "1";
dir_e <= "0";
when "00011" => letra <= X"32"; --2
letra_e <= "1";
dir_e <= "0";
when "00100" => letra <= X"33"; --3
letra_e <= "1";
dir_e <= "0";
when "00101" => letra <= X"34"; --4
letra_e <= "1";
dir_e <= "0";
when "00110" => letra <= X"35"; --5
letra_e <= "1";
dir_e <= "0";
when "00111" => letra <= X"36"; --6
letra_e <= "1";
dir_e <= "0";
when "01000" => letra <= X"37"; --7
letra_e <= "1";
dir_e <= "0";
when "01001" => letra <= X"38"; --8
letra_e <= "1";
dir_e <= "0";
when "01010" => letra <= X"39"; --9
letra_e <= "1";
dir_e <= "0";
when "10001" => letra <= X"41";--A
letra_e <= "1";
dir_e <= "0";
when "10010" => letra <= X"42";--B
letra_e <= "1";
dir_e <= "0";
when "10011" => letra <= X"43";--C
letra_e <= "1";
dir_e <= "0";
when "10100" => letra <= X"44";--D
letra_e <= "1";
dir_e <= "0";
when "10101" => letra <= X"45";--E
letra_e <= "1";
dir_e <= "0";
when "10110" => letra <= X"46";--F
letra_e <= "1";
dir_e <= "0";
when "10111" => lee_sdram <= "1"; --leer sdram
letra_e <= "0";
dir_e <= "0";
when "11000" => graba_sdram <="1";--grabar sdram
letra_e <= "0";
dir_e <= "0";
when "11001" => inc_dir_sdram <= "1";--incrementa dir
--direccion <= direccion +1;
--leds<=CONV_STD_LOGIC_VECTOR(direccion,8);
dir_e <= "1";
letra_e <= "0";
when "11010" => dec_dir_sdram <= "1";--dec direccion
--direccion <= direccion -1;
--leds<=CONV_STD_LOGIC_VECTOR(direccion,8);
letra_e <= "0";
dir_e <= "1";
when others => letra_e <= "0";
dir_e <= "0";
lee_sdram <= "0";
graba_sdram <= "0";
inc_dir_sdram <= "0";
dec_dir_sdram <= "0";
end case;
end process;
-------------------------------------------------
--Rutina de retardo de clock para el LCD
-------------------------------------------------
clockin: process (clk)
begin
if clk"event and clk ="1" then
count1<= count1 + 1;
if count1 = 18000 then
clkout <= not clkout;
count1 <= 0;
end if;
end if;
end process;
------------------------------------------------
--maquina de estado del LCD
------------------------------------------------
maquina: process (reset,clkout)
--variable count: integer range 0 to 19;
--variable countbuf: integer range 0 to 18;
begin
if (reset ="0") then
count<=0;
elsif(clkout"event and clkout ="1") then
if count = 19 then
count<= count;
elsif count =18 then
if letra_e = "1" then
count<=18;
elsif letra_m = "1" then
--elsif token_lcd = "1" then
count<=18;
else
count<=16;
end if;
elsif count = 16 then
if letra_e = "1" then
lcd<=letra; -- dato del teclado
--letra_sdram<= letra;
prueba <= letra;
count<= 17;
elsif letra_m = "1" then
lcd<=letra_mm; -- dato de la memoria
token_lcd<="1";--token de la memoria control
count<=17;
else
count<=16;
end if;
else
count<=count+1;
end if;
case count is
when 0 => en<="1";
rw<="0";
rs<="0";
countbuf<=count;
count<=19;
lcd<=X"38";
when 1 => en<="1";
rw<="0";
rs<="0";
countbuf<=count;
count<=19;
lcd<=X"38";
when 2 => en<="1";
rw<="0";
rs<="0";
countbuf<=count;
count<=19;
lcd<=X"38";
when 3 => en<="1";
rw<="0";
rs<="0";
countbuf<=count;
count<=19;
lcd<=X"06";
when 4 => en<="1";
rw<="0";
rs<="0";
countbuf<=count;
count<=19;
lcd<=X"0C";
when 5 => en<="1";
rw<="0";
rs<="0";
countbuf<=count;
count<=19;
lcd<=X"01";
when 6 => en<="1";
rw<="0";
rs<="0";
countbuf<=count;
count<=19;
lcd<=X"80";
when 7 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
lcd<=X"45"; --E
when 8 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
lcd<=X"54"; --T
when 9 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
lcd<=X"4E"; --N
when 10 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
lcd<=X"FE"; -- " "
when 11 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
lcd<=X"31"; --1
when 12 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
lcd<=X"30"; --0
when 13 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
lcd<=X"34"; --4
when 14 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
lcd<=X"30"; --0
when 15 => en<="1";
rw<="0";
rs<="0";
countbuf<=count;
count<=19;
lcd<=X"0C"; --Nueva linea
when 16 => token_lcd <= "0";
null;
when 17 => en<="1";
rw<="0";
rs<="1";
countbuf<=count;
count<=19;
token_lcd<="1"; --fin
when 18 => --se queda en loop mientras no se deje letra_e
null;
when 19 => en<= "0"; --genera
count<= countbuf+1;
end case;
end if;
end process;
end behabioral;