Forum: FPGA, VHDL & Co. SRAM wird nicht gelesen vom DE1


von Peter B. (funkheld)


Lesenswert?

Hallo, guten Tag.

Ich habe mich jetzt mal an das SRAM rangewagt vom DE1:
IS61LV25616 für mehrere Stunden.

Habe die Belegung und Zeiten aus dem Datenblatt.
"sram_o" habe ich an die LED's angeschlossen.
clk=50Mhz.

Es wird nichts angezeigt. Eigentlich müßte der Wert "111" angezeigt 
werden.
Ich finde den Fehler nicht.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity sdram is
7
port (  clk      : in    STD_LOGIC;
8
        sram_adr : out   STD_LOGIC_VECTOR (17 downto 0);
9
        sram_io  : inout STD_LOGIC_VECTOR (15 downto 0);
10
        sram_o   : out   STD_LOGIC_VECTOR (15 downto 0);
11
        sram_oe  : out   STD_LOGIC;
12
        sram_we  : out   STD_LOGIC;
13
        sram_ce  : out   STD_LOGIC;
14
        sram_ub  : out   STD_LOGIC;
15
        sram_lb  : out   STD_LOGIC
16
        );
17
end sdram;
18
19
architecture Behavioral of sdram is
20
21
signal counter: std_logic_vector (4 downto 0) :="00000";
22
23
begin
24
25
process (clk) begin
26
  if rising_edge (clk) then
27
    counter <= counter + 1;
28
  end if;
29
end process;
30
31
sram_ce <= '0';  
32
sram_ub <= '0';  
33
sram_lb <= '0';  
34
35
process (clk) begin
36
  if rising_edge (clk) then
37
    sram_adr  <= "000000000000000011";
38
    sram_oe   <=  not counter(4);  
39
    sram_we   <=  not counter(4) and counter (0);
40
  end if;
41
end process;
42
43
process (clk) begin
44
  if rising_edge (clk) then
45
    if counter(4) = '0' then
46
      sram_io <= "0000000000000111";
47
    else
48
      sram_io <= (others => 'Z');
49
    end if;
50
  end if;
51
end process;
52
53
sram_o <= sram_io;
54
55
end Behavioral;

Danke.
Gruss

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Hallo, also auf den LEDs wirst du nichts erkennen können, auch wenn das 
richtig funktioniert. das geht viel zu schnell für das menschliche Auge.

Du machst ja

sram_o <= sram_io;

und sram_io ist hier beschrieben:
1
    if counter(4) = '0' then
2
      sram_io <= "0000000000000111";
3
    else
4
      sram_io <= (others => 'Z');
5
    end if;

Also du liest nicht aus dem RAM. Aber in jedem 2^4=16ten Takt ist 
sram_io <= "0000000000000111"; und sonst nicht. Also leuchten die LEDs 
1/16tel der Zeit, und immer aber nur für einen Takt, also 20ns bei 
50MHz.

: Bearbeitet durch User
von Peter B. (funkheld)


Lesenswert?

Jup danke.
So etwas habe ich mir auch gedacht, wollte es aber nicht wahr haben 
,weil ich hier das SRAM lese und beschreibe.

---------------------------
process (clk) begin
  if rising_edge (clk) then
    sram_adr  <= "000000000000000011";
    sram_oe   <=  not counter(4);
    sram_we   <=  not counter(4) and counter (0);
  end if;
end process;
----------------------------

Dann müßte ich das Lesen und Schreiben über ein Switsch einleiten und 
getrennt machen ? Nicht so über verschiedene Zeiten wie oben in einer 
If.

danke.
Gruss

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Peter Bierbach schrieb:
> Ich finde den Fehler nicht.
Was sagt die Simulation? Wie sieht deine Testbench aus?

von Gustl B. (-gb-)


Lesenswert?

Das Problem ist glaube ich ein anderes:

