⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart_serial.vhd

📁 UART接口的VHDL源代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
      tx_top_baud       <= '0';
      tx_br_divisor_cnt := 0;
    elsif rising_edge(clk) then
      tx_top_baud       <= '0';
      if top_ref_baud = '1' then
        tx_br_divisor_cnt := tx_br_divisor_cnt + 1;
        
        if tx_br_divisor_cnt = br_divisor then
          tx_top_baud       <= '1';
          tx_br_divisor_cnt := 0;
        end if;
      
      end if;
    end if;
  end process;
  
  rx_baud_proc:
  process(reset, clk)
    variable rx_br_divisor_cnt : std_logic_vector(9 downto 0);
  begin
    if reset = '1' then
      rx_top_baud       <= '0';
      rx_br_divisor_cnt := (others => '0');
    elsif rising_edge(clk) then
      rx_top_baud       <= '0';
      if clr_rx_baud = '1' then
        rx_br_divisor_cnt := (others => '0');
      elsif top_ref_baud = '1' and rx_state /= IDLE then
        rx_br_divisor_cnt := rx_br_divisor_cnt + 1;
        
        if rx_br_divisor_cnt(8 downto 0) = br_divisor(9 downto 1) then
          rx_top_baud       <= '1';
          rx_br_divisor_cnt := (others => '0');
        end if;
      
      end if;
    end if;
  end process;  


  -------------------------------------------------------------------------------
  -- Transmition process
  -------------------------------------------------------------------------------
  tx_proc:
  process(reset, clk)
    variable tx_bit_cnt : integer;
  begin
    if reset = '1' then
      tx_data_s      <= (others => '0');
      tx_data_reg    <= (others => '1');
      tx_ch_rdy      <= '0';
    elsif rising_edge(clk) then
      case tx_state is
        when IDLE =>
             if tx_data_en = '1' then
               tx_data_s <= tx_data_in;
               tx_ch_rdy <= '0';
               tx_state  <= LOAD_TX_DATA;
             else
               tx_ch_rdy <= '1';
             end if;

        when LOAD_TX_DATA =>
             if tx_top_baud = '1' then
               if parity_en = '1' then
                 -- start + data + parity + stop
                 tx_bit_cnt  := 8 + 3;
                 tx_data_reg(10 downto 0) <= '1' & parity(tx_data_s,parity_type) & tx_data_s(7 downto 0) & '0';
               else
                 -- start + data + stop
                 tx_bit_cnt  := 8 + 2;
                 tx_data_reg(10 downto 0) <= "11" & tx_data_s(7 downto 0) & '0';
               end if;
               tx_state <= TX_DATA;
             end if;
             
        when TX_DATA =>
             if tx_top_baud = '1' then
               tx_data_reg(10 downto 0) <= '1' & tx_data_reg(10 downto 1);
               tx_bit_cnt  := tx_bit_cnt-1;
               if tx_bit_cnt = 1 then
                 tx_state <= TX_STOP;
               end if;
             end if;
        
        when TX_STOP => -- stop bit
             if tx_top_baud = '1' then
               tx_state <= IDLE;
             end if;             
             
        when others =>
             null;
      end case;
    end if;
  end process;
  
  tx_data_serial <= tx_data_reg(0);
  
  
  -------------------------------------------------------------------------------
  -- Reception process
  -------------------------------------------------------------------------------
  process(reset, clk)
    variable rx_bit_cnt : integer;
  begin
    if reset = '1' then
      rx_data_out    <= (others => '0');
      rx_data_en     <= '0';
      rx_ovf_err     <= '0';
      rx_data_i      <= (others => '0');    
      rx_parity_err  <= '0';
      rx_parity_err_i<= '0';
      
    elsif rising_edge(clk) then

      clr_rx_baud    <= '0';
      rx_ovf_err     <= '0';
      rx_parity_err  <= '0';
      rx_parity_err_i<= '0';
      rx_data_en     <= '0';
      
      case rx_state is
        when IDLE =>  -- Wait start bit
             if top_ref_baud = '1' then
               if rx_data_serial = '0' then
                 clr_rx_baud <= '1';
                 rx_state <= START_RX;
                 rx_bit_cnt := 1;
               end if;
             end if;


        when START_RX =>
             if rx_top_baud = '1' then                  
               if rx_data_serial = '1' then
                 rx_state <= RX_OVF;
               else  
                 rx_state <= EDGE_RX;
               end if;
             end if;
        
          
        when EDGE_RX =>
             if rx_top_baud = '1' then
               if (parity_en = '1' and rx_bit_cnt = 10) or                             -- start + data + parity + stop
                  (parity_en = '0' and rx_bit_cnt = 9) then                            -- start + data + stop
                 rx_state <= STOP_RX;
               else                         -- data
                 rx_state <= SHIFT_RX;
               end if;
             end if;
         
        when SHIFT_RX =>
             if rx_top_baud = '1' then
               rx_bit_cnt := rx_bit_cnt + 1;
               if not((parity_en = '1' and rx_bit_cnt = 10)) then                      -- start + data + parity + stop
                 rx_data_i(7 downto 0) <= rx_data_serial & rx_data_i(7 downto 1); 
               else
                 if parity(rx_data_i,parity_type) /= rx_data_serial then
                   rx_parity_err_i <= '1';
                 end if;
               end if;
               rx_state <= EDGE_RX;
             end if;
         
             
        when STOP_RX =>
--             if rx_top_baud = '1' then
               rx_data_out <= rx_data_i;
               rx_parity_err <= rx_parity_err_i;
               rx_ovf_err  <= '0';
               rx_data_en  <= '1';
               rx_state <= IDLE;
--             end if;
             
        when RX_OVF =>    -- Overframe error
             rx_ovf_err <= '1';
             if rx_data_serial = '1' then
               rx_state <= IDLE;
             end if;
                 
        when others => null;
      end case;
    end if;
  end process;
  
end rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -