Add Tercel PHY reset synchronization
[microwatt.git] / sim_16550_uart.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.sim_console.all;
7
8 entity uart_top is
9 port(
10 wb_clk_i : in std_ulogic;
11 wb_rst_i : in std_ulogic;
12 wb_adr_i : in std_ulogic_vector(2 downto 0);
13 wb_dat_i : in std_ulogic_vector(7 downto 0);
14 wb_dat_o : out std_ulogic_vector(7 downto 0);
15 wb_we_i : in std_ulogic;
16 wb_stb_i : in std_ulogic;
17 wb_cyc_i : in std_ulogic;
18 wb_ack_o : out std_ulogic;
19 int_o : out std_ulogic;
20 stx_pad_o : out std_ulogic;
21 srx_pad_i : in std_ulogic;
22 rts_pad_o : out std_ulogic;
23 cts_pad_i : in std_ulogic;
24 dtr_pad_o : out std_ulogic;
25 dsr_pad_i : in std_ulogic;
26 ri_pad_i : in std_ulogic;
27 dcd_pad_i : in std_ulogic
28 );
29 end entity uart_top;
30
31 architecture behaviour of uart_top is
32
33 -- Call POLL every N clocks to generate interrupts
34 constant POLL_DELAY : natural := 100;
35
36 -- Register definitions
37 subtype reg_adr_t is std_ulogic_vector(2 downto 0);
38
39 constant REG_IDX_RXTX : reg_adr_t := "000";
40 constant REG_IDX_IER : reg_adr_t := "001";
41 constant REG_IDX_IIR_FCR : reg_adr_t := "010";
42 constant REG_IDX_LCR : reg_adr_t := "011";
43 constant REG_IDX_MCR : reg_adr_t := "100";
44 constant REG_IDX_LSR : reg_adr_t := "101";
45 constant REG_IDX_MSR : reg_adr_t := "110";
46 constant REG_IDX_SCR : reg_adr_t := "111";
47
48 -- IER bits
49 constant REG_IER_RDI_BIT : natural := 0;
50 constant REG_IER_THRI_BIT : natural := 1;
51 constant REG_IER_RLSI_BIT : natural := 2;
52 constant REG_IER_MSI_BIT : natural := 3;
53
54 -- IIR bit
55 constant REG_IIR_NO_INT : natural := 0;
56 -- IIR values for bit 3 downto 0
57 constant REG_IIR_RDI : std_ulogic_vector(3 downto 1) := "010";
58 constant REG_IIR_THRI : std_ulogic_vector(3 downto 1) := "001";
59 constant REG_IIR_RLSI : std_ulogic_vector(3 downto 1) := "011";
60 constant REG_IIR_MSI : std_ulogic_vector(3 downto 1) := "000";
61
62 -- FCR bits
63 constant REG_FCR_EN_FIFO_BIT : natural := 0; -- Always 1
64 constant REG_FCR_CLR_RCVR_BIT : natural := 1;
65 constant REG_FCR_CLR_XMIT_BIT : natural := 2;
66 constant REG_FCR_DMA_SEL_BIT : natural := 3; -- Not implemented
67 -- FCR values for FIFO threshold in bits 7 downto 6
68 constant REG_FCR_FIFO_TRIG1 : std_ulogic_vector(7 downto 6) := "00";
69 constant REG_FCR_FIFO_TRIG4 : std_ulogic_vector(7 downto 6) := "01";
70 constant REG_FCR_FIFO_TRIG8 : std_ulogic_vector(7 downto 6) := "10";
71 constant REG_FCR_FIFO_TRIG14 : std_ulogic_vector(7 downto 6) := "11";
72
73 -- LCR bits
74 constant REG_LCR_STOP_BIT : natural := 2;
75 constant REG_LCR_PARITY_BIT : natural := 3;
76 constant REG_LCR_EPAR_BIT : natural := 4;
77 constant REG_LCR_SPAR_BIT : natural := 5;
78 constant REG_LCR_SBC_BIT : natural := 6;
79 constant REG_LCR_DLAB_BIT : natural := 7;
80 -- LCR values for data length (bits 1 downto 0)
81 constant REG_LCR_WLEN5 : std_ulogic_vector(1 downto 0) := "00";
82 constant REG_LCR_WLEN6 : std_ulogic_vector(1 downto 0) := "01";
83 constant REG_LCR_WLEN7 : std_ulogic_vector(1 downto 0) := "10";
84 constant REG_LCR_WLEN8 : std_ulogic_vector(1 downto 0) := "11";
85
86 -- MCR bits
87 constant REG_MCR_DTR_BIT : natural := 0;
88 constant REG_MCR_RTS_BIT : natural := 1;
89 constant REG_MCR_OUT1_BIT : natural := 2;
90 constant REG_MCR_OUT2_BIT : natural := 3;
91 constant REG_MCR_LOOP_BIT : natural := 4;
92
93 -- LSR bits
94 constant REG_LSR_DR_BIT : natural := 0;
95 constant REG_LSR_OE_BIT : natural := 1;
96 constant REG_LSR_PE_BIT : natural := 2;
97 constant REG_LSR_FE_BIT : natural := 3;
98 constant REG_LSR_BI_BIT : natural := 4;
99 constant REG_LSR_THRE_BIT : natural := 5;
100 constant REG_LSR_TEMT_BIT : natural := 6;
101 constant REG_LSR_FIFOE_BIT : natural := 7;
102
103 -- MSR bits
104 constant REG_MSR_DCTS_BIT : natural := 0;
105 constant REG_MSR_DDSR_BIT : natural := 1;
106 constant REG_MSR_TERI_BIT : natural := 2;
107 constant REG_MSR_DDCD_BIT : natural := 3;
108 constant REG_MSR_CTS_BIT : natural := 4;
109 constant REG_MSR_DSR_BIT : natural := 5;
110 constant REG_MSR_RI_BIT : natural := 6;
111 constant REG_MSR_DCD_BIT : natural := 7;
112
113 -- Wishbone signals decode:
114 signal reg_idx : reg_adr_t;
115 signal wb_phase : std_ulogic;
116 signal reg_write : std_ulogic;
117 signal reg_read : std_ulogic;
118
119 -- Register storage
120 signal reg_ier : std_ulogic_vector(3 downto 0);
121 signal reg_iir : std_ulogic_vector(3 downto 0);
122 signal reg_fcr : std_ulogic_vector(7 downto 6);
123 signal reg_lcr : std_ulogic_vector(7 downto 0);
124 signal reg_mcr : std_ulogic_vector(4 downto 0);
125 signal reg_lsr : std_ulogic_vector(7 downto 0);
126 signal reg_msr : std_ulogic_vector(7 downto 0);
127 signal reg_scr : std_ulogic_vector(7 downto 0);
128
129 signal reg_div : std_ulogic_vector(15 downto 0);
130
131 -- Control signals
132 signal rx_fifo_clr : std_ulogic;
133 signal tx_fifo_clr : std_ulogic;
134
135 -- Pending interrupts
136 signal int_rdi_pending : std_ulogic;
137 signal int_thri_pending : std_ulogic;
138 signal int_rlsi_pending : std_ulogic;
139 signal int_msi_pending : std_ulogic;
140
141 -- Actual data output
142 signal data_out : std_ulogic_vector(7 downto 0) := x"00";
143
144 -- Incoming data pending signal
145 signal data_in_pending : std_ulogic := '0';
146
147 -- Useful aliases
148 alias dlab : std_ulogic is reg_lcr(REG_LCR_DLAB_BIT);
149
150 alias clk : std_ulogic is wb_clk_i;
151 alias rst : std_ulogic is wb_rst_i;
152 alias cyc : std_ulogic is wb_cyc_i;
153 alias stb : std_ulogic is wb_stb_i;
154 alias we : std_ulogic is wb_we_i;
155 begin
156
157 -- Register index shortcut
158 reg_idx <= wb_adr_i(2 downto 0);
159
160 -- 2 phases WB process.
161 --
162 -- Among others, this gives us a "free" cycle for the
163 -- side effects of some accesses percolate in the form
164 -- of status bit changes in other registers.
165 wb_cycle: process(clk)
166 variable phase : std_ulogic := '0';
167 begin
168 if rising_edge(clk) then
169 if wb_phase = '0' then
170 if cyc = '1' and stb = '1' then
171 wb_ack_o <= '1';
172 wb_phase <= '1';
173 end if;
174 else
175 wb_ack_o <= '0';
176 wb_phase <= '0';
177 end if;
178 end if;
179 end process;
180
181 -- Reg read/write signals
182 reg_write <= cyc and stb and we and not wb_phase;
183 reg_read <= cyc and stb and not we and not wb_phase;
184
185 -- Register read is synchronous to avoid collisions with
186 -- read-clear side effects
187 do_reg_read: process(clk)
188 begin
189 if rising_edge(clk) then
190 wb_dat_o <= x"00";
191 if reg_read = '1' then
192 case reg_idx is
193 when REG_IDX_RXTX =>
194 if dlab = '1' then
195 wb_dat_o <= reg_div(7 downto 0);
196 else
197 wb_dat_o <= data_out;
198 end if;
199 when REG_IDX_IER =>
200 if dlab = '1' then
201 wb_dat_o <= reg_div(15 downto 8);
202 else
203 wb_dat_o <= "0000" & reg_ier;
204 end if;
205 when REG_IDX_IIR_FCR =>
206 -- Top bits always set as FIFO is always enabled
207 wb_dat_o <= "1100" & reg_iir;
208 when REG_IDX_LCR =>
209 wb_dat_o <= reg_lcr;
210 when REG_IDX_LSR =>
211 wb_dat_o <= reg_lsr;
212 when REG_IDX_MSR =>
213 wb_dat_o <= reg_msr;
214 when REG_IDX_SCR =>
215 wb_dat_o <= reg_scr;
216 when others =>
217 end case;
218 end if;
219 end if;
220 end process;
221
222 -- Receive/send synchronous process
223 rxtx: process(clk)
224 variable dp : std_ulogic;
225 variable poll_cnt : natural;
226 variable sim_tmp : std_ulogic_vector(63 downto 0);
227 begin
228 if rising_edge(clk) then
229 if rst = '0' then
230 dp := data_in_pending;
231 if dlab = '0' and reg_idx = REG_IDX_RXTX then
232 if reg_write = '1' then
233 -- FIFO write
234 -- XXX Simulate the FIFO and delays for more
235 -- accurate behaviour & interrupts
236 sim_console_write(x"00000000000000" & wb_dat_i);
237 end if;
238 if reg_read = '1' then
239 dp := '0';
240 data_out <= x"00";
241 end if;
242 end if;
243
244 -- Poll for incoming data
245 if poll_cnt = 0 or (reg_read = '1' and reg_idx = REG_IDX_LSR) then
246 sim_console_poll(sim_tmp);
247 poll_cnt := POLL_DELAY;
248 if dp = '0' and sim_tmp(0) = '1' then
249 dp := '1';
250 sim_console_read(sim_tmp);
251 data_out <= sim_tmp(7 downto 0);
252 end if;
253 poll_cnt := poll_cnt - 1;
254 end if;
255 data_in_pending <= dp;
256 end if;
257 end if;
258 end process;
259
260 -- Interrupt pending bits
261 int_rdi_pending <= data_in_pending;
262 int_thri_pending <= '1';
263 int_rlsi_pending <= reg_lsr(REG_LSR_OE_BIT) or
264 reg_lsr(REG_LSR_PE_BIT) or
265 reg_lsr(REG_LSR_FE_BIT) or
266 reg_lsr(REG_LSR_BI_BIT);
267 int_msi_pending <= reg_msr(REG_MSR_DCTS_BIT) or
268 reg_msr(REG_MSR_DDSR_BIT) or
269 reg_msr(REG_MSR_TERI_BIT) or
270 reg_msr(REG_MSR_DDCD_BIT);
271
272 -- Derive interrupt output from IIR
273 int_o <= not reg_iir(REG_IIR_NO_INT);
274
275 -- Divisor register
276 div_reg_w: process(clk)
277 begin
278 if rising_edge(clk) then
279 if rst = '1' then
280 reg_div <= (others => '0');
281 elsif reg_write = '1' and dlab = '1' then
282 if reg_idx = REG_IDX_RXTX then
283 reg_div(7 downto 0) <= wb_dat_i;
284 elsif reg_idx = REG_IDX_IER then
285 reg_div(15 downto 8) <= wb_dat_i;
286 end if;
287 end if;
288 end if;
289 end process;
290
291 -- IER register
292 ier_reg_w: process(clk)
293 begin
294 if rising_edge(clk) then
295 if rst = '1' then
296 reg_ier <= "0000";
297 else
298 if reg_write = '1' and dlab = '0' and reg_idx = REG_IDX_IER then
299 reg_ier <= wb_dat_i(3 downto 0);
300 end if;
301 end if;
302 end if;
303 end process;
304
305 -- IIR (read only) generation
306 iir_reg_w: process(clk)
307 begin
308 if rising_edge(clk) then
309 reg_iir <= "0001";
310 if int_rlsi_pending = '1' and reg_ier(REG_IER_RLSI_BIT) = '1' then
311 reg_iir <= REG_IIR_RLSI & "0";
312 elsif int_rdi_pending = '1' and reg_ier(REG_IER_RDI_BIT) = '1' then
313 reg_iir <= REG_IIR_RDI & "0";
314 elsif int_thri_pending = '1' and reg_ier(REG_IER_THRI_BIT) = '1' then
315 reg_iir <= REG_IIR_THRI & "0";
316 elsif int_msi_pending = '1' and reg_ier(REG_IER_MSI_BIT) = '1' then
317 reg_iir <= REG_IIR_MSI & "0";
318 end if;
319
320 -- It *seems* like reading IIR should clear THRI for
321 -- some amount of time until it gets set again a few
322 -- clocks later if the transmitter is still empty. We
323 -- don't do that at this point.
324 end if;
325 end process;
326
327 -- FCR (write only) register
328 fcr_reg_w: process(clk)
329 begin
330 if rising_edge(clk) then
331 if rst = '1' then
332 reg_fcr <= "11";
333 rx_fifo_clr <= '1';
334 tx_fifo_clr <= '1';
335 elsif reg_write = '1' and reg_idx = REG_IDX_IIR_FCR then
336 reg_fcr <= wb_dat_i(7 downto 6);
337 rx_fifo_clr <= wb_dat_i(REG_FCR_CLR_RCVR_BIT);
338 tx_fifo_clr <= wb_dat_i(REG_FCR_CLR_XMIT_BIT);
339 else
340 rx_fifo_clr <= '0';
341 tx_fifo_clr <= '0';
342 end if;
343 end if;
344 end process;
345
346 -- LCR register
347 lcr_reg_w: process(clk)
348 begin
349 if rising_edge(clk) then
350 if rst = '1' then
351 reg_lcr <= "00000011";
352 elsif reg_write = '1' and reg_idx = REG_IDX_LCR then
353 reg_lcr <= wb_dat_i;
354 end if;
355 end if;
356 end process;
357
358 -- MCR register
359 mcr_reg_w: process(clk)
360 begin
361 if rising_edge(clk) then
362 if rst = '1' then
363 reg_mcr <= "00000";
364 elsif reg_write = '1' and reg_idx = REG_IDX_MCR then
365 reg_mcr <= wb_dat_i(4 downto 0);
366 end if;
367 end if;
368 end process;
369
370 -- LSR register
371 lsr_reg_w: process(clk)
372 begin
373 if rising_edge(clk) then
374 if rst = '1' then
375 reg_lsr <= "00000000";
376 else
377 reg_lsr(REG_LSR_DR_BIT) <= data_in_pending;
378
379 -- Clear error bits on read. Those bits are
380 -- always 0 in sim for now.
381 -- if reg_read = '1' and reg_idx = REG_IDX_LSR then
382 -- reg_lsr(REG_LSR_OE_BIT) <= '0';
383 -- reg_lsr(REG_LSR_PE_BIT) <= '0';
384 -- reg_lsr(REG_LSR_FE_BIT) <= '0';
385 -- reg_lsr(REG_LSR_BI_BIT) <= '0';
386 -- reg_lsr(REG_LSR_FIFOE_BIT) <= '0';
387 -- end if;
388
389 -- Tx FIFO empty indicators. Always empty in sim
390 reg_lsr(REG_LSR_THRE_BIT) <= '1';
391 reg_lsr(REG_LSR_TEMT_BIT) <= '1';
392 end if;
393 end if;
394 end process;
395
396 -- MSR register
397 msr_reg_w: process(clk)
398 begin
399 if rising_edge(clk) then
400 if rst = '1' then
401 reg_msr <= "00000000";
402 elsif reg_read = '1' and reg_idx = REG_IDX_MSR then
403 reg_msr <= "00000000";
404 -- XXX TODO bit setting machine...
405 end if;
406 end if;
407 end process;
408
409 -- SCR register
410 scr_reg_w: process(clk)
411 begin
412 if rising_edge(clk) then
413 if rst = '1' then
414 reg_scr <= "00000000";
415 elsif reg_write = '1' and reg_idx = REG_IDX_SCR then
416 reg_scr <= wb_dat_i;
417 end if;
418 end if;
419 end process;
420
421 end architecture behaviour;