Counter mit Datentyp natural

OP #7325493
Lesenswert?

Hallo, ich bin der aus Beitrag "Setzen einzelner Stellen eines std_logic_vector" und habe mir jetzt mal einen Account angelegt... In den Lehrbüchern heißt es, dass für einen Zähler bzw. arithmetische Operationen am besten Signed oder Unsigned verwendet werden sollte. In meiner Schaltung verwendete ich ausschließlich natural, was auch einwandfrei zu synthetisieren war. Gibt es einen Grund es nicht so zu machen?

1
entity Beispiel is
2
    generic (ANZAHL:natural:=10);
3
    Port
4
    
5
    (   CLK, RST  : in  STD_LOGIC;
6
        DOUT      : out STD_LOGIC);
7
end Beispiel;
8

9
architecture Behavioral of Beispiel is
10
    constant MAXCOUNT1: natural range 0 to (ANZAHL+10):= (ANZAHL+10);
11
    constant MAXCOUNT2: natural range 0 to ANZAHL:= ANZAHL;
12
    
13
    signal COUNTER1: natural range 0 to (ANZAHL+10):= 0;
14
    
15
begin
16
p1: process(CLK, RST)
17
variable COUNTER2: natural range 0 to MAX:=0;
18
begin
19
    if(RST = '1') then
20
        COUNTER1 := 0;
21
        COUNTER2 := 0;
22
    elsif rising_edge(CLK) then
23
        COUNTER1 := COUNTER1 + 1; 
24
        COUNTER2 := COUNTER2 + 1;
25
    end if;            
26
end process;
27
   
28
end Behavioral;

Der Code ist nicht vollständig und soll nur zeigen was ich meine. Mit unsigned hätte ich das Problem, dass zuvor die Länge des unsigned Vektors bekannt sein muss. Allerdings wollte ich die Parameter der Schaltung zentral konfigurierbar machen und bin mir nicht sicher wie man, ohne IEEE.math_real mit log2(real(max_val)) auf die Breite kommt. Vielleicht hat jemand eine Idee wie ich das lösen könnte. Oder kann man es einfach so lassen? Viele Grüße

Gast #7325514
Lesenswert?

Natural geht auch, wenn man einen range angibt. Nur falls es mal aus dem FPGA rausgehen soll, benötigt man zwei Umwandlungen: http://www.lothar-miller.de/s9y/categories/16-Numeric_Std signed/unsigned ist eben die 'goldene Mitte'.

Die log2 aus der math_real kann man nach meiner Erfahrung problemlos verwenden. Die Bitbreite ist ja i.d.R. zum Synthesezeitpunkt statisch.

Duke

Gast #7325585
Lesenswert?

Zeile 19: Die Klammern beim if sind unnötig Zeile 20: signal velangt '<=' als Zuweisungsoperator

Zeile 3: man kann zuerst einen type definieren, dann hate man mit 'high und 'low Zuigriff auf die grenzen.

1
    typedef T_COUNTER1 is natural range 0 to (ANZAHL+10);
2
    signal COUNTER1: T_COUNTER1 := T_COUNTER1'low; -- unnötige signalinitialisierung, bringt Punktabzug
3

4
--im Process auch
5

6
if COUNTER1 = T_COUNTER'high then
7
 COUNTER1 <= T_COUNTER'low;
8
else
9
   COUNTER <= Counter + 1; 
10
end if;
Gast #7325637
Lesenswert?

Marco schrieb:

Ent-Schnitzer schrieb:

Zeile 20: signal velangt '<=' als Zuweisungsoperator

Ja stimmt, habe ich hier übersehen.

Ent-Schnitzer schrieb:

typedef T_COUNTER1 is natural range 0 to (ANZAHL+10); signal COUNTER1: T_COUNTER1 := T_COUNTER1'low;

Die Konstanten sind gemeint oder? Weil das auch mit T_COUNTER'high angegeben werden kann.

Die ganze typedekleration ist die 'Konstante'. Da haste alles an einer Code-Stelle, obere wie untere Grenze und musst nicht mit zwei Constanten arbeiten. Siehe VHDL-Attribute: https://redirect.cs.umbc.edu/portal/help/VHDL/attribute.html

Wobei subtype statt typedef die korrekte Wahl ist. Etwa wie in: https://www.mikrocontroller.net/attachment/581236/single_led-cynchron.vhd

