-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
2255 lines (2048 loc) · 92.4 KB
/
Copy pathindex.html
File metadata and controls
2255 lines (2048 loc) · 92.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Verify This! - LEFT 2016-2019</title>
<meta name="description" content="Curso Introductorio a UVM">
<meta name="author" content="LeaT - LEFT">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/forkit.css">
<link rel="stylesheet" href="css/demo.css">
<link rel="stylesheet" href="css/theme/night.css" id="theme">
<!-- Code syntax highlighting -->
<link rel="stylesheet" href="lib/css/monokai-sublime.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>Verify This!</h1>
<h3><em>UVM Introduction</em></h3>
<p>
<small>Based on <a href="http://www.verificationacademy.com">Verification Academy</a></small>
<br>
<small>Author <a href="https://github.com/leandrotozzi/verifythis.com">LeaT</a></small>
</p>
</section>
<section data-transition="concave">
<h2>Agenda</h2>
<h4><em> Day 1</em> </h4>
<ul>
<li>Tendencias</li>
<li>Introducción</li>
<li>ALU Specs</li>
<li>TestBench Convencional</li>
<li>SV Interfaces & BFM</li>
<li>Classes y Extensiones</li>
<li>Polimorfismo</li>
</ul>
</section>
<section>
<h2>Tendencias</h2>
<h4><em> ASIC: Tendencias de Diseño</em> </h4>
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-7-1-520x390.png">
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-7-2-520x390.png">
</section>
<section>
<h2>Tendencias</h2>
<h4><em> ASIC: Verificación cada vez más necesaria</em> </h4>
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-8-1-520x390.png">
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-8-2-520x390.png">
</section>
<section>
<h2>Tendencias</h2>
<h4><em> ASIC: Verificación cada vez más necesaria</em> </h4>
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-8-3a-520x390.png">
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-8-4-520x390.png">
</section>
<section>
<h2>Tendencias</h2>
<h4><em> ASIC: Técnicas de Verificación</em> </h4>
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-8-5-520x390.png">
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-9-1-520x390.png">
</section>
<section>
<h2>Tendencias</h2>
<h4><em> ASIC: Lenguajes</em> </h4>
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-10-1-520x390.png">
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-10-2-520x390.png">
</section>
<section>
<h2>Tendencias</h2>
<h4><em> ASIC: Verificación</em> </h4>
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-10-3-520x390.png">
<img data-src="res/wilson/2014-WRG-BLOG-ASIC-10-4-520x390.png">
</section>
<section>
<h2>SystemVerilog es el <em>COBOL</em> de la electronica???</h2>
<table>
<thead>
<tr>
<th>Lenguaje</th>
<th>Reserved Keywords</th>
</tr>
</thead>
<tbody>
<tr>
<td>ANSI COBOL 85</td>
<td>357</td>
</tr>
<tr>
<td>SystemVerilog</td>
<td>323</td>
</tr>
<tr>
<td>VHDL 2008</td>
<td>115</td>
</tr>
<tr>
<td>Verilog 95</td>
<td>102</td>
</tr>
<tr>
<td>C#</td>
<td>102</td>
</tr>
<tr>
<td>C++</td>
<td>82</td>
</tr>
<tr>
<td>Python3.x</td>
<td>33</td>
</tr>
</tbody>
</table><center>
<pre> <em>"* No academic computer scientists participated in the design of COBOL;<br> all of those on the committee came from commerce or government"</em> Parecido no?</pre>
</center>
</section>
<section>
<h2>Introduccion</h2>
<h4><em> Que es iUVieM????</em></h4>
<ul>
<li>Universal Verification Methodology</li>
<li>Esfuerzo llevado a cabo por <em>Accellera</em></li>
<li>Define una metodología de verificación standard y una librería de clases</li>
<li>Inspirada en VMM y OVM y en otras <em>buenas prácticas</em></li>
<li>Open Source y codeada integramente en SystemVerilog</li>
<li><em>IEEE Standard P1800.2</em> (UVM 1.2)</li>
<li>Su objetivo es la <em>eficiencia</em> y la <em>reutilización</em> de piezas de software</li>
<li>Creado por y para la industria.</li>
</ul>
</section>
<section>
<h2>Introduccion</h2>
<h4><em> UVM Origins</em></h4>
<img data-src="res/originUVM.png" height="500">
</section>
<section>
<h2>Introduccion</h2>
<h4><em> SystemVerilog Typical TB</em></h4>
<img data-src="res/TB.png">
</section>
<section>
<h2>Introduccion</h2>
<h4><em> UVM Typical TB</em></h4>
<img data-src="res/TB_UVM.png" height="500">
</section>
<section>
<h2>Introduccion</h2>
<h4><em> UVM Clases</em></h4>
<img data-src="res/uvm_class_diagram.png" height="500">
</section>
<section>
<h2>Introduccion</h2>
<h4><em> Run More Tests, Write Less Code</em> </h4>
<ul>
<li><em>Environment y Component classes</em> rara vez cambian
<ul>
<li>Enviar <em>transactions</em> lo mas rapido posible</li>
<li>Permite que los tests existentes no se rompan</li>
<li><em>Hooks</em> para que los tests puedan inyectar nuevos comportamientos: <em> virtual methods, factories, callbacks</em></li>
</ul>
</li>
<li>Los tests extienden las clases de testbench</li>
<ul>
<li>Agregar constraints para alcanzar casos corners</li>
<li><em>Override</em> de clases para agregar nuevas funcionabilidades</li>
<li>Injectar errores, delays con callbacks</li>
</ul>
<li>Se puede correr cada test con cientos de seeds</li>
</ul>
</section>
<section>
<h2>1. ALU Specs</h2>
<img data-src="res/diagrams/wave-dut.png" style="background:#ffffff" alt="ALU waveform" >
<ul>
<li><em>start</em> debe permanecer en 1 y los operadores estables hasta <br>
que termina la operacion</li>
<li><em>done</em> se levanta cuando termina la operacion</li>
</ul>
</section>
<section>
<h2>1. ALU Specs</h2>
<table>
<thead>
<tr>
<th>Operation</th><th>Opcode</th>
</tr>
</thead>
<tbody>
<tr>
<td>no_op</td><td>3'b000</td>
</tr>
<tr>
<td>add_op</td><td>3'b00</td>
</tr>
<tr>
<td>and_op</td><td>3'b010</td>
</tr>
<tr>
<td>xor_op</td><td>3'b011</td>
</tr>
<tr>
<td>mul_op</td><td>3'b100</td>
</tr>
<tr>
<td>unused</td><td>3'b101-3'b111</td>
</tr>
</tbody>
</table>
</section>
<section>
<h3>1. VHDL ALU Implementation</h3>
<h4><em>Single Cycle: Add - AND - XOR</em></h4>
<pre><code class="vhdl" data-trim local-file style="max-height: 550px;">
code/tinyalu_dut/single_cycle_add_and_xor.vhd
</code></pre>
</section>
<section>
<h3>1. VHDL ALU Implementation</h3>
<h4><em>Multi Cycle: Multiplicacion</em></h4>
<pre><code class="vhdl" data-trim local-file style="max-height: 550px;">
code/tinyalu_dut/three_cycle_mult.vhd
</code></pre>
</section>
<section>
<h3>1. VHDL ALU Implementation</h3>
<h4><em>Top Level</em></h4>
<pre><code class="vhdl" data-trim local-file style="max-height: 550px;">
code/tinyalu_dut/tinyalu.vhd
</code></pre>
</section>
<section>
<h2>2. TestBench Convencional</h2>
<h4><em> Coverage First Methodology</em> </h4>
<ul>
<li>Definimos que queremos cubrir y luego creamos el TB</li>
<li>El objetivo es testear toda la funcionabilidad de la ALU y <br>
simular <em>TODAS</em> las lineas del codigo RTL</li>
<li>El TB tiene 3 partes: stimulus, self-checking y coverage</li>
</ul>
</section>
<section>
<h3>2. TestBench Convencional</h3>
<ul>
<li>Testear todas las operaciones</li>
<li>Casos Border: entradas todas en 0/1 para todas las operaciones</li>
<li>Ejecutar todas las ops luego de un reset</li>
<li>Ejecutar una multiplicacion luego de una single cycle op y viceversa</li>
<li>Simular todas las operaciones ejecutadas 2 veces seguidas</li>
</ul>
<pre><code class="systemverilog" data-trim local-file>
code/ch02/tinyalu_tb.sv
</code></pre>
</section>
<section>
<h2>3. SV Interfaces & BFM</h2>
<ul>
<li>El primer paso hacia UVM es modularizar correctamente el TB</li>
<li>SV interface agrupa signals y permite modelar Bus Functional Models</li>
<li> Los BFM encapsulan el protocolo asociado a un bus en simples transactions</li>
</ul>
<pre><code class="systemverilog" data-trim local-file>
code/ch03/tinyalu_bfm.sv
</code></pre>
</section>
<section>
<h2>3. SV Interfaces & BFM</h2>
<h3><em> Modular TB </em></h3>
<ul>
<li>Dividimos el TB en tester, scoreboard y coverage</li>
<li>La conexion la realizamos mediante nuestra nueva BFM</li>
</ul>
<pre><code class="systemverilog" data-trim local-file>
code/ch03/top.sv
</code></pre>
</section>
<section>
<h2>3. SV Interfaces & BFM</h2>
<h3><em> Scoreboard </em></h3>
<pre><code class="systemverilog" data-trim local-file>
code/ch03/scoreboard.sv
</code></pre>
</section>
<section>
<h2>3. SV Interfaces & BFM</h2>
<h3><em> Tester </em></h3>
<pre><code class="systemverilog" data-trim local-file>
code/ch03/tester.sv
</code></pre>
</section>
<section>
<h2>4.5. Classes y Extensions</h2>
<h3><em>Por que es util OOP?</em></h3>
<ul>
<li><em>Code Reuse & Code Maintainability & Memory Management:</em></li>
</ul>
<pre><code class="systemverilog" data-trim local-file>
code/ch05/classes.sv
</code></pre>
</section>
<section>
<h2>6. Polimorfismo</h2>
<h3><em> Que es???? </em></h3>
<p> Declaro una variable de tipo <em>rectangulo</em> y luego instancio un objeto <em>cuadrado</em>.</p>
<p> Siendo cuadrado una clase extendida de rectangulo.... </p>
<p> Puedo guardar el objeto cuadrado en la variable rectangulo????? </p>
<p> Claro! Se llama <em>Polimorfimo</em> </p>
</section>
<section>
<h2>6. Polimorfismo: Ejemplo basico</h2>
<img data-src="res/diagrams/uml-poli.png" alt="Animal UML Diagram">
<pre><code class="systemverilog" data-trim local-file style="max-height: 300px;">
code/ch06/01_Not_Virtual/not_virtual.sv
</code></pre>
</section>
<section>
<h2>6. Polimorfismo: Virtual Methods</h2>
<ul>
<li>SV usa la keyword virtual por todos lados. </li>
<li> La idea de <em>virtual</em>, es avisar que lo vamos a definir despues</li>
<li>Cuando definimos un metodo como virtual, le estamos diciendo a SV que se fije en que tipo de objeto tiene, no en el tipo de la variable</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch06/02_Virtual/virtual.sv
</code></pre>
</section>
<section>
<h2>6. Polimorfismo: Abstracts Classes and Pure Virtual Methods</h2>
<ul>
<li>El ejemplo anterior se queda corto. Estamos obligando a tener que hacer un override de make_sound() en las clases extendidas. Sino $fatal</li>
<li>Lo malo de esto, es que va a compilar, a correr y en el medio de la simulacion, te puede explotar... Mejor atajar antes el error</li>
<li>SV permite definir <em>abstract class</em>, que solo pueden ser usadas como clases bases. <em>No se pueden instanciar</em></li>
<li>Estas clases permiten definir <em>pure virtual methods</em></li>
<li>Estos metodos son vacios y <em>deben ser redefinimos cuando extendemos la clase abstracta</em></li>
<li>Si no redefinimos un metodo pure virtual, obtenemos error de compilacion</li>
</ul>
</section>
<section>
<h2>6. Polimorfismo: Abstracts Classes and Pure Virtual Methods</h2>
<pre><code class="systemverilog" data-trim local-file style="max-height: 500px;">
code/ch06/03_Pure_Virtual/pure_virtual.sv
</code></pre>
</section>
<section data-transition="concave">
<h2>Agenda</h2>
<h4><em> Day 2</em> </h4>
<ul>
<li>Static Methods and Variables</li>
<li>Clases parametricas</li>
<li>The Factory Pattern</li>
<li>Object Oriented TestBench</li>
</ul>
</section>
<section>
<h2>7. Variables estaticas</h2>
<ul>
<li>Muchas veces es util tener una estructura de datos global dentro de un TB </li>
<li>OK, uso Variables globales? No, son dificiles de debuggear, de encontrar la declaracion... Una tragedia</li>
<li>OOP provee para este tipo de casos la magia de lo <em>static</em></li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch07/01_Static_Variables/static_variables.sv
</code></pre>
</section>
<section>
<h2>7. Variables estaticas</h2>
<ul>
<li>Solo tenemos una copia en memoria de una variable <em>static</em></li>
<li>Sin importar el numero de instancias que tengamos de esa clase </li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch07/01_Static_Variables/ejemplo2.sv
</code></pre>
<p class="fragment current-visible"><b><em>Y el encapsulamiento que onda???</em></b></p>
</section>
<section>
<h2>7. Metodos estaticos</h2>
<ul>
<li>En los ejemplos anteriores, no escondiamos la implementacion. Si en el 1ero, queriamos cambiar la queue por otra estructura, debiamos cambiar por todos lados</li>
<li>Siempre hay que <em>encapsular</em> estas cosas. Declarar <em>protected</em> la variable estatica y armar los <em>metodos de acceso estaticos</em></li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch07/02_Static_Methods/static_methods.sv
</code></pre>
</section>
<section>
<h2>8. Clases Parametricas</h2>
<ul>
<li>En la version anterior, creamos una lion_cage, ok, pero si ahora necesito una chicken_cage??? Copio y pego? NO!</li>
<li>SV incorpora las <em>parameterized class definitions</em></li>
<li>Son una extension de los famosos <em>parameters</em> de verilog</li>
<li>UVM las utiliza mucho, por eso hay que entenderlas</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch08/01_memory_example/pres-ch8.sv
</code></pre>
</section>
<section>
<h2>8. Clases Parametricas</h2>
<ul>
<li>Version con clases estaticas</li>
<li>La queue es estatica, pero al instanciar 2 veces la clase con parametros distintos, SV crea 2 colas distintas</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch08/02_static/cages.sv
</code></pre>
</section>
<section>
<h2>8. Variables con Parametros</h2>
<ul>
<li>En esta version no usamos metodos estaticos, sino que instanciamos <em>animal_cage</em> y usamos ese objeto
para almacenar otros objetos</li>
<li>Funciona igual que el codigo anterior, pero no podemos acceder al animal_cage desde cualquier lugar del TB</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch08/03_instantiated/cages.sv
</code></pre>
</section>
<section>
<h2>9. The Factory Pattern</h2>
<ul>
<li>Design Pattern mas visible en <em>UVM</em> (Programming Trick)</li>
<li>Consiste en crear una clase constructora dedicada a la construcción de objetos de un subtipo</li>
<li>Veamos primero que soluciona:</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch09/without-factory.sv
</code></pre>
<pre><em>La idea es crear datos de tipos aleatorios sin cambiar el codigo. </em></pre>
</section>
<section>
<h2>9. The Factory Pattern</h2>
<img data-src="res/diagrams/ch9_diagram.png" alt="UML Class Example Diagram" > <br>
<ul>
<li><em>Factory Pattern:</em> Queremos pasar un argumento a un metodo y que nos devuelva un objeto del tipo especificado</li>
<li><em>Polimorfismo:</em> Lion y chicken hacen un override de la clase animal. En una variable animal podemos guardar cualquiera de estos tipos</li>
</ul>
</section>
<section>
<h2>9. The Factory Pattern</h2>
<ul>
<li> Vimos que <em> virtual </em> le decia que use el metodo del objeto y no del tipo del handler, pero que pasa si la clase heredada agrega cosas? </li>
<li><em>$cast:</em> system call que convierte la variable del segundo argumento en la clase del primer argumento</li>
<li>Solo funciona si la clase objetivo es derivada de la clase casteada</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch09/factory.sv
</code></pre>
</section>
<section>
<h2>9. The Factory Pattern</h2>
<h3><em>Python Style</em></h3>
<pre><code class="python" data-trim local-file style="max-height: 500px;">
code/ch09/factory.py
</code></pre>
</section>
<section>
<h2>10. An Object-Oriented Testbench</h2>
<ul>
<li><em>Por que tanta lio si los unitarios de verilog funcionan?</em> Funcionan para cosas chicas, no para escenarios complejos</li>
<li><em>OOP encapsula y abstrae</em>, por lo tanto permite manejar complejidades superiores y refuerza la reutilizacion de codigo</li>
</ul>
<br><br>
<h3><em>TinyALU TB en objetos:</em></h2>
<ul>
<li>top: Instancia la clase testbench </li>
<li>testbench: Top-Level Class </li>
<li>tester: Genera los estimulos</li>
<li>scoreboard: Chequea que la TinyAlu esta funcionando</li>
<li>coverage: Captura la informacion de cobertura funcional</li>
</ul>
</section>
<section>
<h2>10. An Object-Oriented Testbench</h2>
<h3><em>Top Module </em></h3>
<ul>
<li>Importamos las definiciones de clases (package)</li>
<li>Instancia la DUT y el BFM y declara la clase testbench</li>
<li>Instancia y ejecuta la clase testbench</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 350px;">
code/ch10/top.sv
</code></pre>
</section>
<section>
<h2>10. An Object-Oriented Testbench</h2>
<h3><em>Testbench Class </em></h3>
<ul>
<li>Los TB orientados a objetos tienen un unico objeto que instancias los demas objetos, los conecta y lanza sus metodos</li>
<li>Luego veremos que <em>UVM</em> maneja muchas de estas funciones por nosotros, pero como por ahora no estamos usando UVM, tenemos que hacer esto nosotros</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 300px;">
code/ch10/tb_classes/testbench.svh
</code></pre>
</section>
<section>
<h2>10. An Object-Oriented Testbench</h2>
<h3><em>Tester Class </em></h3>
<ul>
<li>Estimula el DUT con <em>Random Ops</em> que eventualmente van a cubrir todos los <em>coverpoints</em> funcionales</li>
<li>Muy similar a la version modular salvo que:
<ul>
<li>Definimos una clase en vez de un modulo, usamos una variable para acceder a la BFM (en vez de un port list)</li>
<li>Usamos el metodo <em>execute</em> en vez de un <em>initial block</em></li>
</ul>
</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 250px;">
code/ch10/tb_classes/tester.svh
</code></pre>
</section>
<section>
<h2>10. An Object-Oriented Testbench</h2>
<h3><em>ScoreBoard Class </em></h3>
<pre><code class="systemverilog" data-trim local-file style="max-height: 450px;">
code/ch10/tb_classes/scoreboard.svh
</code></pre>
</section>
<section>
<h2>10. An Object-Oriented Testbench</h2>
<h3><em>Coverage Class </em></h3>
<pre><code class="systemverilog" data-trim local-file style="max-height: 450px;">
code/ch10/tb_classes/coverage.svh
</code></pre>
</section>
<section data-transition="convex">
<h2>Agenda</h2>
<h4><em> Day 3</em> </h4>
<ul>
<li>UVM Tests</li>
<li>UVM Components</li>
<li>UVM Environment</li>
<li>New Paradigm</li>
</ul>
</section>
<section>
<h2>11. UVM Tests</h2>
<ul>
<li><em>Objetivo:</em> Necesitamos correr miles de tests sin tener que recompilar el TB para cada caso. Supongamos que tenemos 1000 tests y tardamos 5 minutos por test en compilar todo. Eso significa <em>5000 minutos</em> o 3.5 dias de compilacion. <em>Drama</em></li>
<li>UVM permite armar un TB <em>dinamicamente configurable.</em> </li>
<li> Esto es, crear un TB definiendo las clases de objetos y luego instanciar distintos objetos para tests diferentes. <em>Sin tener que recompilar</em></li>
<li> El TB del tinyALU como esta hasta ahora, es enteramente hardcodeado, si queremos nuevos estimulos, tenemos que recompilar todo </li>
</ul>
<pre><code class="bash" data-trim style="max-height: 2000px;">
[leat@solchaga uvm-training]$ vsim testbench -coverage +UVM_TESTNAME=addtest (o randomtest)
</code></pre>
<pre><em>El objetivo es pasarle al TB previamente compilado los test que queremos correr<br>Definimos la clase addtest y UVM usa el argumento UVM_TESTNAME para llamar al factory y crear el test</em></pre>
</section>
<section>
<h2>11. UVM Tests</h2>
<h3><em>Lanzando simulaciones con UVM</em></h3>
<ul>
<li><em>uvm_config_db:</em> Clase estatica y parametrizable que permite almacenar info global en el TB</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch11/top.sv
</code></pre>
</section>
<section>
<h2>11. UVM Tests</h2>
<h3><em>Definiendo y Registrando un Test UVM</em></h3>
<ol>
<li>El test extiende uvm_test y lo registro con `uvm_component_utils</li>
<li>Constructor con ciertas reglas</li>
<li>Override del run_phase method</li>
<li>Mecanismo de objections</li>
</ol>
<pre><code class="systemverilog" data-trim local-file style="max-height: 320px;">
code/ch11/tb_classes/random_test.svh
</code></pre>
</section>
<section>
<h2>11. UVM Tests</h2>
<h3><em>Definiendo y Registrando otro Test UVM</em></h3>
<ul>
<li>Ahora creamos el test add_test, de manera similar</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 400px;">
code/ch11/tb_classes/add_test.svh
</code></pre>
</section>
<section>
<h2>11. UVM Tests</h2>
<h3><em>run.do y ejemplo de salida</em></h3>
<pre><code class="bash" data-trim local-file style="max-height: 250px;">
code/ch11/run.do
</code></pre>
<pre><code class="bash" data-trim local-file style="max-height: 220px;">
code/ch11/output.questa
</code></pre>
</section>
<section>
<h2>12. UVM Components</h2>
<ul>
<li>El diseño de un testbench se puede partir en 3:
<ol>
<li><em>Estructura:</em> Describe las partes del TB y como se conectan</li>
<li><em>Secuencias:</em> Comandos que le mandamos al DUT y en que orden</li>
<li><em>Data:</em> Datos de estimulo que usamos en los comandos</li>
</ol>
</li>
<li> UVM describe un TB utilizando una jerarquia de objetos</li>
<li> Nos da herramientas para instanciar, ejecutar y terminar todos los objetos de nuestro TB</li>
<li> La clase <em>uvm_component</em> es la base para armar la estructura del TB. Ejemplo: <em>uvm_test</em> que usamos previamente es un <em>uvm_component</em></li>
</ul>
</section>
<section>
<h2>12. UVM Components</h2>
<h3><em>Definir e Instanciar UVM components</em></h3>
<ul>
<li>
<ol>
<li>Extender la clase <em>uvm_component</em> o clases hijas para definir nuestro componente</li>
<li>Utilizar la macro <em>`uvm_component_utils()</em> para registrar la clase en la factory </li>
<li>Proporcionar al menos el constructor minimo de <em>uvm_component</em></li>
<li>Override los <em>UVM phase methods</em> (de ser necesario)</li>
</ol>
</li>
<li> Antes, extendimos <em>uvm_test</em> e instanciamos las 3 partes del TB como objetos genericos</li>
<li> Ahora vamos a tratar al tester, coverage y scoreboard como <em>uvm_components</em> utilizando las practicas standard de UVM </li>
</ul>
</section>
<section>
<h2>12. UVM Components</h2>
<h3><em>Intro UVM phases</em></h3>
<ul>
<li>Todos los uvm components tienen estos phase methods por herencia</li>
<li>UVM crea los TB y va llamando estos metodos en orden </li>
<li>Cuando hacemos un override de estos metodos, en el constructor debemos llamar a <em>super.(phase_method) primero</em></li>
<ul>
<li><em>function void build_phase(uvm_phase phase):</em> UVM crea el TB (top-down). Los componentes UVM se instancian en este metodo. Si tratas de instanciarlos en otro lado es error </li>
<li><em>function void connect_phase(uvm_phase phase):</em> Conexion de componentes</li>
<li><em>function void end_of_elaboration_phase(uvm_phase phase):</em> UVM lo llama una vez que creo y conecto todos los componentes</li>
<li><em>task run_phase(uvm_phase phase):</em> UVM ejecuta esta task en su propio thread. Todos los run_phase se ejecutan simultaneamente</li>
<li><em>function void report_phase(uvm_phase phase):</em> Se ejecuta cuando se termina la ultima objection del test. Muestra Resultados</li>
</ul>
</li>
</ul>
</section>
<section>
<h2>12. UVM Components</h2>
<h3><em>Scoreboard extends uvm_component</em></h3>
<pre><code class="systemverilog" data-trim local-file style="max-height: 500px;">
code/ch12/tb_classes/scoreboard.svh
</code></pre>
</section>
<section>
<h2>12. UVM Components</h2>
<h3><em>Building the TB</em></h3>
<pre><code class="systemverilog" data-trim local-file style="max-height: 250px;">
code/ch12/tb_classes/random_test.svh
</code></pre>
<pre><code class="systemverilog" data-trim local-file style="max-height: 250px;">
code/ch12/tb_classes/add_test.svh
</code></pre>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Resumen hasta la fecha...</em></h3>
<ul>
<li>Vimos como la <em>factory</em> puede crear un objeto top del tipo <em>uvm_test</em> que se encarga de instanciar los <em>uvm_components</em></li>
<li>Sabemos que UVM llama automaticamente a los <em>phase methods</em> de nuestros componentes</li>
<li>Ademas, UVM va a correr los run_phases de cada componente en su propio thread</li>
<li>Hasta aca usamos <em>uvm_test</em> y <em>uvm_components</em> para crear un TB simple, donde instanciamos los componentes directamente en los tests</li>
<li>Esta forma de crear el TB es sencilla de entender pero dificil de reutilizar</li>
<li>La tipica discusion malaria: <em>Intractable Vs Adaptable Coding</em></li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Intractable Vs Adaptable</em></h3>
<ul>
<li>Se llama intractable al codigo que escribis muy rapido sin pensar a futuro</li>
<li>Se vuelven cada vez mas dificil de modificar y mantener</li>
<li>Hay que escribir el codigo pensando que <em>otra persona lo va a modificar</em> y queremos que no nos putee (tanto)</li>
<li>El codigo adaptable es facilmente reutilizable por otra persona</li>
<li>Arrancamos codeando de mala gana el TB para nuestra ALU y lo estamos reformulando aplicando 3 reglas:
<ul>
<li>Crear clases que hagan una unica cosa muy bien y juntarlas para crear una solucion</li>
<li>Evitar el hardcodeo siempre que se pueda</li>
<li>Programar en base a la interface y no hacer suposiciones sobre la implementacion</li>
</li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Intractable Vs Adaptable</em></h3>
<blockquote>
“Tienen prohibido escribir codigo feo.” <br>Lic. Barros Schelotto
</blockquote>
<img data-src="res/funs/gbarros.jpg" alt="el Guille" align="center">
</section>
<section>
<h2>13. UVM Environments</h2>
<h4><em>Architecturing Adaptable Code</em></h4>
<img data-src="res/diagrams/13_intract_sol_1.png">
<ul>
<li>Nuestro TB actualmente utiliza 2 tests: uno que manda operaciones random <em>(random_tester)</em> y otro puntual para la suma
<em>(add_tester)</em></li>
<li>Random manda 1000 ops random y add manda 1000 sumas</li>
<li>Ambos test mandan los operadores (A y B) mediante constrained random</li>
<li>En nuestra solucion extendemos la clase <em>uvm_component</em> 2 veces, 1 vez por cada tester</li>
<li>Cada clase tiene un metodo <em>get_op()</em>, un <em>get_data()</em> y un <em>run_phase()</em></li>
<li>Lo que lo hace una mala solucion, es que estamos duplicando <em>run_phase()</em></li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h4><em>Architecturing Adaptable Code</em></h4>
<img data-src="res/diagrams/13_using_virtual_class.png">
<ul>
<li>Creamos una clase abstracta (base_tester) que tenga el metodo run_phase() y que mande 1000 operaciones usando get_op() y get_data()</li>
<li>Al ser abstracta no la podemos instanciar y con los metodos <em>pure virtual</em> obligamos a que las clases heredadas redefinan los metodos</li>
<li>Todavia comparten codigo: ambos tester utilizan operadores random...</li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h4><em>Architecturing Adaptable Code</em></h4>
<img data-src="res/diagrams/13_adaptable_sol.png" align="right">
<ul align="left">
<li>random_test: crea operaciones random con operandos <br> aleatorios </li>
<li>Aprovechando esto es facil pensar que heredando la clase <br>
random_tester se pueden crear muchas otras clases utiles</li>
<li>Por ejemplo: xor_test, mult_test, etc </li>
<li>El resultado es que <em>add_tester</em> es muy simple:</li>
<pre><code class="systemverilog" data-trim local-file style="max-height: 300px;">
code/ch13/tb_classes/add_tester.svh
</code></pre>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h4><em>Separating Structure from Stimulus</em></h4>
<ul>
<li>Muy lindo todo pero como lo usamos?</li>
<li>Creamos una familia de clases uvm_test? No es una buena idea</li>
<li> Cada test que extienda random_test va a tener un objeto random_tester...
<pre><code class="systemverilog" data-trim local-file style="max-height: 130px;">
code/ch12/tb_classes/random_test.svh
</code></pre>
</li>
<li>Le pifiamos cuando no cumplimos la promesa de que una clase solo haga 1 cosa muy bien,
random_tester arma la estructura del TB y y especifica el test a realizar</li>
<li> UVM soluciona esto mediante la clase <em>uvm_env</em> que es donde armamos la estructura del TB</li>
<li>uvm_env usualmente solo contiene definiciones de los metodos <em>build_phase</em> y <em>connect_phase</em></li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h4><em>Separating Structure from Stimulus</em></h4>
<img data-src="res/diagrams/13_struct_level.png" alt="" align="center">
<ul>
<li>Aca vemos el diagrama de clases luego de separar la estructura estructura respecto de los test mediante
<em>uvm_env</em></li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h4><em>env class</em></h4>
<ul>
<li>La clase <em>env</em> define la estructura del TB. Instancia los objetos y luego los conecta</li>
<li>OOP: Mientras mas dividamos a un problema en subproblemas mas chicos, obtendremos codigo mas simple</li>
<li>El metodo <em>build_phase()</em> hace llamadas a metodos static que crean los componentes</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 300px;">
code/ch13/tb_classes/env.svh
</code></pre>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Creando UVM components con UVM Factory</em></h3>
<ul>
<li>UVM factory es mas sofisticada que el ejemplo simple que vimos de animales, donde teniamos que <em>castear</em> el resultado y
hardcodear el codigo para agregar nuevos tipos a fabricar</li>
<li>En UVM agregamos nuevas clases a la factory utilizando los siguientes macros:
<ul>
<li><em>`uvm_component_utils()</em></li>
<li><em>`uvm_object_utils()</em></li>
</ul></li>
<li>UVM Factory retorna un objeto del tipo correcto, sin necesidad de caster el resultado</li>
<li>Veamos como hacemos esto... </li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Creando UVM components con UVM Factory</em></h3>
<img data-src="res/diagrams/ch13_uvm_incantation.png" align="center">
<ul>
<li>UVM utiliza la tecnica de static member/method que vimos previamente para entregar un <em>uvm_component</em>.</li>
<li>Las ventajas son las siguientes:
<ul>
<li>No hay que castear el resultado, UVM lo hace automaticamente</li>
<li>En tiempo de compilacion podemos encontrar si no definimos la clase o la escribimos mal</li>
<li>El compilador tambien ataja cuando olvidamos poner algun <em>`uvm_component_utils()</em></li>
</ul>
</li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Creando UVM components con UVM Factory</em></h3>
<ul>
<li>Todo muy lindo pero tester_h pide como resultado un objeto del tipo base_tester y esta es una clase abstracta....</li>
</ul>
<pre><code class="systemverilog" data-trim local-file style="max-height: 200px;">
code/ch13/tb_classes/base_class.svh
</code></pre>
<ul>
<li>Esto funciona porque env esta usando la variable base_tester como un placeholder</li>
<li>El codigo asume que la factory va a retornar un objeto de alguna clase derivada de base_tester</li>
<li>El objeto se determina mediante un override de la clase base_tester en la factory antes que build_phase se ejecute</li>
<li>Aca, el override lo hacemos en la clase test que instancia la clase env</li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Overriding the factory</em></h3>
<ul>
<li>Cuando vimos UVM Test, extendimos a random_test para crear un add_test</li>
<li>add_test reemplazaba al tester mediante un add_tester</li>
<li>Creamos nuestro add_test copiando el random_test y reemplazando el objeto tester por un objeto add_tester. Violando la regla
que dice que no vale copiar codigo</li>
<li>UVM factory soluciona este problema</li>
<li>Debido a que la clase add_tester es hija de la clase base_tester, podemos usar un objeto add_tester, en cualquier lugar que usemos
un base_tester</li>
<li>Es decir, le podemos decir a la factory que produzca un objeto add_tester en cualquier lugar que le pidamos un objeto base_tester</li>
<li> A esto se lo llama, <em>factory override</em></li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Overriding the factory</em></h3>
<img data-src="res/diagrams/ch13_uvm_incantation_2.png" align="center">
<ul>
<li>El metodo static <em>set_type_override()</em> le dice a la factory que cuando vea un pedido por una <em>base_class_name</em>
retorne un objeto del tipo <em>new_class_name</em></li>
<li>Esta feature es la que nos permite separar la estructura del TB (<em>uvm_env</em>) del tipo de estimulo generado
(<em>uvm_test</em>)</li>
</ul>
</section>
<section>
<h2>13. UVM Environments</h2>
<h3><em>Overriding the factory</em></h3>
<pre><code class="systemverilog" data-trim local-file style="max-height: 250px;">
code/ch13/tb_classes/random_test.svh
</code></pre>
<ul>
<li>Vemos que esta version es mas adaptable</li>
<li>Todos los Tests hace un override de base_tester en funcion del tester que necesitan para sus estimulos</li>
<li>La clase env crea el objeto y lo pone en ejecucion</li>
<li>Ahora la clase test hace una cosa bien (generar estimulos) y la clase env hace otra cosa muy bien (crear la estructura)</li>
</ul>
</section>
<section>
<h2>14. A New Paradigm</h2>
<ul>
<li>El <em>paradigma estructural</em> plantea que pasos/receta seguir para resolver un problema</li>
<li><em>OOP</em> plantea, como conectar objetos para poder resolver el problema</li>
<li>Es por eso, que debemos analizar los tipos de comunicaciones que podemos tener entre objetos</li>
<li><ul>
<li><em>Single-Thread:</em> Un objeto corriendo en un thread llama al metodo de otro objeto</li>
<li><em>Dual_Thread:</em> 2 objetos corriendo en threads diferentes necesitan comunicarse entre si y coordinarse</li>
</ul>
</li>
<li> Arrancaremos viendo single-thread y la fabulosa clase <em>uvm_analysis_port</em></li>
</ul>
</section>
<section>
<h2>Agenda</h2>
<h4><em> Day 4</em> </h4>
<ul>
<li>Talking to Multiples Objects</li>
<li>Using Analysis Ports in a TestBench</li>
<li>Interthread Communication</li>
<li>Put and Get Ports in Action</li>
</ul>
</section>
<section>
<h2>15. Talking Multiples Objects</h2>
<h3><em>Problema Introductorio</em></h3>
<ul>
<li>Escribir un programa que simule la ejecucion de tirar dos dados (2d6) 20 veces e informe lo siguiente
<ul>
<li>El promedio de los valores que dieron los dados</li>
<li>Un histograma con la frecuencia de valores</li>
<li>Un reporte de cobertura que muestre si salieron todos los posibles valores de 2 a 12</li>
</ul>
</li>
</ul>
<img data-src="res/funs/two-purple-dice-hi.png" height="182" width="200" align="center">
</section>