Forum: FPGA, VHDL & Co. Dual-Port RAMs with synchronous Read


von Horst (Gast)


Lesenswert?

Hi,

ich verwende in meinem Design Dual-Port RAMs with synchronous Read (Read 
Trough) and Two Clocks.

Nun beobachte ich beim Test an der Hardware, dass im Mittel nach jeder 
10en FPGA Konfiguartion die Logik nicht wie gewünscht arbeitet. Die 
Funktionen die Informationen vom Dual Output Port benötigen 
funktionieren dann nicht richtig.

Kann das mit der Arbitrationslogik ("Zugriffsverwaltung") des Dual-Port 
RAMs zusammenhängen? Wie wird der Zugriff gesteuert?
Vielleicht sind die Phasenversätze der beiden Taktquellen so ungünstig, 
dass immer nur der Primary Output Port richtig ausgelesen wird und der 
Dual-Port nicht????

Was denkt Ihr dazu?

Gruß Horst

von Jan M. (mueschel)


Lesenswert?

Ja.


... Im Ernst: Ein paar mehr Details bitte, Plattform, vielleicht ein 
Auszug aus dem Quelltext. Beispielsweise der Virtex4 hat bekannte Bugs, 
was dual ported fifos angeht.

von Horst (Gast)


Lesenswert?

Zielarchitektur ist ein Virtex II FPGA XC2V1000

Die RAM-Blöcke habe ich folgendermaßen implementiert:
--
-- Dual-Port Block RAM with Different Clocks
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ram is
port (clka : in std_logic;
clkb : in std_logic;
wea : in std_logic;
addra : in std_logic_vector(8 downto 0);
addrb : in std_logic_vector(8 downto 0);
dia : in std_logic_vector(31 downto 0);
doa : out std_logic_vector(31 downto 0);
dob : out std_logic_vector(31 downto 0));
end ram;
architecture syn of ram is
type ram_type is array (511 downto 0) of std_logic_vector (15 downto
0);
signal RAM : ram_type;
signal read_addra : std_logic_vector(8 downto 0);
signal read_addrb : std_logic_vector(8 downto 0);
begin
process (clka)
begin
if (clka'event and clka = '1') then
if (wea = '1') then
RAM(conv_integer(addra)) <= dia;
end if;
read_addra <= addra;
end if;
end process;
process (clkb)
begin
if (clkb'event and clkb = '1') then
read_addrb <= addrb;
end if;
end process;
doa <= RAM(conv_integer(read_addra));
dob <= RAM(conv_integer(read_addrb));
end syn;

von Jan M. (mueschel)


Lesenswert?

Quellcode besser als Anhang - dann funktionieren auch Einrueckungen und 
Codehighlighting.

Warum registrierst du deine Adress-Signale aber nicht die 
Datenausgaenge?

von Horst (Gast)


Lesenswert?

Das ist ein Beispiel für die Implementierung eines DUAl-Port RAMs von 
Xilinx. Viele Alternativen gibt es nicht, sonst wird die Beschreibung 
nicht als BLOCK RAM implementiert.

Das Abspeichern funktioniert!!! Ich wollte nur mal von euch wissen ob es 
möglich ist, dass die Phasenbeziehung zwischen den Takten (clka und clkb 
haben die gleiche Frequenz aber unterschiedliche externe Quellen) die 
Arbitrierung beeinflusst:

von Jan M. (mueschel)


Lesenswert?

Ja natuerlich kann das sein: Z.B. wenn du an eine Adresse schreibst und 
liest direkt wieder von ihr in der anderen Clockdomaene - das kann 
Probleme geben.

Probier es doch mal, die Ausgaenge zu registrieren. Ich glaube aber 
eher, dass das Problem an irgendeinem anderen unsauberen Uebergang 
zwischen beiden Domaenen ist.

von Horst (Gast)


Lesenswert?

Probier es doch mal, die Ausgaenge zu registrieren.
Verstehe nicht was Du damit meinst!

von Jan M. (mueschel)


Lesenswert?

Registrieren = mit FlipFlop versehen:


process (clkb)
  begin
    if (clkb'event and clkb = '1') then
      dob <= RAM(conv_integer(read_addrb));
    end if;
  end process;

von Horst (Gast)


Lesenswert?

Danke!

werde es mal versuchen...

ich glaube das ISE mir dan daraus Distributed RAM macht und ich über 
200% an Ressourcen verbrauche.....

von Jan M. (mueschel)


Lesenswert?

Ise ist zwar nicht gut, was vielerlei Optimierungen angeht, aber so 
schlecht nun auch wieder nicht ;-)

von Andy (Gast)


Lesenswert?

>>Probier es doch mal, die Ausgaenge zu registrieren. Ich glaube aber
>>eher, dass das Problem an irgendeinem anderen unsauberen Uebergang
>>zwischen beiden Domaenen ist.

Wozu sollte man die Ausgänge registrieren? Meiner Meinung nach unnötig. 
Außerdem sollte ein gleichzeitiger Zugriff auf d-bram zu keinen 
Problemen führen.

Hängen bei dir die Phasen unmittelbar voneinander ab?

von Da M. (damicha)


Lesenswert?

Hallo Horst,

Wenn Du Deinen Speicher generisch beschreibst, bekommst Du in der 
Simulation keine Warnings mehr, falls Du von beiden Ports aus auf die 
selbe Speicherstelle schreibst bzw. liest und schreibst. Es sei den Du 
implementierst den Test selbst.
Das Xilinx Blockram Model testet solche Sachen und warnt. Dafür 
simuliert es aber auch etwas langsamer :).

Die Ausgänge in Registern buffern würde ich dann machen, wenn die ca. 
2.5 ns Outputdelay nicht stören und der Netzload für die Outputsignale 
nicht zu hoch ist.


Gruß DaMicha.

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.