Forum: FPGA, VHDL & Co. If, elsif, else funktioniert nicht!


von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

Ich möchte eine kleine FSM bauen, welche einen MCP23S17 mit 
ausgabewerten beschreibt...

Nun habe ich in der Simulation ein nicht nachvollziehbares Verhalten...
hier die FSM:
1
           if state = set_cs then
2
                spi_opcode <= x"F550";
3
                cs <= '0';
4
                time_cnt <= "0101";         --50ns von setzen des Cs bis zum 1. Bit
5
                nxstate <= set_clk;
6
                count := 0;
7
                so <= spi_opcode(count);
8
            elsif (zero = '1') and (nxstate = set_clk) then //Diese Aussage ist nie True!
9
                state <= nxstate;
10
                nxstate <= rst_clk;
11
                sck <= '1';
12
                count := count + 1;
13
                time_cnt <= "0101";         --50ns bis zur fallenden sck-Flankle
14
            elsif zero = '1' and nxstate = rst_clk then
15
                state <= nxstate;
16
                sck <= '0';
17
                so <= spi_opcode(count);
18
                
19
                if count < 15 then 
20
                    nxstate <= set_clk;
21
                    time_cnt <= "0000";         --50ns bis zum nächsten set_clk
22
                else
23
                    nxstate <= rst_cs;
24
                end if;
25
            elsif zero = '1' and nxstate = rst_cs then
26
                state <= nxstate;
27
                nxstate <= set_clk;
28
                cs <= '1';
29
                time_cnt <= "0101";         --50ns clk_delay_Time
30
            elsif zero = '1' and nxstate <= set_clk then
31
                sck <= '1';
32
                state <= nxstate;
33
                nxstate <= rst_clk;
34
                time_cnt <= "0101";         --50ns clk_delay_Time
35
            elsif zero = '1' and nxstate <= rst_clk then
36
                sck <= '0';
37
                state <= nxstate;
38
                nxstate <= set_cs;
39
            else
40
                time_cnt <= "0000";
41
            end if;

Das Verhalten der behav-Simulation kann ich nicht nachvollziehen,
hier wird zero gesetzt, gleichzeitig ist nxstate = set_clk
obwohl die
1
elsif (zero = '1') and (nxstate = set_clk) then
somit eindeutig wahr ist, kann nicht in den nächsten Zustand gesprungen 
werden...

Welchen sehr grundlegenden Fehler mache ich?

Vielen Dank,
Matthias

von few (Gast)


Lesenswert?

Hab mir den Code nicht angeguckt, es heißt aber else if und nicht 
elseif.

von Sebastian S. (amateur)


Lesenswert?

>Welchen sehr grundlegenden Fehler mache ich?
Uns Prosa schicken und die Fehlermeldungen, die der Compiler 
unzweifelhaft ausgibt, unterschlägst.

von user (Gast)


Lesenswert?

few schrieb:
> Hab mir den Code nicht angeguckt, es heißt aber else if und nicht
> elseif.

und du kannst kein VHDL, da gibt es elsif

von Matthias (Gast)


Lesenswert?

few schrieb:
> Hab mir den Code nicht angeguckt, es heißt aber else if und nicht
> elseif.

Nein, es heißt elsif...

Sebastian S. schrieb:
>>Welchen sehr grundlegenden Fehler mache ich?
> Uns Prosa schicken und die Fehlermeldungen, die der Compiler
> unzweifelhaft ausgibt, unterschlägst.

Wenn der Compiler welche geben würde, würde ich sie euch weitergeben...

von user (Gast)


Lesenswert?

In deiner Wave ist an der Position der Markierung state gleich set_cs

somit ist folgendes wahr
if state = set_cs then --ist wahr
   -- das hier wird gemacht
elsif .... -- das hier mag auch wahr sein, wird aber nicht ausgewertet, 
weil das im else Fall ist (elsif = else if)

von Markus F. (mfro)


Lesenswert?

Matthias schrieb:
> Welchen sehr grundlegenden Fehler mache ich?

wenn state erst mal = set_cs ist, wie soll sich das jemals ändern?

Im gezeigten Code jedenfalls nicht.

von daniel__m (Gast)


Lesenswert?

