Forum: FPGA, VHDL & Co. Schieberegister PISO Probleme mit der Ausgabe


von Vicky M. (vicky_m)


Angehängte Dateien:

Lesenswert?

Hi,

da ich noch Anfängerin bin und mich Schritt für Schritt durch den VHDL 
Jungle kämpfe, bin ich nun am Schieberegister angelangt. Ich habe mir 
vorgenommen ein Schieberegister aufzubauen welches parallel zwei 8Bit 
Zeichen einliest und anschließend diese Seriell ausgibt. Später will ich 
diese 8 Bit Zeichen an meinem Nexys Board einlesen welche dann von 
meinem µC kommen. Deshalb habe ich wie @Lothar Miller es beschrieben hat 
den Enable und und Reset einsynchronisiert. Theoretisch müsste ich Load0 
und Load1 auch einsynchronisieren, oder?

Das Einsynchroniseren habe ich versucht wie beschrieben umzusetzten, 
weis aber nicht ob das so komplett passt wie ich das aufgefasst und 
umgesetzt habe. Der Reset muss laut Ihm auch auf jedenfall 
einsynchronisiert werden da dieser von einem Taster kommt und daher 
komplett asynchron wäre.

Nun gut, es funktioniert auch eigentlich alles auch so halbwegs. 
Probleme sind das mein Schieberegister die Werte einliest, aber diese 
nicht ausgibt. Was habe ich falsch verstanden? Habe ein Bild von meiner 
Simulation angehangen.

Auch habe ich bei meinen eingelesen werten einen Taktversatz. Ich lese 
doch parallel ein, warum ist da ein Versatz drinnen?
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity tutorial is
6
          
7
    Port(
8
          clk         :   IN  STD_LOGIC;
9
          enable      :   IN  STD_LOGIC;
10
          reset      :   IN  STD_LOGIC;
11
          y           :   OUT STD_LOGIC
12
           );
13
14
end tutorial;
15
16
architecture Behavioral of tutorial is
17
18
    constant load0    : STD_LOGIC_VECTOR(7 downto 0) := "10101010";
19
    constant load1    : STD_LOGIC_VECTOR(7 downto 0) := "11001100";
20
    signal sr         : STD_LOGIC_VECTOR (7 downto 0) := (others=>'0');
21
    signal resetsr    : STD_LOGIC_VECTOR (1 downto 0);
22
    signal enablesync : std_logic := '0';
23
    
24
    
25
begin
26
27
    process
28
        begin                                         -- Einsynchronisieren der externen Inputs
29
            wait until rising_edge(clk);
30
               enablesync <= enable;
31
               resetsr <= resetsr(0) & reset;
32
     end process;
33
             
34
         process(clk)                                  -- Schieberegister
35
         begin
36
            if (enablesync = '1') and (resetsr(0) = '0') then
37
                sr <= load0;
38
            elsif (enablesync = '0') and (resetsr(0) = '0') then
39
                sr <= load1; 
40
            elsif (resetsr(0) = '1') then
41
                sr <= "00000000";
42
            elsif rising_edge(clk) then
43
                sr <= sr (6 downto 0) & '0';     
44
             end if;
45
         end process;
46
          
47
    y <= sr(0);      
48
49
end Behavioral;

1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity testbench is
6
end testbench;
7
8
architecture Behavioral of testbench is
9
10
COMPONENT tutorial is
11
    Port( 
12
         clk         :   IN  STD_LOGIC;
13
         enable      :   IN  STD_LOGIC;
14
         reset       :   IN  STD_LOGIC;
15
         y           :   OUT STD_LOGIC
16
        ); 
17
        
18
end COMPONENT;
19
20
    signal clk       :   STD_LOGIC := '0';
21
    signal enable    :   STD_LOGIC := '1';
22
    signal reset     :   STD_LOGIC := '0';
23
    signal y         :   STD_LOGIC := '0';
24
  
25
begin
26
    aand : tutorial PORT MAP(
27
         clk        =>  clk,
28
         y          =>  y,
29
         reset      =>  reset,
30
         enable     =>  enable
31
         );
32
33
    clk        <=  not clk after 5 ns;
34
    enable     <=  not enable after 40ns;
35
    reset      <=  not enable after 120ns;
36
   
37
38
end Behavioral;


