Search code examples
verilogsystem-veriloghdl

What is the difference between these 2 counters?


What is the difference between these two statements if they are inside an always_ff @(posedge clk) block?

if(~Intf.DataFull) begin
   rWrPageCntr <= rWrPageCntr - 1;
end

vs

rWrPageCntr <= rWrPageCntr - ~Intf.DataFull;

Solution

  • Under the following assumptions regarding signal bit widths, there is a big difference:

    module tb;
    
    bit DataFull, clk;
    bit [2:0] rWrPageCntr;
    bit [2:0] rWrPageCntr2;
    
    always #5 clk++;
    
    always_ff @(posedge clk)
        if(~DataFull) begin
            rWrPageCntr <= rWrPageCntr - 1;
        end
    
    always_ff @(posedge clk)
            rWrPageCntr2 <= rWrPageCntr2 - ~DataFull;
               
    always @(negedge clk) $display("full=%b %d %d", DataFull, rWrPageCntr, rWrPageCntr2);
    
    initial begin
        DataFull = 1;
        #150;
        DataFull = 0;
        #150 $finish;
    end
    
    endmodule
    

    Outputs:

    full=1 0 2
    full=1 0 4
    full=1 0 6
    full=1 0 0
    full=1 0 2
    full=1 0 4
    full=1 0 6
    full=1 0 0
    full=1 0 2
    full=1 0 4
    full=1 0 6
    full=1 0 0
    full=1 0 2
    full=1 0 4
    full=0 0 6
    full=0 7 7
    full=0 6 0
    full=0 5 1
    full=0 4 2
    full=0 3 3
    full=0 2 4
    full=0 1 5
    full=0 0 6
    full=0 7 7
    full=0 6 0
    full=0 5 1
    full=0 4 2
    full=0 3 3
    full=0 2 4
    

    The first example behaves as you'd expect, but the second example is more complicated.

    In your second example, before the subtraction, DataFull will be extended to 3 bits, then it will be bitwise inverted, yielding 7 and 6. When DataFull=0, ~DataFull=7. When DataFull=1, ~DataFull=6.