Forum: FPGA, VHDL & Co. Fragen zu ersten VHDL Beschreibung (UART Transmitter)


von vhdlnub (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

ich bin VHDL Anfänger (sonst nur embedded C++) und wollte ein 
"einfaches" Hello World VHDL erzeugen: Button press -> sendet Hello 
World über Uart.
Leider habe ich nichts zufriedenstellendes gefunden und daher etwas 
eigenes versucht (voller source und testbench im Anhang):
1
entity uart_transmitter is
2
  generic (
3
        CLK_FREQUENCY : positive := 100e6;
4
        BAUD_RATE     : positive := 9600;
5
        FIFO_LENGTH   : positive := 16;
6
        BYTE_WIDTH    : positive := 1
7
  );
8
  Port ( 
9
        tx_enable_i   : in  std_logic;
10
        data_i        : in  std_logic_vector(BYTE_WIDTH*8 - 1 downto 0);
11
        latch_input_i : in  std_logic;
12
        clk_i         : in  std_logic;
13
        busy_o        : out std_logic;
14
        fifo_full_o   : out std_logic;
15
        tx_o          : out std_logic  
16
  );
17
end uart_transmitter;

-> Es ist ein UART Transmitter mit eingebauter FIFO und konfigurierbar 
breitem Zugriff geworden. Oftmals möchte man Daten fester Länge senden 
und dies wird hiermit vereinfacht.

-> Ich habe in einem Hardwaretest latch_input auf ein Buttonsignal 
gelegt und es kam immer ein voller "Hello World" String heraus (je nach 
Baud dutzende bis Tausende). Soweit so gut.

Ich hoffe Ihr könnt Feedback geben und mir weiterhelfen:
- Braucht man zwingend ein Resetsignal? Im Internet sieht man das fast 
überall, aber die Defaultzuweisung für Signale reicht vielleicht aus?
- fifo_full_o wird ein Takt zu spät auf High gesetzt, obwohl ich die 
Variable writeAvailable im Prozess nochmal update. Lösung?
- Wie warte ich in der Testbench, sodass latch_input genau für einen 
Takt auf High steht? Derzeit mache ich es mit hartem "wait for 10ns".
- Was sagt Ihr allgemein zum Stil? Z.B hatte ich irgendwo gesehen, dass 
man  Portsignale immer mit _i und _o Suffixes ausstattet.
- Ressourcenverbrauch? Ich hatte eine optimierte UART von Xilinx 
gesehen, aber die sah vom Interface her kacke aus. Optimierung ist her 
bestimmt noch drin?
- Statt integers sollte man vermutlich unsigned benutzen..?
- Wozu das Zwischensignal baud_output? Das habe ich ohne Verstand aus 
einem anderem UART Design kopiert.
- Bekommt man die UART Baudrate noch genauer hin? Rundung müsste 
irgendwie gehen und die Division durch 2 müsste man durch DDR 
wegbekommen?

Gerne auch weiteres Feedback.

von Klakx (Gast)


Lesenswert?

vorerst ein Tipp, um den Code sauberer zu schreiben:

schreibe richtige Sensitivity-Listen. Ein getakteter Prozess hat nur den 
clock und höchstens den reset drinstehen.
1
tx_fsm : process (baud_clk, tx_enable_i, fifo_head)
ändern zu:
1
tx_fsm : process (baud_clk)

Des Weiteren:
1
writeAvailable := write_available(fifo_head, fifo_tail);
Diese Variablenbenennung ist wahrlich sadistisch ;)

Zu deinen Fragen (nur ein kurzer Auszug):
- im FPGA muss nicht immer an ein Reset gedacht werden, ein 
Initialisieren der Signal geht auch. Wenn du jetzt nachfragst.. lieber 
nicht.. dann hat dein Thread noch 50 weitere Kommentare dazu..
- Klar kann man integers nutzen. Besonders in der Testbench nützlich.
- den Rest habe ich mir noch nicht so genau angeschaut. Ich empfehle 
aber weniger bis gar keine Variablen am Anfang zu nehmen. Auch sind 
Prozeduren in der Regel nicht notwendig/hilfreich. Ich schreibe schon 
sehr lange und sehr viel, aber Prozeduren nutze ich nur in der 
Testbench.

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


