-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmini_project_uart_TX.vhd
More file actions
136 lines (107 loc) · 4.23 KB
/
mini_project_uart_TX.vhd
File metadata and controls
136 lines (107 loc) · 4.23 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
---this file contains the UART transmitter --
--this implemented transmitter will be able to transmit 8 bits of serial data, one start bit, one stop bit and no parity bit
--when transmission will be done out_TX_done will be driven high for one clock cycle.
--
--
-- set generic g_clock_per_bit as: g_clock_per_bit = (frequency of input_clk)/(frequency(baud) of UART)
--
--frequency of input_clk --25MHz (25000000)
--frequency(baud) of UART --9600
--
--g_clock_per_bit = 2604.167 --117 is an example
--
--IMPLEMENTATION OF RECEIVER
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
entity uart_TX is
generic (
g_clock_per_bit : integer := 10416 -- Needs to be set correctly and as needed
);
port (
in_clk : in std_logic; --input clock
in_TX_DV : in std_logic; --data-valid pulse
in_TX_byte : in std_logic_vector(7 downto 0); --8 bit vector is input to transmitter
out_TX_active : out std_logic;
out_TX_serial : out std_logic;
out_TX_done : out std_logic
);
end uart_TX;
architecture behav of uart_TX is
type t_SM_main is (s_idle, s_TX_start_bit, s_TX_data_bits,
s_TX_stop_bit, s_cleanup);
signal r_SM_main : t_SM_main := s_idle;
signal r_clk_count : integer range 0 to g_clock_per_bit-1 := 0;
signal r_bit_index : integer range 0 to 7 := 0; -- 8 Bits Total
signal r_TX_data : std_logic_vector(7 downto 0) := (others => '0');
signal r_TX_done : std_logic := '0';
begin
process_uart_TX : process (in_clk)
begin
if rising_edge(in_clk) then
case r_SM_main is
when s_idle => --idle state initialization and staying here until something happens
out_TX_active <= '0';
out_TX_serial <= '1'; --Make High for Idle
r_TX_done <= '0';
r_clk_count <= 0;
r_bit_index <= 0;
if in_TX_DV = '1' then --when data-valid pulse is 1
r_TX_data <= in_TX_byte; --register the data on the line
r_SM_main <= s_TX_start_bit;
else
r_SM_main <= s_idle;
end if;
-- Transmit the start bit. The start bit is 0
when s_TX_start_bit =>
out_TX_active <= '1'; --active through out the enitre data transmission
out_TX_serial <= '0'; --actual serial line
-- Here wait g_clock_per_bit-1 for start bit to finish
if r_clk_count < g_clock_per_bit-1 then
r_clk_count <= r_clk_count + 1;
r_SM_main <= s_TX_start_bit;
else
r_clk_count <= 0;
r_SM_main <= s_TX_data_bits; --send the data bits
end if;
-- Here wait g_clock_per_bit-1 clock cycles for data bits to completely transmit
when s_TX_data_bits =>
out_TX_serial <= r_TX_data(r_bit_index);
if r_clk_count < g_clock_per_bit-1 then
r_clk_count <= r_clk_count + 1;
r_SM_main <= s_TX_data_bits;
else
r_clk_count <= 0;
-- Check if we have transmit all bits
if r_bit_index < 7 then
r_bit_index <= r_bit_index + 1;
r_SM_main <= s_TX_data_bits;
else
r_bit_index <= 0;
r_SM_main <= s_TX_stop_bit;
end if;
end if;
-- Transmit the last Stop bit. Stop bit = 1
when s_TX_stop_bit =>
out_TX_serial <= '1';
-- Wait g_clock_per_bit-1 clock cycles for Stop bit to finish
if r_clk_count < g_clock_per_bit-1 then
r_clk_count <= r_clk_count + 1;
r_SM_main <= s_TX_stop_bit;
else
r_TX_done <= '1';
r_clk_count <= 0;
r_SM_main <= s_cleanup;
end if;
-- Stay here for 1 clock cycle
when s_cleanup =>
out_TX_active <= '0';
r_TX_done <= '1';
r_SM_main <= s_idle;
when others =>
r_SM_main <= s_idle;
end case;
end if;
end process process_uart_TX;
out_TX_done <= r_TX_done;
end behav;