Du hast
sram_adr : out   STD_LOGIC_VECTOR (17 downto 0);
sram_io  : inout STD_LOGIC_VECTOR (15 downto 0);
das geht beides raus an das SRAM.

Es ist klar, dass du an sram_adr immer einen Wert angelgst, weil es ist 
ein out. Aber sram_io ist ein inout. Also da solltest du nicht die ganze 
Zeit über einen Wert anlegen, sondern auch davon lesen.

Du musst also zwischen lesen und schreiben unterscheiden.

Ganz grob:
1
sram_io <= daten_out when lesenschreiben = '0' else (others => 'Z');
2
daten_in <= sram_io when lesenschreiben = '1';

daten_out sind std_logic_vector und zwar die Daten die geschrieben 
werden sollen, daten_in ist auch std_logic_vector und zwar das Ziel in 
das gelesen werden soll, also die Bits von sram_io übernommen werden 
sollen.
lesenschreiben ist std_logic, also ein einzelnes Bit. Hier ist es '1' 
wenn gelesen wird und '0' wenn geschrieben wird.

von Peter B. (funkheld)


Lesenswert?

Jup, danke.

Ich habe es jetzt mal getrennt geschrieben:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity sram is
7
port (  clk      : in    STD_LOGIC;
8
        sram_adr : out   STD_LOGIC_VECTOR (17 downto 0);
9
        sram_io  : inout STD_LOGIC_VECTOR (15 downto 0);
10
        sram_o   : out   STD_LOGIC_VECTOR (15 downto 0);
11
        sram_oe  : out   STD_LOGIC;
12
        sram_we  : out   STD_LOGIC;
13
        sram_ce  : out   STD_LOGIC;
14
        sram_ub  : out   STD_LOGIC;
15
        sram_lb  : out   STD_LOGIC;
16
        key  :  in std_logic_vector(3 downto 0)
17
        );
18
end sram;
19
20
architecture Behavioral of sram is
21
22
signal counter: std_logic_vector (4 downto 0) :="00000";
23
24
begin
25
26
process (clk) begin
27
  if rising_edge (clk) then
28
    counter <= counter + 1;
29
  end if;
30
end process;
31
32
sram_ub <= '0';  
33
sram_lb <= '0';  
34
 
35
process (clk) begin
36
  if rising_edge (clk) then
37
    if key(0) ='1' then
38
      sram_oe  <= '1';
39
      sram_ce <= '1';
40
      sram_we <= '1';
41
      
42
      sram_adr <= "000000000000000011";
43
      sram_io <= "0000000000000111";  
44
      
45
      sram_oe  <= '1';
46
      sram_ce <= '1';
47
      sram_we <= '0';
48
      
49
      sram_oe  <= '1';
50
      sram_we <= '0'; 
51
    end if;
52
    
53
    if key(1) ='1' then
54
      sram_oe  <= '1';
55
      sram_ce <= '1';
56
      sram_we <= '1';
57
      
58
      sram_adr <= "000000000000000011";
59
      sram_io <= (others => 'Z');
60
      
61
      sram_oe  <= '0';
62
      sram_ce <= '1';
63
      sram_we <= '1';
64
      
65
      sram_oe  <= '1';
66
      sram_we <= '0'; 
67
    end if;
68
  end if;
69
end process;
70
71
sram_o <= sram_io;
72
73
end Behavioral;

Die LED's gehen noch nicht an.

Gruss

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Was soll das sram_we, sram_ce und das sram_oe? Also wieso steht das da 
öfters? Das was du da für z.B. lesen beschreibst, das geschieht 
gleichzeitig. Also das

      sram_oe  <= '1';
      sram_ce <= '1';
      sram_we <= '1';

      sram_adr <= "000000000000000011";
      sram_io <= (others => 'Z');

      sram_oe  <= '0';
      sram_ce <= '1';
      sram_we <= '1';

      sram_oe  <= '1';
      sram_we <= '0';

