VERILOG




     5. Подпрограммы. Библиотека PLI



             Автоматизация проектирования
                 компьютерных систем

                  д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ
21.02.2011                e-mail: hahanova@mail.ru             1
Цель лекции и содержание
 Цель – изучить методы построения и
  механизм использования подпрограмм
  в Verilog. Узнать возможности
  расширения функций программ
  моделирования с благодаря
  интерфейсу PLI
 План
   Подпрограммы: Task и Function
   Библиотека PLI

 21.02.2011   д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   2
                            hahanova@mail.ru
1 Task и Function: Старый стиль
//Синтаксис функции                          //Синтаксис задачи
function [automatic]                         task [ automatic ] identifier;
   [signed] [range_or_type]                     parameter_declaration;
   identifier;                                  input_declaration;
     parameter_declaration;                     output_declaration;
     input_declaration;                         inout_declaration;
     register_declaration;                      register_declaration;
                                                event_declaration;
         statement;
                                                    statement;
  endfunction                                    endtask

  21.02.2011          д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:        3
                                    hahanova@mail.ru
2 Task и Function: Новый стиль
//Синтаксис функции                        //Синтаксис задачи
function [automatic] [signed]              task [ automatic ]
   [range_or_type] identifier                 task_identifier
   (function_port_list );                             (task_port_list ) ;
   block_item_declaration {
                                              { block_item_declaration }
        block_item_declaration }
                                              statement
    function_statement
                                           endtask
endfunction

Пример                                     Пример
function [7:0] getbyte                       task my_task (input a, b,
          (input [15:0] address);              inout c, output d, e);

  21.02.2011        д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:            4
                                  hahanova@mail.ru
Свойства функций и задач
             Функция                     Задача
  1 Может вызывать другую    Может вызывать как задачи,
    функцию, задачу нет      так и функции
  2 Всегда выполняется       На выполнение может
    мгновенно                постребоваться ненулевой
                             промежуток времени
  3 Не может содержать       Может содержать временные
    временные или событийные или событийные операторы
    операторы управления     управления
  4 Имеет только входные     Может иметь аргументы типа
    аргументы (input)        input, output и inout
  5 Всегда возвращ ает       Не возвращ ает значение, но
    единственное значение    может передавать через
                             аргументы типа output и inout

21.02.2011       д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   5
                               hahanova@mail.ru
Пример использования функции
 function real multiply (input a, b);
        real a, b;
        multiply = ((1.2 * a) * (b * 0.17)) * 5.1;
  endfunction
  //...
  real a;
  initial begin
             a = multiply(1.5, a);
  end
  21.02.2011   д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   6
                             hahanova@mail.ru
Функции для вычисления факториала

module tryfact;                                 //использование функции
     // описание функции                        integer result, n;
 function [31:0] factorial;                  initial
        input [3:0] operand;                    begin
        reg [3:0] i;                            for (n = 0; n <= 7; n = n+1)
   begin                                          begin
    factorial = 1;                                 result = factorial(n);
   for (i = 2; i <= operand; i = i              $display(“%0d
   + 1)                                         factorial=%0d”, n, result);
      factorial = i * factorial;                  end
   end                                          end
 endfunction                                 endmodule

   21.02.2011         д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:         7
                                    hahanova@mail.ru
Создание и использование задач
task first_task;                              integer x;
   parameter size=4;                          reg a, b, y;
   // Входной аргумент                        reg [3:0] z;
   input a; integer a;                        reg [7:0] w;
   // Двунаправленный аргумент
   inout [size-1:0] b;                        ...
   // Выходной аргумент                       first_task(x, z, y);
   output c;                                  first_task(x, w[7:4], w[1]);
    // Внутренняя переменная                  first_task(1,{a,b,w[3], x[0]}, y);
   reg [size-1:0] d;
   // Декларация события
   event e;                               // Использования именного
  begin                                       события
         d = b; c = |d;                   // из задачи
         b = ~b;                          always @(first_task.e)
         if (!a) -> e;
   end                                        count= count+1;
endtask
  21.02.2011       д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:                8
                                 hahanova@mail.ru
Автоматические функции и задачи
   module tryfact; // описание функции
    function automatic [31:0] factorial;                  В автоматических задач
          input [3:0] operand;                            запрещено использование:
          reg [3:0] i;
    begin                                            1.   неблокирующих
          factorial = 1;                                  операторов;
          for (i = 2; i <= operand; i = i + 1)       2.   непрерывных процедурных
          factorial = i * factorial;
    end                                                   операторов assign и force;
    endfunction                                      3.   внутриоператорного
                                                          контроля;
   //использование функции                       4.      системной задачи $monitor.
            integer result; integer n;
    initial
    begin
            for (n = 0; n <= 7; n = n+1)
            begin
             result = factorial(n);
             $display(“%0d factorial=%0d”, n, result);
            end
    end
    endmodule

    21.02.2011               д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:         9
                                           hahanova@mail.ru
Programming Language Interface (PLI)




               Verilog                      Си




                         Системные
                          Задачи



21.02.2011   д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   10
                           hahanova@mail.ru
Интерфейс PLI используется для:
 Создания дополнительных системных задач и
  функций: задач мониторинга, генерации тестов,
  отладки фрагментов программы;
 Построения различных программных приложений:
  трансляторы, анализ временных параметров;
 Получения информации о проекте: иерархия, связи;
 Создание специальных и пользовательских форм
  управления выводом информации;
 Создания подпрограмм, формирующих тестовые
  последовательности;
 Создания любого основанного на Verilog
  программного приложения.
  21.02.2011   д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   11
                             hahanova@mail.ru