Zusatz: Die Zeiten in der Testbench sind von mir frei ausgedacht. Aber 
eigentlich sollten diese passen, oder?

Aller beste Grüße
Vicky

: Bearbeitet durch User
von Vicky M. (vicky_m)


Lesenswert?

Also es ist schon dubios. Ich bekomme keine Error List aber Warnings und 
diese versteh ich nicht:
1
[Synth 8-3332] Sequential element (enablesync_reg) is unused and will be removed from module tutorial.
2
[Synth 8-3332] Sequential element (resetsr_reg[0]) is unused and will be removed from module tutorial.
3
[Synth 8-3332] Sequential element (sr_reg[7]) is unused and will be removed from module tutorial.
4
[Synth 8-3332] Sequential element (sr_reg[6]) is unused and will be removed from module tutorial.
5
[Synth 8-3332] Sequential element (sr_reg[5]) is unused and will be removed from module tutorial.
6
[Synth 8-3332] Sequential element (sr_reg[4]) is unused and will be removed from module tutorial.
7
[Synth 8-3332] Sequential element (sr_reg[3]) is unused and will be removed from module tutorial.
8
[Synth 8-3332] Sequential element (sr_reg[2]) is unused and will be removed from module tutorial.
9
[Synth 8-3332] Sequential element (sr_reg[1]) is unused and will be removed from module tutorial.
10
[Synth 8-3332] Sequential element (sr_reg[0]) is unused and will be removed from module tutorial.
11
[Synth 8-3332] Sequential element (y_reg) is unused and will be removed from module tutorial.

Warum sind die alle unbenutzt? Ich lade diese Register doch und gebe 
diese auf Y was mein Output ist.

: Bearbeitet durch User
von Bernhard K. (bkom)


Lesenswert?

Vicky M. schrieb:
> (...)
> process(clk)                                  -- Schieberegister
>          begin
     viel zu viel asyncrones
>             if (enablesync = '1') and (resetsr(0) = '0') then
>                 sr <= load0;
>             elsif (enablesync = '0') and (resetsr(0) = '0') then
>                 sr <= load1;
>             elsif (resetsr(0) = '1') then
>                 sr <= "00000000";
>             elsif rising_edge(clk) then
>                 sr <= sr (6 downto 0) & '0';
>              end if;
>          end process;

Probier es erstmals so:
1
process(clk)
2
      if rising_edge(clk) then
3
             if (enablesync = '1') and (resetsr(0) = '0') then
4
                 sr <= load0;
5
             elsif (enablesync = '0') and (resetsr(0) = '0') then
6
                 sr <= load1;
7
             elsif (resetsr(0) = '1') then
8
                 sr <= "00000000";
9
             else
10
                 sr <= sr (6 downto 0) & '0';
11
              end if;
12
         end if
13
     end process;
AAAAber: >sr <= sr (6 downto 0) & '0';< kann rein logisch nie erreicht 
werden!

> Theoretisch müsste ich Load0 und Load1 auch einsynchronisieren, oder?
Nein, da die zwei intern und konstant sind.

: Bearbeitet durch User
von Vicky M. (vicky_m)


Lesenswert?

Erst einmal vielen Dank dir. Aber leider bleibt mein y Ausgang immer 
noch auf Null.

Bernhard K. schrieb:
> AAAAber: >sr <= sr (6 downto 0) & '0';< kann rein logisch nie erreicht
> werden!

Das verstehe ich nicht ganz was du damit meinst?

von Bernhard K. (bkom)


Lesenswert?

mach einfach eine Tabelle:
wenn     enablesync und resetsr(0)   dann macht dein VHDL-code
             1             0           sr <= load0
             0             0           sr <= load1;
             - (=egal)     1           sr <= "00000000";

Mit welchen Logikwerten kommt man nun
zu "sr <= sr (6 downto 0) & '0'" ??

Evtl mit einem zusätzlichen Steuersignal:
1
process(clk)
2
      if rising_edge(clk) then
3
             if (enable_load0_sync = '1') and (resetsr(0) = '0') then
4
                 sr <= load0;
5
             elsif (enable_load1_sync = '0') and (resetsr(0) = '0') then
6
                 sr <= load1;
7
             elsif (resetsr(0) = '1') then
8
                 sr <= "00000000";
9
             else
10
                 sr <= sr (6 downto 0) & '0';
11
              end if;
12
         end if
