Forum: FPGA, VHDL & Co. 32 bit integer funkt nicht


von FPGA (Gast)


Lesenswert?

hallo ich möchte einen 32 bit counter implentieren,
funktionsweise: bei eintreffenden impuls wird ein integer wert erhöht, 
bei erreichen von ("11111111111111111111111111111111") 4294967295 wird 
der int wert wieder auf null gesetzt und fängt von 0 zum zählen an.
das umwandeln von int in std_logic_vector mit 
"counterstate <= CONV_STD_LOGIC_VECTOR (value, 32);" funktioniert 
tadellos nur mit dem wertebereich von int komm ich nicht zurecht.

als was könnte ich das "signal value : integer range 0 to 4294967295; "
sonst noch deklarieren/definieren damit dieser wertebereich abgedeckt 
wird ?

Danke !

von Duke Scarring (Gast)


Lesenswert?

1
-- This is Package STANDARD as defined in the VHDL 1992 Language Reference Manual.
2
--
3
--   NOTE: VCOM and VSIM will not work properly if these declarations
4
--         are modified.
5
6
-- Version information: @(#)standard.vhd
7
8
package standard is
9
...
10
type integer is range -2147483648 to 2147483647;

Da wirst Du wohl einen unsigned Vektor verwenden müssen:
1
library ieee;
2
use ieee.numeric_std.all;
3
...
4
signal counter: unsigned(31 downto 0);

Duke

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


Lesenswert?

FPGA schrieb:
> als was könnte ich das "signal value : integer range 0 to 4294967295; "
> sonst noch deklarieren/definieren damit dieser wertebereich abgedeckt
> wird ?
Gar nicht / Ganz einfach: in VHDL ist ein integer üblicherweise (aber 
nicht zwingend) 32 Bit breit. Und das vorderste Bit ist das Vorzeichen. 
Du wirst also nie auf die 4 Billionen kommen. Der Wertebereich eines 
üblichen Integers reicht von -2Bio...+2Bio
http://www.cs.umbc.edu/portal/help/VHDL/types.html


Aber du hast doch den Datentyp unsigned, der solche Einschränkungen 
nicht kennt. Und du denkst doch sowieso in Vektoren
> ("11111111111111111111111111111111")
Sieh dir mal den Beitrag "VHDL: Integer mit großem Wertebereich" an.

von FPGA (Gast)


Lesenswert?

okay nur klappt das inkrementieren des vektors value nicht bzw. taucht 
er in modelsim als undefiniert auf ?

entity bitcounter is
    Port ( Puls : in  STD_LOGIC;
        counterstate : out  STD_LOGIC_VECTOR (31 downto 0));
end bitcounter;

architecture Behavioral of bitcounter is


signal intcount : std_logic_vector (31 downto 0);

--signal value : integer range 0 to 4294967295;
signal value: std_logic_vector (31 downto 0);
begin

    counting : process ( puls, intcount, value)
    begin

        if rising_edge(puls)and  Puls = '1' then
        value <= value + "00000000000000000000000000000001";
        end if;

        if (value = "11111111111111111111111111111111") then 
--4294967295
        value <= "00000000000000000000000000000000";
        end if;


    end process;
  counterstate <= value;
--    counterstate <= CONV_STD_LOGIC_VECTOR (value, 32);
end Behavioral;

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


Lesenswert?

FPGA schrieb:
> if (value = "11111111111111111111111111111111") then --4294967295
>      value <= "00000000000000000000000000000000";
> end if;
Das brauchst du bei einem Vektor nicht. Der läuft von X"FFFFFFFF" nach 
X"00000000" allein über. Da muß nichts zurückgesetzt werden.

  value <= value + "00000000000000000000000000000001";
Das macht das selbe:
  value <= value + '1';
BTW: Diese direkte Vektorrechnung geht nur mit den alten Synopsys-Libs. 
Die sollte man aber nicht verwenden, weil dort bei der Library-Angabe 
nebenher auch ausgewählt wird, ob der Vektor signed oder unsigned ist.
Nimm statt dessen die numeric_std

BTW: Zur Abkürzung der Schreibweise ginge auch
X"FFFF" = "1111111111111111"

Insgesamt ist das eine böse Verquickung von kombinatorischem und 
synchronem Design, verbunden mit einer unüblichen Schreibweise eines 
Clock-Enables:
1
    counting : process ( puls, intcount, value)
2
    begin
3
        -- hier synchron mit unüblichem Clock-Enable (Puls)
4
        if rising_edge(puls)and  Puls = '1' then
5
           value <= value + "00000000000000000000000000000001";
6
        end if;
7
        
8
        -- ab hier kombinatorisch
9
        if (value = "11111111111111111111111111111111") then --4294967295
10
           value <= "00000000000000000000000000000000";
11
        end if;
12
    end process;
Zudem ist intcount in der Sensitivliste unnnötig... :-/

Ich sehe gerade:
        if rising_edge(puls)and  Puls = '1' then
hier ist Puls='1' komplett unnötig, diese Abfrage wird von rising_edge() 
mit erledigt  :-o

Mach es so, und alles wird gut:
1
    counting : process ( puls)
2
    begin
3
        if rising_edge(puls) then
4
           value <= value + '1'; -- Überlauf geht automatisch
5
        end if;
6
    end process;

Aber ich habe angesichts des Taktnamens (Puls) noch einen schlimmen 
Verdacht: wieviele Takte hast du im ganzen Design?

von FPGA (Gast)


Lesenswert?

DAnke für die wertvolen hinweise(vektor überlauf) aber bei deinem 
counting process funkts in modelsim noch immer nicht value wird als 
undef. dargestellt
puls ist eben der eingang an dem die pulse gezählt werden soll
und dann noch ein SCL (soll ein counter als I2c Slave werden)

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


Lesenswert?

Dann probier mal die Angabe eines Initialwertes bei der Definition:
1
signal value: std_logic_vector (31 downto 0) := (others=>'0');
Das sollte man bei jedem Signal machen, denn ohne Initialwert hat der 
Vektor den Wert "UUUUUU...UUU". Und dazu eines draufaddiert gibt 
natürlich wieder "UUUUUU...UUU".

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.