Programming Language Interface (PLI)
               Verilog-код +
             Пользовательские
             системные задачи

                                     Подключение задач
         Verilog-компилятор                                         Таблица
                                                                пользовательских
                                                                системных задач
                                          Доступ к
                                         внутренним
            Внутреннее
                                         структурам
       представление проекта




                                                              п одп ро гр амм PL I



                                                                                     Си-подпрограммы
                                                                                     Пользовательские
        (Структуры данных)




                                                                 Би бл иот ека
                                        Управление
                                      моделированием
              Моделирование

                                     Вывод результатов
      Результаты тестирования          тестирования


21.02.2011               д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:                                   12
                                       hahanova@mail.ru
Разработка системной задачи на Си
 #include “veriuser.h”                            Использование
  #include “aldecpli.h”                        module start_PLI;
  #include <windows.h>                         initial
  int welcome_task()                           begin
  {
       io_printf(“You are welcomet!n”);               $welcome_task;
       return 0;                               end
  }                                            endmodule
  extern "C" __declspec(dllexport) s_tfcell veriusertfs[] =
  {
       {usertask, 0, 0, 0, welcome_task, 0, “$welcome_task”},
       {0}
  };
  BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD
  dwReason,
                                                        LPVOID lpReserved )
       {
  return TRUE;
       }        д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:
 21.02.2011                                                             13
                               hahanova@mail.ru
Синтаксис массива veriusertfs
s_tfcell veriusertfs[] =
  { {usertask | userfunction | userrealfunction, data;
  checktf; sizetf; calltf; misctf; ”$tfname”},
  {0}
  }
 checktf, sizetf, calltf и misctf - различные функции
  обратного вызова, описаны в стандарте Verilog IEEE Std
  1364-1995
 calltf - функция, которая выполняется при вызове
  системной функции или процедуры в Verilog-коде
 “$tfname” – это имя системной функции или задачи в
  Verilog-коде, которое должно начинаться с символа
  доллара ($)
  21.02.2011     д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   14
                               hahanova@mail.ru
Пример массива veriusertfs
s_tfcell veriusertfs[] = {
         {usertask, 0, 0, 0, welcome_task, 0, “$welcome_task”},
         {userfunction, 0, 0, 0, function_call, 0, “$my_function”},
         {0}               // последний элемент должен быть 0
 };




   21.02.2011          д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   15
                                     hahanova@mail.ru
Копии дочерних модулей




                                                              2
                                                    ...




                                                                     1




                                               n1


                 21.02.2011
                                                        Копии примитивов



                                                              2
                                                       ...           1




                                               n2
                                                    Терминалы примитивов
                                                       ...
                                                              2
                                                                     1




                                               n3
                                                                                 module
                                                                              <имя модуля >




              hahanova@mail.ru
                                                        Множества:
                                                        переменные классов,
                                                        цепи и регистры,
                                                      ...




                                                        параметры
д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:
                                                                                              Внутренний формат данных




                                                             Порты модуля
                                                              2




                                                       ...
                                                                     1




                                               nm


                 16
Внутреннее представление данных
     Мультиплексор 2-в-1                                                                                        module
                                                                                                               mux2_to_1


i0                        y1
         n1          a1
                                                                 primitive                          terminal               net                    port




                                              Копии примитивов
              sbar                                                not n1                                                    s                      s
 s                                 o1       out                                                     terminal
                                                                                                                            net
                          y2                                                                                               sbar
                     a2                                          primitive                          terminal
i1                                                                and a1
                                                                                                    terminal               net                    port




                                                                             Терминалы примитивов




                                                                                                                                  Порты модуля
                                                                                                                           i0                      i0




                                                                                                                    Цепи
     module mux2_to_1                                                                               terminal
         (output out,                                                                                                      net
         input i0, i1, s);                                       primitive                          terminal
                                                                                                                           y1

         wire sbar, y1, y2;                                       and a2
                                                                                                                           net                    port
                                                                                                    terminal               i1                      i1
      not n1(sbar, s);
                                                                                                    terminal
      and a1(y1, i0, sbar),                                                                                                net
                                                                                                                           y2
           a2(y2, i1, s);                                        primitive                          terminal
      or o1(out, y1, y2);                                          or o1                                                   net                    port
     endmodule                                                                                      terminal               out                    out

     21.02.2011                д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:
                                                                 terminal                                                                        17
                                             hahanova@mail.ru
Подпрограммы доступа и обслуживания




                         Acc PL I-подпрограмм ы




                                                                     T f PL I-подпрограм мы
   Внутреннее                                      Использующая                                 Пользовательское
  представление                                                                               представление проекта
                                                  PLI -библиотеку                                       +
     проекта                                                                                        тестовые
                                                  пользовательская
(Структуры данных)                                                                             последовательности
                                                  Си-подпрограмма




  21.02.2011         д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:                                             18
                                   hahanova@mail.ru
Подпрограммы доступа (access routine)

 acc_user.h
 Абстрактный идентификатор (handle)
 Существует пять типов подпрограмм доступа:
   Handle routine ( acc_handle_)
   Next routine (acc_next_ )
   Value Change Link (VCL) routine (acc_vcl_)
   Fetch routine (acc_fetch_.)
   Utility access routine (acc_initialize() и acc_close()).
   Modify routine

 21.02.2011      д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   19
                               hahanova@mail.ru