Lesenswert?

Die zweite Abfrage zum rising_edge() kommt arg überraschend:
1
io_process : process (clk_i, latch_input_i, data_i, fifo_head, fifo_tail)
2
:
3
begin
4
:
5
    if (rising_edge(clk_i) and latch_input_i = '1') then
6
       :
7
    end if;
8
    
9
    if (rising_edge(clk_i)) then
10
       :
11
    end if;
12
end process io_process;
Wo hast du diesen "Zwei-Takte-pro-Prozess" Stil gelernt? ;-)

So werden denn auch keine Takte in einem FPGA gemacht:
1
-- Generates baud clock from main clk
2
:
3
            baud_output <= not baud_output;
4
:
5
baud_clk <= baud_output;
6
:
7
    if (rising_edge(baud_clk)) then
Das quittiert der Synthesizer mit Kommentaren wie "no good design 
practice". Um Takte zu erzeugen, gibt es Taktmanager und -buffer.

Das, was du hier eigentlich brauchst, sind simple Clock-Enables und 1 
Takt im gesamten Design:
1
constant BAUD_DIVIDER : positive := (CLK_FREQUENCY / BAUD_RATE);
2
:
3
signal baud_cken     : std_logic := '0';
4
:
5
:
6
-- Generates baud clock from main clk
7
baud_generater : process (clk_i)
8
begin
9
    if (rising_edge(clk_i)) then
10
        if baud_counter = BAUD_DIVIDER-1 then
11
            baud_counter <= 0;
12
            baud_cken <= '1';     -- clock-enable 1 Takt lang gültig
13
        else
14
            baud_counter <= baud_counter + 1;
15
            baud_cken <= '0';
16
        end if;
17
    end if;
18
end process baud_generater;
19
20
-- UART TX state machine
21
tx_fsm : process (clk_i)
22
variable readAvailable : integer;
23
begin
24
    if rising_edge(clk_i) then
25
      if baud_cken='1' then
26
        case tx_state is
27
:
28
:

Noch ein Wort zum Coding-Style allgemein:
1
baud_clk <= baud_output;
Warum der unnötige Umweg über ein weiters Signal. Glaub mir: du wirst 
später immer wieder über diese Umbenennung stolpern.

In die selbe Richtung geht die überaus akademische Beschreibung des Fifo 
mit den vielen Funktionen, die eigentlich nur trivialste Dinge tun. Wenn 
ich die Fifolänge auf eine Zweierpotenz definiere (so wie hier 16), dann 
kann ich die Schreib- und Lesepointer einfach als unsigned Vektoren 
ausführen. Die erzeugen ihren Überlauf auf 0 "automatisch" und müssen 
nur inkrementiert werden. Bei mir würde diese Beschreibung also etwa so 
aussehen:
1
        FIFO_LENGTH   : positive := 4; -- Fifolänge = 2**FIFO_LENGTH
2
:
3
:
4
type tx_state_t is (IDLE, DATA_BITS, STOP_BIT);
5
type fifo_t is array(0 to 2**FIFO_LENGTH-1) of std_logic_vector(7 downto 0);
6
:
7
signal fifo         : fifo_t;
8
:
9
signal wrptr, rdptr : unsigned[FIFO_LENGTH-1 downto 0] := "0000";
10
:
11
:
12
-- UART TX state machine
13
tx_fsm : process
14
begin
15
    wait until rising_edge(clk_i);
16
    if baud_cken='1' then
17
        case tx_state is
18
        
19
        when IDLE =>
20
            if (tx_enable_i = '1' and rdptr/=wrptr) then  -- wenn ungleich -> Daten im Fifo
