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


von Mikey (Gast)


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?
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity Test is
5
port( key : in std_logic_vector(3 downto 0);
6
    sw : in std_logic_vector (9 downto 0);
7
    ledg : out std_logic_vector (3 downto 0)); 
8
end Test;
9
10
11
architecture a of Test is
12
type zustand is (a, b, c, d, e, f, g, h, i); --Zustände
13
signal s, t: zustand; signal x: std_logic;-- s ist aktueller Zustand, t ist naechster Zustand
14
15
begin
16
17
18
19
process(sw(0), s, key(0)) begin -- Berechnung des neuen Zustands/Ausgangs
20
  case s is
21
    when a => if sw(0) = '0' then t <= b; x <= '0'; else t <= f;  end if;
22
    
23
    when b => if sw(0) = '0' then t <= c; x <= '0'; else t <= f;  end if;
24
    when c => if sw(0) = '0' then t <= d; x <= '0'; else t <= f;  end if;
25
    when d => if sw(0) = '0' then t <= e; x <= '0'; else t <= f;  end if;
26
    when e => if sw(0) = '0' then t <= e; x <= '1'; else t <= f;  end if;
27
    
28
    when f => if sw(0) = '1' then t <= b; x <= '0'; else t <= g;  end if;
29
    when g => if sw(0) = '1' then t <= b; x <= '0'; else t <= h;  end if;
30
    when h => if sw(0) = '1' then t <= b; x <= '0'; else t <= i;  end if;
31
    when i => if sw(0) = '1' then t <= b; x <= '1'; else t <= i;  end if;
32
  end case;
33
  
34
  
35
36
end process;
37
38
39
process(key) begin -- Übernahme des neuen Zustands/Ausgangs
40
if falling_edge(key(0)) then s <= t; ledg(0) <= x; end if;
41
--JETZT DER RESET:
42
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"
43
end process;
44
end a;

Vielen Dank im Vorraus!

von pedro (Gast)


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.

von Mikey (Gast)


Lesenswert?

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

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


Lesenswert?

Mikey schrieb:
1
process(key) begin
2
   if falling_edge(key(0)) then s <= t; ledg(0) <= x; end if;
3
   --JETZT DER RESET:
4
   if falling_edge(key(1)) then s <= a; end if;
5
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):
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity Test is
5
port( key  : in std_logic_vector(3 downto 0);
6
      sw   : in std_logic_vector (9 downto 0);
7
      ledg : out std_logic_vector (3 downto 0)); 
8
end Test;
9
10
11
architecture a of Test is
12
signal sr0 : std_logic_vector(3 dontwo 0) := "1111"; 
13
signal sr1 : std_logic_vector(3 dontwo 0) := "0000"; 
14
begin
15
  process (key) begin
16
    if key(1)='0' then 
17
      ledg(0) <= '0'; 
18
      sr0     <= "1111"; 
19
      sr1     <= "0000"; 
20
    elsif falling_edge(key(0)) then 
21
      sr0 <= sr0(2 downto 0) & sw(0);
22
      sr1 <= sr1(2 downto 0) & sw(0);
23
      if (sr0(2 downto 0) & sw(0) = "0000") or (sr1(2 downto 0) & sw(0) = "1111") then
24
        ledg(0) <= '1';
25
      end if;
26
    end if;
27
  end process;
28
end a;

von Mikey (Gast)


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!

von pedro (Gast)


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.

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.