diff --git a/lib/uart/uart_wb.vhd b/lib/uart/uart_wb.vhd new file mode 100644 index 0000000..dd1d5fd --- /dev/null +++ b/lib/uart/uart_wb.vhd @@ -0,0 +1,186 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +ENTITY uart_wb IS + Port + ( + CLK_I : in STD_LOGIC; + RST_I : in STD_LOGIC; + CYC_I : in STD_LOGIC; + STB_I : in STD_LOGIC; + SEL_I : in unsigned(3 downto 0); + WE_I : in STD_LOGIC; + ACK_O : out STD_LOGIC; + SRDY_O : out STD_LOGIC; + MRDY_I : in STD_LOGIC; + ADDR_I : in unsigned(31 downto 0); + DAT_I : in unsigned(31 downto 0); + DAT_O : out unsigned(31 downto 0); + INT_RX_O : out STD_LOGIC; + INT_TX_O : out STD_LOGIC; + ser_rx : in std_logic; + ser_tx : out std_logic + ); +END uart_wb; + +ARCHITECTURE behavior OF uart_wb IS + + COMPONENT uart_tx + Port + ( + data_in : in std_logic_vector(7 downto 0); + write_buffer : in std_logic; + reset_buffer : in std_logic; + en_16_x_baud : in std_logic; + serial_out : out std_logic; + buffer_full : out std_logic; + buffer_half_full : out std_logic; + clk : in std_logic + ); + END COMPONENT; + + COMPONENT uart_rx + Port + ( + serial_in : in std_logic; + data_out : out std_logic_vector(7 downto 0); + read_buffer : in std_logic; + reset_buffer : in std_logic; + en_16_x_baud : in std_logic; + buffer_data_present : out std_logic; + buffer_full : out std_logic; + buffer_half_full : out std_logic; + clk : in std_logic + ); + END COMPONENT; + + -- Signals for UART connections + signal baud_count : unsigned(7 downto 0); + signal en_16_x_baud : std_logic; + signal reg_we_uart_tx : std_logic; + signal tx_full : std_logic; + signal tx_half_full : std_logic; + signal reg_re_uart_rx : std_logic; + signal reg_uart_tx : unsigned(7 downto 0); + signal reg_uart_rx : std_logic_vector(7 downto 0); + signal rx_data_present : std_logic; + signal rx_full : std_logic; + signal rx_half_full : std_logic; + signal uart_status_port : unsigned(7 downto 0); + signal reg_uart_ctrl : unsigned(7 downto 0); + signal reg_uart_baud : unsigned(7 downto 0); + +begin + + SRDY_O <= CYC_I; + +------------------------------------------------------------------ +registers_write: + process(CLK_I) + begin + if rising_edge(CLK_I) then + reg_we_uart_tx <= '0'; + if RST_I = '1' then + reg_uart_baud <= to_unsigned(53, 8); + reg_uart_ctrl <= to_unsigned(0, 8); + elsif (STB_I and CYC_I and WE_I) = '1' then + case ADDR_I(5 downto 2) is + + when "0000" => + if SEL_I(0) = '1' then + reg_we_uart_tx <= '1'; + reg_uart_tx <= DAT_I(7 downto 0); + end if; + + when "0001" => + if SEL_I(0) = '1' then + reg_uart_ctrl <= DAT_I(7 downto 0); + end if; + + when "0010" => + if SEL_I(0) = '1' then + reg_uart_baud <= DAT_I(7 downto 0); + end if; + + when others => null; + end case; + end if; + end if; + end process; + +registers_read: + process(CLK_I) + begin + if rising_edge(CLK_I) then + reg_re_uart_rx <= '0'; + ACK_O <= '0'; + if (STB_I and CYC_I) = '1' then + ACK_O <= not WE_I; + DAT_O <= (others => '0'); + case ADDR_I(5 downto 2) is + + when "0000" => + reg_re_uart_rx <= not WE_I; + DAT_O(7 downto 0) <= unsigned(reg_uart_rx); + + when "0001" => + DAT_O(7 downto 0) <= uart_status_port; + + when "0010" => + DAT_O(7 downto 0) <= reg_uart_baud; + + when others => null; + end case; + end if; + end if; + end process; + +baud_timer: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + baud_count <= (others => '0'); + elsif baud_count = reg_uart_baud then + baud_count <= (others => '0'); + en_16_x_baud <= '1'; + else + baud_count <= baud_count + 1; + en_16_x_baud <= '0'; + end if; + end if; + end process; + +inst_uart_tx: uart_tx + port map + ( + data_in => std_logic_vector(reg_uart_tx), + write_buffer => reg_we_uart_tx, + reset_buffer => RST_I, + en_16_x_baud => en_16_x_baud, + serial_out => ser_tx, + buffer_full => tx_full, + buffer_half_full => tx_half_full, + clk => CLK_I + ); + +inst_uart_rx: uart_rx + port map + ( + serial_in => ser_rx, + data_out => reg_uart_rx, + read_buffer => reg_re_uart_rx, + reset_buffer => RST_I, + en_16_x_baud => en_16_x_baud, + buffer_data_present => rx_data_present, + buffer_full => rx_full, + buffer_half_full => rx_half_full, + clk => CLK_I + ); + + uart_status_port <= (7 downto 5 => '0') & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full; + INT_RX_O <= rx_data_present; + INT_TX_O <= not tx_full; + +end behavior;