FSM funktioniert nicht wie ich will

Gast #7041004
Lesenswert?

Hallo guten Tag,

ich versuche eine Mealy Maschine zum Laufen zu bringen, die Muster eines 
Datensstroms erkennen soll.

* Zuerst möchte ich "0x5a50dad0d1d2d3d4" (64 Bit) erkennen

* wenn ich das separat in einem process mache klappt das ohne weiteres
* Das ist auch relativ einfach, da bei rising edge dieses Signal 
auftauchen kann
```
testcheck : process  (Daten)
WHEN WAIT_FOR_ADR1 =>
                -- check first addres
                case FRAME_PART1v2  is
    when X"5a50dad0d1d2d3d4" => DETECTED_ADR1 <= '1';
    when others =>
end process testcheck;
```
* Mit meiner State Machine klappt das nicht

* Sie scheint zu spät zu prüfen oder so

* Erst wenn ich die "next state output "logic sensibel mache detektiert 
sie dieses Muster...

* Wird nicht bei clk-rising edge der "next_state" aktualisiert und 
deswegen gleichzeitig die FSM aufgerufen?

* Dort müsste doch erkannt werden, dass zu diesem Zeitpunkt dieser 
Vektor (0x5a50dad0d1d2d3d4) anliegt!

* Bei dem Mealy Beispiel von Xilinx stand noch ein x  neben dem 
current_state. Ich könnte das für den Input verwenden...
 Finde ich aber seltsam aber ok.
Wenn sich die state machine gerade in diesem Zustand befindet und dafür 
sensibel sein muss ...


```
--- hier übergebe ich meine Eingangsdaten:
FRAME_PART1v2 <= m_axis_tdata;

-- Das ist meine "reset logic"
-- sie wird bei jedem m_axis_clk  ausgeführt
-- current state wird dabei immer aktualisert

    SYNC_PROC2 : PROCESS (m_axis_clk)
    BEGIN
        IF rising_edge(m_axis_clk) THEN
            IF (axi_reset = '1') THEN
            -- reset..
                current_state <= IDLE;
            ELSE
                current_state <= next_state;
            END IF;
        END IF;
    END PROCESS;


-- next state & Output logic:
-- dadurch, dass current_state bei jedem risign edge aktualisiert wird,
-- wird zeitgleich(?) die next state output logic ausgeführt.
-- es soll eine bestimmte Adresse in dem signal "FRAME_PART1v2" 
detektiert werden.
-- dann soll DETECTED_ADR1 auf 1 gesetzt werden.
-- allerdings klappt das nicht
-- habe dann einfach m_axis_clk in die Sensibilitätsliste eingefügt.. 
und dann geht es
 -- könnte evtl. noch den datenstream selber in in die 
Sensibilitätsliste einfügen . Im xilinx beispiel war dort ein x... habe 
ich weggemacht :D

    NEXT_STATE_DECODE : PROCESS (current_state,m_axis_clk)
    BEGIN

        CASE (next_state) IS
        WHEN IDLE =>
        next_state<= WAIT_FOR_ADR1;
        -- do nothing


        WHEN WAIT_FOR_ADR1 =>
                -- check first addres
                case FRAME_PART1v2  is
    when X"5a50dad0d1d2d3d4" => DETECTED_ADR1 <= '1';
    when others =>
  end case;
```
Moderator (Firma: Titel) Persönliche Seite #7041293
Lesenswert?

Signalisierer schrieb:
> die FSM aufgerufen?
Du hast die falsche Denkweise und "programmierst" Hardware.

Denn in der Hardware wird nichts "aufgerufen", eine FSM wird nicht 
"aufgerufen". Jedes Flipflop, das deine VHDL-Beschreibung in einem FPGA 
oder einem ASIC erzeugt, ist immer da. Und bei der entsprechenden Flanke 
wird einfach der Pegel vom Eingang des Flipflops auf dessen Ausgang 
abgespeichert.

Signalisierer schrieb:
1
testcheck : process  (Daten)
2
   WHEN WAIT_FOR_ADR1 =>
3
                -- check first addres
4
                case FRAME_PART1v2  is
5
    when X"5a50dad0d1d2d3d4" => DETECTED_ADR1 <= '1';
6
    when others => 
7
end process testcheck;
Die Sensitivliste ist falsch. Siehe auch das:
1
    NEXT_STATE_DECODE : PROCESS (current_state,m_axis_clk)
2
    BEGIN
3
        CASE (next_state) IS
4
        WHEN IDLE => 
5
        next_state<= WAIT_FOR_ADR1;
6
        -- do nothing
7
        WHEN WAIT_FOR_ADR1 =>
8
                -- check first addres
9
                case FRAME_PART1v2  is
10
    when X"5a50dad0d1d2d3d4" => DETECTED_ADR1 <= '1';
