]> jspc29.x-matter.uni-frankfurt.de Git - vhdlbasics.git/commitdiff
asynchronous uart, IF
authorIngo Froehlich <ingo@nomail.fake>
Fri, 25 Aug 2017 12:44:01 +0000 (14:44 +0200)
committerIngo Froehlich <ingo@nomail.fake>
Fri, 25 Aug 2017 12:44:01 +0000 (14:44 +0200)
interface/uart_sctrl.vhd

index 0b1f71bbf777716abd8563770b18c6f97931874a..8cc20bb2aa1bf39b2e6d0bc0980eb49743467d13 100644 (file)
@@ -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