Unsigned subtraction followed by comparison

I was testing a piece of code which involved using two reg types in a for loop.


module test;
  
  reg [15:0] start1_addr = 16'h1000;
  reg [15:0] end1_addr = 16'h07FF;
  
  initial
    begin
      for(int i=0; i<(end1_addr-start1_addr+1); i++)
        begin
          $display("Value of i = %d", i);
        end
    end
  
endmodule

In the above case, my loop is going through lot of iterations.

However, when I use type casting to change the following line from:


      for(int i=0; i<(end1_addr-start1_addr+1); i++)

To:


      for(int i=0; i<int'(end1_addr-start1_addr+1); i++)

my purpose is achieved.

It will be great if someone can explain why type casting is working?

In reply to prashantg:

The problem with your original code is you are mixing unsigned and signed types, and the result is unsigned—a very large number. Adding a cast to int results in a negative number.

In reply to dave_59:

In reply to prashantg:
The problem with your original code is you are mixing unsigned and signed types, and the result is unsigned—a very large number. Adding a cast to int results in a negative number.

Dave, i is a signed 32-bit int type. Is it because of the reg subtraction in the comparison? As a coding practice, how do you feel about the subtraction of reg types?

In reply to prashantg:

There’s no problem with subtraction of unsigned types until you get to an underflow case like yours. You can either check that the start address is larger than the end address first, or do the cast to int.

BTW, in SystemVerilog use the logic keyword in place of reg.