Forum: FPGA, VHDL & Co. Suche Befehl eine einzelne Flanke


von Kurz (Gast)


Lesenswert?

Hallo

Ich brauche eine Pinabfrage die nur dann eine if-Schleife aktiviert wenn 
der Port gerade auf 1 springt (Steigende Flanke oder Fallende das ist 
egal)

Dann soll die If-Schleife genau 1 Mal durchlanfen werden.

wenn  ich

process (PWM_Phase)
  begin
    if rising_edge(Plus_Taster)            then
      if PWM_Phase < PWM_Phase_MAX
      then
      PWM_Phase <= PWM_Phase + 7;
      end if;
    end if;

    if rising_edge(Minus_Taster  )
            then
      if PWM_Phase > 0
      then
      PWM_Phase <= PWM_Phase - 7;
      end if;
    end if;
  end process;


wenn ich das compeliere kommt die Fehlermeldung:

Error (10821): HDL error at testpwm.vhd(52): can't infer register for 
"PWM_Phase[0]" because its behavior does not match any supported 
register model

Von welchem Typ müssen die Variablen sein?

Oder was ist sonst der Fehler?


Vielleicht hat jemand ander Lösungsvorschläge wie ich eine Variable um 1 
erhöhen kann (Wenn ich einen Taster drücke und eventuell sogar halte).

Danke für die Hilfe

von Jan M. (mueschel)


Lesenswert?

Du verwendest zwei unterschiedliche Clocks am selben FF. Soetwas kann 
nicht funktionieren, da es ein solches Element in keinem FPGA gibt.
Benutze einen einzigen Takt und Logik fuer die restliche Funktion.

von Frank (Gast)


Lesenswert?

Die sensitivity list passt nicht zum Rest. Abgesehen davon ist das sehr 
schlechter Stil, weil du die Taster als Takt verwenden würdest. Falls 
die nicht entprellt sind, geht das katastrophal nach hinten los.

Besser: Taster evtl. entprellen und dann mit einer state machine (die 
mit dem Systemtakt arbeitet) auswerten.

von Kurz (Gast)


Lesenswert?

Ich weiß nicht wie ich das realisieren soll.

Mein Ziel ist es die Variable NUR um einen bestimmten Wert zu erhöhen. 
Wenn ich das Ganze mit dem CLOCK (66 MHz) laufen lasse kann ich ich den 
Taster gar nicht so schlell loslassen.

Hat jemand eine Idee?

von Kurz (Gast)


Lesenswert?

Wie meinst du das mit der state machine ?

von Kurz (Gast)


Lesenswert?

Ich denke es handelt sich um ein Standartproblem in VHDL eine Variable 
in Abhängigkeit vom Zustand (in dem Fall Taster) zu verändern.

Gibt es dafür Beispiele, die für VHDL - Einsteiger geeignet sind?

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

In Hardware ausgedrückt nimmt man dafür zwei D-Flipflops am Systemtakt , 
die als 2-Bit-Schieberegister hintereinandergeschaltet sind, man kann 
das auch eine state-machine nennen mit 4 möglichen Zuständen.
Eine steigende Flanke wird mit UND-Verknüpfung der beiden Register 
erkannt. Genau dann wenn das erste schon umgeschaltet hat und das zweite 
noch nicht ist der Ausgang des UND high.

von T.M. (Gast)


Lesenswert?

Das Problem löst man, indem man verzögerte Signale für die 
Taster-signale erzeugt, und diese dann in einem geclockten Prozess 
abfragt. Zum Beispiel so (ohne Gewähr):
1
architecture rtl of ... is
2
3
signal plus_taster_delay : std_logic;
4
signal minus_taster_delay : std_logic;
5
6
begin
7
8
process (clk, reset)
9
  begin
10
    if(reset = '0') then
11
      plus_taster_delay  <= '0';
12
      minus_taster_delay <= '0';
13
    elsif(rising_edge(clk)) then
14
      plus_tasterr_delay <= plus_taster;
15
      minus_taster_delay <= minus_taster;
16
      if(plus_taster = '1' and plus_taster_delay = '0') then
17
        if PWM_Phase < PWM_Phase_MAX
18
        then
19
        PWM_Phase <= PWM_Phase + 7;
20
        end if;
21
      end if;
22
      if(minus_taster = '1' and minus_taster_delay = '0') then
23
        if PWM_Phase > 0 then
24
          PWM_Phase <= PWM_Phase - 7;
25
        end if;
26
      end if;
27
    end if;
28
end process;
29
30
end architecture rtl;

von Kurz (Gast)


Lesenswert?

ZUM BEITRAG VON     T.M. Gast:

ist in deinem Beispiel plus_taster_delay nicht immer '1' wenn 
plus_taster = '1'

