Jump to content
    

Проблема с машиной состояний

У меня 2 шины. Одна асинхронная, вторая синхронная.

Сингалы с певрой идут на стайт первую машину. С нее управляющие сигналы (синхронные) идут на вторую, которая генерит циклы на синхронной шине. Так же сюда приходят шигналы с ФИФО и шины, не знаю насколько их можно считать синхронными с учетом задержек. С ФИФО они идут сдвинутые на полпериода, т.к. я тактирую его инвертирыванным клоком, т.к. нет нормального ДЛЛ.

 

Сейчас все стараюсь сделать весь проект синхронным.

Что значит MAX_OFFSET и где это указывается?

 

Спартан 3 можно использовать - он раза в 2 пошустрее, чем Спартан 2. Только там внутри трехстабильных буферов нету, если они Вам нужны. А Виртекс 2 (не говоря уже про 4 и 5) больно дорог, хотя быстр и хорош.

 

Завтра буду выбирать себе присину и думать какие буфера ставить. Видимо Спартан3 не подойдет. Т.к. шину надо захватывать - отпускать, куда без 3-го состояния.

 

по поводу оффсета.

Offset

OFFSET is a basic timing constraint. It specifies the timing relationship between an

external clock and its associated data-in or data-out pin. OFFSET is used only for

pad-related signals, and cannot be used to extend the arrival time specification method to

the internal signals in a design.

 

по поводу вашей реализации:

 

--- Одна асинхронная, ....Сингалы с певрой идут на стайт первую машину.

Вот если вы в лоб побцепили эти сигналы, то не удивительно что имеете такие баги, 2-х тактный синхронизатор обязательно (ну хотя бы однотактный). Пусть даже ценой латентности общения.

 

--- С нее управляющие сигналы (синхронные) идут на вторую

если синхронизаторов нет то черта лысого они будут синхронные.

 

Если шина внешняя, то спартан 3 пойдет IOBUF у него есть. если шина внутренняя то там давно уже на муксерах все стоят.

 

за тактирование инверсным клоком тоже порадоваться не стоит, вы сами себе урезали бюджет в 2 раза.

 

 

Удачи.

Share this post


Link to post
Share on other sites

по поводу вашей реализации:

 

--- Одна асинхронная, ....Сингалы с певрой идут на стайт первую машину.

Вот если вы в лоб побцепили эти сигналы, то не удивительно что имеете такие баги, 2-х тактный синхронизатор обязательно (ну хотя бы однотактный). Пусть даже ценой латентности общения.

 

С асинхронной шиной и работой КА, который ее обслуживает, как не удивительно проблем нет.

 

--- С нее управляющие сигналы (синхронные) идут на вторую

если синхронизаторов нет то черта лысого они будут синхронные.

 

Они синхронные, т.к. я их выставяю по фронту. Т.е. процес начинает с CLK'event.

 

за тактирование инверсным клоком тоже порадоваться не стоит, вы сами себе урезали бюджет в 2 раза.

 

Вот это не понял. Мне над подавать на ФИФО клок и сигнал enable. Если они будут одновременно выставлятся, ФИФО работать не будет - проверено. Сосед на Виртксе тактирует его чуть сдвинутым по фронту сигналом, у меня такого нет... только инверсный.

Share this post


Link to post
Share on other sites

за тактирование инверсным клоком тоже порадоваться не стоит, вы сами себе урезали бюджет в 2 раза.

Это точно. Так делать не стоит.

 

Про Спартан 3 - нет трехстабильных буферов и шин только внутри кристалла (иногда это бывает необходимо, но это похоже не Ваш случай), в блоках ввода вывода все имеется в лучшем виде.

 

Не торопитесь пока делать новую плату выжмите максимум из того что есть, а потом ясно будет. Для Вашего кристалла 50 MHz - это не частота. Правда с ресурсами (например, с теми же глобальными буферами) может сложиться дефицит, особенно если делать все очень правильно.

 

