Forum: FPGA, VHDL & Co. Statemachine "überspringt" Zustand


von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Ich bin gerade etwas Ratlos...

Ich habe es jezt hinbekommen das ich mit dem FPGA Board per RS232 
Zeichen senden und Empfangen kann. Als nächstes wollte ich es so machen, 
das man vom PC aus 2 Zeichen sendet, der FPGA 
addiert/subtrahiert/multipliziert/... die dann und gibt das Ergebnis 
zurück.

Dazu habe ich zwei Zustände:
START => Der FPGA wartet auf den Empfang eines Zeichen gibt dieses auf 
die LEDs aus speichert das Zeichen in "OPCODE" und wechselt in den 
Zustand "DECODE".
DECODE =>
- OPCODE = 0x60 der FPGA sendet die Summe der zwei letzten Zeichen und 
wechselt zu START
- OPCODE = 0x10 der FPGA empfängt das nächste Zeichen und speichert es, 
das vorherige rutscht eine Postion nach unten (TOP1+TOP2), wechsel zu 
Start
- SONST: sende das Zeichen '-', Gehe zu Start

Das bilden der Summe funktioniert auch, ebenso das senden des Zeichens 
'-'

Nur das Empfangen des zusätzlichen Zeichens macht ärger, da ich in 
diesem Falle immer den OPCODE Anstelle des nächsten Zeichens empfange...

Hier erstmal der Code:
1
CPU: process(CLK_50M)
2
begin
3
    if rising_edge(CLK_50M) then
4
    -- Default: Weder lesen noch schreiben...
5
    rx_read  <= '0';
6
    tx_write <= '0';
7
    wr       <= '0';
8
    tx_data  <= (others => '-');
9
    -- End Default
10
    case state is
11
    when START =>
12
           if (rx_ready = '1') then
13
                rx_read <= '1';
14
                OPCODE  <= rx_data;
15
                LED     <= rx_data;
16
                state   <= DECODE;
17
            end if;
18
      when DECODE =>
19
          case OPCODE is
20
                when X"10" =>
21
                    if (rx_ready = '1') then
22
                        rx_read    <= '1';
23
                        data_in    <= X"000000" & rx_data;
24
                        wr         <= '1';
25
                        write_addr <= write_addr +1;
26
                        --SP         <= SP + 1;
27
                        LED        <= (others => '1');
28
                        state      <= START;
29
                    end if;
30
                when X"60" =>
31
                    if (tx_full = '0') then
32
                        tx_write <= '1';
33
                        tx_data  <= TOP1(7 downto 0) + TOP2(7 downto 0);
34
                        state    <= START;
35
                        LED      <= (others => '0');
36
                    end if;
37
                when others =>
38
                    if (tx_full = '0') then
39
                        tx_write <= '1';
40
                        tx_data  <= std_logic_vector(to_unsigned(character'pos('-'), 8));
41
                        state    <= START;
42
                    end if;
43
            end case;
44
        end case;
45
   end if;
Es sieht so aus, alsob er in dem Fall direkt nach DECODE springt (was er 
ja erst einen Takt später tun sollte), und dort gleich das "alte" 
Zeichen nochmal liest.

Ich sende also:
- 0x10 --> Alle LEDs gehen an
- 0xAA --> Jede Zweite LED geht an und der FPGA quitiert mit -

Was ich erwarten würde:
- 0x10 --> 1 Led an
- 0xAA --> Alle Leds an

Als RS232 Transiver nutze ich die Macros vom KCPSM3/PicoBlaze, und laut 
Anleitung sollte sobald das read signal einmal 1 gewesen ist das neue 
Datenpaket am Ausgang anliegen (oder halt signalisiert werden das der 
Puffer leer ist).

Vieleicht sieht ja jemand meinen Fehler, ich steh gerade etwas auf dem 
Schlauch :(

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Hab jezt versucht das auslesen des Parameters mal in den "START" Zustand 
zu verlegen...
1
case state is
2
when START =>
3
       if (rx_ready = '1') then
4
            rx_read <= '1';
5
            if (OPCODE = X"10") then
6
                data_in    <= X"000000" & rx_data;
7
                wr         <= '1';
8
                write_addr <= write_addr +1;
9
                LED        <= (others => '1');
10
                OPCODE     <= rx_data;
11
            else
12
                OPCODE  <= rx_data;
13
                LED     <= rx_data;
14
                state   <= DECODE;
15
            end if;
16
        end if;
17
  when DECODE =>
18
      case OPCODE is
19
            when X"10" =>
20
                    state      <= START;
Meine Überlegung war, das falls ich doppelte Zeichen Empfange er solange 
diese überspringt bis er ein anderes Zeichen Empfängt... Verhalten ist 
aber das selbe wie vorher, so langsam versteh ich garnix mehr...

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Okay, lag nicht an meiner Statemachine... Anscheind wird bei dem RX 
Macro erst zwei Takte nach dem lesen der Zustand des "daten vorhanden" 
Flag erneuert... auf jedenfall ne böse Falle, hab jezt einfach nen 
zusätzlichen Wartezustand eingefügt nun gehts grrr

von Abc (Gast)


Lesenswert?

Erst immer posten, dann überlegen und debuggen. Oder doch lieber 
umgekehrt ?  ;O)

von Lymangood (Gast)


Lesenswert?

War bestimmt nur ein FlipFlop kaputt.

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.