Forum: FPGA, VHDL & Co. Block RAM mit beliebigen Größen


von Nils D. (Gast)


Lesenswert?

Ich habe  ein Problem Block RAM mit nicht 2^n Größen in ghdl zu 
simulieren. Es gibt immer ein out of bound error. Ich definieren Typen 
mit:
1
type coefficient_t is array (0 to 63) of std_logic_vector(17 downto 0);
2
subtype coeff_address_t is unsigned(5 downto 0);

Und dann eine Konstante mit :
1
constant coeff_i : coefficient_t := (
2
...
3
);

Nun will ich in einer RAM Entity darauf zugreifen mit :
1
q <= ram_block(to_integer(unsigned(read_address)));

Wobei read_address vom Typ coeff_address_t ist. Wenn ich aber das Array 
kleiner mache dann bekomme ich immer out of bound Fehler, was logisch 
ist, denn der Datentyp für die Adresse kann größer werden. Da ich das 
später syntetisieren möchte daher die Frage wie man auf ein Array 
benutzen kann wenn der Adresstyp größer als das Array ist? Ich stelle 
sicher, dass niemals auf ein nicht existierendes Element zugegriffen 
wird.

von Gustl (Gast)


Lesenswert?

Tja den code mit dem Fehler hast du leider nicht gepostet. Wie soll man 
dir da helfen?
Mach daraus ein Minimalbeispiel das in der Simulation den Fehler 
beinhaltet und poste das. Meistens sieht man dabei schon was man falsch 
macht.

von Fpgakuechle K. (Gast)


Angehängte Dateien:

Lesenswert?

Da funktionierende beispiele zur BRAM-Instanziierung per array-Typen: 
https://www.mikrocontroller.net/articles/Retrocomputing_auf_FPGA#(P)ROM-Images

Du musst den typ für den addressvector auch alls index-type für das ram 
array verwenden.

Im Anhang ein weiteres Beispiel wit vorinitialisierten RAM

von dfgh (Gast)


Lesenswert?

Nils D. schrieb:
> Ich stelle
> sicher, dass niemals auf ein nicht existierendes Element zugegriffen
> wird.

Das muss man jetzt nur noch der Synthese klar machen - und das kann 
schon mal etwas umständlich sein ;-)

Muss denn die Adresse vom Typ unsigned sein?
Man könnte auch einen Integer-Subtyp mit passendem Wertebereich nutzen 
und den nur bei Bedarf in Unsigned umwandeln. Dann hat man das 
Range-Problem nur noch falls man mal Unsigned->Adresstyp umwandelt, und 
da kann dann einfach festlegen, dass alle "out of range" Werte auf 
irgendeinen bekannten Wert gemappt werden (oder man wirft eine failure).

von Fpgakuechle K. (Gast)


Angehängte Dateien:

Lesenswert?

Da funktionierende Beispiele zur BRAM-Instanziierung per array-Typen: 
https://www.mikrocontroller.net/articles/Retrocomputing_auf_FPGA#(P)ROM-Images

Du musst den typ für den addressvector auch als index-type für das ram 
array verwenden.

Im Anhang ein weiteres Beispiel wit vorinitialisierten RAM. Natürlich 
gibt der FPGA-Hersteller auch beispiele an wie man das für seinen FPGA 
machen sollte: 
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_1/ug901-vivado-synthesis.pdf 
S.95 ff

von Nils D. (Gast)


Lesenswert?

Der Grund warum ich ein unsigned nehme ist, dass ich die Adresse eben 
hochzählen möchte.

von Gustl B. (-gb-)


Lesenswert?

Und weiterhin fehlt der Code der den Fehler erzeugt.

Nils D. schrieb:
> q <= ram_block(to_integer(unsigned(read_address)));

Warum noch ein unsigned() und die Adresse herum wenn doch

Nils D. schrieb:
> Wobei read_address vom Typ coeff_address_t ist.

Nils D. schrieb:
> subtype coeff_address_t is unsigned(5 downto 0);

die Adresse schon ein unsigned ist?
Warum noch den subtype coeff_address_t anlegen wenn man auch gleich

signal read_address : unsigned(5 downto 0);

schreiben könnte?

Fragen über Fragen und zu wenige Antworten in Form von Code.

Nils D. schrieb:
> Der Grund warum ich ein unsigned nehme ist, dass ich die Adresse eben
> hochzählen möchte.

Du kannst auch slv und integer hochzählen.
slv:
slv <= std_logic_vector(unsigned(slv) +1);

: Bearbeitet durch User
von Fpgakuechle K. (Gast)


Lesenswert?

Der soll sich einfach mal den Syntheses style guide zum 'inferredg 
memories' durchlesen, da steht alles mit Beispielen drin. Da das 
beispiel für Altera: 
https://www.intel.com/content/www/us/en/programmable/quartushelp/13.0/mergedProjects/hdl/vhdl/vhdl_pro_ram_inferred.htm

Da das Ganze architekturunabhängig mit address-incrementer: 
https://vhdlwhiz.com/ring-buffer-fifo/

von Nils D. (Gast)


Lesenswert?

Die Beispiele beziehen sich immer auf ramgrößen die zweierpotenzen sind.

von Gustl B. (-gb-)


Lesenswert?

Wo ist denn das Problem mit 2^n? Nimm einfach die nächst größere 
Zweierpotenz. Wenn die Synthese feststellt, dass RAM nicht genutzt wird, 
dann wird das wegoptimiert.

Ausserdem fehlt weiterhin der Code der den Fehler verursacht. Der Code 
von ganz oben ist das nicht, denn coefficient_t hat 2^6 Einträge. Der 
Fehler steckt also irgendwo im Code den du uns noch nicht gezeigt hast.

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.