在 specman 中从无符号到有符号的动态转换
Dynamic casting from unsigned to signed in specman
我正在尝试使用 "as_a(int(bits:))" 在 specman 中将无符号数转换为有符号数。
我的问题是这是动态的,从一个数字变为另一个数字。
当尝试将变量传递给时,我收到一条错误消息,指出只能使用常量。
有办法克服这个问题吗?我试过使用宏,但也没有用。
我想我明白你想做什么:你有一些数字作为 uint 并且不知何故知道它的 "natural" 位大小,然后你需要将它转换为无符号的方式,前导 0s 或 1s根据该位大小是正确的。对吗?
我不明白如何为整数使用可变位大小。如果您想使用本机 'e' 转换,似乎唯一可行的解决方案是对所有可能的位大小转换进行硬编码,并根据位大小变量使用相关案例。它可以使用宏以相对少量的代码生成。
但也许您真的不需要 as_a()?您可以使用位移位实现正确的符号扩展:将您的变量转换为 int,然后以 32 减去 bit_size 的距离来回移动它。最后,你应该得到你期望的 int 值:如果它对你的位大小是正的,它将是相同的正数,如果它应该是负数,它将是正确值的负数。
以下函数将把 unsigned int(bits:*) 转换为有符号的给定位数:
unsigned_to_signed(uval : int(bits:*), sz : uint, fix_range : bool = FALSE) : int(bits:*) is {
assert(sz > 0) else error("unsigned_to_signed error: size must be possitive !");
var max_val : int(bits:*) = 1.as_a(int(bits:*)) << sz;
if (fix_range && uval >= max_val) { // fix uval to be in the range
uval = (uval & (max_val -1));
};
assert (uval >= 0 && uval < max_val) else error(appendf("unsigned_to_signed error: uval is not in a valid range for int(bits:%u) !",sz));
var sign_bit : int(bits:*) = 1.as_a(int(bits:*)) << (sz-1);
if (uval < sign_bit) {
return uval;
} else {
return -(max_val-uval);
};
};
使用示例:
print unsigned_to_signed( (1).as_a(uint) , 8);
print unsigned_to_signed( (-1).as_a(uint(bits:8)) , 8);
print unsigned_to_signed( (127).as_a(uint) , 8);
print unsigned_to_signed( (-128).as_a(uint(bits:8)) , 8);
print unsigned_to_signed( (237).as_a(uint) , 9);
print unsigned_to_signed( (-237).as_a(uint(bits:9)) , 9);
print unsigned_to_signed( (-237).as_a(uint) , 9, TRUE);
我正在尝试使用 "as_a(int(bits:))" 在 specman 中将无符号数转换为有符号数。 我的问题是这是动态的,从一个数字变为另一个数字。
当尝试将变量传递给时,我收到一条错误消息,指出只能使用常量。
有办法克服这个问题吗?我试过使用宏,但也没有用。
我想我明白你想做什么:你有一些数字作为 uint 并且不知何故知道它的 "natural" 位大小,然后你需要将它转换为无符号的方式,前导 0s 或 1s根据该位大小是正确的。对吗?
我不明白如何为整数使用可变位大小。如果您想使用本机 'e' 转换,似乎唯一可行的解决方案是对所有可能的位大小转换进行硬编码,并根据位大小变量使用相关案例。它可以使用宏以相对少量的代码生成。
但也许您真的不需要 as_a()?您可以使用位移位实现正确的符号扩展:将您的变量转换为 int,然后以 32 减去 bit_size 的距离来回移动它。最后,你应该得到你期望的 int 值:如果它对你的位大小是正的,它将是相同的正数,如果它应该是负数,它将是正确值的负数。
以下函数将把 unsigned int(bits:*) 转换为有符号的给定位数:
unsigned_to_signed(uval : int(bits:*), sz : uint, fix_range : bool = FALSE) : int(bits:*) is {
assert(sz > 0) else error("unsigned_to_signed error: size must be possitive !");
var max_val : int(bits:*) = 1.as_a(int(bits:*)) << sz;
if (fix_range && uval >= max_val) { // fix uval to be in the range
uval = (uval & (max_val -1));
};
assert (uval >= 0 && uval < max_val) else error(appendf("unsigned_to_signed error: uval is not in a valid range for int(bits:%u) !",sz));
var sign_bit : int(bits:*) = 1.as_a(int(bits:*)) << (sz-1);
if (uval < sign_bit) {
return uval;
} else {
return -(max_val-uval);
};
};
使用示例:
print unsigned_to_signed( (1).as_a(uint) , 8);
print unsigned_to_signed( (-1).as_a(uint(bits:8)) , 8);
print unsigned_to_signed( (127).as_a(uint) , 8);
print unsigned_to_signed( (-128).as_a(uint(bits:8)) , 8);
print unsigned_to_signed( (237).as_a(uint) , 9);
print unsigned_to_signed( (-237).as_a(uint(bits:9)) , 9);
print unsigned_to_signed( (-237).as_a(uint) , 9, TRUE);