Simulation Behaviour of Associative Array with 64 Bit Index - QuestaSIM


Hi All,

This post is related to unexpected Simulation Behaviour with an Associative Array having 64 Bit Index in QuestaSIM. I had faced this problem and thought many others may have faced it also. So it is worth sharing the solution over here.

NOTE :- This behaviour was observed in QuestaSIM 10.2. It may or may not be observed in the same or other versions of QuestaSIM.

SAMPLE CODE

Here is the sample code :

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

`define key 64
program p;
  int loop_count;
  int iteration; // Try with more than 8 to get the Errors ;)
  dword_memory_st MEMORY[bit [`key-1:0]];
  bit [`key-1:0] st = 'hffff_ffff_ffff_fffa;
  bit [`key-1:0] ft = 'hffff_ffff_ffff_ffff;
  bit [`key-1:0] temp;
  bit [`key:0] max_memory_address = (1 << `key);
  bit bounded_address_used = 0;

  initial
  begin
    void'($value$plusargs("ITE=%d", iteration));
    $display("Iteration - %0d", iteration);
    void'($value$plusargs("BOU=%b", bounded_address_used));
    $display("Bounded Address Used - %0b", bounded_address_used);
    $display("Associative Array Index Size - %0d", `key);
    $display("***** ***** ****** ****** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****");
    forever
    begin
      for(bit[`key-1:0] i=0; i<iteration; i++)
      begin
        if(bounded_address_used)
          MEMORY[bounded_address(st+i)] = i + (loop_count*10);
        else
          MEMORY[st+i] = i + (loop_count*10);
         $display("MEMORY[%0h] exists = %0b, MEMORY[%0h] = %0h", st+i, MEMORY.exists(st+i), st+i, MEMORY[st+i]);
        if((st+i) == ft)
          $display("Rollover Happened");
      end
      loop_count++;
      if(loop_count == 3)
       break;
       $display("***** ***** ****** ****** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****");
    end
    $display("***** ***** ****** ****** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****");
  end

  function bit[`key-1:0] bounded_address(input bit[`key:0] addr);
    MEMORY.delete(addr);
    bounded_address = (addr % max_memory_address);
  endfunction : bounded_address
endprogram

PROBLEM :

Now are the results of this sample code :

Result with 63 Bit Index

Result with 64 Bit Index

So as shown in the image, for 63 Bit Index (Or any Index less than 64 Bits), things work perfectly & after rollover also, it works properly. But for 64 Bit Index, after rollover, tool does not allow to overwrite existing indexes (FFFF_FFFF_FFFF_FFFA - 0000_0000_0000_0000) or store new indexes (0000_0000_0000_0001 - 0000_0000_0000_0003)

SOLUTION

Before writing/overwriting value for any index, first delete it.

This solution works, because of unexpected Simulator Behaviour, For 64 Bit index, after Rollover, simulator considers every index exists, but it does not let any index to be overwritten. (That's why for 64 Bit Index Result, Displays of exist method for each index, gives value 1, but while reading from that index, it gives Warning of Nonexistent Associative Array).

Function bounded_address in the sample code, does the same thing.

Here are the result of this sample code with use of bounded_address method.

Result with 63 Bit Index & bounded_address Method Usage

Result with 64 Bit Index & bounded_address Method Usage

Please feel free to comment on this post or for any suggestions. Your suggestions are always welcomed.

Comments

Popular posts from this blog

SystemVerilog Event Regions

Standard Cell Based ASIC Design Flow

Verilog Event Regions