Еще раз призываю Вас нарисовать сначала схему (из простых блоков типа регистр, счетчик и т.п.) аккуратно проанализировать возможные узкие места (где могут возникнуть неприемлемые задержки), устранить все это недобро (это почти всегда возможно), а уж потом приступать к написанию кода. Когда наберетесь опыта и познакомитесь с основными приемами реализации различных компонентов, это, возможно, перестанет быть необходимым, а пока лучше так. То же самое касается автоматов - рисуйте блок-схемы, не ленитесь. Внимательно анализируйте отчеты синтезатора, маппера и PAR'а, разбирайтесь в причинах появления каждого!!! предупреждения. Только в этом случае можно получить ожидаемый результат.

 

Вот это не понял. Мне над подавать на ФИФО клок и сигнал enable. Если они будут одновременно выставлятся, ФИФО работать не будет - проверено. Сосед на Виртксе тактирует его чуть сдвинутым по фронту сигналом, у меня такого нет... только инверсный.

 

Они никогда!!! не будут одновременно выставляться, потому что существует задержка на логике и трассировке - пока сигнал дойдет до пункта назначения фронт клока пройдет на 100%. Правда, это только если клок у Вас идет через глобальный буфер.

Share this post


Link to post
Share on other sites

Они никогда!!! не будут одновременно выставляться, потому что существует задержка на логике и трассировке - пока сигнал дойдет до пункта назначения фронт клока пройдет на 100%. Правда, это только если клок у Вас идет через глобальный буфер.

 

Хочется присоединиться и добавить, т.к. этот момент мне кажется очень важным для начинающих.

Первое условие: тактирующая частота используется только(!) через глобальную клоковую сеть FPGA.

Второе условие: по возможности все(!) триггеры следует тактировать от этого клока, управляя логикой их работы сигналами разрешения и сброса/установки(желательно синхронными).

 

В случае выполнения этих условий, выставление сигнала разрешения по фронту клока не вызывает срабатывания разрешаемого триггера по этому фронту, точно так же как снятие сигнала разрешения по, например, следующему фронту клока не мешает срабатыванию разрешаемого триггера по этому(следующему) фронту клока.

 

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

Share this post


Link to post
Share on other sites

Они никогда!!! не будут одновременно выставляться, потому что существует задержка на логике и трассировке - пока сигнал дойдет до пункта назначения фронт клока пройдет на 100%. Правда, это только если клок у Вас идет через глобальный буфер.

 

Хочется присоединиться и добавить, т.к. этот момент мне кажется очень важным для начинающих.

Первое условие: тактирующая частота используется только(!) через глобальную клоковую сеть FPGA.

Второе условие: по возможности все(!) триггеры следует тактировать от этого клока, управляя логикой их работы сигналами разрешения и сброса/установки(желательно синхронными).

Я использую ФИФО сгенерированный ядрогенератором Xilinx.

Если я буду тактировать обычным клоком, то сигнал enable будет приходить когда клок уже поднят, т.к. он быстрее распространяется но глобальной сети. Так ФИФО не хочет работать - подвисает, выдает не верные сигналы. Клок должен на него приходить чуть позже. Инверсный клок я тяну с ДЛЛ по глобальной линии.

 

Стараюсь все тактировать одним клоком...

 

 

Маппер пишет самую длинну линию, как раз про этот инверсный клок, видимо он как-то криво её прошитывает. Т.к. считываемые данные я выставляю на слудующий такт и мне не принципиальна эта зедержка.

 

Но и обычный клок он пишет период порядка 15нс. Ну не 100 Мгц это.

 

Собрал прект на Спатран2 и Виртекс2, получил от 7 и 10 нс соответственно. Может Виртекс может и быстрее, т.к. я больше не просил.

 

 

 

Про Спартан 3 - нет трехстабильных буферов и шин только внутри кристалла (иногда это бывает необходимо, но это похоже не Ваш случай), в блоках ввода вывода все имеется в лучшем виде.

 

