title: Transmit on UART from FSM
body: <p>I have created a FSM and I would that, for each state of FSM, to transmit a char (8 bit) from my UART.
  The UART transmitter is defined as:</p>
  
  <pre><code>library ieee;
  use ieee.std_logic_1164.all;
  use ieee.numeric_std.all;
  
  entity UART_TX is
    generic (
      g_CLKS_PER_BIT : integer := 139     -- Needs to be set correctly
      );
    port (
      i_Clk       : in  std_logic;
      i_TX_DV     : in  std_logic;
      i_TX_Byte   : in  std_logic_vector(7 downto 0);
      o_TX_Active : out std_logic;
      o_TX_Serial : out std_logic;
      o_TX_Done   : out std_logic
      );
  end UART_TX;
  
  
  architecture RTL of UART_TX is
  
    type t_SM_Main is (s_Idle, s_TX_Start_Bit, s_TX_Data_Bits,
                       s_TX_Stop_Bit, s_Cleanup);
    signal r_SM_Main : t_SM_Main := s_Idle;
  
    signal r_Clk_Count : integer range 0 to g_CLKS_PER_BIT-1 := 0;
    signal r_Bit_Index : integer range 0 to 7 := 0;  -- 8 Bits Total
    signal r_TX_Data   : std_logic_vector(7 downto 0) := (others =&gt; '0');
    signal r_TX_Done   : std_logic := '0';
  
  begin
  
  
    p_UART_TX : process (i_Clk)
    begin
      if rising_edge(i_Clk) then
  
        case r_SM_Main is
  
          when s_Idle =&gt;
            o_TX_Active &lt;= '0';
            o_TX_Serial &lt;= '1';         -- Drive Line High for Idle
            r_TX_Done   &lt;= '0';
            r_Clk_Count &lt;= 0;
            r_Bit_Index &lt;= 0;
  
            if i_TX_DV = '1' then
              r_TX_Data &lt;= i_TX_Byte;
              r_SM_Main &lt;= s_TX_Start_Bit;
            else
              r_SM_Main &lt;= s_Idle;
            end if;
  
  
          -- Send out Start Bit. Start bit = 0
          when s_TX_Start_Bit =&gt;
            o_TX_Active &lt;= '1';
            o_TX_Serial &lt;= '0';
  
            -- Wait g_CLKS_PER_BIT-1 clock cycles for start bit to finish
            if r_Clk_Count &lt; g_CLKS_PER_BIT-1 then
              r_Clk_Count &lt;= r_Clk_Count + 1;
              r_SM_Main   &lt;= s_TX_Start_Bit;
            else
              r_Clk_Count &lt;= 0;
              r_SM_Main   &lt;= s_TX_Data_Bits;
            end if;
  
  
          -- Wait g_CLKS_PER_BIT-1 clock cycles for data bits to finish          
          when s_TX_Data_Bits =&gt;
            o_TX_Serial &lt;= r_TX_Data(r_Bit_Index);
  
            if r_Clk_Count &lt; g_CLKS_PER_BIT-1 then
              r_Clk_Count &lt;= r_Clk_Count + 1;
              r_SM_Main   &lt;= s_TX_Data_Bits;
            else
              r_Clk_Count &lt;= 0;
  
              -- Check if we have sent out all bits
              if r_Bit_Index &lt; 7 then
                r_Bit_Index &lt;= r_Bit_Index + 1;
                r_SM_Main   &lt;= s_TX_Data_Bits;
              else
                r_Bit_Index &lt;= 0;
                r_SM_Main   &lt;= s_TX_Stop_Bit;
              end if;
            end if;
  
  
          -- Send out Stop bit.  Stop bit = 1
          when s_TX_Stop_Bit =&gt;
            o_TX_Serial &lt;= '1';
  
            -- Wait g_CLKS_PER_BIT-1 clock cycles for Stop bit to finish
            if r_Clk_Count &lt; g_CLKS_PER_BIT-1 then
              r_Clk_Count &lt;= r_Clk_Count + 1;
              r_SM_Main   &lt;= s_TX_Stop_Bit;
            else
              r_TX_Done   &lt;= '1';
              r_Clk_Count &lt;= 0;
              r_SM_Main   &lt;= s_Cleanup;
            end if;
  
  
          -- Stay here 1 clock
          when s_Cleanup =&gt;
            o_TX_Active &lt;= '0';
            r_TX_Done   &lt;= '1';
            r_SM_Main   &lt;= s_Idle;
  
  
          when others =&gt;
            r_SM_Main &lt;= s_Idle;
  
        end case;
      end if;
    end process p_UART_TX;
  
    o_TX_Done &lt;= r_TX_Done;
  
  end RTL;
  </code></pre>
  
  <p>It work well for only one character.
  This VHDL code, wait for DV signal (DataValid) when it transm the r_TX_Data byte. Finally, it set the o_TX_Done signal.</p>
  
  <p>I need to send various char (byte) trough my transmitter.for this reason I use this code:</p>
  
  <pre><code>---[cut]
   type t_SM_serial  is (s_Start, s_COMMAND, s_BA, s_BB, s_BC);
      signal next_state : t_SM_Serial;
    signal r_SM_serial : t_SM_serial := s_Start;
  
  
   -- Low-level byte-write---------------------------------------------------------------
    procedure UART_WRITE_BYTE ( i_data_in       : in  std_logic_vector(7 downto 0)  ) is
   begin
              r_TX_BYTE  &lt;=  i_data_in;
              r_TX_DV  &lt;= '1';
   end UART_WRITE_BYTE;
    --------------------------------------------------------------------------------------
  
  
  
  
  
   begin --------------architecture begin
  
  
   -- Instantiate UART transmitter
    UART_TX_INST : uart_tx
      generic map (
        g_CLKS_PER_BIT =&gt; 139 --c_CLKS_PER_BIT
        )
      port map (
        i_clk       =&gt; Clk,   
        i_tx_dv     =&gt; r_TX_DV, 
        i_tx_byte   =&gt; r_TX_BYTE,
        o_tx_active =&gt; open,
        o_tx_serial =&gt; out_serial_memory,
        o_tx_done   =&gt; w_TX_DONE
        );
  
  
  
      st: process (r_SM_serial,w_TX_DONE)
      begin
          case r_SM_Serial is
              when s_COMMAND =&gt; 
                  if (w_TX_Done = '1' ) then 
                      next_state &lt;= S_BA;
                  end if;
  
              when s_BA =&gt; 
                  if (w_TX_Done = '1' ) then 
                      next_state &lt;= S_BB;
                 end if;
              when s_BB =&gt; 
                  if (w_TX_Done = '1' ) then 
                      next_state &lt;= S_start;
                 end if;
              when others =&gt;
                  next_state &lt;= s_Start;
              end case;
      end process;
  
  
  
          ----------------------------------------
          -- Output Logic 
          ----------------------------------------
          OUT_LOGIC: process (r_SM_Serial) 
          begin
              case r_SM_Serial is
                  when s_Command =&gt; 
                      UART_WRITE_BYTE(X"41");
                  when s_BA =&gt; 
                      UART_WRITE_BYTE(X"42"); 
                  when s_BB =&gt; 
                      UART_WRITE_BYTE(X"43"); 
                  when s_Start =&gt;
                      r_TX_DV &lt;= '0';
                  when others =&gt;  
                      r_TX_DV &lt;= '0';
              end case;
          end process OUT_LOGIC; 
  
  
  process (Clk,reset)
    begin
    if reset = '1' then 
          r_SM_serial &lt;= s_command;
  
    elsif (CLK'event and CLK = '1') then
          r_SM_Serial &lt;= NEXT_STATE;
      end if;
    end process;
  
  </code></pre>
  
  <p>This does not work.
  The transmitter continuously sends the first character (status s_Command) and never stops.</p>
  
  <p>Apparently, the w_TX_Done signal is set, but there are no correct timing.
  I obtain this output:</p>
  
  <p><a href="https://i.stack.imgur.com/MhA3t.png" rel="nofollow noreferrer">PuTTY Output</a></p>
  
  <p>Where am I wrong?</p>
  
  <p>And… the trasmission never end</p>