Hallo zusammen, in den folgenden zwei Beispielen lasse ich mir ein Byte ("ToggleByte") permanent invertieren und an eine Senderoutine schicken. Beide sind einwandfrei simulierbar und tuen, für was sie gedacht. Nach der Synthese sieht das anders aus: Das erste Beispiel funktioniert, das zweite nicht. Hier die beiden Beispiele: Beispiel 1:
1 | Debug_Adder : process(CLK) |
2 | variable StateMachine: integer range 0 to 2 := 0; |
3 | variable ToggleByte : STD_LOGIC_VECTOR(7 downto 0) := x"00"; |
4 | begin
|
5 | if rising_edge(CLK) then |
6 | |
7 | case StateMachine is |
8 | |
9 | -- Senden
|
10 | when 1 => |
11 | if NewTransmitACK = '0' then -- Ist der Sender frei? |
12 | Transmit <= (others => '0'); -- Nachricht pauschal löschen |
13 | Transmit(7 downto 0) <= ToggleByte; -- Byte zur Überprüfung, ob Nachricht aktualisiert wurde, in Byte 0 senden |
14 | NewTransmit <= '1'; -- Senden anfordern |
15 | end if; -- |
16 | |
17 | -- Toggeln
|
18 | when 2 => |
19 | if NewTransmitACK = '1' then -- Nachricht übernommen? |
20 | NewTransmit <= '0'; -- Anforderung zurücknehmen |
21 | ToggleByte := not ToggleByte; -- Byte toggeln |
22 | StateMachine := 0; -- StateMachine resetten, um Überlauf zu verhindern |
23 | end if; -- |
24 | |
25 | when others => |
26 | null; |
27 | end case; |
28 | |
29 | StateMachine := StateMachine + 1; -- Automatisch nächsten Schritt wählen |
30 | |
31 | end if; |
32 | end process; |
Beispiel 2:
1 | Debug_Direct : process(CLK) |
2 | variable StateMachine: integer range 0 to 1 := 0; |
3 | variable ToggleByte : STD_LOGIC_VECTOR(7 downto 0) := x"00"; |
4 | begin
|
5 | if rising_edge(CLK) then |
6 | |
7 | case StateMachine is |
8 | |
9 | -- Senden
|
10 | when 0 => |
11 | if NewTransmitACK = '0' then -- Ist der Sender frei? |
12 | Transmit <= (others => '0'); -- Nachricht pauschal löschen |
13 | Transmit(7 downto 0) <= ToggleByte; -- Byte zur Überprüfung, ob Nachricht aktualisiert wurde, in Byte 0 senden |
14 | NewTransmit <= '1'; -- Senden anfordern |
15 | StateMachine := 1; -- Im nächsten Schritt Zähler erhöhen |
16 | end if; -- |
17 | |
18 | -- Toggeln
|
19 | when 1 => |
20 | if NewTransmitACK = '1' then -- Nachricht übernommen? |
21 | NewTransmit <= '0'; -- Anforderung zurücknehmen |
22 | ToggleByte := not ToggleByte; -- Byte toggeln |
23 | StateMachine := 0; -- Im nächsten Schritt wieder das Senden anfordern |
24 | end if; -- |
25 | |
26 | end case; |
27 | |
28 | end if; |
29 | end process; |
Das meiste davon ist Overhead zum Senden. Der wesentliche Unterschied zwischen den beiden Beispielen: Im Ersten gebe ich den nächsten State meiner Statemachine im aktuellen State vor, im Zweiten erhöhe ich ihn automatisch per Addition. Den Überlauf fange ich dann im letzten Schritt der StateMachine ab. Warum funktioniert das erste Beispiel nicht? Warum dafür das Zweite? Wo ist denn nur der Unterschied? Er synthetisiert es anders. Aber was ist denn an der ersten Beschreibung nur falsch?