Не торопитесь пока делать новую плату выжмите максимум из того что есть, а потом ясно будет. Для Вашего кристалла 50 MHz - это не частота. Правда с ресурсами (например, с теми же глобальными буферами) может сложиться дефицит, особенно если делать все очень правильно.

 

Я и не тороплюсь, т.к. опытныйобразец надо чтоб заработал на этой ПЛИС.

Но на этом же кристале планируется в будущем ещё и контроллер СДРАМ на 100МГц сунуть. Не знаю буду ли я сам писать или возьму готовый (если найду), но ,мне кажется, не потянет Стартан2 это.

Share this post


Link to post
Share on other sites

Я использую ФИФО сгенерированный ядрогенератором Xilinx.

Если я буду тактировать обычным клоком, то сигнал enable будет приходить когда клок уже поднят, т.к. он быстрее распространяется но глобальной сети. Так ФИФО не хочет работать - подвисает, выдает не верные сигналы. Клок должен на него приходить чуть позже. Инверсный клок я тяну с ДЛЛ по глобальной линии.

 

Что-что? :blink:

 

Клок не можут приходить "чуть позже" сигнала разрешения. Клок должен приходить в следующем такте после разрешения. То есть по предыдущему фронту клока обновились сигналы, по которым вычисляется enable, логика их отработала, по следующему фронту клока уже стоит enable, по которому производится запись в FIFO. И только так, а все остальное - какой-то бред.

Share this post


Link to post
Share on other sites

Я использую ФИФО сгенерированный ядрогенератором Xilinx.

Если я буду тактировать обычным клоком, то сигнал enable будет приходить когда клок уже поднят, т.к. он быстрее распространяется но глобальной сети. Так ФИФО не хочет работать - подвисает, выдает не верные сигналы. Клок должен на него приходить чуть позже. Инверсный клок я тяну с ДЛЛ по глобальной линии.

 

Что-что? :blink:

 

Клок не можут приходить "чуть позже" сигнала разрешения. Клок должен приходить в следующем такте после разрешения. То есть по предыдущему фронту клока обновились сигналы, по которым вычисляется enable, логика их отработала, по следующему фронту клока уже стоит enable, по которому производится запись в FIFO. И только так, а все остальное - какой-то бред.

 

да да ругала меня учительница русского... было дело :maniac:

 

Под "он" я имел ввиду enable. Он приходит позже клока.

 

Сейчас попробовал сделать, как посоветовали тактирую обычным клоком. С момента выставляения enable до момента получения данных проходит 22нс, т.е я получаю данные в слудующем такте. При этом маппер пишем частоту работы проекта - 10нс. :ohmy:

 

А когда я тактирую инверсным клоком, данные получаю в томже такте, примерно через 17-18нс. Видимо эти цифры мне и пишет маппер когда считает частоту работы проекта.

 

Резюмирую. Тактируя обычным клоком, я порадовал маппер, который думает что мой проект работает в 2 раза быстрее. Но огорчил себя, т.к. данные я получаю медленне.

 

Интересные наблюдения, но на работоспособность того с чем я мучаюсь - КА, это не влияет.

 

 

 

Хочется присоединиться и добавить, т.к. этот момент мне кажется очень важным для начинающих.

Первое условие: тактирующая частота используется только(!) через глобальную клоковую сеть FPGA.

Второе условие: по возможности все(!) триггеры следует тактировать от этого клока, управляя логикой их работы сигналами разрешения и сброса/установки(желательно синхронными).

 

Проверяю все тригеры в проекте, вот на что наткнулся...

 

Переписал КА, как мне советовали - разделил на 3 процесса. Из моего описание везде вышли тригеры тактируемые от клока и логика, но от одной структуры получается тригер LD, на который приходят не клочные смгналы и с большими задержками.

 