11
    when others => 
12
  end case;
In dieser Sensitivliste sind unnötigerweise "current_state" und 
"m_axis_clk" drin. Dafür fehlen aber "next_state" und "FRAME_PART1v2".

Deshalb wird deine Simulation nicht zur erzeugten Hardware passen.
Das sagt dir der Synthesizer aber auch...

Über die Sensitivliste kannst du lediglich das Verhalten der Simulation 
steuern. Der Synthesizer kümmert sich nicht um die Sensitivliste. Er 
wird deshalb die Signale "next_state" und "FRAME_PART1v2" schlicht 
ignorieren.

Signalisierer schrieb:
> Erst wenn ich die "next state output "logic sensibel mache detektiert
> sie dieses Muster...
Wer detektiert da was zu spät? Wie stellst du das fest? Im Simulator? Im 
echten Leben? Kann man da mal irgendwelche 
Grafiken/Screenshots/Messungen sehen?
Gast #7042221
Lesenswert?

Vielen Dank für das Feedback!

Habe nicht beachtet wie eine Sensitivitätsliste synthetisiert wird.

Sehe gerade einen Beitrag:

>Christian R. (supachris)
>30.05.2013 22:18

>Die Sensitivitätsliste ist ausschließlich für den Simulator relevant
>und gibt an, welche Signale auf Änderungen überwacht werden sollen.
>Jedes mal wenn sich ein Signal aus der Liste ändert, wird das Ergebnis
>des Prozesses vom Simulator neu berechnet. Trotzdem sollte man die Liste
>immer ordentlich beschreiben, da sonst Simulation und Realität nicht
>übereinstimmen. In deinem Fall müsste dann x in die Liste, denn bei
>einer Änderung von x soll sofort der Ausgang neu berechnet werden. Der
>Synthese ist die Liste egal, die spuckt in der Regel nur eine Warnung
>aus, wenn sie nicht vollständig ist.



* Habe mich außerdem an diesem Beispiel orientiert.
* Muss eigentlich nicht synthetisierbar sein
* Möchte es aber trotzdem als Übung machen
* Möchte außerdem eine passende State-Machine wählen um AXI-Stream zu 
checken
 - In der Simulation passt das schon einigermaßen


https://www.xilinx.com/support/documents/university/Vivado-Teaching/HDL-Design/2015x/VHDL/docs-pdf/lab10.pdf
1
TYPE state_type IS (S0, S1);
2
SIGNAL state, next_state : state_type;
3
BEGIN
4
  SYNC_PROC : PROCESS (clk)
5
  BEGIN
6
    IF rising_edge(clk) THEN
7
      IF (reset = '1') THEN
8
        state <= S0;
9
      ELSE
10
        state <= next_state;
11
      END IF;
12
    END IF;
13
  END PROCESS;
14

15
  NEXT_STATE_DECODE : PROCESS (state, x)
16
  BEGIN
17
    parity <= '0';
18
    CASE (state) IS
19
      WHEN S0 => 
20
        IF (x = '1') THEN
21
          parity <= '1';
22
          next_state <= S1;
23
        ELSE
24
          next_state <= S0;
25
        END IF;
26
      WHEN S1 => 
27
        IF (x = '1') THEN
28
          next_state <= S0;
29
        ELSE
30
          parity <= '1';
31
          next_state <= S1;
32
        END IF;
33
      WHEN OTHERS => 
34
        next_state <= S0;
35
    END CASE;
36
END PROCESS;
Gast #7042226
Lesenswert?

Also ok die Simulation benötigt die Angabe der Sensitivitätsliste dafür, 
dass sie sich so wie das Enddesign verhält.
Sonst würde die Simulation bei bestimmten Signaländerungen nicht 
reagieren, während das echte Design dann aber reagieren würde.


Ah hier sehe das auch noch mal...


Entwurf von digitalen Schaltungen und Systemen mit HDLs und FPGAs ...
von Frank Kesel, Ruben Bartholomä s.344

[link]https://books.google.de/books?id=D0_pBQAAQBAJ&pg=PA344&lpg=PA344&dq=sensitivit%C3%A4tsliste+ignoriert&source=bl&ots=17g0iiDcvm&sig=ACfU3U1VRRD-Uuxk-XXuXxPVM-ERN24A-Q&hl=de&sa=X&ved=2ahUKEwiwm7e39qb3AhXYuKQKHazECpUQ6AF6BAgdEAM#v=onepage&q=sensitivit%C3%A4tsliste%20ignoriert&f=false 
[/link]
Gast #7042273
Lesenswert?

* weiß grade nicht wieso ich anstatt.


1
  CASE (state) IS


das hier geschrieben habe
1
  CASE (next_state) IS

