Forum: FPGA, VHDL & Co. UART


von Ulrich K. (jesuz)


Lesenswert?

Hallo, besitzt jemand einen Verilog Sample code fuer ein einfaches UART?
Wuerde mich mal interessieren wie der aussieht...

vlg

von Xenu (Gast)


Lesenswert?

Schon mal probiert "Verilog" und "UART" bei Google einzugeben...

von Ulrich K. (jesuz)


Lesenswert?

ja das habe ich probiert ... aber wirklich viel sinnvolles habe ich dort
nicht gefunden

von Uwe Bonnes (Gast)


Lesenswert?

Schau mal auf opencores. Allerdings ist die Site gerade (14.3. 12.50)
Down...

von ejd (Gast)


Lesenswert?

Man findet einen UART in Verilog unter http://www.fpga4fun.com/

mfG,
ejd

von Sebastian (Gast)


Lesenswert?

Falls Du eine gute Beschreibung in VHDL gefunden hast, dann poste doch
bitte mal den Link bzw. Code.

Danke,
Sebastian

von T.M. (Gast)


Lesenswert?

Ich hab die Tage eine kleine UART in VHDL geschrieben...vielleicht nützt
es was:

Transmitter:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity transmitter is
5
port (reset      : in  std_logic;                     -- asynch reset
6
      clk        : in  std_logic;                     -- clock 40 MHz
7
      data       : in  std_logic_vector(7 downto 0);  -- data input
8
      data_ready : in  std_logic;                     -- control signal
9
data ready
10
      tx_ready   : out std_logic;                     -- transmitter
11
ready for new data
12
      tx         : out std_logic);                    -- transmitter
13
output
14
end transmitter;
15
16
architecture behavior of transmitter is
17
18
-- internal signals
19
signal sending       : boolean;                       -- sending mode
20
signal sent          : boolean;                       -- sent mode
21
signal count_clk     : natural range 0 to 4167;       -- clock counter
22
for clock divider
23
signal count_bit     : natural range 0 to 10;         -- bit counter
24
signal enable        : std_logic;                     -- clock enable
25
for sending mode
26
signal tx_ready_int  : std_logic := '1';              -- initalized
27
to 1 for tx_ready = 1 on start
28
signal data_register : std_logic_vector(7 downto 0);  -- for storage of
29
data input to send
30
31
begin
32
33
  
34
-------------------------------------
35
-- load tx_ready with rx_ready_int --
36
-------------------------------------
37
tx_ready <= tx_ready_int;
38
39
40
--------------------------------------------------
41
-- clock divider for baudrate generation        --
42
-- sensitive to clock, asynch reset by received --
43
-- receiving mode: generate clock enable        --
44
-- for wished baudrate                          --
45
--------------------------------------------------
46
clock_divider : process (clk, sent) is
47
begin
48
if sent then
49
  count_clk <= 0;
50
elsif clk'event and clk = '1' then
51
    if sending then
52
      enable <= '0';
53
      if count_clk = 4167 then
54
        count_clk <= 0;
55
      elsif count_clk = 0 then
56
        enable <= '1';
57
        count_clk <= count_clk + 1;
58
      else
59
        count_clk <= count_clk + 1;
60
      end if;
61
    end if;
62
  end if;
63
end process clock_divider;
64
65
66
-----------------------------------------------------------
67
-- data storage of input data                            --
68
-- sensitive to clock, asynch reset by reset             --
69
-- storage data in internal register when data_ready = 1 --
70
-----------------------------------------------------------
71
data_storage : process (clk, reset, sent) is
72
begin
73
if reset = '1' or sent then
74
  data_register <= (others => '0');
75
  sending       <= false;
76
elsif clk'event and clk = '1' then
77
  if data_ready = '1' then
78
    if not sending then
79
      data_register <= data;
80
      sending       <= true;
81
    end if;
82
  end if;
83
end if;
84
end process data_storage;
85
86
87
-------------------------------------------------------
88
-- send storaged data                                -- 
89
-- sensitive to clock, asynch reset by reset         --
90
-- load tx with content of data register from 0 to 9 --
91
-- when sending complete : ready for new data        --
92
-------------------------------------------------------
93
data_send : process (clk, reset) is
94
begin
95
if reset = '1' then
96
  tx        <= '1';
97
  count_bit <= 0;
98
elsif clk'event and clk = '1' then
99
sent <= false;
100
  if enable = '1' then
101
    tx_ready_int <= '0';
102
    tx           <= '1';
103
    case count_bit is
104
      when 0  => tx        <= '0';
105
                 count_bit <= count_bit + 1;
106
      when 9  => tx        <= '1';
107
                 count_bit <= count_bit + 1;
108
      when 10 => tx            <= '1';
109
                 count_bit     <= 0;
110
                 sent          <= true;
111
                 tx_ready_int  <= '1';
112
      when others => count_bit <= count_bit + 1;
113
                     tx        <= data_register(count_bit - 1);
114
    end case;
115
  end if;
116
end if;
117
end process data_send;
118
    
119
end architecture behavior;

Receiver:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity receiver is
5
port (reset      : in  std_logic;                      -- asynch reset
6
      clk        : in  std_logic;                      -- clock 40 MHz
7
      rx         : in  std_logic;                      -- receive
8
input
9
      data_ready : out std_logic;                      -- status signal
10
data received
11
      data_error : out std_logic;                      -- status signal
12
receive error
13
      data_out   : out std_logic_vector(7 downto 0));  -- received