Привожу код:

 

    when HBG_state1 =>
    if empty = '0' then
        if HBG = '0' then
              state1_next <= befor_write;
        else
            state1_next <= HBG_state1;
        end if;
    else
                state1_next <= reset_state1;
    end if;


    when HBG_state1 =>
       if HBG = '0' then
           wr_in <= '1';
           rd_in <= '1';
       fifo_rd_en_in <= '0';
           en_fifo_in <= '0';
            if empty = '0' then
                HBR_in <= '0';
            else
                HBR_in <= '1';
            end if;
      elsif HBG = '1' then
        wr_in <= 'Z';
        rd_in <= 'Z';
        HBR_in <= '0'; 
      end if;

    when conf_TCB =>  
        start_fly_by <= '0';
        if conf_end = '0' then
            start_conf <= '1';
            HBR_in <= '0';
        else
            start_conf <= '0'; 
            HBR_in <= '1';      --- oaaeeou iinea ioeaaee.
        end if;

 

Первый из процесса определения следующего состояния. Два других из процессов определения выходный сигналов.

 

Подскажите, как переписать так чтобы это была комбинаторика.

Share this post


Link to post
Share on other sites

Сейчас попробовал сделать, как посоветовали тактирую обычным клоком. С момента выставляения enable до момента получения данных проходит 22нс, т.е я получаю данные в слудующем такте. При этом маппер пишем частоту работы проекта - 10нс. :ohmy:

Это нормальная практика работы с ФИФО (Вы хоть доки на это ФИФО посмотрели?) - выставляем разрешение - на следующем такте получаем данные, привыкайте. Или придется мучаться с глюками, которые вы имеете сейчас.

 

Резюмирую. Тактируя обычным клоком, я порадовал маппер, который думает что мой проект работает в 2 раза быстрее. Но огорчил себя, т.к. данные я получаю медленне.

Ваш проект действительно стал работать быстрее. Лучше день (такт) потерять, а потом за полчаса (на более высокой тактовой частоте) долететь.

 

Переписал КА, как мне советовали - разделил на 3 процесса. Из моего описание везде вышли тригеры тактируемые от клока и логика, но от одной структуры получается тригер LD, на который приходят не клочные смгналы и с большими задержками.

Где-то в Case забыли выходу значение присвоить - еще один минус использования Case для функции выходов, попробуйте теперь быстро отыскать где именно :) .

 

Подскажите, как переписать так чтобы это была комбинаторика.

Без всего текста процессов невозможно судить комбинаторика это или нет. Я еще раз спрашиваю - Вам критично использовать входные сигналы автомата в функции выходов (автомат Мили), может использование автомата Мура улучшит положение?

Share this post


Link to post
Share on other sites

Где-то в Case забыли выходу значение присвоить - еще один минус использования Case для функции выходов, попробуйте теперь быстро отыскать где именно :) .

 

Т.е. надо всем выходным сигналам присваивать значене в каждом состоянии , и я где-то указал не все сигналы?

 

Без всего текста процессов невозможно судить комбинаторика это или нет. Я еще раз спрашиваю - Вам критично использовать входные сигналы автомата в функции выходов (автомат Мили), может использование автомата Мура улучшит положение?

 

Да, т.к. HBG - это подтверждение запроса шины. Я не могу начать цикл не получив его. А сигнал empty инициальзирует запрос шины. А в приведенном состоянии отвечает за то что, если переход был случайным (например из за помехи), то машина вывалится в начально состояние. А не будет генерить ошибочный цикл. И ещё куча других сигналов, типа подтверждения приема данных. Муром тут не обойтись.

 

Если ща сам не найду где пропустил, то выложу весь автомат.

Share this post


Link to post
Share on other sites

Т.е. надо всем выходным сигналам присваивать значене в каждом состоянии , и я где-то указал не все сигналы?

Именно так.

 

Да, т.к. HBG - это подтверждение запроса шины. Я не могу начать цикл не получив его. А сигнал empty инициальзирует запрос шины. А в приведенном состоянии отвечает за то что, если переход был случайным (например из за помехи), то машина вывалится в начально состояние. А не будет генерить ошибочный цикл. И ещё куча других сигналов, типа подтверждения приема данных. Муром тут не обойтись.

