通常在关联数组中,工具会处理滚动问题。但是在QuestaSIM中,我面临的问题是,如果关联数组的键是64位变量,那么在溢出之后,它就不能正确存储数据。
假设索引是65'h1_0000_0000_0000_0002
,那么理想情况下它应该用索引64'h2
来存储这个数据,因为密钥的大小(即使这样做,因为我已经打印了整个关联数组和输出存在方法也),但我仍然得到不存在关联数组的警告(如输出中所示)。
这是代码:(我尝试过bounded_address方法,有3种不同的逻辑,但在所有情况下我都得到相同的结果)
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} }
# ***** ***** ***** *****
*/
答案 0 :(得分:1)
我找到了答案。这是一个QuestaSIM错误,但是这个解决方案可以操纵工具来正确存储数据而不会发出任何警告。
这是代码,bounded_address方法的变化:
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