Forum: FPGA, VHDL & Co. Seriell Parallel Wandeln mit einem Asynchronen Dateneingang


von Fabian Z. (fabi_z)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe eine digitales Eingangssignal (Data_in) welches asynchron 
eingespeist wird. Dieses Eingangssignal habe ich zuerst 
Einsynchronisiert für eine Flankenerkennung. Das Eingangssignal hat High 
und Lowpegel mit 2 und 4 MHz. Anschließend wollte ich dieses Signal 
welches seriell ist, parallel wandeln. Jedoch schaffe ich es nicht 
parallel auszugeben. Mein Code ist hier:

1
Startup: Process(CLK,Data_in)
2
    begin
3
        if rising_edge(CLK) then
4
            Data_In_Sync  <= Data_In_Sync(1 downto 0) & Data_in;
5
        end if; 
6
    end Process Startup;
7
8
Shift: Process(CLK)
9
    begin
10
         if rising_edge(CLK) then
11
              
12
              if (Data_In_Sync(2 downto 1) = "01") then 
13
                     enable <= '1';
14
                     Data_Buffer(15 downto 0) <= Data_Buffer(14 downto 0) & Data_In_Sync(0);  
15
              elsif (Data_In_Sync(2 downto 1) = "10") then 
16
                     Data_Buffer(15 downto 0) <= Data_Buffer(14 downto 0) & Data_In_Sync(0); 
17
                     enable <= '0';                  
18
              end if;    
19
                
20
         end if; 
21
     end Process Shift;
22
23
      
24
SIPO: Process(CLK)
25
     begin
26
     if rising_edge(CLK) then
27
            if enable = '1' then 
28
            if Data_Buffer = "0100110100110011" then
29
                 Data_out <= '0';
30
                 Sync_out <= '0';
31
                 Data_Buffer <= "0000000000000000";                     
32
             elsif Data_Buffer = "0100110100110101" then
33
                 Data_out <= '1';
34
                 Sync_out <= '0';
35
                 Data_Buffer <= "0000000000000000";
36
             elsif Data_Buffer = "0100110101010011" then
37
                 Data_out <= '1';
38
                 Sync_out <= '1';
39
                 Data_Buffer <= "0000000000000000";
40
                 end if;
41
                 end if;
42
             end if;
43
     end Process SIPO;
44
                                                  
45
46
end Behavioral;

Das zweite Problem welches ich habe, ist das von meinem Eingangssignal 
(Data_in) zum Beispiel irgendein high Pegel 500ns breit ist. Nach dem 
einsynchronisieren aber nicht mehr, da ja hart auf die steigende Flanke 
des Clks getriggert wird. Wie kann ich das bewerkstelligen das dass 
einsynchronisierte Signal bei dem erwähnten high Pegel auch die 500ns 
hat und nicht um 2.5ns verringert wird?

Grüße und vielen Dank euch

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


Lesenswert?

Fabian Z. schrieb:
> Wie kann ich das bewerkstelligen das dass einsynchronisierte Signal bei
> dem erwähnten high Pegel auch die 500ns hat
Warum ist es nötig, dass es hinterher auch noch 500ns hat?

> Das Eingangssignal hat High und Lowpegel mit 2 und 4 MHz.
?
Kannst du das mal aufzeichnen und posten?
Oder du könntest sagen woher das Signal kommt, evtl. findet man dann 
eine Doku zum Protokoll.
Oder ist das eine übliche NRZ Codierung, wo der Takt zusammen mit den 
Daten übertragen wird?

: Bearbeitet durch Moderator
von Amateur (Gast)


Lesenswert?

Ist Dein Weg der richtige?
Üblicherweise sind die Daten eines seriellen Signales, relativ zur 
"eigenen" Frequenz oder zu einem externen Träger.
Eine "Einsynchronisierung" - was auch immer das heißt - kann ja nur zu 
"Deiner" Frequenz - einer anderen Frequenz wie das Eingangssignal - 
erfolgen.
Da sind üblicherweise die Daten futsch. Ausnahme, Du kannst mit vielfach 
höherer Frequenz abtasten.

von Fabian Z. (fabi_z)


Lesenswert?

Lothar M. schrieb:
> Fabian Z. schrieb:
>> Wie kann ich das bewerkstelligen das dass einsynchronisierte Signal bei
>> dem erwähnten high Pegel auch die 500ns hat
> Warum ist es nötig, dass es hinterher auch noch 500ns hat?

Hm ich hatte Angst das mir irgendwann das Signal wegläuft. Über lange 
Zeit gedacht.

>
>> Das Eingangssignal hat High und Lowpegel mit 2 und 4 MHz.
> ?
> Kannst du das mal aufzeichnen und posten?
> Oder du könntest sagen woher das Signal kommt, evtl. findet man dann
> eine Doku zum Protokoll.
> Oder ist das eine übliche NRZ Codierung, wo der Takt zusammen mit den
> Daten übertragen wird?

