UART-Transmitter in VHDL

Neue Frage »

Auf diesen Beitrag antworten »
deppensido UART-Transmitter in VHDL

hallo,

ich versuche einen UART-Transmitter in VHDL zu beschreiben. Dazu habe ich die Eingänge: din, send, clk und rst sowie den Ausgang txt, wie im Blockschaltbild deklariert (siehe Anhang), zur Erzeugung des Übertragungstaktes habe ich meinen zuvor beschriebenen Baudgenerator benutzt. Von diesem gehe ich aus, dass er korrekt ist. Schließlich habe ich versucht den Zustandsautomat (siehe Anhang) zu beschreiben. Hierfür habe ich die Transition "Taster gedrückt" als "if send = '1' then" interpretiert und "Zeichen gesendet" als "if send = '0' then" interpretiert. Allerdings habe ich keine Ahnung, wie man nun "Zeichen" im Zustand "Sende" ausgeben soll. Ich hatte "txd <= '1' probiert, aber das geht nicht, da txd bereits an den Baudgenerator gebunden ist. Zudem habe ich den Eingang "din" auch gar nicht benutzt und weiß auch nicht wo und wie ich das benutzen soll. Muss ich vielleicht ein Signal für "Zeichen" mit Typ std_logic_vector deklarieren und dann irgendwie jedes Bit von "din" durchgeben? Ich hoffe mir kann jemand weiterhelfen. Ich habe leider nur noch diese Woche Zeit die Aufgabe fertig zu stellen und komme momentan gar nicht weiter, da ich in VHDL auch ein Anfänger bin. Im folgenden mal mein Code:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
entity Transmitter is
    Port ( din : in  std_logic_vector (7 downto 0);
           send : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           txd : out  STD_LOGIC);
end Transmitter;

architecture Behavioral of Transmitter is
	component Baudratengenerator is
		port ( clk : in std_logic;
				 rst : in std_logic;
				 tick : out std_logic);
	end component;
	
	type STATE_T is (Warte, Sende); --Aufzählungstyp
	signal state : STATE_T;			  --Zustandssignal
begin
ba: Baudratengenerator port map(clk=>clk, rst=>rst, tick=>txd);

FSM : process (din, send, clk, rst) is
begin
	if rst = '1' then
		state <= Warte;
	elsif clk'event and clk = '1' then
		case state is
			when Warte =>
				if send = '1' then
					state <= Sende;
					
				end if;
			when Sende =>
				if send = '0' then
					state <= Warte;
				end if;
			end case;
	end if;
end process;
end architecture;


Bin dankbar für jedliche Hilfe.

Grüße
 
Auf diesen Beitrag antworten »
eulerscheZahl

Kannst du nicht mal Probleme mit C haben, da müsste ich nicht erst die Begriffe nachlesen smile
Meine Interpretation dessen, was du geschrieben hast (korrigiere mich, wenn ich falsch liege):
Du willst Daten senden, und zwar über eine einzelne Leitung (txd).
Die Daten liegen an einem Bus an (din). txd ist zu Beginn auf einer logischen 1.
Beim Druck einer Taste(positive Flanke) kommt dein UART in den Zustand senden.
Nach und nach - immer beim clk-Ereignis - wird zunächst eine 0 (Startbit) gesendet, und dann din[0] bis din[7], anschließend noch 1-2 Stopbit. Dann ist der UART wieder im Zustand warte.
richtig?
Dann müsstest du sende noch weiter aufschlüsseln: die 10/11 Bit auf die Leitung jagen und erst dann zurück in warte.

Mal schauen, ob ich es hinkriege, bin selbst recht ausgebucht und kann kaum VHDL.
Auf diesen Beitrag antworten »
deppensido

hallo,

so wie du es beschrieben hast passt es. Bislang ist mir noch nichts nennenswertes wieder eingefallen. Im Anhang sind nun die Informationen, die ich in meinem ersten Post erwähnt hatte. Letzlich soll ja eigentlich nur dieser Zustandsautomat realisiert werden, ist nur die Frage wie das genau geht.

Grüße
Auf diesen Beitrag antworten »
deppensido

