Forum: FPGA, VHDL & Co. FSM springt nicht in nächsten Status


von Richard B. (rbrose)


Lesenswert?

Hallo,

ich habe folgendes Problem:

Ich habe eine FSM die nicht in den nächsten Status springt:
1
state_switcher : process (CLK)
2
begin
3
  if rising_edge(CLK) then
4
    if Reset = '1' then
5
      State <= Power_Up;
6
    else
7
      State <= Next_State;
8
    end if;
9
  end if;
10
end process state_switcher;
11
12
stateMachine : process (State)
13
begin
14
15
  case (State) is
16
    when Power_Up =>
17
      Next_State <= Power_Up_Delay;
18
      
19
    when Power_Up_Delay =>
20
      if (Delay_45ms = "1000100101010100010000") then
21
        Next_State <= Off_Power_Up_Delay;
22
      else
23
        Next_State <= Power_Up_Delay;
24
      end if;
25
      
26
    when Off_Power_Up_Delay =>
27
      Next_State <= Write_Data;

Er bleibt immer im Power_Up_Delay Status.

Das ist hier der Delay Process:
1
---------------------------------------------------------------------------------------------
2
-- Power Up Delay.
3
---------------------------------------------------------------------------------------------
4
-- Power Up Delay Switch.
5
process (State)
6
begin
7
   if ((State = Power_Up) or (State = Power_Up_Delay)) then
8
    Delay_45ms_E <= '1';
9
   else
10
    Delay_45ms_E <= '0';
11
   end if;
