1 | -- TITLE: Uart transmitter
|
2 | -- AUTHOR: Rene Doss
|
3 | -- Company Dossmatik GmbH
|
4 | -- DATE CREATED: 27.6.2011
|
5 | -- FILENAME: UART_TX_8N1.vhd
|
6 | -- PROJECT: MAIS CPU core
|
7 | --
|
8 | -- COPYRIGHT: Creative Commons CC BY-NC 3.0 with exception
|
9 | -- commercial applicants have to pay a licence fee
|
10 | --
|
11 | -- DESCRIPTION:
|
12 | -- Uart transmit timing
|
13 | ---------------------------------------------------------------------
|
14 |
|
15 | library IEEE;
|
16 | use IEEE.STD_LOGIC_1164.all;
|
17 |
|
18 | use ieee.numeric_std.all;
|
19 |
|
20 | --Uart transmiter without parity
|
21 |
|
22 | entity Uart_8N1_TX is
|
23 | generic(
|
24 | clk_freq : integer;
|
25 | baudrate : integer);
|
26 | port(
|
27 | clk : in std_logic;
|
28 | reset : in std_logic;
|
29 |
|
30 | send_data : in std_logic_vector(7 downto 0);
|
31 | write_en : in std_logic;
|
32 | send_busy : out std_logic;
|
33 | send_empty: out std_logic;
|
34 | tx : out std_logic);
|
35 | end;
|
36 |
|
37 |
|
38 | architecture Behavioral of Uart_8N1_TX is
|
39 | --FSM
|
40 | type state_type is (idle, start, data0, data1, data2, data3, data4, data5, data6, data7, stop);
|
41 | signal state, nextstate : state_type := idle;
|
42 |
|
43 | --FIFO
|
44 | type RAM is array (0 to 255) of std_logic_vector (7 downto 0);
|
45 | signal fifo : RAM;
|
46 | signal nextwrite : unsigned(7 downto 0);
|
47 | signal nextread : unsigned(7 downto 0);
|
48 |
|
49 |
|
50 | --output
|
51 | signal data_tx : std_logic_vector (7 downto 0);
|
52 | signal tick_counter : unsigned (10 downto 0);
|
53 | constant tick : integer := (clk_freq/baudrate);
|
54 |
|
55 |
|
56 | begin
|
57 |
|
58 | send_busy <= '1' when (nextwrite+1 = nextread) else '0';
|
59 | send_empty <= '1' when nextwrite=nextread else '0';
|
60 |
|
61 | process(clk)
|
62 | begin
|
63 | if rising_edge(clk) then
|
64 | if reset = '1' then
|
65 | nextread <= (others => '0');
|
66 | elsif state = stop and nextstate = idle then
|
67 | nextread <= nextread+1;
|
68 | end if;
|
69 | end if;
|
70 | end process;
|
71 |
|
72 | process(clk)
|
73 | begin
|
74 | if rising_edge(clk) then
|
75 | state <= nextstate;
|
76 | end if;
|
77 | end process;
|
78 |
|
79 | process(clk)
|
80 | begin
|
81 | if rising_edge(clk) then
|
82 | if reset = '1' then
|
83 | nextwrite <= (others => '0');
|
84 | elsif write_en = '1' then
|
85 | fifo(to_integer(nextwrite)) <= send_data;
|
86 | nextwrite <= nextwrite+1;
|
87 |
|
88 | end if;
|
89 | end if;
|
90 | end process;
|
91 |
|
92 |
|
93 | process(clk)
|
94 | begin
|
95 | if rising_edge(clk) then
|
96 |
|
97 | if reset = '1' then
|
98 | tick_counter <= (others => '0');
|
99 | tx <= '1';
|
100 | nextstate <= idle;
|
101 |
|
102 |
|
103 | -- elsif tick_counter= unsigned(baudreg) then
|
104 | elsif tick_counter = tick then
|
105 | tick_counter <= (others => '0');
|
106 |
|
107 | case state is
|
108 | when idle =>
|
109 | if nextwrite /= nextread then
|
110 | nextstate <= start;
|
111 | data_tx <= fifo(to_integer(nextread));
|
112 | tick_counter <= (others => '0');
|
113 | tx <= '0';
|
114 | else
|
115 | tx <= '1';
|
116 | end if;
|
117 | when start =>
|
118 | nextstate <= data0;
|
119 | tx <= data_tx(0);
|
120 |
|
121 | when data0 =>
|
122 | nextstate <= data1;
|
123 | tx <= data_tx(1);
|
124 | when data1 =>
|
125 | nextstate <= data2;
|
126 | tx <= data_tx(2);
|
127 | when data2 =>
|
128 | nextstate <= data3;
|
129 | tx <= data_tx(3);
|
130 | when data3 =>
|
131 | nextstate <= data4;
|
132 | tx <= data_tx(4);
|
133 | when data4 =>
|
134 | nextstate <= data5;
|
135 | tx <= data_tx(5);
|
136 | when data5 =>
|
137 | nextstate <= data6;
|
138 | tx <= data_tx(6);
|
139 | when data6 =>
|
140 | nextstate <= data7;
|
141 | tx <= data_tx(7);
|
142 | when data7 =>
|
143 | nextstate <= stop;
|
144 | tx <= '1';
|
145 | when stop =>
|
146 | nextstate <= idle;
|
147 | tx <= '1';
|
148 | end case;
|
149 | else
|
150 | tick_counter <= tick_counter + 1;
|
151 | end if;
|
152 | end if;
|
153 |
|
154 | end process;
|
155 | end Behavioral;
|