Forum: FPGA, VHDL & Co. RS232 Daten Empfangen, Vergleichen, auf Monitor ausgeben (SPARTAN 3)


von nico (Gast)


Lesenswert?

Guten Tag,

ich stehe mit meiner Arbeitsgruppe vor einem Problem zu welchem wir 
einfach keine Lösung finden, es geht um folgendes:

Es sollen von einem PC im Terminalbetrieb Zeichen (ASCII) gesendet und 
mit dem FPGA empfangen werden. Hier sollen sie abgetastet und 
identifiziert werden und über eine VGA Schnittstelle auf einem zweiten 
Monitor ausgegeben werden.

Die Problematik mit der wir uns momentan beschäftigen ist die, dass wir 
(noch in der Simulation) uns ein Signal via Testbench erzeugen (ASCII e 
mit negativ Logic) und dies erstmal mit einem statischen Vektor, welcher 
die Zeichenfolge eines e's in ASCII enthält vergleichen. Stimmt dieser 
Vergleich wird unser Ausgangssignal auf '1' gesetzt, falls nicht '0'. 
Das dient lediglich zur überprüfung. All das geschieht in einem Prozess. 
Abhängig ist dieser von einem Internen Signal, welche bei Steigender 
Flanke des Datensignals (jedes ASCII mit neg Logik fängt auf Grund eines 
gesetzten Stopbits mit einer steigenden Flanke an) auf '1' gesetzt wird 
und so lange '1' bleibt  bis der Vergleich von Vektor und Datensignal 
vollzogen ist. Das Zurücksetzen funktioniert allerdings nicht. Es ist 
möglich, dass unser Denkansatz der Falsche ist, aber wir sind nicht 
besonders bewandert was VHDL angeht.

Problematisch ist, dass das Schreiben des Datensignals, in einen Vektor 
zum vergleichen, Clockflanken gesteuert ist und des Setzen des internen 
Signals von Datensignalflanke abhängig ist.

Wir haben 3 Prozesse:
1.Clockteilung
2.Abtastung und Vergleich (vom geteiltenClock abhängig)
3.Setzen des internen Signals

Wie schon geschildert  verwenden wir das in 3. auf 1 gesetzte Signal in 
2. und setzen es nach Abtastung und Vergleich auch in 2. wieder auf 0. 
Jedenfalls ist das die Idee, welche aber leider nicht funktioniert.

von Alexander S. (alexanders)


Lesenswert?

Hallo,

ich bin zwar selbst noch im VHDL lernen, aber ich versuche mich mal.

Ich finde den Ansatz recht kompliziert und sehe den Sinn dahinter nicht 
ganz.

Ihr braucht meiner Meinung nach später mal folgendes:

UART-RECIEVER -> Speicherelement -> Buchstabenvergleich -> ASCII to VGA 
- Wandler + VGA-Timing -> Monitor

Ich würde erst einmal etwas in VHDL einzusteigen, z.B. mit dem 
VGA-Timing.

Die textuelle Beschreibung eures Codes ist wenig zielführend. Bitte 
ladet das dazugehörige VHDL File hoch.

Gruß

Alexander S.

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


Lesenswert?

nico schrieb:
> Die Problematik mit der wir uns momentan beschäftigen ist die, dass wir
> (noch in der Simulation) uns ein Signal via Testbench erzeugen
Das können bestenfalls ein paar Zeilen sein...
> (ASCII e mit negativ Logic)
Positive oder negative Logik, diese Blockade exixsiert nur im Kopf...

> Das Zurücksetzen funktioniert allerdings nicht.
Warum nicht?
> Wir haben 3 Prozesse:
> 1.Clockteilung
Hoppala, das fängt schon gut an...
> 2.Abtastung und Vergleich (vom geteiltenClock abhängig)
Was wird abgetastet und verglichen?
> 3.Setzen des internen Signals
Sieht nach einem umständlichen Konzept aus. Hast du da mal eine 
VHDL-Datei dazu? Kannst du die hier einfach als *.vhd (oder *.vhdl) 
anhängen?