21
                tx_o <= '0';             -- Los gehts mit dem Startbit
22
                tx_data <= fifo(rdptr);  -- fifo auslesen
23
                rdptr <= rtptr+1;        -- Lesezeiger hochzählen, Überlauf gibts gratis
24
                tx_bit_index <= 0;
25
                tx_state <= DATA_BITS;
26
                busy_o <= '1';
27
            else
28
                tx_o <= '1';             -- sonst Ruhepegel ausgeben
29
                busy_o <= '0';
30
            end if;
31
           
32
        when DATA_BITS =>
33
            tx_o <= tx_data(tx_bit_index);
34
            tx_bit_index <= tx_bit_index + 1;
35
            if (tx_bit_index = 7) then
36
                tx_state <= STOP_BIT;
37
            end if;
38
            
39
        when STOP_BIT =>
40
            tx_o <= '1';
41
            tx_state <= IDLE;
42
            end if;
43
            
44
        end case;
45
    end if;
46
end process tx_fsm;
Den extra Abzweig im Zustand STOP_BIT lasse ich auch weg, denn er ist 
nicht mehr nötig, weil die FSM ja schon aus dem Idle heraus das Startbit 
ausgeben kann.
Und das "when others" kann ich weglassen, wenn sowieso alle Zustände der 
FSM auscodiert sind:
http://www.lothar-miller.de/s9y/categories/25-when-others

BTW: es ist nicht verboten, sich den Quellcode von anderen anzuschauen, 
ihn zu analysieren und zu verstehen. Und es dann ggfs. besser zu machen.

BTW2: man muss nicht unbedingt englische Kommentare schreiben, wenn man 
nicht Gefahr läuft, das der Code von internationalem Interesse ist.

: Bearbeitet durch Moderator
von vhdlnub (Gast)


Lesenswert?

Danke für die Antworten.

Lothar M. schrieb:
> Die zweite Abfrage zum rising_edge() kommt arg überraschend:
> [...]
> Wo hast du diesen "Zwei-Takte-pro-Prozess" Stil gelernt? ;-)
Das muss ich nochmal anschauen, genauso wie die Sensitivity Listen.

>
> So werden denn auch keine Takte in einem FPGA gemacht:
> [...]
> Das quittiert der Synthesizer mit Kommentaren wie "no good design
> practice". Um Takte zu erzeugen, gibt es Taktmanager und -buffer.
> Das, was du hier eigentlich brauchst, sind simple Clock-Enables und 1
> Takt im gesamten Design:
Schade, fand mein Konzept logischer. Das "1 single clock" Konzept muss 
noch nachvollziehen. Wie bekommt man solche Warnungen (in Vivado) 
angezeigt? Gibt es eine äquivalente -Wall Option?

> In die selbe Richtung geht die überaus akademische Beschreibung des Fifo
> mit den vielen Funktionen, die eigentlich nur trivialste Dinge tun.
> [...]
>
1
                 tx_o <= '0';             -- Los gehts mit dem Startbit
2
                 tx_data <= fifo(rdptr);  -- fifo auslesen
3
                 rdptr <= rtptr+1;        -- Lesezeiger hochzählen, Überlauf gibts gratis
Trivial, bis plötzlich Kommentare Abläufe erklären. ;)
Meiner Programmiererfahrung nach sind für sich selbst sprechende 
Subprogramme inline Kommentaren vorzuziehen. Kann man sicherlich drüber 
streiten in diesem Beispiel.


> Den extra Abzweig im Zustand STOP_BIT lasse ich auch weg, denn er ist
> nicht mehr nötig, weil die FSM ja schon aus dem Idle heraus das Startbit
> ausgeben kann.
Stimmt, so ist es kompakter.

> Und das "when others" kann ich weglassen, wenn sowieso alle Zustände der
> FSM auscodiert sind:
Hm, das habe ich jetzt sogar als "Information" des Synthesizers 
entdeckt. :)

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


