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.
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.
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-IOhttp://www.lothar-miller.de/s9y/categories/42-RS232
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
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.
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.
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
ifsetProcRun='0'then
4
blatest3<='0';
5
ProcRun<='0';
6
elsifsetProcRun='1'then
7
blatest3<='1';
8
ProcRun<='1';
9
endif;
10
11
ifrising_edge(RxData)then
12
blatest3<='1';
13
ProcRun<='1';
14
endif;
15
16
ifrising_edge(Rst)then
17
blatest3<='0';
18
ProcRun<='0';
19
endif;
20
endprocessCheckProcRun;
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
ifsetProcRun='0'then
2
blatest3<='0';
3
ProcRun<='0';
4
elsifsetProcRun='1'then
5
blatest3<='1';
6
ProcRun<='1';
7
endif;
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.
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.
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.
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.
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.
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
> "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
constanta:std_logic_vector:="01100001";
2
constantb:std_logic_vector:="01100010";
3
constantc:std_logic_vector:="01100011";
4
constantd:std_logic_vector:="01100100";
5
constante:std_logic_vector:="01100101";
6
constantf:std_logic_vector:="01100110";
7
constantg:std_logic_vector:="01100111";
8
constanth:std_logic_vector:="01101000";
9
constanti:std_logic_vector:="01101001";
10
constantj:std_logic_vector:="01101010";
11
constantk:std_logic_vector:="01101011";
12
constantl:std_logic_vector:="01101100";
13
constantm:std_logic_vector:="01101101";
14
constantn:std_logic_vector:="01101110";
15
constanto:std_logic_vector:="01101111";
16
constantp:std_logic_vector:="01110000";
17
constantq:std_logic_vector:="01110001";
18
constantr:std_logic_vector:="01110010";
19
constants:std_logic_vector:="01110011";
20
constantt:std_logic_vector:="01110100";
21
constantu:std_logic_vector:="01110101";
22
constantv:std_logic_vector:="01110110";
23
constantw:std_logic_vector:="01110111";
24
constantx:std_logic_vector:="01111000";
25
constanty:std_logic_vector:="01111001";
26
constantz: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.