BTW: sieh dir mal meine serielle Schnitte an, evtl. kommt dann Licht ins 
Dunkel...
http://www.lothar-miller.de/s9y/categories/49-RS232-IO
http://www.lothar-miller.de/s9y/categories/42-RS232

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Ich habe mal eine Uart to VGA geschrieben. Das ist schon etwas 
aufwendig.
Und braucht etwas internen Speicher.
Wenn du einen UART zum Senden hast würde ich die INFO auch zu Uart 
wieder raussenden. Hast ja schon alle Kabel dran.

Wie  das Timing für einen VGA-Monitor in VHDL aus sieht habe ich auf 
meiner Homepage. Auch mit Simulation testbench.

http://www.dossmatik.de/vhdl.html

von Alexander S. (alexanders)


Lesenswert?

Hallo,

folgende Datei ist mir gerade in die Hände gefallen. Da wird ein Teil 
eures Komplexes ganz gut beschrieben.

http://e21.frm2.tum.de/fileadmin/user_upload/documents/lectures/epraktikum/kapitel13.pdf

Gruß

: Bearbeitet durch User
von Weltbester FPGA-Pongo (Gast)


Lesenswert?

Woran doch die TUM so alles arbeitet ... :-)

Ich würde mich erst mal an einen funktionierenden UART machen, was nicht 
so schwer ist, wenn man FSMs schreiben kann. Davon habe ich nämlich noch 
nichts gelesen.

Was eure Arbeitsgruppe dann noch braucht ist ein Verständnis für das 
dynamische Speichern von Daten. Die gewonnenen Zeichen kommen ja 
irgendwann mit irgendeinem Takt asynchron rein, müssen plausibilisiert 
und gfs ge-CRC-t werden. Erst, wenn die Zeichen aus dem Bitstrom 
extrahiert wurden, kann man sie in einen Zeichenspeicher schreiben.

Darauf basierend braucht es einen Process, der die Zeichen managed und 
die letzten, sagen wir 128 an einen Bildspeicher übergibt, was für mich 
ein BRAM ist.

Dann gibt es einen davon unabhängigen Takt, der permament das BRAM 
ausliest, den Zeichen-Code an einen Zeichengenerator gibt, welcher 
ermittelt, ob der jeweils anliegende Videopunkt X,Y an sein muss oder 
aus, was durch Komparatoren geschieht.

Solche Projekte gibt es auf open cores zu Hauf, allerdings ist keines 
ordentlich dokumentiert, funktioniert fehlerfrei oder wäre direkt 
einsetzbar.

von nico (Gast)


Angehängte Dateien:

Lesenswert?

Also abgetastet wird das RS232 Signal, da diese Schnittstelle keinen 
eigenen Takt hat, müssen wir den internen 50Mhz Takt des Boards 
runterteilen auf eine Baudrate von 9600.
Wichtig ist bei uns, dass wir das ankommende Signal abtasten, was 
inzwischen auch funktioniert. Das Problem war/ist dass nach der 1. 
Flanke des Signals unser Prozess nicht wieder anspringen darf. Das 
versuchten wir mit einem Internen Signal zu machen, was gesetzt wird, 
wenn der Prozess arbeitet und nach erfolgreichem Abtasten wieder auf 0 
geht. ich hänge mal unseren code (der einige Testsignale aufweist) an 
diese Nachricht an.

Prinzipiell funktioniert das ganze schon, nur das Reseten macht noch ein 
paar Probleme. Momentan versuchen wir das zulösen um dann das 
eingelesenen ASCII Zeichen auf einem Bildschirm und einer 7 
Segmentanzeige auszugeben.

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


Lesenswert?

nico schrieb:
> Das Problem war/ist dass nach der 1. Flanke des Signals unser Prozess
> nicht wieder anspringen darf.
Ein Prozess "springt" nicht an.
Der wird umgesetzt in richtige echte reale immer vorhandene Hardware! 
Und wenn die falsch beschrieben ist, dann reagiert sie eben auch auf 
andere Signalwechsel als die gewünschten...

> ... wenn der Prozess arbeitet
Der Prozess arbeitet immer.

nico schrieb:
> Prinzipiell funktioniert das ganze schon
Wo funktioniert das?
1
CheckProcRun : process (RxData,setProcRun,Rst)
2
begin
3
   if setProcRun = '0' then