Lesenswert?

vhdlnub schrieb:
> die Sensitivity Listen.
... sind ausschließlich für die Simulation interessant. Der 
Synthesizer schert sich nur insofern um diese Listen, als er eine Info 
ausgibt, die besagt, dass wegen der falschen Liste die Simulation nicht 
zur erzeugten Hardware passt.

vhdlnub schrieb:
> Schade, fand mein Konzept logischer.
Eigentlich schießt du dir mit diesem langsamen "Takt" insofern ins Bein, 
als du für jede Aktion dieses Moduls warten musst, bis dieser Takt 
wieder aktiv ist. Wenn also jetzt gerade die FSM im IDLE steht, gerade 
ein baud_clk war und genau jetzt war zu versenden wäre, kann der 
Transmitter nicht starten, sondern muss aufgrund des langsamen 
"Baud-Taktes" noch eine komplette Bitzeit abwarten, bis es losgeht. In 
meinem Sender dort auf 
http://www.lothar-miller.de/s9y/categories/42-RS232 kann auf Anforderung 
mit jedem Quarztakt eine neue Übertragung gestartet werden, weil der 
gesamte UART mit dem Systemtakt läuft.
(Dort sieht man übrigens auch, dass ich das Senderegister mit einem 10 
Bit Schieberegister implementiert habe, das geht in einem FPGA 
effizienter als die Implementation eines Multiplexers. Ich bin da 
übrigens nicht selber drauf gekommen, sondern habe mir die internen 
Hardwarekomponenten von gängigen µC mal genauer angeschaut, deren 
Verhalten untersucht und das dann beschrieben... ;-)

> Das "1 single clock" Konzept muss noch nachvollziehen.
Unbedingt. Ein "ideales" FPGA Design hat systemweit nur 1 Takt, der Rest 
wird mit Clock-Enables (man könnte sie auch "Flags" nennen) erledigt, 
die jeweils ebenfalls für 1 Taktzyklus aktiv sind und damit in anderen 
Modulen irgendwas auslösen.
Und wenn eben doch ein zweiter Takt nötig ist, dann muss der mit 
Clockmanagern erzeugt werden, damit die Toolchain die abgeleiteten 
Timings bestimmen und kontrollieren kann.

> Wie bekommt man solche Warnungen (in Vivado) angezeigt?
Umpf, ehrlich gesagt weiß ich das jetzt gar nicht, weil ich solche 
Meldungen nicht produziere...  ;-)
Aber ich würde da jetzt mal nach Anmerkungen zu "Jitter" und "Skew" 
suchen.

> Meiner Programmiererfahrung nach sind für sich selbst sprechende
> Subprogramme inline Kommentaren vorzuziehen.
Ja, nur muss man dann eben immer wieder mal schauen, was das Subprogramm 
denn überhaupt macht. Und vor allen ist die Denkweise in "Subprogrammen" 
in VHDL prinzipiell falsch, weil ja kein "Subprogramm" aufgerufen, 
sondern Hardware daraus erzeugt wird. Insofern sollte man sich immmer 
vergegenwärtigen, dass man mit VHDL eben nicht prozedural sequenziell 
"programmiert", sondern parallele Hardware "beschreibt". Nicht umsonst 
ist das D und nicht ein P in VHDL...  ;-)

Und wo ich mir das hier mal gerade genauer anschaue:
1
procedure copy_data_in (signal fifo : inout fifo_t; signal fifo_head : in integer) is
2
variable dstIndex : integer;
3
begin
4
    for i in 0 to BYTE_WIDTH-1 loop
5
        if (fifo_head + i > FIFO_LENGTH - 1) then
6
            dstIndex := fifo_head + i - FIFO_LENGTH;
7
        else
8
            dstIndex := fifo_head + i;
9
        end if;
10
        fifo(dstIndex) <= data_i(8*i + 7 downto i*8);