Наверняка это все можно обойти в рамках протокола, правда порой путем пропуска тактов. Не пытайтесь пока сделать чтобы быстро не работало - сделайте чтобы устойчиво работало.

Share this post


Link to post
Share on other sites

Т.е. надо всем выходным сигналам присваивать значене в каждом состоянии , и я где-то указал не все сигналы?

 

Именно так.

 

не обязательно, можно присваивать только в нужных состояниях.

автору вот пример простого КА.

    type state_t is (
        idle,       -- ready state 
        decode,     -- decode state 
        procX,      -- process address X coordinate when burstX /= 0 
        procY       -- process address Y coordinate when burstX /= 0 and burstX = 0
        );
    
    signal ri_state : state_t;
    signal r_state  : state_t;
    
begin

    fsm_comb_proc : process (
        Valid_in,       
        --
        DataValid_in,
        --
        BurstX_Eq0_in,
        --
        CntX_Eq1_in,
        CntY_Eq0_in, 
        --
        r_state
        ) is 
        variable v : state_t;
    begin
        
        v := state_t'LEFT;
        --
        case (r_state) is 
            when idle   => 
                if (Valid_in = '1') then 
                    v := decode; 
                else 
                    v := state_t'LEFT;
                end if;
            -- decode state 
            when decode =>                 
                if (BurstX_Eq0_in = '1') then 
                    v := procY;
                else 
                    v := procX;
                end if;
            -- state where we wait for data valid/dec cnt X/write data
            when procX  =>
                if (DataValid_in = '1') then
                    if (CntX_Eq1_in = '0') then 
                        v := procX;
                    else 
                        v := procY;
                    end if;
                else 
                    v := procX;
                end if;                    
            -- state where we wait for data valid/dec cnt Y/write data
            when procY  => 
                if (DataValid_in = '1') then
                    if (CntY_Eq0_in = '0') then 
                        if (BurstX_Eq0_in = '0') then 
                            v := procX;
                        else 
                            v := procY;
                        end if;
                    else
                        v := idle;
                    end if;          
                else 
                    v := procY;
                end if;
            when others => null;
        end case;            
        ri_state <= v;
    end process fsm_comb_proc;
    
    -- fsm decode logic 
    fsm_decode_proc : process (
        DataValid_in,
        -- 
        CntY_Eq0_in,
        --
        r_state 
        ) is 
    begin      
        --
        -- moore logic 
        --
        Ready_out       <= '0';
        DataReady_out   <= '0';
        DataCapture_out <= '0';
        AddrInitLd_out  <= '0';
        case (r_state) is 
            when idle   => 
                Ready_out       <= '1';
                DataCapture_out <= '1';
            when decode => 
                AddrInitLd_out  <= '1';
            when procX  => 
                DataReady_out   <= '1'; 
            when procY  => 
                DataReady_out   <= '1'; 
            when others => null;
        end case;
        
        --
        -- mealy logic 
        --
        DataWrReq_out   <= '0';
        --
        CntLdX_out      <= '0';
        CntDecX_out     <= '0';
        --
        CntDecY_out     <= '0';  
        CntLdY_out      <= '0';
        --
        AddrLd_out      <= '0';
        AddrIncX_out    <= '0';
        AddrIncY_out    <= '0';
        -- 
        Done_out        <= '0';
        case (r_state) is 
            when idle   => null;
            when decode => 
                CntLdX_out  <= '1';
                CntLdY_out  <= '1'; 
                AddrLd_out  <= '1';
            when procX  => 
                if (DataValid_in = '1') then 
                    DataWrReq_out   <= '1';    
                    CntDecX_out     <= '1'; 
                    AddrIncX_out    <= '1';
                end if;
            when procY  => 
                if (DataValid_in = '1') then 
                    DataWrReq_out   <= '1';  
                    CntDecY_out     <= '1';
                    CntLdX_out      <= '1';
                    AddrLd_out      <= '1';
                    AddrIncY_out    <= '1';
                    
                    if (CntY_Eq0_in = '1') then 
                        Done_out    <= '1';
                    end if;
                end if;
            when others => null;
        end case; 
        
    end process fsm_decode_proc;
    
    fsm_reg_proc : process (
        clk 
        ) is 
    begin
        if (rising_edge(clk)) then     
            if (sclr = '1') then 
                r_state <= state_t'LEFT;
            elsif (clk_ena = '1') then 
                r_state <= ri_state;
            end if;   
        end if;
    end process fsm_reg_proc;

 

