Forum: FPGA, VHDL & Co. Sporadischer Lesefehler


von vhtl (Gast)


Lesenswert?

In meiner Schaltung benutze ich einen RAM-Baustein, der von einem 
Schreiber gefüllt und von einem Leser ausgelesen wird. Während des 
Füllens darf der Leser nicht zugreifen, sonst gibt es Murks.

+---------+       +-----------+
|         |       |           |
|   RAM   +---+---+   Leser   |
|         |   |   |           |
+---------+   |   +-----------+
              |                           SO NICHT!
              |   +-----------+
              |   |           |
              +---+ Schreiber |
                  |           |
                  +-----------+

Also benutze ich einen XC9572XL, der als Vermittler für den RAM-Baustein 
dienen soll. (Natürlich macht der 9572 noch viel mehr.)

+---------+       +---------+       +-----------+
|         |       |         |       |           |
|   RAM   +-------+  PROXY  +-------+   Leser   |
|         |       |  (9572) |       |           |
+---------+       +----+----+       +-----------+
                       |
                       |            +-----------+
                       |            |           |
                       +------------+ Schreiber |
                                    |           |
                                    +-----------+

Das Problem ist nun, wenn ich meine Schaltung laufen lasse (also NICHT 
in der Simulation), funktioniert zunächst alles wunderbar, aber jeweils 
nach durchschnittlich 5-10 Minuten erhalte ich einen Lesefehler.

Hier ist die Implementierung von Lesen und Schreiben (soweit relevant):
1
entity proxy is
2
  Port ( PROXY_ADDR : in std_logic_vector(7 downto 0);
3
         PROXY_DATA : out std_logic_vector(7 downto 0) := (others => 'Z');
4
         PROXY_SELECT : in std_logic;  -- alle Signale active low
5
         PROXY_READ : in std_logic;
6
7
         RAM_DATA : inout std_logic_vector(7 downto 0) := (others => 'Z');
8
         RAM_ADDR : out std_logic_vector(15 downto 0);
9
         RAM_OE : out std_logic := '1';
10
         RAM_WR : out std_logic := '1';
11
12
         -- Schreiber setzt LOAD auf 0
13
         LOAD : in std_logic;
14
         LOAD_DATA : in std_logic_vector(7 downto 0);
15
         LOAD_WE : in std_logic ); 
16
end logic;
17
18
architecture Behavioral of proxy is
19
  signal load_addr : std_logic_vector(15 downto 0);
20
begin
21
              
22
  RAM_ADDR <= load_addr when LOAD = '0' else
23
              "00110000" & PROXY_ADDR when PROXY_SEL = '0' else 
24
              (others => '-');
25
26
  with LOAD select
27
    RAM_DATA <= LOAD_DATA when '0',
28
                (others => 'Z') when others;
29
   
30
  RAM_OE <= '1' when LOAD = '0' else
31
            '0' when PROXY_SEL = '0' else
32
            '1';
33
34
  with LOAD select
35
    RAM_WE <= LOAD_WE when '0',
36
              '1' when others;
37
38
  PROXY_DATA <= RAM_DATA when LOAD = '1' and PROXY_SEL = '0' and
39
                              PROXY_READ = '0' else
40
                (others => 'Z');
41
42
  RAMLOAD: process(...)
43
  begin
44
    -- Schreiblogik ...
45
  end process;
46
47
end Behavioral;

Der Schreiber setzt zu Beginn LOAD auf 0 und füllt das RAM. Nach einer 
Sekunde geht LOAD auf 1 und ändert sich nicht mehr. Das funktioniert 
problemlos.

Der Leser legt pro Lesevorgang PROXY_ADDR an und setzt PROXY_SEL auf 0. 
Nach kurzer Zeit geht dann auch PROXY_READ auf 0, und die Daten werden 
gelesen. Danach geht erst PROXY_READ und dann PROXY_SEL auf 1.

Ich freue mich, daß noch jemand bis hierhin mitgelesen hat. :-) Aber hat 
der- oder diejenige auch eine Idee, was diese sporadischen Lesefehler 
verursachen kann? Selbst wenn der Code wie oben reduziert ist, treten 
sie auf.

Ich selbst habe nur zwei Theorien, die aber für mich unwahrscheinlich 
klingen.

(1) Irgendeines der Signal kommt zu früh/zu spät an, bevor sich alles 
stabilisieren kann. Ich wüßte nur nicht, welches Signal das sein sollte. 
Die Bedingungen von RAM_ADDR und RAM_OE erfüllen sich früher, damit sich 
das RAM stabilisieren kann.

(2) Die Signale kommen nicht rechtzeitig an. Es dauert einige Zeit, bis 
sich die Leseanforderung zum RAM und wieder zurück gekämpft hat. Aber 
PROXY_READ ist ca. 500 ns auf 0, was doch ausreichen sollte?!

Ich bin noch ein ziemlicher VHDL-Anfänger und arbeite schon zwei Wochen 
an dem Problem, aber  ohne Ideen komme ich hier nicht mehr weiter.

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


Lesenswert?

vhtl schrieb:
> Aber hat der- oder diejenige auch eine Idee, was diese sporadischen
> Lesefehler verursachen kann?
Ist es ein Lesefehler oder werden falsche Daten ins RAM geschrieben?

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


Lesenswert?

vhtl schrieb:
> Ich selbst habe nur zwei Theorien, die aber für mich unwahrscheinlich
> klingen.... (1)...  (2)...
(3) Irgendwelche Störungen.
(4) keine bzw zu wenige Blockkondensatoren am CPLD.
(5) ungünstiges Layout

> else        (others => '-');
Das wird nicht synthetisiert...

vhtl schrieb:
> aber jeweils nach durchschnittlich 5-10 Minuten erhalte ich einen
> Lesefehler.
Zeigt der ein Muster? Sind immer gleiche Bits betroffen?

: Bearbeitet durch Moderator
von vhtl (Gast)


Lesenswert?

Nein, es ist wirklich ein Lesefehler. Mein Testprogramm läuft in einer 
Endlosschleife und liest alle Bytes ringsrum. Erst nach einigen Tausend 
Zyklen gibt es einen Lesefehler, d.h. das Schreiben muß korrekt sein.

von vhtl (Gast)


Lesenswert?

Danke für Deine Ideen.

Lothar M. schrieb:
> (3) Irgendwelche Störungen.
> (4) keine bzw zu wenige Blockkondensatoren am CPLD.
> (5) ungünstiges Layout

Schwer einzuschätzen, aber ich sage mal so: Der Rest vom CPLD (der auch 
auf das RAM zugreift) funktioniert einwandfrei. Aber klar, einige 
Signale gibt es nur hier.

>> Lesefehler.
> Zeigt der ein Muster? Sind immer gleiche Bits betroffen?

Nein, kein Muster. Aber jetzt, wo Du fragt, fällt mir auf, daß unter den 
falsch gelesenen Werte auch Werte sind, die im RAM gar nicht vorkommen!

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


Lesenswert?

Dann würde ich das RAM jetzt mal mit lauter 0x55 beschreiben und nochmal 
testen. Danach mit 0xAA. Und dann mit aufsteigenden Werten usw. Auch ein 
Gray-Code hilft als Füllmuster manchmal weiter...

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.