11
    end loop;
12
end procedure copy_data_in;
Weil eine loop in VHDL mehrfache Hardware erzeugt, die gleichzeitig 
aktiv ist, ergibt diese Beschreibung bei einer BYTE_WIDTH (irgendwie 
verwirred dieser Name, ein Byte hat anerkanntermaßen doch 8 Bits...) 
ungleich 1 einen 8 Bit (=1 Byte) breiten Speicher, in dem gleichzeitig 
auf mehrere Bytes/Adressen zugegriffen wird. Sowas gibt es in Hardware 
auf einfache Weise nicht, es muss recht umständlich und aufwändig 
zusammengebastelt werden. Man müsste eigetnlich ein Blockram (das kann 
zwei unterschiedliche Wortbreiten) nehmen und die beiden Ports in der 
Breite entsprechend konfigurieren, aber so ein Bauteil muss manuell 
instanziiert werden (siehe dazu den passenden Abschnitt im Synthesizer 
User Guide).

Konkret bedeutet das hier, dass bei größeren Wortbreiten auch für das 
Schreiben des Fifos sinnvollerweise eine FSM nötig wäre, die von einem 
16 oder 32 Bit Wert ein Byte nach dem anderen in den Fifo einträgt.

Sehr sinnvoll ist es übrigens, sich anfänglich ab&zu mal den 
RTL-Schaltplan der erzeugten Hardware anzusehen und zu kontrollieren, ob 
der Synthesizer aus der VHDL Beschreibung die Hardware 
herausdestillieren konnte, die die Grundlage für die ursprüngliche 
Hardwarebeschreibung war.

von Vancouver (Gast)


Lesenswert?

Just my 2 Cents...

Zum Thema Reset: Vorbelegung der Signale funktioniert im FPGA, aber eben 
nur dort und auch nur einmal. Was ist, wenn du deinen UART mal im 
laufenden Betrieb resetten musst? Kommt vielleicht nicht oft vor, aber 
deinen Embedded C++-Code versuchst du auch, möglichst waaserdicht zu 
machen, richtig? Also wenn dein Design definierte Signale erfordert, um 
korrekt zu funktionieren, dann ist ein Reset auf jeden Fall die saubere 
Lösung, die immer und auf jeder Zielplattform funktioniert. Das braucht 
ntürlich ein paar Resourcen, aber wenn das Design so auf Kante genäht 
ist, dass keine Resetlogik mehr reinpasst, dann wurde da schon viel 
früher ein konzeptioneller Fehler gemacht.

Clockdomains: Wenn du mehrere Takte verwendest, musst du üblicherweise 
auch Daten von der einen Domain in die andere transportieren. Das nennt 
sich clock domain crossing (CDC) und ist im höchten Maße nichttrivial 
und eine schier unerschöpfliche Fehlerquelle. Besonders dann, wenn die 
beiden Takte stark unterschiedliche Frequenzen haben. Wenn dein Design 
mit 100MHz läuft aber Daten mit 9600bps ausgeben soll, dann stehen die 
Takte in einem Verhältnis von ca. 1:104. In diesem Fall reichen keine 
einfachen (bzw. dreifachen) Synchronsationsstufen mehr, sondern man 
braucht asynchrone Fifos, um Daten sicher in die andere Clockdomain zu 
übertragen.
Es ist in diesem Fall viel einfacher und sicherer, nur einen Takt zu 
verwenden und das UART-Timing mit Steuersignalen zu erzeugen, die aus 
Zählern und FSMs generiert werden. Peripherals, die im x*100kHz-Bereich 
arbeiten, haben üblicherweise kein Recht auf eigene Clockdomain :-)

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


Lesenswert?

Vancouver schrieb:
> Peripherals, die im x*100kHz-Bereich arbeiten, haben üblicherweise kein
> Recht auf eigene Clockdomain :-)
mit x = 0..100