12
end process;
13
14
-- 45ms Delay Element.
15
process (Clk)
16
begin  
17
   if (Clk'event and Clk = '1') then
18
      if Reset = '1' then
19
      Delay_45ms <= "0000000000000000000000";
20
      else
21
      if (Delay_45ms_E = '1') then
22
        Delay_45ms <= Delay_45ms + 1;
23
      end if;
24
      end if;
25
   end if;
26
end process;


Was ist das Problem? Anbei ein Auszug auf dem ModelSim.

Danke.

von Xenu (Gast)


Lesenswert?

Du hast vergessen das Signal "Delay_45ms" mit in die Sensitivitätsliste 
des Prozesses aufzunehmen.

Ach ja, "state" heisst "Zustand" und nicht "Status" (state machine = 
Zustandsautomat).

von lkmiller (Gast)


Lesenswert?

>Ich habe eine FSM die nicht in den nächsten Status springt
Die SM wird in der Realität schon weiterspringen.

Du müsstest eigentlich schreiben:
Ich habe eine FSM die in der Simulation nicht in den nächsten Status 
springt

von Eman (Gast)


Lesenswert?

Ich hab das jetzt hier schon dreimal gesehen, dass die State-Machine in 
einen taktgesteuerten und taktlosen Teil getrennt ist.
Hat das irgendwelche Vorteile gegenüber der "normalen" Lösung mit halt 
einer taktgesteuerten Machine?

von lkmiller (Gast)


Lesenswert?

Ja:
Weil das ziemlich schnell keiner mehr kapiert
kann man sein geistiges Eigentum besser vor Diebstahl schützen.

Es ist wohl eher so, wie man das gelernt hat.
Ich habe alle Schreibweisen ausprobiert (3, 2, 1-Prozess) und bin bei 
der 1-Prozess-SM geblieeben, weil man keine Signale in der SensList 
vergessen kann.

Kombinatorik schreibe ich dann gerne concurrent, also statt
1
-- Power Up Delay Switch.
2
process (State)
3
begin
4
   if ((State = Power_Up) or (State = Power_Up_Delay)) then
5
    Delay_45ms_E <= '1';
6
   else
7
    Delay_45ms_E <= '0';
8
   end if;
9
end process;

kürzer:
1
-- Power Up Delay Switch.
2
Delay_45ms_E <= '1' when ((State=Power_Up) or (State=Power_Up_Delay)) else '0';

von lkmiller (Gast)


Lesenswert?

Das wäre in etwa die Kurzschreibweise in 1 Prozess:
1
:
2
signal Delay_45ms : integer;
3
:
4
:
5
state_switcher : process (CLK)
6
begin
7
  if rising_edge(CLK) then
8
    if Reset = '1' then -- das ist ja wohl auch der Power-Up-Zustand?
9
      State <= Power_Up_Delay;
10
      Delay_45ms <= 0;
11
    else
12
      case (State) is
13
      when Power_Up_Delay =>
14
        Delay_45ms <= Delay_45ms + 1;
15
        if (Delay_45ms = 2250000) then -- offenbar ein 50MHz-Takt?
16
          State <= Off_Power_Up_Delay;
17
        end if;
18
19
      when Off_Power_Up_Delay =>
20
        State <= Write_Data;
21
:
22
:

Wäre doch viel zu einfach zu kopieren/kapieren?

von Morin (Gast)


Lesenswert?

> Ich hab das jetzt hier schon dreimal gesehen, dass die State-Machine in
> einen taktgesteuerten und taktlosen Teil getrennt ist.
> Hat das irgendwelche Vorteile gegenüber der "normalen" Lösung mit halt
> einer taktgesteuerten Machine?

Wird oft noch so gelehrt, von Lehrern/Profs/was auch immer, die noch aus 
einer Zeit kommen, in der man eine FSM von Hand implementieren musste 
(und das geht mit der Trennung sehr viel einfacher).

von lkmiller (Gast)


Lesenswert?

Wenn jemand von der Viel-Prozess-Schreibweise zur Ein-Prozess-Methode 
wechselt kann der sich da schnell mal 1 Takt Latency einhandeln (weil ja 
der Zustand der Signale erst mit dem nächsten Takt geändert wird).
Aber das ist nur ein kurzer Lernprozess, danach wird alles viel 
einfacher.

Es gibt z.B. keine mehrfachen Zuweisungen an Signale, alle 
Abhängigkeiten stehen im selben Prozess, und der ist zur größten Freude 
auch noch getaktet.....

von Richard B. (rbrose)


Lesenswert?

Ahh stimmt hab die Sensitivitätsliste vergessen.

Ok. Nächste Frage: Wieso habe ich in ModelSim bei 45000000 ns = 45 ms 
nur 1125000 als Wert bei delay_45ms? Wie rechne ich da richtig?

Muss ich 45000000 * 20 = 900000000 nehmen weil mein CPU Clock mit 20ns 
Verzögerung kommt?
1
clock : PROCESS
2
   begin
3
   wait for 20 ns; CLK  <= not CLK;
4
end PROCESS clock;

Wie ist die Verzögerung im realen System? Bei einem Spartan 3E XC3S500E 
/ FG320 und Speed auf -4 ?

20 ns? Oder gilt der Wert nur für I/O Toggle?

von Roger S. (edge)


Lesenswert?

Richard B. wrote:
> Ok. Nächste Frage: Wieso habe ich in ModelSim bei 45000000 ns = 45 ms
> nur 1125000 als Wert bei delay_45ms? Wie rechne ich da richtig?
>
> Muss ich 45000000 * 20 = 900000000 nehmen weil mein CPU Clock mit 20ns
> Verzögerung kommt?

Ist das ein Scherz? Du teilst deine Wartezeit durch die Periodendauer 
deines CPU clocks. ModelSim gibt dir ja schon die korrekte Antwort.
Dein Clock hat im uebrigen keine 20ns Verzoegerung, sondern eine halbe 
Periodendauer von 20ns.

Cheers, Roger

von lkmiller (Gast)


Lesenswert?

Also (concurrent, ohne process)

CLK  <= not CLK after 10ns; -- gibt 50MHz-Takt: 10ns low, 10ns high

von Richard B. (rbrose)


Lesenswert?

Also stimmt das, dass der Spartan 3E 900000000 Takte machen muss um 45 
ms zu kriegen?

Ist das schon vorgeben das der Spartan 3E eine Periodendauer von 20ns 
hat? Oder muss man die Konfigurieren?

Danke!

von lkmiller (Gast)


Lesenswert?

>Also stimmt das, dass der Spartan 3E 900000000 Takte machen muss
>um 45ms zu kriegen?
Das wäre richtig bei einer Taktfrequenz von 20GHz.

Du schreibst doch selber ...if(Delay_45ms = 2250000)...
Das heisst, du wartest 2250000 Takte für 45ms, das sind dann 50MHz.

Datenblatt. Von Xilinx.

Da gibt es Takteingänge, der Spartan 3 kann ohne externen Takt gar nix.
(OK, OK, er kann Kombinatorik).

BTW:
Lattice MachXO können den eingebauten Oszillator, der zum Laden des 
FPGAs verwendet wird, auch für User-Zwecke verwenden.

von Richard B. (rbrose)


Lesenswert?

@lkmiller

Beim state_switcher : process (CLK) brauch ich dann nicht mehr die 
Sensitivitätsliste erweitern? Weil der process getaktet wird?

von lkmiller (Gast)


Lesenswert?

Richtig, nur CLK in die Liste.

Die sensitivity-list eines process ist nur für die Simulation 
interessant. Wenn sich der Zustand eines der Signale in der Liste 
ändert, wird die Simulation neu berechnet.
Die Synthese legt mit einer unvollständigen Liste ein paar Warnungen 
vor, macht aber sonst alles richtig (fügt die Signale selbständig ein).

Und in dem von mir beschriebenen getakteten Prozess kann sich nur was 
ändern, wenn sich CLK ändert. Und dann wird alles neu berechnet.
Bei der fallenden Flanke ist die Berechnung dann auch gleich fertig, da 
gibts nix zu tun. Bei der steigenden Flanke gehts dafür aber richtig zur 
Sache.

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.