5

I am new to verilog and I understand it is not a sequential language. So, I wanted to ask is there some way to display results in a module after some execution?Because display should always be inside initial block and so there is no way I can use display for debugging purposes. Here is a sample code which may better explain my problem-

module A(a,b,c);
    input a,b;
    output c;

    assign c=a&b;

    initial
      $display("%b",c);
endmodule

module testbench11;
   reg a,b;
   wire c;

   A a1(a,b,c);

   initial
      $monitor(,$time,"a=%b,b=%b,c=%b",a,b,c);

   initial
      begin
         #0 a=1'b0;b=1'b0;         
         #3 a=1'b0;b=1'b0; 
         #3 a=1'b0;b=1'b0; 
      end
endmodule

So I want to display the result of c after every time instance so as to check whether I am getting desired output. It may seem to display results at the end in this case, but in some complex problems I wanted to use display for debugging purposes just as I use printf in C. Is there some way to do that in verilog?

  • Depending on how you code the module, `$display` might or might not work for what you want to do. Your current use of `$monitor` will certainly inform you whenever any of `a`, `b` or `c` (which are linked to those signals of you module) change, which is probably good enough. Without a better example, the exact form of printing that is best is very difficult to determine. – Unn Nov 11 '15 at 15:14

2 Answers2

5

Because display should always be inside initial block and so there is no way I can use display for debugging purposes.

I am not sure where you got this from, it is the same as nearly everything but assign in that it must be used inside a block, intial or always.

To use it to debug inside the module:

module A(a,b,c);
  input  a,b;
  output c;

  assign c = a&b;

  always @*
    $display("%b",c);
endmodule

It is best to display and check from the top level keeping the module code clean. to use display in the testench you can do:

The same format as inside the module:

always @* begin
  $display("%b",c);
end

Or to know you are displaying after each stimulus step:

initial begin
  #0 a=1'b0;b=1'b0;         
  #1 $display("%b",c);

  #3 a=1'b0;b=1'b0; 
  #1 $display("%b",c);

  #3 a=1'b0;b=1'b0; 
  #1 $display("%b",c);
end 
Morgan
  • 19,934
  • 8
  • 58
  • 84
5

Verilog/SystemVerilog contains a well organized event queue. All the statements in each and every time stamp executes according to this queue. Following are some of the different display system tasks.

  • $display executes in ACTIVE region, so if there is any non-blocking assignment(which executes in INACTIVE region), it won't be shown by $display. This displays a single output line.

  • $write also executes in ACTIVE region, but an explicit call to newline character(\n) is required to insert another line. This system task is generally used when you want to display Multidimensional array using for loop. This is similar to display except (\n) character.

  • $strobe executes in MONITOR/POSTPONED region, that is, at the end of time stamp. Hence the updated value is shown by $strobe.

  • $monitor displays every time one of its display parameters changes. Only one $monitor per Simulation is to be used. Monitor, as the name suggests, monitors the signals continuously and executes if any signal value changes.

For your code, to display at various points, following change of code can be done.

    initial
    #5 $display("%b",c);  // display after some arbitrary time.

    initial
    begin
    repeat(5)
    begin 
     wait(c);
     $display("%b",c);  // display after   change in c 5 times.
    end
    end

    initial
    begin
    forever
    begin 
     #1;
     $display("%b",c);  // display c at every timestamp
    end
    end

    always @(c)
    $display("%b",c);  // display after any change in c

    always @(a,b,c)
    $display("%b",c);  // display after any change in a or b or c

For displaying at every change, $monitor is useful. $display can be used as above but this will make your code messy. Just remember that there must be only one $monitor in your code. There is no such limit in $display.

These are just some of the methods, many other are available. Further information can be found out at this and this links.

sharvil111
  • 4,301
  • 1
  • 14
  • 29
  • `$strobe` and `$monitor` is in the **monitor event region** in Verilog. IEEE1364-1995 §5.3, IEEE1364-2001 §5.3, & IEEE1364-2005 §11.3. SystemVerilog the region got renamed to **postponed event region**, [IEEE1800-2012] §4.4. **Inactive event region** for explicit `#0` delay (citation in the same sections as the monitor region) – Greg Nov 11 '15 at 17:49
  • @Greg yeah, I have made a mistake here. Just got confused in **Inactive** and **Postponed** region. I've edited my answer accordingly. Thanks for the pointers. – sharvil111 Nov 11 '15 at 18:02