|
- ---------------------------------------------------------------------
- -- TITLE: UART
- -- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
- -- DATE CREATED: 5/29/02
- -- FILENAME: uart.vhd
- -- PROJECT: Plasma CPU core
- -- COPYRIGHT: Software placed into the public domain by the author.
- -- Software 'as is' without warranty. Author liable for nothing.
- -- DESCRIPTION:
- -- Implements the UART.
- ---------------------------------------------------------------------
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_misc.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_textio.all;
- use ieee.std_logic_unsigned.all;
- use std.textio.all;
- use work.mlite_pack.all;
-
- entity uart is
- generic(log_file : string := "UNUSED");
- port(clk : in std_logic;
- reset : in std_logic;
- enable_read : in std_logic;
- enable_write : in std_logic;
- data_in : in std_logic_vector(7 downto 0);
- data_out : out std_logic_vector(7 downto 0);
- uart_read : in std_logic;
- uart_write : out std_logic;
- busy_write : out std_logic;
- data_avail : out std_logic);
- end; --entity uart
-
- architecture logic of uart is
- signal delay_write_reg : std_logic_vector(9 downto 0);
- signal bits_write_reg : std_logic_vector(3 downto 0);
- signal data_write_reg : std_logic_vector(8 downto 0);
- signal delay_read_reg : std_logic_vector(9 downto 0);
- signal bits_read_reg : std_logic_vector(3 downto 0);
- signal data_read_reg : std_logic_vector(7 downto 0);
- signal data_save_reg : std_logic_vector(17 downto 0);
- signal busy_write_sig : std_logic;
- signal read_value_reg : std_logic_vector(6 downto 0);
- signal uart_read2 : std_logic;
-
- begin
-
- uart_proc: process(clk, reset, enable_read, enable_write, data_in,
- data_write_reg, bits_write_reg, delay_write_reg,
- data_read_reg, bits_read_reg, delay_read_reg,
- data_save_reg, read_value_reg, uart_read2,
- busy_write_sig, uart_read)
- constant COUNT_VALUE : std_logic_vector(9 downto 0) :=
- "0100011110"; --33MHz/2/57600Hz = 0x11e
- -- "1101100100"; --50MHz/57600Hz = 0x364
- -- "0110110010"; --25MHz/57600Hz = 0x1b2 -- Plasma IF uses div2
- -- "0011011001"; --12.5MHz/57600Hz = 0xd9
- -- "0000000100"; --for debug (shorten read_value_reg)
- begin
- uart_read2 <= read_value_reg(read_value_reg'length - 1);
-
- if reset = '1' then
- data_write_reg <= ZERO(8 downto 1) & '1';
- bits_write_reg <= "0000";
- delay_write_reg <= ZERO(9 downto 0);
- read_value_reg <= ONES(read_value_reg'length-1 downto 0);
- data_read_reg <= ZERO(7 downto 0);
- bits_read_reg <= "0000";
- delay_read_reg <= ZERO(9 downto 0);
- data_save_reg <= ZERO(17 downto 0);
- elsif rising_edge(clk) then
-
- --Write UART
- if bits_write_reg = "0000" then --nothing left to write?
- if enable_write = '1' then
- delay_write_reg <= ZERO(9 downto 0); --delay before next bit
- bits_write_reg <= "1010"; --number of bits to write
- data_write_reg <= data_in & '0'; --remember data & start bit
- end if;
- else
- if delay_write_reg /= COUNT_VALUE then
- delay_write_reg <= delay_write_reg + 1; --delay before next bit
- else
- delay_write_reg <= ZERO(9 downto 0); --reset delay
- bits_write_reg <= bits_write_reg - 1; --bits left to write
- data_write_reg <= '1' & data_write_reg(8 downto 1);
- end if;
- end if;
-
- --Average uart_read signal
- if uart_read = '1' then
- if read_value_reg /= ONES(read_value_reg'length - 1 downto 0) then
- read_value_reg <= read_value_reg + 1;
- end if;
- else
- if read_value_reg /= ZERO(read_value_reg'length - 1 downto 0) then
- read_value_reg <= read_value_reg - 1;
- end if;
- end if;
-
- --Read UART
- if delay_read_reg = ZERO(9 downto 0) then --done delay for read?
- if bits_read_reg = "0000" then --nothing left to read?
- if uart_read2 = '0' then --wait for start bit
- delay_read_reg <= '0' & COUNT_VALUE(9 downto 1); --half period
- bits_read_reg <= "1001"; --bits left to read
- end if;
- else
- delay_read_reg <= COUNT_VALUE; --initialize delay
- bits_read_reg <= bits_read_reg - 1; --bits left to read
- data_read_reg <= uart_read2 & data_read_reg(7 downto 1);
- end if;
- else
- delay_read_reg <= delay_read_reg - 1; --delay
- end if;
-
- --Control character buffer
- if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then
- if data_save_reg(8) = '0' or
- (enable_read = '1' and data_save_reg(17) = '0') then
- --Empty buffer
- data_save_reg(8 downto 0) <= '1' & data_read_reg;
- else
- --Second character in buffer
- data_save_reg(17 downto 9) <= '1' & data_read_reg;
- if enable_read = '1' then
- data_save_reg(8 downto 0) <= data_save_reg(17 downto 9);
- end if;
- end if;
- elsif enable_read = '1' then
- data_save_reg(17) <= '0'; --data_available
- data_save_reg(8 downto 0) <= data_save_reg(17 downto 9);
- end if;
- end if; --rising_edge(clk)
-
- uart_write <= data_write_reg(0);
- if bits_write_reg /= "0000"
- -- Comment out the following line for full UART simulation (much slower)
- and log_file = "UNUSED"
- then
- busy_write_sig <= '1';
- else
- busy_write_sig <= '0';
- end if;
- busy_write <= busy_write_sig;
- data_avail <= data_save_reg(8);
- data_out <= data_save_reg(7 downto 0);
-
- end process; --uart_proc
-
- -- synthesis_off
- uart_logger:
- if log_file /= "UNUSED" generate
- uart_proc: process(clk, enable_write, data_in)
- file store_file : text open write_mode is log_file;
- variable hex_file_line : line;
- variable c : character;
- variable index : natural;
- variable line_length : natural := 0;
- begin
- if rising_edge(clk) and busy_write_sig = '0' then
- if enable_write = '1' then
- index := conv_integer(data_in(6 downto 0));
- if index /= 10 then
- c := character'val(index);
- write(hex_file_line, c);
- line_length := line_length + 1;
- end if;
- if index = 10 or line_length >= 72 then
- --The following line may have to be commented out for synthesis
- writeline(store_file, hex_file_line);
- line_length := 0;
- end if;
- end if; --uart_sel
- end if; --rising_edge(clk)
- end process; --uart_proc
- end generate; --uart_logger
- -- synthesis_on
-
- end; --architecture logic
|