LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; LIBRARY WORK; USE WORK.uart_types.all; ENTITY uart_wb IS Port ( CLK_I : in STD_LOGIC; RST_I : in STD_LOGIC; INT_O : out 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); ser_rx : in std_logic; ser_tx : out std_logic ); END uart_wb; ARCHITECTURE rtl OF uart_wb IS COMPONENT uart Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; we : in STD_LOGIC; re : in STD_LOGIC; din : in unsigned(7 downto 0); dout : out unsigned(7 downto 0); ser_rx : in std_logic; ser_tx : out std_logic; ctrl : in ctrl_t; status : out status_t ); END COMPONENT; -- Signals for UART connections signal reg_uart_baud : unsigned(15 downto 0); signal reg_we_uart_tx : std_logic; signal reg_re_uart_rx : std_logic; signal reg_uart_tx : unsigned(7 downto 0); signal reg_uart_rx : unsigned(7 downto 0); signal uart_status_port : unsigned(15 downto 0); signal rx_int_en : std_logic; signal tx_int_en : std_logic; signal irq_rx : std_logic; signal irq_tx : std_logic; signal ctrl : ctrl_t; signal status : status_t; begin SRDY_O <= CYC_I; ctrl.baudrate <= reg_uart_baud; inst_uart : uart PORT MAP ( clk => CLK_I, rst => RST_I, we => reg_we_uart_tx, re => reg_re_uart_rx, din => reg_uart_tx, dout => reg_uart_rx, ser_rx => ser_rx, ser_tx => ser_tx, ctrl => ctrl, status => status ); ------------------------------------------------------------------ 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, 16); 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_uart_tx <= DAT_I(7 downto 0); reg_we_uart_tx <= '1'; when "0001" => rx_int_en <= DAT_I(6); tx_int_en <= DAT_I(5); when "0010" => reg_uart_baud <= DAT_I(15 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) <= reg_uart_rx; when "0001" => DAT_O(15 downto 0) <= uart_status_port; when "0010" => DAT_O(15 downto 0) <= reg_uart_baud; when others => null; end case; end if; end if; end process; irq_register: process(CLK_I) begin if rising_edge(CLK_I) then irq_tx <= status.tx_empty and tx_int_en; irq_rx <= status.rx_present and rx_int_en; end if; end process; uart_status_port <= "000000" & irq_rx & irq_tx & '0' & rx_int_en & tx_int_en & status.rx_present & '0' & '0' & status.tx_full & status.tx_full; INT_O <= irq_rx or irq_tx; end rtl;