mikrocontroller.net

Forum: FPGA, VHDL & Co. VHDL: Zähler nach 3 Werten unterscheiden


Autor: uluxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe einen Zähler, dessen Wert ich auslesen will.
Jer nach Ergebniss gibt es 3 verschiedene Möglichkeiten:

0<Zähler<=Wert1 -> Tue iwas
Wert1 < Zähler <=Wert2 -> Tue iwas
Wert2 < Zähler -> Tue iwas

Ich habe es bisher so gemacht:

if(Zähler<15)then
   Aktion1
elsif(Zähler < 500)then
   Aktion2
else
   Aktion3
end if;

Das Problem ist aber dass er bei Werten kleiner 500 prinzipiell Aktion2 
macht, Aktion1 wird nie ausgeführt, auch wenn der Wert kleiner als 15 
ist.

Aktion3 wird bei Werten über 500 ausgeführt, das funktionert.

Was mache ich falsch?

Danke schonmal, uLuxx

Autor: Nephilim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
poste am besten deinen quellcode

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Bei mir gehts:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity CompareRange is
    Port ( value : in  STD_LOGIC_VECTOR (9 downto 0);
           lo  : out std_logic;
           mid : out std_logic;
           hi  : out std_logic);
end CompareRange;

architecture Behavioral of CompareRange is
signal wert : integer range 0 to 1023;
begin
  wert <= to_integer(unsigned(value));
  process (wert) begin
     lo  <= '0';
     mid <= '0';
     hi  <= '0';
     if (wert<15) then
       lo  <= '1';
     elsif (wert<500) then
       mid <= '1';
     else
       hi  <= '1';
     end if;
  end process;
end Behavioral;
Was machst du anders?


EDIT
Oder so:
  process (wert) begin
     lo  <= '0';
     mid <= '0';
     hi  <= '0';
     if (wert<500) then
       if (wert<15) then  lo  <= '1';
       else               mid <= '1';
       end if;
     else
       hi <= '1';
     end if;
  end process;

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die einfachste Methode wird sein, wenn du die Abfragen von hinten 
angehst, also die if-Anweisungen von großen zu kleinen Werten abfragen 
läßt, z.B. so:

if(Zähler>500)then
   Aktion3
elsif(Zähler > 15)then
   Aktion2
else
   Aktion1
end if;

Da der Code innerhalb des Prozesses für die if-Anweisung sequentiell 
abläuft, sollte die Umkehrung dann genau das tun, was du dir vorstellst.

Gruß Thomas

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, das darf keinen Unterschied machen! Ich würde dennoch mal 
probieren, ob man nicht die Bedingung auf " >15 and < 500" erweitern 
sollte.

Dann besser auch :

lo  <= '1';
mid <= '0';
hi  <= '0';


lo  <= '0';
mid <= '1';
hi  <= '0';

Da dies nicht explicit dargestellt ist, steckt die erste Bedingung von 
in der zweiten drin und muss bez lo nicht unterschieden / realisiert 
werden.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wuerde auch drauf tippen, dass die Bedingung nicht exakt genug ist.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ uLuxx
Ist der Zähler ein Signal oder eine Variable?
Zeig doch mal den ganzen Code...

> Das Problem ist dass er bei Werten kleiner 500 prinzipiell Aktion2 macht,
> Aktion1 wird nie ausgeführt, auch wenn der Wert kleiner als 15 ist.
In der Simulation oder in der Realität?

Autor: uluxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also erst mal danke für die Hilfe!

Der Code macht das in der Realität, Testbench ist was was ich bisher 
nicht hinbekomme :-)

>Oder so:
>
>  process (wert) begin
>     lo  <= '0';
>     mid <= '0';
>     hi  <= '0';
>     if (wert<500) then
>       if (wert<15) then  lo  <= '1';
>       else               mid <= '1';
>       end if;
>     else
>       hi <= '1';
>     end if;
>  end process;

Ja das habe ich auch schon versucht gleiches Ergebnis...

Der Zähler ist ein Signal.

Hier mein Code:
elsif rising_edge(CLK)then
    
if(Counter < 500)then

if(0 < Counter < 150)then
Data <= Data(58 downto 0) & '0';
Sek <= not(Sek);
Long <= '1';
Short <= '0';
NewM <= '1';
else
Data <= Data(58 downto 0) & '1';
Sek <= not(Sek);
Long <= '0';
Short <= '1';
NewM <= '1';
end if;
else
Data <= "111111111111111111111111111111111111111111111111111111111111";
Sek <= '0';
        
Long <= '1';
Short <= '1';
NewM <= '0';
        
end if;
      
end if;  
  

  
end process;


Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> if(0 < Counter < 150)then
Der ist aber neu hier...

Das das gehen soll hätte ich nicht erwartet...

Ich hätte das eher so geschrieben:
  if(0 < Counter and Counter < 150)then

BTW:
Data <= "111111111111111111111111111111111111111111111111111111111111";
Das geht kürzer so:
Data <= (others=>'1');

Autor: uluxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> if(0 < Counter < 150)then
Der ist aber neu hier...


sorry, sollte heißen if(Counter < 150)

war aus einem test

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.