Trung tâm đào tạo thiết kế vi mạch Semicon


  • ĐĂNG KÝ TÀI KHOẢN ĐỂ TRUY CẬP NHIỀU TÀI LIỆU HƠN!
  • Create an account
    *
    *
    *
    *
    *
    Fields marked with an asterisk (*) are required.
semicon_lab.jpg

Structs And Units Part-III

E-mail Print PDF
Introduction to Units

e Units are the basic structural blocks for creating verification modules (verification cores) that can easily be integrated together to test larger and larger portions of an HDL design as it develops. 

Units, like structs, are compound data types that contain data fields, procedural methods, and other members. Unlike structs, however, a unit instance is bound to a particular component in the DUT (an HDL path). Furthermore, each unit instance has a unique and constant place (an e path) in the run-time data structure of an e program. Both the e path and the complete HDL path associated with a unit instance are determined before the run begins.

To understand better about the applications of units, look at the below example. Which is a switch fabric with 6 ports. We can have one unit, which implements the driver part of the functionality of the testbench, and this driver can be instantiated 6 times with each of them have unique HDL paths.

The basic run-time data structure of an e program is a tree of unit instances whose root is sys, the only predefined unit in e. Additionally there are structs that are dynamically bound to unit instances. The run-time data structure of a typical e program using units is similar to that of the switch_fabric program shown in figure below.

Each unit instance in the unit instance tree of the switch_fabric matches a module instance in the Verilog DUT, as shown in figure above. The one-to-one correspondence in this particular design between e unit instances and DUT module instances is not required for all designs. In more complex designs, there may be several levels of DUT hierarchy corresponding to a single level of hierarchy in the tree of e unit instances.
Binding an e unit instance to a particular component in the DUT hierarchy allows you to reference signals within that DUT component using relative HDL path names. This ability to use relative path names to reference HDL objects allows you to freely change the combination of verification cores as the HDL design and the verification environment evolve. Regardless of where the DUT component is instantiated in the final integration, the HDL path names in the verification environment remain valid.

Defining Units And Fields

Units are the basic structural blocks for creating verification modules (verification cores) that can easily be integrated together to test larger designs. Units are a special kind of struct, with two important properties:

  • Units or unit instances can be bound to a particular component in the DUT (an HDL path).
  • Each unit instance has a unique and constant parent unit (an e path). Unit instances create a static tree, determined during pre-run generation, in the runtime data structure of an e program.

Because the base unit type (any_unit) is derived from the base struct type (any_struct), user-defined units have the same predefined methods. In addition, units can have verilog members and have several specialized predefined methods.
A unit type can be extended or used as the basis for creating unit subtypes. Extended unit types or unit subtypes inherit the base type's members and contain additional members.
Syntax :
 unit unit-type [like base-unit-type] { [unit-member; ...]}

Parameter

Description

unit-type

The type of the new unit.

base-unit-type

The type of the unit from which the new unit inherits its members.

unit-member

Like structs, units can have the following types of members

 .

-data fields for storing data

.

-methods for procedures

.

-events for defining temporal triggers

.

-coverage groups for defining coverage points

.

-when, for specifying inheritance subtypes

.

-declarative constraints for describing relations between data fields

-on, for specifying actions to perform upon event occurrences

.

-expect, for specifying temporal behavior rules

The definition of a unit can be empty, containing no members.

