mikrocontroller.net

Forum: FPGA, VHDL & Co. Auf-Ab Zähler VHDL


Autor: Mirko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich habe ein kleines Problem mit meinem Programm. Ich soll einen 
Zähler entwerfen, der zwischen zwei 4-Bit Zahlen (Input) hoch und runter 
zählt. Die Zahlen werden anschließend in einer 7 Segment Anzeige 
ausgegeben, was auch ganz gut funktioniert. Ich habe nun das Problem, 
dass mein Zähler bis zum Minimum runter zählt und anschließend immer +1 
und dann wieder Minimum. Also zB. ist das Minimum 3 und der Zähler 
startet bei 6, dann bekomme ich diese Zahlenfolge: 6,5,4,3,4,3,4,... 
Kann mir jemand sagen warum dies so ist, bzw was ich ändern kann?
entity count4bit is
  port (
    MLEFT: in std_logic_vector(1 downto 0);    --Geschwindigkeit ClockLeft
    MRIGHT: in std_logic_vector(1 downto 0);  --Geschwindigkeit ClockRight
    A, B : in std_logic_vector (3 downto 0);
    y1: out std_logic_vector (1 to 8);
    D9, D11: out std_logic;
    C: out std_logic
  );
    
end entity count4bit;

architecture behavior of count4bit is
    signal ClkLeft, ClkRight, Clk100Hz, ClkOsc : std_logic;
    signal ModeLeft, ModeRight: std_logic_vector (1 downto 0);
    signal count4: std_logic_vector(3 downto 0) := "0000";
      signal dir1 : boolean;
  begin
      Clock: entity work.ClkGen(behavior)
      port map(
      ClkModeLeft => ModeLeft, 
      ClkModeRight => ModeRight, 
      PulseLeft => '0', 
      PulseRight => '0',
      ClkLeft => ClkLeft, 
      ClkRight => ClkRight,
      Clk100Hz => Clk100Hz,
      ClkOsc => ClkOsc);  
      

      minmax: entity work.minmax(behavior)
      port map(
      A => A,
      B => B,
      dir => dir1,
      count => count4);
      
      seg7: entity work.dec7s(behavior)
      port map(
      y => y1,
      count7 => count4 );
      
      C <= '1';    --Segmentauswahl

  ----------------------------------------
    
  main: process(clkleft,dir1) is
  begin
  
    if (rising_edge(clkleft)) then      --addieren bzw subtrahieren
      if (dir1 = false) then
        count4 <= std_logic_vector (unsigned (count4) + 1);
        D9  <= '0';      --Anzeige aufwaerts/ abwaerts zaehlen
        D11 <= '1';
      else
        count4 <= std_logic_vector (unsigned (count4) - 1);
        D9  <= '1';
        D11 <= '0';
      end if;
    end if;
    
  end process main;

  -----------------------------------------

  ClockMode: process (MLEFT, MRIGHT) is
  begin
    ModeLeft  <= MLEFT;
    ModeRight <= MRIGHT;
  end process ClockMode;
end architecture behavior;

-----------------------------------------
-----------------------------------------

entity minmax is
  port (
    count : in std_logic_vector (3 downto 0);
    dir : out boolean;
    A, B : in std_logic_vector (3 downto 0)
    );
  
  end entity minmax; 
 
 
architecture behavior of minmax is 

signal help : boolean;

begin
  
  dir4: process (count,A,B) is
    
  begin
    
    if count = A then
      help <= false;
    elsif count = B then
      help <= true;
    end if;
    
    dir <= help;
    
  end process dir4;

end architecture behavior;

: Bearbeitet durch Moderator
Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorneweg:
Antwort schreiben
Wichtige Regeln - erst lesen, dann posten!
    :
    :
    Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)
    :
    :
    [vhdl]VHDL-Code[/vhdl]

Mirko schrieb:
> Also zB. ist das Minimum 3 und der Zähler startet bei 6, dann bekomme
> ich diese Zahlenfolge: 6,5,4,3,4,3,4,...
Wie stellst du das fest? Mit einer Simulation?

Mirko schrieb:
     if count = A then
       help <= false;
     elsif count = B then
       help <= true;
     end if;
Das ist ein Latch, das von Kombinatorik angesteuert wird. Das geht 
unbedingt schief! Stichwort zur weiteren Recherche: "Glitch"

Du bist da heute schon der Zweite, der sowas asynchrones probiert: 
Beitrag "Re: Stoppuhr Normal/Addition/Split, Funktion abhängig von "Taktrate""

Der Merksatz dazu ist: Latches verwenden nur die, die es können und die, 
die es nicht können. Erstere bewusst und Zweitere aus Zufall...  ;-)

Mach da einen Takt mit rein und aus dem "help" ein Flipflop statt eines 
Latches.

: Bearbeitet durch Moderator
Autor: Mirko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, vielen erstmal Dank fürs bearbeiten, das mit dem Dateianhang merk 
ich mir fürs nächste mal.

Lothar M. schrieb:
> Wie stellst du das fest? Mit einer Simulation?

Ich kann die Zahlenfolge an meinem Demoboard ablesen,bekomme den Code so 
wie er ist auch aufgespielt.

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

Bewertung
0 lesenswert
nicht lesenswert
Diesen Prozess hier kannst du genauso gut oder besser duch die 
entsprechenden Concurrent-Anweisungen ersetzen:
--  ClockMode: process (MLEFT, MRIGHT) is
--  begin
    ModeLeft  <= MLEFT;
    ModeRight <= MRIGHT;
--  end process ClockMode;

Zum Code selber:
Insgesamt sind die Signalnamen extrem ungünstig und völlig nichtssagend: 
was ist denn "A" und "B"? Und was ist "dir"? Sollten die drei nicht 
besser /durchgängig/(!!) z.B. minimum, maximum und dirUP heißen? Oder du 
definierst einen neuen Typ für "dir", sodass du z.B. so abfragen kannst:
if dir = UP then ...

Und auch die Kommentare sind nutzlos: nicht mal am Kommentar kann man 
ablesen, ob jetzt hoch oder runter gezähl werden soll. Man muss den 
entsprechenden Code lesen und verstehen, um zu erahnen, was da gewollt 
ist.

Du solltest die komplette Takterzeugung aus dem Zählermodul heraushalten 
und dort nur den 1 gültigen Takt einspeisen.

Und zum Takt: wird wer immer noch auf diese krude Art&Weise händisch mit 
Zählern und toggelnden Flipflops erzeugt? Auf eine Art also, von der ich 
schon im Beitrag "Lauflicht mit vorgegbenen Clkgen" schrieb, dass man 
das so nicht macht, weil es nicht zuverlässig funktioniert?
Zur Takterzeugung in FPGAs nimmt man deren Taktmanager und arbeitet mit 
Clock-Enables.

Generell: wenn man das verbastelte Design mal soweit verbiegt, dass man 
den eigentlichen Zähler und seine Umschaltung (was man ja eigentlich 
überprüfen will) simuliert, dann sieht man (im Screenshot die untern 5 
Signale), dass der "im Prinzip" schon funktioniert, nur nicht ganz 
rechtzeitig umschaltet (abwärts wird auf 2 gezählt trotz Untergrenze 3, 
und aufwärts bis 7 trotz Obergrenze 6). Der dort beobachtete Effekt 
nennt sich "Latency".

: Bearbeitet durch Moderator

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.

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