Си подпрограмма для поиска полных
иерархических имен портов
    #include “acc_user.h”
     int get_ports()
     {      handle mod, port;
            int input_ctr = 0;    int output_ctr = 0; int inout_ctr = 0;
      acc_initialize();
      mod = acc_handle_tfarg(1);
      port = acc_handle_port(mod,0);         /* получить первый порт модуля*/
      while (port!=null) /*цикл для всех портов*/
      {
        if (acc_fetch_direction(port) == accInput) /*Входной порт*/
             { io_printf(“Input Port %s n”, acc_fetch_fullname(port)); input_ctr++; }
       else if (acc_fetch_direction(port) == accOutput) /*Выходной порт*/
             { io_printf(“Output Port %s n”, acc_fetch_fullname(port)); output_ctr++; }
       else if (acc_fetch_direction(port) == accInout) /*Двунаправленный порт*/
             {io_printf(“Inout Port %s n”, acc_fetch_fullname(port)); inout_ctr++; }
             port = acc_next_port(mod, port); /*перейти к следующему порту*/
        }
      io_printf(“Input Ports = %d Output Ports = %d, Inout ports = %dnn”,
                                              input_ctr, output_ctr, inout_ctr);
       acc_close();
     return 0;}
    21.02.2011              д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:                   20
                                          hahanova@mail.ru
Использование системной задачи
 module top;
      wire OUT;
      reg I0, I1, S;
  mux2_to_1 my_mux(OUT, I0,I1, S); /*Копия модуля mux2_to_1*/
  initial
  begin
        /*Вызов задачи $get_ports, генерирующей список портов*/
        $get_ports("top.my_mux");
  end
  endmodule
       // Результат моделирования:
  # Output Port top2.my_mux.out
  # Input Port top2.my_mux.i0
  # Input Port top2.my_mux.i1
  # Input Port top2.my_mux.s
  # Input Ports = 3 Output Ports = 1, Inout ports = 0

 21.02.2011         д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   21
                                  hahanova@mail.ru
Мониторинг значений сигналов.1
#include “acc_user.h”

  char convert_to_char();
  int display_net();
  int my_monitor()
  {     handle net;
        char *netname; /* указатель для сохранения имени линии*/
        char *malloc();

  acc_initialize();/*инициализация среды*/
  net = acc_handle_tfarg(1);/*получение идентификатора
  наблюдаемой линии*/

  /*Следующие операторы ищут и сохраняют иерархическое имя
  линии*/
  netname = malloc(strlen(acc_fetch_fullname(net)));
  strcopy(netname, acc_fetch_fullname(net));
 21.02.2011         д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   22
                                  hahanova@mail.ru
Мониторинг значений сигналов. 2
/*Вызов подпрограммы VCL для добавления сигнала в список
мониторинга. Передается четыре аргумента: 1-й: handle объекта
(net); 2-й: указатель на Си-подпрограмму, вызываемую при
изменении значения объекта(display_net); 3-й: Строка передается в
пользовательскую подпрограмму Си; 4-й: предопределенный VCL
флаг: vc1_verilog_logic*/
      acc_vcl_add(net, display_net, netname, vcl_verilog_logic);
      acc_close();
      return 0;}
/*Пользовательская подпрограмма. Вызывается при каждом
изменении наблюдаемых сигналов*/
display_net(vc_record)
      p_vc_record vc_record; /*Структура p_vc_record
      предопределена в пакете acc_user.h*/
{ *Выводится время, имя и новое значение изменившейся линии*/
io_printf("%d New value of net %s is %c n", vc_record -> vc_lowtime,
vc_record -> user_data, convert_to_char(vc_record-
>out_value.logic_value)); }

21.02.2011        д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:    23
                                hahanova@mail.ru
Мониторинг значений сигналов. 3

    /*Смешанные подпограммы для преобразования константы
    предопределенного символа в ASCII символ*/
    char convert_to_char(logic_val)
    char logic_val;
    {
         char temp;
         switch(logic_val)
         {
         /*vc10, vc11, vc1x предопределены в пакете acc_user.h*/
         case vcl0: temp = '0'; break;
         case vcl1: temp = '1'; break;
         case vclX: temp = 'X'; break;
         case vclZ: temp = 'Z'; break;
         }
    return(temp);
    }

    21.02.2011       д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   24
                                   hahanova@mail.ru
Использование задачи мониторинга
 module top;
      wire OUT;
      reg I0, I1, S;
  mux2_to_1 my_mux(OUT, I0, I1, S); //Копия модуля mux2_to_1
  initial     // Добавление сигнала в список мониторинга
        begin
              $my_monitor("top.my_mux.sbar");
              $my_monitor("top.my_mux.y1");
        end
  initial begin
               I0 = 1'b0; I1 = 1'b1; S = 1'b0;
               #5 I0 = 1'b1; I1 = 1'b1; S = 1'b1;
               #5 I0 = 1'b0; I1 = 1'b1; S = 1'bx;
               #5 I0 = 1'b1; I1 = 1'b1; S = 1'b1;
        end
  endmodule
  21.02.2011         д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   25
                                   hahanova@mail.ru