ich habe nochmal am Code gebastelt. Meiner Logik nach müsste es eigentlich so gehen. Der Syntaxcheck gibt mir ein Ok, allerdings meckert die Synthese, dass txd zwei Quellen zugeordnet ist, nämlich den Baudgenerator und den Transmitter. Aber so wie ich den Baudgenerator eingebunden habe, ist es doch eigentlich die einzige Möglichkeit. Naja im folgenden mal der Code (die hinzugefügten Zeilen sind kommentiert)

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
----------------------------------------------------------------------------------
-- Company: 
-- Engineer:		 Volker Deppe
-- 
-- Create Date:    17:29:52 07/02/2013 
-- Design Name: 
-- Module Name:    Transmitter - Behavioral 
-- Project Name: 	 UART
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Transmitter is
    Port ( din : in  std_logic_vector (7 downto 0);
           send : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           txd : out  STD_LOGIC);
end Transmitter;

architecture Behavioral of Transmitter is
	component Baudratengenerator is
		port ( clk : in std_logic;
				 rst : in std_logic;
				 tick : out std_logic);
	end component;
	signal gesendet : boolean:= false;
	signal bitcounter : integer:= 0;
	type STATE_T is (Warte, Sende); --Aufzählungstyp
	signal state : STATE_T;			  --Zustandssignal
begin
ba: Baudratengenerator port map(clk=>clk, rst=>rst, tick=>txd);

FSM : process (din, send, clk, rst) is
begin
	if rst = '1' then
		state <= Warte;
	elsif clk'event and clk = '1' then
		case state is
			when Warte =>
				if send = '1' then --Transition "Taster gedrückt"
					state <= Sende;
				end if;
			when Sende =>
				if bitcounter = 0 then
					txd <= '0';  --start bit
				end if;
				if bitcounter < 8 then
					txd <= din(bitcounter); --Daten nacheinander an txd anlegen
				else
					txd <= '1'; --stopp bit
					gesendet <= true;  --Transition "Zeichen gesendet"
					bitcounter <= 0;
				end if;
				if gesendet = true then
					state <= Warte;
					gesendet <= false;
				end if;
			end case;
	end if;
end process;
end architecture;



hoffe dir fällt noch etwas ein. Vielen Dank schon mal.

Grüße
 
Auf diesen Beitrag antworten »
eulerscheZahl

Hier mal nur der UART, unter der Annahme, dass die Eingangsfrequenz schon passt:

Vergleiche deine Zeile 68 mit meiner Zeile 35, du wolltest das erste Datenbit unterschlagen.
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Transmitter is
    Port ( din : in  std_logic_vector (7 downto 0);
           send : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           txd : out  STD_LOGIC);
end Transmitter;

architecture Behavioral of Transmitter is
	signal bitcounter : integer:= 0;
	type STATE_T is (Warte, Sende); --Aufzählungstyp
	signal state : STATE_T;			  --Zustandssignal
	signal sendeTaster: std_logic := '0';
begin
FSM : process (din, send, clk, rst) is
begin
	if rising_edge(clk) then
		if sendeTaster = '0' and send = '1' then -- Taktflanke des Tasters
			state <= Sende;
			bitcounter <= 0;
		end if;
	
		if state = Warte then
			txd <= '1';
		else --Sende
			if bitcounter = 0 then
				txd <= '0'; -- start bit
			elsif bitcounter = 9 then
				txd <= '0'; --stop Bit
				state <= Warte;
			else --Daten senden
				txd <= din(bitcounter + 1);
			end if; --bitCounter
			bitcounter <= bitcounter + 1;
		end if; --Sende
		
		sendeTaster <= send;
	end if; -- clk
	
	if rst = '1' then
		state <= Warte;
		bitcounter <= 0;
	end if; 
end process;
end architecture;

Dürftest du zum Verbinden von Baudratengenerator und UART auch einfach ein Block Diagram verwenden?

Wie man in der Simulation sehen kann, funktioniert mein Programm nur, wenn der Tastendruck während der Taktflanke der Clock erfolgt, dürfte aber kein Problem darstellen. Mit dem Entprellen darfst du dich selbst rumschlagen.
Auf diesen Beitrag antworten »
deppensido

