@@ -52,16 +52,39 @@ def _int_tv(index: int) -> tys.ExtType:
5252INT_T = int_t (5 )
5353
5454
55+ def _to_unsigned (val : int , bits : int ) -> int :
56+ """Convert a signed integer to its unsigned representation
57+ in twos-complement form.
58+
59+ Positive integers are unchanged, while negative integers
60+ are converted by adding 2^bits to the value.
61+
62+ Raises ValueError if the value is out of range for the given bit width
63+ (valid range is [-2^(bits-1), 2^(bits-1)-1]).
64+ """
65+ half_max = 1 << (bits - 1 )
66+ min_val = - half_max
67+ max_val = half_max - 1
68+ if val < min_val or val > max_val :
69+ msg = f"Value { val } out of range for { bits } -bit signed integer."
70+ raise ValueError (msg ) #
71+
72+ if val < 0 :
73+ return (1 << bits ) + val
74+ return val
75+
76+
5577@dataclass
5678class IntVal (val .ExtensionValue ):
57- """Custom value for an integer."""
79+ """Custom value for a signed integer."""
5880
5981 v : int
6082 width : int = field (default = 5 )
6183
6284 def to_value (self ) -> val .Extension :
6385 name = "ConstInt"
64- payload = {"log_width" : self .width , "value" : self .v }
86+ unsigned = _to_unsigned (self .v , 1 << self .width )
87+ payload = {"log_width" : self .width , "value" : unsigned }
6588 return val .Extension (
6689 name ,
6790 typ = int_t (self .width ),
@@ -72,8 +95,9 @@ def __str__(self) -> str:
7295 return f"{ self .v } "
7396
7497 def to_model (self ) -> model .Term :
98+ unsigned = _to_unsigned (self .v , 1 << self .width )
7599 return model .Apply (
76- "arithmetic.int.const" , [model .Literal (self .width ), model .Literal (self . v )]
100+ "arithmetic.int.const" , [model .Literal (self .width ), model .Literal (unsigned )]
77101 )
78102
79103
0 commit comments