Hallo,
ich versuche einen UART-Transmitter in VHDL zu beschreiben. Dazu habe
ich ein Modul "Baudratengenerator" beschrieben der mit einer Frequenz
von 9600Hz das nächste Datenbit an txd anlegen soll. Desweiteren habe
ich ein Modul "Transmitter" beschrieben, der letzlich den
UART-Transmitter realisieren soll und dabei den Baudratengenerator
benutzt. Allerdings gibt mir die Synthese einen Fehler aus, da txd an
den Baudratengenerator gebunden und den Transmitter gebunden ist. Wie
kann ich das beheben? Rein logisch müsste mein Code funktionieren. Siehe
dazu die Anhänge.
Im folgenden der Code für den Baudratengenerator:
txd<=din(bitcounter);--Daten nacheinander an txd anlegen
38
else
39
txd<='1';--stopp bit
40
gesendet<=true;--Transition "Zeichen gesendet"
41
bitcounter<=0;
42
endif;
43
ifgesendet=truethen
44
state<=Warte;
45
gesendet<=false;
46
endif;
47
endcase;
48
endif;
49
endprocess;
50
endarchitecture;
dabei bin ich mir sicher, den Baudratengenerator richtig beschrieben zu
haben und auch richtig im Transmitter verwendet zu haben, da es ja
eigentlich keine andere Möglichkeit gibt.
Ich hoffe mir kann jemand weiterhelfen.
Vielen Dank im voraus.
Grüße, Volker
Volker D. schrieb:>> richtig im Transmitter verwendet zu haben, da es ja> eigentlich keine andere Möglichkeit gibt.>
Nein hast du nicht richtig verwendet, und es gibt immer mehere
Möglichkeiten.
Da es wohl eine Hausaufgabe ist, nur ein kurzer Tipp: Lern mal wozu
Clockenables da sind.
ich galube, ich weiß jetzt, was ich falsch gemacht habe. Im Transmitter
selber, wird der Baudratengenerator gar nicht eingebunden, sondern nur
der Transmitter beschrieben. Das heißt also, dass beim Transmitter die
Component Baudratengenerator und die dazugehörige Port map entfernt
wird. In einem dritten VHDL-Modul, was ich dann z.B. UART nennen kann,
wird der Transmitter und der Baudratengenerator über die Port maps
verbunden und gegebenenfalls ein Signal zum verdrahten eingeführt. Bin
ich damit auf dem richtigen Weg?
Die Synthese hat schon recht, wenn sie meckert.
Was wolltest du erreichen? Einen "tick", der vom Baudratengenerator
kommt und ein "txd", welches das eigentliche Datum darstellt.
Soweit ist der Gedanke korrekt. Aber was würde passieren, wenn du für
den Baudratengenerator und den eigentlichen Sender zwei reale Bauelemnte
hättest und deren Ausgänge, so wie du es gemacht hast, einfach
zusammenschaltest?
Richtig: Das kann nicht gehen! Sagt der eine "1" und der andere "0",
dann hättest du einen Kurzschluss. Und genau das erkennt die Synthese
und meckert (zurecht)
Es kann immer nur einen geben (wie beim Highlander), der direkt auf ein
Signal treibt.
Was du eigentlich brauchst, ist eine Art Steuereingang für den
Transmitter, über den der Baudratengenerator ihm sagt: "so, jetzt bitte
nächstes Bit ausgeben" und der Transmitter muss dann so geschrieben
werden, dass er immer brav wartet, bis er vom Baudratengenerator die
Erlaubnis bekommt, das nächste Bit zu senden.
danke für die Antwort. Die Erklärung klingt logisch (einen Kurzschluss
möchte ich natürlich nicht beschreiben). Ich versuch es dann erst mal
weiter und wenn weitere Probleme auftreten meld ich mich wieder.
Grüße, Volker
hallo,
ich denke, ich habe den UART-Transmitter jetzt richtig beschrieben. Den
Baudratengenerator habe ich so gelassen, wie in meinem ersten Post. Im
folgenden der überarbeitete Transmitter und die Gesamtschaltung. Ich
würd mich freuen, wenn jemand schauen könnte, ob die Codes so korrekt
sind.
Transmitter:
1
entityTransmitteris
2
Port(din:instd_logic_vector(7downto0);
3
send:inSTD_LOGIC;
4
clk:inSTD_LOGIC;
5
rst:inSTD_LOGIC;
6
txd:outSTD_LOGIC);
7
endTransmitter;
8
9
architectureBehavioralofTransmitteris
10
signalgesendet:boolean:=false;
11
signalbitcounter:integer:=0;
12
typeSTATE_Tis(Warte,Sende);--Aufzählungstyp
13
signalstate:STATE_T;--Zustandssignal
14
begin
15
16
FSM:process(din,send,clk,rst)is
17
begin
18
ifrst='1'then
19
state<=Warte;
20
bitcounter<=0;
21
elsifclk'eventandclk='1'then
22
casestateis
23
whenWarte=>
24
gesendet<=false;
25
ifsend='1'then--Transition "Taster gedrückt"
26
state<=Sende;
27
endif;
28
whenSende=>
29
ifbitcounter=0then
30
txd<='0';--start bit
31
elsifbitcounter<9then
32
txd<=din(bitcounter-1);--Daten nacheinander an txd anlegen
In der Sensivity-Liste brauchts nur clk und rst.
>FSM : process (din, send, clk, rst) is
FSM : process ( clk, rst) is
Und hier machst du einen asyncronen Reset,
>FSM : process (din, send, clk, rst) is>begin> if rst = '1' then
Wenn das Signal "rst" eine asyncrone Quelle hat (z.B.: Taster)
das sollte man "rst" einsyncronisieren:
Beitrag "Detailfrage Reset"
sonst sind hier "manchmal gehts nicht" vorprogrammiert.
Und wenn das Ziel ein FPGA ist dann auch mal
Xilinx- WP272 und den Rest von oben durchlesen.
Und hier vermute ich einen abgeleiteten Takt:
>ba : Baudratengenerator port map (clk=>clk, rst=>rst, tick=>sw);>tr : Transmitter port map (din=>din, send=>send, clk=>*sw*, rst=>rst, >txd=>txd);
Da Zitiere ich das Lothar Miller-Postulat:
"Ein Design (insbesondere ein Anfängerdesign) hat genau 1 Takt, der
immer
auf dieselbe Flanke aktiv ist."
Beitrag "Re: Fehler durch Signalabgreifen"
Besser ists mit einem clock-enable zu arbeiten, hier mit Beispiel:
http://www.mikrocontroller.net/articles/Taktung_FPGA/CPLD
Volker D. schrieb:> Ich> würd mich freuen, wenn jemand schauen könnte, ob die Codes so korrekt> sind.
Wenn Du noch eine Testbench dazu machst, schau ich mir das Ganze mal im
Simulator an.
Duke
Naja man sampled aber bei der Asynchronen Schnittstelle zwischen der
positiven und der negativen Taktflanke also in der mite eines Taktes.
Deshalb solle die Taktfrequenz schon mndestens Doppelt so hoch sein.
Moderne und alte UARTs arbeiten normalerweise mit 16fach höheren Takt.
Da kann man dann auch noch sowas wie ne Fehlererkennung einbauen wie nen
Equivalent oder der vier mittleren Pegel.
Volker D. schrieb:> Die Aufgabe habe ich korrekt gelöst
Ich hätte da (mit sehr hoher Wahrscheinlichkeit) einen grundlegenden
Denkfehler gefunden:
Volker D. schrieb:> if counter = 5208 then
Dir ist schon klar, dass dein Zähler hier die Frequenz um 5209 teilt
(und nicht um 5208, was einen kleineren Fehler in der Baudrate
darstellen würde)?
Logisch macht das hier den Kohl nicht fett, aber was, wenn deine
Taktfrequenz 96kHz gewesen wäre? Dann würde es schon was ausmachen, ob
du durch 10 oder durch 11 teilst...
Uwe schrieb:> Naja man sampled aber bei der Asynchronen Schnittstelle zwischen der> positiven und der negativen Taktflanke also in der mite eines Taktes.
Naja, das betrifft aber nur den Empfänger. Der hier beschriebene
Sender kann von einem Oversampling nicht profitieren...