4
    blatest3 <= '0';
5
     ProcRun <= '0';
6
  elsif setProcRun = '1' then
7
     blatest3 <= '1';
8
     ProcRun <= '1';
9
  end if;
10
  
11
  if rising_edge(RxData) then
12
    blatest3 <= '1';
13
     ProcRun <= '1';
14
  end if;
15
  
16
  if rising_edge(Rst) then
17
    blatest3 <= '0';
18
     ProcRun <= '0';
19
  end if;
20
end process CheckProcRun;
Hut ab. Das wird sicher nie zuverlässig in Hardware umgesetzt werden 
können. Was hier steht, ist ein Flipflop namens "ProcRun", das von zwei 
Taktquellen (Rst und RxData) angesteuert wird und zudem über eine 
Kombinatorik noch als Latch arbeiten soll.
So ein Bauteil habe ich noch niemals nirgendwo gesehen.
1
   if setProcRun = '0' then
2
    blatest3 <= '0';
3
     ProcRun <= '0';
4
  elsif setProcRun = '1' then
5
     blatest3 <= '1';
6
     ProcRun <= '1';
7
  end if;
Ich würde diese 7 Zeilen so schreiben (ungeachtet davon, dass dieser 
Prozess wie schon beschrieben sowieso nicht sauber funktioniert):
1
     blatest3 <= setProcRun; 
2
     ProcRun <= setProcRun;

Kreuze die zutreffende Antwort an:
Ich habe die Antworten in den obigen Posts
[ ] nicht gelesen
[ ] nicht verstanden

Mein Tipp: such im Forum hier mal nach Postulate und denk drüber nach.
Beitrag "vhdl-richtlinien f. synthese?"
Insbesondere über das erste Postulat, das jedes Anfängerdesign genau 1 
Takt hat. Und selbst ein Profi versucht möglichst nahe an diese Zahl zu 
kommen. Denn genau dann minimiert sich die Anzahl der Probleme mit 
asynchronen Taktdomänen.

: Bearbeitet durch Moderator
von greg (Gast)


Lesenswert?

nico schrieb:
> Also abgetastet wird das RS232 Signal, da diese Schnittstelle keinen
> eigenen Takt hat, müssen wir den internen 50Mhz Takt des Boards
> runterteilen auf eine Baudrate von 9600.

Das klappt so nicht (zuverlässig). Du musst überabtasten (üblich ist 
16x) oder die Flanke des Startbits erkennen und dann auf jeden Fall 
richtig verzögern, um sicher in der Mitte der Bitzeit abzutasten.

Du versuchst irgendwie eine state machine umständlich von hinten durch 
die Brust ins Auge zu implementieren. Guck dir doch mal ein paar gute 
Beispiele für state machines an.

Außerdem: bitte nicht std_logic_unsigned verwenden. Das ist nicht 
standardisiert und unsauber. Stattdessen nimm lieber numeric_std.

Ich bin zwar auch ein VHDL-Anfänger, aber dein Code sieht mir danach 
aus, als müsstest du dich ganz von vorne angefangen mit den Basics 
beschäftigen.

von nico (Gast)


Lesenswert?

Weltbester FPGA-Pongo schrieb im Beitrag #3478824:
> Woran doch die TUM so alles arbeitet ... :-)

Was soll das bitte heißen? TU München? Tut mir leid aber ich studiere 
nicht in München.


> Ein Prozess "springt" nicht an.
> Der wird umgesetzt in richtige echte reale immer vorhandene Hardware!
> Und wenn die falsch beschrieben ist, dann reagiert sie eben auch auf

ich entschuldige mich für meine mehr als unkorrekte Ausdrucksweise. 
Meine Kenntnisse in VHDL und Hardware Beschreibung sind sehr begrenzt, 
ich hab mein Wissen aus meiner Vorlesung und wurde dann vor dieses 
Projekt gesetzt.


> Hut ab. Das wird sicher nie zuverlässig in Hardware umgesetzt werden
> können. Was hier steht, ist ein Flipflop namens "ProcRun", das von zwei
> Taktquellen (Rst und RxData) angesteuert wird und zudem über eine
> Kombinatorik noch als Latch arbeiten soll.