Als Eingangsfolge kommt sowas von einem Messgerät: 
100110100110011011100100110101010011010011010011010101001101001101010100 
11010011001101001101001100110100110100110011010011  Die ersten 16 sind 
Synchronisationsbits dann folgen 288 Datenbits gefolgt wieder von 16 
Synchronisationsbits.  Dieses will ich auswerten. Man kann die 
Datenfolge auch im Bild (Simulation) oben sehen. Data_in ist die 
Eingangsfolge vom Messgerät. Ich glaube das geht auch wie ich es oben 
versucht habe, jedoch ist das Problem das dass hineinschieben klappt 
aber das erkennen  mit

if Data_Buffer = "0100110100110011“ then

usw.

nicht.

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


Lesenswert?

Fabian Z. schrieb:
> Hm ich hatte Angst das mir irgendwann das Signal wegläuft. Über lange
> Zeit gedacht.
Natürlich, das wird passieren, wenn du den Empfang nicht zwischendurch 
wieder auf die Flanken synchronisierst.
Das ist ein NRZ Signal wie beim RC5 Code. Und so ein Signal bringt mit 
jedem Datenbit einen Taktflanke zur Synchronisation mit. Meine 
Implementierung dort kann Frequenabweichungen bin zu 25% kompensieren:
http://www.lothar-miller.de/s9y/categories/50-RC-5

> Man kann die Datenfolge auch im Bild (Simulation) oben sehen.
Diese da eingelesene Reihenfolge ist Zufall. Sie hängt  extrem von den 
Samplingzeitpunkten ab. Es klappt zwar irgendwie in der Simulation, weil 
du da ein festes und starres, immer gleich wiederkehrendes Bitmuster 
hast, es wird aber garantiert in der Realität nicht zuverlässig 
funktionieren, wenn du das einfach als Bitstrom einliest und mit einem 
festen Wert vergleichst.

: Bearbeitet durch Moderator
von Fabian Z. (fabi_z)


Lesenswert?

Ok super, ich habe mal in deinen Code hineingeschaut und meinen daran 
angepasst. Jetzt wollte ich mal einen Simulation Langzeittest machen ob 
mir da was wegläuft. Jedoch mache ich in der Testbench was mit der 
for-Schleife falsch. Da ich zu Faul war die Bitkette immer wieder zu 
kopieren wollte ich diese mit einer Schleife immer und immer wieder neu 
einlesen. Geht aber irgendwie nicht. Was mache ich da den falsch?

