Предупреждение: это будет долго. Извините, если это слишком многословно.
Я только начинаю изучать FPGA и VHDL, используя Quartus Prime. За последние несколько дней я научил себя:
- Как написать VHDL
- Как сделать компонент
- Как написать тестовый стенд
- Как использовать ранее созданные и протестированные компоненты - связанные вместе - для создания нового компонента
Однако я не могу понять, как создать тестовый стенд, который тестирует новый компонент, использующий два существующих компонента, когда некоторые из сигналов этого нового компонента являются только внутренними сигналами.
Итак, вот два суперпростых компонента, которые я успешно написал и протестировал на испытательных стендах. Между прочим, я понимаю, что это не настоящий мир, я просто пытаюсь сделать маленькие шаги.
1. Четырехбитный регистр
library ieee;
use ieee.std_logic_1164.all;
entity four_bit_reg is
port
(
bcd_in: in std_logic_vector(3 downto 0);
clk: in std_logic;
clr: in std_logic;
bcd_out: out std_logic_vector(3 downto 0)
);
end four_bit_reg;
architecture behaviour of four_bit_reg is
begin
process (clk,clr)
begin
if (clr = '1') then
bcd_out <= "0000";
elsif rising_edge(clk) then
bcd_out <= bcd_in;
end if;
end process;
end behaviour;
2. Преобразователь BCD в семь сегментов
library ieee;
use ieee.std_logic_1164.all;
entity sev_seg is
port
(
bcd_value : in std_logic_vector(3 downto 0);
sev_seg_value : out std_logic_vector(6 downto 0)
);
end sev_seg;
architecture behaviour of sev_seg is
begin
sev_seg_process : process (bcd_value)
begin
case bcd_value is
when "0000" => sev_seg_value <="0111111"; -- 0
when "0001" => sev_seg_value <="0000110"; -- 1
when "0010" => sev_seg_value <="0111011"; -- 2
when "0011" => sev_seg_value <="1001111"; -- 3
when "0100" => sev_seg_value <="1100110"; -- 4
when "0101" => sev_seg_value <="1101101"; -- 5
when "0110" => sev_seg_value <="1111101"; -- 6
when "0111" => sev_seg_value <="0000111"; -- 7
when "1000" => sev_seg_value <="1111111"; -- 8
when "1001" => sev_seg_value <="1101111"; -- 9
when others => sev_seg_value <= "0000000"; -- A to F should show blank
end case;
end process sev_seg_process;
end behaviour;
Первый вопрос: как вы называете две вещи выше? Компоненты? Модули? Сущности? Что-то другое?
Затем я использую эти два в другом новом компоненте / объекте / модуле (в зависимости от ситуации), как показано ниже:
library ieee;
use ieee.std_logic_1164.all;
entity two_modules is
port
(
bcd_pins : in std_logic_vector(3 downto 0);
sev_seg_pins : out std_logic_vector(6 downto 0)
);
end two_modules;
architecture behaviour of two_modules is
-- Internal signals
signal int_clk: std_logic;
signal int_bus: std_logic_vector(3 downto 0);
-- List any components used in the design
component four_bit_reg is
port
(
bcd_in: in std_logic_vector(3 downto 0);
clk: in std_logic;
clr: in std_logic;
bcd_out: out std_logic_vector(3 downto 0)
);
end component;
component sev_seg is
port
(
bcd_value : in std_logic_vector(3 downto 0);
sev_seg_value : out std_logic_vector(6 downto 0)
);
end component;
begin -- start the instances
fbr: four_bit_reg port map
(
clk => int_clk,
bcd_in => bcd_pins,
clr => '0',
bcd_out => int_bus
);
sseg: sev_seg port map
(
bcd_value => int_bus,
sev_seg_value => sev_seg_pins
);
end behaviour;
Итак, для этой вещи, которую я назвал two_modules, структура для тестового стенда, созданного Quartus, выглядит следующим образом:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY two_modules_vhd_tst IS
END two_modules_vhd_tst;
ARCHITECTURE two_modules_arch OF two_modules_vhd_tst IS
-- constants
-- signals
SIGNAL bcd_pins : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL sev_seg_pins : STD_LOGIC_VECTOR(6 DOWNTO 0);
signal internal_clock : std_logic := '0';
COMPONENT two_modules
PORT (
bcd_pins : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
sev_seg_pins : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
);
END COMPONENT;
BEGIN
i1 : two_modules
PORT MAP (
-- list connections between master ports and signals
bcd_pins => bcd_pins,
sev_seg_pins => sev_seg_pins
);
internal_clock <= not internal_clock after 500 us;
init : PROCESS
-- variable declarations
BEGIN
-- code that executes only once
WAIT;
END PROCESS init;
always : PROCESS
-- optional sensitivity list
-- ( )
-- variable declarations
BEGIN
-- code executes for every event on sensitivity list
WAIT;
END PROCESS always;
END two_modules_arch;
Как вы можете видеть, я создал внутренние часы, и я хотел бы, исключительно для целей изучения, как делать подобные вещи, подчеркиваю, я понимаю, что это не полный дизайн , присоединитесь к internal_clock (который, как я вижу, работает и представляет собой сигнал в редакторе сигналов модели Sim), чтобы кликнуть в four_bit_reg.
Я думаю и надеюсь, что когда я знаю, как это сделать, я смогу вспахать и получить настоящий сложный испытательный стенд. Однако после долгих поисков я не могу найти ссылки на то, как связать воедино сигналы от подкомпонентов. Это может быть потому, что я использую совершенно неправильную терминологию и где-то там может быть идеальное руководство.
Итак:
- Как я могу для начала подключить мой internal_clock к субкомпоненту, входу clk four_bit_reg?
- Какова правильная терминология, когда вы используете и соединяете такие вещи, как four_bit_reg и sev_seg? Подкомпоненты? Что-то другое?
Большое спасибо, если вы зашли так далеко!