Das habe ich noch nie so betrachtet. Leider versteh ich auch nicht alle 
deine Aussagen.


> Kreuze die zutreffende Antwort an:
> Ich habe die Antworten in den obigen Posts
> [ ] nicht gelesen
> [ ] nicht verstanden

Ich hab das sehr wohl gelesen, zwar nicht durchweg verstanden, aber 
gelesen. Es ist nicht einfach für uns das zu verstehen. Ich hab leider 
auch nicht die Zeit für das Projekt, die ich mir gerne nehmen würde. Wir 
versuchen das mit unserem Wissen zu lösen und ich dachte vielleicht 
bekomme ich hier einige Tips. Leider muss ich sagen, dass ich mir durch 
sowas sehr dumm vorkomme und ich sowas sehr unpassend ist.

Nun zu den Neuigkeiten:

Ich hab zur Kenntnis genommen, dass unsere Art der Beschreibung wohl 
wenig sinnvoll ist und wahrscheinlich nicht zum best möglichen Ergebnis 
führen wird. Momentan funktioniert es soweit, dass das empfangene 
Zeichen auf den LED's (des Boards) richtig angezeigt werden kann und wir 
können das Zeichen auf der 7 Segmentanzeige des Boards ausgeben.
Ich muss gestehen, dass mein gefährliches Halbwissen nicht ausreicht um 
auch nur einen der Posts hier zu 100% nachvollziehen zu können, aber das 
liegt leider an mir. Ich werde die Tage nochmal meinen Code posten, so 
wie er momentan aussieht und erklären, was wir uns dabei denken. Ich bin 
natürlich dankbar für die bisherige Hilfe.

von Alexander S. (alexanders)


Lesenswert?