Обслуживающие подпрограммы (utility routine)

 #include "veriuser.h"
 Задачи, решаемые с применением обслуживающих
  подпрограмм:
    Получение информации о вызванных системных задачах,
     списке аргументов, считывание и изменение значения
     аргумента.
    Наблюдение за изменениями значений аргументов
    Выполнение вспомогательных задач, таких как сохранение
     рабочей области, сохранения указателя на задачу.
    Выполнение сложных вычислений
    Вывод сообщения
    Получение информации о времени моделирования и очереди
     событий.
    Остановка, завершение, сохранение и восстановление
     процесса моделирования.

  21.02.2011     д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   26
                               hahanova@mail.ru
Обслуживающая PLI-подпрограмма. 1

                    Спецификация для $my_stop_finish

    Аргументы
                                                       Действие
1-й         2-й
                        Остановка моделирования. Вывод сообщения и модельного
0             нет
                        времени
                        Завершение моделирования. Вывод сообщения и модельного
1             нет
                        времени
                        Остановка моделирования. Вывод сообщения, имя модуля из
0      любое значение
                        которого был произведен вызов задачи и модельного времени

                        Завершение моделирования. Вывод сообщения, имя модуля из
1      любое значение
                        которого был произведен вызов задачи и модельного времени



 21.02.2011             д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:        27
                                      hahanova@mail.ru
Обслуживающая PLI-подпрограмма. 2
    int my_stop_finish()
     {
     if(tf_nump() == 1)
     { if (tf_getp(1)==0)
       {      io_printf("Mymessage: Simulation stopped at time %dn", tf_gettime());
              tf_dostop();         /*Остановка моделирования*/
       }
       else if (tf_getp(1) == 1) /*Если аргумент = 1, моделирование завершается*/
       {      io_printf("Mymessage: Simulation finished at time &dn", tf_gettime());
              tf_dofinish();                  /*Завершение моделирования*/
       }
       else tf_warning("Bad arguments to $my_stop_finish at time %dn", tf_gettime());
       }
     else if (tf_nump() == 2)
       { if (tf_getp(1) == 0)
         { io_printf("Mymessage: Simulation stopped at time %d in instance %s n",
                         tf_gettime(), tf_mipname()); tf_dostop(); }
         else if (tf_getp(1) == 1)
         { io_printf("Mymessage: Simulation finished at time %d in instance %s n",
                         tf_gettime(), tf_mipname()); tf_dofinish();
         }
        else tf_warning("Bad arguments to $my_stop_finish at time %dn", tf_gettime());
              }
      return 0;
     }
    21.02.2011            д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:               28
                                        hahanova@mail.ru
Обслуживающая PLI-подпрограмма. 3
    module top;                                      Результат моделирования
         wire OUT;
         reg I0, I1, S;
                                                      # Mymessage: Simulation
                                                         stopped at time 0
     mux2_to_1 my_mux(OUT, I0, I1, S);
                                                      # Mymessage: Simulation
     initial                                             stopped at time 5 in instance
     begin                                               top
       I0 = 1'b0; I1 = 1'b1; S = 1'b0;
       $my_stop_finish(0);                            # : Bad arguments to
       #5 I0 = 1'b1; I1 = 1'b1; S = 1'b1;                 $my_stop_finish at time 10
       $my_stop_finish(0,1);                              # : : $my_stop_finish
       #5 I0 = 1'b0; I1 = 1'b1; S = 1'bx;                 f:My_Designsnewmy_new/sr
       $my_stop_finish(2,1);                              c/top1.v(13)
       #5 I0 = 1'b1; I1 = 1'b1; S = 1'b1;
                                                      # Mymessage: Simulation
      $my_stop_finish(1,1);                              finished at time 15 in instance
     end                                                 top
     endmodule
    21.02.2011             д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:            29
                                         hahanova@mail.ru
Тест-вопросы
1. Какое модельное время затрачивается
   на выполнение функции?
2. Можно ли в функции использовать
   задержки, события и операторы
   управления временем.




 21.02.2011   д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   30
                            hahanova@mail.ru
Контрольные задания.1
1. Создать функцию, умножающую два 4-битовых числа и
   формирующую 32-битовый результат. Написать тестовый
   модуль для вызова функции и проверки результата ее работы.
2. Создать функцию, моделирующую восьмиоперационное АЛУ.
   Функция принимает 3-битовый код операции, два 4-разрядных
   операнда, а возвращает 5-битовый результат. Написать
   тестовый модуль для вызова функции и проверки результата ее
   работы.       OP             Функция
               3'b000    out = a
               3'b001    out = a + b
               3'b010    out = a - b
               3'b011    out = a / b
               3'b100    out = a % b
               3'b101    out = a << b
               3'b110    out = a >> b
               3'b111    out = (a > b), сравнение амплитуд
  21.02.2011       д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   31
                                 hahanova@mail.ru
Контрольные задания.2
1. Создать задачу, выполняющую проверку на четность 16-битового
   числа. Результат – 31-битовое число. На него поступает значение после
   трех положительных фронтов синхронизации. Использовать оператор
   repeat.
