architecture beh of uart_rx is
constant timer_max : integer := 35;
+ constant counter_max : integer := 9;
+ constant samples : integer := 8;
type STATE_UART_RX is (IDLE, BUSY, DONE);
signal timer, timer_next : integer range 0 to 65535;
signal counter, counter_next : integer range 0 to 15;
+ signal sample_counter, sample_counter_next : integer range 0 to counter_max-1;
signal state, state_next : STATE_UART_RX;
- signal tx_data_prev : std_logic_vector(7 downto 0); -- FIXME: this isnt named next so that the interface isn't called tx_data_next ...
+ signal sync1, sync2, txd_next: std_logic; --synchronizers FIXME!
-- these are internal signals that are actually used as in and output
- signal tx_data_i : std_logic_vector(7 downto 0);
+ signal tx_data_prev : std_logic_vector(7 downto 0);
signal tx_new_i : std_logic;
+ signal shift, shift_value, shift_reset : std_logic;
begin
---FIXME:
tx_new <= tx_new_i;
- tx_data <= tx_data_i;
process(sys_clk, sys_res)
begin
-- Set reset state
state <= IDLE;
tx_data_prev <= X"00";
+
+ txd_next <= '0'; --fixme: syncronizers!
+ sync2 <= '0';
+ sync1 <= '0';
+ timer <= 0;
+ counter <= 0;
elsif rising_edge(sys_clk) then
-- Store next state
state <= state_next;
- tx_data_prev <= tx_data_i;
+ if (shift = '1') then
+ tx_data(7 downto 1) <= tx_data_prev(6 downto 1);
+ tx_data(0) <= shift_value;
+ elsif ( shift_reset = '1') then
+ tx_data <= X"00";
+ end if;
+
+ txd_next <= sync2; --fixme: syncronizers!
+ sync2 <= sync1;
+ sync1 <= txd;
+ counter <= counter_next;
+ sample_counter <= sample_counter_next;
+ timer <= timer_next;
end if;
end process;
process(state, txd, counter)
begin
state_next <= state;
+
+ shift <= '0';
+ shift_reset <='0';
+ shift_value <= '0';
+ timer_next <= 0;
+ counter_next <= 0;
+
case state is
when IDLE =>
if (txd = '0') then
state_next <= BUSY;
- else
- state_next <= IDLE;
+ shift_reset <= '1';
end if;
when BUSY =>
- if (counter = 9) then --FIXME: is this true?
+ if (counter = counter_max) 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_i <= '0';
-
- -- Calculate the outputs
- -- based on the current
- -- state
- case state is
- when IDLE =>
- tx_new_i <= '0';
- when BUSY =>
- tx_new_i <= '0';
- when DONE =>
- tx_new_i <= '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_i)
- begin
- if (tx_new_i = '1') then
- if (timer = timer_max) then
- if (counter > 10) then
- counter_next <= 0;
- else
+ if (timer = timer_max) then
+ timer_next <= 0;
counter_next <= counter + 1;
+ if (sample_counter < samples/2) then
+ shift_value <= '1';
+ else
+ shift_value <= '0';
+ end if;
+ shift <= '1';
+ else
+ timer_next <= timer + 1;
end if;
- else
- counter_next <= counter;
- end if;
- else
- counter_next <= 0;
- end if;
- end process;
- process (counter, txd)
- begin
- tx_data_i <= 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_i(0) <= txd;
- when 2 =>
- tx_data_i(1) <= txd;
- when 3 =>
- tx_data_i(2) <= txd;
- when 4 =>
- tx_data_i(3) <= txd;
- when 5 =>
- tx_data_i(4) <= txd;
- when 6 =>
- tx_data_i(5) <= txd;
- when 7 =>
- tx_data_i(6) <= txd;
- when 8 =>
- tx_data_i(7) <= txd;
- when 9 => -- stop bit
- assert (txd = '1');
- when others => -- idle
- assert (txd = '1');
+ if timer = timer_max/samples and txd_next = '1' then
+ sample_counter_next <= sample_counter + 1;
+ end if;
+ when DONE =>
+ state_next <= IDLE;
end case;
end process;