14
data
15
end receiver;
16
17
architecture behaviour of receiver is
18
19
signal received      : boolean;                       -- for received
20
mode
21
signal receiving     : boolean;                       -- for receive
22
mode
23
signal count_start   : natural range 0 to 2083;       -- start counter
24
for detecting middle of startbit
25
signal count_clk     : natural range 0 to 4167;       -- clock counter
26
for clock divider
27
signal count_bit     : natural range 0 to 9;          -- bit counter
28
for received bits
29
signal enable        : std_logic;                     -- clock enable
30
for receive mode
31
signal data_register : std_logic_vector(7 downto 0);  -- data register
32
for received bits
33
34
35
begin
36
37
38
--------------------------------------------------
39
-- detecting startbit                           --
40
-- sensitive to clock, asynch reset by received --
41
-- if rx = 0 counts to 2083 to know if there is --
42
-- a startbit                                   --
43
-- when startbit:   go in receiving mode        --
44
-- when no starbit: count again from 0 to 2083  --
45
--------------------------------------------------
46
sampling : process (clk, received) is
47
begin
48
if received then
49
  receiving <= false;
50
  count_start <= 0;
51
elsif clk'event and clk = '1' then
52
  if rx = '0' then
53
    if count_start = 2083 then
54
      receiving <= true;
55
    else
56
      count_start <= count_start + 1;
57
    end if;
58
  end if;
59
end if;
60
end process sampling;
61
62
63
--------------------------------------------------
64
-- clock divider for baudrate generation        --
65
-- sensitive to clock, asynch reset by received --
66
-- receiving mode: generate clock enable        --
67
-- for wished baudrate                          --
68
--------------------------------------------------
69
clock_divider: process (clk, received) is
70
begin
71
if received then
72
count_clk <= 0;
73
elsif clk'event and clk = '1' then
74
    if receiving then
75
      enable <= '0';
76
      if count_clk = 4167 then
77
        count_clk <= 0;
78
      elsif count_clk = 0 then
79
        enable <= '1';
80
        count_clk <= count_clk + 1;
81
      else
82
        count_clk <= count_clk + 1;
83
      end if;
84
    end if;
85
  end if;
86
end process clock_divider;
87
88
89
--------------------------------------------------------
90
-- receive data                                       --
91
-- sensitive to clock. asynch reset by reset          --
92
-- clock enable by enable                             --
93
-- load 9 bit in data register & put data on data out --
94
-- last bit = 1 : valid stopbit => data ready         --
95
-- last bit = 0 : invalid stopbit => data error       --
96
--------------------------------------------------------
97
data_read: process (clk, reset) is
98
begin
99
if reset = '1' then
100
  data_register <= (others => '0');
101
elsif clk'event and clk = '1' then
102
received   <= false;  
103
  if enable = '1' then
104
     data_ready <= '0';
105
     data_error <= '0';
106
     case count_bit is
107
       when 0 => count_bit <= count_bit + 1;
108
       when 9 => count_bit <= 0;
109
                 received  <= true;
110
     data_out  <= data_register;
111
                 if rx = '1' then
112
                   data_ready <= '1';
113
                 else
114
                   data_error <= '1';
115
                 end if;
116
       when others => count_bit <= count_bit + 1;
117
                      data_register(count_bit-1) <= rx;
118
     end case;
119
  end if;
120
end if;
121
end process data_read;
122
                
123
end behaviour;

Testbench kann ich wenn erwünscht auch liefern...

von T.M. (Gast)


Lesenswert?

Hä? Was muss denn seit neusten für VHDL code eingeben? Früher ging mal
mal c in eckigen Klammern....

von FPGA-User (Gast)


Lesenswert?

sieht nicht schlecht aus, aber warum nimmst Du für
data_register() kein Schieberegister ?
Und jeweils oben in TX und RX sollte eine Konstante
sein, wo man den Teiler einfach an die Taktfrequenz
anpassen kann. Dann wäre es ganz hübsch ... ;-)

von axel (Gast)


Lesenswert?

@ T.M. gute arbeit. Aber ein c in klammern sagt, das es ein c-Code ist.
Mit vhdl am anfang und /VHDL am ende gehts besser :-) Natürlich in
eckige klammern.

von T.M. (Gast)


Lesenswert?

Ja, ich wollte eh noch generics einführen für die Einstellung der
Baudrate... Sowas mach ich immer nachdem ich weiss, dass es prinzipiell
funzt ;-)
Das mit dem Schieberegister ist natürlich ne Alternative. Muss ich dann
mal guggn.
Danke :-)

von Ralf H. (hagemann)


Lesenswert?

Hy T.M.,

dein Beitrag ist zwar schon ne Weile her, aber immer noch interessant.
Läuft dein UART stabil ?
Ich habe bei meinem UART-CORE immer das Problem, das Zeichen beim lesen 
verschluckt weden ?

Hat du vielleicht eine Testbench für deinen UART ?

Gruss
Ralf

Ps.:
Ich verwende das Xilinx Spartan3 StarterKitBoard mit dem
"PicoBlaze Core von Ken Chapman (Xilinx Ltd)
October 2002" und den "UART Transmitter Version 1.00 von Ken Chapman,
Xilinx Ltd, Benchmark House".



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.