{"id":12080,"date":"2016-01-29T15:34:39","date_gmt":"2016-01-29T22:34:39","guid":{"rendered":"https:\/\/blogs.mentor.com\/verificationhorizons\/?p=12080"},"modified":"2026-03-27T08:40:26","modified_gmt":"2026-03-27T12:40:26","slug":"whats-going-on-with-my-systemverilog-queue","status":"publish","type":"post","link":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/2016\/01\/29\/whats-going-on-with-my-systemverilog-queue\/","title":{"rendered":"What&#8217;s Going On With My SystemVerilog Queue?"},"content":{"rendered":"<p>I want my MTV!<\/p>\n<p>And while I&#8217;m at it, I&#8217;m also curious about what&#8217;s going on with my SystemVerilog queues. You too with your queues?<\/p>\n<p>What kinds of information do we want to know from our queues?<\/p>\n<p>How about what&#8217;s in them? Then how big they are. Maybe how many times they&#8217;ve been certain sizes (&#8220;this queue was empty for almost the entire simulation&#8221; &#8211; or &#8220;this queue was almost always larger than 100 elements&#8221;) &#8211; And then Why?<\/p>\n<p>&#8220;Why?&#8221; is the hard part. That&#8217;s other kinds of debug for another discussion&#8230; But we can certainly produce the report on queue size, activity and bins; let the queue debugging begin.<\/p>\n<p>What if we had a magic macro &#8211; a macro that would instrument a queue, so that we could better understand what it was doing?<\/p>\n<p>My Queue:<\/p>\n<pre style=\"padding-left: 30px\"><strong>int<\/strong> my_queue[$];\n\n<\/pre>\n<p>The &#8220;magic macro&#8221;:<\/p>\n<pre style=\"padding-left: 30px\">`QUEUE_VIEW_C(<strong>int<\/strong>, my_queue)\n\n<\/pre>\n<p>The magic macro takes two arguments &#8211; the type contained in the queue (int), and the queue name (my_queue). That&#8217;s *really* easy to use. The only change that is needed is to add this magic macro where there is a queue that needs some monitoring.<\/p>\n<p>OK. What kind of information do we really want in our reports?<\/p>\n<pre>  Current Queue Size\n  Maximum Queue Size so far\n  The top 3 elements in the Queue (or the last 3, or both)\n  Queue Contents (the whole thing)\n  Queue size bins\n\n<\/pre>\n<p>Inside the macro we&#8217;ll build a queue monitor. It can monitor many things &#8211; for example in pseudocode, our queue monitor:<\/p>\n<pre style=\"padding-left: 30px\"> 37 <strong>task<\/strong> monitor (<strong>ref<\/strong> T q[$]);\n 38   <strong>forever<\/strong> <strong>begin<\/strong>\n 39     @(q.size change);\n 40     size_bins[q.size()]++;\n 41     <strong>if<\/strong> (q.size() &gt; maxsize) maxsize = q.size();\n 42     f0 = q[0];\n 43     f1 = q[1];\n 44     f2 = q[2];\n 45     $display(\"@%t: %s : size=%0d %0d %0d %0d q=[%p]\", \n 46       $time, name, q.size(), f0, f1, f2, q);\n 47   <strong>end<\/strong>\n 48 <strong>endtask\n\n<\/strong><\/pre>\n<p>Line 37 provides the actual queue as a reference argument. That&#8217;s how the queue will be tracked.<br \/>\nLine 38 and 39 provide an infinite loop which waits for the queue to change size.<br \/>\nOnce the queue changes size, Line 40 does the binning. In one line it increments the bin for the current queue size.<br \/>\nLine 41 captures the maximum size that this queue has attained.<br \/>\nLine 42, 43 and 44 capture the top of the queue, the second and the third elements (with range checking removed).<br \/>\nLine 45 just prints a nice snapshot of the queue: the current time, the queue viewer name, the size of the queue, the top 3 values, and finally using the magic &#8220;%p&#8221;, it prints the entire queue.<\/p>\n<p>Here&#8217;s some output from line 45:<\/p>\n<pre> # @ 123: qview_6.c_flow_q : size=0 0 0 0 q=['{}]\n # @ 152: qview_6.c_flow_q : size=1 2 0 0 q=['{2}]\n # @ 160: qview_6.c_flow_q : size=2 2 2 0 q=['{2, 2}]\n # @ 168: qview_6.c_flow_q : size=3 2 2 2 q=['{2, 2, 2}]\n # @ 181: qview_6.c_flow_q : size=4 6 2 2 q=['{6, 2, 2, 2}]\n # @ 188: qview_6.c_flow_q : size=5 2 6 2 q=['{2, 6, 2, 2, 2}]\n # @ 199: qview_6.c_flow_q : size=6 8 2 6 q=['{8, 2, 6, 2, 2, 2}]\n # @ 206: qview_6.c_flow_q : size=7 4 8 2 q=['{4, 8, 2, 6, 2, 2, 2}]\n # @ 214: qview_6.c_flow_q : size=8 2 4 8 q=['{2, 4, 8, 2, 6, 2, 2, 2}]\n # @ 223: qview_6.c_flow_q : size=9 6 2 4 q=['{6, 2, 4, 8, 2, 6, 2, 2, 2}]\n # @ 233: qview_6.c_flow_q : size=8 6 2 4 q=['{6, 2, 4, 8, 2, 6, 2, 2}]\n # @ 235: qview_6.c_flow_q : size=7 6 2 4 q=['{6, 2, 4, 8, 2, 6, 2}]\n # @ 236: qview_6.c_flow_q : size=8 2 6 2 q=['{2, 6, 2, 4, 8, 2, 6, 2}]\n # @ 238: qview_6.c_flow_q : size=7 2 6 2 q=['{2, 6, 2, 4, 8, 2, 6}]\n # @ 240: qview_6.c_flow_q : size=6 2 6 2 q=['{2, 6, 2, 4, 8, 2}]\n # @ 242: qview_6.c_flow_q : size=5 2 6 2 q=['{2, 6, 2, 4, 8}]\n # @ 245: qview_6.c_flow_q : size=4 2 6 2 q=['{2, 6, 2, 4}]\n # @ 248: qview_6.c_flow_q : size=3 2 6 2 q=['{2, 6, 2}]\n # @ 249: qview_6.c_flow_q : size=2 2 6 0 q=['{2, 6}]\n # @ 251: qview_6.c_flow_q : size=1 2 0 0 q=['{2}]\n # @ 254: qview_6.c_flow_q : size=0 0 0 0 q=['{}]\n # @ 317: qview_6.c_flow_q : size=1 7 0 0 q=['{7}]\n # @ 330: qview_6.c_flow_q : size=2 5 7 0 q=['{5, 7}]\n # @ 338: qview_6.c_flow_q : size=3 2 5 7 q=['{2, 5, 7}]\n # @ 345: qview_6.c_flow_q : size=4 1 2 5 q=['{1, 2, 5, 7}]\n # @ 355: qview_6.c_flow_q : size=5 3 1 2 q=['{3, 1, 2, 5, 7}]\n # @ 368: qview_6.c_flow_q : size=6 7 3 1 q=['{7, 3, 1, 2, 5, 7}]\n # @ 372: qview_6.c_flow_q : size=5 7 3 1 q=['{7, 3, 1, 2, 5}]\n # @ 373: qview_6.c_flow_q : size=4 7 3 1 q=['{7, 3, 1, 2}]\n # @ 375: qview_6.c_flow_q : size=3 7 3 1 q=['{7, 3, 1}]\n # @ 377: qview_6.c_flow_q : size=2 7 3 0 q=['{7, 3}]\n # @ 379: qview_6.c_flow_q : size=1 7 0 0 q=['{7}]\n # @ 381: qview_6.c_flow_q : size=0 0 0 0 q=['{}]\n\n<\/pre>\n<p>And finally, at the end of simulation, I might want a report about the bins<\/p>\n<pre style=\"padding-left: 30px\"> 50 <strong>function<\/strong> <strong>void<\/strong> summary(<strong>ref<\/strong> T q[$]);\n 51   $display(\"@%t: %s : maxsize=%0d currentsize=%0d q=[%p]\", \n 52     $time, name, maxsize, q.<strong>size<\/strong>(), q);\n 53   $display(\"@%t: %s : sizebins=%p\", $time, name, size_bins);\n 54 <strong>endfunction\n\n<\/strong><\/pre>\n<pre style=\"padding-left: 30px\"> # @ 10000: qview_2.c_flow_q : maxsize=10 currentsize=2 q=['{2, 2}]\n # @ 10000: qview_2.c_flow_q : sizebins='{0:98, 1:181, 2:171, 3:167, 4:152, 5:136, 6:121, 7:89, 8:45, 9:14, 10:1 }\n\n<\/pre>\n<p>That&#8217;s a pretty boring report on bins. How about the best kind of summary or report; a graph. It&#8217;s easy to throw the bin results into a Google Doc Spreadsheet and draw a graph.<\/p>\n<figure id=\"attachment_12081\" aria-describedby=\"caption-attachment-12081\" style=\"width: 533px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2016\/01\/Blog-2.5-QueueBins.jpg\" rel=\"attachment wp-att-12081\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-12081\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2016\/01\/Blog-2.5-QueueBins.jpg\" alt=\"Bins for Queue Size\" width=\"533\" height=\"253\" \/><\/a><figcaption id=\"caption-attachment-12081\" class=\"wp-caption-text\"><strong><em>Bins for Queue Size<\/em><\/strong><\/figcaption><\/figure>\n<p>Or maybe just put the &#8220;Queue Viewer&#8221; for the queue &#8220;c_flow_q&#8221; into the waveform window<\/p>\n<figure id=\"attachment_12087\" aria-describedby=\"caption-attachment-12087\" style=\"width: 753px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2016\/01\/Blog-2.5-QueueViewer-Waveform.jpg\" rel=\"attachment wp-att-12087\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-12087\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2016\/01\/Blog-2.5-QueueViewer-Waveform.jpg\" alt=\"Queue Viewer for the c_flow_q variable\" width=\"753\" height=\"300\" \/><\/a><figcaption id=\"caption-attachment-12087\" class=\"wp-caption-text\"><strong><em>Queue Viewer for the c_flow_q variable<\/em><\/strong><\/figcaption><\/figure>\n<p>Hopefully this note wets your appetite for more kinds of debug. A magic macro &#8211; a one line change that provides lots of visibility.<\/p>\n<p>How do you debug your SystemVerilog queues? What other kinds of information are you interested in?<\/p>\n<p>Catch me at DVCON 2016 &#8211; we can talk debug some more, I&#8217;ll be in the Mentor Booth &#8211; #501.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I want my MTV! And while I&#8217;m at it, I&#8217;m also curious about what&#8217;s going on with my SystemVerilog queues&#8230;.<\/p>\n","protected":false},"author":71540,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spanish_translation":"","french_translation":"","german_translation":"","italian_translation":"","polish_translation":"","japanese_translation":"","chinese_translation":"","footnotes":""},"categories":[1],"tags":[751],"industry":[],"product":[],"coauthors":[],"class_list":["post-12080","post","type-post","status-publish","format-standard","hentry","category-news","tag-systemverilog"],"_links":{"self":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/12080","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/users\/71540"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/comments?post=12080"}],"version-history":[{"count":1,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/12080\/revisions"}],"predecessor-version":[{"id":14486,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/12080\/revisions\/14486"}],"wp:attachment":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/media?parent=12080"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/categories?post=12080"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/tags?post=12080"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/industry?post=12080"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/product?post=12080"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/coauthors?post=12080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}