-- UART 1 BYTE BUFFER

library ieee;
use ieee.std_logic_1164.all;

-- Buffer to save 1 byte. set_flag is driven by uart_receiver (rx_done_tick)
-- indicates the availability of a byte -- flag is set. System fetches it and 
-- clears by asserting clr_flag which resets flag. din and dout are the data in
-- byte (from uart_receiver) and data out byte

entity OneByteBufAndFlag is
   port(
      clk, reset: in std_logic;
      clr_flag, set_flag: in std_logic;
      din: in std_logic_vector(7 downto 0);
      dout: out std_logic_vector(7 downto 0);
      flag: out std_logic
   );
end OneByteBufAndFlag;

architecture beh of OneByteBufAndFlag is
   signal buf_reg, buf_next: std_logic_vector(7 downto 0);
   signal flag_reg, flag_next: std_logic;
   begin

-- FFs
   process(clk, reset)
      begin
      if (reset = '1') then
         buf_reg <= (others =>'0');
         flag_reg <= '0';
      elsif (clk'event and clk='1') then
         buf_reg <= buf_next;
         flag_reg <= flag_next;
      end if;
   end process;

-- next-state logic

   process (buf_reg, flag_reg, set_flag, clr_flag, din)
      begin

-- hold onto the current buffer value by default
      buf_next <= buf_reg;
      flag_next <= flag_reg;

-- If new byte is available, store it and set flag
      if (set_flag = '1') then
         buf_next <= din;
         flag_next <= '1';

-- If fetching a byte, just reset the flab.
      elsif (clr_flag = '1') then
         flag_next <= '0';
      end if;
   end process;

-- dout driven with data byte reg, same for flag
   dout <= buf_reg;
   flag <= flag_reg;

end beh;
