从FSM在UART上发送

时间:2019-03-28 14:11:28

标签: vhdl uart fsm

我已经创建了一个FSM,并且我希望针对FSM的每个状态从我的UART发送一个char(8位)。 UART发送器定义为:

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 => '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 =>
          o_TX_Active <= '0';
          o_TX_Serial <= '1';         -- Drive Line High for Idle
          r_TX_Done   <= '0';
          r_Clk_Count <= 0;
          r_Bit_Index <= 0;

          if i_TX_DV = '1' then
            r_TX_Data <= i_TX_Byte;
            r_SM_Main <= s_TX_Start_Bit;
          else
            r_SM_Main <= s_Idle;
          end if;


        -- Send out Start Bit. Start bit = 0
        when s_TX_Start_Bit =>
          o_TX_Active <= '1';
          o_TX_Serial <= '0';

          -- Wait g_CLKS_PER_BIT-1 clock cycles for start bit to finish
          if r_Clk_Count < g_CLKS_PER_BIT-1 then
            r_Clk_Count <= r_Clk_Count + 1;
            r_SM_Main   <= s_TX_Start_Bit;
          else
            r_Clk_Count <= 0;
            r_SM_Main   <= s_TX_Data_Bits;
          end if;


        -- Wait g_CLKS_PER_BIT-1 clock cycles for data bits to finish          
        when s_TX_Data_Bits =>
          o_TX_Serial <= r_TX_Data(r_Bit_Index);

          if r_Clk_Count < g_CLKS_PER_BIT-1 then
            r_Clk_Count <= r_Clk_Count + 1;
            r_SM_Main   <= s_TX_Data_Bits;
          else
            r_Clk_Count <= 0;

            -- Check if we have sent out all bits
            if r_Bit_Index < 7 then
              r_Bit_Index <= r_Bit_Index + 1;
              r_SM_Main   <= s_TX_Data_Bits;
            else
              r_Bit_Index <= 0;
              r_SM_Main   <= s_TX_Stop_Bit;
            end if;
          end if;


        -- Send out Stop bit.  Stop bit = 1
        when s_TX_Stop_Bit =>
          o_TX_Serial <= '1';

          -- Wait g_CLKS_PER_BIT-1 clock cycles for Stop bit to finish
          if r_Clk_Count < g_CLKS_PER_BIT-1 then
            r_Clk_Count <= r_Clk_Count + 1;
            r_SM_Main   <= s_TX_Stop_Bit;
          else
            r_TX_Done   <= '1';
            r_Clk_Count <= 0;
            r_SM_Main   <= s_Cleanup;
          end if;


        -- Stay here 1 clock
        when s_Cleanup =>
          o_TX_Active <= '0';
          r_TX_Done   <= '1';
          r_SM_Main   <= s_Idle;


        when others =>
          r_SM_Main <= s_Idle;

      end case;
    end if;
  end process p_UART_TX;

  o_TX_Done <= r_TX_Done;

end RTL;

仅对一个字符有效。 此VHDL代码在传输r_TX_Data字节时等待DV信号(DataValid)。最后,它设置了o_TX_Done信号。

我需要通过发送器发送各种字符(字节)。因此,我使用以下代码:

---[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  <=  i_data_in;
            r_TX_DV  <= '1';
 end UART_WRITE_BYTE;
  --------------------------------------------------------------------------------------





 begin --------------architecture begin


 -- Instantiate UART transmitter
  UART_TX_INST : uart_tx
    generic map (
      g_CLKS_PER_BIT => 139 --c_CLKS_PER_BIT
      )
    port map (
      i_clk       => Clk,   
      i_tx_dv     => r_TX_DV, 
      i_tx_byte   => r_TX_BYTE,
      o_tx_active => open,
      o_tx_serial => out_serial_memory,
      o_tx_done   => w_TX_DONE
      );



    st: process (r_SM_serial,w_TX_DONE)
    begin
        case r_SM_Serial is
            when s_COMMAND => 
                if (w_TX_Done = '1' ) then 
                    next_state <= S_BA;
                end if;

            when s_BA => 
                if (w_TX_Done = '1' ) then 
                    next_state <= S_BB;
               end if;
            when s_BB => 
                if (w_TX_Done = '1' ) then 
                    next_state <= S_start;
               end if;
            when others =>
                next_state <= s_Start;
            end case;
    end process;



        ----------------------------------------
        -- Output Logic 
        ----------------------------------------
        OUT_LOGIC: process (r_SM_Serial) 
        begin
            case r_SM_Serial is
                when s_Command => 
                    UART_WRITE_BYTE(X"41");
                when s_BA => 
                    UART_WRITE_BYTE(X"42"); 
                when s_BB => 
                    UART_WRITE_BYTE(X"43"); 
                when s_Start =>
                    r_TX_DV <= '0';
                when others =>  
                    r_TX_DV <= '0';
            end case;
        end process OUT_LOGIC; 


process (Clk,reset)
  begin
  if reset = '1' then 
        r_SM_serial <= s_command;

  elsif (CLK'event and CLK = '1') then
        r_SM_Serial <= NEXT_STATE;
    end if;
  end process;

这不起作用。 发送器连续发送第一个字符(状态s_Command),并且永不停止。

显然,已设置w_TX_Done信号,但没有正确的时序。 我得到以下输出:

PuTTY Output

我在哪里错了?

而且……传递永远不会结束

0 个答案:

没有答案