hallo,

erst mal danke für die Hilfe. Aber din ist doch ein std_logic_vector von 0 bis 7.
Dann müsste Zeile 31 doch bitcounter = 8 heißen oder?
Und warum bei Zeile 35 din(bitcounter+1), wenn man din(0) bis din(7) nur zur Verfügung hat,
da greift man doch auf nicht vorhandene Daten zu oder?
Dies versteh ich noch nicht wirklich. Ansonsten ist unser Code von der Logik her identisch
würde ich sagen. Bleibt dann nur noch das Problem, dass das Programm meckert, da txd zwei
unterschiedlichen Treibern zugeordnet ist, aber das kann ich vielleicht auch noch in meinem
Praktikum erfragen.

Grüße
Auf diesen Beitrag antworten »
eulerscheZahl

Da haben meine Finger wohl nicht so gaz gemacht, was sie sollten.
Geplant war: txd <= din(bitcounter - 1);, denn din[7..0] soll durch einen bitcounter in [8..1] angesprochen werden.
Jetzt wird auch ein 'e' gesendet, wie von mir beabsichtigt.

Falls du es unbedingt in VHDL haben willst: hier der Code (aus Blockschaltbild automatisch generiert)
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
-- Copyright (C) 1991-2010 Altera Corporation
-- Your use of Altera Corporation's design tools, logic functions 
-- and other software and tools, and its AMPP partner logic 
-- functions, and any output files from any of the foregoing 
-- (including device programming or simulation files), and any 
-- associated documentation or information are expressly subject 
-- to the terms and conditions of the Altera Program License 
-- Subscription Agreement, Altera MegaCore Function License 
-- Agreement, or other applicable license agreement, including, 
-- without limitation, that your use is for the sole purpose of 
-- programming logic devices manufactured by Altera and sold by 
-- Altera or its authorized distributors.  Please refer to the 
-- applicable agreement for further details.

-- PROGRAM		"Quartus II"
-- VERSION		"Version 9.1 Build 350 03/24/2010 Service Pack 2 SJ Web Edition"
-- CREATED		"Wed Jul 03 17:45:59 2013"

LIBRARY ieee;
USE ieee.std_logic_1164.all; 

LIBRARY work;

ENTITY uart IS 
	PORT
	(
		clk :  IN  STD_LOGIC;
		reset :  IN  STD_LOGIC;
		sender :  IN  STD_LOGIC;
		din :  IN  STD_LOGIC_VECTOR(7 DOWNTO 0);
		tick :  OUT  STD_LOGIC;
		txd :  OUT  STD_LOGIC
	);
END uart;

ARCHITECTURE bdf_type OF uart IS 

COMPONENT baudratengenerator
	PORT(clk : IN STD_LOGIC;
		 rst : IN STD_LOGIC;
		 tick : OUT STD_LOGIC
	);
END COMPONENT;

COMPONENT transmitter
	PORT(send : IN STD_LOGIC;
		 clk : IN STD_LOGIC;
		 rst : IN STD_LOGIC;
		 din : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 txd : OUT STD_LOGIC
	);
END COMPONENT;

SIGNAL	SYNTHESIZED_WIRE_0 :  STD_LOGIC;


BEGIN 
tick <= SYNTHESIZED_WIRE_0;



b2v_inst : baudratengenerator
PORT MAP(clk => clk,
		 rst => reset,
		 tick => SYNTHESIZED_WIRE_0);


b2v_inst1 : transmitter
PORT MAP(send => sender,
		 clk => SYNTHESIZED_WIRE_0,
		 rst => reset,
		 din => din,
		 txd => txd);


END bdf_type;
Auf diesen Beitrag antworten »
deppensido

hallo,

vor allem dank des Blockschaltbildes hab ich endlich verstanden, wie der Baudratengenerator und der Transmitter verbunden sein müssen. Darauf aufbauend sollte ich jetzt voran kommen.

Vielen Dank für die Hilfe.

Grüße
Auf diesen Beitrag antworten »
deppensido

Nochmals danke für die Hilfe. Ich konnte gestern meine Lösung vorstellen und diese war korrekt.

Grüße
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »