GHDL зависает запущенный тестовый стенд
При тестировании простой реализации game of life в VHDL, имитация GHDL пустого тестового стенда зависает со 100% использованием процессора, после распечатки сообщения "конец теста".
Вот код:
----- Package ------------------------------
library ieee;
use ieee.std_logic_1164.all;
package data_types is
type array2D is array (0 to 10, 0 to 10) of std_logic;
end data_types;
----- Main Code ----------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.data_types.all;
entity de0 is
port (matrix : inout array2D);
end de0;
architecture life of de0 is
-- Return the integer value of a cell, treating all out of bounds as 0
function cellValue (matrix : array2D; x, y : integer) return integer is
begin
if (y < 0 or y > matrix'high(1) or x < 0 or x > matrix'high(2) or matrix(y, x) = '0') then
return 0;
else
return 1;
end if;
end cellValue;
begin
-- Iterate over all cells
row: for y in matrix'range(1) generate
column: for x in matrix'range(2) generate
process
variable neighbours : integer := cellValue(matrix, x - 1, y - 1) +
cellValue(matrix, x - 1, y) +
cellValue(matrix, x - 1, y + 1) +
cellValue(matrix, x, y - 1) +
cellValue(matrix, x, y + 1) +
cellValue(matrix, x + 1, y - 1) +
cellValue(matrix, x + 1, y) +
cellValue(matrix, x + 1, y + 1);
begin
-- Update the cell value according to the game of life rules
if (neighbours = 2 or neighbours = 3) then
matrix(y, x) <= '1';
else
matrix(y, x) <= '0';
end if;
end process;
end generate;
end generate;
end life;
И тестовый стенд:
library ieee;
use ieee.std_logic_1164.all;
use work.data_types.all;
entity life_tb is
end life_tb;
architecture behaviour of life_tb is
component life
port (matrix : inout array2D);
end component;
for test: life use entity work.de0;
signal matrix : array2D;
begin
test: life port map (matrix => matrix);
process
begin
assert false
report "End of test" severity note;
wait;
end process;
end behaviour;
2 ответа:
Процесс в жизни de0 не имеет ни списка чувствительности, ни оператора ожидания, поэтому этот процесс будет выполняться вечно, просто выполняя операторы в процессе в бесконечном цикле в то же время моделирования, и моделирование, следовательно, не остановится.
Это можно исправить, добавив список чувствительности
(matrix)
или ожидание с некоторым условием.
Это дополняет прекрасный ответ Мортенздка. Он просто слишком большой, чтобы идти в комментариях и не меняет этот ответ. Он демонстрирует, как сделать вашу модель тактовой, а также как остановить ее непрерывный запуск.
Матрица размещения-это список чувствительности немеченого процесса в de0 (life)
process (matrix)
Дает:
ghdl -a de0.vhdl ghdl -a life_tb.vhdl ghdl -e life_tb ghdl -r life_tb life_tb.vhdl:22:13:@0ms:(assertion note): End of test
Тест утверждения выполняется только один раз и немедленно, он не сигнализирует о завершении теста.
Обратите внимание, что модель перестала выполняться, но мы не имею ни малейшего представления, сколько циклов моделирования это заняло. Идея, лежащая в основе времени моделирования, заключается в том, чтобы сохранить осциллограммы, а также квантовать относительное время.
Добавление часов к моделированию:
В декларативной области архитектуры мы объявляем тактовый сигнал:
signal clk: std_logic;
Вы можете добавить новый процесс для создания часов в вашем тестовом стенде (life_tb.vhdl):
Он имеет период 20 НС, и первое положительное ребро составляет 10 НС в моделировании.CLOCK: process begin wait for 10 ns; clk <= '0'; wait for 10 ns; clk <= '1'; end process;
Добавим часы к порту на life:
component life port ( matrix : inout array2D; clk: in std_logic ); end component;
Мы обновляем сущность de0, чтобы использовать clk:
entity de0 is port ( matrix : inout array2D; clk: in std_logic );
Мы обновляем процесс, чтобы он был чувствителен к clk и был синхронизирован:
process (clk) variable neighbours : integer := cellValue(matrix, x - 1, y - 1) + cellValue(matrix, x - 1, y) + cellValue(matrix, x - 1, y + 1) + cellValue(matrix, x, y - 1) + cellValue(matrix, x, y + 1) + cellValue(matrix, x + 1, y - 1) + cellValue(matrix, x + 1, y) + cellValue(matrix, x + 1, y + 1); begin if clk'event and clk = '1' then -- Update the cell value according to the game of life rules if (neighbours = 2 or neighbours = 3) then matrix(y, x) <= '1'; else matrix(y, x) <= '0'; end if; end if;
Теперь, поскольку clk является свободно работающим осциллятором, нам нужно использовать stop-time:
ghdl -a de0.vhdl ghdl -a life_tb.vhdl ghdl -e life_tb ghdl -r life_tb --stop-time=100ns --wave=life_tb.ghw life_tb.vhdl:35:13:@0ms:(assertion note): End of test ghdl:info: simulation stopped by --stop-time
Если прокрутить элементы maxtrix, мы обнаружим, что четыре угла матрицы имеют значение '1' при первом событии синхронизации. Все остальные элементы имеют значение '0'.
Второе событие clk показанный на курсоре не присваивает новые значения никаким элементам матрицы (четыре угла матрицы каждый видит три соседа, они стабильны).
Если бы матрица была в списке чувствительности процесса вместо этого, ваше моделирование остановилось бы после второго раза (без синхронизации).
И смысл временной симуляции заключается в том, что она позволяет заглянуть в симуляцию, исследуя формы волн, в данном случае с gtkwave. Альтернативой являются утверждения и / или отчеты, но в несвоевременное моделирование они будут происходить на границах цикла, и нет никакой гарантии порядка, если они не являются последовательными утверждениями в одном и том же процессе.
И вы могли бы отметить, что без изменения исходного кода, кроме оператора assertion, оценивающего для matrix ' Event в testbench, вы могли бы заставить вашу модель прекратить имитацию. Вы хотите изменить порог для остановки моделирования с помощью опции времени выполнения (например, --assert-level=warning, где утверждение для отсутствия matrix'Event-это предупреждение. (И утверждение означало бы фактический конец теста).
Фиксация cellValue, как говорится, упражнение, оставленное читателю. (Например, как и почему были установлены углы матрицы в первую очередь?)Интересная часть заключается в том, чтобы сказать, когда ваша модель находится в состоянии покоя, когда она синхронизирована. Вы можете использовать matrix ' Event для переключения сигнала (использовать его как часы) и использовать часы для проверки двух последовательных вхождений одного и того же значения этого сигнала. И конечно сигнал может используется в операторе утверждения с assert-level для завершения моделирования в состоянии покоя.
Синтезируемое оборудование немного сложнее.