Add Tercel PHY reset synchronization
[microwatt.git] / sim_pp_uart.vhdl
1 -- Sim console UART, provides the same interface as potato UART by
2 -- Kristian Klomsten Skordal.
3
4 library ieee;
5 use ieee.std_logic_1164.all;
6 use ieee.numeric_std.all;
7
8 library work;
9 use work.wishbone_types.all;
10 use work.sim_console.all;
11
12 --! @brief Simple UART module.
13 --! The following registers are defined:
14 --! |--------------------|--------------------------------------------|
15 --! | Address | Description |
16 --! |--------------------|--------------------------------------------|
17 --! | 0x00 | Transmit register (write-only) |
18 --! | 0x08 | Receive register (read-only) |
19 --! | 0x10 | Status register (read-only) |
20 --! | 0x18 | Sample clock divisor register (dummy) |
21 --! | 0x20 | Interrupt enable register (read/write) |
22 --! |--------------------|--------------------------------------------|
23 --!
24 --! The status register contains the following bits:
25 --! - Bit 0: receive buffer empty
26 --! - Bit 1: transmit buffer empty
27 --! - Bit 2: receive buffer full
28 --! - Bit 3: transmit buffer full
29 --!
30 --! Interrupts are enabled by setting the corresponding bit in the interrupt
31 --! enable register. The following bits are available:
32 --! - Bit 0: data received (receive buffer not empty)
33 --! - Bit 1: ready to send data (transmit buffer empty)
34 entity pp_soc_uart is
35 generic(
36 FIFO_DEPTH : natural := 64 --Unused
37 );
38 port(
39 clk : in std_logic;
40 reset : in std_logic;
41
42 -- UART ports:
43 txd : out std_logic;
44 rxd : in std_logic;
45
46 -- Interrupt signal:
47 irq : out std_logic;
48
49 -- Wishbone ports:
50 wb_adr_in : in std_logic_vector(11 downto 0);
51 wb_dat_in : in std_logic_vector( 7 downto 0);
52 wb_dat_out : out std_logic_vector( 7 downto 0);
53 wb_we_in : in std_logic;
54 wb_cyc_in : in std_logic;
55 wb_stb_in : in std_logic;
56 wb_ack_out : out std_logic
57 );
58 end entity pp_soc_uart;
59
60 architecture behaviour of pp_soc_uart is
61
62 signal sample_clk_divisor : std_logic_vector(7 downto 0);
63
64 -- IRQ enable signals:
65 signal irq_recv_enable, irq_tx_ready_enable : std_logic := '0';
66
67 -- Wishbone signals:
68 type wb_state_type is (IDLE, WRITE_ACK, READ_ACK);
69 signal wb_state : wb_state_type;
70 signal wb_ack : std_logic; --! Wishbone acknowledge signal
71
72 begin
73
74 wb_ack_out <= wb_ack and wb_cyc_in and wb_stb_in;
75
76 -- For the sim console, the transmit buffer is always empty, so always
77 -- interrupt if enabled. No recieve interrupt.
78 irq <= irq_tx_ready_enable;
79
80 wishbone: process(clk)
81 variable sim_tmp : std_logic_vector(63 downto 0);
82 begin
83 if rising_edge(clk) then
84 if reset = '1' then
85 wb_ack <= '0';
86 wb_state <= IDLE;
87 sample_clk_divisor <= (others => '0');
88 irq_recv_enable <= '0';
89 irq_tx_ready_enable <= '0';
90 else
91 case wb_state is
92 when IDLE =>
93 if wb_cyc_in = '1' and wb_stb_in = '1' then
94 if wb_we_in = '1' then -- Write to register
95 if wb_adr_in(11 downto 0) = x"000" then
96 sim_console_write(x"00000000000000" & wb_dat_in);
97 elsif wb_adr_in(11 downto 0) = x"018" then
98 sample_clk_divisor <= wb_dat_in;
99 elsif wb_adr_in(11 downto 0) = x"020" then
100 irq_recv_enable <= wb_dat_in(0);
101 irq_tx_ready_enable <= wb_dat_in(1);
102 end if;
103 wb_ack <= '1';
104 wb_state <= WRITE_ACK;
105 else -- Read from register
106 if wb_adr_in(11 downto 0) = x"008" then
107 sim_console_read(sim_tmp);
108 wb_dat_out <= sim_tmp(7 downto 0);
109 elsif wb_adr_in(11 downto 0) = x"010" then
110 sim_console_poll(sim_tmp);
111 wb_dat_out <= "00000" & sim_tmp(0) & '1' & not sim_tmp(0);
112 elsif wb_adr_in(11 downto 0) = x"018" then
113 wb_dat_out <= sample_clk_divisor;
114 elsif wb_adr_in(11 downto 0) = x"020" then
115 wb_dat_out <= (0 => irq_recv_enable,
116 1 => irq_tx_ready_enable,
117 others => '0');
118 else
119 wb_dat_out <= (others => '0');
120 end if;
121 wb_ack <= '1';
122 wb_state <= READ_ACK;
123 end if;
124 end if;
125 when WRITE_ACK|READ_ACK =>
126 if wb_stb_in = '0' then
127 wb_ack <= '0';
128 wb_state <= IDLE;
129 end if;
130 end case;
131 end if;
132 end if;
133 end process wishbone;
134
135 end architecture behaviour;