рекомендую использовать при описании подобный подход

Share this post


Link to post
Share on other sites

не обязательно, можно присваивать только в нужных состояниях.

автору вот пример простого КА.

 

BSV, прав. Если присваивать значение сигнала не в каждом состоянии, при синтезе получаются не понятные тригеры в место комбинаторики. Возможно это зависит от синтезатора. Но в Симплифае это так, я проверил.

 

автору вот пример простого КА.

 

    when procX  =>
            if (DataValid_in = '1') then
                    if (CntX_Eq1_in = '0') then 
                        v := procX;
                    else 
                        v := procY;
                    end if;
                else 
                    v := procX;
                end if;

 

рекомендую использовать при описании подобный подход

 

На данный момент, я так всё и переделал. Но в указанной структуре у меня КА соверщает не правильеный переход. На вашем примере, у меня происходит следующее. При выставленном DataValid_in = '1', машина вываливается в состояние v := procX.

 

Объяснить это я не могу. Сигнал установлен - это 100%, иначе бы машина не попалабы в это стостояние.

 

Наверняка это все можно обойти в рамках протокола, правда порой путем пропуска тактов. Не пытайтесь пока сделать чтобы быстро не работало - сделайте чтобы устойчиво работало.

 

Конечно возможно, подождать примерно тактов 20 и точно запрос придет. Но это же большие потери производтельноти. Но инициализация работы все равно джолжна быть условной, это как обойти?

 

Сейчас всё тригеры тактируемы не клоком выкинул, быстрее от этого проект не стал. Только блоки стали красивее.

Share this post


Link to post
Share on other sites

Про Latch'и - у меня это и в XST (ISE 6.3) тоже было, теперь я так не делаю.

 

По поводу всего остального - пока советы были общие без учета особенностей задачи. Если не лениво (и не жаба :) ) поподробней описать задачу в проблемной части с времянками и т.п. (Вы это уже делали, но не очень подробно), можно поговорить более конкретно. Если хотите, пишите в личку, или прямо сюда, как хотите.

Share this post


Link to post
Share on other sites

Про Latch'и - у меня это и в XST (ISE 6.3) тоже было, теперь я так не делаю.

 

По поводу всего остального - пока советы были общие без учета особенностей задачи. Если не лениво (и не жаба :) ) поподробней описать задачу в проблемной части с времянками и т.п. (Вы это уже делали, но не очень подробно), можно поговорить более конкретно. Если хотите, пишите в личку, или прямо сюда, как хотите.

 

Предпочитаю, пока сюда писать.

 

Кажется проблемы с машиной состояний появляются из-за ДЛЛ. По крайней мере, когда я его убрал ещё ни разу с проблемами КА не столкнулся.

Но появилась другая проблема без ДЛЛ ушли фронты клока. Проект синтезится с периодом 12-14нс. При частоте шины 50МГц, наблюдается не стабильная работа. Т.е. на анализаторе циклы выглядят идельно, но видимо адрес или данные процессорами защелкиваются не те.

 

Думаю, как с этим бороться.

Share this post


Link to post
Share on other sites

Про Latch'и - у меня это и в XST (ISE 6.3) тоже было, теперь я так не делаю.

 

От всех лишних триггеров в проекте я избавился. Теперь у меня всего 1 клок обнаруживается. Но быстрее работать он не стал. Может это и не нужно?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...