Лекции
Практические
Тесты
Лабораторные
Доп. материалы
 
- Заголовок
-  Написание тестирующей программы
- Автор
-  Авдеев Н.А.
- Нижний колонтитул
-  ПТСиПЦУвСБ/Лекция 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;