Und auch einen 20MHz SPI würde ich nach Möglichkeit eher mit 
ClockEnables machen als mit zwei Clockdomains herumzukrampfen... ;-)

Vancouver schrieb:
> Also wenn dein Design definierte Signale erfordert, um korrekt zu
> funktionieren, dann ist ein Reset auf jeden Fall die saubere Lösung
Wobei man dann aber nicht jedes Flipflop (und schon gar nicht asynchron) 
zurücksetzen muss, sondern eigentlich "nur" die FSM (die für den 
Ruhezustand auf der "Leitung nach aussen" sorgt) auf IDLE und die 
Pointer des Fifo zum selben Wert bringen muss. Denn in diesem Zustand 
"räumt" sich die Geschichte hier ja quasi selber auf.

Eine gewichtige zu beantwortende Frage ist allerdings: woher kommt 
dieser Reset?
Von einem externen Taster? Wenn ja: Reset unnötig, denn der Taster kann 
ja via "Config" auch das FPGA laden.
Von einem externen µC? Warum möchte der das FPGA zurücksetzen? Und warum 
zupft er nicht einfach an der "Config"-Leitung?

von Duke Scarring (Gast)


Lesenswert?

Vancouver schrieb:
> Das nennt
> sich clock domain crossing (CDC) und ist im höchten Maße nichttrivial
> und eine schier unerschöpfliche Fehlerquelle. Besonders dann, wenn die
> beiden Takte stark unterschiedliche Frequenzen haben.
Nunja, wenn die Takte nahe beieinander liegen, dann geht das Design die 
meiste Zeit und setzt nur sporadisch aus.

BTDT:
Ein CPU lief mit 90 MHz, der Rest des Designs aber mit 100 MHz. In 9 von 
10 Fällen kamen die Daten von der CPU im Design richtig an.

Sporadisch auftretende, nicht sicher reproduzierbare Fehler sind mit die 
kniffligsten...

Duke

von Vancouver (Gast)


Lesenswert?

Lothar M. schrieb:
> Von einem externen Taster? Wenn ja: Reset unnötig, denn der Taster kann
> ja via "Config" auch das FPGA laden.
> Von einem externen µC? Warum möchte der das FPGA zurücksetzen? Und warum
> zupft er nicht einfach an der "Config"-Leitung?

Auf diese Weise wird dann alles platt gemacht, das ist nicht immer 
erwünscht.
Beispiele:

- Eine Signalverarbeitungspipeline kann man z.B. einfach resetten bevor 
die neuen Daten kommen, anstatt den ganzen restlichen Müll 
rauszuflushen, wobei der Controller aber weiterlaufen soll. Macht man 
manchmal so, wenn IIR-Filter drin sind, die eine Ewigkeit zum Abklingen 
brauchen.

- Bei Aerospace-Designs verwendet man manchmal Triple Modular 
Redundancy, d.h. man vergleicht die Ergbisse von drei redundanten 
Prozessen und trifft eine Mehrheitsentscheidung. Liefert einer der 
Prozesse dauerhaft ein abweichendes Ergebnis, wird er resettet, während 
die anderen weiterlaufen.

- Oder man möchte bestimmte Teile des Designs im Reset halten, bis 
irgendeine Bedingung eingetreten ist.


- Und dann gibts noch das Thema Unabhängigkeit von der Zeiltechnologie. 
Wie gesagt, im FPGA geht eine Initialisierung ohne Reset, im ASIC aber 
nicht.


Ok, wenn alles das nicht zutrifft, kann man im FPGA einfach am config 
ziehen und fertig.

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


Lesenswert?

Vancouver schrieb:
> Auf diese Weise wird dann alles platt gemacht, das ist nicht immer
> erwünscht.
Richtig, aber dann ist das eigentlich kein "Reset" im üblichen Sinn, 
sondern ein definiertes Setzen von bestimmten Modulen oder Teilen des 
Bausteins auf einen definierten Zustand. Das wird eben nicht über das 
übliche systemweite Resetnetzwerk gemacht, sondern lokal an den gerade 
nötigen Stellen.

