Frage zu fifo

Gast #1635845
Lesenswert?

Hi Lothar,

wenn ich deine Single-Clock-Fifo Beschreibung simuliere, erhalte ich in 
Modelsim folgende Fehlermeldung:
# ** Fatal: (vsim-3421) Value 256 is out of range 0 to 255.
1
process begin
2
  wait until rising_edge(CLK);
3
  if (Write='1' and full_loc='0') then
4
     memory(wrcnt) <= unsigned(Din);
5
     wrcnt <= wrcnt+1;
6
  end if;
7
  if (Read='1') then
8
     Dout <= std_logic_vector(memory(rdcnt)); -- Adresse getaktet --> BRAM
9
     rdcnt <= rdcnt+1;
10
  end if;
11
  end process;

In der Synthese stellt das Überrollen der Zähler kein Problem dar. Wie 
löst man das Problem für die Simulation?

Matze
Moderator (Firma: Titel) Persönliche Seite #1635869
Lesenswert?

Hmm... böseböse... :-/
Das muß ich mal noch genauer anschauen...

Probiers mal mit einem unsigned als Pointer. Der läuft kostenlos über:
1
signal wrcnt : unsigned (Addrbreite-1 downto 0) := (others => '0');
2
signal rdcnt : unsigned (Addrbreite-1 downto 0) := (others => '0');
3

4
type speicher is array(0 to (2**Addrbreite)-1) of unsigned(Wortbreite-1 downto 0);
5
signal memory : speicher;   
6

7
begin
8
  process begin
9
  wait until rising_edge(CLK);
10
  if (Write='1' and full_loc='0') then
11
     memory(to_integer(wrcnt)) <= unsigned(Din);
12
     wrcnt <= wrcnt+1;
13
  end if;
14
  if (Read='1') then
15
     Dout <= std_logic_vector(memory(to_integer(rdcnt))); -- Adresse getaktet --> BRAM
16
     rdcnt <= rdcnt+1;
17
  end if;
18
  end process;
19
  Full  <= '1' when rdcnt = wrcnt+1 else '0';
20
  Empty <= '1' when rdcnt = wrcnt   else '0';
21
end Behavioral;
Gast #1635871
Lesenswert?

1
wrcnt <= (wrcnt+1) % 2**Addrbreite;
2
...
3
rdcnt <= (rdcnt+1) % 2**Addrbreite;
Das sollte den Fehler abwenden. Allerdings könnte es zu ernsten 
(funktionellen) Problemen kommen, wenn die FIFO-Adressen überlaufen...

Duke
Moderator (Firma: Titel) Persönliche Seite #1636206
Lesenswert?

Also, wie versprochen hier der überarbeitete Code. Einmal mit unsigned 
und einemal mit integer. Beide Beschreibungen verhalten sich in der 
Simulation und auch in der Synthese identisch. Es werden keine Daten 
verloren oder hergezaubert, die Signale Full und Empty kommen immer 
korrekt.
Ich habe zusätzlich zum Code vom ganz oben noch eine "Lesesicherung" 
eingebaut. Jetzt kann bei fälschlichem mehrmaligen Lesen trotz Empty='1' 
der Lesezeiger richtig verwaltet.
Angehängte Dateien:
Gast #1636678
Lesenswert?

Frage : schonmal einen ressourcenvergleich gemacht ?

wenn das keine Nachteile hat werde ich demnächst nurnoch eine solche 
Beschreibung benutzen, dann ist man wenigstens von der Technologie 
unabhängig, nicht wie beim coregen.
Moderator (Firma: Titel) Persönliche Seite #1636835
Lesenswert?

>> Frage : schonmal einen ressourcenvergleich gemacht ?
Gegen den Xilinx-Core habe ich noch nicht verglichen, aber die beiden 
Implementierungen (unsigned und integer) brauchen für einen 1k * 8Bit 
Fifo die Ressourcen wie im Screenshot.

> die unsigned-Variante sieht nun gut aus in der Simulation!
Die Integer-Variante laut meiner Simulation auch...
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #1637435
Lesenswert?

Matthias Krüßelin schrieb:
> Leider kann ich bei einer Addressbreite von 4
> nur 15 statt 16 Einträgen speichern,
Korrekt.
> Ist dies so gewünscht?
Es ist toleriert ;-)
Dadurch vereinfacht sich die Verwaltung von Full und Empty eklatant.

> Wie könnte man dies verbessern?
Die Verwaltung des Busy-Flags muß in den Schreib-Pfad des Prozesses mit 
hinein. Damit wird das Setzen und Rücksetzen des Flags aufgeteilt und 
schwieriger zu handhaben.

Und ehrlich: Wenn dein Fifo volläuft, dann kommt es auf 1 Datenwort hin 
oder her auch nicht mehr an  :-o

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