--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+--use work.gen_pkg.all;
+
+--package int_types is
+-- type STATE_UART_RX is (IDLE, BUSY, DONE);
+--end package int_types;
+
+entity uart_rx is
+port(
+ sys_clk : in std_logic;
+ sys_res : in std_logic;
+ txd : in std_logic; -- warning: this is asynchronous input!
+ tx_data : out std_logic_vector(7 downto 0); -- map this to a larger register with containing input
+ tx_new : out std_logic;
+);
+end entity uart_rx;
+
+architecture beh of uart_rx is
+ constant timer_max : integer := 35;
+
+ signal timer, timer_next : integer range 0 to 65535;
+ signal counter, counter_next : integer range 0 to 15;
+ signal state, state_next : STATE_UART_RX;
+ signal tx_data_pref : std_logic_vector(7 downto 0); -- FIXME: this isnt named next so that the interface isn't called tx_data_next ...
+
+begin
+--FIXME:
+ process(sys_clk, sys_res_n)
+ begin
+ if sys_res_n = ‘0‘ then
+ -- Set reset state
+ state <= IDLE;
+ tx_data_prev <= X"0";
+ elsif rising_edge(sys_clk) then
+ -- Store next state
+ state <= state_next;
+ tx_data_prev <= tx_data;
+ end if;
+ end process;
+
+ process(state, txd, counter)
+ begin
+ state_next <= state;
+ case state is
+ when IDLE =>
+ if (txd = 0) then
+ state_next <= BUSY;
+ else
+ state_next <= IDLE;
+ end if;
+ when BUSY =>
+ if (counter = 9) then --FIXME: is this true?
+ state_next <= DONE;
+ else
+ state_next <= BUSY;
+ end if;
+ when DONE =>
+ state_next <= IDLE;
+ end case;
+ end process;
+
+ process(state)
+ begin
+ -- Set default values
+ -- for the outputs
+ tx_new <= ‘0‘;
+
+ -- Calculate the outputs
+ -- based on the current
+ -- state
+ case state is
+ when IDLE =>
+ tx_new <= ‘0‘;
+ when BUSY =>
+ tx_new <= ‘0‘;
+ case (counter)
+ tx_data(counter-2) <= txd;
+ end case;
+ when DONE =>
+ tx_new <= '1';
+ end case;
+ end process;
+-- END FIXME: do fill this out CORRECTLY
+
+ process (sys_clk, sys_res)
+ begin
+ if sys_res = '0' then
+ counter <= 0;
+ timer <= 0;
+ elsif rising_edge(sys_clk) then
+ counter <= counter_next;
+ timer <= timer_next;
+ end if;
+ end process;
+
+ process(timer)
+ begin
+ if (timer = timer_max) then
+ timer_next <= 0;
+ else
+ timer_next <= timer + 1;
+ end if;
+ end process;
+
+ process (timer, counter, tx_new)
+ begin
+ if (tx_new = '1') then
+ if (timer = timer_max) then
+ if (counter > 10) then
+ counter_next <= 0;
+ else
+ counter_next <= counter + 1;
+ end if;
+ else
+ counter_next <= counter;
+ end if;
+ else
+ counter_next <= 0;
+ end if;
+ end process;
+
+ process (counter, txd)
+ begin
+ tx_data <= tx_data_prev;
+ -- TODO: we probably want oversampling and averaging + failure!
+ -- FIXME: this is per se not synthesisable
+ case (counter) is
+ when 0 => --start bit
+ assert (txd = '0');
+ when 1 =>
+ tx_data(0) <= txd;
+ when 2 =>
+ tx_data(1) <= txd;
+ when 3 =>
+ tx_data(2) <= txd;
+ when 4 =>
+ tx_data(3) <= txd;
+ when 5 =>
+ tx_data(4) <= txd;
+ when 6 =>
+ tx_data(5) <= txd;
+ when 7 =>
+ tx_data(6) <= txd;
+ when 8 =>
+ tx_data(7) <= txd;
+ when 9 => -- stop bit
+ assert (txd = '1');
+ when others => -- idle
+ assert (txd = '1');
+ end case;
+ end process;
+
+ tx_done <= '0';
+
+end architecture beh;