Испытательный стенд приемника UART

Я новичок в VHDL и пытаюсь проверить, как работает приемник UART. Я синтезировал приведенный ниже код (процитированный из книги), и это нормально, но если нужно больше, дайте мне знать :). Частота моей платы составляет 100 МГц, а данные, которые я хочу получить, - 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;

person Alsphere    schedule 07.04.2015    source источник
comment
Кажется, это взято из главы 7 книги Понга «Прототипирование ПЛИС на примерах VHDL». Ранее в этой главе упоминался генератор скорости передачи, подразумевающий, что вы должны использовать счетчик a, аналогичный тому, что описан в разделе 4.3.2. В коде, который идет с книгой, имя файла list_ch04_11_mod_m.vhd. Не помните, какую тактовую частоту он ожидает, вам, возможно, придется прочитать книгу или посмотреть демонстрационную плату, которую он рекомендует.   -  person    schedule 07.04.2015


Ответы (1)


Обычно приемники UART работают со скоростью, в 8 раз превышающей скорость передачи данных. Если ваш битрейт 115200, это означает частоту дискретизации 921600. Если вы работаете на 100Mzh, вам нужно будет создать делитель тактовой частоты, чтобы перейти от 100 МГц к желаемой частоте дискретизации. Для перехода с 921600 на 100 МГц будет работать следующее:

100 МГц = 100 000 000 Гц

921 600 выборок/сек = 921 600 Гц

делитель = 100 000 000/921 600 = 108,51.

Таким образом, вам понадобится счетчик, который будет считать до 109 (мы округляем в большую сторону, так как мы должны производить выборку с целым числом тактовой частоты) на восходящем_крае (часы), а затем поднимаем сигнал включения, который сообщает вашему компоненту, что пришло время для выборки. линии и сбросьте счетчик. В приведенном выше примере предполагалось 8 выборок на бит, что, насколько мне известно, типично. Таким образом, если вы установите период ваших основных часов в симуляции равным 1 нс и настроите схему счетчика, описанную выше, вы должны получить испытательный стенд, который вы ищете.

РЕДАКТИРОВАТЬ: предупреждение о неравномерном делении часов

Чуть не забыл упомянуть об этом. Поскольку ваша тактовая частота неравномерно делится на скорость передачи данных для UART, при кодировании этой схемы необходимо проявлять особую осторожность. Ваша частота дискретизации будет двигаться все дальше и дальше в передаче по предложенной мной схеме. Вам, вероятно, придется добавить простое смещение, чтобы изменить значение счетчика на 108 для четных битов, чтобы вы были более согласованы с входящими битами данных.

Дополнительную информацию см. здесь: https://electronics.stackexchange.com/questions/42236/uart-receiver-clock-speed

person NKamrath    schedule 09.04.2015