Example

  1 module switch_fabric(

  2   clk, reset, data_in0, data_in1, data_in2,

  3   data_in3, data_in4, data_in5, data_in_valid0,

  4   data_in_valid1, data_in_valid2, data_in_valid3,

  5   data_in_valid4, data_in_valid5, data_out0,

  6   data_out1, data_out2, data_out3, data_out4,

  7   data_out5, data_out_ack0, data_out_ack1,

  8   data_out_ack2, data_out_ack3, data_out_ack4,

  9   data_out_ack5

 10 );

 11

 12 input           clk, reset;

 13 input  [7:0]    data_in0, data_in1, data_in2, data_in3;

 14 input  [7:0]    data_in4, data_in5;

 15 input           data_in_valid0, data_in_valid1, data_in_valid2;

 16 input  [7:0]    data_in_valid3, data_in_valid4, data_in_valid5;

 17 output [7:0]    data_out0, data_out1, data_out2, data_out3;

 18 output [7:0]    data_out4, data_out5;

 19 output          data_out_ack0, data_out_ack1, data_out_ack2;

 20 output [7:0]    data_out_ack3, data_out_ack4, data_out_ack5;

 21

 22 switch port_0 ( .clk(clk), .reset(reset), .data_in(data_in0),

 23   .data_in_valid(data_in_valid0), .data_out(data_out0),

 24   .data_out_ack(data_out_ack0));

 25

 26 switch port_1 ( .clk(clk), .reset(reset), .data_in(data_in1),

 27   .data_in_valid(data_in_valid1), .data_out(data_out1),

 28   .data_out_ack(data_out_ack1));

 29

 30 switch port_2 ( .clk(clk), .reset(reset), .data_in(data_in2),

 31   .data_in_valid(data_in_valid2), .data_out(data_out2), .

 32   data_out_ack(data_out_ack2));

 33

 34 switch port_3 ( .clk(clk), .reset(reset), .data_in(data_in3),

 35   .data_in_valid(data_in_valid3), .data_out(data_out3),

 36   .data_out_ack(data_out_ack3));

 37

 38 switch port_4 ( .clk(clk), .reset(reset), .data_in(data_in4),

 39   .data_in_valid(data_in_valid4), .data_out(data_out4),

 40   .data_out_ack(data_out_ack4));

 41

 42 switch port_5 ( .clk(clk), .reset(reset), .data_in(data_in5),

 43   .data_in_valid(data_in_valid5), .data_out(data_out5),

 44   .data_out_ack(data_out_ack5));

 45

 46 endmodule

 47

 48 module switch (

 49   clk,

 50   reset,

 51   data_in,

 52   data_in_valid,

 53   data_out,

 54   data_out_ack

 55 );

 56

 57 input   clk;

 58 input   reset;

 59 input [7:0]  data_in;

 60 input   data_in_valid;

 61 output [7:0]  data_out;

 62 output  data_out_ack;

 63

 64 reg [7:0]  data_out;

 65 reg   data_out_ack;

 66

 67 always @ (posedge clk)

 68 if (reset) begin

 69    data_out <= 0;

 70    data_out_ack <= 0;

 71 end else if (data_in_valid) begin

 72    data_out <= data_in;

 73    data_out_ack <= 1;

 74 end else begin

 75    data_out <= 0;

 76    data_out_ack <= 0;

 77 end

 78

 79 endmodule

  1 `include "switch_fabric.v"

  2

  3 module unit_example();

  4

  5 reg  clk, reset;

  6 reg  [7:0] data_in0, data_in1, data_in2, data_in3;

  7 reg  [7:0] data_in4, data_in5;

  8 reg  data_in_valid0, data_in_valid1, data_in_valid2;

  9 reg  data_in_valid3, data_in_valid4, data_in_valid5;

 10 wire [7:0] data_out0, data_out1, data_out2;

 11 wire [7:0] data_out3, data_out4, data_out5;

 12 wire data_out_ack0, data_out_ack1, data_out_ack2;

 13 wire data_out_ack3, data_out_ack4, data_out_ack5;

 14

 15 initial begin

 16   clk = 0;

 17   reset = 0;

 18    #10  reset = 1;

 19    #10  reset = 0;

 20   data_in0  = 0;      

 21   data_in1  = 0;

 22   data_in2  = 0;

 23   data_in3  = 0;

 24   data_in4  = 0;

 25   data_in5  = 0;

 26   data_in_valid0  = 0;

 27   data_in_valid1  = 0;

 28   data_in_valid2  = 0;

 29   data_in_valid3  = 0;

 30   data_in_valid4  = 0;

 31   data_in_valid5  = 0;

 32 end

 33

 34 always #2.5 clk = ~clk;

 35

 36 switch_fabric U_switch_fabric(

 37  .clk(clk), .reset(reset),

 38  .data_in0(data_in0), .data_in1(data_in1),

 39  .data_in2(data_in2), .data_in3(data_in3),

 40  .data_in4(data_in4), .data_in5(data_in5),

 41  .data_in_valid0(data_in_valid0), .data_in_valid1(data_in_valid1),

 42  .data_in_valid2(data_in_valid2), .data_in_valid3(data_in_valid3),

 43  .data_in_valid4(data_in_valid4), .data_in_valid5(data_in_valid5),

 44  .data_out0(data_out0), .data_out1(data_out1),

 45  .data_out2(data_out2), .data_out3(data_out3),

 46  .data_out4(data_out4), .data_out5(data_out5),

 47  .data_out_ack0(data_out_ack0), .data_out_ack1(data_out_ack1),

 48  .data_out_ack2(data_out_ack2), .data_out_ack3(data_out_ack3),

 49  .data_out_ack4(data_out_ack4), .data_out_ack5(data_out_ack5)

 50 );

 51

 52 endmodule

  1 <'

  2 unit switch_driver {

  3    inst_no : uint;

  4    event clk is rise('clk')@sim;

  5    // This is real dump driver!!!

  6    drive_data(data : byte)@clk is {

  7      wait cycle;

  8       outf ("Driving port : %d\n",inst_no);

  9       outf ("    in  data : %d\n",data);

 10      'data_in(inst_no)'       = data;

 11      'data_in_valid(inst_no)' = 1;

 12      wait cycle;

 13      'data_in(inst_no)'       = 0;

 14      'data_in_valid(inst_no)' = 0;

 15      wait cycle;

 16       outf ("    out data : %d\n",data);

 17      // Check if the data is coming out

 18      if ('data_out_ack(inst_no)' == 1) {

 19        check that data == 'data_out(inst_no)';

 20      } else {

 21        out ("There seems to be a error in DUT");

 22      };

 23    };

 24 };

 25

 26 unit switch_fabric {

 27   ports: list of switch_driver is instance;

 28   keep ports.size() == 6;

 29   // Assign path and unique number to each drive instance

 30   keep for each in ports { 

 31     .hdl_path() == "";

 32     .inst_no    == index;

 33   };

 34   // Have clock reference

 35   event clk is rise('clk')@sim;

 36   // Drive traffic into switch

 37   txgen()@clk is {

 38     wait [10]*cycle;

 39     ports[0].drive_data(10);

 40     ports[1].drive_data(11);

 41     ports[2].drive_data(12);

 42     ports[3].drive_data(13);

 43     ports[4].drive_data(14);

 44     ports[5].drive_data(15);

 45     wait [10]*cycle;

 46     stop_run();

 47   };

 48 };

 49

 50 extend sys {

 51   switch_fabric :  switch_fabric is instance;

 52   keep switch_fabric.hdl_path() == "unit_example";

 53   run() is also {

 54     start switch_fabric.txgen();

 55   };

 56 };

 57 '>

Driving port : 0

     in  data : 10

     out data : 10

 Driving port : 1

     in  data : 11

     out data : 11

 Driving port : 2

     in  data : 12

     out data : 12

 Driving port : 3

     in  data : 13

     out data : 13

 Driving port : 4

     in  data : 14

     out data : 14

 Driving port : 5

     in  data : 15

     out data : 15Bạn Có Đam Mê Với Vi Mạch hay Nhúng      -     Bạn Muốn Trau Dồi Thêm Kĩ Năng

Mong Muốn Có Thêm Cơ Hội Trong Công Việc

Và Trở Thành Một Người Có Giá Trị Hơn

Bạn Chưa Biết Phương Thức Nào Nhanh Chóng Để Đạt Được Chúng

Hãy Để Chúng Tôi Hỗ Trợ Cho Bạn. SEMICON  

 
Last Updated ( Wednesday, 01 June 2022 18:09 )  
Chat Zalo