13
     end process;

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


Lesenswert?

Wozu hat reset_sr eigentlich 2 Bits, wenn das zweite davon niemals 
benutzt wird?

Vicky M. schrieb:
> deshalb habe ich wie @Lothar Miller es beschrieben hat den Enable und und
> Reset einsynchronisiert.
Das solltest du dir nochmal genauer ansehen und vor allem: versuchen zu 
verstehen, warum da 2 Flipflops hintereinander kommen sollten...

> Der Reset muss laut Ihm auch auf jedenfall einsynchronisiert werden da
> dieser von einem Taster kommt und daher komplett asynchron wäre.
Meine Worte sind: ein Reset ist unnötig, weil im echten Leben ein 
Resettaster niemals gedrückt wird. Nur vermurkste Designs und Anfänger 
brauchen sowas.

BTW: deine Simulation ist FALSCH, weil die Sensitivliste nicht 
komplett ist. Da fehlen enablesync und reset_sr. Deshalb ist der 
Screenshot auch teilweise so schön synchron zum fallenden(!!) 
Taktflanke, obwohl die Signale asynchron sind...

von Vicky M. (vicky_m)


Lesenswert?

Bernhard K. schrieb:
> mach einfach eine Tabelle:
> wenn     enablesync und resetsr(0)   dann macht dein VHDL-code
>              1             0           sr <= load0
>              0             0           sr <= load1;
>              - (=egal)     1           sr <= "00000000";
>
> Mit welchen Logikwerten kommt man nun
> zu "sr <= sr (6 downto 0) & '0'" ??
>
> Evtl mit einem zusätzlichen Steuersignal:
>
1
> process(clk)
2
>       if rising_edge(clk) then
3
>              if (enable_load0_sync = '1') and (resetsr(0) = '0') then
4
>                  sr <= load0;
5
>              elsif (enable_load1_sync = '0') and (resetsr(0) = '0') then
6
>                  sr <= load1;
7
>              elsif (resetsr(0) = '1') then
8
>                  sr <= "00000000";
9
>              else
10
>                  sr <= sr (6 downto 0) & '0';
11
>               end if;
12
>          end if
13
>      end process;
14
>

Ok, ich hoffe ich habe es verstanden. Ich glaube du möchtest mir damit 
sagen das ich immer in den ersten drei if hängenbleibe und nie in die 
else Bedingung komme. Somit wird nie der Befehl
1
sr <= sr (6 downto 0) & '0;

ausgeführt. Somit müsste das letzte else eigentlich ein elsif mit 
Bedingung sein damit ich da rein komme.

Jo da stehe ich dann aber vor dem Problem was für eine Bedingung das 
sein soll. Theoretisch ein writeout. Theoretisch könnte ich es auch 
Taktgesteuert herausführen und aus der elsif herausnehmen sobal das 
Schieberegister geladen ist?
1
           
2
         process(clk, enablesync, resetsr)                                -- Schieberegister
3
         begin
4
          if rising_edge(clk) then
5
                if (enablesync = '1') and (resetsr(0) = '0') then
6
                    sr <= load0;
7
                    writeout <= '1';
8
                elsif (enablesync = '0') and (resetsr(0) = '0') then
9
                    sr <= load1; 
10
                    writeout <= '1';
11
                elsif (resetsr(0) = '1') then
12
                    sr <= "00000000";
13
                    writeout <= '1';
14
                elsif (writeout = '1') then
15
                    sr <= sr (6 downto 0) & '0';  
16
                    writeout <= '0';  
17
                 end if;
18
            end if;     
19
         end process;  
20
          
21
      y <= sr(0);  
22
23
end Behavioral;

Nachtrag: Dieser Versuch führte auch nicht zum gewünschten Ziel. Ich 
habe es wohl doch falsch verstanden.

Lothar M. schrieb:
> Wozu hat reset_sr eigentlich 2 Bits, wenn das zweite davon niemals
> benutzt wird?

Da muss ich ehrlich zugeben das ich es nicht vollständig verstanden 
habe. Ich habe mich auch gewundert. Damit ich keine Fehler mehr bekommen 
habe habe ich dann ein Bit ausgewählt.

Lothar M. schrieb:
> BTW: deine Simulation ist FALSCH, weil die Sensitivliste nicht
> komplett ist. Da fehlen enablesync und reset_sr. Deshalb ist der
> Screenshot auch teilweise so schön synchron zum fallenden(!!)
> Taktflanke, obwohl die Signale asynchron sind...

