1

Normally in Associative Array, Rollover issue is taken care by the tool. But in QuestaSIM, I am facing the issue, like if key of the Associative Array is 64 bit variable, then after overflow, it does not store data properly.

Suppose index is 65'h1_0000_0000_0000_0002, then ideally it should store this data with index 64'h2, because of the size of the key (Even it does that, as I have printed whole Associative Array and Output of exists method also), but still I am getting Warning of Nonexistent Associative Array (as shown in the Output).

Here is the Code : ( I have tried bounded_address method, with 3 different logic, but in all case I am getting same results)

typedef struct packed {
  bit [7:0] data;
  bit        valid;
} dword_memory_st;

program p;
  dword_memory_st MEMORY[bit [63:0]];
  bit [63:0] st = 64'hffff_ffff_ffff_fffa;
  bit [63:0] temp;
  bit [64:0] max_memory_address = (1 << 64);

  initial
  begin
    for(bit[63:0] i = 0; i<=10; i++)
    begin
      $display("***** ***** ***** *****");
      temp = bounded_address(st+i);
      MEMORY[temp] = i;
      $display("MEMORY['h%0h].exists - %0b MEMORY['h%0h] = %0d", temp, MEMORY.exists(temp), temp, MEMORY[temp]);
      $display("MEMORY - %p", MEMORY);
      $display("***** ***** ***** *****");
    end
  end

  function bit[63:0] bounded_address(input  bit [64:0] addr);
    /* Option - 1
    bounded_address = (addr % max_memory_address);
    $display("KARAN bounded_address - %0h, addr - %0h, max_memory_address - %0h", bounded_address, addr, max_memory_address);
    */

    /* Option - 2
    $display("KARAN addr - %0h, max_memory_address - %0h", addr, max_memory_address);
    if(addr > (max_memory_address - 1))
    begin
      $display("Greater than max_memory_address - 1");
      return (addr - max_memory_address);
    end
    else
    begin
      $display("Less than max_memory_address - 1");
      return addr;
    end
    */

    // Option - 3
    addr[64] = 0;
    $display("KARAN addr - %0h, max_memory_address - %0h", addr, max_memory_address);
    return addr;
  endfunction : bounded_address  
endprogram

/* Output on QuestaSIM - 
# ***** ***** ***** *****
# KARAN addr - fffffffffffffffa, max_memory_address - 10000000000000000
# MEMORY['hfffffffffffffffa].exists - 1 MEMORY['hfffffffffffffffa] = 0
# MEMORY - '{18446744073709551610:'{data:0, valid:0} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - fffffffffffffffb, max_memory_address - 10000000000000000
# MEMORY['hfffffffffffffffb].exists - 1 MEMORY['hfffffffffffffffb] = 1
# MEMORY - '{18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - fffffffffffffffc, max_memory_address - 10000000000000000
# MEMORY['hfffffffffffffffc].exists - 1 MEMORY['hfffffffffffffffc] = 2
# MEMORY - '{18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - fffffffffffffffd, max_memory_address - 10000000000000000
# MEMORY['hfffffffffffffffd].exists - 1 MEMORY['hfffffffffffffffd] = 3
# MEMORY - '{18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0}, 18446744073709551613:'{data:1, valid:1} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - fffffffffffffffe, max_memory_address - 10000000000000000
# MEMORY['hfffffffffffffffe].exists - 1 MEMORY['hfffffffffffffffe] = 4
# MEMORY - '{18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0}, 18446744073709551613:'{data:1, valid:1}, 18446744073709551614:'{data:2, valid:0} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - ffffffffffffffff, max_memory_address - 10000000000000000
# MEMORY['hffffffffffffffff].exists - 1 MEMORY['hffffffffffffffff] = 5
# MEMORY - '{18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0}, 18446744073709551613:'{data:1, valid:1}, 18446744073709551614:'{data:2, valid:0}, 18446744073709551615:'{data:2, valid:1} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - 0, max_memory_address - 10000000000000000
# MEMORY['h0].exists - 1 MEMORY['h0] = 6
# MEMORY - '{0:'{data:3, valid:0}, 18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0}, 18446744073709551613:'{data:1, valid:1}, 18446744073709551614:'{data:2, valid:0}, 18446744073709551615:'{data:2, valid:1} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - 1, max_memory_address - 10000000000000000
# ** Warning: (vsim-3829) string_based_object_creation.sv(93): Non-existent associative array entry. Returning default value.
# MEMORY['h1].exists - 1 MEMORY['h1] = 0
# MEMORY - '{0:'{data:3, valid:0}, 1:'{data:3, valid:1}, 18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0}, 18446744073709551613:'{data:1, valid:1}, 18446744073709551614:'{data:2, valid:0}, 18446744073709551615:'{data:2, valid:1} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - 2, max_memory_address - 10000000000000000
# ** Warning: (vsim-3829) string_based_object_creation.sv(93): Non-existent associative array entry. Returning default value.
# MEMORY['h2].exists - 1 MEMORY['h2] = 0
# MEMORY - '{0:'{data:3, valid:0}, 1:'{data:3, valid:1}, 2:'{data:4, valid:0}, 18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0}, 18446744073709551613:'{data:1, valid:1}, 18446744073709551614:'{data:2, valid:0}, 18446744073709551615:'{data:2, valid:1} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - 3, max_memory_address - 10000000000000000
# ** Warning: (vsim-3829) string_based_object_creation.sv(93): Non-existent associative array entry. Returning default value.
# MEMORY['h3].exists - 1 MEMORY['h3] = 0
# MEMORY - '{0:'{data:3, valid:0}, 1:'{data:3, valid:1}, 2:'{data:4, valid:0}, 3:'{data:4, valid:1}, 18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0}, 18446744073709551613:'{data:1, valid:1}, 18446744073709551614:'{data:2, valid:0}, 18446744073709551615:'{data:2, valid:1} }
# ***** ***** ***** *****
# ***** ***** ***** *****
# KARAN addr - 4, max_memory_address - 10000000000000000
# ** Warning: (vsim-3829) string_based_object_creation.sv(93): Non-existent associative array entry. Returning default value.
# MEMORY['h4].exists - 1 MEMORY['h4] = 0
# MEMORY - '{0:'{data:3, valid:0}, 1:'{data:3, valid:1}, 2:'{data:4, valid:0}, 3:'{data:4, valid:1}, 4:'{data:5, valid:0}, 18446744073709551610:'{data:0, valid:0}, 18446744073709551611:'{data:0, valid:1}, 18446744073709551612:'{data:1, valid:0}, 18446744073709551613:'{data:1, valid:1}, 18446744073709551614:'{data:2, valid:0}, 18446744073709551615:'{data:2, valid:1} }
# ***** ***** ***** *****
*/
Greg
  • 18,111
  • 5
  • 46
  • 68
