Monoflop mit Spartan 3 und VHDL

Gast #690961
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
Gast #691008
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 ^^
Gast #691119
Lesenswert?

So, das wäre mein Vorschlag für dein Problem. Das ganze ist ein nicht 
nachtriggerbares Monoflop.
1
port(
2
  clk     : in std_logic;
3
  trigger : in std_logic;
4
  d_out   : out std_logic
5
);
6

7

8
process(clk,trigger)
9
  variable aktiv : std_logic := '0';
10
  variable counter : integer range 0 to ??? ; --such dir eine größe aus, je nach takt
11
begin
12
  if rising_edge(clk) then
13
    if trigger = '1' and aktiv = '0' then
14
      aktiv = '1';
15
      counter := ???;
16
    elsif aktiv = '1' then
17
      d_out <= '1';
18
      counter := counter - 1;
19
      if counter = 0 then
20
        aktiv := '0';
21
      end if;
22
    else
23
      d_out <= '0';
24
    end if;
25
  end if;
26
end;
Gast #691181
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
Gast #691241
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;
Gast #1424133
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
Moderator (Firma: Titel) Persönliche Seite #1424170
Lesenswert?

David schrieb:
> Hi, I am interested to know how trig1_q is updated in the code:
1
   if rising_edge(clk) then
2
      trig0_q <= trigger;
3
      trig1_q <= trig0_q;
4
      :
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:
1
            ______  trig0_q  _____  trig1_q
2
trigger ---| D   Q|---------|D   Q|-------
3
           |      |         |     |   
4
      clk--|>_____|    clk--|>____|


You can write the above code also this way with absolutely no change in 
functionality:
1
   if rising_edge(clk) then
2
      trig1_q <= trig0_q;
3
      trig0_q <= trigger;
4
      :
Moderator (Firma: Titel) Persönliche Seite #1424380
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren