Назначение входа в testbench и выходные значения (ghdl и gtkwave)
Я иду прямо к конкретике.
Я использую Ubuntu 14.04LTS, компилятор GHDL и GTKWave для симуляции.
У меня есть два файла для моделирования простого 2-мультиплексора: mux2.vhd и mux2_testbench.vhd
Это код для mux2.vhd
-- Libraries
library ieee;
use ieee.std_logic_1164.all;
-- Entity declaration
entity mux2 is
port(
e0, e1 : in std_logic;
c : in std_logic;
output : out std_logic
);
end mux2;
-- Architecture declaration
architecture mux2_arch of mux2 is
begin
process (e0, e1, c)
begin
if c = '0' then
output <= e0;
else
output <= e1;
end if;
end process;
end mux2_arch;
Код для испытательного стенда
--Libraries
library ieee;
use ieee.std_logic_1164.all;
--Empty entity for simulation
entity mux2_testbench is
end mux2_testbench;
architecture testbench_arch of mux2_testbench is
component test is
port(
c : in std_logic;
e0, e1 : in std_logic;
output : out std_logic
);
end component;
signal c: std_logic;
constant clk: time:=50 ns;
signal e0: std_logic;
signal e1: std_logic;
signal output: std_logic;
begin
lab: test
port map(
c => c,
e0 => e0,
e1 => e1,
output => output
);
process
begin
--Case 1: Control signal is low
c <= '0';
e0 <= '0';
e1 <= '0';
wait for 100 ns;
e0 <= '0';
e0 <= '1';
wait for 100 ns;
e0 <= '1';
e0 <= '0';
wait for 100 ns;
e0 <= '1';
e0 <= '1';
wait for 100 ns;
--Case 2: Control signal is high
c <= '1';
e0 <= '0';
e1 <= '0';
wait for 100 ns;
e0 <= '0';
e0 <= '1';
wait for 100 ns;
e0 <= '1';
e0 <= '0';
wait for 100 ns;
e0 <= '1';
e0 <= '1';
end process;
end testbench_arch;
Вещи, которые я делаю:
Я собираю через терминал без ошибок с: ghdl -a mux2.vhd и ghdl -a mux2_testbench.vhd
Затем я создаю исполняемый файл для testbench: ghdl -e mux2_testbench
Наконец, я создаю файл vcd, который мне нужен для использования gtkwave: ghdl -r mux2_testbench --vcd = test.vcd &
Симуляция: gtkwave test.vcd
У меня две проблемы с этим кодом: 1. Несмотря на то, что я записываю разные значения в сигналах e0 и e1, e1 ничего не показывает в симуляции. Это всегда "0".
- Выходной сигнал показывает значение "U" в симуляции, я даже не уверен, что это значит, и не смог найти ничего ясного в Google.
Спасибо всем заранее, приятели.
2 ответа
В соответствии с комментарием Брайана я добавил спецификацию конфигурации для использования mux2 вместо test в testbench:
architecture testbench_arch of mux2_testbench is
component test is
port (
c: in std_logic;
e0, e1: in std_logic;
output: out std_logic
);
end component;
signal c: std_logic;
constant clk: time := 50 ns;
signal e0: std_logic;
signal e1: std_logic;
signal output: std_logic;
for lab: test use entity work.mux2; -- added
begin
lab:
test
port map (
c => c,
e0 => e0,
e1 => e1,
output => output
);
process
begin
--Case 1: Control signal is low
c <= '0';
e0 <= '0';
e1 <= '0';
wait for 100 ns;
e0 <= '0';
e0 <= '1';
wait for 100 ns;
e0 <= '1';
e0 <= '0';
wait for 100 ns;
e0 <= '1';
e0 <= '1';
wait for 100 ns;
--Case 2: Control signal is high
c <= '1';
e0 <= '0';
e1 <= '0';
wait for 100 ns;
e0 <= '0';
e0 <= '1';
wait for 100 ns;
e0 <= '1';
e0 <= '0';
wait for 100 ns;
e0 <= '1';
e0 <= '1';
wait for 100 ns; -- added to terminate the simulation
wait; -- added ""
end process;
end architecture testbench_arch;
Я также добавил два оператора ожидания, чтобы симуляция завершалась без добавления флага --stop-time=somvalue при использовании --wave=testbench.ghw вместо --vcd = test.vcd.
(Gtkwave также принимает формат файла дампа GHW, который является уникальным для ghdl, он является сжатым форматом и не так удобен, как CTL-C, чтобы остановить симуляцию, которая в противном случае непрерывно зациклилась бы).
Это дает:
Обратите внимание, что из уважения к ответу Мэтью e1
всегда низкий, вы все еще можете различить, какой вход отображается на output
, демонстрируя c
обеспечивает функцию выбора.
"U" появилось бы, потому что компонентный тест не был связан с тестом сущности, не найденным в рабочей библиотеке.
Указание привязки в вышеприведенном примере выполняется спецификацией конфигурации. См. IEEE Std 1076-2008 7.3 Спецификация конфигурации и 7.3.2 Индикация привязки.
Вы также можете использовать непосредственное создание экземпляра сущности в качестве защитника Мэтью или с помощью объявления конфигурации, содержащего указание привязки, оставить создание экземпляра тестового компонента как есть.
Возможность повторного использования испытательного стенда будет ограничена схемами стимулов для входов в тестируемое устройство (лабораторию).
Во-первых, 'U'
значение по умолчанию для типа std_logic
, Это означает, что неинициализирован. Любой сигнал, который не был назначен или не управляется, будет иметь значение 'U'
, Я думаю, что весьма вероятно, что ваши выходные данные не управляются, потому что вы создали экземпляр компонента под названием test
пока ваше устройство тестируется entity
называется mux2
, Я рекомендую изменить имя вашего компонента на mux2
тогда правила связывания по умолчанию позволят вашей сущности mux2
быть привязанным к компоненту mux2
:
component mux2 is
port( c : in std_logic;
e0, e1 : in std_logic;
output : out std_logic );
end component;
а также
-- this is component instantiation
lab: mux2
port map(
c => c,
e0 => e0,
e1 => e1,
output => output
);
Итак entity
mux2
не привязан к component
test
, Думать о component
как подобие сокета IC; думать о entity
как то, как IC, который идет в сокете. Если твой component
называется test
и ваш entity
называется mux2
Как симулятор узнает, как связать (то есть соединить) их вместе? Вы могли бы написать то, что называется configuration
сделать это связывание, но было бы гораздо проще изменить component
имя для mux2
тогда это произойдет автоматически.
(Или, что еще лучше, зачем вообще использовать создание компонентов? Зачем беспокоиться о компоненте? Почему бы вместо этого не использовать прямое создание экземпляров?)
-- this is direct instantiation
lab: entity work.mux2
port map(
c => c,
e0 => e0,
e1 => e1,
output => output
);
Во-вторых, очевидно, что вы не за рулем e1. Конечно, такие строки:
e0 <= '0';
e0 <= '1';
должно быть
e0 <= '0';
e1 <= '1';
-- ^
-- |