Habe die Sensitivliste vervollständigt.

Des Weiteren meinst du ich sollte den Reset heraus nehmen. Ich wusste 
nicht das dieser besser weggelassen wird. Ich dachte das wenn mal ein 
Fehler auftaucht das ein Reset gedrückt werden kann :D .

: Bearbeitet durch User
von Bernhard K. (bkom)


Lesenswert?

Vicky M. schrieb:
> (...)
>Ich habe es wohl doch falsch verstanden.
ja, dennwie soll "sr <= sr (6 downto 0) & '0';" erreicht werden, ohne 
neues Signal in den ersten if-abfragen ?

Ich meine etwa so:
1
 process(clk)
2
                                -- Schieberegister
3
  begin
4
     if rising_edge(clk) then       --      -----> hier das neue Signal
5
       if (enablesync = '1') and (resetsr(0) = '0') and (writeout='0') then
6
              sr <= load0;
7
8
    --- und so weiter und so fort ...
9
10
               elsif (writeout = '1') then
11
                    sr <= sr (6 downto 0) & '0';  
12
                 end if;
13
            end if;     
14
         end process;
Und lass den reset einfach erstmal drin, wenn dann das Beispiel geht
könntest du bei FPGAs den reset auch rauslassen, mach aber erst mal 
den ersten Schritt mit reset!

von Vicky M. (vicky_m)


Lesenswert?

Also so sehr ich es auch versuche und weitere Variablen einführe usw. 
will der Ausgang einfach nichts ausgeben. So langsam glaube ich der 
Hunde liegt noch wo anders begraben.
1
    process(clk, enablesync, resetsr)                                  -- Schieberegister
2
         begin
3
          if rising_edge(clk) then
4
                if (enablesync = '1') and (resetsr(0) = '0') and (writeout='0') then
5
                    sr <= load0;
6
                elsif (enablesync = '0') and (resetsr(0) = '0') and (writeout='0') then
7
                    sr <= load1; 
8
                elsif (resetsr(0) = '1') and (writeout='0')then
9
                    sr <= "00000000";
10
                elsif (writeout = '1') then
11
                    sr <= sr (6 downto 0) & '0';  
12
                 end if;
13
            end if;     
14
         end process;
15
 
16
      y <= sr(0);

Ich habe auch diesen Betrag von Lothar Miller gefunden.
https://embdev.net/topic/348169
Ganz am Anfang meines Post habe ich es doch so ähnlich gemacht.

: Bearbeitet durch User
von Vicky M. (vicky_m)


Lesenswert?

Sodelle ich habe nun nochmals alles aufgeräumt und getestet. Ich habe 
ein Timingproblem! In meiner Testbench habe ich meine Zeiten und Enables 
usw. nicht im Griff. Deshalb kommt beim Seriellen Ausgang nur Müll raus.

Wie gehe ich da am besten vor?

Ich habe 8Bit die Parallel zu Seriell gewandelt werden. das bedeutet, 8* 
CLK ist die Zeit die das Schieberegister benötigt die Bits auszugeben 
bevor neue hinein geladen werden dürfen. Stimmt das?

Jetzt muss ich schauen wie ich meine loadenable und shift richtig setze 
damit es funktioniert. Aus Einfachheitsgründen habe ich den Reset mal 
weggelassen.



Programm:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity tutorial is
6
7
    Port(
8
      clk           : IN  std_logic;
9
      enable        : IN  std_logic;
10
      shift_i       : IN  std_logic;
11
      ser_out       : OUT std_logic;
12
      loadenable    : IN  std_logic
13
       );
14
15
end tutorial;
16
17
architecture Behavioral of tutorial is
18
19
    constant load0        : STD_LOGIC_VECTOR (7 downto 0) := "10101010";
20
    constant load1        : STD_LOGIC_VECTOR (7 downto 0) := "11001100";
21
    signal sr             : STD_LOGIC_VECTOR (7 downto 0);
22
    
23
    begin                           -- Schieftregister
24
25
         process(clk)
26
             begin
27
                  if rising_edge(clk) then
28
                     if enable = '1' and loadenable = '1' then
29
                         sr <= load0;
30
                     elsif enable = '1' and loadenable = '0' then
