Forum: FPGA, VHDL & Co. Anzahl bits für ein integer range 0 to N herausfinden


von Till (Gast)


Lesenswert?

Hallo Leute, ich suche eine Möglichkeit die Anzahl der verwendeten Bits 
für diesen Datentyp herauszufinden:
1
subtype meinTyp is integer range 0 to N-1;

N ist hierbei ein Design-Parameter, steht also zu Beginn fest, aber soll 
bei Änderung keine weiteren Änderungen sonstwo im Code nach sich ziehen.

An anderer Stelle möchte ich alle Bits einer Variable von obigem Typ von 
links nach rechts durchlaufen. Dafür möchte ich das ganze in einen 
Vector umformen:
1
mybitvector := to_unsigned(myinteger, myinteger'length);

was so natürlich nicht geht - 'length gibt es nicht für meinen Typ.

helfen könnte 'high - aber dann muss ich irgendwie den dualen 
Logarithmus bestimmen - und da wüsste ich auch wieder nicht wie das 
geht. Da das aber vor der Synthese geschehen kann, muss es doch einen 
Weg geben?!

von D. I. (Gast)


Lesenswert?


von Duke Scarring (Gast)


Lesenswert?


von Matthias G. (mgottke)


Lesenswert?

Kleiner Auszug aus einem meiner Designs:
1
generic
2
(   max_range : positive );
3
...
4
5
   constant BIT_SIZE : natural := integer(ceil(log2(real(max_range) + 0.5)));

von Till (Gast)


Lesenswert?

Mh, danke für diese Lösungen.

Irgendwie sehe ich aber nicht ganz ein, warum das so umständlich sein 
muss. Eine synthetisierbare log2-Funktion ist schon gar nicht nötig...

Eigentlich könnte schon bevor überhaupt ein Synthesetool gestartet wird 
der richtige Wert bestimmt werden. Das würde die ganze Synthese 
beschleunigen und nebenbei für viel mehr Übersichtlichkeit sorgen... Ich 
"löse" das jetzt mal so, dass ich einfach die zugehörige Breite zusammen 
mit dem Design Parameter explizit angebe.
1
constant N     : integer := 64;            -- design parameter
2
constant Nbits : integer := 6;             -- ceil(log2(N))
3
4
subtype meinTyp is integer range 0 to N-1; -- bitwidth of Nbits used

Oder gibt es einen Grund, warum "meinTyp" auf einen Vector anderer 
Breite abgebildet werden könnte? Signed oder Unsigned ergibt sich ja aus 
der range... wenn das nicht klappt könnte man auch natural verwenden, 
glaube aber nicht, dass das einen Unterschied macht (oder?).

von Annexe (Gast)


Lesenswert?

Das Log2 wird ja nicht synthetisiert, sondern davor wie du es in deinem 
Beispiel manuell gemacht hast, eine weitere Konstante automatisch 
berechnet.

von Till (Gast)


Lesenswert?

Ok, das heißt also, dass ich zwar eine synthetisierbare Funktion 
aufrufe, diese aber nur verwendet wird um eine weitere Konstante zu 
bestimmen?

Ist das nicht trotzdem total ineffizient, weil erst mal die 
selbstdefinierte Funktion interpretiert werden muss? Eine in der Sprache 
VHDL verankerte Funktion für log2 wäre halt deutlich besser (und eben 
auch eindeutiger sowie weniger fehleranfällig als wenn ich das selbst 
schreibe).

Wenn das schon nicht in VHDL verankert ist, was mir aber grade bei log2 
total unüberlegt erscheint, dann sollte es zumindest Tricks seitens der 
IDE geben... ich verwende hier Xilinx ISE 12.2 (das Ganze wird später 
für einen FPGA synthetisiert).

Hier habe ich auch grade festgestellt, dass wenn ich eine Testbench für 
eine Entity mit einem Port vom Typ "integer range 0 to N-1" erstellen 
lasse (wobei N=64), korret erkannt wird, dass hierzu dann ein 
std_logic_vector (5 downto 0) passt. Warum kann das nicht immer 
automatisch gehn (am Besten über eine Methode ala 'length für integer 
range ...)? VHDL ist doch doof! :D

Aber danke für eure Hilfe, hat sich erledigt denke ich.

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


Lesenswert?

> Ok, das heißt also, dass ich zwar eine synthetisierbare Funktion
> aufrufe, diese aber nur verwendet wird um eine weitere Konstante zu
> bestimmen?
Ich möchte sehr stark bezweifeln, dass du die log2() Funktion 
tatsächlich synthetisiert bekommst...

> Ist das nicht trotzdem total ineffizient, weil erst mal die
> selbstdefinierte Funktion interpretiert werden muss?
Das passiert ja nur 1 mal auf dem Syntheserechner.

> Eine in der Sprache VHDL verankerte Funktion für log2 wäre halt
> deutlich besser
Was bringt dich auf diesen Gedanken? Es sind die Basisoperatoren in VHDL 
definiert. Und es ist nachgewiesen, dass mit diesen Basisoperatoren alle 
nötigen Berechnungen angestellt werden können.
In C mußt du Libraries einbinden, um bestimmte naheliegende Funktionen 
aufrufen zu können. Und genau das passiert hier auch:
1
USE ieee.math_real.log2;
2
USE ieee.math_real.ceil;
3
:
4
constant COUNT_WIDTH : integer := INTEGER(CEIL(LOG2(REAL(COUNT_MAX+1))));
5
signal   cnt  : unsigned (COUNT_WIDTH-1 downto 0) := (others=>'0');
Und dann ist LOG2() wieder nur ein Funktionsaufruf.

> VHDL ist doch doof! :D
Ja, VDHL ist eben VHDL. Besser, du findest dich längerfristig damit ab, 
dass VHDL viel mehr kann, als ein Synthesizer kann...  ;-)

Till schrieb:
>> Oder gibt es einen Grund, warum "meinTyp" auf einen Vector anderer
>> Breite abgebildet werden könnte?
Ja. NAND-Flash-Zellen können z.B. mehr als 1 Bit speichern. Du brauchst 
um das in VHDL zu beschreiben also z.B. eine Logik, die 8 Zustände (3 
Bit) auf 1 Speicherzelle abbilden kann. Damit wäre dann eine 
Integer-Busbreite von 32 Bit auf einmal ein Vektor mit einer Breite von 
11 Speicherzellen.
Und spätestens dann kommst du auch mit einer eingebauten log2() Funktion 
nicht sehr weit...

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.