2. Написать задачу, вычисляющую сумму квадратов входных значений A и
   B. Входные значения имеют тип real. Задача возвращает значение
   через вещественную переменную sum_of_squares.
     Разработать testbench для тестирования работы задачи из п. а).
       Тестовые значения формировать с помощьюсистемной функции
       $random. Результаты моделирования выводить в текстовый файл в
       формате:
     A = значение B = значение sum_of_squares = значение.
     Например,
     A = 3 B = 2 sum_of_squares = 13.
 Написать задачу, генерирующую импульсы синхросигнала syn_clk
   длиной 1 ед. времени с периодом в 20 ед. времени. Когда сигнал reset =
   1, то задача переключает syn_clk в 0 и возвращает управление.


   21.02.2011         д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   32
                                    hahanova@mail.ru
Контрольные вопросы и задания.3
1. Для каких задач используются подрограммы
   доступа?
2. Какие задачи решают обслуживающие
   подрограммы?
3. Создать пользовательскую системную задачу
   $get_in_port, которая формирует сообщение о
   входных портах заданного модуля.
   Иерархическое имя модуля будет входным
   параметром задачи.



 21.02.2011   д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:   33
                            hahanova@mail.ru
Контрольные вопросы и задания.4
1.      Написать пользовательскую системную задачу
        $count_and_gates, которая подсчитывает число
        стандартных примитивов and в модуле. Для
        тестирования использовать следующую модель
        мультиплексора:
            •     module mux_4_to_1 (Out, In0, In1, In2, In3, Sel1, Sel0);
                     output Out;
                     input In0, In1, In2, In3, Sel1, Sel0;
                     wire NotSel0, NotSel1;
                     wire Y0, Y1, Y2, Y3;
                   and (Y1, In1, NotSel1, NotSel0);
                   not (NotSel0, Sel0);
                   and (Y3, In3, Sel1, Sel0);
                   or (Out, Y0, Y1, Y2, Y3);
                   and (Y0, In0, NotSel1, NotSel0);
                   not (NotSel1, Sel1);
                   and (Y2, In2, Sel1, NotSel0);
                  endmodule
     21.02.2011             д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail:     34
                                          hahanova@mail.ru

