UART接收器测试平台

时间:2015-04-07 01:30:54

标签: vhdl fpga

我是VHDL的新手,我试图验证UART接收器是如何工作的。 我合成了下面的代码(从书中引用)和它的罚款,但如果需要更多让我知道:)。 我的电路板的频率是100 Mhz,我想要接收的数据是8位,波特率是115200,时钟和刻度应该如何在测试平台或者什么是正确的测试平台?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
entity uart_rx is
    generic(
        data_bits: integer := 8;      --  #  d a t a   b i t s  
        stop_bit_ticks: integer := 16   --  #  t i c k s   f o r   s t o p   b i t s  
    );
    Port ( rx : in STD_LOGIC;
           clk : in STD_LOGIC;
           reset: in STD_LOGIC;
           tick : in STD_LOGIC;
           rx_done : out STD_LOGIC;
           data_out : out STD_LOGIC_VECTOR (7 downto 0));
end uart_rx;
architecture arch of uart_rx is
    type state_type is (idle, start, data, stop);
    SIGNAL state_reg, state_next: state_type;
    SIGNAL s_reg, s_next: UNSIGNED(3 downto 0);
    SIGNAL n_reg, n_next: UNSIGNED(2 downto 0);
    SIGNAL b_reg, b_next: STD_LOGIC_VECTOR(7 downto 0);
begin
--  FSMD  s t a t e   &  d a t a   r e g i s t e r s  
    process(clk, reset) -- FSMD state and data regs.
    begin
        if (reset = '1') then
            state_reg <= idle;
            s_reg <= (others => '0');
            n_reg <= (others => '0');
            b_reg <= (others => '0');
            --rx_done <= '0';
        --  rx <= '1';
        elsif (clk'event and clk='1') then
            state_reg <= state_next;
            s_reg <= s_next;
            n_reg <= n_next;
            b_reg <= b_next;
        end if;
    end process;
   --  n e x t - s t a t e   l o g i c   &  d a t a   p a t h   f u n c t i o n a l   u n i t s / r o u t i n g
    process (state_reg, s_reg, n_reg, b_reg, tick, rx)
    begin
        state_next <= state_reg;
        s_next <= s_reg;
        n_next <= n_reg;
        b_next <= b_reg;
        rx_done <= '0';
        case state_reg is
        when idle =>
            if (rx = '0') then
            state_next <= start;
            s_next <= (others => '0');
            end if;
        when start =>
            if (tick = '1') then
                if (s_reg = 7) then
                    state_next <= data;
                    s_next <= (others => '0');
                    n_next <= (others => '0');
                else
                    s_next <= s_reg + 1;
                end if;
            end if;
        when data =>
            if (tick = '1') then
                if (s_reg = 15) then
                    s_next <= (others => '0');
                    b_next <= rx & b_reg(7 downto 1);
                    if (n_reg = (data_bits - 1)) then
                        state_next <= stop;
                    else
                        n_next <= n_reg + 1;
                    end if;
                else
                    s_next <= s_reg + 1;
                end if;
            end if;
        when stop =>
            if (tick = '1') then
                if (s_reg = (stop_bit_ticks - 1)) then
                    state_next <= idle;
                    rx_done <= '1';
                else
                    s_next <= s_reg + 1;
                end if;
            end if;
        end case;
    end process;
    data_out <= b_reg; 
end arch;

1 个答案:

答案 0 :(得分:1)

通常,UART接收器以比特率的8倍运行。如果您的比特率是115200,这意味着采样率为921600.如果您运行在100Mzh,您将需要创建一个时钟分频器,以使您从100 MHz到所需的采样率。要从921600转到100 MHz,以下内容将起作用:

100 MHz = 100,000,000 Hz

921600个样本/秒= 921,600赫兹

divider = 100,000,000 / 921,600 = 108.51。

因此,你需要一个计数器,它会在rising_edge(时钟)上计数到109(我们需要以时钟速率的整数采样),然后产生一个启动信号,告诉你的组件它的时间采样线并重置计数器。上面的例子假设8个样本/位,这是我所知道的典型。因此,如果您将模拟中主时钟的周期设置为1ns并设置上述的计数器电路,您应该得到您正在寻找的测试台。

编辑:关于时钟分割不均的警告

几乎忘了提这个。由于您的时钟速率不能均匀分配到UART的比特率,因此在编写此电路时必须格外小心。根据我提出的方案,您的采样率将在稍后和之后的传输中移动。您可能需要添加一个简单的偏移量来将计数器更改为偶数位上的108,以使您与输入数据位更加一致。

请点击此处了解更多信息:https://electronics.stackexchange.com/questions/42236/uart-receiver-clock-speed