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_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_baud : unsigned(7 downto 0); signal rx_int_en : std_logic; signal tx_int_en : std_logic; 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); rx_int_en <= '0'; tx_int_en <= '0'; elsif (STB_I and CYC_I and WE_I) = '1' then case ADDR_I(5 downto 2) is when "0000" => reg_we_uart_tx <= '1'; reg_uart_tx <= DAT_I(7 downto 0); when "0001" => rx_int_en <= DAT_I(6); tx_int_en <= DAT_I(5); when "0010" => reg_uart_baud <= DAT_I(7 downto 0); 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 <= '0' & rx_int_en & tx_int_en & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full; INT_O <= (rx_data_present and rx_int_en) or (not tx_full and tx_int_en); end behavior;