SRAM wird nicht gelesen vom DE1

OP #3633530
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
#3633580
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.
OP #3633634
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
#3633678
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.
OP #3633713
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
#3633721
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.
#3633740
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, ...
Moderator (Firma: Titel) Persönliche Seite #3633744
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!
OP #3633754
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
#3633778
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren