1 | ----------------------------------------------------------------------------------
|
2 | -- Company:
|
3 | -- Engineer:
|
4 | --
|
5 | -- Create Date: 13:20:04 06/06/2018
|
6 | -- Design Name:
|
7 | -- Module Name: Spartan6_Uart - Behavioral
|
8 | -- Project Name:
|
9 | -- Target Devices:
|
10 | -- Tool versions:
|
11 | -- Description:
|
12 | --
|
13 | -- Dependencies:
|
14 | --
|
15 | -- Revision:
|
16 | -- Revision 0.01 - File Created
|
17 | -- Additional Comments:
|
18 | --
|
19 | ----------------------------------------------------------------------------------
|
20 | library IEEE;
|
21 | use IEEE.STD_LOGIC_1164.ALL;
|
22 |
|
23 | -- Uncomment the following library declaration if using
|
24 | -- arithmetic functions with Signed or Unsigned values
|
25 | use IEEE.NUMERIC_STD.ALL;
|
26 |
|
27 | -- Uncomment the following library declaration if instantiating
|
28 | -- any Xilinx primitives in this code.
|
29 | --library UNISIM;
|
30 | --use UNISIM.VComponents.all;
|
31 |
|
32 | entity Spartan6_Uart is
|
33 | Generic (
|
34 | CLK_FREQ : integer := 100e6; -- set system clock frequency in Hz
|
35 | BAUD_RATE : integer := 9600 -- baud rate value
|
36 | );
|
37 | Port (
|
38 | -- FPGA_GCLK, 8MHz
|
39 | CLK : in STD_LOGIC;
|
40 |
|
41 | -- FPGA_LFC, 1 Hz
|
42 | CLK_LFC : in STD_LOGIC;
|
43 |
|
44 | -- LED outputs
|
45 | LED_0 : out STD_LOGIC;
|
46 | LED_1 : out STD_LOGIC;
|
47 | LED_2 : out STD_LOGIC;
|
48 | LED_3 : out STD_LOGIC;
|
49 |
|
50 | -- BTN inputs
|
51 | BTN_0 : in STD_LOGIC;
|
52 | BTN_1 : in STD_LOGIC;
|
53 |
|
54 | -- connected to physical I/O pad
|
55 | PORTA : inout STD_LOGIC_VECTOR (7 downto 0);
|
56 | PORTB : inout STD_LOGIC_VECTOR (7 downto 0);
|
57 | PORTC : inout STD_LOGIC_VECTOR (6 downto 0);
|
58 | PORTD : inout STD_LOGIC_VECTOR (7 downto 0);
|
59 | PORTE : inout STD_LOGIC_VECTOR (7 downto 0);
|
60 | PORTF : inout STD_LOGIC_VECTOR (6 downto 0)
|
61 | );
|
62 | end Spartan6_Uart;
|
63 |
|
64 | architecture Behavioral of Spartan6_Uart is
|
65 | -------------------------------------------------------
|
66 | -- 100 MHz clock
|
67 | -------------------------------------------------------
|
68 | component Clock_100Mhz
|
69 | port
|
70 | (
|
71 | -- Clock in ports
|
72 | CLK_IN1 : in std_logic;
|
73 | -- Clock out ports
|
74 | CLK_OUT1 : out std_logic
|
75 | );
|
76 | end component;
|
77 |
|
78 | signal clk_100 : STD_LOGIC;
|
79 |
|
80 | -------------------------------------------------------
|
81 | -- UART
|
82 | -------------------------------------------------------
|
83 |
|
84 | signal data_in : std_logic_vector(7 downto 0) := ( others => '0' );
|
85 | signal data_out : std_logic_vector(7 downto 0) := ( others => '0' );
|
86 |
|
87 | signal valid_in: std_logic := '0';
|
88 | signal valid_out: std_logic := '0';
|
89 |
|
90 | signal BUSY : std_logic;
|
91 |
|
92 | -- FSM states
|
93 | type statetype is (idle, sync_1, sync_2, address_match, cmd3_r, send_address, AKN, s_tx);
|
94 | signal state, next_state, next_tx_state : statetype := idle;
|
95 |
|
96 | signal timeout_counter : integer range 0 to 1 := 0;
|
97 | signal timeout : std_logic := '0';
|
98 |
|
99 | begin
|
100 |
|
101 | reset <= BTN_0;
|
102 |
|
103 | my_100MHz_clock_instance : Clock_100Mhz
|
104 | port map
|
105 | (
|
106 | -- Clock in ports
|
107 | CLK_IN1 => CLK,
|
108 | -- Clock out ports
|
109 | CLK_OUT1 => clk_100
|
110 | );
|
111 |
|
112 | uart_i: entity work.UART
|
113 | generic map (
|
114 | CLK_FREQ => CLK_FREQ,
|
115 | BAUD_RATE => BAUD_RATE
|
116 | )
|
117 | port map (
|
118 | CLK => clk_100,
|
119 | RST => reset,
|
120 | -- UART INTERFACE
|
121 | UART_TXD => PORTD(4),
|
122 | UART_RXD => PORTD(5),
|
123 | -- USER DATA OUTPUT INTERFACE
|
124 | DATA_OUT => data_in,
|
125 | DATA_VLD => valid_in,
|
126 | -- USER DATA INPUT INTERFACE
|
127 | DATA_IN => data_out,
|
128 | DATA_SEND => valid_out,
|
129 | BUSY => BUSY
|
130 | );
|
131 |
|
132 | process (clk_100) is
|
133 | begin
|
134 | if rising_edge(clk_100) then
|
135 | if timeout = '0' then
|
136 | state <= next_state;
|
137 | else
|
138 | state <= idle;
|
139 | end if;
|
140 | end if;
|
141 | end process;
|
142 |
|
143 | process (CLK_LFC) is
|
144 | begin
|
145 | if rising_edge(CLK_LFC) then
|
146 | if state /= idle then
|
147 | timeout_counter <= timeout_counter + 1;
|
148 |
|
149 | if timeout_counter = 1 then
|
150 | timeout <= '1';
|
151 | else
|
152 | timeout <= '0';
|
153 | end if;
|
154 | else
|
155 | timeout_counter <= 0;
|
156 | timeout <= '0';
|
157 | end if;
|
158 | end if;
|
159 | end process;
|
160 |
|
161 | process(state, valid_in, BUSY)
|
162 | variable bits : integer range 0 to 48 := 0;
|
163 | begin
|
164 | next_state <= state;
|
165 | valid_out <= '0';
|
166 |
|
167 | case state is
|
168 | when idle =>
|
169 | next_state <= idle;
|
170 | if valid_in = '1' then
|
171 | if data_in = x"AA" then
|
172 | next_state <= sync_1;
|
173 | end if;
|
174 | end if;
|
175 |
|
176 | when sync_1 =>
|
177 | next_state <= sync_1;
|
178 | if valid_in = '1' then
|
179 | if data_in = x"55" then
|
180 | next_state <= sync_2;
|
181 | else
|
182 | next_state <= idle;
|
183 | end if;
|
184 | end if;
|
185 |
|
186 | when sync_2 =>
|
187 | next_state <= sync_2;
|
188 | if valid_in = '1' then
|
189 | if unsigned(data_in) = unsigned(PORTF) then
|
190 | next_state <= address_match;
|
191 | else
|
192 | next_state <= idle;
|
193 | end if;
|
194 | end if;
|
195 |
|
196 | when address_match =>
|
197 | next_state <= address_match;
|
198 | if valid_in = '1' then
|
199 | if unsigned(data_in) = x"03" then
|
200 | bits := 16;
|
201 | next_state <= cmd3_r;
|
202 | end if;
|
203 | end if;
|
204 |
|
205 | when cmd3_r =>
|
206 | next_state <= cmd3_r;
|
207 | if valid_in = '1' then
|
208 |
|
209 | bits := bits - 8;
|
210 | --load 16 unsigned value
|
211 |
|
212 | if bits = 0 then
|
213 | next_tx_state <= AKN;
|
214 | next_state <= send_address;
|
215 | end if;
|
216 | end if;
|
217 |
|
218 | when s_rx_wait_done =>
|
219 | if valid_in = '0' then
|
220 | next_state <= next_rx_state;
|
221 | end if;
|
222 |
|
223 | when send_address =>
|
224 | data_out <= "0" & PORTF;
|
225 | next_state <= s_tx;
|
226 |
|
227 | when AKN =>
|
228 | data_out <= x"55";
|
229 | next_tx_state <= idle;
|
230 | next_state <= s_tx;
|
231 |
|
232 | when s_tx =>
|
233 | next_state <= s_tx;
|
234 | if BUSY = '0' then
|
235 | valid_out <= '1';
|
236 | next_state <= next_tx_state;
|
237 | end if;
|
238 | end case;
|
239 | end process;
|
240 |
|
241 |
|
242 |
|
243 | -------------------------------------------------------
|
244 | -- LED/BTN Testing
|
245 | -------------------------------------------------------
|
246 | LED_3 <= CLK_LFC;
|
247 | LED_2 <= not CLK_LFC;
|
248 |
|
249 | LED_0 <= BTN_0;
|
250 | LED_1 <= timeout;
|
251 |
|
252 | end Behavioral;
|