1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
LIBRARY ieee;
4
USE ieee.std_logic_1164.ALL;
5
6
7
entity testbench is
8
--  Port ( );
9
end testbench;
10
11
architecture Behavioral of testbench is
12
13
COMPONENT  Demod is
14
    Port ( CLK : in STD_LOGIC;
15
           Data_in : in STD_LOGIC;
16
17
    END COMPONENT;
18
19
    SIGNAL clk,data_in  :   STD_LOGIC := '0';
20
    
21
    SIGNAL  i           : INTEGER :=0;
22
 
23
    SIGNAL buf : STD_LOGIC_VECTOR(0 to 208) := "11010011010101001101001100110111001001101010100110100110100110101010011010011010101001101001100110100110100110011010011010011001101001101001100110100110100110101010011010011010101001101001100110100110101010011";
24
25
begin
26
    DUT : Demod 
27
    PORT MAP(
28
    CLK=>clk, 
29
    Data_in => Data_in,
30
31
    clk_data_in <= not clk_data_in after 125ns;
32
33
process
34
             for i in 0 to 208 loop
35
                wait for  25ns;
36
                     data_in <= buf(i);
37
                END loop;
38
end process;
39
40
         clk <= not clk after 5000ps;
41
         
42
end Behavioral;

: Bearbeitet durch User
von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

Es wäre schön, wenn Du compilierbaren Code einstellst:
1
$ vcom tb.vhd
2
3
Model Technology ModelSim SE-64 vcom 10.6c Compiler 2017.07 Jul 26 2017
4
-- Loading package STANDARD
5
-- Loading package TEXTIO
6
-- Loading package std_logic_1164
7
-- Compiling entity testbench
8
-- Compiling architecture Behavioral of testbench
9
###### tb.vhd(17):     END COMPONENT;
10
** Error: tb.vhd(17): near "END": (vcom-1576) expecting IDENTIFIER.
11
###### tb.vhd(19):     SIGNAL clk,data_in  :   STD_LOGIC := '0';
12
** Error: tb.vhd(19): (vcom-1294) Declaration with designator "clk" already exists in this region.
13
** =====> Prior declaration of "CLK" is at tb.vhd(14).
14
** Error: tb.vhd(19): (vcom-1294) Declaration with designator "data_in" already exists in this region.
15
** =====> Prior declaration of "Data_in" is at tb.vhd(15).
16
###### tb.vhd(31):     clk_data_in <= not clk_data_in after 125ns;
17
** Error: tb.vhd(31): (vcom-1136) Unknown identifier "clk_data_in".
18
** Error: tb.vhd(31): (vcom-1136) Unknown identifier "clk_data_in".
19
** Error: tb.vhd(31): ** Error: (vcom-1590) Bad expression in right operand of infix expression '<='.
20
** Error: tb.vhd(31): near "after": (vcom-1576) expecting ',' or ')'.
21
** Warning: tb.vhd(31): (vcom-1207) An abstract literal and an identifier must have a separator between them.
22
###### tb.vhd(34):              for i in 0 to 208 loop
23
** Error: tb.vhd(34): near "in": (vcom-1576) expecting ':'.
24
###### tb.vhd(35):                 wait for  25ns;
25
** Warning: tb.vhd(35): (vcom-1207) An abstract literal and an identifier must have a separator between them.
26
End time: 07:32:57 on May 31,2018, Elapsed time: 0:00:00
27
Errors: 8, Warnings: 2

Nach Behebung aller syntaktischen Fehler läuft die Simulation.
Welche Signalform hattest Du erwartet?

Duke

von A. F. (chefdesigner)


Lesenswert?

Könnte mir bitte jemand den Sinn einer bedingten 
Serien-Parallel-Wandlung verdeutlichen?

Warum wird nur bei der Flanke weitergeschoben?
1
              if (Data_In_Sync(2 downto 1) = "01") then 
2
                     enable <= '1';
3
                     Data_Buffer(15 downto 0) <= Data_Buffer(14 downto 0) & Data_In_Sync(0);  
4
              elsif (Data_In_Sync(2 downto 1) = "10") then 
5
                     Data_Buffer(15 downto 0) <= Data_Buffer(14 downto 0) & Data_In_Sync(0); 
6
                     enable <= '0';                  
7
              end if;

von A. F. (chefdesigner)


Lesenswert?

Keiner?

von Gustl B. (-gb-)


Lesenswert?

Wann soll denn sonst weitergeschoben werden?

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


Lesenswert?

Andreas F. schrieb:
> Warum wird nur bei der Flanke weitergeschoben?
Sinnvollerweise wird sogar nur bei der jeweils gleichen Flanke 
geschoben. Sonst hättest du ein Double Data Rate (DDR) Design  wo sich 
mit jeder Taktflanke was ändert. Und das macht die Sache nicht 
einfacher...

von Weltbester FPGA-Pongo (Gast)


Lesenswert?

Lothar M. schrieb:
> Sinnvollerweise wird sogar nur bei der jeweils gleichen Flanke
> geschoben.
Das unübersichtliche hier ist das Weiterschalten der Eingangsdaten in 
der Bedingungsabfrage. Die gehört nach draußen, da sie eh läuft. Dann:

der TE sollte sich mal fragen, ob er alle Fälle abgefangen hat und wie 
man so etwas geschickter in eine TB versetzt.

Aber mal was anderes:

Duke Scarring schrieb:
> Es wäre schön, wenn Du compilierbaren Code einstellst:$ vcom tb.vhd
"einstelltest" (Konjunktiv Präsens)

> Model Technology ModelSim SE-64 vcom 10.6c Compiler 2017.07 Jul 26 2017
Ist die 10.6 die aktuelle Version vom SE?
Wenn ich das richtig lese, ist letzten Monat abgelaufen - was kostet 
denn aktuell eine Lizenz vom SE?

Mein AG spendiert leider nur die DE, vormalige PE.

von Duke Scarring (Gast)


Lesenswert?

Weltbester FPGA-Pongo schrieb im Beitrag #5574655:
>> Model Technology ModelSim SE-64 vcom 10.6c Compiler 2017.07 Jul 26 2017
> Ist die 10.6 die aktuelle Version vom SE?
> Wenn ich das richtig lese, ist letzten Monat abgelaufen - was kostet
> denn aktuell eine Lizenz vom SE?
Aktuell ist 10.7c. Aber seit Jahren sind da für mich keine nennenswerten 
Features hinzugekommen, wie z.B. die Unterstützung für SystemVerilog.

Außerdem darf man dann sicher wieder den Lizenzserver updaten und ggf. 
das System auf dem dieser läuft gleich dazu.
Der Academicpreis (pro Jahr) liegt in der Höhe eines mittleren 
FPGA-Evalboards.

Duke

von Weltbester FPGA-Pongo (Gast)


Lesenswert?

D.h. du bist an einem Institut tätig und kannst den zu den Konditionen 
bekommen? Wir haben zuletzt für den DE noch 5 stellig bezahlt!

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.