-- `Deep Thought', a softcore CPU implemented on a FPGA -- -- Copyright (C) 2010 Markus Hofstaetter -- Copyright (C) 2010 Martin Perner -- Copyright (C) 2010 Stefan Rebernig -- Copyright (C) 2010 Manfred Schwarz -- Copyright (C) 2010 Bernhard Urban -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use work.common_pkg.all; use work.core_pkg.all; use work.mem_pkg.all; use work.extension_pkg.all; use work.extension_uart_pkg.all; architecture behav of extension_uart is signal w1_st_co, w1_st_co_nxt, w2_uart_config, w2_uart_config_nxt, w3_uart_send, w3_uart_send_nxt, w4_uart_receive, w4_uart_receive_nxt : gp_register_t; signal new_bus_rx,new_wb_data, new_wb_data_nxt, new_tx_data, new_tx_data_nxt, tx_rdy, tx_rdy_int : std_logic; signal bd_rate : baud_rate_l; signal rx_data : std_logic_vector(7 downto 0); signal uart_int_nxt : std_logic; signal uart_data_read_nxt : std_logic; begin rs232_tx_inst : rs232_tx generic map( RESET_VALUE ) port map( --System inputs clk, reset, --Bus bus_tx, --From/to sendlogic new_tx_data, w3_uart_send(byte_t'range), tx_rdy, bd_rate, w1_st_co(16) ); rs232_rx_inst : rs232_rx generic map( RESET_VALUE, 2 ) port map( --System inputs clk, reset, --Bus bus_rx, --From/to sendlogic new_bus_rx, rx_data, bd_rate ); syn : process (clk, reset) begin if (reset = RESET_VALUE) then w1_st_co <= (others=>'0'); w2_uart_config(31 downto 16) <= (others=>'0'); w2_uart_config(15 downto 0) <= std_logic_vector(to_unsigned(CLK_PER_BAUD, 16)); w3_uart_send <= (others=>'0'); w4_uart_receive <= (others=>'0'); tx_rdy_int <= '0'; new_tx_data <= '0'; uart_int <= '0'; elsif rising_edge(clk) then w1_st_co <= w1_st_co_nxt; w2_uart_config <= w2_uart_config_nxt; w3_uart_send <= w3_uart_send_nxt; w4_uart_receive <= w4_uart_receive_nxt; new_tx_data <= new_tx_data_nxt; tx_rdy_int <= tx_rdy; uart_int <= uart_int_nxt; end if; end process syn; -------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------ gwriten : process (ext_reg,tx_rdy,w1_st_co,w2_uart_config,w3_uart_send,w4_uart_receive,tx_rdy_int, rx_data, new_bus_rx, uart_data_read_nxt) variable tmp_data : gp_register_t; begin uart_int_nxt <= '0'; w1_st_co_nxt <= w1_st_co; w2_uart_config_nxt <= w2_uart_config; w3_uart_send_nxt <= w3_uart_send; w4_uart_receive_nxt <= w4_uart_receive; if ext_reg.sel = '1' and ext_reg.wr_en = '1' then tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) :=ext_reg.data(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := ext_reg.data((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := ext_reg.data((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := ext_reg.data((4*byte_t'length-1) downto 3*byte_t'length); end if; case ext_reg.addr(1 downto 0) is when "00" => w1_st_co_nxt <= tmp_data; when "01" => w2_uart_config_nxt <= tmp_data; when "10" => w1_st_co_nxt(0) <= '1'; -- busy flag set w3_uart_send_nxt <= tmp_data; when "11" => --w4_uart_receive_nxt <= tmp_data; sollte nur gelesen werden when others => null; end case; end if; if tx_rdy = '1' and tx_rdy_int = '0' then w1_st_co_nxt(0) <= '0'; -- busy flag reset end if; if new_bus_rx = '1' then w4_uart_receive_nxt(7 downto 0) <= rx_data; w1_st_co_nxt(1) <= '1'; uart_int_nxt <= '1'; end if; if (uart_data_read_nxt = '1' and w1_st_co(1) = '1' and ext_reg.sel = '1') then w1_st_co_nxt(1) <= '0'; end if; end process gwriten; gread : process (clk,ext_reg,w1_st_co,w2_uart_config,w3_uart_send,w4_uart_receive) variable tmp_data : gp_register_t; begin uart_data_read_nxt <= '0'; if ext_reg.sel = '1' and ext_reg.wr_en = '0' then case ext_reg.addr(1 downto 0) is when "00" => tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) := w1_st_co(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := w1_st_co((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w1_st_co((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w1_st_co((4*byte_t'length-1) downto 3*byte_t'length); end if; data_out <= tmp_data; when "01" => tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) := w2_uart_config(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := w2_uart_config((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w2_uart_config((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w2_uart_config((4*byte_t'length-1) downto 3*byte_t'length); end if; data_out <= tmp_data; when "10" => tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) := w3_uart_send(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := w3_uart_send((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w3_uart_send((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w3_uart_send((4*byte_t'length-1) downto 3*byte_t'length); end if; data_out <= tmp_data; when "11" => tmp_data := (others =>'0'); uart_data_read_nxt <= '1'; if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) := w4_uart_receive(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := w4_uart_receive((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w4_uart_receive((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w4_uart_receive((4*byte_t'length-1) downto 3*byte_t'length); end if; data_out <= tmp_data; when others => null; end case; else data_out <= (others=>'0'); end if; end process gread; -------------------------- LESEN UND SCHREIBEN ENDE --------------------------------------------------------------- -------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------ dataprocess : process (ext_reg,tx_rdy,w2_uart_config) begin new_tx_data_nxt <= '0'; bd_rate <= w2_uart_config(15 downto 0); if ext_reg.sel = '1' and ext_reg.wr_en = '1' then case ext_reg.addr(1 downto 0) is when "00" => when "01" => when "10" => new_tx_data_nxt <= '1'; when "11" => when others => null; end case; end if; end process dataprocess; -------------------------- INTERNE VERARBEITUNG ENDE -------------------------------------------------------------- end behav;