{"id":680,"date":"2020-11-16T10:30:01","date_gmt":"2020-11-16T10:30:01","guid":{"rendered":"http:\/\/dsd.webs.upv.es\/?page_id=680"},"modified":"2025-08-06T18:46:03","modified_gmt":"2025-08-06T18:46:03","slug":"paso-5-ordenandolo-todo-un-poco","status":"publish","type":"page","link":"https:\/\/dsd.webs.upv.es\/?page_id=680","title":{"rendered":"Paso 5: ordenandolo todo un poco"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\" id=\"block-63e05d19-e066-47fe-b6be-bfa5e35c856f\">Siguiendo los pasos de la creaci\u00f3n de un banco de pruebas para el radicador que responda a una estructura m\u00e1s actual y basada en systemVerilog, hemos visto conveniente hacer unas \u00faltimas incorporaciones que os puedan ayudar a mejorar el estilo de vuestros bancos de pruebas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"block-018a511a-9dff-478e-954d-960ea7b4ba4b\">Empecemos recordando la estructura que deseamos<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"block-50f7a252-5d26-458b-b367-f1bebdf7922d\">Estructura del banco de pruebas SystemVerilog<\/h2>\n\n\n\n<figure class=\"wp-block-image\" id=\"block-e41333d3-8e17-4d25-b8b8-ad4dabcc5d1a\"><img decoding=\"async\" src=\"https:\/\/poliformat.upv.es\/access\/content\/group\/GRA_12450_2019\/Ocultos\/Imagenes\/sv_simple_tb_with_scb.png\" alt=\"This image has an empty alt attribute; its file name is sv_simple_tb_with_scb.png\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"block-f3fe32e0-da5c-44e6-a742-056ff771e939\">En esta estructura las grandes construcciones que forman parte del banco de pruebas (module sin puertos del top) son:<\/p>\n\n\n\n<ul id=\"block-9187646e-035f-448c-9b30-5d77d8af22b5\" class=\"wp-block-list\">\n<li>DUT o DUV : dise\u00f1o bajo verificaci\u00f3n que ser\u00e1 un \u201cmodule\u201d instanciado<\/li>\n\n\n\n<li>test: Elementos constituyentes del sistema de verificaci\u00f3n que ser\u00e1 un \u201cprogram\u201d instanciado<\/li>\n\n\n\n<li>Elemento de comunicaci\u00f3n entre ambas construcciones que permita hacer llegar los est\u00edmulos generados por el test al DUV y permita observar tanto dichos est\u00edmulos como los resultados obtenidos por el DUV para hac\u00e9rselos llegar los elementos constitutivos del test. Esta construcci\u00f3n que permite esa comunicaci\u00f3n ser\u00e1 un \u201cinterface\u201d instanciado.<\/li>\n\n\n\n<li>Y deber\u00edamos completar con un generador de reloj y un generador de reset, si bien este \u00faltimo podr\u00eda generarse en el test como un est\u00edmulo m\u00e1s.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: systemverilog; title: ; notranslate\" title=\"\">\n`timescale 1ns\/1ps\nmodule prueba_radicador();\n\/\/ constants                                           \n\/\/ general purpose registers\nreg CLK;\nreg RESET;\n\n\/\/instanciacion del interfaz\ntest_if interfaz(.reloj(CLK),.rst(RESET));\n\n\/\/instanciaci\u00c3\u00b3n del disenyo                  \n top_duv duv (.bus(interfaz));\n            \n\/\/instanciacion del program  \nestimulos estim1 (.testar(interfaz),.monitorizar(interfaz));  \n\n\/\/ CLK\nalways\nbegin\n\tCLK = 1&#039;b0;\n\tCLK = #50 1&#039;b1;\n\t#50;\nend \n\n\/\/ RESET\ninitial\nbegin\n  RESET=1&#039;b1;\n  # 1  RESET=1&#039;b0;\n  #99 RESET = 1&#039;b1;\nend \n \nendmodule\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\" id=\"block-61ac0ec1-a924-49f5-a0f7-02b8b73e1304\">Vamos a incluir dichos elementos empezando con el elemento de intercomunicaci\u00f3n, que desarrollaremos a trav\u00e9s de un \u00abinterface\u00bb<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"block-daaf2cb3-6c87-46ee-b096-0c08f542f1fb\">INTERFAZ<\/h4>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: systemverilog; title: ; notranslate\" title=\"\">\n`timescale 1ns\/1ps\ninterface test_if (  input  bit  reloj,   input  bit  rst) ;\n  logic       empieza  ;\n  logic       termina  ;\n  logic &#x5B;7:0] data_in  ;\n  logic  &#x5B;4:0] data_out;\n  clocking md @(posedge reloj);\n\tinput #1ns data_out;\n\tinput #1ns data_in;\n\tinput #1ns empieza;\n    input #1ns termina;\n   endclocking:md;\n  clocking sd @(posedge reloj);\n    input #2ns  data_out;\n    output #2ns data_in;\n    input #2ns  termina;\n    output #2ns empieza; \n  endclocking:sd;\n  modport monitor (clocking md);\n  modport test (clocking sd);\n  modport duv (\n  \t\tinput          \treloj      ,\n  \t\tinput        \trst      ,\n  \t\toutput          termina  ,\n  \t\tinput         \tempieza   ,\n  \t\tinput  \t        data_in  ,\n  \t\toutput          data_out\n\t\t);\nendinterface\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\" id=\"block-493cc913-5b51-462f-aece-d3152afa1c74\">Este ejemplo de interfaz utiliza tres \u00abmod ports\u00bb : dos de ellos para proporcionar dos puntos de vista que debe usar el test: control (color violeta) y observabilidad (color granate); y un tercer punto de vista que utilizar\u00e1 el DUT (color azul en la figura)<\/p>\n\n\n\n<figure class=\"wp-block-image\" id=\"block-d1dd6b86-e047-453b-8240-0f20a1e34677\"><img decoding=\"async\" src=\"https:\/\/dsd.webs.upv.es\/wp-content\/uploads\/2020\/11\/image.png\" alt=\"This image has an empty alt attribute; its file name is image.png\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"block-cff2006f-a347-473c-a4a3-f6c39448e286\">.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"block-6f96f71b-ee75-441c-9b8e-75eccdc5a7ff\">Los dos modos que usar\u00e1 el test tienen asociados sus correspondientes \u00abclocking blocks\u00bb para sincronizar esas comunicaciones<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"block-406f118b-76e2-4e76-9eeb-07581e321162\">DUT<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"block-ffdd92af-39bb-4b23-ac34-cf889545b966\">Como hemos basado la interconexi\u00f3n en el banco de pruebas mediante \u00abinterface\u00bb el top del dise\u00f1o suele ser un fichero de adaptaci\u00f3n de interfaz a puertos y viceversa.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><\/pre>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: systemverilog; title: ; notranslate\" title=\"\">\nmodule top_duv (test_if.duv bus) ; \n\n\nsed  radicador_duv(\n  .CLK  (bus.reloj),     \/\/ Clock input\n.RESET  (bus.rst),     \/\/ Active LOW ASINCRONOUS reset\n.X      (bus.data_in), \/\/ Data input\n.COUNT  (bus.data_out),\/\/ Data Output\n.START  (bus.empieza),   \/\/ duv empieza\n .FIN   (bus.termina)     \/\/duv termina\n);\n\nendmodule\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"block-217e8c5b-bb46-47be-833f-e1cc5c40f96c\">TEST<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"block-4edb21c4-547d-41a9-9566-aa354c75996c\">Este elemento es el que m\u00e1s hemos cambiado.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><\/pre>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: systemverilog; title: ; notranslate\" title=\"\">\nprogram estimulos\n  (test_if.test testar,\n   test_if.monitor monitorizar  \n  );\n  \nutilidades_verificacion::enviroment casos = new(testar, monitorizar);     \/\/declaraci\u00f3n e instanciaci\u00f3n objeto                 \n\ninitial\nbegin\n  casos.muestrear;\n  $display(&quot;hacemos un test directo&quot;);\n  casos.prueba_directa;\n  $display(&quot;functional coverage after prueba_directa  is %e&quot;, casos.valores_X_trigger.get_coverage());\n \/\/ $stop;           \n         \n  $display(&quot;hacemos un test random de pares&quot;);\n  casos.prueba_random_pares;\n  $display(&quot;functional coverage after prueba_random_pares  is %e&quot;, casos.valores_X_trigger.get_coverage());\n\/\/  $stop;  \n           \n  $display(&quot;hacemos un test random de impares&quot;);\n  casos.prueba_random_impares;\n  $display(&quot;functional coverage afterprueba_random_impares  is %e&quot;, casos.valores_X_trigger.get_coverage());\n  $stop;             \n\nend\nendprogram\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\" id=\"block-ff9cbb25-ff62-4e57-866c-477c20e94e1d\">Destacan en dicho c\u00f3digo lo siguiente:<\/p>\n\n\n\n<ul id=\"block-8e31efa6-658c-4be0-a338-ac4dbe9b246e\" class=\"wp-block-list\">\n<li>Realizaci\u00f3n con la construcci\u00f3n \u00abprogram\u00bb. Como ya he dicho reiterada veces muchos ingenieros de verificaci\u00f3n prefieren seguir utilizando un \u00abmodule\u00bb<\/li>\n\n\n\n<li>Dicho \u00abprogram\u00bb consiste de\n<ul class=\"wp-block-list\">\n<li>un \u00abinitial\u00bb principal donde se suceden los diferentes casos contemplados en la verificaci\u00f3n y<\/li>\n\n\n\n<li>de un objeto de la clase \u00abenviroment\u00bb donde se encuentran los siguientes elementos:\n<ul class=\"wp-block-list\">\n<li>Los covergroups<\/li>\n\n\n\n<li>La clase de RCSG<\/li>\n\n\n\n<li>La clase del Scoreboard<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<ul id=\"block-245bed9a-6b96-430c-9ef3-bdf2baca0a94\" class=\"wp-block-list\">\n<li>Para poder declarar e instanciar un objeto de la clase enviroment hemos utilizado un \u00abpackage\u00bb denominado utilizades_verificacion que es importado utilizando el operador ::. Esto es una alternativa m\u00e1s elegante que nos permite que la compilaci\u00f3n no tenga problemas aunque estos elementos sean guardados en ficheros diferentes, en cuyo caso la visibilidad de las clases solo es conseguida si son incluidos los ficheros (soluci\u00f3n poco elegante) o si son importados los objetos.<\/li>\n\n\n\n<li>La inclusi\u00f3n de los covergroups en una clase (enviroment) en lugar de en el interior directamente del program nos sirve de ejemplo para observar los \u00abembedded covergroups\u00bb en los cuales\n<ul class=\"wp-block-list\">\n<li>Definir : con la construci\u00f3n covergroup<\/li>\n\n\n\n<li>Declaraci\u00f3n es impl\u00edcita<\/li>\n\n\n\n<li>Instanciaci\u00f3n: con el constructor new<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"block-c044df20-1329-4365-9bbd-5b799e09c614\">Veamos esa declaraci\u00f3n de package con esas clases, objetos y covergroups<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: systemverilog; title: ; notranslate\" title=\"\">\npackage utilidades_verificacion;\nclass RCSG;\n  rand logic &#x5B;7:0] valor;\n  constraint impares    {valor&#x5B;0] == 1&#039;b1;}\n  constraint pares {valor&#x5B;0] == 1&#039;b0;}\nendclass\nclass Scoreboard;\n  reg &#x5B;3:0] cola_targets   &#x5B;$];\n  reg &#x5B;3:0] target,pretarget,salida_obtenida;\n  reg FINAL;\n  virtual test_if.monitor mports;\n  \n  function new (virtual test_if.monitor mpuertos);\n  begin\n    this.mports = mpuertos;\n  end\n  endfunction\n   \n task monitor_input;\n   begin\n     while (1)\n       begin       \n         @(mports.md);\n         if (mports.md.empieza==1&#039;b1)\n           begin\n             pretarget=$floor($sqrt(mports.md.data_in));\/\/funcion ideal de obtencion e raiz cuadrada\n             cola_targets={pretarget,cola_targets};\/\/meto el valor deseado en la cola\n           end\n\t\tend\n   end\n endtask\n  task monitor_output;\n   begin\n     while (1)\n       begin       \n         @(mports.md);\n         if (mports.md.termina==1&#039;b1)\n           begin\n         \tFINAL=mports.md.termina;\n         \ttarget= cola_targets.pop_back();\n         \tsalida_obtenida=mports.md.data_out;\n             assert (salida_obtenida==target) else $error(&quot;operacion mal realizada: la raiz cuadrada de %d es %d y tu diste %d&quot;,mports.md.data_in,target,salida_obtenida);\n           end\n\t\tend\n   end\n endtask \n  \n    \n    \nendclass \n    \nclass enviroment;\n  virtual test_if.test testar_ports;\n  virtual test_if.monitor monitorizar_ports;\n \n\/\/esto nos permitir\u00c3\u00a1 utilziar el operador ## para los ciclos de reloj\n  \ncovergroup valores_X;    \n  idea1:coverpoint  monitorizar_ports.md.data_in;\n  idea2:coverpoint  monitorizar_ports.md.data_in\n    {\n    bins cero ={8&#039;h00};\n    bins extremo = {8&#039;h80};\n  }\nendgroup; \ncovergroup valores_X_trigger @(monitorizar_ports.md);\n  mon_entradas_pares:coverpoint  monitorizar_ports.md.data_in \n   {\n     wildcard bins impares&#x5B;] ={8&#039;bxxxxxxx0};\n  }\n  mon_entradas_impares:coverpoint  monitorizar_ports.md.data_in \n   {\n     wildcard bins pares&#x5B;] ={8&#039;bxxxxxxx1};\n  }\nendgroup; \n\/\/declaraciones de objetos\nScoreboard sb;\nRCSG busInst;\n  \nfunction new (virtual test_if.test ports, virtual test_if.monitor mports);\n  begin\n    testar_ports = ports;\n    monitorizar_ports = mports;\n    \/\/instanciaci\u00f3n objetos\n    busInst = new;\/\/construimos la case de valores random\n    valores_X=new;\/\/construimos el covergroup\n    valores_X_trigger=new;\/\/construimos el covergroup\n    sb=new(monitorizar_ports); \/\/construimos el scoreboard\n    \/\/inicializacion   \n     testar_ports.sd.empieza  &lt;= 1&#039;b0;\n     testar_ports.sd.data_in &lt;= 8&#039;d0;\n  end\n  endfunction  \n\/\/declaraciones de 4 metodos\n  \ntask muestrear;\nbegin\n    \/\/lanzamiento de procedimientos de monitorizacion\n     fork\n      sb.monitor_input; \/\/lanzo el procedimiento de monitorizacion cambio entrada y calculo del valor target\n      sb.monitor_output;\/\/lanzo el procedimiento de monitorizacion cambio salida y comparacion ideal\n     join_none\nend\nendtask  \ntask prueba_directa;\n\ttestar_ports.sd.empieza &lt;= 1&#039;b0;\n\ttestar_ports.sd.data_in &lt;= 8&#039;d25;\n  repeat(3) @(testar_ports.sd);\n\ttestar_ports.sd.empieza &lt;= 1&#039;b1;\n  @(testar_ports.sd);\n\ttestar_ports.sd.empieza &lt;= 1&#039;b0;\n  @(negedge testar_ports.sd.termina);\nendtask\ntask prueba_random_impares;\n  while ( valores_X_trigger.mon_entradas_impares.get_coverage()&amp;lt;80)\n\tbegin\n\t   busInst.pares.constraint_mode(0);\n\t   $display(&quot;pruebo con impares&quot;);\n\t   assert (busInst.randomize()) else    $fatal(&quot;randomization failed&quot;);\n    \ttestar_ports.sd.data_in&lt;= busInst.valor;\t\n    \tvalores_X.sample();\n      @(testar_ports.sd);\n\t   testar_ports.sd.empieza &lt;= 1&#039;b1;\n      @(testar_ports.sd);\n\t   testar_ports.sd.empieza &lt;= 1&#039;b0;\n      @(negedge testar_ports.sd.termina);\n   end\nendtask\ntask prueba_random_pares;\n  while ( valores_X_trigger.mon_entradas_pares.get_coverage()&amp;lt;80)\n\tbegin\n \t   busInst.impares.constraint_mode(0);\n\t   busInst.pares.constraint_mode(1);\n\t   $display(&quot;pruebo con pares&quot;);\n\t   assert (busInst.randomize()) else    $fatal(&quot;randomization failed&quot;);\n    \ttestar_ports.sd.data_in &lt;= busInst.valor;\t\n    \tvalores_X.sample();  \n      @(testar_ports.sd);\n        testar_ports.sd.empieza &lt;= 1&#039;b1;\n      @(testar_ports.sd);\n\t   testar_ports.sd.empieza &lt;= 1&#039;b0;\n      @(negedge testar_ports.sd.termina);\n   end\nendtask\n  \nendclass\nendpackage\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\" id=\"block-9eb2c1d7-4dd7-41bc-8ced-2afd16da4035\">Vamos a ver todo el proyecto en el siguiente laboratorio virtual. Esta soluci\u00f3n de banco de pruebas funciona perfectamente en questasim aun cuando el \u00abtestbench\u00bb sea distribuido en cuatro ficheros:<\/p>\n\n\n\n<ul id=\"block-a190a545-e695-4044-903b-e001dc27b3bd\" class=\"wp-block-list\">\n<li>interfaz.sv<\/li>\n\n\n\n<li>test.sv<\/li>\n\n\n\n<li>enviroment.sv<\/li>\n\n\n\n<li>banco_pruebas.sv<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Laboratorio virtual<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.edaplayground.com\/x\/78af\">https:\/\/www.edaplayground.com\/x\/78af<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.edaplayground.com\/x\/78af\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"295\" height=\"71\" src=\"https:\/\/dsd.webs.upv.es\/wp-content\/uploads\/2023\/09\/image-8.png\" alt=\"\" class=\"wp-image-1518\"\/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Siguiendo los pasos de la creaci\u00f3n de un banco de pruebas para el radicador que responda a una estructura m\u00e1s actual y basada en systemVerilog, hemos visto conveniente hacer unas \u00faltimas incorporaciones que os puedan ayudar a mejorar el estilo de vuestros bancos de pruebas. Empecemos recordando la estructura que deseamos Estructura del banco de pruebas SystemVerilog En esta estructura las grandes construcciones que forman parte del banco de pruebas (module sin puertos del top) son: Vamos a incluir dichos elementos empezando con el elemento de intercomunicaci\u00f3n, que desarrollaremos a trav\u00e9s de un \u00abinterface\u00bb INTERFAZ Este ejemplo de interfaz utiliza tres \u00abmod ports\u00bb : dos de ellos para proporcionar dos puntos de vista que debe usar el test: control (color violeta) y observabilidad (color granate); y un tercer punto de vista que utilizar\u00e1 el DUT (color azul en la figura) . Los dos modos que usar\u00e1 el test tienen asociados sus correspondientes \u00abclocking blocks\u00bb para sincronizar esas comunicaciones DUT Como hemos basado la interconexi\u00f3n en el banco de pruebas mediante \u00abinterface\u00bb el top del dise\u00f1o suele ser un fichero de adaptaci\u00f3n de interfaz a puertos y viceversa. TEST Este elemento es el que m\u00e1s hemos cambiado. Destacan en dicho c\u00f3digo lo siguiente: Veamos esa declaraci\u00f3n de package con esas clases, objetos y covergroups Vamos a ver todo el proyecto en el siguiente laboratorio virtual. Esta soluci\u00f3n de banco de pruebas funciona perfectamente en questasim aun cuando el \u00abtestbench\u00bb sea distribuido en cuatro ficheros: Laboratorio virtual https:\/\/www.edaplayground.com\/x\/78af<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":463,"menu_order":5,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","ub_ctt_via":"","footnotes":""},"class_list":["post-680","page","type-page","status-publish","hentry"],"featured_image_src":null,"_links":{"self":[{"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/pages\/680","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=680"}],"version-history":[{"count":10,"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/pages\/680\/revisions"}],"predecessor-version":[{"id":1925,"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/pages\/680\/revisions\/1925"}],"up":[{"embeddable":true,"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/pages\/463"}],"wp:attachment":[{"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}