Matthias schrieb:
> if state = set_cs then
>                 spi_opcode <= x"F550";
>                 cs <= '0';
>                 time_cnt <= "0101";         --50ns von setzen des Cs bis
> zum 1. Bit
>                 nxstate <= set_clk;
>                 count := 0;
>                 so <= spi_opcode(count);
>             elsif (zero = '1') and (nxstate = set_clk) then //Diese
> Aussage ist nie True!

hi,

du hast state und nxstate. Wie verhalten dies sich zueinander? Soll das 
die typische 2 Process-FSM sein? Wie/wo ist der Takt?

Sprich, der Code ist nicht vollständig und zeigt dein Problem nicht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Matthias schrieb:
> Wenn der Compiler welche geben würde, würde ich sie euch weitergeben...
Das ist kein Compilerproblem, sondern ein Logikproblem.

Matthias schrieb:
> Das Verhalten der behav-Simulation kann ich nicht nachvollziehen,
> hier wird zero gesetzt, gleichzeitig ist nxstate = set_clk
> obwohl die elsif (zero = '1') and (nxstate = set_clk) then
> somit eindeutig wahr ist, kann nicht in den nächsten Zustand gesprungen
> werden...
Weil vorher was Anderes abgefragt wird. Nimm einfach mal die Zustände 
und durchlauf deinen Code. Du hast offenbar ein Prioritätsproblem bei 
deinen if-Abfragen.
1
           if state = set_cs then           // Diese Abfrage hat Vorrang!
2
                spi_opcode <= x"F550";
3
                cs <= '0';
4
                time_cnt <= "0101";         --50ns von setzen des Cs bis zum 1. Bit
5
                nxstate <= set_clk;
6
                count := 0;
7
                so <= spi_opcode(count);
8
            elsif (zero = '1') and (nxstate = set_clk) then // Diese Aussage wird gar nie abgefragt!
9
                state <= nxstate;
10
                nxstate <= rst_clk;
11
                sck <= '1';
12
                count := count + 1;
13
                time_cnt <= "0101";         --50ns bis zur fallenden sck-Flankle
Ein klassisches Layer 8 Problem... ;-)

Wenn du deinen Code so abänderst, dann konnt der nächste Zustand:
1
            if (zero = '1') and (nxstate = set_clk) then // Diese Aussage ist nie True!
2
                state <= nxstate;
3
                nxstate <= rst_clk;
4
                sck <= '1';
5
                count := count + 1;
6
                time_cnt <= "0101";         --50ns bis zur fallenden sck-Flankle
7
           elsif state = set_cs then
8
                spi_opcode <= x"F550";
9
                cs <= '0';
10
                time_cnt <= "0101";         --50ns von setzen des Cs bis zum 1. Bit
11
                nxstate <= set_clk;
12
                count := 0;
13
                so <= spi_opcode(count);
14
...
Ob dann das restliche Verhalten aber noch passt, steht auf einem anderen 
Blatt...

daniel__m schrieb:
> du hast state und nxstate. Wie verhalten dies sich zueinander?
Und einmal wird state und ein andres Mal nxstate abgefragt. Das scheint 
mir dubios.

von Matthias (Gast)


Lesenswert?

user schrieb:
> In deiner Wave ist an der Position der Markierung state gleich set_cs
>
> somit ist folgendes wahr
> if state = set_cs then --ist wahr
>    -- das hier wird gemacht
> elsif .... -- das hier mag auch wahr sein, wird aber nicht ausgewertet,
> weil das im else Fall ist (elsif = else if)

Vielen Dank, genau dass war der Fehler, so funktioniert es nun :)

Lothar M. schrieb:
> daniel__m schrieb:
>> du hast state und nxstate. Wie verhalten dies sich zueinander?
> Und einmal wird state und ein andres Mal nxstate abgefragt. Das scheint
> mir dubios.
Ihr habt Recht, das war nicht korrekt/sinvoll...

Vielen Dank auch für alle Anderen Antworten :)

Übrigens der MCP23S17 läuft mit 50MHz SPI-Takt auch wenn
laut Datenblatt nur 10MHZ drin sind...
Bei 60MHz macht er nicht mehr mit..

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Matthias schrieb:
> Übrigens der MCP23S17 läuft mit 50MHz SPI-Takt auch wenn laut Datenblatt
> nur 10MHZ drin sind...
Mach den mal anständig warm... ?

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.