Есть две сразу бросающиеся в глаза вещи неправильно.
Первый счетчик не объявлен (закомментируйте, достаточно просто).
Во-вторых, оказавшись в S1 n_state ‹= S1, другими словами, вы идете в S1 и сидите там. Следствием этого является то, что процесс INPUT_BLOCK не имеет триггерного события - чувствительность содержит только c_state и никаких дальнейших изменений в c_state.
![scan_tb, однократное изменение состояния](https://i.stack.imgur.com/cmtUX.png)
Я полагаю, что Брайан Драммонд будет рассказывать вам об использовании одного процесса для вашего 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 исправлено](https://i.stack.imgur.com/G6oTX.png)
Обратите внимание, что основание для светодиода было изменено в форме сигнала на двоичное.
Также обратите внимание, что первая часть двух сигналов совпадает. Я также добавил распознаватель состояния 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;
И вы получаете светодиоды сканирования, чтобы продолжать сканирование:
![сканирование с непрерывной рециркуляцией](https://i.stack.imgur.com/uZWMm.png)
Мы переключили светодиод (0), чтобы он не зависел от других положений shft_reg, установленных в «1» (не «0»).
person
Community
schedule
22.06.2014