Класс Driver
Класс Driver описан в файле Driver.sv. Основным методом этого класса является метод start(), который вызывается в методе Environment::start(). Этот метод запускает генерацию случайных тестовых воздействий. С помощью вызова встроенной в каждой класс виртуальной функции randomize() переменные класса Transaction, объявленные как rand или randc, заполняются случайными значениями:
- task start();
- Transaction trans = new trans_e;
- repeat(`NUM_OF_TRANS) begin
- if ( trans.randomize) begin
- trans.display_inputs();
- drive(trans);
- cov.sample(trans);
- end else begin
- $display (" %0d Driver : **ERROR: randomization failed",$time);
- trans.errors++;
- end
- end
- @(posedge input_intf.clock);
- trans.stop = 1;
- endtask : start
Если при генерации случайных значений произошла ошибка, то выводится соответствующее сообщение и к вектору ошибок прибавляется 1. Если все нормально, то сгенерированная транзакция выводится на экран:
- trans.display_inputs();
Далее вызывается метод drive:
- drive(trans);
, который выдает сгенерированную транзакцию в соответствии с протоколом передачи:
- @(posedge input_intf.clock);
- input_intf.cb.a <= trans.a;
- input_intf.cb.b <= trans.b;
- input_intf.cb.c <= trans.c;
- input_intf.cb.d <= trans.d;
В нашем случае протокол передачи очень прост и все сгенерированные значения выдаются в одном такте, но при желании, изменив метод drive(), можно реализовать более сложные протоколы передачи.
После того, как мы послали транзакцию, вызывается метод Coverage::sample(), который собирает информацию о посланных транзакциях.
Драйвер повторяет эту последовательность действий число раз, которое задано константой NUM_OF_TRANS. Для удобства эта константа объявлена в файле Globals.sv:
- `define NUM_OF_TRANS 100
После завершения генерации всех транзакций драйвер устанавливает сигнал остановки генерации тестовых воздействий:
- trans.stop = 1;
Код класса Driver:
- `ifndef _DRIVER_
- `define _DRIVER_
- `include "Globals.sv"
- class Driver;
- virtual input_interface.input_prt input_intf;
- Transaction trans_e;
- Coverage cov = new();
- // Constructor
- function new(virtual input_interface.input_prt input_intf_new);
- this.input_intf = input_intf_new;
- trans_e = new();
- endfunction : new
- task drive(Transaction trans);
- @(posedge input_intf.clock);
- input_intf.cb.a <= trans.a;
- input_intf.cb.b <= trans.b;
- input_intf.cb.c <= trans.c;
- input_intf.cb.d <= trans.d;
- endtask : drive
- // Start method
- task start();
- Transaction trans = new trans_e;
- repeat(`NUM_OF_TRANS) begin
- if (trans.randomize) begin
- trans.display_inputs();
- drive(trans);
- cov.sample(trans);
- end else begin
- $display (" %0d Driver : **ERROR: randomization failed",$time);
- trans.errors++;
- end
- end
- @(posedge input_intf.clock);
- trans.stop = 1;
- endtask : start
- endclass
- `endif
Изменениям в этом классе при конфигурировании подвергается только метод drive().