Reputation: 25
I'm trying to make casting in specman from unsigned to signed number using "as_a(int(bits:))". My problem is that is something that's dynamic and changes from one number to another.
When trying to pass a variable to I'm getting an error saying that only constant numbers can be used.
Is there a way to overcome this? I've tried using macro but it didn't help as well.
Upvotes: 0
Views: 474
Reputation: 208
The following function will convert the unsigned int(bits:*) to signed in a given amount of 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);
};
};
Usage Examples:
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);
Upvotes: 0
Reputation: 338
I think I understand what you are trying to do: you have some number as uint and somehow know its "natural" bit size, and then you need to convert it to unsigned the way that leading 0s or 1s are correct according to that bit size. Right?
I don't see how it's possible to use variable bit size for integer. It seems that the only feasible solution, if you want to use the native 'e' casting, is to have all the possible bit size conversion hard-coded and use the relevant case according to bit size variable. It can be generated with relatively small amount of code using macros.
But maybe you don't really need as_a()? You can achieve correct sign extension using bit shift: convert your variable to int, and then shift it back and forth at distance 32 minus bit_size. At the end you should have the value you expect as an int: if it's positive for your bit size, it will be the same positive, and if it's supposed to be negative, it will be negative of correct value.
Upvotes: 1