das würde bedeuten (da Prozesse ja sequentiell ablaufen) dass die 
Abfrage:


IF (plus_taster ='1' and plus_taster_delay ='0')

nie erfüllt wäre


Oder täusche ich mich?

von Andreas S. (andreas) (Admin) Benutzerseite


Angehängte Dateien:

Lesenswert?

Eine einfache Flankenerkennung reicht oft nicht, da die Signale von 
mechanischen Tastern prellen und keine sauberen Flanken liefern. Ich hab 
mal schnell ein Beispiel für 8 Taster zusammengehackt (gekürzt, 
Testbench im Anhang):
1
  -- Register
2
  signal state0, state1, state2: std_logic_vector(7 downto 0) := (others => '0');
3
  signal key_pressed_old: std_logic_vector(7 downto 0) := (others => '0');
4
  signal key_pressed: std_logic_vector(7 downto 0) := (others => '0');
5
6
  -- Taster mit langsamem Takt einlesen (3-Bit-Schieberegister je Taste)
7
  -- ce: clock enable mit ca. 1 kHz
8
  process(clk)
9
  begin
10
    if rising_edge(clk) and ce = '1' then
11
      state0 <= key_in;
12
      state1 <= state0;
13
      state2 <= state1;
14
    end if;
15
  end process;
16
17
  -- Mehrheitsentscheidung:
18
  -- 2x '1' => Taste geht in den Zustand "gedrückt"
19
  -- 2x '0' => Taste geht in den Zustand "nicht gedrückt"
20
  -- Vorteil: einzelne Pulse haben keine Auswirkung
21
  process(clk)
22
    variable state: std_logic_vector(2 downto 0);
23
  begin
24
    if rising_edge(clk) then
25
      for i in state0'range loop
26
        state := state2(i) & state1(i) & state0(i);
27
        case state is
28
          when "000" => key_pressed(i) <= '0';
29
          when "001" => key_pressed(i) <= '0';
30
          when "010" => key_pressed(i) <= '0';
31
          when "100" => key_pressed(i) <= '0';
32
          when others => key_pressed(i) <= '1';
33
        end case;
34
      end loop;
35
36
      key_pressed_old <= key_pressed;
37
    end if;
38
  end process;
39
40
  -- Ausgangssignale erzeugen:
41
  -- key_pressed_out: aktueller Zustand der Taste
42
  -- key_down_out: geht für 1 Takt auf '1' wenn Taste gedrückt
43
  -- key_up_out: geht für 1 Takt auf '1' wenn Taste losgelassen
44
  process(key_pressed, key_pressed_old)
45
  begin
46
    key_down_out <= key_pressed and (not key_pressed_old);
47
    key_up_out <= (not key_pressed) and key_pressed_old;
48
    key_pressed_out <= key_pressed;
49
  end process;

von T.M. (Gast)


Lesenswert?

Davon bin ich mal ausgegangen, dass die Dinger entprellt und 
synchronisiert wurden. Sonst stimme ich Andreas zu.

von Volker (Gast)


Lesenswert?

Auszug aus dem VHDL-Code von Andreas

  process(clk)
  begin
    if rising_edge(clk) and ce = '1' then


Dies ist meiner Meinung nach ein "gated Clock" welches man verhindern
sollte.
Besser wäre:

if rising_edge(clk) then
  if ce = '1' then
   ... Code hier
  end if;
end if;

So gibts nämlich in der Synthese ein getaktetes FF (synchrones Design).

Gruß Volker

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Mit rising_edge(clk and ce) wäre das ein Gated clock, so ist das nur 
eine kürzere Schreibweise für die zwei verschachtelten ifs. Mag 
allerdings sein dass ein paar veraltete Synthestools das nicht kapieren.

von Volker (Gast)


Lesenswert?

Ok, ich werde es morgen nochmals genau ansehen und einige ISE-Versionen 
dabei verwenden.

Und dann wäre zumindest dieser Thread (Beitrag 5 ff.) in Frage zu 
stellen.

Beitrag "Synthesefähiger Code"

Volker

von Volker (Gast)


Lesenswert?

OK, so wie es ausschaut hat Andreas Recht. Sorry

Volker

von Frank (Gast)


Lesenswert?

Also QuartusII hat zumindest bis vor kurzem (6.x) auch noch ein gated 
clock draus gemacht.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Na dann doch lieber die verschachtelte Version.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Nachtrag: noch besser (=robuster) wäre es eigentlich, nur umzuschalten 
wenn alle drei Register gleich sind, also:
1
      for i in state0'range loop
2
        state := state2(i) & state1(i) & state0(i);
3
        case state is
4
          when "000" => key_pressed(i) <= '0';
5
          when "111" => key_pressed(i) <= '1';
6
        end case;
7
      end loop;

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.