Forum: FPGA, VHDL & Co. Sequential System Design Using ASM Charts


von Daniel P. (daniel2345)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich versuche mich aktuell an Aufgabe 1-1 von Lab 11 Xilinx HDL Design 
using Vivado.

Als Lösung ist auch das ASM chart auf Seite 6 angegeben.
Mit diesem ASM chart komme ich jedoch nicht auf das Timing Diagramm von
Seite 5.

Mit ein paar Änderungen habe ich das Timing Diagramm fast hinbekommen.
Jedoch verstehe ich nicht was für Werte in product_int angezeigt werden, 
bevor das Endergebnis drinnen steht.

Könnte bitte mal jemand meine ASM begutachten?

Danke und Gruß
Daniel

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

Die Simulation sieht doch gar nicht so schlecht aus, zumindest kommen 
auch plausible Ergebnisse raus.
Bei der zweiten Berechnung (4*1) würde ich das Startsignal nur für einen 
Takt einschalten. Außerdem ist es hilfreich ein Signal zu haben, welches 
anzeigt, wann ein gültiges Ergebnis vorliegt.

Und noch ein Hinweis an den Autor des Tutorials: Es ist didaktisch nicht 
hilfreich, wenn die Zustände einer State-Machine mit S0, S1, ..., Sn 
einfach nur durchnummeriert sind.

Duke

von my 2 cents (Gast)


Lesenswert?

Duke Scarring schrieb:
> Es ist didaktisch nicht
> hilfreich, wenn die Zustände einer State-Machine mit S0, S1, ..., Sn
> einfach nur durchnummeriert sind.

Das wäre auch zub einfach! Wo kämen wir hin, wenn aufwändige 
Chart-Methoden erzeugt, vermittelt und propagiert werden, um sie dann 
nicht einsetzen zu müssen, weil manch einer einfach einen Geradeaus-Code 
schreibt, der selbsterklärend ist?

von Duke Scarring (Gast)


Lesenswert?

Daniel P. schrieb:
> Könnte bitte mal jemand meine ASM begutachten?
Ja. Deine Trennung von State Machine und Berechnungen machen es unnötig 
unübersichtlich. Auch die zusätzliche Verwendung von CU, CD und done_int 
machen es nicht einfacher.
Außerdem dürfte sich das falling_edge(start) im State S1 nicht 
synthetisieren lassen.

Wenn ich so einen Multiplizierer bräuchte, würde der bei mir ungefähr so 
aussehen:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
6
entity multiply is
7
    port 
8
    (
9
        clk          : in  std_logic;
10
        start        : in  std_logic;
11
        multiplicand : in  std_logic_vector(2 downto 0);
12
        multiplier   : in  std_logic_vector(2 downto 0);
13
        --
14
        product      : out std_logic_vector(5 downto 0);
15
        done         : out std_logic
16
    );
17
end entity multiply;
18
19
20
architecture rtl of multiply is
21
22
    type state_type is (IDLE, ADD, SHIFT);
23
    signal state            : state_type;
24
    --
25
    signal count            : natural range 0 to 2;
26
    signal ma               : unsigned(2 downto 0);
27
    signal mb               : unsigned(5 downto 0);
28
    signal result           : unsigned(5 downto 0);
29
30
begin
31
32
    process
33
    begin
34
        wait until rising_edge(clk);
35
                    
36
        -- default
37
        done    <= '0';
38
39
        case state is
40
41
            when IDLE =>
42
                if start = '1' then
43
                    state       <= ADD;
44
                    count       <= 2;
45
                    ma          <= unsigned( multiplicand);
