constant BAUD : integer := CLK_FREQ/BAUDRATE;
type STATE_UART_RX is (IDLE, STARTBIT, DBITS, STOPBIT);
- signal state_int, state_next : STATE_UART_RX;
+ signal state : STATE_UART_RX;
- signal rx_data_next, rx_data_int : std_logic_vector(7 downto 0);
- signal rx_new_next, rx_new_int : std_logic;
signal startbitdetection : std_logic_vector(1 downto 0);
- signal bitcnt_int, bitcnt_next : integer range 0 to 7;
- signal baudcnt_int, baudcnt_next : integer range 0 to BAUD;
+ signal bitcnt : integer range 0 to 7;
+ signal baudcnt : integer range 0 to BAUD + 2;
+ signal rx_data_int : std_logic_vector(7 downto 0);
begin
- rx_new <= rx_new_int;
rx_data <= rx_data_int;
-
process(sys_clk, sys_res_n)
begin
if (sys_res_n = '0') then
- state_int <= IDLE;
+ state <= IDLE;
rx_data_int <= (others => '0');
- rx_new_int <= '0';
- bitcnt_int <= 0;
- baudcnt_int <= 0;
+ rx_new <= '0';
+ bitcnt <= 0;
+ baudcnt <= 0;
startbitdetection <= b"11";
elsif rising_edge(sys_clk) then
- state_int <= state_next;
- rx_data_int <= rx_data_next;
- rx_new_int <= rx_new_next;
- bitcnt_int <= bitcnt_next;
- baudcnt_int <= baudcnt_next;
- startbitdetection(0) <= rxd;
- startbitdetection(1) <= startbitdetection(0);
- end if;
- end process;
-
- process(state_int, rx_data_int, rxd, bitcnt_int, baudcnt_int,
- startbitdetection)
- begin
- state_next <= state_int;
- rx_data_next <= rx_data_int;
- rx_new_next <= '0';
- bitcnt_next <= bitcnt_int;
- baudcnt_next <= baudcnt_int;
-
- case state_int is
- when IDLE =>
- -- bei fallender flanke koennte starbit folgen
- if startbitdetection = b"10" then
- state_next <= STARTBIT;
- baudcnt_next <= 0;
- end if;
- when STARTBIT =>
- rx_data_next <= (others => '0');
+ startbitdetection <= startbitdetection(0) & rxd;
+ rx_new <= '0';
+ baudcnt <= baudcnt + 1;
+ case state is
+ when IDLE =>
+ baudcnt <= 0;
+ -- bei fallender flanke koennte starbit folgen
+ if startbitdetection = b"10" then
+ state <= STARTBIT;
+ end if;
+ when STARTBIT =>
+ rx_data_int <= (others => '0');
- -- halbe BAUDTIME warten, um immer in der mitte abzutasten
- -- vgl. http://upload.wikimedia.org/wikipedia/de/d/de/RS-232_timing.png
- if baudcnt_int < BAUD/2 then
- baudcnt_next <= baudcnt_int + 1;
- else
- baudcnt_next <= 0;
- if rxd = '0' then
- -- starbit (= '0')? dann kommen daten
- state_next <= DBITS;
- bitcnt_next <= 0;
- baudcnt_next <= 0;
- else
- -- sonst war das nix...
- state_next <= IDLE;
+ -- halbe BAUDTIME warten, um immer in der mitte abzutasten
+ -- vgl. http://upload.wikimedia.org/wikipedia/de/d/de/RS-232_timing.png
+ if baudcnt = BAUD/2 then
+ baudcnt <= 0;
+ if rxd = '0' then
+ -- starbit (= '0')? dann kommen daten
+ state <= DBITS;
+ bitcnt <= 0;
+ baudcnt <= 0;
+ else
+ -- sonst war das nix...
+ state <= IDLE;
+ end if;
end if;
- end if;
- when DBITS =>
- if baudcnt_int < BAUD then
- baudcnt_next <= baudcnt_int + 1;
- else
- baudcnt_next <= 0;
- -- bitorder beachten
- rx_data_next <= rxd & rx_data_int(7 downto 1);
+ when DBITS =>
+ if baudcnt = BAUD then
+ baudcnt <= 0;
+ -- bitorder beachten
+ rx_data_int <= rxd & rx_data_int(7 downto 1);
- if bitcnt_int = 7 then
- state_next <= STOPBIT;
- else
- bitcnt_next <= bitcnt_int + 1;
+ if bitcnt = 7 then
+ state <= STOPBIT;
+ else
+ bitcnt <= bitcnt + 1;
+ end if;
end if;
- end if;
- when STOPBIT =>
- if baudcnt_int < BAUD then
- baudcnt_next <= baudcnt_int + 1;
- else
- state_next <= IDLE;
- if rxd = '1' then
- rx_new_next <= '1';
+ when STOPBIT =>
+ if baudcnt = BAUD then
+ state <= IDLE;
+ if rxd = '1' then
+ rx_new <= '1';
+ end if;
end if;
- end if;
- end case;
+ end case;
+ end if;
end process;
end architecture beh;