From: Ingo Froehlich Date: Fri, 25 Aug 2017 12:44:01 +0000 (+0200) Subject: asynchronous uart, IF X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=4196e161c579b3a39345fa3f84859097e7dc2f11;p=vhdlbasics.git asynchronous uart, IF --- diff --git a/interface/uart_sctrl.vhd b/interface/uart_sctrl.vhd index 0b1f71b..8cc20bb 100644 --- a/interface/uart_sctrl.vhd +++ b/interface/uart_sctrl.vhd @@ -23,11 +23,13 @@ entity uart_sctrl is UART_TX : out std_logic; DATA_OUT : out std_logic_vector(31 downto 0); - DATA_IN : in std_logic_vector(31 downto 0); ADDR_OUT : out std_logic_vector(7 downto 0); WRITE_OUT : out std_logic; READ_OUT : out std_logic; + + DATA_IN : in std_logic_vector(31 downto 0); READY_IN : in std_logic; + BUSY_OUT : out std_logic; DEBUG : out std_logic_vector(15 downto 0) ); @@ -43,9 +45,13 @@ signal tx_data : std_logic_vector(7 downto 0); signal rx_ready : std_logic; signal tx_send : std_logic; signal tx_ready : std_logic; -signal bytecount : integer range 0 to 15; -type rx_state_t is (IDLE,START,START2,DO_COMMAND,DO_READ,SEND_BYTE1,SEND_BYTE2,SEND_BYTE3,SEND_TERM,SEND_FINISH); +signal bytecount : integer range 0 to 9; +signal txbytecount : integer range 0 to 7; +type rx_state_t is (IDLE,START,START2,DO_COMMAND); +type tx_state_t is (DO_READ,SEND_BYTE1,SEND_BYTE2,SEND_BYTE3,SEND_TERM,SEND_FINISH, SEND_WAIT); signal state : rx_state_t; +signal txstate : tx_state_t; +signal txbuf : unsigned(7 downto 0); signal addr_data : std_logic_vector(39 downto 0); signal addr_data_tx : std_logic_vector(31 downto 0); @@ -79,12 +85,11 @@ THE_TX : entity work.uart_trans ); PROC_RX : process - variable tmp,tmp2 : unsigned(7 downto 0); + variable tmp2 : unsigned(7 downto 0); begin wait until rising_edge(CLK); READ_OUT <= '0'; WRITE_OUT <= '0'; - tx_send <= '0'; timer <= timer + 1; case state is when IDLE => @@ -98,70 +103,79 @@ begin cmd_rd <= '1'; elsif rx_data = x"57" then cmd_wr <= '1'; + else + state <= IDLE; end if; end if; when START => + if rx_data >= x"40" then + tmp2 := unsigned(rx_data) + x"09"; + else + tmp2 := unsigned(rx_data); + end if; if rx_ready = '1' then - if rx_data >= x"40" then - tmp2 := unsigned(rx_data) + x"09"; - else - tmp2 := unsigned(rx_data); - end if; state <= START2; end if; when START2 => addr_data(bytecount*4+3 downto bytecount*4) <= std_logic_vector(tmp2(3 downto 0)); + bytecount <= bytecount - 1; + if (bytecount = 0 and cmd_wr = '1') or (bytecount = 8 and cmd_rd = '1') then state <= DO_COMMAND; else - bytecount <= bytecount - 1; state <= START; end if; when DO_COMMAND => WRITE_OUT <= cmd_wr; READ_OUT <= cmd_rd; - if cmd_rd = '1' then - state <= DO_READ; - else - state <= IDLE; - end if; - + state <= IDLE; + end case; + + if RESET = '1' or timeout = '1' then + state <= IDLE; + end if; +end process; + + +PROC_TX : process begin + wait until rising_edge(CLK); + tx_send <= '0'; + case txstate is --Read cycle when DO_READ => if READY_IN = '1' then addr_data_tx(31 downto 0) <= DATA_IN; tx_send <= '1'; - tx_data <= x"52"; - state <= SEND_BYTE1; - bytecount <= 7; + txbuf <= x"52"; + txstate <= SEND_BYTE1; + txbytecount <= 7; end if; when SEND_BYTE1 => - tmp := x"0" & unsigned(addr_data_tx(bytecount*4+3 downto bytecount*4)); - state <= SEND_BYTE2; + txbuf <= x"0" & unsigned(addr_data_tx(txbytecount*4+3 downto txbytecount*4)); + txstate <= SEND_BYTE2; when SEND_BYTE2 => - if tmp(3 downto 0) > x"9" then - tmp := tmp + x"41" - x"0a"; + if txbuf(3 downto 0) > x"9" then + txbuf <= txbuf + x"41" - x"0a"; else - tmp := tmp + x"30"; + txbuf <= txbuf + x"30"; end if; - state <= SEND_BYTE3; + txstate <= SEND_BYTE3; when SEND_BYTE3 => if tx_ready = '1' then - tx_data <= std_logic_vector(tmp); tx_send <= '1'; - if bytecount = 0 then - state <= SEND_TERM; + if txbytecount = 0 then + txstate <= SEND_TERM; else - bytecount <= bytecount - 1; - state <= SEND_BYTE1; + txbytecount <= txbytecount - 1; + txstate <= SEND_BYTE1; end if; end if; @@ -170,29 +184,31 @@ begin when SEND_TERM=> if tx_ready = '1' then tx_send <= '1'; - tx_data <= x"0a"; - state <= SEND_FINISH; + txbuf <= x"0d"; + txstate <= SEND_FINISH; end if; when SEND_FINISH=> if tx_ready = '1' then tx_send <= '1'; - tx_data <= x"0d"; - state <= IDLE; + txbuf <= x"0a"; + txstate <= SEND_WAIT; end if; - + when SEND_WAIT => + if tx_ready = '1' then + txstate <= DO_READ; + end if; end case; - - if RESET = '1' or timeout = '1' then - state <= IDLE; - timer <= (others => '0'); + if RESET = '1' then + txstate <= DO_READ; end if; + end process; DATA_OUT <= addr_data(31 downto 0); ADDR_OUT <= addr_data(39 downto 32); - -timeout <= timer(19); - +tx_data <= std_logic_vector(txbuf); +timeout <= timer(20); +BUSY_OUT <= '0' when txstate = DO_READ else '1'; end architecture; \ No newline at end of file