> Eine Signalverarbeitungspipeline kann man z.B. einfach resetten bevor
> die neuen Daten kommen, anstatt den ganzen restlichen Müll rauszuflushen
Genau dafür ist aber dann meist wieder wesentlich mehr nötig. Denn wenn 
die Daten in einem RAM stehen, dann ist ja schon Essig mit einem simplen 
Reset, weil ein RAM so einen Reset-Anschluss ja gar nicht hat.

> Ok, wenn alles das nicht zutrifft, kann man im FPGA einfach am config
> ziehen und fertig.
Man kann sihc auf diese Art das Leben signifikant erleichtern. Und bei 
ganz arg vielen Diskussionen zu diesem Thema abseits von redundanten 
Systemen und ASICs möchten viele einfach nur deshalb irgendeinen Reset, 
weil sie den so "gewöhnt" sind.

Aber wir schweifen ab...  ;-)

von S. R. (svenska)


Lesenswert?

Lothar M. schrieb:
> Den extra Abzweig im Zustand STOP_BIT lasse ich auch weg, denn er ist
> nicht mehr nötig, weil die FSM ja schon aus dem Idle heraus das Startbit
> ausgeben kann.

Ja, das vereinfacht die FSM für den Sender...

Lothar M. schrieb:
> Wenn also jetzt gerade die FSM im IDLE steht, gerade
> ein baud_clk war und genau jetzt war zu versenden wäre, kann der
> Transmitter nicht starten, sondern muss aufgrund des langsamen
> "Baud-Taktes" noch eine komplette Bitzeit abwarten, bis es losgeht.

...aber riskiert man dann nicht, dass das Stopbit nur einen Quarztakt 
(statt einer Bitzeit) lang ist? Zumindest habe ich das so in Erinnerung, 
und daher ist das Stopbit bei mir ein Teil der FSM.

von Vancouver (Gast)


Lesenswert?

Lothar M. schrieb:
> aber dann ist das eigentlich kein "Reset" im üblichen Sinn,
> sondern ein definiertes Setzen von bestimmten Modulen oder Teilen des
> Bausteins auf einen definierten Zustand.

Ist das nicht die Definition des Reset?

Lothar M. schrieb:
> möchten viele einfach nur deshalb irgendeinen Reset,
> weil sie den so "gewöhnt" sind.

Wie gesagt, wenn die Rekonfiguration als Reset möglich ist, dann gut.

Lothar M. schrieb:
> Aber wir schweifen ab...  ;-)

Warum auch nicht. Solange es der Erkenntnis dient :-)

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


Lesenswert?

S. R. schrieb:
> ...aber riskiert man dann nicht, dass das Stopbit nur einen Quarztakt
> (statt einer Bitzeit) lang ist?
Nein, es ist wegen des Zustands STOP_BIT sogar mindestens einen 
Quarztakt länger als nötig. Dafür kann aber eben auch nach 1,2 oder 2,7 
oder sonstwas Komma irgendwas Baudtakten mit jedem Quarztakt neu 
gestartet werden.

von Michel (Gast)


Lesenswert?

Lothar M. schrieb:
> Dafür kann aber eben auch nach 1,2 oder 2,7
> oder sonstwas Komma irgendwas Baudtakten mit jedem Quarztakt neu
> gestartet werden.

Oha. Schau an, das wusste ich noch gar nicht.

von Duke Scarring (Gast)


Lesenswert?

Letztendlich ist das Stopbit bei der UART eine Pause, die dem Empfänger 
bleibt, um daa empfangene Datum auszuwerten.
Die eignetliche Bitlänge ist i.d.R. unerheblich, sie wird nicht gemessen 
oder geprüft, nur zu schnell darf es nicht werden.

Die Übertragung wird beim nächsten Startbit wieder synchronisiert.

Duke

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.