Karan Shah
  • 1,912
  • 1
  • 29
  • 42
  • Looks like a bug in QuestaSim. The out of bound bit should have been truncated regardless. An explicit range may help. Try changing `return addr;` to `return addr[63:0];` in your bounded_address function. – Greg Aug 04 '15 at 18:42
  • @Greg : After doing addr[63:0], still the results are same. I have printed that Associative Array also, so it seems like while storing the data, it behaves properly, but while reading, in $display with same temp variable, it is not able to find that index. – Karan Shah Aug 05 '15 at 04:49
  • @Greg : I have found one solution, and posted the answer, but I don't know the need of using delete method, so it would be grateful, if you can help me to understand the need of that. – Karan Shah Aug 05 '15 at 06:45
  • 1
    When declaring sparse memory with an associative array, you should assign it a default value `dword_memory_st MEMORY[bit [63:0]] = '{default:0};` – dave_59 Aug 05 '15 at 07:22
  • @dave_59 : Thanks. Default value should be used in associative array. Can you please help me to understand the need of .delete method in the Answer? – Karan Shah Aug 05 '15 at 09:00

1 Answers1

1

I have found the answer. It is a QuestaSIM bug, but this solution can manipulate tool to store data properly without any warning.

Here is the Code, change in bounded_address method :

function bit[63:0] bounded_address(input  bit [64:0] addr);
  MEMORY.delete(addr); // Dont know why, but after overflow, if we delete that index, than it works.
  bounded_address = (addr % max_memory_address);
  $display("KARAN bounded_address - %0h, addr - %0h, max_memory_address - %0h", bounded_address, addr, max_memory_address);
endfunction : bounded_address
Karan Shah
  • 1,912
  • 1
  • 29
  • 42
  • This seems like a Questa bug, but only if the address range is 64:0, any other ranges work. Don't know why the deleting the element first works, but use the '{default:0} initialization also works, and is the preferred coding style anyways. – dave_59 Aug 05 '15 at 16:23
  • @dave_59 : I have observed that for 64 bit index, after rollover, questa does not allow to overwrite even previously existed address (like 64"hffff_ffff_ffff_fffe on any other in previous example). And so if we delete them and again assign them, than issue of overwriting does not occur. – Karan Shah Aug 05 '15 at 16:32