mikrocontroller.net

Forum: FPGA, VHDL & Co. Monoflop mit Spartan 3 und VHDL


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich gerade am verzweifeln. Ich versuche seit Stunden, ein Monoflop in 
VHDL zu programmieren, aber habe leider bisher keinen Erfolg. Hat jemand 
von euch sowas schon mal gemacht und kann mir vielleicht einen Beispiel 
Code geben, damit ich wenigstens die grobe Richtung weiß wo ich hin 
muss. Vielen Dank jetzt shcon mal.

Gruß Markus

Autor: thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm Monoflop ... Ausgang für eine bestimmte Zeit auf High legen und dann 
kippt er von alleine wieder auf Low ...

Mein Tip: Prozess, der einen Counter hochzählt, je nach gewünschter 
Länge des High Pegels.
Wenn logisch 1 am Eingang anliegt wird der Ausgang auf 1 gesetzt und der 
Counter gestartet bis dieser den gewünschten Wert überschreitet. Ausgang 
wird wieder 0 gesetzt und Counter wird gestoppt.

Wenn Du es bis morgen nicht hinbekommst und keiner Dir ein Beispiel 
postet, dann mach ich mich mal dran ... geh jetzt aber erstmal ein wenig 
schlafen ^^

Autor: thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, das wäre mein Vorschlag für dein Problem. Das ganze ist ein nicht 
nachtriggerbares Monoflop.
port(
  clk     : in std_logic;
  trigger : in std_logic;
  d_out   : out std_logic
);


process(clk,trigger)
  variable aktiv : std_logic := '0';
  variable counter : integer range 0 to ??? ; --such dir eine größe aus, je nach takt
begin
  if rising_edge(clk) then
    if trigger = '1' and aktiv = '0' then
      aktiv = '1';
      counter := ???;
    elsif aktiv = '1' then
      d_out <= '1';
      counter := counter - 1;
      if counter = 0 then
        aktiv := '0';
      end if;
    else
      d_out <= '0';
    end if;
  end if;
end;

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank Thomas,

ich werde mich gleich mal ran machen und deinen Code ausprobieren.

Gruß Markus

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Thomas,

hab deinen Code gerade getestet, aber tut nicht das was ich erwartet 
hätte, ich wollte z.B. auf eine Taste drücken und danach geht für eine 
bestimmte Zeit eine LED an und danach wieder aus. Aber entweder sie ist 
immer an oder geht gar nicht an. Aber dein Code müßte funktionieren, bin 
eigentlich alles Schritt für Schritt durhgegangen, naja ich versuchs 
noch etwas. Werde dann nochmal meinen Code posten.

Gruß Markus

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Markus,

bitte nicht den Code unverändert übernehmen. Und das Verhalten ist so, 
dass bei gedrückter Taste (Trigger = 1) der Ausgang für 1 Takt auf 0 
geht und dann gleich wieder auf 1. D.h. es gibt keine Flankentriggerung.
Die Variablen sind hier auch ungünstig.
Ich würde folgendes vorschlagen:

constant MONO_DELAY : integer := 20; -- Bsp.

signal cnt_q : integer range 0 to MONO_DELAY;
signal trig0_q : std_logic;
signal trig1_q : std_logic;

process(clk)
begin
   if rising_edge(clk) then
      trig0_q <= trigger;
      trig1_q <= trig0_q;

      if cnt_q > 0 then
         dout <= '1';
         cnt_q <= cnt_q -1;
      else
         dout <= '0';

         if trig0_q ='1' and trig1_q='0' then -- rising_edge trigger
            cnt_q <= MONO_DELAY;
         end if;
      end if;
   end if;
end process;

Autor: thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guter Hinweis Mark, es lag wirklich nur an den Variablen bei mir. 
Signale drauß gemacht und schon ging es ohne Probleme.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könntest auch ein RC-Kombination simulieren.

Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, I am interested to know how trig1_q is updated in the code:

process(clk)
begin
   if rising_edge(clk) then
      trig0_q <= trigger;
      trig1_q <= trig0_q;

      if cnt_q > 0 then
         dout <= '1';
         cnt_q <= cnt_q -1;
      else
         dout <= '0';

         if trig0_q ='1' and trig1_q='0' then -- rising_edge trigger
            cnt_q <= MONO_DELAY;
         end if;
      end if;
   end if;
end process;

Thanks

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

Bewertung
0 lesenswert
nicht lesenswert
David schrieb:
> Hi, I am interested to know how trig1_q is updated in the code:
   if rising_edge(clk) then
      trig0_q <= trigger;
      trig1_q <= trig0_q;
      :
trig1_q gets the value of trig0_q at the rising edge of clk.
With the same rising edge trig0_q gets the value of trigger.

This whole thing is a 2 bit shift register:
            ______  trig0_q  _____  trig1_q
trigger ---| D   Q|---------|D   Q|-------
           |      |         |     |   
      clk--|>_____|    clk--|>____|   



You can write the above code also this way with absolutely no change in 
functionality:
   if rising_edge(clk) then
      trig1_q <= trig0_q;
      trig0_q <= trigger;
      :

Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi again,
I thought the code after the sensitivity list is sequential, therefore 
if trigger = 1 then trig0_q = 1 and triq1_q = 1.

So (if trig0_q ='1' and trig1_q='0' then) will never be true.

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

Bewertung
0 lesenswert
nicht lesenswert
> therefore if trigger = 1 then trig0_q = 1 and triq1_q = 1.
This assumption is wrong.

The process is calculated each time clk changes its state. And only if 
the change is a rising edge, the value of the signals will be evaluated. 
After finishing this process the last assigned value will be transferred 
to the signal. Throughout the evaluation the value of signal itself 
doesn't change.

So if trig0_q = 1 and triq1_q = 1 and trigger is 0, after processing the 
signals will be trig0_q = 0 and triq1_q = 1. With the next rising edge 
of clk this will change to trig0_q = 0 and triq1_q = 0.
So, the behaviour is like a shift register.

> therefore if trigger = 1 then trig0_q = 1 and triq1_q = 1.
Variables change their value immediately with the assignment.
Singals change their value after evaluating the whole process.

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.