31
                         sr <= load1;
32
                     elsif shift_i = '1' then
33
                         sr <= '0' & sr(7 downto 1);  
34
                     end if;
35
                  end if;
36
          end process;
37
          
38
        ser_out  <= sr(0);                                       
39
40
end Behavioral;

Testbench
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity testbench is
6
end testbench;
7
8
architecture Behavioral of testbench is
9
10
COMPONENT tutorial is
11
12
    Port( 
13
         clk        :   IN  STD_LOGIC;
14
         enable     :   IN  STD_LOGIC;
15
         shift_i    :   IN  STD_LOGIC;
16
         ser_out    :   OUT STD_LOGIC;
17
         loadenable :   IN  std_logic
18
        ); 
19
        
20
end COMPONENT;
21
22
    signal clk         :   STD_LOGIC := '0';
23
    signal enable      :   STD_LOGIC := '0';
24
    signal shift_i     :   STD_LOGIC := '0';
25
    signal ser_out     :   STD_LOGIC := '0';
26
    signal loadenable  :   STD_LOGIC := '0';
27
28
  
29
begin
30
    aand : tutorial PORT MAP(
31
         clk       =>  clk,
32
         ser_out   =>  ser_out,
33
         shift_i   =>  shift_i,
34
         enable    =>  enable,
35
         loadenable    =>  loadenable
36
         );
37
38
    clk        <=  not clk after 5 ns;
39
    loadenable <=  not loadenable after 45 ns;
40
    enable     <=    '1' after  45ns,
41
                     '0' after  50ns,
42
                     '1' after  95ns,
43
                     '0' after  100ns;
44
    shift_i    <=  not shift_i after 5 ns;
45
--                   '0' after  50ns,
46
--                   '1' after  55ns;
47
48
end Behavioral;

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


Lesenswert?

Vicky M. schrieb:
> 8* CLK ist die Zeit die das Schieberegister benötigt die Bits
> auszugeben bevor neue hinein geladen werden dürfen. Stimmt das?
Und zudem brauchst du noch mindestens 1 Taktzyklus zur Übernahme des 
nächsten Datenworts.

BTW: das was du da machst wird bei SPI im Grunde auch gemacht...

Vicky M. schrieb:
> Programm:
Dir sollte klar werden, dass du da nicht programmierst, denn sonst hieße 
es ja VHPL.

Vicky M. schrieb:
> In meiner Testbench habe ich meine Zeiten und Enables usw. nicht im
> Griff. Deshalb kommt beim Seriellen Ausgang nur Müll raus.
> Wie gehe ich da am besten vor?
Was macht nun diese Beschreibung mit dieser Testbench? Woher kommen im 
"echten Leben" diese Signale? Wie sieht dort das zeitliche Verhalten 
aus? Denn im besten Fall ist die Testbench eine Nachbildung der 
Realität...

: Bearbeitet durch Moderator
von Vicky M. (vicky_m)


Lesenswert?

Lothar M. schrieb:
> Vicky M. schrieb:
>> 8* CLK ist die Zeit die das Schieberegister benötigt die Bits
>> auszugeben bevor neue hinein geladen werden dürfen. Stimmt das?
> Und zudem brauchst du noch mindestens 1 Taktzyklus zur Übernahme des
> nächsten Datenworts.

Wenn ich dann aber meine parallel eingeschobene Bits seriell ausgeben 
möchte, habe ich dann immer einen Takt Versatz von load0 zu load1. Das 
macht mir ja meine serielle Bitkette kaputt?

> Vicky M. schrieb:
>> In meiner Testbench habe ich meine Zeiten und Enables usw. nicht im
>> Griff. Deshalb kommt beim Seriellen Ausgang nur Müll raus.
>> Wie gehe ich da am besten vor?
> Was macht nun diese Beschreibung mit dieser Testbench? Woher kommen im
> "echten Leben" diese Signale? Wie sieht dort das zeitliche Verhalten
> aus? Denn im besten Fall ist die Testbench eine Nachbildung der
> Realität...

Projekt 1.)

Wie oben beschrieben ist es ein Eigenprojekt die ich mir ausgedacht habe 
um ein besseres Verständnis für alles zu bekommen. Load0 und Load1 sind 
noch Konstanten, welche ich aber später mit einem STM Board zu meinem 
FPGA sende. Dort will ich diese einlesen und anschließend Parallel 
Seriell Wandeln um eine schöne Bitkette zu bekommen.