geschieht gleichzeitig weil im gleichen Takt. Und da kann z.B. sram_oe 
nur 0 ODER 1 sein aber nicht beides. Wenn du das nacheinander haben 
willst, musst du es auf mehrere Takte aufteilen. VHDL ist nicht wie C 
oder Pascal oder andere Programmiersprachen, es wird nicht von oben nach 
unten der Reihe nach abgearbeitet sondern beschreibt eine 
Hardwareschaltung bei der alle simultan geschieht.

von Peter B. (funkheld)


Lesenswert?

Jup, danke.
Dann muss ich es nach den Takten im Counter aufteilen?
"counter <= counter + 1;" ist ja zu Anfang gesetzt.

Wie setze ich bitte jetzt den counter + einer Zeit in eine If um dieses 
zu setzen:   sram_oe  <= '1'; ?

Gruss

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Wenn du etwas auf mehrere Takte aufteilen willst nennt man das oft 
Zustandsautomat. Man hat also mehrere Zustände in denen jeweils was 
anderes gemacht wird. Wenn die Zustände immer in der gleichen 
Reihenfolge und gleich lang dauern kann man das mit einem Zähler machen.

Also wenn der Zähler 0 ist dann mach dies, wenn der Zähler 1 ist dann 
mache jenes, ...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Gustl Buheitel schrieb:
> VHDL ist nicht wie C oder Pascal oder andere Programmiersprachen, es
> wird nicht von oben nach unten der Reihe nach abgearbeitet
Ein Dejavu!
Allerdings: Peter weiss das schon. Seit 2 Wochen wird es ihm fast 
täglich gesagt. Und er hat sogar ein Buch, das diesen Sachverhalt immer 
wieder unterstreicht.
Allerdings hat er offenbar auch ein sehr selektives und 
in-sich-gekehrtes Wahrnehmungsvermögen...

@Peter:
Meine Frage nach der Simulation und der Testbench hatte durchaus ihren 
Hintergrund!

von Peter B. (funkheld)


Lesenswert?

Hmm...die Testbench habe ich noch nicht gemacht.

---------------------
Also wenn der Zähler 0 ist dann mach dies, wenn der Zähler 1 ist dann
mache jenes, ...
---------------------
Das ich hatte ich wieder nicht gemacht, danke.

Dann müsste ich solche Zeiten verschieden festlegen nach Datenblatt:
signal we : integer range 0 to 1000 := 0;
signal oe usw...

Und dann vor jeden Lese/Schreibvogang in dem einen Process
-----------------------
if (c<1000) then
    c <= c+1;
  else
    schreibe/lese
endif
----------------------
diese Zeiten reinsetzen und am Ende des Processes c wieder auf "0" 
setzen?


Für das Lesen einen Process mit :
if key(0) ='1' then....

und für das Schreiben einen Process mit:
if key(1) ='1' then....



Danke.
Gruss

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Nein. Ein Takt ist bei 50MHz 20ns lang. Wenn du jetzt nur als Beispiel 
sram_oe für 20ns auf 1 und danach für 40ns auf 0 und dann wieder für 
20ns auf 1, ... legen willst, dann zählst du von 0 bis 2.

If Zähler < 2 then
Zähler <= Zähler +1;
Else
Zähler <= 0;
End if;

Und dann:

If Zähler = 0 then
sram_oe <= 1;
Elseif Zähler 1 or Zähler = 2 then
sram_oe <= 0;
End if;

Das kann man in diesem Beispiel auch noch einfacher schreiben aber es 
wird hoffentlich klar, dass sram_oe jetzt für einen Takt auf 1 und dann 
für 2 Takte auf 0 gesetzt wird. So kann man das mit verschiedenen Zeiten 
umsetzen. Wenn etwas länger dauern soll zählt man eben länger.

von Peter B. (funkheld)


Lesenswert?

Ja danke.

So werde ich es mal schreiben nach dem Datenblatt.


Gruss

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.