апкс 2011 05_verilog

  • 1.
    VERILOG 5. Подпрограммы. Библиотека PLI Автоматизация проектирования компьютерных систем д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ 21.02.2011 e-mail: hahanova@mail.ru 1
  • 2.
    Цель лекции исодержание  Цель – изучить методы построения и механизм использования подпрограмм в Verilog. Узнать возможности расширения функций программ моделирования с благодаря интерфейсу PLI  План  Подпрограммы: Task и Function  Библиотека PLI 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 2 hahanova@mail.ru
  • 3.
    1 Task иFunction: Старый стиль //Синтаксис функции //Синтаксис задачи function [automatic] task [ automatic ] identifier; [signed] [range_or_type] parameter_declaration; identifier; input_declaration; parameter_declaration; output_declaration; input_declaration; inout_declaration; register_declaration; register_declaration; event_declaration; statement; statement; endfunction endtask 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 3 hahanova@mail.ru
  • 4.
    2 Task иFunction: Новый стиль //Синтаксис функции //Синтаксис задачи function [automatic] [signed] task [ automatic ] [range_or_type] identifier task_identifier (function_port_list ); (task_port_list ) ; block_item_declaration { { block_item_declaration } block_item_declaration } statement function_statement endtask endfunction Пример Пример function [7:0] getbyte task my_task (input a, b, (input [15:0] address); inout c, output d, e); 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 4 hahanova@mail.ru
  • 5.
    Свойства функций изадач Функция Задача 1 Может вызывать другую Может вызывать как задачи, функцию, задачу нет так и функции 2 Всегда выполняется На выполнение может мгновенно постребоваться ненулевой промежуток времени 3 Не может содержать Может содержать временные временные или событийные или событийные операторы операторы управления управления 4 Имеет только входные Может иметь аргументы типа аргументы (input) input, output и inout 5 Всегда возвращ ает Не возвращ ает значение, но единственное значение может передавать через аргументы типа output и inout 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 5 hahanova@mail.ru
  • 6.
    Пример использования функции function real multiply (input a, b); real a, b; multiply = ((1.2 * a) * (b * 0.17)) * 5.1; endfunction //... real a; initial begin a = multiply(1.5, a); end 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 6 hahanova@mail.ru
  • 7.
    Функции для вычисленияфакториала module tryfact; //использование функции // описание функции integer result, n; function [31:0] factorial; initial input [3:0] operand; begin reg [3:0] i; for (n = 0; n <= 7; n = n+1) begin begin factorial = 1; result = factorial(n); for (i = 2; i <= operand; i = i $display(“%0d + 1) factorial=%0d”, n, result); factorial = i * factorial; end end end endfunction endmodule 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 7 hahanova@mail.ru
  • 8.
    Создание и использованиезадач task first_task; integer x; parameter size=4; reg a, b, y; // Входной аргумент reg [3:0] z; input a; integer a; reg [7:0] w; // Двунаправленный аргумент inout [size-1:0] b; ... // Выходной аргумент first_task(x, z, y); output c; first_task(x, w[7:4], w[1]); // Внутренняя переменная first_task(1,{a,b,w[3], x[0]}, y); reg [size-1:0] d; // Декларация события event e; // Использования именного begin события d = b; c = |d; // из задачи b = ~b; always @(first_task.e) if (!a) -> e; end count= count+1; endtask 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 8 hahanova@mail.ru
  • 9.
    Автоматические функции изадачи  module tryfact; // описание функции function automatic [31:0] factorial; В автоматических задач input [3:0] operand; запрещено использование: reg [3:0] i; begin 1. неблокирующих factorial = 1; операторов; for (i = 2; i <= operand; i = i + 1) 2. непрерывных процедурных factorial = i * factorial; end операторов assign и force; endfunction 3. внутриоператорного контроля;  //использование функции 4. системной задачи $monitor. integer result; integer n; initial begin for (n = 0; n <= 7; n = n+1) begin result = factorial(n); $display(“%0d factorial=%0d”, n, result); end end endmodule 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 9 hahanova@mail.ru
  • 10.
    Programming Language Interface(PLI) Verilog Си Системные Задачи 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 10 hahanova@mail.ru
  • 11.
    Интерфейс PLI используетсядля:  Создания дополнительных системных задач и функций: задач мониторинга, генерации тестов, отладки фрагментов программы;  Построения различных программных приложений: трансляторы, анализ временных параметров;  Получения информации о проекте: иерархия, связи;  Создание специальных и пользовательских форм управления выводом информации;  Создания подпрограмм, формирующих тестовые последовательности;  Создания любого основанного на Verilog программного приложения. 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 11 hahanova@mail.ru
  • 12.
    Programming Language Interface(PLI) Verilog-код + Пользовательские системные задачи Подключение задач Verilog-компилятор Таблица пользовательских системных задач Доступ к внутренним Внутреннее структурам представление проекта п одп ро гр амм PL I Си-подпрограммы Пользовательские (Структуры данных) Би бл иот ека Управление моделированием Моделирование Вывод результатов Результаты тестирования тестирования 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 12 hahanova@mail.ru
  • 13.
    Разработка системной задачина Си  #include “veriuser.h” Использование #include “aldecpli.h” module start_PLI; #include <windows.h> initial int welcome_task() begin { io_printf(“You are welcomet!n”); $welcome_task; return 0; end } endmodule extern "C" __declspec(dllexport) s_tfcell veriusertfs[] = { {usertask, 0, 0, 0, welcome_task, 0, “$welcome_task”}, {0} }; BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) { return TRUE; } д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 21.02.2011 13 hahanova@mail.ru
  • 14.
    Синтаксис массива veriusertfs s_tfcellveriusertfs[] = { {usertask | userfunction | userrealfunction, data; checktf; sizetf; calltf; misctf; ”$tfname”}, {0} }  checktf, sizetf, calltf и misctf - различные функции обратного вызова, описаны в стандарте Verilog IEEE Std 1364-1995  calltf - функция, которая выполняется при вызове системной функции или процедуры в Verilog-коде  “$tfname” – это имя системной функции или задачи в Verilog-коде, которое должно начинаться с символа доллара ($) 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 14 hahanova@mail.ru
  • 15.
    Пример массива veriusertfs s_tfcellveriusertfs[] = { {usertask, 0, 0, 0, welcome_task, 0, “$welcome_task”}, {userfunction, 0, 0, 0, function_call, 0, “$my_function”}, {0} // последний элемент должен быть 0 }; 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 15 hahanova@mail.ru
  • 16.
    Копии дочерних модулей 2 ... 1 n1 21.02.2011 Копии примитивов 2 ... 1 n2 Терминалы примитивов ... 2 1 n3 module <имя модуля > hahanova@mail.ru Множества: переменные классов, цепи и регистры, ... параметры д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: Внутренний формат данных Порты модуля 2 ... 1 nm 16
  • 17.
    Внутреннее представление данных Мультиплексор 2-в-1 module mux2_to_1 i0 y1 n1 a1 primitive terminal net port Копии примитивов sbar not n1 s s s o1 out terminal net y2 sbar a2 primitive terminal i1 and a1 terminal net port Терминалы примитивов Порты модуля i0 i0 Цепи module mux2_to_1 terminal (output out, net input i0, i1, s); primitive terminal y1 wire sbar, y1, y2; and a2 net port terminal i1 i1 not n1(sbar, s); terminal and a1(y1, i0, sbar), net y2 a2(y2, i1, s); primitive terminal or o1(out, y1, y2); or o1 net port endmodule terminal out out 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: terminal 17 hahanova@mail.ru
  • 18.
    Подпрограммы доступа иобслуживания Acc PL I-подпрограмм ы T f PL I-подпрограм мы Внутреннее Использующая Пользовательское представление представление проекта PLI -библиотеку + проекта тестовые пользовательская (Структуры данных) последовательности Си-подпрограмма 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 18 hahanova@mail.ru
  • 19.
    Подпрограммы доступа (accessroutine)  acc_user.h  Абстрактный идентификатор (handle)  Существует пять типов подпрограмм доступа:  Handle routine ( acc_handle_)  Next routine (acc_next_ )  Value Change Link (VCL) routine (acc_vcl_)  Fetch routine (acc_fetch_.)  Utility access routine (acc_initialize() и acc_close()).  Modify routine 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 19 hahanova@mail.ru
  • 20.
    Си подпрограмма дляпоиска полных иерархических имен портов  #include “acc_user.h” int get_ports() { handle mod, port; int input_ctr = 0; int output_ctr = 0; int inout_ctr = 0; acc_initialize(); mod = acc_handle_tfarg(1); port = acc_handle_port(mod,0); /* получить первый порт модуля*/ while (port!=null) /*цикл для всех портов*/ { if (acc_fetch_direction(port) == accInput) /*Входной порт*/ { io_printf(“Input Port %s n”, acc_fetch_fullname(port)); input_ctr++; } else if (acc_fetch_direction(port) == accOutput) /*Выходной порт*/ { io_printf(“Output Port %s n”, acc_fetch_fullname(port)); output_ctr++; } else if (acc_fetch_direction(port) == accInout) /*Двунаправленный порт*/ {io_printf(“Inout Port %s n”, acc_fetch_fullname(port)); inout_ctr++; } port = acc_next_port(mod, port); /*перейти к следующему порту*/ } io_printf(“Input Ports = %d Output Ports = %d, Inout ports = %dnn”, input_ctr, output_ctr, inout_ctr); acc_close(); return 0;} 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 20 hahanova@mail.ru
  • 21.
    Использование системной задачи module top; wire OUT; reg I0, I1, S; mux2_to_1 my_mux(OUT, I0,I1, S); /*Копия модуля mux2_to_1*/ initial begin /*Вызов задачи $get_ports, генерирующей список портов*/ $get_ports("top.my_mux"); end endmodule // Результат моделирования: # Output Port top2.my_mux.out # Input Port top2.my_mux.i0 # Input Port top2.my_mux.i1 # Input Port top2.my_mux.s # Input Ports = 3 Output Ports = 1, Inout ports = 0 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 21 hahanova@mail.ru
  • 22.
    Мониторинг значений сигналов.1 #include“acc_user.h” char convert_to_char(); int display_net(); int my_monitor() { handle net; char *netname; /* указатель для сохранения имени линии*/ char *malloc(); acc_initialize();/*инициализация среды*/ net = acc_handle_tfarg(1);/*получение идентификатора наблюдаемой линии*/ /*Следующие операторы ищут и сохраняют иерархическое имя линии*/ netname = malloc(strlen(acc_fetch_fullname(net))); strcopy(netname, acc_fetch_fullname(net)); 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 22 hahanova@mail.ru
  • 23.
    Мониторинг значений сигналов.2 /*Вызов подпрограммы VCL для добавления сигнала в список мониторинга. Передается четыре аргумента: 1-й: handle объекта (net); 2-й: указатель на Си-подпрограмму, вызываемую при изменении значения объекта(display_net); 3-й: Строка передается в пользовательскую подпрограмму Си; 4-й: предопределенный VCL флаг: vc1_verilog_logic*/ acc_vcl_add(net, display_net, netname, vcl_verilog_logic); acc_close(); return 0;} /*Пользовательская подпрограмма. Вызывается при каждом изменении наблюдаемых сигналов*/ display_net(vc_record) p_vc_record vc_record; /*Структура p_vc_record предопределена в пакете acc_user.h*/ { *Выводится время, имя и новое значение изменившейся линии*/ io_printf("%d New value of net %s is %c n", vc_record -> vc_lowtime, vc_record -> user_data, convert_to_char(vc_record- >out_value.logic_value)); } 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 23 hahanova@mail.ru
  • 24.
    Мониторинг значений сигналов.3  /*Смешанные подпограммы для преобразования константы предопределенного символа в ASCII символ*/ char convert_to_char(logic_val) char logic_val; { char temp; switch(logic_val) { /*vc10, vc11, vc1x предопределены в пакете acc_user.h*/ case vcl0: temp = '0'; break; case vcl1: temp = '1'; break; case vclX: temp = 'X'; break; case vclZ: temp = 'Z'; break; } return(temp); } 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 24 hahanova@mail.ru
  • 25.
    Использование задачи мониторинга module top; wire OUT; reg I0, I1, S; mux2_to_1 my_mux(OUT, I0, I1, S); //Копия модуля mux2_to_1 initial // Добавление сигнала в список мониторинга begin $my_monitor("top.my_mux.sbar"); $my_monitor("top.my_mux.y1"); end initial begin I0 = 1'b0; I1 = 1'b1; S = 1'b0; #5 I0 = 1'b1; I1 = 1'b1; S = 1'b1; #5 I0 = 1'b0; I1 = 1'b1; S = 1'bx; #5 I0 = 1'b1; I1 = 1'b1; S = 1'b1; end endmodule 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 25 hahanova@mail.ru
  • 26.
    Обслуживающие подпрограммы (utilityroutine)  #include "veriuser.h"  Задачи, решаемые с применением обслуживающих подпрограмм:  Получение информации о вызванных системных задачах, списке аргументов, считывание и изменение значения аргумента.  Наблюдение за изменениями значений аргументов  Выполнение вспомогательных задач, таких как сохранение рабочей области, сохранения указателя на задачу.  Выполнение сложных вычислений  Вывод сообщения  Получение информации о времени моделирования и очереди событий.  Остановка, завершение, сохранение и восстановление процесса моделирования. 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 26 hahanova@mail.ru
  • 27.
    Обслуживающая PLI-подпрограмма. 1 Спецификация для $my_stop_finish Аргументы Действие 1-й 2-й Остановка моделирования. Вывод сообщения и модельного 0 нет времени Завершение моделирования. Вывод сообщения и модельного 1 нет времени Остановка моделирования. Вывод сообщения, имя модуля из 0 любое значение которого был произведен вызов задачи и модельного времени Завершение моделирования. Вывод сообщения, имя модуля из 1 любое значение которого был произведен вызов задачи и модельного времени 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 27 hahanova@mail.ru
  • 28.
    Обслуживающая PLI-подпрограмма. 2  int my_stop_finish() { if(tf_nump() == 1) { if (tf_getp(1)==0) { io_printf("Mymessage: Simulation stopped at time %dn", tf_gettime()); tf_dostop(); /*Остановка моделирования*/ } else if (tf_getp(1) == 1) /*Если аргумент = 1, моделирование завершается*/ { io_printf("Mymessage: Simulation finished at time &dn", tf_gettime()); tf_dofinish(); /*Завершение моделирования*/ } else tf_warning("Bad arguments to $my_stop_finish at time %dn", tf_gettime()); } else if (tf_nump() == 2) { if (tf_getp(1) == 0) { io_printf("Mymessage: Simulation stopped at time %d in instance %s n", tf_gettime(), tf_mipname()); tf_dostop(); } else if (tf_getp(1) == 1) { io_printf("Mymessage: Simulation finished at time %d in instance %s n", tf_gettime(), tf_mipname()); tf_dofinish(); } else tf_warning("Bad arguments to $my_stop_finish at time %dn", tf_gettime()); } return 0; } 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 28 hahanova@mail.ru
  • 29.
    Обслуживающая PLI-подпрограмма. 3  module top; Результат моделирования wire OUT; reg I0, I1, S; # Mymessage: Simulation stopped at time 0 mux2_to_1 my_mux(OUT, I0, I1, S); # Mymessage: Simulation initial stopped at time 5 in instance begin top I0 = 1'b0; I1 = 1'b1; S = 1'b0; $my_stop_finish(0); # : Bad arguments to #5 I0 = 1'b1; I1 = 1'b1; S = 1'b1; $my_stop_finish at time 10 $my_stop_finish(0,1); # : : $my_stop_finish #5 I0 = 1'b0; I1 = 1'b1; S = 1'bx; f:My_Designsnewmy_new/sr $my_stop_finish(2,1); c/top1.v(13) #5 I0 = 1'b1; I1 = 1'b1; S = 1'b1; # Mymessage: Simulation $my_stop_finish(1,1); finished at time 15 in instance end top endmodule 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 29 hahanova@mail.ru
  • 30.
    Тест-вопросы 1. Какое модельноевремя затрачивается на выполнение функции? 2. Можно ли в функции использовать задержки, события и операторы управления временем. 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 30 hahanova@mail.ru
  • 31.
    Контрольные задания.1 1. Создатьфункцию, умножающую два 4-битовых числа и формирующую 32-битовый результат. Написать тестовый модуль для вызова функции и проверки результата ее работы. 2. Создать функцию, моделирующую восьмиоперационное АЛУ. Функция принимает 3-битовый код операции, два 4-разрядных операнда, а возвращает 5-битовый результат. Написать тестовый модуль для вызова функции и проверки результата ее работы. OP Функция 3'b000 out = a 3'b001 out = a + b 3'b010 out = a - b 3'b011 out = a / b 3'b100 out = a % b 3'b101 out = a << b 3'b110 out = a >> b 3'b111 out = (a > b), сравнение амплитуд 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 31 hahanova@mail.ru
  • 32.
    Контрольные задания.2 1. Создатьзадачу, выполняющую проверку на четность 16-битового числа. Результат – 31-битовое число. На него поступает значение после трех положительных фронтов синхронизации. Использовать оператор repeat. 2. Написать задачу, вычисляющую сумму квадратов входных значений A и B. Входные значения имеют тип real. Задача возвращает значение через вещественную переменную sum_of_squares.  Разработать testbench для тестирования работы задачи из п. а). Тестовые значения формировать с помощьюсистемной функции $random. Результаты моделирования выводить в текстовый файл в формате:  A = значение B = значение sum_of_squares = значение.  Например,  A = 3 B = 2 sum_of_squares = 13.  Написать задачу, генерирующую импульсы синхросигнала syn_clk длиной 1 ед. времени с периодом в 20 ед. времени. Когда сигнал reset = 1, то задача переключает syn_clk в 0 и возвращает управление. 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 32 hahanova@mail.ru
  • 33.
    Контрольные вопросы изадания.3 1. Для каких задач используются подрограммы доступа? 2. Какие задачи решают обслуживающие подрограммы? 3. Создать пользовательскую системную задачу $get_in_port, которая формирует сообщение о входных портах заданного модуля. Иерархическое имя модуля будет входным параметром задачи. 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 33 hahanova@mail.ru
  • 34.
    Контрольные вопросы изадания.4 1. Написать пользовательскую системную задачу $count_and_gates, которая подсчитывает число стандартных примитивов and в модуле. Для тестирования использовать следующую модель мультиплексора: • module mux_4_to_1 (Out, In0, In1, In2, In3, Sel1, Sel0); output Out; input In0, In1, In2, In3, Sel1, Sel0; wire NotSel0, NotSel1; wire Y0, Y1, Y2, Y3; and (Y1, In1, NotSel1, NotSel0); not (NotSel0, Sel0); and (Y3, In3, Sel1, Sel0); or (Out, Y0, Y1, Y2, Y3); and (Y0, In0, NotSel1, NotSel0); not (NotSel1, Sel1); and (Y2, In2, Sel1, NotSel0); endmodule 21.02.2011 д.т.н. Хаханова И.В, каф.АПВТ, ХНУРЭ e-mail: 34 hahanova@mail.ru