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
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.
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.
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?
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?
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.
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; |
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?
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; |
Davon bin ich mal ausgegangen, dass die Dinger entprellt und synchronisiert wurden. Sonst stimme ich Andreas zu.
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
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.
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
Also QuartusII hat zumindest bis vor kurzem (6.x) auch noch ein gated clock draus gemacht.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.