* Auf jeden Fall werde ich das ganze überarbeiten
  - vor allem da ich Sensibilitätslisten jetzt ein bisschen anders sehe!
Moderator (Firma: Titel) Persönliche Seite #7042286
Lesenswert?

Signalisierer schrieb:
> weiß grade nicht wieso ich anstatt
>   CASE (state) IS
> das hier geschrieben habe
>   CASE (next_state) IS
Mein Tipp: schreib synchrone FSM in der 1-Prozess-Schreibweise, dann 
passiert sowas nie wieder.
Siehe dazu auch den Thread Beitrag "FSM Beschreibung in VHDL (registered, combinatorial)" 
und die Links darin.
Gast #7042522
Lesenswert?

* Ich weiß jetzt gerade gar nicht, was ich wählen soll.
* 1 Prozess klingt gut
* Aber ich hätte überhaupt kein Problem Kombinatorik und Synchrones zu 
trennen



Wollte eigentlich mit einem Zähler arbeiten, der bei jeden Takt prüft, 
ob das aktuelle Signal einen validen Code enthält.

* Also  64 Bit Signal = valide dann  counter++ bei rising edge
   - 64 Bit  kann dabei auch konstant bleiben.
   - Kombinatorisch nicht erkennbar, weil Takt einzige Änderung.

* Also angenommen ich möchte bei dem Xilinx Beispiel bleiben.
  - Mit 2 Prozessen.
* Wo soll ich dann diesen Counter hinschreiben?
  - In den ersten oder in den 2ten Prozess.
  - Oder einen neuen Prozess dafür erstellen?
Moderator (Firma: Titel) Persönliche Seite #7042535
Lesenswert?

Signalisierer schrieb:
> Also angenommen ich möchte bei dem Xilinx Beispiel bleiben.
> Mit 2 Prozessen.
> Wo soll ich dann diesen Counter hinschreiben?
> In den ersten oder in den 2ten Prozess.
Du musst nach reiner Lehre den Counter aufteilen in Register z.B. 
namens "cnt" und einen Addierer, der "cnt_next" ausrechnet.

Das wollte ich vorhin eigentlich auch noch verlinken, da steht das drin:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
Gast #7042563
Lesenswert?

Ah vielen Dank für den Link!
Würde das nämlich mindestens gerne nachvollziehen :D

(Habe vorhin schon mal nach "FSM" in dem Suchfeld gesucht, aber es kam 
nichts!)



Was meinst du damit:

Lother M. schrieb:
> ein synchroner und ein kombinatorischer Prozess gemergt in einer
> process-Umgebung.
Die kurze Schreibweise dafür ist "Murks!"
Gast #7042571
Lesenswert?

Hab  das sogar bei meinem pattern generator ( nicht der gerade erwähnte 
pattern checker) auf deine Weise gemacht:


#### Hier der Ausschnitt:

Anmerkungen:

* Der SYNC_PROC ist einfach nur da, weil ich das aus dem Beispiel hatte 
und nicht wusste, ob ich das mit reinbringen soll oder nicht...
* next_state und state passen hier aber von der Namensgebung evtl. 
nicht..
* sm_pr : PROCESS (m_axis_clk) beschreibt dann die states..
* Funktioniert auch soweit ich das nachvollziehen konnte..


1
 SYNC_PROC : PROCESS (m_axis_clk)
2
    BEGIN
3
        IF rising_edge (m_axis_clk) THEN
4
            IF (axi_reset = '1') THEN
5
                current_state <= IDLE; -- its like reset
6
            ELSE
7
                current_state <= next_state;
8
            END IF;
9
        END IF;
10
    END PROCESS SYNC_PROC;
11
    -- connect data
12
    axi_data (63 DOWNTO 0) <= axi_data_content(63 DOWNTO 0); -- axi data
13
    m_axis_tdata <= STD_LOGIC_VECTOR(axi_data); -- data is converted to std logic vector and layed onto signal!
14
    ------------------------------------------------
15
    --- FSM: 
16
    sm_pr : PROCESS (m_axis_clk)
17
    BEGIN
18
        IF (rising_edge (m_axis_clk)) THEN
19
            CASE (next_state) IS
20
                    --- 
21
                WHEN IDLE => -- its like reset
22

23
.
24
.
25
.
Moderator (Firma: Titel) Persönliche Seite #7042831
Lesenswert?

Signalisierer schrieb:
> Was meinst du damit
Man schreibt entweder einen kombinatorischen Prozess ohne Takt, oder 
man schreibt einen synchronen Prozess, wo neben dem Takt 
schlimmstenfalls nur noch ein Reset in der Sensitivliste steht.

Aber man fasst nicht die Kombinatorik und die Register einer 
2-Prozess-Beschreibung hintereinander im selben Prozess zusammen.
Beitrag #7043085 wurde von einem Moderator gelöscht.

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