Block RAM mit beliebigen Größen

Gast #6974376
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.
Gast #6974414
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.
Gast #6974434
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).
Gast #6974437
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
Angehängte Dateien:
#6974790
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);
#6974928
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.

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