«…Труд избавляет человека от трех великих зол: скуки, порока, нужды…»

ПТСиПЦУвСБ/Лекция 5 — различия между версиями

Материал из Wiki
Перейти к: навигация, поиск
м
м
 
(не показаны 2 промежуточные версии 1 участника)
Строка 13: Строка 13:
 
* Структура тестирующей программы
 
* Структура тестирующей программы
 
* подмножество языка VHDL для написания тестирующих программ
 
* подмножество языка VHDL для написания тестирующих программ
* [[VHDL/Генерация входных воздействий|Генерация входных воздействий]]
+
** [[VHDL/Генерация входных воздействий|Генерация входных воздействий]]
 +
** работа с файлами в VHDL (стр. 233)
 +
 
 +
== Слайд: Структура тестирующей программы ==
 +
 
 +
{| align=center
 +
! <html><img src="https://docs.google.com/drawings/d/19Shv2NAXrvECpxVOqDzdi7CPHrZ_i1wTRznZjEoodIs/pub?w=800"></html>
 +
|}
 +
 
 +
 
 +
{{Hider|VHDL-описания компонентов}}
 +
 
 +
<big><big>
 +
 
 +
{{Файл|ram_pkg.vhd|
 +
<big><big>
 +
<source lang="vhdl">
 +
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;
 +
</source>
 +
</big></big>
 +
}}
 +
 
 +
 
 +
{{Файл|ram_testctrl.vhd|
 +
<source lang="vhdl">
 +
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;
 +
</source>
 +
}}
 +
 
 +
 
 +
{{Файл|ram_model.vhd|
 +
<source lang="vhdl">
 +
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;
 +
</source>
 +
}}
 +
 
 +
{{Файл|ram.vhd|
 +
<source lang="vhdl">
 +
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;
 +
</source>
 +
}}
 +
 
 +
 
 +
{{Файл|ram_tb.vhd|
 +
<source lang="vhdl">
 +
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;
 +
</source>
 +
}}
 +
</big></big>
 +
{{Hider|end}}
 +
 
  
 
{{:VHDL/Генерация входных воздействий}}
 
{{:VHDL/Генерация входных воздействий}}
 +
 +
== Слайд: Процедуры ==
 +
 +
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;
 +
 +
<big><big>
 +
<source lang="vhdl">
 +
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;
 +
</source>
 +
</big></big>
 +
 +
== Слайд: Функции ==
 +
 +
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;

Текущая версия на 17:58, 8 апреля 2014

Лекции ПТСиПЦУвСБ

Лекции

Практические
Тесты

Лабораторные

Доп. материалы

Заголовок
Написание тестирующей программы
Автор
Авдеев Н.А.
Нижний колонтитул
ПТСиПЦУвСБ/Лекция 5
Дополнительный нижний колонтитул
Авдеев Н.А., 17:58, 8 апреля 2014


Содержание

Слайд: Содержание

  • Назначение тестирующей программы
  • Структура тестирующей программы
  • подмножество языка VHDL для написания тестирующих программ

Слайд: Структура тестирующей программы



Слайд: Подача сигнала сброса

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 ] ) { ; ... }
   modein | 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;