OpenCores
URL https://opencores.org/ocsvn/light8080/light8080/trunk

Subversion Repositories light8080

[/] [light8080/] [trunk/] [vhdl/] [demos/] [4kbasic/] [rs232_rx.vhdl] - Rev 82

Compare with Previous | Blame | View Log

--##############################################################################
-- RS-232 receiver, parametrizable bit rate through generics.
-- Bit rate defaults to 19200 bps @50MHz.
-- WARNING: Hacked up for light8080 demo. Poor performance, no formal testing!
-- I don't advise using this in for any general purpose.
--##############################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
entity rs232_rx is
  generic (
    BAUD_RATE     : integer := 19200;
    CLOCK_FREQ    : integer := 50000000);
    port ( 
        rxd       : in std_logic;
 
        data_rx   : out std_logic_vector(7 downto 0);
        rx_rdy    : out std_logic;
        read_rx   : in std_logic;
 
        clk       : in std_logic;
        reset     : in std_logic);
end rs232_rx;
 
architecture hardwired of rs232_rx is
 
-- Bit sampling period is 1/16 of the baud rate
constant SAMPLING_PERIOD : integer := (CLOCK_FREQ / BAUD_RATE) / 16;
 
 
--##############################################################################
 
-- Serial port signals
signal rxd_q :            std_logic;
signal tick_ctr :         std_logic_vector(3 downto 0);
signal state :            std_logic_vector(3 downto 0);
signal next_state :       std_logic_vector(3 downto 0);
signal start_bit_detected : std_logic;
signal reset_tick_ctr :   std_logic;
signal stop_bit_sampled : std_logic;
signal load_rx_buffer :   std_logic;
signal stop_error :       std_logic;
signal samples :          std_logic_vector(2 downto 0);
signal sampled_bit :      std_logic;
signal do_shift :         std_logic;
signal rx_buffer :        std_logic_vector(7 downto 0);
signal rx_shift_reg :     std_logic_vector(9 downto 0);
signal tick_ctr_enable :  std_logic;
signal tick_baud_ctr :    std_logic_vector(10 downto 0);
 
signal rx_rdy_flag :      std_logic;
signal set_rx_rdy_flag :  std_logic;
 
 
begin
 
process(clk)
begin
  if clk'event and clk='1' then
    if reset='1' then
      tick_baud_ctr <= (others => '0');
    else
      if conv_integer(tick_baud_ctr)=SAMPLING_PERIOD then -- 325 for 9600 bps
        tick_baud_ctr <= (others => '0');
      else
        tick_baud_ctr <= tick_baud_ctr + 1;
      end if;
    end if;
  end if;
end process;
 
tick_ctr_enable<= '1' when conv_integer(tick_baud_ctr)=SAMPLING_PERIOD else '0';
 
process(clk)
begin
  if clk'event and clk='1' then
    if reset='1' then
      rxd_q <= '0';
    else
      if tick_ctr_enable='1' then
        rxd_q <= rxd;
      end if;
    end if;
  end if;
end process;
 
 
start_bit_detected <= '1' when state="0000" and rxd_q='1' and rxd='0' else '0';
reset_tick_ctr <= '1' when start_bit_detected='1' else '0';
 
stop_bit_sampled <= '1' when state="1010" and tick_ctr="1011" else '0';
load_rx_buffer <= '1' when stop_bit_sampled='1' and sampled_bit='1' else '0';
stop_error <= '1' when stop_bit_sampled='1' and sampled_bit='0' else '0';
 
process(clk)
begin
  if clk'event and clk='1' then
    if reset='1' then
      tick_ctr <= "0000";
    else
      if tick_ctr_enable='1' then
        if tick_ctr="1111" or reset_tick_ctr='1' then
          tick_ctr <= "0000";
        else
          tick_ctr <= tick_ctr + 1;
        end if;
      end if;
    end if;
  end if;
end process;
 
next_state <= 
  "0001" when state="0000" and start_bit_detected='1' else
  "0000" when state="0001" and tick_ctr="1010" and sampled_bit='1' else
  "0000" when state="1010" and tick_ctr="1111" else
  state + 1 when tick_ctr="1111" and do_shift='1' else
  state;
 
 
process(clk)
begin
  if clk'event and clk='1' then
    if reset='1' then
      state <= "0000";
    else
      if tick_ctr_enable='1' then
        state <= next_state;
      end if;   
    end if;
  end if;
end process;
 
process(clk)
begin
  if clk'event and clk='1' then
    if reset='1' then
      samples <= "000";
    else
      if tick_ctr_enable='1' then
        if tick_ctr="0111" then
          samples(0) <= rxd;
        end if;
        if tick_ctr="1000" then
          samples(1) <= rxd;
        end if;
        if tick_ctr="1001" then
          samples(2) <= rxd;
        end if;
      end if;
    end if;
  end if;
end process;
 
with samples select 
  sampled_bit <=  '0' when "000",
                  '0' when "001",
                  '0' when "010",
                  '1' when "011",
                  '0' when "100",
                  '1' when "101",
                  '1' when "110",
                  '1' when others;
 
process(clk)
begin
  if clk'event and clk='1' then
    if reset='1' then
      rx_buffer <= "00000000";
      set_rx_rdy_flag <= '0';
    else
      if tick_ctr_enable='1' and load_rx_buffer='1' and rx_rdy_flag='0' then
        rx_buffer <= rx_shift_reg(8 downto 1);
        set_rx_rdy_flag <= '1';
      else
        set_rx_rdy_flag <= '0';
      end if;
    end if;
  end if;
end process;
 
process(clk)
begin
  if clk'event and clk='1' then
    if reset='1' then
      rx_rdy_flag <= '0';
    else
      if set_rx_rdy_flag='1' then
        rx_rdy_flag <= '1';
      else
        if read_rx = '1' then
          rx_rdy_flag <= '0';
        end if;
      end if;
    end if;
  end if;
end process;
 
do_shift <= state(0) or state(1) or state(2) or state(3);
 
-- reception shift register
process(clk)
begin
  if clk'event and clk='1' then
    if reset='1' then
      rx_shift_reg <= "1111111111";
    else
      if tick_ctr_enable='1' then
        if tick_ctr="1010" and do_shift='1' then
          rx_shift_reg(9) <= sampled_bit;
          rx_shift_reg(8 downto 0) <= rx_shift_reg(9 downto 1);
        end if;
      end if;
    end if;
  end if;
end process;
 
rx_rdy <= rx_rdy_flag;
 
data_rx <= rx_buffer;
 
end hardwired;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.