{"id":1762,"date":"2025-08-06T08:17:00","date_gmt":"2025-08-06T08:17:00","guid":{"rendered":"https:\/\/dsd.webs.upv.es\/?page_id=1762"},"modified":"2025-08-06T09:06:39","modified_gmt":"2025-08-06T09:06:39","slug":"concurrencia","status":"publish","type":"page","link":"https:\/\/dsd.webs.upv.es\/?page_id=1762","title":{"rendered":"Concurrencia"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">El Concepto Clave: Paralelismo Real vs. Simulaci\u00f3n Secuencial<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El comentario m\u00e1s importante sobre la concurrencia en Verilog\/SystemVerilog es entender que, aunque est\u00e1s describiendo un hardware que es <strong>inherentemente paralelo<\/strong>, el simulador que ejecuta tu c\u00f3digo es un programa de software que funciona de manera <strong>secuencial<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esta diferencia es la fuente de los problemas m\u00e1s comunes, como las condiciones de carrera (<code>race conditions<\/code>), y la raz\u00f3n por la que existen las asignaciones <code>blocking<\/code> (<code>=<\/code>) y <code>non-blocking<\/code> (<code>&lt;=<\/code>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Analog\u00eda para entenderlo<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Imagina que est\u00e1s describiendo una coreograf\u00eda de baile con 100 bailarines. En la vida real, todos los bailarines realizan su quinto paso <strong>exactamente en el mismo instante<\/strong>. Eso es <strong>paralelismo real<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora, imagina que el director de la coreograf\u00eda (el simulador) solo puede dar instrucciones a un bailar\u00edn a la vez. Para simular que todos se mueven al mismo tiempo, el director debe seguir un proceso:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Fase de Evaluaci\u00f3n (RHS):<\/strong> El director \u00abmira\u00bb la posici\u00f3n actual de todos los bailarines y calcula cu\u00e1l ser\u00e1 el pr\u00f3ximo movimiento de cada uno. Apunta en su libreta: \u00abBailar\u00edn 1 ir\u00e1 a la posici\u00f3n X, Bailar\u00edn 2 a la posici\u00f3n Y&#8230;\u00bb, etc. Lo hace para los 100 bailarines sin que ninguno se mueva todav\u00eda.<\/li>\n\n\n\n<li><strong>Fase de Actualizaci\u00f3n (LHS):<\/strong> Una vez que ha calculado todos los movimientos futuros, grita \u00ab\u00a1AHORA!\u00bb y todos los bailarines se mueven a la nueva posici\u00f3n que \u00e9l calcul\u00f3.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">\u00bfC\u00f3mo se refleja esto en el c\u00f3digo?<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Las <strong>asignaciones non-blocking (<code>&lt;=<\/code>)<\/strong> modelan este comportamiento correctamente. Son la forma de decirle al simulador: \u00abCalcula todos los resultados de la derecha ahora, pero no actualices las variables de la izquierda hasta que hayas terminado de calcularlos todos\u00bb. Esto es esencial para modelar registros y l\u00f3gica secuencial, donde todos los flip-flops se actualizan simult\u00e1neamente con el flanco del reloj.<\/li>\n\n\n\n<li>Las <strong>asignaciones blocking (<code>=<\/code>)<\/strong>, por otro lado, son como si el director le dijera al Bailar\u00edn 1 que se mueva, luego al Bailar\u00edn 2, y as\u00ed sucesivamente. El movimiento del Bailar\u00edn 2 depender\u00e1 de la <em>nueva<\/em> posici\u00f3n del Bailar\u00edn 1, no de la original. Esto rompe la ilusi\u00f3n de paralelismo y es \u00fatil para describir l\u00f3gica combinacional, donde las se\u00f1ales se propagan en cascada.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En resumen, el concepto m\u00e1s cr\u00edtico es que <strong>debes usar <code>non-blocking<\/code> (<code>&lt;=<\/code>) para modelar la concurrencia real del hardware s\u00edncrono<\/strong>, asegurando que el simulador secuencial se comporte como el hardware paralelo que est\u00e1s dise\u00f1ando. Fallar en esto es la causa n\u00famero uno de que una simulaci\u00f3n no coincida con el comportamiento del hardware real.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Y para terminar una an\u00e9cdota: <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>el Verilog original fue creado sin asignaciones non-blocking (<code>&lt;=<\/code>)<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Este no es un detalle menor; es una pieza clave de su historia que explica por qu\u00e9 el uso correcto de <code>non-blocking<\/code> es tan fundamental hoy en d\u00eda.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">El Caos del Verilog Primitivo<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">En sus inicios, Verilog solo contaba con la asignaci\u00f3n bloqueante (<code>=<\/code>). Esto provocaba un \u00abcaos de simulaci\u00f3n\u00bb al intentar modelar componentes s\u00edncronos, que son la base de casi toda la l\u00f3gica digital.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El problema se puede ilustrar con el ejemplo m\u00e1s simple: <strong>intentar intercambiar el valor de dos registros<\/strong> en un flanco de reloj.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>El intento fallido con el Verilog original:<\/strong> Si solo tienes asignaciones bloqueantes (<code>=<\/code>), el c\u00f3digo para un intercambio se ver\u00eda as\u00ed:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fragmento de c\u00f3digo<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: systemverilog; title: ; notranslate\" title=\"\">\n\/\/ ESTE C\u00d3DIGO NO FUNCIONA COMO UN INTERCAMBIO\nalways @(posedge clk) begin\n  a = b; \/\/ 1. &#039;a&#039; toma inmediatamente el valor de &#039;b&#039;.\n  b = a; \/\/ 2. &#039;b&#039; toma el valor de &#039;a&#039;, \u00a1pero &#039;a&#039; ya fue sobreescrito!\nend\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">En este caso, ambos registros terminar\u00edan con el valor original de <code>b<\/code>. El intercambio fracasa porque el simulador ejecuta las l\u00edneas en orden estricto, una detr\u00e1s de otra.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">La Soluci\u00f3n: El Nacimiento del <code>Non-Blocking<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Los ingenieros se dieron cuenta de que necesitaban una forma de decirle al simulador: \u00abCalcula todos los resultados que deben ocurrir en este flanco de reloj primero, y luego actualiza todas las se\u00f1ales a la vez\u00bb.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As\u00ed naci\u00f3 la asignaci\u00f3n non-blocking (<code>&lt;=<\/code>). Fue introducida espec\u00edficamente para resolver este defecto de nacimiento del lenguaje.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>El mismo intercambio, ahora funcionando correctamente:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fragmento de c\u00f3digo<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: systemverilog; title: ; notranslate\" title=\"\">\n\/\/ ESTE C\u00d3DIGO S\u00cd FUNCIONA\nalways @(posedge clk) begin\n  a &lt;= b; \/\/ Planifica que &#039;a&#039; tome el valor antiguo de &#039;b&#039;.\n  b &lt;= a; \/\/ Planifica que &#039;b&#039; tome el valor antiguo de &#039;a&#039;.\nend\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Aqu\u00ed, el simulador primero lee los valores antiguos de <code>a<\/code> y <code>b<\/code> y, solo despu\u00e9s, actualiza ambos registros. Esto imita perfectamente el comportamiento del hardware real, donde todos los flip-flops capturan sus datos en el mismo instante.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En conclusi\u00f3n, la asignaci\u00f3n <code>non-blocking<\/code> no fue una simple mejora, sino <strong>una correcci\u00f3n fundamental<\/strong> que permiti\u00f3 a Verilog modelar de forma fiable el hardware s\u00edncrono y convertirse en el est\u00e1ndar de la industria para el dise\u00f1o y la s\u00edntesis.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>El Concepto Clave: Paralelismo Real vs. Simulaci\u00f3n Secuencial El comentario m\u00e1s importante sobre la concurrencia en Verilog\/SystemVerilog es entender que, aunque est\u00e1s describiendo un hardware que es inherentemente paralelo, el simulador que ejecuta tu c\u00f3digo es un programa de software que funciona de manera secuencial. Esta diferencia es la fuente de los problemas m\u00e1s comunes, como las condiciones de carrera (race conditions), y la raz\u00f3n por la que existen las asignaciones blocking (=) y non-blocking (&lt;=). Analog\u00eda para entenderlo Imagina que est\u00e1s describiendo una coreograf\u00eda de baile con 100 bailarines. En la vida real, todos los bailarines realizan su quinto paso exactamente en el mismo instante. Eso es paralelismo real. Ahora, imagina que el director de la coreograf\u00eda (el simulador) solo puede dar instrucciones a un bailar\u00edn a la vez. Para simular que todos se mueven al mismo tiempo, el director debe seguir un proceso: \u00bfC\u00f3mo se refleja esto en el c\u00f3digo? En resumen, el concepto m\u00e1s cr\u00edtico es que debes usar non-blocking (&lt;=) para modelar la concurrencia real del hardware s\u00edncrono, asegurando que el simulador secuencial se comporte como el hardware paralelo que est\u00e1s dise\u00f1ando. Fallar en esto es la causa n\u00famero uno de que una simulaci\u00f3n no coincida con el comportamiento del hardware real. Y para terminar una an\u00e9cdota: el Verilog original fue creado sin asignaciones non-blocking (&lt;=). Este no es un detalle menor; es una pieza clave de su historia que explica por qu\u00e9 el uso correcto de non-blocking es tan fundamental hoy en d\u00eda. El Caos del Verilog Primitivo En sus inicios, Verilog solo contaba con la asignaci\u00f3n bloqueante (=). Esto provocaba un \u00abcaos de simulaci\u00f3n\u00bb al intentar modelar componentes s\u00edncronos, que son la base de casi toda la l\u00f3gica digital. El problema se puede ilustrar con el ejemplo m\u00e1s simple: intentar intercambiar el valor de dos registros en un flanco de reloj. El intento fallido con el Verilog original: Si solo tienes asignaciones bloqueantes (=), el c\u00f3digo para un intercambio se ver\u00eda as\u00ed: Fragmento de c\u00f3digo En este caso, ambos registros terminar\u00edan con el valor original de b. El intercambio fracasa porque el simulador ejecuta las l\u00edneas en orden estricto, una detr\u00e1s de otra. La Soluci\u00f3n: El Nacimiento del Non-Blocking Los ingenieros se dieron cuenta de que necesitaban una forma de decirle al simulador: \u00abCalcula todos los resultados que deben ocurrir en este flanco de reloj primero, y luego actualiza todas las se\u00f1ales a la vez\u00bb. As\u00ed naci\u00f3 la asignaci\u00f3n non-blocking (&lt;=). Fue introducida espec\u00edficamente para resolver este defecto de nacimiento del lenguaje. El mismo intercambio, ahora funcionando correctamente: Fragmento de c\u00f3digo Aqu\u00ed, el simulador primero lee los valores antiguos de a y b y, solo despu\u00e9s, actualiza ambos registros. Esto imita perfectamente el comportamiento del hardware real, donde todos los flip-flops capturan sus datos en el mismo instante. En conclusi\u00f3n, la asignaci\u00f3n non-blocking no fue una simple mejora, sino una correcci\u00f3n fundamental que permiti\u00f3 a Verilog modelar de forma fiable el hardware s\u00edncrono y convertirse en el est\u00e1ndar de la industria para el dise\u00f1o y la s\u00edntesis.<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","ub_ctt_via":"","footnotes":""},"class_list":["post-1762","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\/1762","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=1762"}],"version-history":[{"count":4,"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/pages\/1762\/revisions"}],"predecessor-version":[{"id":1769,"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=\/wp\/v2\/pages\/1762\/revisions\/1769"}],"wp:attachment":[{"href":"https:\/\/dsd.webs.upv.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1762"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}