Лекции
Практические
Тесты
Лабораторные
Доп. материалы
- Заголовок
- Написание тестирующей программы
- Автор
- Авдеев Н.А.
- Нижний колонтитул
- ПТСиПЦУвСБ/Лекция 5
- Дополнительный нижний колонтитул
- Авдеев Н.А., 17:58, 8 апреля 2014
Слайд: Содержание
- Назначение тестирующей программы
- Структура тестирующей программы
- подмножество языка VHDL для написания тестирующих программ
Слайд: Структура тестирующей программы
|
VHDL-описания компонентов
Файл: ram_pkg.vhd
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package ram_pkg is
constant addr_width : natural := 8;
constant data_width : natural := 4;
subtype TString is string(1 to 100);
type PortsInRecType is record
addr : std_logic_vector(addr_width - 1 downto 0);
di : std_logic_vector(data_width - 1 downto 0);
wr : std_logic;
clk : std_logic;
Info : TString;
end record PortsInRecType;
type PortsOutRecType is record
do : std_logic_vector(data_width - 1 downto 0);
end record PortsOutRecType;
end package ram_pkg;
-- package body ram_pkg is
-- end package body ram_pkg;
|
Файл: ram_testctrl.vhd
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ram_pkg.all;
entity TestCtrl is
generic (
addr_width : natural := 8;
data_width : natural := 4);
port (
PortsInRec : out PortsInRecType;
PortsOutRec : in PortsOutRecType
);
end entity TestCtrl;
architecture Test1 of TestCtrl is
signal Clk : std_logic := '1';
procedure wr_data (
signal port_in : out PortsInRecType;
data : in natural;
addr : in natural) is
begin
port_in.clk <= 'Z';
wait until clk = '0' and clk'event;
port_in.di <= std_logic_vector(to_unsigned(data, data_width));
port_in.addr <= std_logic_vector(to_unsigned(addr, addr_width));
port_in.wr <= '1';
wait until clk = '1' and clk'event;
-- port_in.wr <= '0';
end ;
procedure rd_data (
signal port_in : out PortsInRecType;
-- data : out natural;
addr : in natural) is
begin
port_in.clk <= 'Z';
wait until clk = '0' and clk'event;
port_in.addr <= std_logic_vector(to_unsigned(addr, addr_width));
port_in.wr <= '0';
wait until clk = '1' and clk'event;
end ;
begin -- architecture Test1
-- clock generation
Clk <= not Clk after 5 ns;
PortsInRec.clk <= clk;
-- waveform generation
WaveGen_Proc: process
begin
wr_data(PortsInRec, 10, 15);
wr_data(PortsInRec, 20, 16);
rd_data(PortsInRec, 15);
rd_data(PortsInRec, 16);
rd_data(PortsInRec, 17);
wait for 10 ns;
assert false report "END Simulation" severity failure;
wait;
end process WaveGen_Proc;
end architecture Test1;
|
Файл: ram_model.vhd
|
library ieee;
use ieee.std_logic_1164.all;
use work.ram_pkg.all;
entity ram_model is
generic (
addr_width : natural := 8;
data_width : natural := 4);
port (
PortsInRec : In PortsInRecType;
PortsOutRec : out PortsOutRecType;
addr : out std_logic_vector(addr_width - 1 downto 0);
di : out std_logic_vector(data_width - 1 downto 0);
wr : out std_logic;
clk : out std_logic;
do : in std_logic_vector(data_width - 1 downto 0));
end entity ram_model;
architecture beh of ram_model is
begin -- architecture beh
addr <= PortsInRec.addr;
di <= PortsInRec.di;
wr <= PortsInRec.wr;
clk <= PortsInRec.clk;
PortsOutRec.do <= do;
end architecture beh;
|
Файл: ram.vhd
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ram is
generic (
addr_width : natural := 8;
data_width : natural := 4);
port (
addr : in std_logic_vector(addr_width - 1 downto 0);
di : in std_logic_vector(data_width - 1 downto 0);
wr : in std_logic;
clk : in std_logic;
do : out std_logic_vector(data_width - 1 downto 0));
end entity ram;
architecture beh of ram is
type mem_t is array (natural range <>) of std_logic_vector(data_width - 1 downto 0);
signal mem : mem_t(0 to (2**addr_width - 1));
begin -- architecture beh
p1: process (clk) is
variable addr_i : natural;
begin -- process p1
addr_i := to_integer(unsigned(addr));
if clk'event and clk = '1' then -- rising clock edge
if wr = '1' then
mem(addr_i) <= di;
do <= di;
else
do <= mem(addr_i);
end if;
end if;
end process p1;
end architecture beh;
|
Файл: ram_tb.vhd
|
library ieee;
use ieee.std_logic_1164.all;
use work.ram_pkg.all;
-------------------------------------------------------------------------------
entity ram_tb is
end entity ram_tb;
-------------------------------------------------------------------------------
architecture tb of ram_tb is
-- component generics
constant addr_width : natural := 8;
constant data_width : natural := 4;
-- component ports
signal addr : std_logic_vector(addr_width - 1 downto 0);
signal di : std_logic_vector(data_width - 1 downto 0);
signal wr : std_logic;
signal clk : std_logic;
signal do : std_logic_vector(data_width - 1 downto 0);
signal PortsInRec : PortsInRecType;
signal PortsOutRec : PortsOutRecType;
begin -- architecture tb
-- component instantiation
DUT: entity work.ram
generic map (
addr_width => addr_width,
data_width => data_width)
port map (
addr => addr,
di => di,
wr => wr,
clk => clk,
do => do);
TestCtrl_1: entity work.TestCtrl
generic map (
addr_width => addr_width,
data_width => data_width)
port map (
PortsInRec => PortsInRec,
PortsOutRec => PortsOutRec);
model_1: entity work.ram_model
generic map (
addr_width => addr_width,
data_width => data_width)
port map (
PortsInRec => PortsInRec,
PortsOutRec => PortsOutRec,
addr => addr,
di => di,
wr => wr,
clk => clk,
do => do);
end architecture tb;
|
Слайд: Подача сигнала сброса
signal rst : std_logic;
. . .
rst <= '1', '0' after 15 ns; -- Вариант 1
p1: process is -- Вариант 2
begin -- process p1
rst <= '1';
wait for 15 ns;
rst <= '0';
wait;
end process p1;
Слайд: Подача синхросигнала
signal clk : std_logic := '0';
. . .
clk <= not clk after 5 ns; -- Вариант 1
p1: process is -- Вариант 2
begin -- process p1
clk <= '1';
wait for 5 ns;
clk <= '0';
wait for 5 ns;
end process p1;
Слайд: Подача последовательности тестовых векторов
Слайд: Подача последовательности тестовых векторов (Вариант 1)
signal x : std_logic_vector(2 downto 0) := (others => '0');
. . .
x(0) <= not x(0) after 50 ns;
x(1) <= not x(1) after 100 ns;
x(2) <= not x(2) after 200 ns;
Слайд: Подача последовательности тестовых векторов (Вариант 2)
signal x : std_logic_vector(2 downto 0) := (others => '0');
. . .
l1: for i in 0 to 2 generate
x(i) <= not x(i) after (2**i) * 10 ns;
end generate l1;
Слайд: Подача последовательности тестовых векторов (Вариант 3)
use ieee.numeric_std.all;
...
signal x : std_logic_vector(2 downto 0) := (others => '0');
signal xu : unsigned(2 downto 0) := (others => '0');
. . .
xu <= xu + 1 after 10 ns;
x <= std_logic_vector(xu);
x <= std_logic_vector(unsigned(x) + 1) after 10 ns;
Слайд: Подача заданной последовательности тестовых векторов
p1: process is
begin -- process p1
rst <= '1';
x <= "001";
en <= '0'
wait for 15 ns;
rst <= '0';
wait for 5 ns;
en <= '1'
wait for 20 ns;
en <= '0'
wait for 5 ns;
x <= "101";
wait for 25 ns;
x <= "100";
wait for 25 ns;
en <= '1'
x <= "110";
wait;
end process p1;
Слайд: Использование процедур для генерации тестовых векторов
Слайд: Подача псевдослучайной последовательности тестовых векторов
- Требуется дополнительная компиляция пакета RandomPkg из OSVVM.zip
use work.RandomPkg.all;
. . .
constant inputs : natural := 10;
signal x : std_logic_vector(inputs - 1 downto 0);
. . .
p1: process is
variable RV : RandomPType ; -- переменная RV защищенного (protected) типа RandomPType
begin -- process p1
RV.initseed(RV'instance_name); -- начальная установка псевдослучайного генератора
l1: loop
x <= RV.RandSlv(inputs); -- генерация псевдослучайного вектора разрядностью inputs
wait for 2 ns;
end loop;
end process p1;
Слайд: Процедуры
subprogram_body ⇐
procedure identifier [ ( parameter_interface_list ) ] is
{ subprogram_declarative_part }
begin
{ sequential_statement }
end [ procedure ] [ identifier ] ;
return_statement ⇐ [ label : ] return ;
interface_list ⇐
( [ constant | variable | signal ]
identifier { , ... } : [ mode ] subtype_indication
[ := static_expression ] ) { ; ... }
mode ⇐ in | out | inout
procedure do_arith_op ( op : in func_code ) is
variable result : integer;
begin
case op is
when add =>
result := op1 + op2;
when subtract =>
result := op1 - op2;
end case;
dest <= result after Tpd;
Z_flag <= result = 0 after Tpd;
end procedure do_arith_op;
library ieee;
use ieee.std_logic_1164.all;
entity signal_generator is
end entity signal_generator;
architecture top_level of signal_generator is
signal raw_signal : std_ulogic;
procedure generate_pulse_train
( width, separation : in delay_length;
number : in natural;
signal s : out std_ulogic ) is
begin
for count in 1 to number loop
s <= '1', '0' after width;
wait for width + separation;
end loop;
end procedure generate_pulse_train;
begin
raw_signal_generator : process is
begin
generate_pulse_train ( width => 20 ns,
separation => 10 ns,
number => 10,
s => raw_signal );
generate_pulse_train ( width => 5 ns,
separation => 20 ns,
number => 10,
s => raw_signal );
wait;
end process raw_signal_generator;
end architecture top_level;
Слайд: Функции
subprogram_body ⇐
[ pure I impure ]
function identifier [ ( parameter_interface_list ) ] return type_mark is
{ subprogram_declarative_item }
begin
{ sequential_statement }
end [ function ] [ identifier ] ;
return_statement ⇐ [ label : ] return expression ;
function_call ⇐ function_name [ ( parameter_association_list ) ]
function limit ( value, min, max : integer ) return integer is
begin
if value > max then
return max;
elsif value < min then
return min;
else
return value;
end if;
end function limit;