-1

I write an simple ALU in verilog like this:

input [15:0] in;
output reg [15:0] out;

reg [15:0] r [0:7];
reg [3:0] opcode;
reg [3:0] outreg;
reg [3:0] var1, var2;
reg [15:0] a1, a2;

parameter STO = 4'b0000;
parameter ADD = 4'b0001;
parameter MUL = 4'b0010;

always @ (in)
begin

    opcode = in [15:12]; 
    outreg = in [11:8]; 
    var1 = in [7:4];
    var2 = in [3:0];
    a1 = (var1[3]) ? var1[2:0] : r[var1];
    a2 = (var2[3]) ? var2[2:0] : r[var2];
    case (opcode)
        STO: begin r[outreg] = a1; end 
        ADD: begin r[outreg] = a1 + a2; end
        MUL: begin r[outreg] = a1 * a2; end
        SUB: begin r[outreg] = a1 - a2; end
        DIV: begin r[outreg] = a1 / a2; end
        default: begin $display("error input"); end
    endcase
    out = r[outreg];
end

And in test bench, I give such input:

initial begin
$monitor("%d", out);
in = 16'h0280; #10; // STO r2, #0
in = 16'h00d0; #10; // STO r0, #5
in = 16'h01c0; #10; // STO r1, #4
in = 16'h2110; #10; // MUL r1, r1, r0
in = 16'h1221; #10; // ADD r2, r2, r1
end

the result should be (as I predict)

0
5
4
20
20

Is that right?

But modelsim shows the answer as follows:

0
5
4
20

and no output of

ADD r2, r2, r0

Is my prediction of the answer right? Or what's the problem make that happens?

Zh.Z
  • 3
  • 4
  • Thanks, I only post key part of my code, SUB/DIV is not used in testing, I forgot delete those two lines, I can handle other problems. After changing `$monitor`, two lines of `20` displayed. But why only one `20` shows with `$monitor("%d", out)` ? – Zh.Z Sep 23 '16 at 20:27
  • Look at my answer! – Thomas B Preusser Sep 23 '16 at 20:43

2 Answers2

0

$monitor displays the values of its parameters EVERY time ANY of its parameter changes value. How can you expect two lines of 20?

Ref

Thomas B Preusser
  • 1,159
  • 5
  • 10
0
$monitor("%d", out);

is equivalent to writing this as a separate process.

always @(out)
    $strobe("%d", out); // like $display except prints only once at the end of the time slot

and

   $monitor("%h %d", in,out);

is equivalent to writing this as a separate process.

always @(in or out)
    $strobe("%h %d", in,out); // like $display except prints only once at the end of the time slot

As a general rule, $monitor is only for very simple cases and $display or $strobe should be used instead.

dave_59
  • 39,096
  • 3
  • 24
  • 63