www.mikrocontroller.net

Forum: FPGA, VHDL & Co. RESET einfügen bei FSM


Autor: Mikey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich soll eine FSM(Finite State Machine) programmieren, die 4 
aufeinanderfolgende "0en" oder "1en" erkennt, zum erzeugen der "0en" und 
"1en" wird sw(0) benutzt, zur Vorgabe des Taktes key(0) und mit key(1) 
soll das ganze geresetet werden! Wenn die Signalfolge erkannt wurde, 
wird ledg(0) auf "1" gesetzt!
Mein Problem: wie soll ich den RESET einfügen?
library ieee;
use ieee.std_logic_1164.all;

entity Test is
port( key : in std_logic_vector(3 downto 0);
    sw : in std_logic_vector (9 downto 0);
    ledg : out std_logic_vector (3 downto 0)); 
end Test;


architecture a of Test is
type zustand is (a, b, c, d, e, f, g, h, i); --Zustände
signal s, t: zustand; signal x: std_logic;-- s ist aktueller Zustand, t ist naechster Zustand

begin



process(sw(0), s, key(0)) begin -- Berechnung des neuen Zustands/Ausgangs
  case s is
    when a => if sw(0) = '0' then t <= b; x <= '0'; else t <= f;  end if;
    
    when b => if sw(0) = '0' then t <= c; x <= '0'; else t <= f;  end if;
    when c => if sw(0) = '0' then t <= d; x <= '0'; else t <= f;  end if;
    when d => if sw(0) = '0' then t <= e; x <= '0'; else t <= f;  end if;
    when e => if sw(0) = '0' then t <= e; x <= '1'; else t <= f;  end if;
    
    when f => if sw(0) = '1' then t <= b; x <= '0'; else t <= g;  end if;
    when g => if sw(0) = '1' then t <= b; x <= '0'; else t <= h;  end if;
    when h => if sw(0) = '1' then t <= b; x <= '0'; else t <= i;  end if;
    when i => if sw(0) = '1' then t <= b; x <= '1'; else t <= i;  end if;
  end case;
  
  

end process;


process(key) begin -- Übernahme des neuen Zustands/Ausgangs
if falling_edge(key(0)) then s <= t; ledg(0) <= x; end if;
--JETZT DER RESET:
if falling_edge(key(1)) then s <= a; end if; -- HIER BEKOMM ICH DEN FEHLER "couldn't implement registers for assignements on this clock edge"
end process;
end a;

Vielen Dank im Vorraus!

Autor: pedro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon einmal ein Flip-Flop mit 2 Clock / Enable gesehen? Ein Flip-Flop 
verträgt nur ein Clock. Warum löst du den Reset nicht asynchron? 
(Vielleicht mit Flip-Flop einsynchronisieren).


Nehme an, dass sich das Ding simulieren, jedoch nicht auf Hardware/FPGA 
übersetzt werden kann.

Autor: Mikey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@pedro:
Erstmal danke für die schnelle Antwort!
Wie meinst du das einsynchronisieren? Nochmal einen process schreiben?
Kann dir nicht ganz folgen!

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

Bewertung
0 lesenswert
nicht lesenswert
Mikey schrieb:
process(key) begin
   if falling_edge(key(0)) then s <= t; ledg(0) <= x; end if;
   --JETZT DER RESET:
   if falling_edge(key(1)) then s <= a; end if;
end process;
Wie soll denn s in der Hardware realisiert werden?
Ein Flipflop mit 2 Takteingängen? Das gibt es nicht.

Deshalb könntest du es bestenfalls so machen:
process(key) begin
   if key(1)='0' then
      s <= a;
   elsif falling_edge(key(0)) then
      s <= t; ledg(0) <= x; end if;
   end if;
end process;

Jetzt braucht das nötigte FF eine Takteingang und einen Reset-Eingang. 
Das gibt es, das kann umgesetzt werden.

> zur Vorgabe des Taktes key(0)
Dir ist schon klar, dass du mit einer Taste ohne Entprellung keinen Takt 
bekommst. Da hast du dann schnell bei einem tastendruck so 10-20 
Taktimplse benander...

Ich würde das so machen (noch mit dem key-Takt):
library ieee;
use ieee.std_logic_1164.all;

entity Test is
port( key  : in std_logic_vector(3 downto 0);
      sw   : in std_logic_vector (9 downto 0);
      ledg : out std_logic_vector (3 downto 0)); 
end Test;


architecture a of Test is
signal sr0 : std_logic_vector(3 dontwo 0) := "1111"; 
signal sr1 : std_logic_vector(3 dontwo 0) := "0000"; 
begin
  process (key) begin
    if key(1)='0' then 
      ledg(0) <= '0'; 
      sr0     <= "1111"; 
      sr1     <= "0000"; 
    elsif falling_edge(key(0)) then 
      sr0 <= sr0(2 downto 0) & sw(0);
      sr1 <= sr1(2 downto 0) & sw(0);
      if (sr0(2 downto 0) & sw(0) = "0000") or (sr1(2 downto 0) & sw(0) = "1111") then
        ledg(0) <= '1';
      end if;
    end if;
  end process;
end a;

Autor: Mikey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank Lothar, du hast mir sehr geholfen! Das Programm läuft jetzt! 
Ach ja, das mit dem Entprellen ist glaub ich hardwaremäßig gelöst (ist 
ein Altera DE1 Entwicklungsboard)!
Übrigens super Forum hier!

Autor: pedro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das mit dem Einsynchronisieren des Resets war folgendermassen gemeint: 
Wenn der Reset nicht etprellt ist, kann mit einigen Flip-Flops eine 
Tasterentprellung gebaut werden. Da das bei dir aber mit der Hardware 
bereits gelöst ist --> nicht nötig.

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.