Forum: FPGA, VHDL & Co. Eingang abtasten und per Uart ausgeben


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mario (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,

ich hoffe, jemand kann mir helfen, da ich gerade etwas verzweifele. Bin 
recht noch am Anfang mit VHDL. Folgender Sachverhalt:
Verwende Basys3 mit 100 Mhz Clk.

Ich möchte gerne ein Eingang mit 1Mhz takt abtasten und diesen Wert per 
Uart ausgeben. Ich möchte aber per Uart die binäre zahl des Counters 
ausgeben.

Dazu 3 Prozesse:

1. Prozess 100Mhz auf 1 Mhz runtertakten
2. Prozess Wenn Eingang = 1, dann zähle Counter hoch
3. Prozess Wenn Eingang wieder auf 0 dann übertrage die Daten per Uart:

Um es relativ kurz zu halten, hier ein Auszug des Codes:
1
entity UART_TX_CTRL is
2
    Port ( --SEND : in  STD_LOGIC;
3
           --DATA : in  STD_LOGIC_VECTOR (7 downto 0);
4
           SAMPLEINPUT: in std_logic:='0';
5
           CLK : in  STD_LOGIC;
6
           READY : out  STD_LOGIC;
7
           UART_TX : out  STD_LOGIC);
8
end UART_TX_CTRL;
9
10
11
12
signal DATA_BYTE_20 :  STD_LOGIC_VECTOR (7 downto 0):=(others => '0');
13
signal DATA_BYTE_19 :  STD_LOGIC_VECTOR (7 DOWNTO 0):= (others => '0');
14
signal DATA_BYTE_18 :  STD_LOGIC_VECTOR (7 downto 0):= (others => '0');
15
signal DATA_BYTE_17 :  STD_LOGIC_VECTOR (7 downto 0):= (others => '0');
16
...
17
18
signal TRIGGER_SAMPLE:      std_logic := '0';
19
signal TRIGGER_DATAOUTPUT: std_logic :='0';
20
signal cnt_100Mhz: integer range 0 to 100000000:=0;
21
signal CNT_1Mhz: integer range 0 to 100000:=0;
22
signal CLOCK_1Mhz: std_logic := '0';
23
signal SEND :     STD_LOGIC;
24
begin
25
26
Mhz_takt_process: process (CLK)
27
begin
28
    if (rising_edge(CLK)) then
29
        if  CNT_1Mhz = 5000 then
30
            CLOCK_1Mhz<= not CLOCK_1Mhz;
31
            CNT_1Mhz <= 0;
32
        else 
33
            CNT_1Mhz <=   CNT_1Mhz +1;
34
        end if;
35
    end if;
36
end process;
37
38
39
data_sample_process: process (CLOCK_1Mhz)
40
begin
41
42
    if rising_edge (CLOCK_1Mhz) then
43
        if (TRIGGER_DATAOUTPUT = '0') AND (TRIGGER_SAMPLE  ='0') then
44
            if SAMPLEINPUT = '1' then
45
                SAMPLE_DATA_cnt <= SAMPLE_DATA_cnt +1;
46
                TRIGGER_SAMPLE <='1';
47
                TRIGGER_DATAOUTPUT <='0';
48
            else    
49
                SAMPLE_DATA_cnt <= SAMPLE_DATA_cnt;
50
                TRIGGER_DATAOUTPUT <='1'; 
51
                TRIGGER_SAMPLE <='0';   
52
            end if;
53
        end if;
54
    end if;
55
end process;
56
57
58
data_outpout_process : process (CLK)
59
begin
60
 
61
       if (TRIGGER_DATAOUTPUT = '1') AND (TRIGGER_SAMPLE  ='0') then
62
        if  cnt_100Mhz = 500 then
63
            DATA_BYTE_20    <= "0011000" & SAMPLE_DATA_cnt(20);
64
            DATA_BYTE_19    <= "0011000" & SAMPLE_DATA_cnt(19);
65
            DATA_BYTE_18    <= "0011000" & SAMPLE_DATA_cnt(18);
66
            DATA_BYTE_17    <= "0011000" & SAMPLE_DATA_cnt(17);
67
       ......
68
        elsif cnt_100Mhz =  104171  then
69
            DATA <=  DATA_BYTE_20;
70
            SEND <= '1';
71
            cnt_100Mhz <= cnt_100Mhz+1;

Ich bekomme den Fehler dass, SAMPLE_DATA_cnt mehrmals gleichzeitig 
verwendet wird. Mir ist auch klar, dass VHDL alles gelichzeitg ausführt 
und mein Siganl in zwei Prozessen auftaucht und er deswegen streikt.

Aber ich komme auch nicht auf die Lösung wie ich es hintereinadner 
ausführe?

Für Hilfe wäre ich dankbar.

Danke & Gruß
Mario

von --- (Gast)


Bewertung
0 lesenswert
nicht lesenswert
1
            ...
2
            else    
3
                SAMPLE_DATA_cnt <= SAMPLE_DATA_cnt;
4
            ...

ist ja auch Kaese.

Du musst die Funktion beschreiben und nicht programmieren!

von Duke Scarring (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Mario schrieb:
> 1. Prozess 100Mhz auf 1 Mhz runtertakten
Auf FPGA ist es besser ein clk_enable zu erzeugen. Damit läuft das 
komplette Design mit einem Takt (dem schnellsten) und es kann kein 
Clock-Domain-Crossing (CDC) geben.

Duke

von Mario (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Danke für die Antworten, leider komme ich nicht weiter. Könnte mir 
jemand ein Tipp geben, was ich an welcher Stelle umbbauen muss.

Bezüglich der Clock: Wenn ich mir in Vivado ein 1 Mhz Clock aus dem 
Clockwizzard generien will bekomme ich immer ein verilog modul und kein 
VHDL modul...


Für Hilfen wäre ich sehr dankbar.

Danke & Gruß
Mario

von --- (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das ganze braucht nur 1 Prozess mit dem 100 MHz Clock und dem
Eingangssignal in der Sensitivy List.

Der Rest folgt daraus...

von Schlumpf (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist eher, dass du ganz offensichtlich keine wirkliche 
Vorstellung von dem Thema PFGA und VHDL hast. (meine es nicht böse)

Man könnte dir jetzt einen Code posten, der tut, was du willst, aber das 
bringt dich dann halt nicht weiter.

Oder man müsste dir einige Grundlagen erklären, was den Rahmen hier 
sprengen würde.

Aber paar Stichworte:

1. Verwende, wenn es irgendwie geht, im Design nur einen einzigen Takt 
(z.B. 100 MHz). Und "enable" damit alle weiteren Aktionen.

Also Takte deine Sample-Einheit mit 100 MHz, aber sample immer nur jeden 
100sten Takt. Damit schließt du die o.g. CDC-Probleme aus.

2. Signale dürfen immer nur innerhalb eines Prozess verändert werden. 
Dürfen aber selbstverständlich in beliebig vielen Prozessen "gelesen" 
werden. Wie da eben in echter Hardware so ist: Ein Signal kann nur eine 
Quelle, aber mehrere Senken haben.

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Mario schrieb:
> if (rising_edge(CLK)) then
>         if  CNT_1Mhz = 5000 then
>             CLOCK_1Mhz<= not CLOCK_1Mhz;
>             CNT_1Mhz <= 0;
Zwei Klassiker:
1. So werden keine Takte erzeugt. Überhaupt hat ein Anfängerdesign nur 
1einzigen Takt. Der Rest wird mit Clock-Enables gemacht.
2. Der Off-by-one Fehler. Der Zähler zählt 5001 Takte, weil 0 auf 1 auch 
schon einen Takt braucht.

Mario schrieb:
> data_outpout_process : process (CLK)
Diese Sensitivliste ist unvollständig. Die Simulation wird nicht zur 
Realität passen, denn die Sensitivliste ist nur für die Simulation 
interessant.
Oder andersrum: der Synthesizer schert sich einen feuchten Kehrricht um 
diese Liste. Er sagt dir bestenfalls, dass er die fehlenden Signale 
automatisch aufgenommen hat.

Und wenn er das getan hat, dann wirds extrem kritisch, denn dann taucht 
wegen dieses Prozesses alles auf, was man falsch machen kann:
- asynchroner kombinatorischer Reset mitsamt  Glitches (wenn da 
tatsächlich ein Takt drin auftauchen sollte).
- kombinatorische Schleifen
- Latches
Such zu diesrn Stichworten einfach mal hier im Forum. Du bist nicht der 
Erste, der diese Fehler macht. Allerdings ist es durchaus eine Leistung, 
alle in 1 Prozess zu machen... ?

: Bearbeitet durch Moderator

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.