Die TU München hat an dem Link 
(http://e21.frm2.tum.de/fileadmin/user_upload/documents/lectures/epraktikum/kapitel13.pdf) 
gearbeitet den ich gepostet habe.

Dort wird, wie bereits oben erwähnt, die grundlegende Umsetzung 
besprochen.

Du kannst gerne deinen Code posten und sicherlich findet sich die ein 
oder andere Seele die diesen reflektiert doch du solltest darüber 
nachdenken, ob deine Herangehensweise an so ein Projekt die Richtige 
ist.

Auch wenn du unter Zeitdruck stehst, Try und Error dauert bei einem 
Design dieser Größenordnung mindestens genauso lange, wie Grundlagen 
aneignen und dann richtig designen (und das sage ich sogar aus 
Erfahrung).

Die etwas bissigen Kommentare kommen vermutlich daher, dass jede Woche 
mindestens eine Person auftaucht, die mal schnell etwas in VHDL machen 
möchte.

Gruß

Alexander S.

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


Lesenswert?

nico schrieb:
> Leider muss ich sagen, dass ich mir durch sowas sehr dumm vorkomme und
> ich sowas sehr unpassend ist.
???
Wie auch immer: wenn du eine Frage stellst dann musst du mit der Antwort 
leben. Und wenn die nicht so weichgespült ausfällt, wie du dir das 
vorstellst, kann ich nichts ändern. Ich kenne deine Vorstellungen nicht. 
Du brauchst für Unwissenheit aber auch nicht um Entschuldigung bitten. 
Denn da gibt es nichts zu entschuldigen, sondern du musst einfach mehr 
üben und dadurch lernen...

> Ich hab zur Kenntnis genommen, dass unsere Art der Beschreibung wohl
> wenig sinnvoll ist und wahrscheinlich nicht zum best möglichen Ergebnis
> führen wird
Und du hast sie dann auch geändert, denn du schreibst:
> Momentan funktioniert es soweit
Aber sicher nicht der gepostete Code,
denn wie ich schon schrieb:
>>>> So ein Bauteil habe ich noch niemals nirgendwo gesehen.
Und der Synthesizer meldet denn auch:
1
ERROR:Xst:827 - ".../rs232.vhd" line 38: Signal BlaTest3 cannot be 
2
synthesized, bad synchronous description. The description style you are 
3
using to describe a synchronous element (register, memory, etc.) is not 
4
supported in the current software release.

> Ich werde die Tage nochmal meinen Code posten, so wie er momentan
> aussieht und erklären, was wir uns dabei denken.
Mach das.

: Bearbeitet durch Moderator
von Nico (Gast)


Angehängte Dateien:

Lesenswert?

Guten Tag,


ich habe mich mit dem Code aus diesem link:

http://www.lothar-miller.de/s9y/categories/42-RS232

beschäftigt. Leider muss ich zugeben, dass ich ihn nicht ganz 
durchdringe. Ich habe ihn in unser Projekt eingepflegt, anstatt des von 
mir geposteten Moduls. (natürlich nur den Prozess zum empfangen)
Ich habe aber einige Fragen,da ein paar Fehler aftreten, wenn ich unser 
Projekt teste.

Was machen folgende Zeilen genau?

rxd_sr <= rxd_sr(rxd_sr'left-1 downto 0) & RXD;

rxsr     <= rxd_sr(rxd_sr'left-1) & rxsr(rxsr'left downto 1)

Ich verstehe, dass es eine Art Shift ist, aber ich kann leider nicht 
direkt nachvollziehen was mit "rxsr'left" gemacht wird.

Weiterhin dachte ich ich könnte das RX_BUSY dazuverwenden um meinem 
7Segmentmodul zu signalisieren, dass eine Abtastung vollzogen ist. Ich 
wollte also RX_BUSY mit dem Enable meines Moduls zur ansteuerung der 
7Segmentanzeige "verbinden". Dazu wollte ich auf die fallende Flanke 
abwarten. Leider zeigt die Anzeige nur Striche an, was bedeutet dass er 
kein ASCII zeichen erkannt hat. Frage ich auf die steigende Flanke ab, 
dann gibt er die Buchstaben, doppelt aus. Was logisch ist, da RX_BUSY 
auf 1 geht, wenn die Abtastung läuft.

Ich poste dazu unten noch den Code meiner Siebensegmtanzeige und das 
Package in der die verwendete Prozedur zu finden ist.

Ich hoffe das war einigermaßen verständlich, weiterhin hoffe ich, dass 
ihr mir helfen weiterhin helfen könnt.

mfg,

nico

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


Lesenswert?

> "rxsr'left"
'left (sprich "tick left") ist ein Attribut:
www.eda.org/rassp/vhdl/guidelines/vhdlqrc.pdf
Das Attribut 'left gibt das "linkeste" Element des Typs (hier ein 
Vektor) zurück.
1
constant  a :std_logic_vector := "01100001";
2
constant  b :std_logic_vector := "01100010";
3
constant  c :std_logic_vector := "01100011";
4
constant  d :std_logic_vector := "01100100";
5
constant  e :std_logic_vector := "01100101";
6
constant  f :std_logic_vector := "01100110";
7
constant  g :std_logic_vector := "01100111";
8
constant  h :std_logic_vector := "01101000";
9
constant  i :std_logic_vector := "01101001";
10
constant  j :std_logic_vector := "01101010";
11
constant  k :std_logic_vector := "01101011";
12
constant  l :std_logic_vector := "01101100";
13
constant  m :std_logic_vector := "01101101";
14
constant  n :std_logic_vector := "01101110";
15
constant  o :std_logic_vector := "01101111";
16
constant  p :std_logic_vector := "01110000";
17
constant  q :std_logic_vector := "01110001";
18
constant  r :std_logic_vector := "01110010";
19
constant  s :std_logic_vector := "01110011";
20
constant  t :std_logic_vector := "01110100";
21
constant  u :std_logic_vector := "01110101";
22
constant  v :std_logic_vector := "01110110";
23
constant  w :std_logic_vector := "01110111";
24
constant  x :std_logic_vector := "01111000";
25
constant  y :std_logic_vector := "01111001";
26
constant  z :std_logic_vector := "01111010";
Sieh mal nach, wie der Typ char definiert ist. Und dann überleg, wie du 
dir mit den Attributen 'pos oder 'val diese ganze 
Konstantendeklariererei sparen könntest.

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.