Gast #7325644
Lesenswert?

Es ist in der Tat möglich, dass "natural" die bequemste Wahl für arithmetische Operationen in einem Zähler ist, da es keine Begrenzungen auf die maximale Anzahl der Bits hat und es automatisch die richtige Anzahl der Bits für den Zähler berechnet. Es gibt jedoch auch Nachteile bei der Verwendung von "natural", da es möglicherweise zu Überläufen führen kann, falls die maximale Anzahl der Bits nicht korrekt berechnet wurde.

Da du die Schaltung zentral konfigurierbar machen wollen, könnsten du die Breite des Zählers auf Basis des generischen Parameters ANZAHL berechnen. Hier ist ein Beispiel, wie du das tun kannst:

constant MAXCOUNT: natural range 0 to ANZAHL:= ANZAHL; constant ZAEHLERBREITE: integer:=ceil(log2(real(MAXCOUNT))); signal COUNTER: unsigned(ZAEHLERBREITE-1 downto 0) := (others => '0');

Dieser Code berechnet die Breite des Zählers basierend auf dem generischen Parameter ANZAHL und deklariert den Zähler als "unsigned" mit der berechneten Breite. Beachten Sie, dass ich hier die VHDL-Funktion "ceil" verwendet habe, die den nächst höheren ganzzahligen Wert zurückgibt, um sicherzustellen, dass die Zählerbreite groß genug ist, um alle möglichen Zählerwerte aufzunehmen.

Letztlich hängt die Wahl zwischen "natural" oder "unsigned" von deinen spezifischen Anforderungen und Bedenken ab. Wenn du sicher bist, dass deine Schaltung korrekt funktionieren wird, wenn du "natural" verwenden, kannst du es einfach so lassen. Andernfalls kannst du die Breite des Zählers berechnen und ihn als "unsigned" deklarieren, um sicherzustellen, dass es keine Überläufe gibt.

#7325679
Lesenswert?

Hallooooo schrieb:

Es ist in der Tat möglich

Typische ChatBot AI-Antwort.

Episches Rumgelabere und am Ende ist die Antwort eben doch grottenfalsch.

Natural kann man tatsächlich prima als Zähler einsetzen, aber der Datentyp hat nun mal keineswegs "keine Beschränkung in der Anzahl der Bits". Im Gegenteil - bei praktische allen Tools ist beim Wertebereich bei 2 ** 31 - 1 Schluss (und das ist auch der Grund dafür, warum UNSIGNED oft die bessere Wahl ist)..

Gast #7325780
Lesenswert?

Markus F. schrieb:

(und das ist auch der Grund dafür, warum UNSIGNED oft die bessere Wahl ist)..

Und wer weiterdenkt kommt auf "ganz wilde" Zähler, die nicht wie die dummen Hühner 1,2,3,4,5,6 .... die Körner wegpicken, sondern bspw. 1,3,7,5,4 . Brauchen die selben ressourcen aber weniger Strom und sind Fehlertoleranter. (Gray-encoded counter). Oder LFSR basierte Counter als Schnellläufer, ...

https://hackaday.com/2014/06/29/counting-really-really-fast-with-an-fpga/

Das macht man dann eher mit std_logic_vector.

Gast #7325796
Lesenswert?

Im Gegenteil - bei praktische allen Tools ist beim Wertebereich bei 2 ** 31 - 1 Schluss (und das ist auch der Grund dafür, warum UNSIGNED oft die bessere Wahl ist)..

Danke fuer die schnelle Korrektur. Ich dachte schon ich bin im falschen Film.

Gast #7325821
Lesenswert?

Markus F. schrieb:

Natural ... aber der Datentyp hat nun mal keineswegs "keine Beschränkung in der Anzahl der Bits". Im Gegenteil - bei praktische allen Tools ist beim Wertebereich bei 2 ** 31 - 1 Schluss

Weil natural ein subtype von Integer ist: https://www.allaboutcircuits.com/technical-articles/integer-and-its-subtypes-in-vhdl/

In der letzte Fassung von VHDL, VHDL-2019, soll der integer auf 64 bit aufgepumpt wurden sein: https://vhdlwhiz.com/vhdl-2019/#long-integers

Ich kenne kein Tool, was diesen neumodischen Geschiss unterstützt.

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