В поведенческом моделировании у моего FSM есть состояние, которое занимает более 1 такта ... И мне это не нравится

Пожалуйста, простите меня, если вы найдете какие-то тривиальные ошибки в моем коде. Я все еще новичок в VHDL.

Ну, я должен иметь дело с последовательным интерфейсом от АЦП. Интерфейс довольно прост ... есть провод для последовательных данных (кадр из 24 бит), сигнал DRDY, который сообщает мне, когда доступны новые данные выборки, и последовательные часы (SCLK), которые вставляют бит в ( поднимающийся край). Все работает непрерывно...

Мне нужно правильно захватить 24-битный образец, поместить их на параллельную шину (сдвиговый регистр) и предоставить сигнал «действительные данные» для блоков, которые будут обрабатывать образцы...

Из-за того, что мои системные часы в 4 раза превышают частоту последовательного интерфейса, я подумал, что работать с FSM будет легко...

Когда вы посмотрите на код, вы увидите процесс захвата нарастающих фронтов DRDY и SCLK.

Затем FSM с несколькими состояниями (Init, wait_drdy, wait_sclk, inc_count, check_count).

Я использую счетчик (cnt unsigned), чтобы проверить, захватил ли я уже 24 бита, а также перенаправить состояния FSM в состояние «check_count». Вот картинка:

В поведенческом моделировании у моего FSM есть состояние, которое занимает более 1 такта ... И мне это не нравится

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity serial_ads1675 is
    Port ( 
            clk     : in STD_LOGIC;
            reset   : in STD_LOGIC;
            sclk    : in std_logic;
            sdata   : in std_logic;
            drdy    : in std_logic;
            pdata   : out std_logic_vector(23 downto 0);
            pdready : out std_logic
    );
end serial_ads1675;

architecture Behavioral of serial_ads1675 is

-- Internal declarations
signal ipdata : std_logic_vector (23 downto 0);
signal ipdready : std_logic;
signal tmp1, tmp2, tmp3, tmp4 : std_logic;
signal rise_drdy, rise_sclk : std_logic;
signal cnt : unsigned (4 downto 0);

type state is (init, wait_drdy, wait_sclk, inc_count, check_count);
signal actual_state, next_state : state;




begin

-- Concurrent statements
pdata <= ipdata;
pdready <= ipdready;
rise_drdy <= '1' when ((tmp1 = '1') and (tmp2 = '0')) else '0';
rise_sclk <= '1' when ((tmp3 = '1') and (tmp4 = '0')) else '0';



-- Process

process (clk, reset)
begin
    if (reset = '0') then
        tmp1 <= '0';
        tmp2 <= '0';
        tmp3 <= '0';
        tmp4 <= '0';
    elsif (falling_edge(clk)) then
        tmp1 <= drdy;
        tmp2 <= tmp1;
        tmp3 <= sclk;
        tmp4 <= tmp3;
    end if;
end process;

process (reset, clk)
begin
    if (reset = '0') then
        actual_state <= init;
    elsif (rising_edge(clk)) then
        actual_state <= next_state;
    end if;
end process;

process (rise_sclk, rise_drdy)   -- Next State affectation
begin
    case actual_state is
    
        when init =>
            next_state <= wait_drdy;
            ipdata <= (others => '0');
            ipdready <= '0';
            cnt <= (others => '0');
            
        when wait_drdy =>
            if (rise_drdy = '0') then
                next_state <= actual_state;
            else
                next_state <= wait_sclk;
            end if;
            cnt <= (others => '0');
            
        when wait_sclk =>
            if (rise_sclk = '0') then
                next_state <= actual_state;
            else
                next_state <= inc_count;
            end if;
            ipdready <= '0';
                        
        when inc_count =>
            next_state <= check_count;
            cnt <= cnt + 1;
            ipdready <= '0';
            ipdata(23 downto 1) <= ipdata(22 downto 0);
            ipdata(0) <= sdata;
            
        when check_count =>
            case cnt is
                when "11000" =>
                    next_state <= wait_drdy;
                    ipdready <= '1';
                when others =>
                    next_state <= wait_sclk;
                    ipdready <= '0';
            end case;
                        
        when others =>
            next_state <= init;
    end case;
end process;



end Behavioral;

Моя проблема в состоянии check_count...

Я ожидаю, что это состояние должно длиться один системный такт, но на самом деле оно длится гораздо дольше.

Вот снимок поведенческого моделирования:

В поведенческом моделировании у моего FSM есть состояние, которое занимает более 1 такта ... И мне это не нравится

Из-за того, что это состояние длится дольше ожидаемого, я пропускаю следующий импульс SCLK и не записываю следующий бит...

Я не понимаю, почему это состояние длится столько системных тактов, а не один...

У кого-нибудь есть какие-нибудь подсказки и принести немного света в мою темную ночь?

Заранее спасибо.

Редактировать: я пытался изменить сигнал cnt для целочисленной переменной, внутренней для процесса FSM... Те же результаты

Привет и добро пожаловать в SO. Обычно читателям было бы полезно предоставить MCVE. У вас есть несколько проблем в вашем коде. Синтез будет игнорировать списки конфиденциальности и создавать логику исключительно из того, что находится в процессе. Чтобы получить лучшее представление о том, что аппаратное обеспечение действительно будет делать, я настоятельно рекомендую вам изменить режим файла на VHDL 2008 и использовать process(all), чтобы компилятор мог определить список чувствительности.

Tricky 10.12.2022 09:43

Если вы не хотите использовать VHDL 2008, вам нужно изменить процесс на process(actual_state, rdy_sclk, rise_drdy , cnt, ipdata, sdata) После этого вы, вероятно, заметите, что код больше не работает так, как вы ожидали. Я настоятельно рекомендую вам синхронизировать все с помощью clk.

Tricky 10.12.2022 09:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка такова:

process (rise_sclk, rise_drdy)   -- Next State affectation
begin
    -- code omitted, but does generally this:
    next_state <= SOME_VALUE;
end process;

Поскольку список чувствительности включает только сигналы rise_sclk и rise_drdy, процесс «выполняется» только в случае изменения любого из этих сигналов. Вы можете проследить это на волновой диаграмме.

У вас нет синхронного дизайна, работающего на clk. Внесите clk в список чувствительности и основывайте решения на уровнях rise_sclk и rise_drdy. Как отрывок:

process (clk)   -- Next State affectation
begin
    if rising_edge(clk) then
        case actual_state is

        when init =>
            next_state <= wait_drdy;
            -- and so on
   
        end case;
    end if;
end process;

Другие вопросы по теме