46
                    mb          <= resize( unsigned( multiplier), mb'length);
47
                    result      <= ( others => '0');
48
                end if;
49
50
            when ADD =>
51
                if ma( 0) = '1' then
52
                    result      <= result + mb;
53
                end if;
54
                state           <= SHIFT;
55
      
56
            when SHIFT =>
57
                if count > 0 then
58
                    mb          <= shift_left( mb, 1);
59
                    ma          <= shift_right( ma, 1);
60
                    count       <= count - 1;
61
                    state       <= ADD;
62
                else
63
                    done        <= '1';
64
                    product     <= std_logic_vector( result);
65
                    state       <= IDLE;
66
                end if;
67
68
        end case;
69
70
    end process;
71
72
end architecture rtl;

Wahrscheinlich würde ich die States SHIFT und ADD noch zusammenfassen 
und in der Portmap unsigned statt std_logic_vector verwenden. Da ist 
nach außen hin sofort klar, was für ein Datentyp erwartet wird.

Duke

von Daniel P. (daniel2345)


Lesenswert?

Duke Scarring schrieb:
> Wenn ich so einen Multiplizierer bräuchte, würde der bei mir ungefähr so
> aussehen:


Hallo Duke Scarring,

vielen Dank für deinen Beitrag.
Ich muss zugeben, deine Variante ist kürzer, übersichtlicher und auch 
verständlicher.

Ich werde zukünftig auch die 1-Prozess Variante für die FSM benutzen.

Zu Lernzwecken habe ich jedoch versucht deine 1-Prozess Schreibweise in 
eine 2-Prozess Schreibweise zu konvertieren.
Allerdings klappt das nicht wie erhofft, daher die Frage ist das 
überhaupt mit vernünftigen Mitteln möglich?
Oder müssen die ganzen Berechnungen dann in den getakten Prozess und im 
kombninatorischen Prozess kann ich nur Ausgänge und Hilfsignale setzen.
Wenn das so ist, bin ich wieder ganz schnell bei meiner sehr 
unübersichtlichen Version von oben.


Ich hätte auch noch eine Frage zur Sensitivity list.
Soweit ich das verstanden habe, ist die Sensitivity list vor allem für 
die Simulation wichtig. Wenn ich bei der Simulation Signale in der Liste 
vergesse, bekomme ich eine Abweichung von der Funktion in Simulation zur 
Funktion in Hardware.
Wie verhält es sich dann mit der Sensitivity List bei der Synthese?
Hier kann ich doch meines Wissens den FPGA bzw. den Prozess nicht mit 
einzelnen Signalen in der Sensitivity List steuern.
Fügt der Syntheskompiler dann automatisch alle im Prozess verwendeten 
Signale zur Liste hinzu so ähnlich wie process(all)?


Daniel

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


Lesenswert?

Daniel P. schrieb:
> Fügt der Syntheskompiler dann automatisch alle im Prozess verwendeten
> Signale zur Liste hinzu
Ja. Und der Synthesizer meldet dann recht unscheinbar, dass die erzeugte 
Hardware nicht zur Simulation passen wird.

Daniel P. schrieb:
> Oder müssen die ganzen Berechnungen dann in den getakten Prozess
In der 2-Prozess-FSM sind Berechnungen wie Addition und Multiplikation 
oder ähnliche kombinatorische Rechenvorgänge im kombinatorischen 
Prozess. Nur die Speicher werden getaktet und damit in der Hardware zu 
Flipflops.

von Daniel P. (daniel2345)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe jetzt die Version des Multiplizieres von Duke Scarring als 
2-Prozess Schreibweise ausgeführt.
Dazu hätte ich zwei Fragen:

1. Ich habe zwar alle Berechnungen im kombinatorischen Teil 
untergebracht, aber nur mit dem Hilfskonstrukt "next" im Getaktetem Teil 
(count_next, ma_next, usw.). Gibt es dazu einfachere bzw. elegantere 
Lösungen?

2. Am Anfang hat zwar die Simulation funktioniert, aber die Funktion in 
Hardware nicht. Es kam eine Warnung des einige Latches eingefügt wurden.
Ich habe dann am Anfang vom kombinatorischen Prozess alle Signale in der 
Art
"result_next <= result" beschrieben. Ist das so sinnvoll oder wäre es 
eine Alternative jedes Signal in jedem case zu beschreiben?


Danke und Gruß
Daniel

: Bearbeitet durch User
von Duke Scarring (Gast)


Lesenswert?

Daniel P. schrieb:

> 1. Ich habe zwar alle Berechnungen im kombinatorischen Teil
> untergebracht, aber nur mit dem Hilfskonstrukt "next" im Getaktetem Teil
> (count_next, ma_next, usw.). Gibt es dazu einfachere bzw. elegantere
> Lösungen?
Da fällt mir nur die 1-Prozess-Schreibweise ein ;-)

> 2. Am Anfang hat zwar die Simulation funktioniert, aber die Funktion in
> Hardware nicht. Es kam eine Warnung des einige Latches eingefügt wurden.
> Ich habe dann am Anfang vom kombinatorischen Prozess alle Signale in der
> Art
> "result_next <= result" beschrieben. Ist das so sinnvoll oder wäre es
> eine Alternative jedes Signal in jedem case zu beschreiben?
Speicherelemente kann man auf zwei Arten beschreiben: flankengesteuert 
(rising_edge), dann wird ein Flip-Flop draus oder pegelgesteuert (if 
level=... ohne default und ohne else), dann wird es ein Latch.
Wenn es auf der Steuerleitung glitcht, können Latches Probleme machen. 
Darum sollte man sie vermeiden.

Wenn es in Deinem kombinatorischer Prozess nicht zu allen Signale in 
jedem Fall eine Zuweisung gibt, hast Du Latches generiert. Entweder 
erstmal allen Signalen per Default einen Wert zuweisen oder zu jedem 
if-Zweig auch einen else-Zweig mit einer Zuweisung hinschreiben:
1
-- Latch, da kein Takt und nicht in jedem Fall eine Zuweisung
2
process
3
begin
4
  if sig = '1' then
5
    value_next <= value + 1;
6
  end if;
7
end process;
8
9
-- kein Latch, da in jedem Fall eine Zuweisung
10
process
11
begin
12
  if sig = '1' then
13
    value_next <= value + 1;
14
  else
15
    value_next <= value;
16
  end if;
17
end process;
18
19
-- kein Latch, da in jedem Fall eine Zuweisung
20
process
21
begin
22
  value_next <= value;
23
  if sig = '1' then
24
    value_next <= value + 1;
25
  end if;
26
end process;
27
28
-- kein Latch, da getaktet
29
process
30
begin
31
  wait until rising_edge( clk);
32
  if sig = '1' then
33
    value <= value + 1;
34
  end if;
35
end process;

Duke

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


Lesenswert?

Noch eine Silbe zum Code:
1
       when others =>
Es gibt für diese FSM kein "others", weil alle 4 möglichen Zustände 
manuell auscodiert sind. Siehe dort:
http://www.lothar-miller.de/s9y/categories/25-when-others
Man kann mit einem solchen "when others" also logischerweise auch 
niemals eine "irre gelaufene" FSM wieder "einfangen".

Daniel P. schrieb:
> Es kam eine Warnung des einige Latches eingefügt wurden.
Hinweise auf solche Latches können auch Hinweise auf (gegatete) 
kombinatorische Schleifen sein.
http://www.lothar-miller.de/s9y/categories/36-Kombinatorische-Schleife

Und hier die Darstellung dieser Thematik mit ein oder zwei Prozessen:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html

: Bearbeitet durch Moderator
von Daniel P. (daniel2345)


Lesenswert?

Vielen Dank euch beiden für eure Hilfe.

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.