1// Literatur: Vorlesungsunterlagen AMV von Rainer Findenig (FH-Hagenberg)
2
3// Coverage ... Grad der Abdeckung
4
5// Covergroups & Coverpoints
6 bit mysignal2;
7 int mysignal3;
8
9 covergroup mycg @(myEvent);
10 label1: coverpoint mysignal1;
11 label2: coverpoint mysignal2 {
12 bins enabled = { 1 };
13 bins disabled = { 0 };
14 }
15 label3: coverpoint mysignal3 {
16 bins firstSection = { 0, 1, 2 };
17 bins secondSection = { 10, 20, 30 };
18 bins other = default;
19 }
20 label4: coverpoint mysignal4 {
21 // bins die nicht betrachtet werden
22 ignore_bins zero = {0};
23 ...
24 // bins die nicht auftreten sollten/duerfen
25 illegal_bins invalid = default;
26 ...
27 // Transition Coverage:
28 // wie oft wurden bestimmte Uebergaenge ausgefuehrt
29 bins posEdge = ( 0 => 1 );
30 bins negEdge = ( 1 => 0 );
31 bins nothing = ( 0 => 0 ), ( 1 => 1 );
32 }
33 // Conditional Coverage: Bsp. keine Infos waehrend Reset
34 label5: coverpoint mysignal5 iff (!rst);
35 endgroup
36
37 mycg cg = new; // Objekt muss angelegt werden
38 mycg = new;
39
40
41// Cross Coverage
42 covergroup cg_opcodes @(posedge clk);
43 val_cmd: coverpoint cmd {
44 bins arith = { ... };
45 bins logic_ = { ... };
46 ...
47 }
48 val_reg: coverpoint regaddr;
49
50 cmd_with_reg: cross val_cmd, val_reg;
51
52 // Illegale Kombinationen markieren
53 // Bsp. logische Operationen duerfen Register 0 nicht nuetzen
54 cmd_with_reg: cross val_cmd, val_reg {
55 illegal_bins log_r0 = binsof(val_cmd.logi_) &&
56 binsof(val_reg) intersect {0};
57 }
58 endgroup
59
60
61// Bereiche Betrachten
62 int regaddr;
63 ...
64 covergroup somecg @(someevent);
65 reg_address: coverpoint regaddr {
66 bins zero = { 0 }; // 1 bin
67 bins local_ [] = { [1:7] }; // 7 bins: local_[1]..local_[7]
68 bins in = { [8:15] }; // 1 bin
69 bins out [] = { [16:24] }; // 8 bins
70
71 bins invalid = default;
72 }
73 endgroup
74
75
76// zufaellig generierte Werte
77 typedef enum { NOP=0, SLEEP=1,
78 LOADI=2, LOAD=3, STORE=4,
79 JUMP=8, JUMPC=10, JUMPZ=11,
80 MOVE=12,
81 AND=16, OR=17, XOR=18, NOT=19,
82 ADD=20, ADDC=21, SUB=22, SUBC=23,
83 COMP=24,
84 INC=26, DEC=27,
85 SHL=28, SHR=29, SHLC=30, SHRC=31 } aProl16Command;
86 typedef bit [REGISTER_WIDTH-1 : 0] aData_v;
87
88 class clProl16Opcode;
89 rand int ra;
90 rand int rb;
91 rand aProl16Command cmd;
92 rand aData_v data;
93 // rand ... zufaellige Werte
94 // randc ... zufaellige Werte, wiederholt Werte erst
95 // wenn bereits alle vorgekommen
96
97 constraint no_invalid_model_cmd {
98 cmd != NOP;
99 cmd != SLEEP;
100 cmd != LOAD;
101 cmd != STORE;
102 };
103
104 constraint only_valid_regA {
105 ra >= 0;
106 ra < REGISTER_NR;
107 };
108
109 constraint only_valid_regB {
110 rb >= 0;
111 rb < REGISTER_NR;
112 };
113
114 function void pre_randomize();
115 begin
116 $write("pre_randomize: Called for randomizing data.");
117 end
118 endfunction
119
120 function void post_randomize();
121 begin
122 $write("post_randomize: Called after randomizing data.");
123 end
124 endfunction
125 endclass
126
127 ...
128 opcode = new ();
129 void'(opcode.randomize());
130 // void damit keine Warnings ausgegeben werden
131
132 opcode.randomize() with {
133 cmd == NOP;
134 };
135
136
137
138// Constraints steuern
139 opcode.only_valid_regA::constraint_mode(0); // Constraint aus
140 opcode.only_valid_regA::constraint_mode(1); // Constraint ein
141 opcode::constraint_mode(0);
142
143 // Constraint Modus auslesen
144 int on = opcode.only_valid_regA::constraint_mode();
145
146 opcode.only_valid_regA::rand_mode(0); // Random-Funkt. aus
147 int on = opcode.only_valid_regA::rand_mode(); // auslesen
148
149
150// weitere Constraints
151 constraint array_size { data.size() <= 8; };
152 constraint id_not_null { id != 0; };
153 constraint c {
154 // inclusive
155 src_port inside { [8'h0:8'hA],8'h14,8'h18 };
156 // exclusive
157 ! (des_port inside { [8'h4:8'hFF] });
158 }
159
160 constraint len {
161 length dist {
162 [64 : 127 ] := 10, // mindestens 10x im Bereich 64-127
163 [128 : 511 ] := 10, // ...
164 [512 : 2048] := 10
165 };
166 }
167 constraint src {
168 src_port dist {
169 0 := 1,
170 1 := 1,
171 2 := 5,
172 4 := 1
173 };
174 }
175
176 // gewichtete Distribution:
177 constraint high_id {
178 id dist {
179 [0 : 0x400] :/ 25, // 25% im Bereich 0-0x400
180 [0x401 , 0x800] :/ 75 // 75% im Bereich 0x401-0x800
181 }
182 }
183 // bedingte Constraints
184 constraint my_const {
185 (id == 0) -> data.size() >= 2;
186 (id == 100) -> data.size() == 0;
187
188 if (size == RUNT) {
189 length >= 0;
190 length <= 63;
191 } else if (size == OVERSIZE) {
192 length >= 1501;
193 length <= 5000;
194 }
195 };
196
197 // Iterative Constraints
198 constraint frame_sizes {
199 data.size inside {[1:10]}; // im Bereich 1-10
200 foreach (data[i]) // bekommt jedes Element ein
201 data[i] == i; // eigenes Constraint
202 }
203
204 // Variable Ordnung der Constraints
205 constraint frame_sizes {
206 solve zero before data.size; // zuvor wird zero ausgewertet,
207 zero -> data.size == 0; // danach data.size
208 data.size inside {[0:10]};
209 foreach (data[i])
210 data[i] == i;
211 }
212
213
214// zufaelliges Abarbeiten eines Zweiges
215 task do_randcase();
216 begin
217 randcase
218 20 : begin // 20 gibt das Gewicht
219 $write ("first randcase \n"); // dieses Zweiges an
220 end // (aus Summe berechnet)
221 20 : begin
222 $write ("second randcase \n");
223 end
224 20 : begin
225 $write ("third randcase\n");
226 end
227 endcase
228 end
229 endtask