Projekt 2.)

STM Board sendet die serielle Bitkette zum FPGA und soll diese Parallel 
Wandeln um wieder Load0 und Load1 zu erkennen. Theoretisch versuche ich 
eine sehr einfache Übertragung aufzubauen. Theoretisch das oben 
rückwärts.


Aber zu aller erst muss es in der Simulation mit festen Werten 
funktionieren, anschließend schau ich weiter wie es mit den externen 
Signalen funktioniert. Somit muss ich mir jetzt eine Frequenz aussuchen 
wo mit die 8Bit+ Taktversatz rein passt damit mein Ausgangssignal 
vollständig abgebildet wird.

100MHz ist vom Nexys der Grundtakt. Das bedeutet ja das 10ns eine 
Periode vom Takt ist. Dann brauche ich 90ns (8Bit+ Taktversatz) für 
meine Bitkette (z.b. load0) aber nur beim ersten mal, oder? Wie verhält 
sich es mit dem Taktversatz beim Wechsel von load0 zu load1?

Sollte ich andere, tiefere Frequenzen wählen? Theoretisch kann ich diese 
ja später immer noch mit einem Zähler langsamer machen, oder? Wie macht 
man das in der Paxis?

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


Lesenswert?

Vicky M. schrieb:
> Wenn ich dann aber meine parallel eingeschobene Bits seriell ausgeben
> möchte, habe ich dann immer einen Takt Versatz von load0 zu load1. Das
> macht mir ja meine serielle Bitkette kaputt?
Ja nun, wenn du alle 8 Bits ein neues Wort einlesen und nahtlos 
ausgeben willst, dann musst du da ein wenig mehr Gehirnschmalz 
reinstekcne und praktisch schon am vorhergehenden Takt alles für Laden 
vorbereiten. Es ist dann ja nichts zufällig, sondern es muss einfach 
einen Takt früher passieren...

> Load0 und Load1 sind noch Konstanten, welche ich aber später mit einem
> STM Board zu meinem FPGA sende. Dort will ich diese einlesen und
> anschließend Parallel Seriell Wandeln um eine schöne Bitkette zu bekommen.
Wenn in deinem Bitstrom ausschließlich Datenbits kommen, wie kann sich 
der Empfänger dann synchronisieren? SPI verwendet zum Synchronisieren 
z.B. den SlaveSelect.

> Sollte ich andere, tiefere Frequenzen wählen?
Du solltest die Frequenz maximal so hoch wählen, dass du deine Daten 
ausreichend schnell übertragen kannst. Wenn du die beiden 8 Bit Worte 
100000 mal pro Sekunde übertragen musst (! Achtung: es zählt nur das, 
was du musst, nicht das, was du willst), dann reichen dir 2 MHz Takt 
locker aus.

> Theoretisch versuche ich eine sehr einfache Übertragung aufzubauen.
Praktisch wirst du sehen, dass dir da der angesprochene 
Synchronisationsmechanismus fehlt. Denn wenn da nur 1 kleine Störung 
auftritt und der Empfänger einen Taktimpuls doppelt oder gar nicht 
erkennt, dann läuft deine gesamte Kommunikation von da an um 1 Bit 
versetzt.

von Vicky M. (vicky_m)


Lesenswert?

Lothar M. schrieb:
> Vicky M. schrieb:
>> Wenn ich dann aber meine parallel eingeschobene Bits seriell ausgeben
>> möchte, habe ich dann immer einen Takt Versatz von load0 zu load1. Das
>> macht mir ja meine serielle Bitkette kaputt?
> Ja nun, wenn du alle 8 Bits ein neues Wort einlesen und nahtlos
> ausgeben willst, dann musst du da ein wenig mehr Gehirnschmalz
> reinstekcne und praktisch schon am vorhergehenden Takt alles für Laden
> vorbereiten. Es ist dann ja nichts zufällig, sondern es muss einfach
> einen Takt früher passieren...

Mach ich das mit einem Zähler? Sozusagen alles fängt an mit Zählerstand 
10 außer das Laden das wird schon ab Takt 9 ausgeführt? Also benötigt 
man hierfür zwei Zähler? Oder gibts eine einfachere Lösung?

Lothar M. schrieb:

>> Theoretisch versuche ich eine sehr einfache Übertragung aufzubauen.
> Praktisch wirst du sehen, dass dir da der angesprochene
> Synchronisationsmechanismus fehlt. Denn wenn da nur 1 kleine Störung
> auftritt und der Empfänger einen Taktimpuls doppelt oder gar nicht
> erkennt, dann läuft deine gesamte Kommunikation von da an um 1 Bit
> versetzt.

Also müsste ich ein weiteres load „load2" einführen mit fest definierten 
Datenbits, welche immer an einer gewissen Stelle vorkommen. Und beim 
Empfänger eine Biterkennung aufbauen. Theoretisch ein MUX der immer 
schaltet wenn eine gewisse Folge anliegt.

Ziemlich komplex finde ich gerade. Gibts hier irgendwo ein Beispiel für 
so etwas?

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Wieso verwendest Du nichts Fertiges wie UART? Oder zumindest das Konzept 
mit Startbit und Stoppbit ...

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


Lesenswert?

Vicky M. schrieb:
> Also müsste ich ein weiteres load „load2" einführen mit fest definierten
> Datenbits, welche immer an einer gewissen Stelle vorkommen. Und beim
> Empfänger eine Biterkennung aufbauen. Theoretisch ein MUX der immer
> schaltet wenn eine gewisse Folge anliegt.
Du musst noch weiter denken, denn wenn dieses 
"Synchronisations-Bitmuster" zufällig mal durch andere Daten erzeugt 
wird, dann machst du ebenfalls einen Resync. Denn mal angenommen, dein 
Synchronisationspattern ist 01010101, dann sag mir mal, wo du bei dieser 
Bitfolge neu aufsetzen würdest:
1
...111001101010101010101010111001101010101010101010111001101010101010101010111001...
Ein Tipp: das sind tatsächlich immer die selben 3 Bytes, die 
nacheinander gesendet werden. Und eines davon ist das "Sync-Byte" 
01010101
Sag mir jetzt, welches die beiden anderen Bytes sind. Ich sage dir dann 
hinterher, welche ich tatsächlich gesendet habe...

Aber wie schon erwähnt: das Rad ist bereits erfunden. Du kannst dir 
einfach mal anschauen, wie andere das machen: RS232, SPI, Microwire, 
usw. usf.

> Mach ich das mit einem Zähler? Sozusagen alles fängt an mit Zählerstand
> 10 außer das Laden das wird schon ab Takt 9 ausgeführt? Also benötigt
> man hierfür zwei Zähler? Oder gibts eine einfachere Lösung?
Ein Zähler reicht aus. Und den nimmst du dann gleich als Basis für einen 
Multiplexer, der diese Bits auf den Ausgang durchschaltet...

: Bearbeitet durch Moderator
von Gustl B. (-gb-)


Lesenswert?

Also bei einem Datenstrom übertrage ich viele bytes aber bei jedem byte 
ist das letzte bit reserviert. Ist das das erste byte in einem Paket so 
ist das bit 1 und bei allen weiteren bytes im Paket 0. also kostet zwar 
Datenrate aber funktioniert super.

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


Lesenswert?

Gustl B. schrieb:
> Ist das das erste byte in einem Paket so ist das bit 1 und bei allen
> weiteren bytes im Paket 0. also kostet zwar Datenrate aber funktioniert
> super.
Es funktioniert aber auch nur dann, wenn du weißt, welches das "erste" 
Bit ist. Du brauchst also noch einen weiteren 
Synchronisationsmechanismus, der anzeigt, wo denn so ein Datenwort 
anfängt.
Bei der RS232 z.B. muss mindestens einmal eine Pause von mindestens 
einem ganzen Byte eingelegt werden, sonst hast du ständig falsch 
empfangene Bytes zusammen mit irgendwelchen Framing- oder 
Parity-Fehlern...

von Gustl B. (-gb-)


Lesenswert?

Ach so, ja. Also ich habe das nur um Pakete aus mehreren Byte zu 
erkennen. Übertragen wird das über UART oder parallel FIFO da ist immer 
klar wo ein Byte anfängt und wo es endet.
Also ich verstehe nicht wieso hier nicht auch einfach UART oder so 
genommen wird. Kann man ja schneller laufen lassen als Daten nachkommen 
und hat so eitwas Pausezeiten dazwischen.

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.