Проблемы с запуском FSM на Nexys2

Я пытаюсь запустить простой FSM, в котором сканируются светодиоды. Я применил эту логику, сдвинув биты влево, используя для этого оператор &. Он вообще не смещается, только светится LSB, и все, я также замедлил часы, используя часы 1,5 Гц. Кто-нибудь, пожалуйста, скажите мне, что здесь не так.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity scan is
Port ( 
            clk         : in    STD_LOGIC;
            led         : out   STD_LOGIC_VECTOR (7 downto 0);
            reset       : in    STD_LOGIC
        );
end scan;
architecture Behavioral of scan is

Type state is
    (
    RESET_ST,
    S1
    );

    signal n_state : state;
    signal c_state : state;

    signal input_temp   :unsigned (7 downto 0):= "00000001";

begin
--------------------------------------------------------------------------
--------------------------CURRENT STATE ASSIGNMENT------------------------
--------------------------------------------------------------------------

STATE_ASSIGNMENT: process (clk, reset)
    begin
    if (reset = '1') then
            c_state <= RESET_ST;
    elsif  (clk'event and clk = '1') then
            c_state <= n_state;
    end if;
    end process STATE_ASSIGNMENT;


--------------------------------------------------------------------------
----------------------------- INTPUT BLOCK--------------------------------  
--------------------------------------------------------------------------

INPUT_BLOCK : process (c_state) 
    begin
case (c_state) is

when RESET_ST   =>  
input_temp  <= "00000001";
n_state         <= S1;

when S1             =>
    input_temp  <= input_temp (6 downto 0) & '0';
    n_state         <= S1;
when others => 
n_state         <= RESET_ST;

end case;
end process;
--------------------------------------------------------------------------
----------------------------- OUTPUT BLOCK--------------------------------  
--------------------------------------------------------------------------

OUTPUT_BLOCK : process (c_state, input_temp)
begin   

case (c_state) is

when RESET_ST               =>
led <= std_logic_vector (input_temp);

when S1                     =>
led <= std_logic_vector (input_temp);
when others                 =>
led                         <= (others => '1');

end case;
end process OUTPUT_BLOCK;


end Behavioral;

person alexhilton    schedule 22.06.2014    source источник
comment
Я бы переработал способ обработки сигнала input_temp. Прямо сейчас это комбинаторный процесс, когда input_temp отсутствует в списке чувствительности. Кроме того, input_temp не определен в другом состоянии, поэтому вы подразумеваете защелку. Что вам нужно, так это регистр сдвига, и, как следует из названия, input_temp должен быть обусловлен в последовательном (синхронизированном) процессе.   -  person Ciano    schedule 22.06.2014


Ответы (1)


Есть две сразу бросающиеся в глаза вещи неправильно.

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

Во-вторых, оказавшись в S1 n_state ‹= S1, другими словами, вы идете в S1 и сидите там. Следствием этого является то, что процесс INPUT_BLOCK не имеет триггерного события - чувствительность содержит только c_state и никаких дальнейших изменений в c_state.

scan_tb, однократное изменение состояния

Я полагаю, что Брайан Драммонд будет рассказывать вам об использовании одного процесса для вашего FSM. По сути, input_temp следует изменить на что-то с хранилищем и переместить в синхронизируемый процесс.

Вы могли бы заметить, что нет ничего, что можно было бы обнаружить, когда input_temp становится статическим (все 0).

Дополнение

Из вашего комментария:

Хорошо, если я добавлю следующее состояние, то есть n_state, в список чувствительности, это сработает?

Нет. Если вы посмотрите на сигнал выше, n_state всегда содержит S1.

Во-вторых, да, когда все 0, я ничего не увижу, но как насчет сдвигающейся части?

В конце концов, эта '1' будет потеряна, как только она достигнет input_temp(7).

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

Есть три вещи, которые вы могли бы сделать. 1. пусть все выходы перейдут в «0», 2. рециркулируют «1» (счетчик Джонсона) или 3. остановятся с отображением некоторого светодиода.

Если бы состояния были одним горячим, новые 8 состояний могли бы управлять светодиодом каждое. – Дэвид Кунц 2 часа назад

Ты:

Не могли бы вы случайно показать мне пример или что-то в этом роде? Это помогло бы мне больше понять

В общем, это неподходящее место для обучения базовым навыкам VHDL или цифрового дизайна, и уж точно не в ветке комментариев. Это место, где можно задавать конкретные вопросы VHDL и отвечать на них. См. раздел Как задать хороший вопрос?

Ты спросил:

Кто-нибудь, пожалуйста, скажите мне, что здесь не так.

Я ответил, включая изображение.

Примерно здесь вы могли заметить, что изображение волны выше противоречит первому абзацу вашего вопроса:

Он вообще не смещается, только светится LSB, и все, я также замедлил часы, используя часы 1,5 Гц.

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

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

Реализуйте и 8-битный регистр сдвига, который сдвигается влево (или подключается в обратном порядке), и может быть реализован с синхронной загрузкой (до «00000001»), подключенной для сброса. 8 часов спустя это все 0.

Определено девять состояний (по одному для каждого из светодиодов, которые горят, и одно, когда все светодиоды гаснут). Вы можете добавить 10-е состояние, добавив триггер этого состояния. Вы можете использовать 10 триггеров для одного горячего конечного автомата, 8 триггеров только для сдвигового регистра или 9 для включения c_state (и удержания сброса).

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

Вот самая простая реализация с наименьшим количеством изменений в вашем коде:

architecture foo of scan is

    type state is ( RESET_ST, S1 );
    signal n_state:    state;
    signal c_state:    state;
    -- signal input_temp:  unsigned (7 downto 0):= "00000001";
    signal shft_reg:   std_logic_vector (7 downto 1);

begin

state_assignment: 
    process (clk, reset)
        begin
            if reset = '1' then
                c_state <= RESET_ST;
                -- counter <= (others => '0');
                shft_reg <= (others => '0');
            elsif  clk'event and clk = '1' then
                c_state <= n_state;
                if c_state = RESET_ST then
                    shft_reg <= shft_reg (6 downto 1) & '1';
                elsif shft_reg /= "1000000" then
                    shft_reg <= shft_reg (6 downto 1) & '0';
                end if;
            end if;
    end process;

--input_block : 
NEXT_STATE:
    process (c_state) 
    begin
        case (c_state) is
            when RESET_ST =>  
                -- input_temp <= "00000001";
                n_state <= S1;
            when S1 =>
                -- input_temp <= input_temp (6 downto 0) & '0';
                n_state  <= S1;
            when others => 
                n_state  <= RESET_ST;
        end case;
    end process;

-- output_block:
--     process (c_state, input_temp)
--     begin
--         case (c_state) is
--             when RESET_ST =>
--                 led <= std_logic_vector (input_temp);
--             when S1 =>
--                 led <= std_logic_vector (input_temp);
--             when others  =>
--                 led <= (others => '1');
--             end case;
--     end process;

-- LED0_OUT:
--     led(0) <= '1' when c_state = RESET_ST else '0';
LEDOUT:  
    process (c_state, shft_reg)
    begin
        if c_state = RESET_ST then
            led(0) <= '1';
        else
            led(0) <= '0';
        end if;
        led (7 downto 1) <= shft_reg;  -- shft_reg(7 downto 1)
    end process;

end architecture foo;

library ieee;
use ieee.std_logic_1164.all;

entity scan_tb is
end entity;

architecture foo of scan_tb is
    signal clk:     std_logic := '0';
    signal reset:   std_logic := '1';
    signal led:     std_logic_vector ( 7 downto 0);
begin

DUT:
    entity work.scan 
        port map (
            clk => clk,
            led => led,
            reset => reset
        );

CLOCK:
    process
    begin
        wait for 0.33 sec;  -- one half clock period, 1.5 Hz
        clk <= not clk;
        if Now > 20 sec then
            wait;
        end if;
    end process;

STIMULUS:
    process
    begin
        wait until rising_edge(clk);
        wait for 0.33 sec;
        wait until rising_edge(clk);
        reset <= '0';
        wait;        
    end process;

end architecture;

А вот как выглядят формы волны:

scan_tb2 исправлено

Обратите внимание, что основание для светодиода было изменено в форме сигнала на двоичное.

Также обратите внимание, что первая часть двух сигналов совпадает. Я также добавил распознаватель состояния shft_reg, чтобы заморозить shft_reg, когда установлен led(7).

Вы также можете заметить, что есть оптимизация. Первый светодиод выводится из c_state, остальные 7 выводятся из 7-битного сдвигового регистра (shft_reg). Также следует отметить, что используется всего 8 триггеров.

И, как отмечает sonicwave в комментарии к вашему вопросу, вы должны сначала смоделировать этот материал, так что вот простой тестовый стенд.

Это было смоделировано с использованием вашего объявления объекта с удаленным предложением использования для пакета numeric_std (shft_reg имеет тип std_logic_vector), новой архитектуры foo и пары объект/архитектура для scan_tb с использованием ghdl-0.31:

david_koontz@Macbook: ghdl -a scan.vhdl
david_koontz@Macbook: ghdl -e scan_tb
david_koontz@Macbook: ghdl -r scan_tb --wave=scan_tb.ghw

На Mac под управлением OS X 10.9.3, где scan_tb.ghw — это специальный формат файла дампа сигнала ghdl, очень подходящий для VHDL.

Теперь, пожалуйста, не задавайте больше вопросов в комментариях к вопросу, который вы изначально задали. Также вы могли бы закомментировать назначение необъявленного счетчика сигналов в своем примере кода вместо того, чтобы редактировать его. Это разрушает преемственность между вопросами и ответами.

далее

Процесс присвоения состояния можно написать без оценки c_state:

state_assignment: 
    process (clk, reset)
        begin
            if reset = '1' then
                c_state <= RESET_ST;
                -- counter <= (others => '0');
                shft_reg <= (others => '0');
            elsif  clk'event and clk = '1' then
                c_state <= n_state;
--                if c_state = RESET_ST then
                if shft_reg = "0000000" then
                    shft_reg <= shft_reg (6 downto 1) & '1';
                elsif shft_reg /= "1000000" then
                    shft_reg <= shft_reg (6 downto 1) & '0';
                end if;
            end if;
    end process;

И делает то же самое.

Теперь прокомментируйте немного больше:

state_assignment: 
    process (clk, reset)
        begin
            if reset = '1' then
                c_state <= RESET_ST;
                -- counter <= (others => '0');
                shft_reg <= (others => '0');
            elsif  clk'event and clk = '1' then
                c_state <= n_state;
--                if c_state = RESET_ST then
                if shft_reg = "0000000" then
                    shft_reg <= shft_reg (6 downto 1) & '1';
--                elsif shft_reg /= "1000000" then
                else
                    shft_reg <= shft_reg (6 downto 1) & '0';
                end if;
            end if;
    end process;

И сделайте такое же изменение решения в процессе LEDOUT:

LEDOUT:  
    process (shft_reg)
    begin
        if shft_reg = "0000000" then
            led(0) <= '1';
        else
            led(0) <= '0';
        end if;
        led (7 downto 1) <= shft_reg;  -- shft_reg(7 downto 1)
    end process;

И вы получаете светодиоды сканирования, чтобы продолжать сканирование:

сканирование с непрерывной рециркуляцией

Мы переключили светодиод (0), чтобы он не зависел от других положений shft_reg, установленных в «1» (не «0»).

person Community    schedule 22.06.2014
comment
Извините за этот счетчик, я забыл его прокомментировать, я его не использую. Хорошо, если я добавлю следующее состояние, то есть n_state, в список чувствительности, это сработает? Во-вторых, да, когда все 0, я ничего не увижу, но как насчет сдвигающейся части? Я определил выходы явно для каждого состояния, должен ли я установить здесь ограничение? - person alexhilton; 22.06.2014
comment
а) нет, n_state в списке чувствительности ничего не сделает б) смещение всех нулей по-прежнему все нули. Вы можете рассмотреть состояние для каждого отображаемого светодиода, всего 10 состояний. Если бы состояния были одним горячим, новые 8 состояний могли бы управлять светодиодом каждое. - person ; 22.06.2014
comment
И это определило бы счетчик Джонсона. - person ; 22.06.2014
comment
Не могли бы вы случайно показать мне пример или что-то в этом роде? Это помогло бы мне больше понять - person alexhilton; 22.06.2014