1-- ----------------------------------------------------------------- 2-- 3-- Copyright 2019 IEEE P1076 WG Authors 4-- 5-- See the LICENSE file distributed with this work for copyright and 6-- licensing information and the AUTHORS file. 7-- 8-- This file to you under the Apache License, Version 2.0 (the "License"). 9-- You may obtain a copy of the License at 10-- 11-- http://www.apache.org/licenses/LICENSE-2.0 12-- 13-- Unless required by applicable law or agreed to in writing, software 14-- distributed under the License is distributed on an "AS IS" BASIS, 15-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16-- implied. See the License for the specific language governing 17-- permissions and limitations under the License. 18-- 19-- Title : Fixed-point package (Generic package body) 20-- : 21-- Library : This package shall be compiled into a library 22-- : symbolically named IEEE. 23-- : 24-- Developers: Accellera VHDL-TC and IEEE P1076 Working Group 25-- : 26-- Purpose : This packages defines basic binary fixed point arithmetic 27-- : arithmetic functions 28-- : 29-- Note : This package may be modified to include additional data 30-- : required by tools, but it must in no way change the 31-- : external interfaces or simulation behavior of the 32-- : description. It is permissible to add comments and/or 33-- : attributes to the package declarations, but not to change 34-- : or delete any original lines of the package declaration. 35-- : The package body may be changed only in accordance with 36-- : the terms of Clause 16 of this standard. 37-- : 38-- -------------------------------------------------------------------- 39-- $Revision: 1220 $ 40-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $ 41-- -------------------------------------------------------------------- 42 43library IEEE; 44use IEEE.MATH_REAL.all; 45 46package body fixed_generic_pkg is 47 -- Author David Bishop (dbishop@vhdl.org) 48 -- Other contributers: Jim Lewis, Yannick Grugni, Ryan W. Hilton 49 -- null array constants 50 constant NAUF : UNRESOLVED_ufixed (0 downto 1) := (others => '0'); 51 constant NASF : UNRESOLVED_sfixed (0 downto 1) := (others => '0'); 52 constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0'); 53 54 -- This differed constant will tell you if the package body is synthesizable 55 -- or implemented as real numbers, set to "true" if synthesizable. 56 constant fixedsynth_or_real : BOOLEAN := true; 57 58 -- Special version of "minimum" to do some boundary checking without errors 59 function mins (l, r : INTEGER) 60 return INTEGER is 61 begin -- function mins 62 if (l = INTEGER'low or r = INTEGER'low) then 63 return 0; -- error condition, silent 64 end if; 65 return minimum (l, r); 66 end function mins; 67 68 -- Special version of "minimum" to do some boundary checking with errors 69 function mine (l, r : INTEGER) 70 return INTEGER is 71 begin -- function mine 72 if (l = INTEGER'low or r = INTEGER'low) then 73 report fixed_generic_pkg'instance_name 74 & " Unbounded number passed, was a literal used?" 75 severity error; 76 return 0; 77 end if; 78 return minimum (l, r); 79 end function mine; 80 81 -- The following functions are used only internally. Every function 82 -- calls "cleanvec" either directly or indirectly. 83 -- purpose: Fixes "downto" problem and resolves meta states 84 function cleanvec ( 85 arg : UNRESOLVED_sfixed) -- input 86 return UNRESOLVED_sfixed 87 is 88 begin -- function cleanvec 89 assert not (arg'ascending and (arg'low /= INTEGER'low)) 90 report fixed_generic_pkg'instance_name 91 & " Vector passed using a ""to"" range, expected is ""downto""" 92 severity error; 93 return arg; 94 end function cleanvec; 95 96 -- purpose: Fixes "downto" problem and resolves meta states 97 function cleanvec ( 98 arg : UNRESOLVED_ufixed) -- input 99 return UNRESOLVED_ufixed 100 is 101 begin -- function cleanvec 102 assert not (arg'ascending and (arg'low /= INTEGER'low)) 103 report fixed_generic_pkg'instance_name 104 & " Vector passed using a ""to"" range, expected is ""downto""" 105 severity error; 106 return arg; 107 end function cleanvec; 108 109 -- Type convert a "unsigned" into a "ufixed", used internally 110 function to_fixed ( 111 arg : UNRESOLVED_UNSIGNED; -- shifted vector 112 constant left_index : INTEGER; 113 constant right_index : INTEGER) 114 return UNRESOLVED_ufixed 115 is 116 variable result : UNRESOLVED_ufixed (left_index downto right_index); 117 begin -- function to_fixed 118 result := UNRESOLVED_ufixed(arg); 119 return result; 120 end function to_fixed; 121 122 -- Type convert a "signed" into an "sfixed", used internally 123 function to_fixed ( 124 arg : UNRESOLVED_SIGNED; -- shifted vector 125 constant left_index : INTEGER; 126 constant right_index : INTEGER) 127 return UNRESOLVED_sfixed 128 is 129 variable result : UNRESOLVED_sfixed (left_index downto right_index); 130 begin -- function to_fixed 131 result := UNRESOLVED_sfixed(arg); 132 return result; 133 end function to_fixed; 134 135 -- Type convert a "ufixed" into an "unsigned", used internally 136 function to_uns ( 137 arg : UNRESOLVED_ufixed) -- fp vector 138 return UNRESOLVED_UNSIGNED 139 is 140 subtype t is UNRESOLVED_UNSIGNED(arg'high - arg'low downto 0); 141 variable slv : t; 142 begin -- function to_uns 143 slv := t(arg); 144 return slv; 145 end function to_uns; 146 147 -- Type convert an "sfixed" into a "signed", used internally 148 function to_s ( 149 arg : UNRESOLVED_sfixed) -- fp vector 150 return UNRESOLVED_SIGNED 151 is 152 subtype t is UNRESOLVED_SIGNED(arg'high - arg'low downto 0); 153 variable slv : t; 154 begin -- function to_s 155 slv := t(arg); 156 return slv; 157 end function to_s; 158 159 -- adds 1 to the LSB of the number 160 procedure round_up (arg : in UNRESOLVED_ufixed; 161 result : out UNRESOLVED_ufixed; 162 overflowx : out BOOLEAN) is 163 variable arguns, resuns : UNRESOLVED_UNSIGNED (arg'high-arg'low+1 downto 0) 164 := (others => '0'); 165 begin -- round_up 166 arguns (arguns'high-1 downto 0) := to_uns (arg); 167 resuns := arguns + 1; 168 result := to_fixed(resuns(arg'high-arg'low 169 downto 0), arg'high, arg'low); 170 overflowx := (resuns(resuns'high) = '1'); 171 end procedure round_up; 172 173 -- adds 1 to the LSB of the number 174 procedure round_up (arg : in UNRESOLVED_sfixed; 175 result : out UNRESOLVED_sfixed; 176 overflowx : out BOOLEAN) is 177 variable args, ress : UNRESOLVED_SIGNED (arg'high-arg'low+1 downto 0); 178 begin -- round_up 179 args (args'high-1 downto 0) := to_s (arg); 180 args(args'high) := arg(arg'high); -- sign extend 181 ress := args + 1; 182 result := to_fixed(ress (ress'high-1 183 downto 0), arg'high, arg'low); 184 overflowx := ((arg(arg'high) /= ress(ress'high-1)) 185 and (or (STD_ULOGIC_VECTOR(ress)) /= '0')); 186 end procedure round_up; 187 188 -- Rounding - Performs a "round_nearest" (IEEE 754) which rounds up 189 -- when the remainder is > 0.5. If the remainder IS 0.5 then if the 190 -- bottom bit is a "1" it is rounded, otherwise it remains the same. 191 function round_fixed (arg : UNRESOLVED_ufixed; 192 remainder : UNRESOLVED_ufixed; 193 overflow_style : fixed_overflow_style_type := fixed_overflow_style) 194 return UNRESOLVED_ufixed 195 is 196 variable rounds : BOOLEAN; 197 variable round_overflow : BOOLEAN; 198 variable result : UNRESOLVED_ufixed (arg'range); 199 begin 200 rounds := false; 201 if (remainder'length > 1) then 202 if (remainder (remainder'high) = '1') then 203 rounds := (arg(arg'low) = '1') 204 or (or (to_sulv(remainder(remainder'high-1 downto 205 remainder'low))) = '1'); 206 end if; 207 else 208 rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1'); 209 end if; 210 if rounds then 211 round_up(arg => arg, 212 result => result, 213 overflowx => round_overflow); 214 else 215 result := arg; 216 end if; 217 if (overflow_style = fixed_saturate) and round_overflow then 218 result := saturate (result'high, result'low); 219 end if; 220 return result; 221 end function round_fixed; 222 223 -- Rounding case statement 224 function round_fixed (arg : UNRESOLVED_sfixed; 225 remainder : UNRESOLVED_sfixed; 226 overflow_style : fixed_overflow_style_type := fixed_overflow_style) 227 return UNRESOLVED_sfixed 228 is 229 variable rounds : BOOLEAN; 230 variable round_overflow : BOOLEAN; 231 variable result : UNRESOLVED_sfixed (arg'range); 232 begin 233 rounds := false; 234 if (remainder'length > 1) then 235 if (remainder (remainder'high) = '1') then 236 rounds := (arg(arg'low) = '1') 237 or (or (to_sulv(remainder(remainder'high-1 downto 238 remainder'low))) = '1'); 239 end if; 240 else 241 rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1'); 242 end if; 243 if rounds then 244 round_up(arg => arg, 245 result => result, 246 overflowx => round_overflow); 247 else 248 result := arg; 249 end if; 250 if round_overflow then 251 if (overflow_style = fixed_saturate) then 252 if arg(arg'high) = '0' then 253 result := saturate (result'high, result'low); 254 else 255 result := not saturate (result'high, result'low); 256 end if; 257 -- Sign bit not fixed when wrapping 258 end if; 259 end if; 260 return result; 261 end function round_fixed; 262 263 -- converts an sfixed into a ufixed. The output is the same length as the 264 -- input, because abs("1000") = "1000" = 8. 265 function to_ufixed ( 266 arg : UNRESOLVED_sfixed) 267 return UNRESOLVED_ufixed 268 is 269 constant left_index : INTEGER := arg'high; 270 constant right_index : INTEGER := mine(arg'low, arg'low); 271 variable xarg : UNRESOLVED_sfixed(left_index+1 downto right_index); 272 variable result : UNRESOLVED_ufixed(left_index downto right_index); 273 begin 274 if arg'length < 1 then 275 return NAUF; 276 end if; 277 xarg := abs(arg); 278 result := UNRESOLVED_ufixed (xarg (left_index downto right_index)); 279 return result; 280 end function to_ufixed; 281 282----------------------------------------------------------------------------- 283-- Visible functions 284----------------------------------------------------------------------------- 285 -- Conversion functions. These are needed for synthesis where typically 286 -- the only input and output type is a std_logic_vector. 287 function to_sulv ( 288 arg : UNRESOLVED_ufixed) -- fixed point vector 289 return STD_ULOGIC_VECTOR 290 is 291 variable intermediate_result : UNRESOLVED_ufixed(arg'length-1 downto 0); 292 begin 293 if arg'length < 1 then 294 return NSLV; 295 end if; 296 intermediate_result := arg; 297 return STD_ULOGIC_VECTOR (intermediate_result); 298 end function to_sulv; 299 300 function to_sulv ( 301 arg : UNRESOLVED_sfixed) -- fixed point vector 302 return STD_ULOGIC_VECTOR 303 is 304 variable intermediate_result : UNRESOLVED_sfixed(arg'length-1 downto 0); 305 begin 306 if arg'length < 1 then 307 return NSLV; 308 end if; 309 intermediate_result := arg; 310 return STD_ULOGIC_VECTOR (intermediate_result); 311 end function to_sulv; 312 313 function to_slv ( 314 arg : UNRESOLVED_ufixed) -- fixed point vector 315 return STD_LOGIC_VECTOR is 316 begin 317 return to_sulv(arg); 318 end function to_slv; 319 320 function to_slv ( 321 arg : UNRESOLVED_sfixed) -- fixed point vector 322 return STD_LOGIC_VECTOR is 323 begin 324 return to_sulv(arg); 325 end function to_slv; 326 327 function to_ufixed ( 328 arg : STD_ULOGIC_VECTOR; -- shifted vector 329 constant left_index : INTEGER; 330 constant right_index : INTEGER) 331 return UNRESOLVED_ufixed 332 is 333 variable result : UNRESOLVED_ufixed (left_index downto right_index); 334 begin 335 if (arg'length < 1 or right_index > left_index) then 336 return NAUF; 337 end if; 338 if (arg'length /= result'length) then 339 report fixed_generic_pkg'instance_name & "TO_UFIXED(SLV) " 340 & "Vector lengths do not match. Input length is " 341 & INTEGER'image(arg'length) & " and output will be " 342 & INTEGER'image(result'length) & " wide." 343 severity error; 344 return NAUF; 345 else 346 result := to_fixed (arg => UNRESOLVED_UNSIGNED(arg), 347 left_index => left_index, 348 right_index => right_index); 349 return result; 350 end if; 351 end function to_ufixed; 352 353 function to_sfixed ( 354 arg : STD_ULOGIC_VECTOR; -- shifted vector 355 constant left_index : INTEGER; 356 constant right_index : INTEGER) 357 return UNRESOLVED_sfixed 358 is 359 variable result : UNRESOLVED_sfixed (left_index downto right_index); 360 begin 361 if (arg'length < 1 or right_index > left_index) then 362 return NASF; 363 end if; 364 if (arg'length /= result'length) then 365 report fixed_generic_pkg'instance_name & "TO_SFIXED(SLV) " 366 & "Vector lengths do not match. Input length is " 367 & INTEGER'image(arg'length) & " and output will be " 368 & INTEGER'image(result'length) & " wide." 369 severity error; 370 return NASF; 371 else 372 result := to_fixed (arg => UNRESOLVED_SIGNED(arg), 373 left_index => left_index, 374 right_index => right_index); 375 return result; 376 end if; 377 end function to_sfixed; 378 379 -- Two's complement number, Grows the vector by 1 bit. 380 -- because "abs (1000.000) = 01000.000" or abs(-16) = 16. 381 function "abs" ( 382 arg : UNRESOLVED_sfixed) -- fixed point input 383 return UNRESOLVED_sfixed 384 is 385 constant left_index : INTEGER := arg'high; 386 constant right_index : INTEGER := mine(arg'low, arg'low); 387 variable ressns : UNRESOLVED_SIGNED (arg'length downto 0); 388 variable result : UNRESOLVED_sfixed (left_index+1 downto right_index); 389 begin 390 if (arg'length < 1 or result'length < 1) then 391 return NASF; 392 end if; 393 ressns (arg'length-1 downto 0) := to_s (cleanvec (arg)); 394 ressns (arg'length) := ressns (arg'length-1); -- expand sign bit 395 result := to_fixed (abs(ressns), left_index+1, right_index); 396 return result; 397 end function "abs"; 398 399 -- also grows the vector by 1 bit. 400 function "-" ( 401 arg : UNRESOLVED_sfixed) -- fixed point input 402 return UNRESOLVED_sfixed 403 is 404 constant left_index : INTEGER := arg'high+1; 405 constant right_index : INTEGER := mine(arg'low, arg'low); 406 variable ressns : UNRESOLVED_SIGNED (arg'length downto 0); 407 variable result : UNRESOLVED_sfixed (left_index downto right_index); 408 begin 409 if (arg'length < 1 or result'length < 1) then 410 return NASF; 411 end if; 412 ressns (arg'length-1 downto 0) := to_s (cleanvec(arg)); 413 ressns (arg'length) := ressns (arg'length-1); -- expand sign bit 414 result := to_fixed (-ressns, left_index, right_index); 415 return result; 416 end function "-"; 417 418 -- Addition 419 function "+" ( 420 l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) + ufixed(c downto d) = 421 return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d)) 422 is 423 constant left_index : INTEGER := maximum(l'high, r'high)+1; 424 constant right_index : INTEGER := mine(l'low, r'low); 425 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 426 variable result : UNRESOLVED_ufixed (left_index downto right_index); 427 variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index 428 downto 0); 429 variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index 430 downto 0); 431 begin 432 if (l'length < 1 or r'length < 1 or result'length < 1) then 433 return NAUF; 434 end if; 435 lresize := resize (l, left_index, right_index); 436 rresize := resize (r, left_index, right_index); 437 lslv := to_uns (lresize); 438 rslv := to_uns (rresize); 439 result_slv := lslv + rslv; 440 result := to_fixed(result_slv, left_index, right_index); 441 return result; 442 end function "+"; 443 444 function "+" ( 445 l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) + sfixed(c downto d) = 446 return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d)) 447 is 448 constant left_index : INTEGER := maximum(l'high, r'high)+1; 449 constant right_index : INTEGER := mine(l'low, r'low); 450 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 451 variable result : UNRESOLVED_sfixed (left_index downto right_index); 452 variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0); 453 variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0); 454 begin 455 if (l'length < 1 or r'length < 1 or result'length < 1) then 456 return NASF; 457 end if; 458 lresize := resize (l, left_index, right_index); 459 rresize := resize (r, left_index, right_index); 460 lslv := to_s (lresize); 461 rslv := to_s (rresize); 462 result_slv := lslv + rslv; 463 result := to_fixed(result_slv, left_index, right_index); 464 return result; 465 end function "+"; 466 467 -- Subtraction 468 function "-" ( 469 l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) - ufixed(c downto d) = 470 return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d)) 471 is 472 constant left_index : INTEGER := maximum(l'high, r'high)+1; 473 constant right_index : INTEGER := mine(l'low, r'low); 474 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 475 variable result : UNRESOLVED_ufixed (left_index downto right_index); 476 variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index 477 downto 0); 478 variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index 479 downto 0); 480 begin 481 if (l'length < 1 or r'length < 1 or result'length < 1) then 482 return NAUF; 483 end if; 484 lresize := resize (l, left_index, right_index); 485 rresize := resize (r, left_index, right_index); 486 lslv := to_uns (lresize); 487 rslv := to_uns (rresize); 488 result_slv := lslv - rslv; 489 result := to_fixed(result_slv, left_index, right_index); 490 return result; 491 end function "-"; 492 493 function "-" ( 494 l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) - sfixed(c downto d) = 495 return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d)) 496 is 497 constant left_index : INTEGER := maximum(l'high, r'high)+1; 498 constant right_index : INTEGER := mine(l'low, r'low); 499 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 500 variable result : UNRESOLVED_sfixed (left_index downto right_index); 501 variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0); 502 variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0); 503 begin 504 if (l'length < 1 or r'length < 1 or result'length < 1) then 505 return NASF; 506 end if; 507 lresize := resize (l, left_index, right_index); 508 rresize := resize (r, left_index, right_index); 509 lslv := to_s (lresize); 510 rslv := to_s (rresize); 511 result_slv := lslv - rslv; 512 result := to_fixed(result_slv, left_index, right_index); 513 return result; 514 end function "-"; 515 516 function "*" ( 517 l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) * ufixed(c downto d) = 518 return UNRESOLVED_ufixed -- ufixed(a+c+1 downto b+d) 519 is 520 variable lslv : UNRESOLVED_UNSIGNED (l'length-1 downto 0); 521 variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0); 522 variable result_slv : UNRESOLVED_UNSIGNED (r'length+l'length-1 downto 0); 523 variable result : UNRESOLVED_ufixed (l'high + r'high+1 downto 524 mine(l'low, l'low) + mine(r'low, r'low)); 525 begin 526 if (l'length < 1 or r'length < 1 or 527 result'length /= result_slv'length) then 528 return NAUF; 529 end if; 530 lslv := to_uns (cleanvec(l)); 531 rslv := to_uns (cleanvec(r)); 532 result_slv := lslv * rslv; 533 result := to_fixed (result_slv, result'high, result'low); 534 return result; 535 end function "*"; 536 537 function "*" ( 538 l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) * sfixed(c downto d) = 539 return UNRESOLVED_sfixed -- sfixed(a+c+1 downto b+d) 540 is 541 variable lslv : UNRESOLVED_SIGNED (l'length-1 downto 0); 542 variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0); 543 variable result_slv : UNRESOLVED_SIGNED (r'length+l'length-1 downto 0); 544 variable result : UNRESOLVED_sfixed (l'high + r'high+1 downto 545 mine(l'low, l'low) + mine(r'low, r'low)); 546 begin 547 if (l'length < 1 or r'length < 1 or 548 result'length /= result_slv'length) then 549 return NASF; 550 end if; 551 lslv := to_s (cleanvec(l)); 552 rslv := to_s (cleanvec(r)); 553 result_slv := lslv * rslv; 554 result := to_fixed (result_slv, result'high, result'low); 555 return result; 556 end function "*"; 557 558 function "/" ( 559 l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) / ufixed(c downto d) = 560 return UNRESOLVED_ufixed is -- ufixed(a-d downto b-c-1) 561 begin 562 return divide (l, r); 563 end function "/"; 564 565 function "/" ( 566 l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) / sfixed(c downto d) = 567 return UNRESOLVED_sfixed is -- sfixed(a-d+1 downto b-c) 568 begin 569 return divide (l, r); 570 end function "/"; 571 572 -- This version of divide gives the user more control 573 -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1) 574 function divide ( 575 l, r : UNRESOLVED_ufixed; 576 constant round_style : fixed_round_style_type := fixed_round_style; 577 constant guard_bits : NATURAL := fixed_guard_bits) 578 return UNRESOLVED_ufixed 579 is 580 variable result : UNRESOLVED_ufixed (l'high - mine(r'low, r'low) downto 581 mine (l'low, l'low) - r'high -1); 582 variable dresult : UNRESOLVED_ufixed (result'high downto result'low -guard_bits); 583 variable lresize : UNRESOLVED_ufixed (l'high downto l'high - dresult'length+1); 584 variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 585 variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0); 586 variable result_slv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 587 begin 588 if (l'length < 1 or r'length < 1 or 589 mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then 590 return NAUF; 591 end if; 592 lresize := resize (arg => l, 593 left_index => lresize'high, 594 right_index => lresize'low, 595 overflow_style => fixed_wrap, -- vector only grows 596 round_style => fixed_truncate); 597 lslv := to_uns (cleanvec (lresize)); 598 rslv := to_uns (cleanvec (r)); 599 if (rslv = 0) then 600 report fixed_generic_pkg'instance_name 601 & "DIVIDE(ufixed) Division by zero" severity error; 602 result := saturate (result'high, result'low); -- saturate 603 else 604 result_slv := lslv / rslv; 605 dresult := to_fixed (result_slv, dresult'high, dresult'low); 606 result := resize (arg => dresult, 607 left_index => result'high, 608 right_index => result'low, 609 overflow_style => fixed_wrap, -- overflow impossible 610 round_style => round_style); 611 end if; 612 return result; 613 end function divide; 614 615 -- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c) 616 function divide ( 617 l, r : UNRESOLVED_sfixed; 618 constant round_style : fixed_round_style_type := fixed_round_style; 619 constant guard_bits : NATURAL := fixed_guard_bits) 620 return UNRESOLVED_sfixed 621 is 622 variable result : UNRESOLVED_sfixed (l'high - mine(r'low, r'low) + 1 downto 623 mine (l'low, l'low) - r'high); 624 variable dresult : UNRESOLVED_sfixed (result'high downto result'low-guard_bits); 625 variable lresize : UNRESOLVED_sfixed (l'high+1 downto l'high+1 -dresult'length+1); 626 variable lslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 627 variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0); 628 variable result_slv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 629 begin 630 if (l'length < 1 or r'length < 1 or 631 mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then 632 return NASF; 633 end if; 634 lresize := resize (arg => l, 635 left_index => lresize'high, 636 right_index => lresize'low, 637 overflow_style => fixed_wrap, -- vector only grows 638 round_style => fixed_truncate); 639 lslv := to_s (cleanvec (lresize)); 640 rslv := to_s (cleanvec (r)); 641 if (rslv = 0) then 642 report fixed_generic_pkg'instance_name 643 & "DIVIDE(sfixed) Division by zero" severity error; 644 result := saturate (result'high, result'low); 645 else 646 result_slv := lslv / rslv; 647 dresult := to_fixed (result_slv, dresult'high, dresult'low); 648 result := resize (arg => dresult, 649 left_index => result'high, 650 right_index => result'low, 651 overflow_style => fixed_wrap, -- overflow impossible 652 round_style => round_style); 653 end if; 654 return result; 655 end function divide; 656 657 -- 1 / ufixed(a downto b) = ufixed(-b downto -a-1) 658 function reciprocal ( 659 arg : UNRESOLVED_ufixed; -- fixed point input 660 constant round_style : fixed_round_style_type := fixed_round_style; 661 constant guard_bits : NATURAL := fixed_guard_bits) 662 return UNRESOLVED_ufixed 663 is 664 constant one : UNRESOLVED_ufixed (0 downto 0) := "1"; 665 begin 666 return divide (l => one, 667 r => arg, 668 round_style => round_style, 669 guard_bits => guard_bits); 670 end function reciprocal; 671 672 -- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a) 673 function reciprocal ( 674 arg : UNRESOLVED_sfixed; -- fixed point input 675 constant round_style : fixed_round_style_type := fixed_round_style; 676 constant guard_bits : NATURAL := fixed_guard_bits) 677 return UNRESOLVED_sfixed 678 is 679 constant one : UNRESOLVED_sfixed (1 downto 0) := "01"; -- extra bit. 680 variable resultx : UNRESOLVED_sfixed (-mine(arg'low, arg'low)+2 downto -arg'high); 681 begin 682 if (arg'length < 1 or resultx'length < 1) then 683 return NASF; 684 else 685 resultx := divide (l => one, 686 r => arg, 687 round_style => round_style, 688 guard_bits => guard_bits); 689 return resultx (resultx'high-1 downto resultx'low); -- remove extra bit 690 end if; 691 end function reciprocal; 692 693 -- ufixed (a downto b) rem ufixed (c downto d) 694 -- = ufixed (min(a,c) downto min(b,d)) 695 function "rem" ( 696 l, r : UNRESOLVED_ufixed) -- fixed point input 697 return UNRESOLVED_ufixed is 698 begin 699 return remainder (l, r); 700 end function "rem"; 701 702 -- remainder 703 -- sfixed (a downto b) rem sfixed (c downto d) 704 -- = sfixed (min(a,c) downto min(b,d)) 705 function "rem" ( 706 l, r : UNRESOLVED_sfixed) -- fixed point input 707 return UNRESOLVED_sfixed is 708 begin 709 return remainder (l, r); 710 end function "rem"; 711 712 -- ufixed (a downto b) rem ufixed (c downto d) 713 -- = ufixed (min(a,c) downto min(b,d)) 714 function remainder ( 715 l, r : UNRESOLVED_ufixed; -- fixed point input 716 constant round_style : fixed_round_style_type := fixed_round_style; 717 constant guard_bits : NATURAL := fixed_guard_bits) 718 return UNRESOLVED_ufixed 719 is 720 variable result : UNRESOLVED_ufixed (minimum(l'high, r'high) downto 721 mine(l'low, r'low)); 722 constant rlow : integer := mins(r'low, r'low); 723 variable lresize : UNRESOLVED_ufixed (maximum(l'high, r'low) downto 724 rlow-guard_bits); 725 variable rresize : UNRESOLVED_ufixed (r'high downto rlow-guard_bits); 726 variable dresult : UNRESOLVED_ufixed (rresize'range); 727 variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 728 variable rslv : UNRESOLVED_UNSIGNED (rresize'length-1 downto 0); 729 variable result_slv : UNRESOLVED_UNSIGNED (rslv'range); 730 begin 731 if (l'length < 1 or r'length < 1 or 732 mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then 733 return NAUF; 734 end if; 735 lresize := resize (arg => l, 736 left_index => lresize'high, 737 right_index => lresize'low, 738 overflow_style => fixed_wrap, -- vector only grows 739 round_style => fixed_truncate); 740 lslv := to_uns (lresize); 741 rresize := resize (arg => r, 742 left_index => rresize'high, 743 right_index => rresize'low, 744 overflow_style => fixed_wrap, -- vector only grows 745 round_style => fixed_truncate); 746 rslv := to_uns (rresize); 747 if (rslv = 0) then 748 report fixed_generic_pkg'instance_name 749 & "remainder(ufixed) Division by zero" severity error; 750 result := saturate (result'high, result'low); -- saturate 751 else 752 if (r'low <= l'high) then 753 result_slv := lslv rem rslv; 754 dresult := to_fixed (result_slv, dresult'high, dresult'low); 755 result := resize (arg => dresult, 756 left_index => result'high, 757 right_index => result'low, 758 overflow_style => fixed_wrap, -- can't overflow 759 round_style => round_style); 760 end if; 761 if l'low < r'low then 762 result(mins(r'low-1, l'high) downto l'low) := 763 cleanvec(l(mins(r'low-1, l'high) downto l'low)); 764 end if; 765 end if; 766 return result; 767 end function remainder; 768 769 -- remainder 770 -- sfixed (a downto b) rem sfixed (c downto d) 771 -- = sfixed (min(a,c) downto min(b,d)) 772 function remainder ( 773 l, r : UNRESOLVED_sfixed; -- fixed point input 774 constant round_style : fixed_round_style_type := fixed_round_style; 775 constant guard_bits : NATURAL := fixed_guard_bits) 776 return UNRESOLVED_sfixed 777 is 778 variable l_abs : UNRESOLVED_ufixed (l'range); 779 variable r_abs : UNRESOLVED_ufixed (r'range); 780 variable result : UNRESOLVED_sfixed (minimum(r'high, l'high) downto 781 mine(r'low, l'low)); 782 variable neg_result : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto 783 mins(r'low, l'low)); 784 begin 785 if (l'length < 1 or r'length < 1 or 786 mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then 787 return NASF; 788 end if; 789 l_abs := to_ufixed (l); 790 r_abs := to_ufixed (r); 791 result := UNRESOLVED_sfixed (remainder ( 792 l => l_abs, 793 r => r_abs, 794 round_style => round_style)); 795 neg_result := -result; 796 if l(l'high) = '1' then 797 result := neg_result(result'range); 798 end if; 799 return result; 800 end function remainder; 801 802 -- modulo 803 -- ufixed (a downto b) mod ufixed (c downto d) 804 -- = ufixed (min(a,c) downto min(b, d)) 805 function "mod" ( 806 l, r : UNRESOLVED_ufixed) -- fixed point input 807 return UNRESOLVED_ufixed is 808 begin 809 return modulo (l, r); 810 end function "mod"; 811 812 -- sfixed (a downto b) mod sfixed (c downto d) 813 -- = sfixed (c downto min(b, d)) 814 function "mod" ( 815 l, r : UNRESOLVED_sfixed) -- fixed point input 816 return UNRESOLVED_sfixed is 817 begin 818 return modulo(l, r); 819 end function "mod"; 820 821 -- modulo 822 -- ufixed (a downto b) mod ufixed (c downto d) 823 -- = ufixed (min(a,c) downto min(b, d)) 824 function modulo ( 825 l, r : UNRESOLVED_ufixed; -- fixed point input 826 constant round_style : fixed_round_style_type := fixed_round_style; 827 constant guard_bits : NATURAL := fixed_guard_bits) 828 return UNRESOLVED_ufixed is 829 begin 830 return remainder(l => l, 831 r => r, 832 round_style => round_style, 833 guard_bits => guard_bits); 834 end function modulo; 835 836 -- sfixed (a downto b) mod sfixed (c downto d) 837 -- = sfixed (c downto min(b, d)) 838 function modulo ( 839 l, r : UNRESOLVED_sfixed; -- fixed point input 840 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 841 constant round_style : fixed_round_style_type := fixed_round_style; 842 constant guard_bits : NATURAL := fixed_guard_bits) 843 return UNRESOLVED_sfixed 844 is 845 variable l_abs : UNRESOLVED_ufixed (l'range); 846 variable r_abs : UNRESOLVED_ufixed (r'range); 847 variable result : UNRESOLVED_sfixed (r'high downto 848 mine(r'low, l'low)); 849 variable dresult : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto 850 mins(r'low, l'low)); 851 variable dresult_not_zero : BOOLEAN; 852 begin 853 if (l'length < 1 or r'length < 1 or 854 mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then 855 return NASF; 856 end if; 857 l_abs := to_ufixed (l); 858 r_abs := to_ufixed (r); 859 dresult := "0" & UNRESOLVED_sfixed(remainder (l => l_abs, 860 r => r_abs, 861 round_style => round_style)); 862 if (to_s(dresult) = 0) then 863 dresult_not_zero := false; 864 else 865 dresult_not_zero := true; 866 end if; 867 if to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '0' 868 and dresult_not_zero then 869 result := resize (arg => r - dresult, 870 left_index => result'high, 871 right_index => result'low, 872 overflow_style => overflow_style, 873 round_style => round_style); 874 elsif to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '1' then 875 result := resize (arg => -dresult, 876 left_index => result'high, 877 right_index => result'low, 878 overflow_style => overflow_style, 879 round_style => round_style); 880 elsif to_x01(l(l'high)) = '0' and to_x01(r(r'high)) = '1' 881 and dresult_not_zero then 882 result := resize (arg => dresult + r, 883 left_index => result'high, 884 right_index => result'low, 885 overflow_style => overflow_style, 886 round_style => round_style); 887 else 888 result := resize (arg => dresult, 889 left_index => result'high, 890 right_index => result'low, 891 overflow_style => overflow_style, 892 round_style => round_style); 893 end if; 894 return result; 895 end function modulo; 896 897 -- Procedure for those who need an "accumulator" function 898 procedure add_carry ( 899 L, R : in UNRESOLVED_ufixed; 900 c_in : in STD_ULOGIC; 901 result : out UNRESOLVED_ufixed; 902 c_out : out STD_ULOGIC) is 903 constant left_index : INTEGER := maximum(L'high, R'high)+1; 904 constant right_index : INTEGER := mins(L'low, R'low); 905 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 906 variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index 907 downto 0); 908 variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index 909 downto 0); 910 variable cx : UNRESOLVED_UNSIGNED (0 downto 0); -- Carry in 911 begin 912 if (L'length < 1 or R'length < 1) then 913 result := NAUF; 914 c_out := '0'; 915 else 916 cx (0) := c_in; 917 lresize := resize (L, left_index, right_index); 918 rresize := resize (R, left_index, right_index); 919 lslv := to_uns (lresize); 920 rslv := to_uns (rresize); 921 result_slv := lslv + rslv + cx; 922 c_out := result_slv(left_index); 923 result := to_fixed(result_slv (left_index-right_index-1 downto 0), 924 left_index-1, right_index); 925 end if; 926 end procedure add_carry; 927 928 procedure add_carry ( 929 L, R : in UNRESOLVED_sfixed; 930 c_in : in STD_ULOGIC; 931 result : out UNRESOLVED_sfixed; 932 c_out : out STD_ULOGIC) is 933 constant left_index : INTEGER := maximum(L'high, R'high)+1; 934 constant right_index : INTEGER := mins(L'low, R'low); 935 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 936 variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index 937 downto 0); 938 variable result_slv : UNRESOLVED_SIGNED (left_index-right_index 939 downto 0); 940 variable cx : UNRESOLVED_SIGNED (1 downto 0); -- Carry in 941 begin 942 if (L'length < 1 or R'length < 1) then 943 result := NASF; 944 c_out := '0'; 945 else 946 cx (1) := '0'; 947 cx (0) := c_in; 948 lresize := resize (L, left_index, right_index); 949 rresize := resize (R, left_index, right_index); 950 lslv := to_s (lresize); 951 rslv := to_s (rresize); 952 result_slv := lslv + rslv + cx; 953 c_out := result_slv(left_index); 954 result := to_fixed(result_slv (left_index-right_index-1 downto 0), 955 left_index-1, right_index); 956 end if; 957 end procedure add_carry; 958 959 -- Scales the result by a power of 2. Width of input = width of output with 960 -- the decimal point moved. 961 function scalb (y : UNRESOLVED_ufixed; N : INTEGER) 962 return UNRESOLVED_ufixed 963 is 964 variable result : UNRESOLVED_ufixed (y'high+N downto y'low+N); 965 begin 966 if y'length < 1 then 967 return NAUF; 968 else 969 result := y; 970 return result; 971 end if; 972 end function scalb; 973 974 function scalb (y : UNRESOLVED_ufixed; N : UNRESOLVED_SIGNED) 975 return UNRESOLVED_ufixed is 976 begin 977 return scalb (y => y, 978 N => to_integer(N)); 979 end function scalb; 980 981 function scalb (y : UNRESOLVED_sfixed; N : INTEGER) 982 return UNRESOLVED_sfixed 983 is 984 variable result : UNRESOLVED_sfixed (y'high+N downto y'low+N); 985 begin 986 if y'length < 1 then 987 return NASF; 988 else 989 result := y; 990 return result; 991 end if; 992 end function scalb; 993 994 function scalb (y : UNRESOLVED_sfixed; N : UNRESOLVED_SIGNED) 995 return UNRESOLVED_sfixed is 996 begin 997 return scalb (y => y, 998 N => to_integer(N)); 999 end function scalb; 1000 1001 function Is_Negative (arg : UNRESOLVED_sfixed) return BOOLEAN is 1002 begin 1003 if to_X01(arg(arg'high)) = '1' then 1004 return true; 1005 else 1006 return false; 1007 end if; 1008 end function Is_Negative; 1009 1010 function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC) 1011 return INTEGER is 1012 begin 1013 for_loop : for i in arg'reverse_range loop 1014 if arg(i) ?= y then 1015 return i; 1016 end if; 1017 end loop; 1018 return arg'high+1; -- return out of bounds 'high 1019 end function find_rightmost; 1020 1021 function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC) 1022 return INTEGER is 1023 begin 1024 for_loop : for i in arg'range loop 1025 if arg(i) ?= y then 1026 return i; 1027 end if; 1028 end loop; 1029 return arg'low-1; -- return out of bounds 'low 1030 end function find_leftmost; 1031 1032 function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC) 1033 return INTEGER is 1034 begin 1035 for_loop : for i in arg'reverse_range loop 1036 if arg(i) ?= y then 1037 return i; 1038 end if; 1039 end loop; 1040 return arg'high+1; -- return out of bounds 'high 1041 end function find_rightmost; 1042 1043 function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC) 1044 return INTEGER is 1045 begin 1046 for_loop : for i in arg'range loop 1047 if arg(i) ?= y then 1048 return i; 1049 end if; 1050 end loop; 1051 return arg'low-1; -- return out of bounds 'low 1052 end function find_leftmost; 1053 1054 function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) 1055 return UNRESOLVED_ufixed 1056 is 1057 variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0); 1058 variable result : UNRESOLVED_ufixed (ARG'range); 1059 begin 1060 argslv := to_uns (ARG); 1061 argslv := argslv sll COUNT; 1062 result := to_fixed (argslv, result'high, result'low); 1063 return result; 1064 end function "sll"; 1065 1066 function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) 1067 return UNRESOLVED_ufixed 1068 is 1069 variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0); 1070 variable result : UNRESOLVED_ufixed (ARG'range); 1071 begin 1072 argslv := to_uns (ARG); 1073 argslv := argslv srl COUNT; 1074 result := to_fixed (argslv, result'high, result'low); 1075 return result; 1076 end function "srl"; 1077 1078 function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) 1079 return UNRESOLVED_ufixed 1080 is 1081 variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0); 1082 variable result : UNRESOLVED_ufixed (ARG'range); 1083 begin 1084 argslv := to_uns (ARG); 1085 argslv := argslv rol COUNT; 1086 result := to_fixed (argslv, result'high, result'low); 1087 return result; 1088 end function "rol"; 1089 1090 function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) 1091 return UNRESOLVED_ufixed 1092 is 1093 variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0); 1094 variable result : UNRESOLVED_ufixed (ARG'range); 1095 begin 1096 argslv := to_uns (ARG); 1097 argslv := argslv ror COUNT; 1098 result := to_fixed (argslv, result'high, result'low); 1099 return result; 1100 end function "ror"; 1101 1102 function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) 1103 return UNRESOLVED_ufixed 1104 is 1105 variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0); 1106 variable result : UNRESOLVED_ufixed (ARG'range); 1107 begin 1108 argslv := to_uns (ARG); 1109 -- Arithmetic shift on an unsigned is a logical shift 1110 argslv := argslv sll COUNT; 1111 result := to_fixed (argslv, result'high, result'low); 1112 return result; 1113 end function "sla"; 1114 1115 function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) 1116 return UNRESOLVED_ufixed 1117 is 1118 variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0); 1119 variable result : UNRESOLVED_ufixed (ARG'range); 1120 begin 1121 argslv := to_uns (ARG); 1122 -- Arithmetic shift on an unsigned is a logical shift 1123 argslv := argslv srl COUNT; 1124 result := to_fixed (argslv, result'high, result'low); 1125 return result; 1126 end function "sra"; 1127 1128 function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) 1129 return UNRESOLVED_sfixed 1130 is 1131 variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0); 1132 variable result : UNRESOLVED_sfixed (ARG'range); 1133 begin 1134 argslv := to_s (ARG); 1135 argslv := argslv sll COUNT; 1136 result := to_fixed (argslv, result'high, result'low); 1137 return result; 1138 end function "sll"; 1139 1140 function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) 1141 return UNRESOLVED_sfixed 1142 is 1143 variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0); 1144 variable result : UNRESOLVED_sfixed (ARG'range); 1145 begin 1146 argslv := to_s (ARG); 1147 argslv := argslv srl COUNT; 1148 result := to_fixed (argslv, result'high, result'low); 1149 return result; 1150 end function "srl"; 1151 1152 function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) 1153 return UNRESOLVED_sfixed 1154 is 1155 variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0); 1156 variable result : UNRESOLVED_sfixed (ARG'range); 1157 begin 1158 argslv := to_s (ARG); 1159 argslv := argslv rol COUNT; 1160 result := to_fixed (argslv, result'high, result'low); 1161 return result; 1162 end function "rol"; 1163 1164 function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) 1165 return UNRESOLVED_sfixed 1166 is 1167 variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0); 1168 variable result : UNRESOLVED_sfixed (ARG'range); 1169 begin 1170 argslv := to_s (ARG); 1171 argslv := argslv ror COUNT; 1172 result := to_fixed (argslv, result'high, result'low); 1173 return result; 1174 end function "ror"; 1175 1176 function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) 1177 return UNRESOLVED_sfixed 1178 is 1179 variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0); 1180 variable result : UNRESOLVED_sfixed (ARG'range); 1181 begin 1182 argslv := to_s (ARG); 1183 if COUNT > 0 then 1184 -- Arithmetic shift left on a 2's complement number is a logic shift 1185 argslv := argslv sll COUNT; 1186 else 1187 argslv := argslv sra -COUNT; 1188 end if; 1189 result := to_fixed (argslv, result'high, result'low); 1190 return result; 1191 end function "sla"; 1192 1193 function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) 1194 return UNRESOLVED_sfixed 1195 is 1196 variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0); 1197 variable result : UNRESOLVED_sfixed (ARG'range); 1198 begin 1199 argslv := to_s (ARG); 1200 if COUNT > 0 then 1201 argslv := argslv sra COUNT; 1202 else 1203 -- Arithmetic shift left on a 2's complement number is a logic shift 1204 argslv := argslv sll -COUNT; 1205 end if; 1206 result := to_fixed (argslv, result'high, result'low); 1207 return result; 1208 end function "sra"; 1209 1210 -- Because some people want the older functions. 1211 function SHIFT_LEFT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL) 1212 return UNRESOLVED_ufixed is 1213 begin 1214 if (ARG'length < 1) then 1215 return NAUF; 1216 end if; 1217 return ARG sla COUNT; 1218 end function SHIFT_LEFT; 1219 1220 function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL) 1221 return UNRESOLVED_ufixed is 1222 begin 1223 if (ARG'length < 1) then 1224 return NAUF; 1225 end if; 1226 return ARG sra COUNT; 1227 end function SHIFT_RIGHT; 1228 1229 function SHIFT_LEFT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL) 1230 return UNRESOLVED_sfixed is 1231 begin 1232 if (ARG'length < 1) then 1233 return NASF; 1234 end if; 1235 return ARG sla COUNT; 1236 end function SHIFT_LEFT; 1237 1238 function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL) 1239 return UNRESOLVED_sfixed is 1240 begin 1241 if (ARG'length < 1) then 1242 return NASF; 1243 end if; 1244 return ARG sra COUNT; 1245 end function SHIFT_RIGHT; 1246 1247 ---------------------------------------------------------------------------- 1248 -- logical functions 1249 ---------------------------------------------------------------------------- 1250 function "not" (L : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 1251 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1252 begin 1253 RESULT := not to_sulv(L); 1254 return to_ufixed(RESULT, L'high, L'low); 1255 end function "not"; 1256 1257 function "and" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 1258 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1259 begin 1260 if (L'high = R'high and L'low = R'low) then 1261 RESULT := to_sulv(L) and to_sulv(R); 1262 else 1263 assert no_warning 1264 report fixed_generic_pkg'instance_name 1265 & """and"": Range error L'RANGE /= R'RANGE" 1266 severity warning; 1267 RESULT := (others => 'X'); 1268 end if; 1269 return to_ufixed(RESULT, L'high, L'low); 1270 end function "and"; 1271 1272 function "or" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 1273 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1274 begin 1275 if (L'high = R'high and L'low = R'low) then 1276 RESULT := to_sulv(L) or to_sulv(R); 1277 else 1278 assert no_warning 1279 report fixed_generic_pkg'instance_name 1280 & """or"": Range error L'RANGE /= R'RANGE" 1281 severity warning; 1282 RESULT := (others => 'X'); 1283 end if; 1284 return to_ufixed(RESULT, L'high, L'low); 1285 end function "or"; 1286 1287 function "nand" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 1288 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1289 begin 1290 if (L'high = R'high and L'low = R'low) then 1291 RESULT := to_sulv(L) nand to_sulv(R); 1292 else 1293 assert no_warning 1294 report fixed_generic_pkg'instance_name 1295 & """nand"": Range error L'RANGE /= R'RANGE" 1296 severity warning; 1297 RESULT := (others => 'X'); 1298 end if; 1299 return to_ufixed(RESULT, L'high, L'low); 1300 end function "nand"; 1301 1302 function "nor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 1303 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1304 begin 1305 if (L'high = R'high and L'low = R'low) then 1306 RESULT := to_sulv(L) nor to_sulv(R); 1307 else 1308 assert no_warning 1309 report fixed_generic_pkg'instance_name 1310 & """nor"": Range error L'RANGE /= R'RANGE" 1311 severity warning; 1312 RESULT := (others => 'X'); 1313 end if; 1314 return to_ufixed(RESULT, L'high, L'low); 1315 end function "nor"; 1316 1317 function "xor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 1318 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1319 begin 1320 if (L'high = R'high and L'low = R'low) then 1321 RESULT := to_sulv(L) xor to_sulv(R); 1322 else 1323 assert no_warning 1324 report fixed_generic_pkg'instance_name 1325 & """xor"": Range error L'RANGE /= R'RANGE" 1326 severity warning; 1327 RESULT := (others => 'X'); 1328 end if; 1329 return to_ufixed(RESULT, L'high, L'low); 1330 end function "xor"; 1331 1332 function "xnor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 1333 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1334 begin 1335 if (L'high = R'high and L'low = R'low) then 1336 RESULT := to_sulv(L) xnor to_sulv(R); 1337 else 1338 assert no_warning 1339 report fixed_generic_pkg'instance_name 1340 & """xnor"": Range error L'RANGE /= R'RANGE" 1341 severity warning; 1342 RESULT := (others => 'X'); 1343 end if; 1344 return to_ufixed(RESULT, L'high, L'low); 1345 end function "xnor"; 1346 1347 function "not" (L : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 1348 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1349 begin 1350 RESULT := not to_sulv(L); 1351 return to_sfixed(RESULT, L'high, L'low); 1352 end function "not"; 1353 1354 function "and" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 1355 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1356 begin 1357 if (L'high = R'high and L'low = R'low) then 1358 RESULT := to_sulv(L) and to_sulv(R); 1359 else 1360 assert no_warning 1361 report fixed_generic_pkg'instance_name 1362 & """and"": Range error L'RANGE /= R'RANGE" 1363 severity warning; 1364 RESULT := (others => 'X'); 1365 end if; 1366 return to_sfixed(RESULT, L'high, L'low); 1367 end function "and"; 1368 1369 function "or" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 1370 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1371 begin 1372 if (L'high = R'high and L'low = R'low) then 1373 RESULT := to_sulv(L) or to_sulv(R); 1374 else 1375 assert no_warning 1376 report fixed_generic_pkg'instance_name 1377 & """or"": Range error L'RANGE /= R'RANGE" 1378 severity warning; 1379 RESULT := (others => 'X'); 1380 end if; 1381 return to_sfixed(RESULT, L'high, L'low); 1382 end function "or"; 1383 1384 function "nand" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 1385 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1386 begin 1387 if (L'high = R'high and L'low = R'low) then 1388 RESULT := to_sulv(L) nand to_sulv(R); 1389 else 1390 assert no_warning 1391 report fixed_generic_pkg'instance_name 1392 & """nand"": Range error L'RANGE /= R'RANGE" 1393 severity warning; 1394 RESULT := (others => 'X'); 1395 end if; 1396 return to_sfixed(RESULT, L'high, L'low); 1397 end function "nand"; 1398 1399 function "nor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 1400 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1401 begin 1402 if (L'high = R'high and L'low = R'low) then 1403 RESULT := to_sulv(L) nor to_sulv(R); 1404 else 1405 assert no_warning 1406 report fixed_generic_pkg'instance_name 1407 & """nor"": Range error L'RANGE /= R'RANGE" 1408 severity warning; 1409 RESULT := (others => 'X'); 1410 end if; 1411 return to_sfixed(RESULT, L'high, L'low); 1412 end function "nor"; 1413 1414 function "xor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 1415 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1416 begin 1417 if (L'high = R'high and L'low = R'low) then 1418 RESULT := to_sulv(L) xor to_sulv(R); 1419 else 1420 assert no_warning 1421 report fixed_generic_pkg'instance_name 1422 & """xor"": Range error L'RANGE /= R'RANGE" 1423 severity warning; 1424 RESULT := (others => 'X'); 1425 end if; 1426 return to_sfixed(RESULT, L'high, L'low); 1427 end function "xor"; 1428 1429 function "xnor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 1430 variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto 1431 begin 1432 if (L'high = R'high and L'low = R'low) then 1433 RESULT := to_sulv(L) xnor to_sulv(R); 1434 else 1435 assert no_warning 1436 report fixed_generic_pkg'instance_name 1437 & """xnor"": Range error L'RANGE /= R'RANGE" 1438 severity warning; 1439 RESULT := (others => 'X'); 1440 end if; 1441 return to_sfixed(RESULT, L'high, L'low); 1442 end function "xnor"; 1443 1444 -- Vector and std_ulogic functions, same as functions in numeric_std 1445 function "and" (L : STD_ULOGIC; R : UNRESOLVED_ufixed) 1446 return UNRESOLVED_ufixed 1447 is 1448 variable result : UNRESOLVED_ufixed (R'range); 1449 begin 1450 for i in result'range loop 1451 result(i) := L and R(i); 1452 end loop; 1453 return result; 1454 end function "and"; 1455 1456 function "and" (L : UNRESOLVED_ufixed; R : STD_ULOGIC) 1457 return UNRESOLVED_ufixed 1458 is 1459 variable result : UNRESOLVED_ufixed (L'range); 1460 begin 1461 for i in result'range loop 1462 result(i) := L(i) and R; 1463 end loop; 1464 return result; 1465 end function "and"; 1466 1467 function "or" (L : STD_ULOGIC; R : UNRESOLVED_ufixed) 1468 return UNRESOLVED_ufixed 1469 is 1470 variable result : UNRESOLVED_ufixed (R'range); 1471 begin 1472 for i in result'range loop 1473 result(i) := L or R(i); 1474 end loop; 1475 return result; 1476 end function "or"; 1477 1478 function "or" (L : UNRESOLVED_ufixed; R : STD_ULOGIC) 1479 return UNRESOLVED_ufixed 1480 is 1481 variable result : UNRESOLVED_ufixed (L'range); 1482 begin 1483 for i in result'range loop 1484 result(i) := L(i) or R; 1485 end loop; 1486 return result; 1487 end function "or"; 1488 1489 function "nand" (L : STD_ULOGIC; R : UNRESOLVED_ufixed) 1490 return UNRESOLVED_ufixed 1491 is 1492 variable result : UNRESOLVED_ufixed (R'range); 1493 begin 1494 for i in result'range loop 1495 result(i) := L nand R(i); 1496 end loop; 1497 return result; 1498 end function "nand"; 1499 1500 function "nand" (L : UNRESOLVED_ufixed; R : STD_ULOGIC) 1501 return UNRESOLVED_ufixed 1502 is 1503 variable result : UNRESOLVED_ufixed (L'range); 1504 begin 1505 for i in result'range loop 1506 result(i) := L(i) nand R; 1507 end loop; 1508 return result; 1509 end function "nand"; 1510 1511 function "nor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed) 1512 return UNRESOLVED_ufixed 1513 is 1514 variable result : UNRESOLVED_ufixed (R'range); 1515 begin 1516 for i in result'range loop 1517 result(i) := L nor R(i); 1518 end loop; 1519 return result; 1520 end function "nor"; 1521 1522 function "nor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC) 1523 return UNRESOLVED_ufixed 1524 is 1525 variable result : UNRESOLVED_ufixed (L'range); 1526 begin 1527 for i in result'range loop 1528 result(i) := L(i) nor R; 1529 end loop; 1530 return result; 1531 end function "nor"; 1532 1533 function "xor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed) 1534 return UNRESOLVED_ufixed 1535 is 1536 variable result : UNRESOLVED_ufixed (R'range); 1537 begin 1538 for i in result'range loop 1539 result(i) := L xor R(i); 1540 end loop; 1541 return result; 1542 end function "xor"; 1543 1544 function "xor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC) 1545 return UNRESOLVED_ufixed 1546 is 1547 variable result : UNRESOLVED_ufixed (L'range); 1548 begin 1549 for i in result'range loop 1550 result(i) := L(i) xor R; 1551 end loop; 1552 return result; 1553 end function "xor"; 1554 1555 function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed) 1556 return UNRESOLVED_ufixed 1557 is 1558 variable result : UNRESOLVED_ufixed (R'range); 1559 begin 1560 for i in result'range loop 1561 result(i) := L xnor R(i); 1562 end loop; 1563 return result; 1564 end function "xnor"; 1565 1566 function "xnor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC) 1567 return UNRESOLVED_ufixed 1568 is 1569 variable result : UNRESOLVED_ufixed (L'range); 1570 begin 1571 for i in result'range loop 1572 result(i) := L(i) xnor R; 1573 end loop; 1574 return result; 1575 end function "xnor"; 1576 1577 function "and" (L : STD_ULOGIC; R : UNRESOLVED_sfixed) 1578 return UNRESOLVED_sfixed 1579 is 1580 variable result : UNRESOLVED_sfixed (R'range); 1581 begin 1582 for i in result'range loop 1583 result(i) := L and R(i); 1584 end loop; 1585 return result; 1586 end function "and"; 1587 1588 function "and" (L : UNRESOLVED_sfixed; R : STD_ULOGIC) 1589 return UNRESOLVED_sfixed 1590 is 1591 variable result : UNRESOLVED_sfixed (L'range); 1592 begin 1593 for i in result'range loop 1594 result(i) := L(i) and R; 1595 end loop; 1596 return result; 1597 end function "and"; 1598 1599 function "or" (L : STD_ULOGIC; R : UNRESOLVED_sfixed) 1600 return UNRESOLVED_sfixed 1601 is 1602 variable result : UNRESOLVED_sfixed (R'range); 1603 begin 1604 for i in result'range loop 1605 result(i) := L or R(i); 1606 end loop; 1607 return result; 1608 end function "or"; 1609 1610 function "or" (L : UNRESOLVED_sfixed; R : STD_ULOGIC) 1611 return UNRESOLVED_sfixed 1612 is 1613 variable result : UNRESOLVED_sfixed (L'range); 1614 begin 1615 for i in result'range loop 1616 result(i) := L(i) or R; 1617 end loop; 1618 return result; 1619 end function "or"; 1620 1621 function "nand" (L : STD_ULOGIC; R : UNRESOLVED_sfixed) 1622 return UNRESOLVED_sfixed 1623 is 1624 variable result : UNRESOLVED_sfixed (R'range); 1625 begin 1626 for i in result'range loop 1627 result(i) := L nand R(i); 1628 end loop; 1629 return result; 1630 end function "nand"; 1631 1632 function "nand" (L : UNRESOLVED_sfixed; R : STD_ULOGIC) 1633 return UNRESOLVED_sfixed 1634 is 1635 variable result : UNRESOLVED_sfixed (L'range); 1636 begin 1637 for i in result'range loop 1638 result(i) := L(i) nand R; 1639 end loop; 1640 return result; 1641 end function "nand"; 1642 1643 function "nor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed) 1644 return UNRESOLVED_sfixed 1645 is 1646 variable result : UNRESOLVED_sfixed (R'range); 1647 begin 1648 for i in result'range loop 1649 result(i) := L nor R(i); 1650 end loop; 1651 return result; 1652 end function "nor"; 1653 1654 function "nor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC) 1655 return UNRESOLVED_sfixed 1656 is 1657 variable result : UNRESOLVED_sfixed (L'range); 1658 begin 1659 for i in result'range loop 1660 result(i) := L(i) nor R; 1661 end loop; 1662 return result; 1663 end function "nor"; 1664 1665 function "xor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed) 1666 return UNRESOLVED_sfixed 1667 is 1668 variable result : UNRESOLVED_sfixed (R'range); 1669 begin 1670 for i in result'range loop 1671 result(i) := L xor R(i); 1672 end loop; 1673 return result; 1674 end function "xor"; 1675 1676 function "xor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC) 1677 return UNRESOLVED_sfixed 1678 is 1679 variable result : UNRESOLVED_sfixed (L'range); 1680 begin 1681 for i in result'range loop 1682 result(i) := L(i) xor R; 1683 end loop; 1684 return result; 1685 end function "xor"; 1686 1687 function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed) 1688 return UNRESOLVED_sfixed 1689 is 1690 variable result : UNRESOLVED_sfixed (R'range); 1691 begin 1692 for i in result'range loop 1693 result(i) := L xnor R(i); 1694 end loop; 1695 return result; 1696 end function "xnor"; 1697 1698 function "xnor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC) 1699 return UNRESOLVED_sfixed 1700 is 1701 variable result : UNRESOLVED_sfixed (L'range); 1702 begin 1703 for i in result'range loop 1704 result(i) := L(i) xnor R; 1705 end loop; 1706 return result; 1707 end function "xnor"; 1708 1709 -- Reduction operators 1710 function "and" (l : UNRESOLVED_ufixed) return STD_ULOGIC is 1711 begin 1712 return and to_sulv(l); 1713 end function "and"; 1714 1715 function "nand" (l : UNRESOLVED_ufixed) return STD_ULOGIC is 1716 begin 1717 return nand to_sulv(l); 1718 end function "nand"; 1719 1720 function "or" (l : UNRESOLVED_ufixed) return STD_ULOGIC is 1721 begin 1722 return or to_sulv(l); 1723 end function "or"; 1724 1725 function "nor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is 1726 begin 1727 return nor to_sulv(l); 1728 end function "nor"; 1729 1730 function "xor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is 1731 begin 1732 return xor to_sulv(l); 1733 end function "xor"; 1734 1735 function "xnor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is 1736 begin 1737 return xnor to_sulv(l); 1738 end function "xnor"; 1739 1740 function "and" (l : UNRESOLVED_sfixed) return STD_ULOGIC is 1741 begin 1742 return and to_sulv(l); 1743 end function "and"; 1744 1745 function "nand" (l : UNRESOLVED_sfixed) return STD_ULOGIC is 1746 begin 1747 return nand to_sulv(l); 1748 end function "nand"; 1749 1750 function "or" (l : UNRESOLVED_sfixed) return STD_ULOGIC is 1751 begin 1752 return or to_sulv(l); 1753 end function "or"; 1754 1755 function "nor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is 1756 begin 1757 return nor to_sulv(l); 1758 end function "nor"; 1759 1760 function "xor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is 1761 begin 1762 return xor to_sulv(l); 1763 end function "xor"; 1764 1765 function "xnor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is 1766 begin 1767 return xnor to_sulv(l); 1768 end function "xnor"; 1769 -- End reduction operators 1770 1771 function "?=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is 1772 constant left_index : INTEGER := maximum(L'high, R'high); 1773 constant right_index : INTEGER := mins(L'low, R'low); 1774 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 1775 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 1776 begin -- ?= 1777 if ((L'length < 1) or (R'length < 1)) then 1778 assert no_warning 1779 report fixed_generic_pkg'instance_name 1780 & """?="": null detected, returning X" 1781 severity warning; 1782 return 'X'; 1783 else 1784 lresize := resize (L, left_index, right_index); 1785 rresize := resize (R, left_index, right_index); 1786 lslv := to_uns (lresize); 1787 rslv := to_uns (rresize); 1788 return lslv ?= rslv; 1789 end if; 1790 end function "?="; 1791 1792 function "?/=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is 1793 constant left_index : INTEGER := maximum(L'high, R'high); 1794 constant right_index : INTEGER := mins(L'low, R'low); 1795 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 1796 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 1797 begin -- ?/= 1798 if ((L'length < 1) or (R'length < 1)) then 1799 assert no_warning 1800 report fixed_generic_pkg'instance_name 1801 & """?/="": null detected, returning X" 1802 severity warning; 1803 return 'X'; 1804 else 1805 lresize := resize (L, left_index, right_index); 1806 rresize := resize (R, left_index, right_index); 1807 lslv := to_uns (lresize); 1808 rslv := to_uns (rresize); 1809 return lslv ?/= rslv; 1810 end if; 1811 end function "?/="; 1812 1813 function "?>" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is 1814 constant left_index : INTEGER := maximum(L'high, R'high); 1815 constant right_index : INTEGER := mins(L'low, R'low); 1816 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 1817 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 1818 begin -- ?> 1819 if ((L'length < 1) or (R'length < 1)) then 1820 assert no_warning 1821 report fixed_generic_pkg'instance_name 1822 & """?>"": null detected, returning X" 1823 severity warning; 1824 return 'X'; 1825 else 1826 lresize := resize (L, left_index, right_index); 1827 rresize := resize (R, left_index, right_index); 1828 lslv := to_uns (lresize); 1829 rslv := to_uns (rresize); 1830 return lslv ?> rslv; 1831 end if; 1832 end function "?>"; 1833 1834 function "?>=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is 1835 constant left_index : INTEGER := maximum(L'high, R'high); 1836 constant right_index : INTEGER := mins(L'low, R'low); 1837 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 1838 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 1839 begin -- ?>= 1840 if ((L'length < 1) or (R'length < 1)) then 1841 assert no_warning 1842 report fixed_generic_pkg'instance_name 1843 & """?>="": null detected, returning X" 1844 severity warning; 1845 return 'X'; 1846 else 1847 lresize := resize (L, left_index, right_index); 1848 rresize := resize (R, left_index, right_index); 1849 lslv := to_uns (lresize); 1850 rslv := to_uns (rresize); 1851 return lslv ?>= rslv; 1852 end if; 1853 end function "?>="; 1854 1855 function "?<" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is 1856 constant left_index : INTEGER := maximum(L'high, R'high); 1857 constant right_index : INTEGER := mins(L'low, R'low); 1858 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 1859 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 1860 begin -- ?< 1861 if ((L'length < 1) or (R'length < 1)) then 1862 assert no_warning 1863 report fixed_generic_pkg'instance_name 1864 & """?<"": null detected, returning X" 1865 severity warning; 1866 return 'X'; 1867 else 1868 lresize := resize (L, left_index, right_index); 1869 rresize := resize (R, left_index, right_index); 1870 lslv := to_uns (lresize); 1871 rslv := to_uns (rresize); 1872 return lslv ?< rslv; 1873 end if; 1874 end function "?<"; 1875 1876 function "?<=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is 1877 constant left_index : INTEGER := maximum(L'high, R'high); 1878 constant right_index : INTEGER := mins(L'low, R'low); 1879 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 1880 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 1881 begin -- ?<= 1882 if ((L'length < 1) or (R'length < 1)) then 1883 assert no_warning 1884 report fixed_generic_pkg'instance_name 1885 & """?<="": null detected, returning X" 1886 severity warning; 1887 return 'X'; 1888 else 1889 lresize := resize (L, left_index, right_index); 1890 rresize := resize (R, left_index, right_index); 1891 lslv := to_uns (lresize); 1892 rslv := to_uns (rresize); 1893 return lslv ?<= rslv; 1894 end if; 1895 end function "?<="; 1896 1897 function "?=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is 1898 constant left_index : INTEGER := maximum(L'high, R'high); 1899 constant right_index : INTEGER := mins(L'low, R'low); 1900 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 1901 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 1902 begin -- ?= 1903 if ((L'length < 1) or (R'length < 1)) then 1904 assert no_warning 1905 report fixed_generic_pkg'instance_name 1906 & """?="": null detected, returning X" 1907 severity warning; 1908 return 'X'; 1909 else 1910 lresize := resize (L, left_index, right_index); 1911 rresize := resize (R, left_index, right_index); 1912 lslv := to_s (lresize); 1913 rslv := to_s (rresize); 1914 return lslv ?= rslv; 1915 end if; 1916 end function "?="; 1917 1918 function "?/=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is 1919 constant left_index : INTEGER := maximum(L'high, R'high); 1920 constant right_index : INTEGER := mins(L'low, R'low); 1921 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 1922 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 1923 begin -- ?/= 1924 if ((L'length < 1) or (R'length < 1)) then 1925 assert no_warning 1926 report fixed_generic_pkg'instance_name 1927 & """?/="": null detected, returning X" 1928 severity warning; 1929 return 'X'; 1930 else 1931 lresize := resize (L, left_index, right_index); 1932 rresize := resize (R, left_index, right_index); 1933 lslv := to_s (lresize); 1934 rslv := to_s (rresize); 1935 return lslv ?/= rslv; 1936 end if; 1937 end function "?/="; 1938 1939 function "?>" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is 1940 constant left_index : INTEGER := maximum(L'high, R'high); 1941 constant right_index : INTEGER := mins(L'low, R'low); 1942 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 1943 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 1944 begin -- ?> 1945 if ((L'length < 1) or (R'length < 1)) then 1946 assert no_warning 1947 report fixed_generic_pkg'instance_name 1948 & """?>"": null detected, returning X" 1949 severity warning; 1950 return 'X'; 1951 else 1952 lresize := resize (L, left_index, right_index); 1953 rresize := resize (R, left_index, right_index); 1954 lslv := to_s (lresize); 1955 rslv := to_s (rresize); 1956 return lslv ?> rslv; 1957 end if; 1958 end function "?>"; 1959 1960 function "?>=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is 1961 constant left_index : INTEGER := maximum(L'high, R'high); 1962 constant right_index : INTEGER := mins(L'low, R'low); 1963 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 1964 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 1965 begin -- ?>= 1966 if ((L'length < 1) or (R'length < 1)) then 1967 assert no_warning 1968 report fixed_generic_pkg'instance_name 1969 & """?>="": null detected, returning X" 1970 severity warning; 1971 return 'X'; 1972 else 1973 lresize := resize (L, left_index, right_index); 1974 rresize := resize (R, left_index, right_index); 1975 lslv := to_s (lresize); 1976 rslv := to_s (rresize); 1977 return lslv ?>= rslv; 1978 end if; 1979 end function "?>="; 1980 1981 function "?<" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is 1982 constant left_index : INTEGER := maximum(L'high, R'high); 1983 constant right_index : INTEGER := mins(L'low, R'low); 1984 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 1985 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 1986 begin -- ?< 1987 if ((L'length < 1) or (R'length < 1)) then 1988 assert no_warning 1989 report fixed_generic_pkg'instance_name 1990 & """?<"": null detected, returning X" 1991 severity warning; 1992 return 'X'; 1993 else 1994 lresize := resize (L, left_index, right_index); 1995 rresize := resize (R, left_index, right_index); 1996 lslv := to_s (lresize); 1997 rslv := to_s (rresize); 1998 return lslv ?< rslv; 1999 end if; 2000 end function "?<"; 2001 2002 function "?<=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is 2003 constant left_index : INTEGER := maximum(L'high, R'high); 2004 constant right_index : INTEGER := mins(L'low, R'low); 2005 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2006 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 2007 begin -- ?<= 2008 if ((L'length < 1) or (R'length < 1)) then 2009 assert no_warning 2010 report fixed_generic_pkg'instance_name 2011 & """?<="": null detected, returning X" 2012 severity warning; 2013 return 'X'; 2014 else 2015 lresize := resize (L, left_index, right_index); 2016 rresize := resize (R, left_index, right_index); 2017 lslv := to_s (lresize); 2018 rslv := to_s (rresize); 2019 return lslv ?<= rslv; 2020 end if; 2021 end function "?<="; 2022 2023 -- Match function, similar to "std_match" from numeric_std 2024 function std_match (L, R : UNRESOLVED_ufixed) return BOOLEAN is 2025 begin 2026 if (L'high = R'high and L'low = R'low) then 2027 return std_match(to_sulv(L), to_sulv(R)); 2028 else 2029 assert no_warning 2030 report fixed_generic_pkg'instance_name 2031 & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE" 2032 severity warning; 2033 return false; 2034 end if; 2035 end function std_match; 2036 2037 function std_match (L, R : UNRESOLVED_sfixed) return BOOLEAN is 2038 begin 2039 if (L'high = R'high and L'low = R'low) then 2040 return std_match(to_sulv(L), to_sulv(R)); 2041 else 2042 assert no_warning 2043 report fixed_generic_pkg'instance_name 2044 & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE" 2045 severity warning; 2046 return false; 2047 end if; 2048 end function std_match; 2049 2050 -- compare functions 2051 function "=" ( 2052 l, r : UNRESOLVED_ufixed) -- fixed point input 2053 return BOOLEAN 2054 is 2055 constant left_index : INTEGER := maximum(l'high, r'high); 2056 constant right_index : INTEGER := mins(l'low, r'low); 2057 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 2058 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 2059 begin 2060 if (l'length < 1 or r'length < 1) then 2061 assert no_warning 2062 report fixed_generic_pkg'instance_name 2063 & """="": null argument detected, returning FALSE" 2064 severity warning; 2065 return false; 2066 elsif (Is_X(l) or Is_X(r)) then 2067 assert no_warning 2068 report fixed_generic_pkg'instance_name 2069 & """="": metavalue detected, returning FALSE" 2070 severity warning; 2071 return false; 2072 end if; 2073 lresize := resize (l, left_index, right_index); 2074 rresize := resize (r, left_index, right_index); 2075 lslv := to_uns (lresize); 2076 rslv := to_uns (rresize); 2077 return lslv = rslv; 2078 end function "="; 2079 2080 function "=" ( 2081 l, r : UNRESOLVED_sfixed) -- fixed point input 2082 return BOOLEAN 2083 is 2084 constant left_index : INTEGER := maximum(l'high, r'high); 2085 constant right_index : INTEGER := mins(l'low, r'low); 2086 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2087 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 2088 begin 2089 if (l'length < 1 or r'length < 1) then 2090 assert no_warning 2091 report fixed_generic_pkg'instance_name 2092 & """="": null argument detected, returning FALSE" 2093 severity warning; 2094 return false; 2095 elsif (Is_X(l) or Is_X(r)) then 2096 assert no_warning 2097 report fixed_generic_pkg'instance_name 2098 & """="": metavalue detected, returning FALSE" 2099 severity warning; 2100 return false; 2101 end if; 2102 lresize := resize (l, left_index, right_index); 2103 rresize := resize (r, left_index, right_index); 2104 lslv := to_s (lresize); 2105 rslv := to_s (rresize); 2106 return lslv = rslv; 2107 end function "="; 2108 2109 function "/=" ( 2110 l, r : UNRESOLVED_ufixed) -- fixed point input 2111 return BOOLEAN 2112 is 2113 constant left_index : INTEGER := maximum(l'high, r'high); 2114 constant right_index : INTEGER := mins(l'low, r'low); 2115 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 2116 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 2117 begin 2118 if (l'length < 1 or r'length < 1) then 2119 assert no_warning 2120 report fixed_generic_pkg'instance_name 2121 & """/="": null argument detected, returning TRUE" 2122 severity warning; 2123 return true; 2124 elsif (Is_X(l) or Is_X(r)) then 2125 assert no_warning 2126 report fixed_generic_pkg'instance_name 2127 & """/="": metavalue detected, returning TRUE" 2128 severity warning; 2129 return true; 2130 end if; 2131 lresize := resize (l, left_index, right_index); 2132 rresize := resize (r, left_index, right_index); 2133 lslv := to_uns (lresize); 2134 rslv := to_uns (rresize); 2135 return lslv /= rslv; 2136 end function "/="; 2137 2138 function "/=" ( 2139 l, r : UNRESOLVED_sfixed) -- fixed point input 2140 return BOOLEAN 2141 is 2142 constant left_index : INTEGER := maximum(l'high, r'high); 2143 constant right_index : INTEGER := mins(l'low, r'low); 2144 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2145 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 2146 begin 2147 if (l'length < 1 or r'length < 1) then 2148 assert no_warning 2149 report fixed_generic_pkg'instance_name 2150 & """/="": null argument detected, returning TRUE" 2151 severity warning; 2152 return true; 2153 elsif (Is_X(l) or Is_X(r)) then 2154 assert no_warning 2155 report fixed_generic_pkg'instance_name 2156 & """/="": metavalue detected, returning TRUE" 2157 severity warning; 2158 return true; 2159 end if; 2160 lresize := resize (l, left_index, right_index); 2161 rresize := resize (r, left_index, right_index); 2162 lslv := to_s (lresize); 2163 rslv := to_s (rresize); 2164 return lslv /= rslv; 2165 end function "/="; 2166 2167 function ">" ( 2168 l, r : UNRESOLVED_ufixed) -- fixed point input 2169 return BOOLEAN 2170 is 2171 constant left_index : INTEGER := maximum(l'high, r'high); 2172 constant right_index : INTEGER := mins(l'low, r'low); 2173 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 2174 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 2175 begin 2176 if (l'length < 1 or r'length < 1) then 2177 assert no_warning 2178 report fixed_generic_pkg'instance_name 2179 & """>"": null argument detected, returning FALSE" 2180 severity warning; 2181 return false; 2182 elsif (Is_X(l) or Is_X(r)) then 2183 assert no_warning 2184 report fixed_generic_pkg'instance_name 2185 & """>"": metavalue detected, returning FALSE" 2186 severity warning; 2187 return false; 2188 end if; 2189 lresize := resize (l, left_index, right_index); 2190 rresize := resize (r, left_index, right_index); 2191 lslv := to_uns (lresize); 2192 rslv := to_uns (rresize); 2193 return lslv > rslv; 2194 end function ">"; 2195 2196 function ">" ( 2197 l, r : UNRESOLVED_sfixed) -- fixed point input 2198 return BOOLEAN 2199 is 2200 constant left_index : INTEGER := maximum(l'high, r'high); 2201 constant right_index : INTEGER := mins(l'low, r'low); 2202 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2203 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 2204 begin 2205 if (l'length < 1 or r'length < 1) then 2206 assert no_warning 2207 report fixed_generic_pkg'instance_name 2208 & """>"": null argument detected, returning FALSE" 2209 severity warning; 2210 return false; 2211 elsif (Is_X(l) or Is_X(r)) then 2212 assert no_warning 2213 report fixed_generic_pkg'instance_name 2214 & """>"": metavalue detected, returning FALSE" 2215 severity warning; 2216 return false; 2217 end if; 2218 lresize := resize (l, left_index, right_index); 2219 rresize := resize (r, left_index, right_index); 2220 lslv := to_s (lresize); 2221 rslv := to_s (rresize); 2222 return lslv > rslv; 2223 end function ">"; 2224 2225 function "<" ( 2226 l, r : UNRESOLVED_ufixed) -- fixed point input 2227 return BOOLEAN 2228 is 2229 constant left_index : INTEGER := maximum(l'high, r'high); 2230 constant right_index : INTEGER := mins(l'low, r'low); 2231 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 2232 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 2233 begin 2234 if (l'length < 1 or r'length < 1) then 2235 assert no_warning 2236 report fixed_generic_pkg'instance_name 2237 & """<"": null argument detected, returning FALSE" 2238 severity warning; 2239 return false; 2240 elsif (Is_X(l) or Is_X(r)) then 2241 assert no_warning 2242 report fixed_generic_pkg'instance_name 2243 & """<"": metavalue detected, returning FALSE" 2244 severity warning; 2245 return false; 2246 end if; 2247 lresize := resize (l, left_index, right_index); 2248 rresize := resize (r, left_index, right_index); 2249 lslv := to_uns (lresize); 2250 rslv := to_uns (rresize); 2251 return lslv < rslv; 2252 end function "<"; 2253 2254 function "<" ( 2255 l, r : UNRESOLVED_sfixed) -- fixed point input 2256 return BOOLEAN 2257 is 2258 constant left_index : INTEGER := maximum(l'high, r'high); 2259 constant right_index : INTEGER := mins(l'low, r'low); 2260 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2261 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 2262 begin 2263 if (l'length < 1 or r'length < 1) then 2264 assert no_warning 2265 report fixed_generic_pkg'instance_name 2266 & """<"": null argument detected, returning FALSE" 2267 severity warning; 2268 return false; 2269 elsif (Is_X(l) or Is_X(r)) then 2270 assert no_warning 2271 report fixed_generic_pkg'instance_name 2272 & """<"": metavalue detected, returning FALSE" 2273 severity warning; 2274 return false; 2275 end if; 2276 lresize := resize (l, left_index, right_index); 2277 rresize := resize (r, left_index, right_index); 2278 lslv := to_s (lresize); 2279 rslv := to_s (rresize); 2280 return lslv < rslv; 2281 end function "<"; 2282 2283 function ">=" ( 2284 l, r : UNRESOLVED_ufixed) -- fixed point input 2285 return BOOLEAN 2286 is 2287 constant left_index : INTEGER := maximum(l'high, r'high); 2288 constant right_index : INTEGER := mins(l'low, r'low); 2289 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 2290 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 2291 begin 2292 if (l'length < 1 or r'length < 1) then 2293 assert no_warning 2294 report fixed_generic_pkg'instance_name 2295 & """>="": null argument detected, returning FALSE" 2296 severity warning; 2297 return false; 2298 elsif (Is_X(l) or Is_X(r)) then 2299 assert no_warning 2300 report fixed_generic_pkg'instance_name 2301 & """>="": metavalue detected, returning FALSE" 2302 severity warning; 2303 return false; 2304 end if; 2305 lresize := resize (l, left_index, right_index); 2306 rresize := resize (r, left_index, right_index); 2307 lslv := to_uns (lresize); 2308 rslv := to_uns (rresize); 2309 return lslv >= rslv; 2310 end function ">="; 2311 2312 function ">=" ( 2313 l, r : UNRESOLVED_sfixed) -- fixed point input 2314 return BOOLEAN 2315 is 2316 constant left_index : INTEGER := maximum(l'high, r'high); 2317 constant right_index : INTEGER := mins(l'low, r'low); 2318 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2319 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 2320 begin 2321 if (l'length < 1 or r'length < 1) then 2322 assert no_warning 2323 report fixed_generic_pkg'instance_name 2324 & """>="": null argument detected, returning FALSE" 2325 severity warning; 2326 return false; 2327 elsif (Is_X(l) or Is_X(r)) then 2328 assert no_warning 2329 report fixed_generic_pkg'instance_name 2330 & """>="": metavalue detected, returning FALSE" 2331 severity warning; 2332 return false; 2333 end if; 2334 lresize := resize (l, left_index, right_index); 2335 rresize := resize (r, left_index, right_index); 2336 lslv := to_s (lresize); 2337 rslv := to_s (rresize); 2338 return lslv >= rslv; 2339 end function ">="; 2340 2341 function "<=" ( 2342 l, r : UNRESOLVED_ufixed) -- fixed point input 2343 return BOOLEAN 2344 is 2345 constant left_index : INTEGER := maximum(l'high, r'high); 2346 constant right_index : INTEGER := mins(l'low, r'low); 2347 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 2348 variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0); 2349 begin 2350 if (l'length < 1 or r'length < 1) then 2351 assert no_warning 2352 report fixed_generic_pkg'instance_name 2353 & """<="": null argument detected, returning FALSE" 2354 severity warning; 2355 return false; 2356 elsif (Is_X(l) or Is_X(r)) then 2357 assert no_warning 2358 report fixed_generic_pkg'instance_name 2359 & """<="": metavalue detected, returning FALSE" 2360 severity warning; 2361 return false; 2362 end if; 2363 lresize := resize (l, left_index, right_index); 2364 rresize := resize (r, left_index, right_index); 2365 lslv := to_uns (lresize); 2366 rslv := to_uns (rresize); 2367 return lslv <= rslv; 2368 end function "<="; 2369 2370 function "<=" ( 2371 l, r : UNRESOLVED_sfixed) -- fixed point input 2372 return BOOLEAN 2373 is 2374 constant left_index : INTEGER := maximum(l'high, r'high); 2375 constant right_index : INTEGER := mins(l'low, r'low); 2376 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2377 variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0); 2378 begin 2379 if (l'length < 1 or r'length < 1) then 2380 assert no_warning 2381 report fixed_generic_pkg'instance_name 2382 & """<="": null argument detected, returning FALSE" 2383 severity warning; 2384 return false; 2385 elsif (Is_X(l) or Is_X(r)) then 2386 assert no_warning 2387 report fixed_generic_pkg'instance_name 2388 & """<="": metavalue detected, returning FALSE" 2389 severity warning; 2390 return false; 2391 end if; 2392 lresize := resize (l, left_index, right_index); 2393 rresize := resize (r, left_index, right_index); 2394 lslv := to_s (lresize); 2395 rslv := to_s (rresize); 2396 return lslv <= rslv; 2397 end function "<="; 2398 2399 -- overloads of the default maximum and minimum functions 2400 function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 2401 constant left_index : INTEGER := maximum(l'high, r'high); 2402 constant right_index : INTEGER := mins(l'low, r'low); 2403 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 2404 begin 2405 if (l'length < 1 or r'length < 1) then 2406 return NAUF; 2407 end if; 2408 lresize := resize (l, left_index, right_index); 2409 rresize := resize (r, left_index, right_index); 2410 return to_fixed(maximum(to_uns(lresize), to_uns(rresize)), 2411 left_index, right_index); 2412 end function maximum; 2413 2414 function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 2415 constant left_index : INTEGER := maximum(l'high, r'high); 2416 constant right_index : INTEGER := mins(l'low, r'low); 2417 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2418 begin 2419 if (l'length < 1 or r'length < 1) then 2420 return NASF; 2421 end if; 2422 lresize := resize (l, left_index, right_index); 2423 rresize := resize (r, left_index, right_index); 2424 return to_fixed(maximum(to_s(lresize), to_s(rresize)), 2425 left_index, right_index); 2426 end function maximum; 2427 2428 function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is 2429 constant left_index : INTEGER := maximum(l'high, r'high); 2430 constant right_index : INTEGER := mins(l'low, r'low); 2431 variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index); 2432 begin 2433 if (l'length < 1 or r'length < 1) then 2434 return NAUF; 2435 end if; 2436 lresize := resize (l, left_index, right_index); 2437 rresize := resize (r, left_index, right_index); 2438 return to_fixed(minimum(to_uns(lresize), to_uns(rresize)), 2439 left_index, right_index); 2440 end function minimum; 2441 2442 function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is 2443 constant left_index : INTEGER := maximum(l'high, r'high); 2444 constant right_index : INTEGER := mins(l'low, r'low); 2445 variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index); 2446 begin 2447 if (l'length < 1 or r'length < 1) then 2448 return NASF; 2449 end if; 2450 lresize := resize (l, left_index, right_index); 2451 rresize := resize (r, left_index, right_index); 2452 return to_fixed(minimum(to_s(lresize), to_s(rresize)), 2453 left_index, right_index); 2454 end function minimum; 2455 2456 function to_ufixed ( 2457 arg : NATURAL; -- integer 2458 constant left_index : INTEGER; -- left index (high index) 2459 constant right_index : INTEGER := 0; -- right index 2460 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 2461 constant round_style : fixed_round_style_type := fixed_round_style) 2462 return UNRESOLVED_ufixed 2463 is 2464 constant fw : INTEGER := mins (right_index, right_index); -- catch literals 2465 variable result : UNRESOLVED_ufixed (left_index downto fw); 2466 variable sresult : UNRESOLVED_ufixed (left_index downto 0) := 2467 (others => '0'); -- integer portion 2468 variable argx : NATURAL; -- internal version of arg 2469 begin 2470 if (result'length < 1) then 2471 return NAUF; 2472 end if; 2473 if arg /= 0 then 2474 argx := arg; 2475 for I in 0 to sresult'left loop 2476 if (argx mod 2) = 0 then 2477 sresult(I) := '0'; 2478 else 2479 sresult(I) := '1'; 2480 end if; 2481 argx := argx/2; 2482 end loop; 2483 if argx /= 0 then 2484 assert no_warning 2485 report fixed_generic_pkg'instance_name 2486 & "TO_UFIXED(NATURAL): vector truncated" 2487 severity warning; 2488 if overflow_style = fixed_saturate then 2489 return saturate (left_index, right_index); 2490 end if; 2491 end if; 2492 result := resize (arg => sresult, 2493 left_index => left_index, 2494 right_index => right_index, 2495 round_style => round_style, 2496 overflow_style => overflow_style); 2497 else 2498 result := (others => '0'); 2499 end if; 2500 return result; 2501 end function to_ufixed; 2502 2503 function to_sfixed ( 2504 arg : INTEGER; -- integer 2505 constant left_index : INTEGER; -- left index (high index) 2506 constant right_index : INTEGER := 0; -- right index 2507 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 2508 constant round_style : fixed_round_style_type := fixed_round_style) 2509 return UNRESOLVED_sfixed 2510 is 2511 constant fw : INTEGER := mins (right_index, right_index); -- catch literals 2512 variable result : UNRESOLVED_sfixed (left_index downto fw); 2513 variable sresult : UNRESOLVED_sfixed (left_index downto 0) := 2514 (others => '0'); -- integer portion 2515 variable argx : INTEGER; -- internal version of arg 2516 variable sign : STD_ULOGIC; -- sign of input 2517 begin 2518 if (result'length < 1) then -- null range 2519 return NASF; 2520 end if; 2521 if arg /= 0 then 2522 if (arg < 0) then 2523 sign := '1'; 2524 argx := -(arg + 1); 2525 else 2526 sign := '0'; 2527 argx := arg; 2528 end if; 2529 for I in 0 to sresult'left loop 2530 if (argx mod 2) = 0 then 2531 sresult(I) := sign; 2532 else 2533 sresult(I) := not sign; 2534 end if; 2535 argx := argx/2; 2536 end loop; 2537 if argx /= 0 or left_index < 0 or sign /= sresult(sresult'left) then 2538 assert no_warning 2539 report fixed_generic_pkg'instance_name 2540 & "TO_SFIXED(INTEGER): vector truncated" 2541 severity warning; 2542 if overflow_style = fixed_saturate then -- saturate 2543 if arg < 0 then 2544 result := not saturate (result'high, result'low); -- underflow 2545 else 2546 result := saturate (result'high, result'low); -- overflow 2547 end if; 2548 return result; 2549 end if; 2550 end if; 2551 result := resize (arg => sresult, 2552 left_index => left_index, 2553 right_index => right_index, 2554 round_style => round_style, 2555 overflow_style => overflow_style); 2556 else 2557 result := (others => '0'); 2558 end if; 2559 return result; 2560 end function to_sfixed; 2561 2562 function to_ufixed ( 2563 arg : REAL; -- real 2564 constant left_index : INTEGER; -- left index (high index) 2565 constant right_index : INTEGER; -- right index 2566 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 2567 constant round_style : fixed_round_style_type := fixed_round_style; 2568 constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits 2569 return UNRESOLVED_ufixed 2570 is 2571 constant fw : INTEGER := mins (right_index, right_index); -- catch literals 2572 variable result : UNRESOLVED_ufixed (left_index downto fw) := 2573 (others => '0'); 2574 variable Xresult : UNRESOLVED_ufixed (left_index downto 2575 fw-guard_bits) := 2576 (others => '0'); 2577 variable presult : REAL; 2578 begin 2579 -- If negative or null range, return. 2580 if (left_index < fw) then 2581 return NAUF; 2582 end if; 2583 if (arg < 0.0) then 2584 report fixed_generic_pkg'instance_name 2585 & "TO_UFIXED: Negative argument passed " 2586 & REAL'image(arg) severity error; 2587 return result; 2588 end if; 2589 presult := arg; 2590 if presult >= (2.0**(left_index+1)) then 2591 assert no_warning report fixed_generic_pkg'instance_name 2592 & "TO_UFIXED(REAL): vector truncated" 2593 severity warning; 2594 if overflow_style = fixed_wrap then 2595 presult := presult mod (2.0**(left_index+1)); -- wrap 2596 else 2597 return saturate (result'high, result'low); 2598 end if; 2599 end if; 2600 for i in Xresult'range loop 2601 if presult >= 2.0**i then 2602 Xresult(i) := '1'; 2603 presult := presult - 2.0**i; 2604 else 2605 Xresult(i) := '0'; 2606 end if; 2607 end loop; 2608 if guard_bits > 0 and round_style = fixed_round then 2609 result := round_fixed (arg => Xresult (left_index 2610 downto right_index), 2611 remainder => Xresult (right_index-1 downto 2612 right_index-guard_bits), 2613 overflow_style => overflow_style); 2614 else 2615 result := Xresult (result'range); 2616 end if; 2617 return result; 2618 end function to_ufixed; 2619 2620 function to_sfixed ( 2621 arg : REAL; -- real 2622 constant left_index : INTEGER; -- left index (high index) 2623 constant right_index : INTEGER; -- right index 2624 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 2625 constant round_style : fixed_round_style_type := fixed_round_style; 2626 constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits 2627 return UNRESOLVED_sfixed 2628 is 2629 constant fw : INTEGER := mins (right_index, right_index); -- catch literals 2630 variable result : UNRESOLVED_sfixed (left_index downto fw) := 2631 (others => '0'); 2632 variable Xresult : UNRESOLVED_sfixed (left_index+1 downto fw-guard_bits) := 2633 (others => '0'); 2634 variable presult : REAL; 2635 begin 2636 if (left_index < fw) then -- null range 2637 return NASF; 2638 end if; 2639 if (arg >= (2.0**left_index) or arg < -(2.0**left_index)) then 2640 assert no_warning report fixed_generic_pkg'instance_name 2641 & "TO_SFIXED(REAL): vector truncated" 2642 severity warning; 2643 if overflow_style = fixed_saturate then 2644 if arg < 0.0 then -- saturate 2645 result := not saturate (result'high, result'low); -- underflow 2646 else 2647 result := saturate (result'high, result'low); -- overflow 2648 end if; 2649 return result; 2650 else 2651 presult := abs(arg) mod (2.0**(left_index+1)); -- wrap 2652 end if; 2653 else 2654 presult := abs(arg); 2655 end if; 2656 for i in Xresult'range loop 2657 if presult >= 2.0**i then 2658 Xresult(i) := '1'; 2659 presult := presult - 2.0**i; 2660 else 2661 Xresult(i) := '0'; 2662 end if; 2663 end loop; 2664 if arg < 0.0 then 2665 Xresult := to_fixed(-to_s(Xresult), Xresult'high, Xresult'low); 2666 end if; 2667 if guard_bits > 0 and round_style = fixed_round then 2668 result := round_fixed (arg => Xresult (left_index 2669 downto right_index), 2670 remainder => Xresult (right_index-1 downto 2671 right_index-guard_bits), 2672 overflow_style => overflow_style); 2673 else 2674 result := Xresult (result'range); 2675 end if; 2676 return result; 2677 end function to_sfixed; 2678 2679 function to_ufixed ( 2680 arg : UNRESOLVED_UNSIGNED; -- unsigned 2681 constant left_index : INTEGER; -- left index (high index) 2682 constant right_index : INTEGER := 0; -- right index 2683 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 2684 constant round_style : fixed_round_style_type := fixed_round_style) 2685 return UNRESOLVED_ufixed 2686 is 2687 constant ARG_LEFT : INTEGER := arg'length-1; 2688 alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg; 2689 variable result : UNRESOLVED_ufixed (left_index downto right_index); 2690 begin 2691 if arg'length < 1 or (left_index < right_index) then 2692 return NAUF; 2693 end if; 2694 result := resize (arg => UNRESOLVED_ufixed (XARG), 2695 left_index => left_index, 2696 right_index => right_index, 2697 round_style => round_style, 2698 overflow_style => overflow_style); 2699 return result; 2700 end function to_ufixed; 2701 2702 -- converted version 2703 function to_ufixed ( 2704 arg : UNRESOLVED_UNSIGNED) -- unsigned 2705 return UNRESOLVED_ufixed 2706 is 2707 constant ARG_LEFT : INTEGER := arg'length-1; 2708 alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg; 2709 begin 2710 if arg'length < 1 then 2711 return NAUF; 2712 end if; 2713 return UNRESOLVED_ufixed(XARG); 2714 end function to_ufixed; 2715 2716 function to_sfixed ( 2717 arg : UNRESOLVED_SIGNED; -- signed 2718 constant left_index : INTEGER; -- left index (high index) 2719 constant right_index : INTEGER := 0; -- right index 2720 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 2721 constant round_style : fixed_round_style_type := fixed_round_style) 2722 return UNRESOLVED_sfixed 2723 is 2724 constant ARG_LEFT : INTEGER := arg'length-1; 2725 alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg; 2726 variable result : UNRESOLVED_sfixed (left_index downto right_index); 2727 begin 2728 if arg'length < 1 or (left_index < right_index) then 2729 return NASF; 2730 end if; 2731 result := resize (arg => UNRESOLVED_sfixed (XARG), 2732 left_index => left_index, 2733 right_index => right_index, 2734 round_style => round_style, 2735 overflow_style => overflow_style); 2736 return result; 2737 end function to_sfixed; 2738 2739 -- converted version 2740 function to_sfixed ( 2741 arg : UNRESOLVED_SIGNED) -- signed 2742 return UNRESOLVED_sfixed 2743 is 2744 constant ARG_LEFT : INTEGER := arg'length-1; 2745 alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg; 2746 begin 2747 if arg'length < 1 then 2748 return NASF; 2749 end if; 2750 return UNRESOLVED_sfixed(XARG); 2751 end function to_sfixed; 2752 2753 function to_sfixed (arg : UNRESOLVED_ufixed) return UNRESOLVED_sfixed is 2754 variable result : UNRESOLVED_sfixed (arg'high+1 downto arg'low); 2755 begin 2756 if arg'length < 1 then 2757 return NASF; 2758 end if; 2759 result (arg'high downto arg'low) := UNRESOLVED_sfixed(cleanvec(arg)); 2760 result (arg'high+1) := '0'; 2761 return result; 2762 end function to_sfixed; 2763 2764 -- Because of the fairly complicated sizing rules in the fixed point 2765 -- packages these functions are provided to compute the result ranges 2766 -- Example: 2767 -- signal uf1 : ufixed (3 downto -3); 2768 -- signal uf2 : ufixed (4 downto -2); 2769 -- signal uf1multuf2 : ufixed (ufixed_high (3, -3, '*', 4, -2) downto 2770 -- ufixed_low (3, -3, '*', 4, -2)); 2771 -- uf1multuf2 <= uf1 * uf2; 2772 -- Valid characters: '+', '-', '*', '/', 'r' or 'R' (rem), 'm' or 'M' (mod), 2773 -- '1' (reciprocal), 'A', 'a' (abs), 'N', 'n' (-sfixed) 2774 function ufixed_high (left_index, right_index : INTEGER; 2775 operation : CHARACTER := 'X'; 2776 left_index2, right_index2 : INTEGER := 0) 2777 return INTEGER is 2778 begin 2779 case operation is 2780 when '+'| '-' => return maximum (left_index, left_index2) + 1; 2781 when '*' => return left_index + left_index2 + 1; 2782 when '/' => return left_index - right_index2; 2783 when '1' => return -right_index; -- reciprocal 2784 when 'R'|'r' => return mins (left_index, left_index2); -- "rem" 2785 when 'M'|'m' => return mins (left_index, left_index2); -- "mod" 2786 when others => return left_index; -- For abs and default 2787 end case; 2788 end function ufixed_high; 2789 2790 function ufixed_low (left_index, right_index : INTEGER; 2791 operation : CHARACTER := 'X'; 2792 left_index2, right_index2 : INTEGER := 0) 2793 return INTEGER is 2794 begin 2795 case operation is 2796 when '+'| '-' => return mins (right_index, right_index2); 2797 when '*' => return right_index + right_index2; 2798 when '/' => return right_index - left_index2 - 1; 2799 when '1' => return -left_index - 1; -- reciprocal 2800 when 'R'|'r' => return mins (right_index, right_index2); -- "rem" 2801 when 'M'|'m' => return mins (right_index, right_index2); -- "mod" 2802 when others => return right_index; -- for abs and default 2803 end case; 2804 end function ufixed_low; 2805 2806 function sfixed_high (left_index, right_index : INTEGER; 2807 operation : CHARACTER := 'X'; 2808 left_index2, right_index2 : INTEGER := 0) 2809 return INTEGER is 2810 begin 2811 case operation is 2812 when '+'| '-' => return maximum (left_index, left_index2) + 1; 2813 when '*' => return left_index + left_index2 + 1; 2814 when '/' => return left_index - right_index2 + 1; 2815 when '1' => return -right_index + 1; -- reciprocal 2816 when 'R'|'r' => return mins (left_index, left_index2); -- "rem" 2817 when 'M'|'m' => return left_index2; -- "mod" 2818 when 'A'|'a' => return left_index + 1; -- "abs" 2819 when 'N'|'n' => return left_index + 1; -- -sfixed 2820 when others => return left_index; 2821 end case; 2822 end function sfixed_high; 2823 2824 function sfixed_low (left_index, right_index : INTEGER; 2825 operation : CHARACTER := 'X'; 2826 left_index2, right_index2 : INTEGER := 0) 2827 return INTEGER is 2828 begin 2829 case operation is 2830 when '+'| '-' => return mins (right_index, right_index2); 2831 when '*' => return right_index + right_index2; 2832 when '/' => return right_index - left_index2; 2833 when '1' => return -left_index; -- reciprocal 2834 when 'R'|'r' => return mins (right_index, right_index2); -- "rem" 2835 when 'M'|'m' => return mins (right_index, right_index2); -- "mod" 2836 when others => return right_index; -- default for abs, neg and default 2837 end case; 2838 end function sfixed_low; 2839 2840 -- Same as above, but using the "size_res" input only for their ranges: 2841 -- signal uf1multuf2 : ufixed (ufixed_high (uf1, '*', uf2) downto 2842 -- ufixed_low (uf1, '*', uf2)); 2843 -- uf1multuf2 <= uf1 * uf2; 2844 function ufixed_high (size_res : UNRESOLVED_ufixed; 2845 operation : CHARACTER := 'X'; 2846 size_res2 : UNRESOLVED_ufixed) 2847 return INTEGER is 2848 begin 2849 return ufixed_high (left_index => size_res'high, 2850 right_index => size_res'low, 2851 operation => operation, 2852 left_index2 => size_res2'high, 2853 right_index2 => size_res2'low); 2854 end function ufixed_high; 2855 2856 function ufixed_low (size_res : UNRESOLVED_ufixed; 2857 operation : CHARACTER := 'X'; 2858 size_res2 : UNRESOLVED_ufixed) 2859 return INTEGER is 2860 begin 2861 return ufixed_low (left_index => size_res'high, 2862 right_index => size_res'low, 2863 operation => operation, 2864 left_index2 => size_res2'high, 2865 right_index2 => size_res2'low); 2866 end function ufixed_low; 2867 2868 function sfixed_high (size_res : UNRESOLVED_sfixed; 2869 operation : CHARACTER := 'X'; 2870 size_res2 : UNRESOLVED_sfixed) 2871 return INTEGER is 2872 begin 2873 return sfixed_high (left_index => size_res'high, 2874 right_index => size_res'low, 2875 operation => operation, 2876 left_index2 => size_res2'high, 2877 right_index2 => size_res2'low); 2878 end function sfixed_high; 2879 2880 function sfixed_low (size_res : UNRESOLVED_sfixed; 2881 operation : CHARACTER := 'X'; 2882 size_res2 : UNRESOLVED_sfixed) 2883 return INTEGER is 2884 begin 2885 return sfixed_low (left_index => size_res'high, 2886 right_index => size_res'low, 2887 operation => operation, 2888 left_index2 => size_res2'high, 2889 right_index2 => size_res2'low); 2890 end function sfixed_low; 2891 2892 -- purpose: returns a saturated number 2893 function saturate ( 2894 constant left_index : INTEGER; 2895 constant right_index : INTEGER) 2896 return UNRESOLVED_ufixed 2897 is 2898 constant sat : UNRESOLVED_ufixed (left_index downto right_index) := 2899 (others => '1'); 2900 begin 2901 return sat; 2902 end function saturate; 2903 2904 -- purpose: returns a saturated number 2905 function saturate ( 2906 constant left_index : INTEGER; 2907 constant right_index : INTEGER) 2908 return UNRESOLVED_sfixed 2909 is 2910 variable sat : UNRESOLVED_sfixed (left_index downto right_index) := 2911 (others => '1'); 2912 begin 2913 -- saturate positive, to saturate negative, just do "not saturate()" 2914 sat (left_index) := '0'; 2915 return sat; 2916 end function saturate; 2917 2918 function saturate ( 2919 size_res : UNRESOLVED_ufixed) -- only the size of this is used 2920 return UNRESOLVED_ufixed is 2921 begin 2922 return saturate (size_res'high, size_res'low); 2923 end function saturate; 2924 2925 function saturate ( 2926 size_res : UNRESOLVED_sfixed) -- only the size of this is used 2927 return UNRESOLVED_sfixed is 2928 begin 2929 return saturate (size_res'high, size_res'low); 2930 end function saturate; 2931 2932 -- As a concession to those who use a graphical DSP environment, 2933 -- these functions take parameters in those tools format and create 2934 -- fixed point numbers. These functions are designed to convert from 2935 -- a std_logic_vector to the VHDL fixed point format using the conventions 2936 -- of these packages. In a pure VHDL environment you should use the 2937 -- "to_ufixed" and "to_sfixed" routines. 2938 -- Unsigned fixed point 2939 function to_UFix ( 2940 arg : STD_ULOGIC_VECTOR; 2941 width : NATURAL; -- width of vector 2942 fraction : NATURAL) -- width of fraction 2943 return UNRESOLVED_ufixed 2944 is 2945 variable result : UNRESOLVED_ufixed (width-fraction-1 downto -fraction); 2946 begin 2947 if (arg'length /= result'length) then 2948 report fixed_generic_pkg'instance_name 2949 & "TO_UFIX (STD_ULOGIC_VECTOR) " 2950 & "Vector lengths do not match. Input length is " 2951 & INTEGER'image(arg'length) & " and output will be " 2952 & INTEGER'image(result'length) & " wide." 2953 severity error; 2954 return NAUF; 2955 else 2956 result := to_ufixed (arg, result'high, result'low); 2957 return result; 2958 end if; 2959 end function to_UFix; 2960 2961 -- signed fixed point 2962 function to_SFix ( 2963 arg : STD_ULOGIC_VECTOR; 2964 width : NATURAL; -- width of vector 2965 fraction : NATURAL) -- width of fraction 2966 return UNRESOLVED_sfixed 2967 is 2968 variable result : UNRESOLVED_sfixed (width-fraction-1 downto -fraction); 2969 begin 2970 if (arg'length /= result'length) then 2971 report fixed_generic_pkg'instance_name 2972 & "TO_SFIX (STD_ULOGIC_VECTOR) " 2973 & "Vector lengths do not match. Input length is " 2974 & INTEGER'image(arg'length) & " and output will be " 2975 & INTEGER'image(result'length) & " wide." 2976 severity error; 2977 return NASF; 2978 else 2979 result := to_sfixed (arg, result'high, result'low); 2980 return result; 2981 end if; 2982 end function to_SFix; 2983 2984 -- finding the bounds of a number. These functions can be used like this: 2985 -- signal xxx : ufixed (7 downto -3); 2986 -- -- Which is the same as "ufixed (UFix_high (11,3) downto UFix_low(11,3))" 2987 -- signal yyy : ufixed (UFix_high (11, 3, "+", 11, 3) 2988 -- downto UFix_low(11, 3, "+", 11, 3)); 2989 -- Where "11" is the width of xxx (xxx'length), 2990 -- and 3 is the lower bound (abs (xxx'low)) 2991 -- In a pure VHDL environment use "ufixed_high" and "ufixed_low" 2992 function ufix_high ( 2993 width, fraction : NATURAL; 2994 operation : CHARACTER := 'X'; 2995 width2, fraction2 : NATURAL := 0) 2996 return INTEGER is 2997 begin 2998 return ufixed_high (left_index => width - 1 - fraction, 2999 right_index => -fraction, 3000 operation => operation, 3001 left_index2 => width2 - 1 - fraction2, 3002 right_index2 => -fraction2); 3003 end function ufix_high; 3004 3005 function ufix_low ( 3006 width, fraction : NATURAL; 3007 operation : CHARACTER := 'X'; 3008 width2, fraction2 : NATURAL := 0) 3009 return INTEGER is 3010 begin 3011 return ufixed_low (left_index => width - 1 - fraction, 3012 right_index => -fraction, 3013 operation => operation, 3014 left_index2 => width2 - 1 - fraction2, 3015 right_index2 => -fraction2); 3016 end function ufix_low; 3017 3018 function sfix_high ( 3019 width, fraction : NATURAL; 3020 operation : CHARACTER := 'X'; 3021 width2, fraction2 : NATURAL := 0) 3022 return INTEGER is 3023 begin 3024 return sfixed_high (left_index => width - fraction, 3025 right_index => -fraction, 3026 operation => operation, 3027 left_index2 => width2 - fraction2, 3028 right_index2 => -fraction2); 3029 end function sfix_high; 3030 3031 function sfix_low ( 3032 width, fraction : NATURAL; 3033 operation : CHARACTER := 'X'; 3034 width2, fraction2 : NATURAL := 0) 3035 return INTEGER is 3036 begin 3037 return sfixed_low (left_index => width - fraction, 3038 right_index => -fraction, 3039 operation => operation, 3040 left_index2 => width2 - fraction2, 3041 right_index2 => -fraction2); 3042 end function sfix_low; 3043 3044 function to_unsigned ( 3045 arg : UNRESOLVED_ufixed; -- ufixed point input 3046 constant size : NATURAL; -- length of output 3047 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3048 constant round_style : fixed_round_style_type := fixed_round_style) 3049 return UNRESOLVED_UNSIGNED is 3050 begin 3051 return to_uns(resize (arg => arg, 3052 left_index => size-1, 3053 right_index => 0, 3054 round_style => round_style, 3055 overflow_style => overflow_style)); 3056 end function to_unsigned; 3057 3058 function to_unsigned ( 3059 arg : UNRESOLVED_ufixed; -- ufixed point input 3060 size_res : UNRESOLVED_UNSIGNED; -- length of output 3061 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3062 constant round_style : fixed_round_style_type := fixed_round_style) 3063 return UNRESOLVED_UNSIGNED is 3064 begin 3065 return to_unsigned (arg => arg, 3066 size => size_res'length, 3067 round_style => round_style, 3068 overflow_style => overflow_style); 3069 end function to_unsigned; 3070 3071 function to_signed ( 3072 arg : UNRESOLVED_sfixed; -- sfixed point input 3073 constant size : NATURAL; -- length of output 3074 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3075 constant round_style : fixed_round_style_type := fixed_round_style) 3076 return UNRESOLVED_SIGNED is 3077 begin 3078 return to_s(resize (arg => arg, 3079 left_index => size-1, 3080 right_index => 0, 3081 round_style => round_style, 3082 overflow_style => overflow_style)); 3083 end function to_signed; 3084 3085 function to_signed ( 3086 arg : UNRESOLVED_sfixed; -- sfixed point input 3087 size_res : UNRESOLVED_SIGNED; -- used for length of output 3088 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3089 constant round_style : fixed_round_style_type := fixed_round_style) 3090 return UNRESOLVED_SIGNED is 3091 begin 3092 return to_signed (arg => arg, 3093 size => size_res'length, 3094 round_style => round_style, 3095 overflow_style => overflow_style); 3096 end function to_signed; 3097 3098 function to_real ( 3099 arg : UNRESOLVED_ufixed) -- ufixed point input 3100 return REAL 3101 is 3102 constant left_index : INTEGER := arg'high; 3103 constant right_index : INTEGER := arg'low; 3104 variable result : REAL; -- result 3105 variable arg_int : UNRESOLVED_ufixed (left_index downto right_index); 3106 begin 3107 if (arg'length < 1) then 3108 return 0.0; 3109 end if; 3110 arg_int := To_X01(cleanvec(arg)); 3111 if (Is_X(arg_int)) then 3112 assert no_warning 3113 report fixed_generic_pkg'instance_name 3114 & "TO_REAL (ufixed): metavalue detected, returning 0.0" 3115 severity warning; 3116 return 0.0; 3117 end if; 3118 result := 0.0; 3119 for i in arg_int'range loop 3120 if (arg_int(i) = '1') then 3121 result := result + (2.0**i); 3122 end if; 3123 end loop; 3124 return result; 3125 end function to_real; 3126 3127 function to_real ( 3128 arg : UNRESOLVED_sfixed) -- ufixed point input 3129 return REAL 3130 is 3131 constant left_index : INTEGER := arg'high; 3132 constant right_index : INTEGER := arg'low; 3133 variable result : REAL; -- result 3134 variable arg_int : UNRESOLVED_sfixed (left_index downto right_index); 3135 -- unsigned version of argument 3136 variable arg_uns : UNRESOLVED_ufixed (left_index downto right_index); 3137 -- absolute of argument 3138 begin 3139 if (arg'length < 1) then 3140 return 0.0; 3141 end if; 3142 arg_int := to_X01(cleanvec(arg)); 3143 if (Is_X(arg_int)) then 3144 assert no_warning 3145 report fixed_generic_pkg'instance_name 3146 & "TO_REAL (sfixed): metavalue detected, returning 0.0" 3147 severity warning; 3148 return 0.0; 3149 end if; 3150 arg_uns := to_ufixed (arg_int); 3151 result := to_real (arg_uns); 3152 if (arg_int(arg_int'high) = '1') then 3153 result := -result; 3154 end if; 3155 return result; 3156 end function to_real; 3157 3158 function to_integer ( 3159 arg : UNRESOLVED_ufixed; -- fixed point input 3160 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3161 constant round_style : fixed_round_style_type := fixed_round_style) 3162 return NATURAL 3163 is 3164 constant left_index : INTEGER := arg'high; 3165 variable arg_uns : UNRESOLVED_UNSIGNED (left_index+1 downto 0) 3166 := (others => '0'); 3167 begin 3168 if (arg'length < 1) then 3169 return 0; 3170 end if; 3171 if (Is_X (arg)) then 3172 assert no_warning 3173 report fixed_generic_pkg'instance_name 3174 & "TO_INTEGER (ufixed): metavalue detected, returning 0" 3175 severity warning; 3176 return 0; 3177 end if; 3178 if (left_index < -1) then 3179 return 0; 3180 end if; 3181 arg_uns := to_uns(resize (arg => arg, 3182 left_index => arg_uns'high, 3183 right_index => 0, 3184 round_style => round_style, 3185 overflow_style => overflow_style)); 3186 return to_integer (arg_uns); 3187 end function to_integer; 3188 3189 function to_integer ( 3190 arg : UNRESOLVED_sfixed; -- fixed point input 3191 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3192 constant round_style : fixed_round_style_type := fixed_round_style) 3193 return INTEGER 3194 is 3195 constant left_index : INTEGER := arg'high; 3196 variable arg_s : UNRESOLVED_SIGNED (left_index+1 downto 0); 3197 begin 3198 if (arg'length < 1) then 3199 return 0; 3200 end if; 3201 if (Is_X (arg)) then 3202 assert no_warning 3203 report fixed_generic_pkg'instance_name 3204 & "TO_INTEGER (sfixed): metavalue detected, returning 0" 3205 severity warning; 3206 return 0; 3207 end if; 3208 if (left_index < -1) then 3209 return 0; 3210 end if; 3211 arg_s := to_s(resize (arg => arg, 3212 left_index => arg_s'high, 3213 right_index => 0, 3214 round_style => round_style, 3215 overflow_style => overflow_style)); 3216 return to_integer (arg_s); 3217 end function to_integer; 3218 3219 function to_01 ( 3220 s : UNRESOLVED_ufixed; -- ufixed point input 3221 constant XMAP : STD_ULOGIC := '0') -- Map x to 3222 return UNRESOLVED_ufixed 3223 is 3224 begin 3225 if (s'length < 1) then 3226 assert no_warning 3227 report fixed_generic_pkg'instance_name 3228 & "TO_01(ufixed): null detected, returning NULL" 3229 severity warning; 3230 return NAUF; 3231 end if; 3232 return to_fixed (to_01(to_uns(s), XMAP), s'high, s'low); 3233 end function to_01; 3234 3235 function to_01 ( 3236 s : UNRESOLVED_sfixed; -- sfixed point input 3237 constant XMAP : STD_ULOGIC := '0') -- Map x to 3238 return UNRESOLVED_sfixed 3239 is 3240 begin 3241 if (s'length < 1) then 3242 assert no_warning 3243 report fixed_generic_pkg'instance_name 3244 & "TO_01(sfixed): null detected, returning NULL" 3245 severity warning; 3246 return NASF; 3247 end if; 3248 return to_fixed (to_01(to_s(s), XMAP), s'high, s'low); 3249 end function to_01; 3250 3251 function Is_X ( 3252 arg : UNRESOLVED_ufixed) 3253 return BOOLEAN 3254 is 3255 variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0); -- slv 3256 begin 3257 argslv := to_sulv(arg); 3258 return Is_X (argslv); 3259 end function Is_X; 3260 3261 function Is_X ( 3262 arg : UNRESOLVED_sfixed) 3263 return BOOLEAN 3264 is 3265 variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0); -- slv 3266 begin 3267 argslv := to_sulv(arg); 3268 return Is_X (argslv); 3269 end function Is_X; 3270 3271 function To_X01 ( 3272 arg : UNRESOLVED_ufixed) 3273 return UNRESOLVED_ufixed is 3274 begin 3275 return to_ufixed (To_X01(to_sulv(arg)), arg'high, arg'low); 3276 end function To_X01; 3277 3278 function to_X01 ( 3279 arg : UNRESOLVED_sfixed) 3280 return UNRESOLVED_sfixed is 3281 begin 3282 return to_sfixed (To_X01(to_sulv(arg)), arg'high, arg'low); 3283 end function to_X01; 3284 3285 function To_X01Z ( 3286 arg : UNRESOLVED_ufixed) 3287 return UNRESOLVED_ufixed is 3288 begin 3289 return to_ufixed (To_X01Z(to_sulv(arg)), arg'high, arg'low); 3290 end function To_X01Z; 3291 3292 function to_X01Z ( 3293 arg : UNRESOLVED_sfixed) 3294 return UNRESOLVED_sfixed is 3295 begin 3296 return to_sfixed (To_X01Z(to_sulv(arg)), arg'high, arg'low); 3297 end function to_X01Z; 3298 3299 function To_UX01 ( 3300 arg : UNRESOLVED_ufixed) 3301 return UNRESOLVED_ufixed is 3302 begin 3303 return to_ufixed (To_UX01(to_sulv(arg)), arg'high, arg'low); 3304 end function To_UX01; 3305 3306 function to_UX01 ( 3307 arg : UNRESOLVED_sfixed) 3308 return UNRESOLVED_sfixed is 3309 begin 3310 return to_sfixed (To_UX01(to_sulv(arg)), arg'high, arg'low); 3311 end function to_UX01; 3312 3313 function resize ( 3314 arg : UNRESOLVED_ufixed; -- input 3315 constant left_index : INTEGER; -- integer portion 3316 constant right_index : INTEGER; -- size of fraction 3317 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3318 constant round_style : fixed_round_style_type := fixed_round_style) 3319 return UNRESOLVED_ufixed 3320 is 3321 constant arghigh : INTEGER := maximum (arg'high, arg'low); 3322 constant arglow : INTEGER := mine (arg'high, arg'low); 3323 variable invec : UNRESOLVED_ufixed (arghigh downto arglow); 3324 variable result : UNRESOLVED_ufixed(left_index downto right_index) := 3325 (others => '0'); 3326 variable needs_rounding : BOOLEAN := false; 3327 begin -- resize 3328 if (arg'length < 1) or (result'length < 1) then 3329 return NAUF; 3330 elsif (invec'length < 1) then 3331 return result; -- string literal value 3332 else 3333 invec := cleanvec(arg); 3334 if (right_index > arghigh) then -- return top zeros 3335 needs_rounding := (round_style = fixed_round) and 3336 (right_index = arghigh+1); 3337 elsif (left_index < arglow) then -- return overflow 3338 if (overflow_style = fixed_saturate) and 3339 (or(to_sulv(invec)) = '1') then 3340 result := saturate (result'high, result'low); -- saturate 3341 end if; 3342 elsif (arghigh > left_index) then 3343 -- wrap or saturate? 3344 if (overflow_style = fixed_saturate and 3345 or (to_sulv(invec(arghigh downto left_index+1))) = '1') 3346 then 3347 result := saturate (result'high, result'low); -- saturate 3348 else 3349 if (arglow >= right_index) then 3350 result (left_index downto arglow) := 3351 invec(left_index downto arglow); 3352 else 3353 result (left_index downto right_index) := 3354 invec (left_index downto right_index); 3355 needs_rounding := (round_style = fixed_round); -- round 3356 end if; 3357 end if; 3358 else -- arghigh <= integer width 3359 if (arglow >= right_index) then 3360 result (arghigh downto arglow) := invec; 3361 else 3362 result (arghigh downto right_index) := 3363 invec (arghigh downto right_index); 3364 needs_rounding := (round_style = fixed_round); -- round 3365 end if; 3366 end if; 3367 -- Round result 3368 if needs_rounding then 3369 result := round_fixed (arg => result, 3370 remainder => invec (right_index-1 3371 downto arglow), 3372 overflow_style => overflow_style); 3373 end if; 3374 return result; 3375 end if; 3376 end function resize; 3377 3378 function resize ( 3379 arg : UNRESOLVED_sfixed; -- input 3380 constant left_index : INTEGER; -- integer portion 3381 constant right_index : INTEGER; -- size of fraction 3382 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3383 constant round_style : fixed_round_style_type := fixed_round_style) 3384 return UNRESOLVED_sfixed 3385 is 3386 constant arghigh : INTEGER := maximum (arg'high, arg'low); 3387 constant arglow : INTEGER := mine (arg'high, arg'low); 3388 variable invec : UNRESOLVED_sfixed (arghigh downto arglow); 3389 variable result : UNRESOLVED_sfixed(left_index downto right_index) := 3390 (others => '0'); 3391 variable reduced : STD_ULOGIC; 3392 variable needs_rounding : BOOLEAN := false; -- rounding 3393 begin -- resize 3394 if (arg'length < 1) or (result'length < 1) then 3395 return NASF; 3396 elsif (invec'length < 1) then 3397 return result; -- string literal value 3398 else 3399 invec := cleanvec(arg); 3400 if (right_index > arghigh) then -- return top zeros 3401 if (arg'low /= INTEGER'low) then -- check for a literal 3402 result := (others => arg(arghigh)); -- sign extend 3403 end if; 3404 needs_rounding := (round_style = fixed_round) and 3405 (right_index = arghigh+1); 3406 elsif (left_index < arglow) then -- return overflow 3407 if (overflow_style = fixed_saturate) then 3408 reduced := or (to_sulv(invec)); 3409 if (reduced = '1') then 3410 if (invec(arghigh) = '0') then 3411 -- saturate POSITIVE 3412 result := saturate (result'high, result'low); 3413 else 3414 -- saturate negative 3415 result := not saturate (result'high, result'low); 3416 end if; 3417 -- else return 0 (input was 0) 3418 end if; 3419 -- else return 0 (wrap) 3420 end if; 3421 elsif (arghigh > left_index) then 3422 if (invec(arghigh) = '0') then 3423 reduced := or (to_sulv(invec(arghigh-1 downto 3424 left_index))); 3425 if overflow_style = fixed_saturate and reduced = '1' then 3426 -- saturate positive 3427 result := saturate (result'high, result'low); 3428 else 3429 if (right_index > arglow) then 3430 result := invec (left_index downto right_index); 3431 needs_rounding := (round_style = fixed_round); 3432 else 3433 result (left_index downto arglow) := 3434 invec (left_index downto arglow); 3435 end if; 3436 end if; 3437 else 3438 reduced := and (to_sulv(invec(arghigh-1 downto 3439 left_index))); 3440 if overflow_style = fixed_saturate and reduced = '0' then 3441 result := not saturate (result'high, result'low); 3442 else 3443 if (right_index > arglow) then 3444 result := invec (left_index downto right_index); 3445 needs_rounding := (round_style = fixed_round); 3446 else 3447 result (left_index downto arglow) := 3448 invec (left_index downto arglow); 3449 end if; 3450 end if; 3451 end if; 3452 else -- arghigh <= integer width 3453 if (arglow >= right_index) then 3454 result (arghigh downto arglow) := invec; 3455 else 3456 result (arghigh downto right_index) := 3457 invec (arghigh downto right_index); 3458 needs_rounding := (round_style = fixed_round); -- round 3459 end if; 3460 if (left_index > arghigh) then -- sign extend 3461 result(left_index downto arghigh+1) := (others => invec(arghigh)); 3462 end if; 3463 end if; 3464 -- Round result 3465 if (needs_rounding) then 3466 result := round_fixed (arg => result, 3467 remainder => invec (right_index-1 3468 downto arglow), 3469 overflow_style => overflow_style); 3470 end if; 3471 return result; 3472 end if; 3473 end function resize; 3474 3475 -- size_res functions 3476 -- These functions compute the size from a passed variable named "size_res" 3477 -- The only part of this variable used it it's size, it is never passed 3478 -- to a lower level routine. 3479 function to_ufixed ( 3480 arg : STD_ULOGIC_VECTOR; -- shifted vector 3481 size_res : UNRESOLVED_ufixed) -- for size only 3482 return UNRESOLVED_ufixed 3483 is 3484 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3485 variable result : UNRESOLVED_ufixed (size_res'left downto fw); 3486 begin 3487 if (result'length < 1 or arg'length < 1) then 3488 return NAUF; 3489 else 3490 result := to_ufixed (arg => arg, 3491 left_index => size_res'high, 3492 right_index => size_res'low); 3493 return result; 3494 end if; 3495 end function to_ufixed; 3496 3497 function to_sfixed ( 3498 arg : STD_ULOGIC_VECTOR; -- shifted vector 3499 size_res : UNRESOLVED_sfixed) -- for size only 3500 return UNRESOLVED_sfixed 3501 is 3502 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3503 variable result : UNRESOLVED_sfixed (size_res'left downto fw); 3504 begin 3505 if (result'length < 1 or arg'length < 1) then 3506 return NASF; 3507 else 3508 result := to_sfixed (arg => arg, 3509 left_index => size_res'high, 3510 right_index => size_res'low); 3511 return result; 3512 end if; 3513 end function to_sfixed; 3514 3515 function to_ufixed ( 3516 arg : NATURAL; -- integer 3517 size_res : UNRESOLVED_ufixed; -- for size only 3518 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3519 constant round_style : fixed_round_style_type := fixed_round_style) 3520 return UNRESOLVED_ufixed 3521 is 3522 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3523 variable result : UNRESOLVED_ufixed (size_res'left downto fw); 3524 begin 3525 if (result'length < 1) then 3526 return NAUF; 3527 else 3528 result := to_ufixed (arg => arg, 3529 left_index => size_res'high, 3530 right_index => size_res'low, 3531 round_style => round_style, 3532 overflow_style => overflow_style); 3533 return result; 3534 end if; 3535 end function to_ufixed; 3536 3537 function to_sfixed ( 3538 arg : INTEGER; -- integer 3539 size_res : UNRESOLVED_sfixed; -- for size only 3540 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3541 constant round_style : fixed_round_style_type := fixed_round_style) 3542 return UNRESOLVED_sfixed 3543 is 3544 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3545 variable result : UNRESOLVED_sfixed (size_res'left downto fw); 3546 begin 3547 if (result'length < 1) then 3548 return NASF; 3549 else 3550 result := to_sfixed (arg => arg, 3551 left_index => size_res'high, 3552 right_index => size_res'low, 3553 round_style => round_style, 3554 overflow_style => overflow_style); 3555 return result; 3556 end if; 3557 end function to_sfixed; 3558 3559 function to_ufixed ( 3560 arg : REAL; -- real 3561 size_res : UNRESOLVED_ufixed; -- for size only 3562 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3563 constant round_style : fixed_round_style_type := fixed_round_style; 3564 constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits 3565 return UNRESOLVED_ufixed 3566 is 3567 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3568 variable result : UNRESOLVED_ufixed (size_res'left downto fw); 3569 begin 3570 if (result'length < 1) then 3571 return NAUF; 3572 else 3573 result := to_ufixed (arg => arg, 3574 left_index => size_res'high, 3575 right_index => size_res'low, 3576 guard_bits => guard_bits, 3577 round_style => round_style, 3578 overflow_style => overflow_style); 3579 return result; 3580 end if; 3581 end function to_ufixed; 3582 3583 function to_sfixed ( 3584 arg : REAL; -- real 3585 size_res : UNRESOLVED_sfixed; -- for size only 3586 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3587 constant round_style : fixed_round_style_type := fixed_round_style; 3588 constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits 3589 return UNRESOLVED_sfixed 3590 is 3591 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3592 variable result : UNRESOLVED_sfixed (size_res'left downto fw); 3593 begin 3594 if (result'length < 1) then 3595 return NASF; 3596 else 3597 result := to_sfixed (arg => arg, 3598 left_index => size_res'high, 3599 right_index => size_res'low, 3600 guard_bits => guard_bits, 3601 round_style => round_style, 3602 overflow_style => overflow_style); 3603 return result; 3604 end if; 3605 end function to_sfixed; 3606 3607 function to_ufixed ( 3608 arg : UNRESOLVED_UNSIGNED; -- unsigned 3609 size_res : UNRESOLVED_ufixed; -- for size only 3610 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3611 constant round_style : fixed_round_style_type := fixed_round_style) 3612 return UNRESOLVED_ufixed 3613 is 3614 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3615 variable result : UNRESOLVED_ufixed (size_res'left downto fw); 3616 begin 3617 if (result'length < 1 or arg'length < 1) then 3618 return NAUF; 3619 else 3620 result := to_ufixed (arg => arg, 3621 left_index => size_res'high, 3622 right_index => size_res'low, 3623 round_style => round_style, 3624 overflow_style => overflow_style); 3625 return result; 3626 end if; 3627 end function to_ufixed; 3628 3629 function to_sfixed ( 3630 arg : UNRESOLVED_SIGNED; -- signed 3631 size_res : UNRESOLVED_sfixed; -- for size only 3632 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3633 constant round_style : fixed_round_style_type := fixed_round_style) 3634 return UNRESOLVED_sfixed 3635 is 3636 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3637 variable result : UNRESOLVED_sfixed (size_res'left downto fw); 3638 begin 3639 if (result'length < 1 or arg'length < 1) then 3640 return NASF; 3641 else 3642 result := to_sfixed (arg => arg, 3643 left_index => size_res'high, 3644 right_index => size_res'low, 3645 round_style => round_style, 3646 overflow_style => overflow_style); 3647 return result; 3648 end if; 3649 end function to_sfixed; 3650 3651 function resize ( 3652 arg : UNRESOLVED_ufixed; -- input 3653 size_res : UNRESOLVED_ufixed; -- for size only 3654 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3655 constant round_style : fixed_round_style_type := fixed_round_style) 3656 return UNRESOLVED_ufixed 3657 is 3658 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3659 variable result : UNRESOLVED_ufixed (size_res'high downto fw); 3660 begin 3661 if (result'length < 1 or arg'length < 1) then 3662 return NAUF; 3663 else 3664 result := resize (arg => arg, 3665 left_index => size_res'high, 3666 right_index => size_res'low, 3667 round_style => round_style, 3668 overflow_style => overflow_style); 3669 return result; 3670 end if; 3671 end function resize; 3672 3673 function resize ( 3674 arg : UNRESOLVED_sfixed; -- input 3675 size_res : UNRESOLVED_sfixed; -- for size only 3676 constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; 3677 constant round_style : fixed_round_style_type := fixed_round_style) 3678 return UNRESOLVED_sfixed 3679 is 3680 constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals 3681 variable result : UNRESOLVED_sfixed (size_res'high downto fw); 3682 begin 3683 if (result'length < 1 or arg'length < 1) then 3684 return NASF; 3685 else 3686 result := resize (arg => arg, 3687 left_index => size_res'high, 3688 right_index => size_res'low, 3689 round_style => round_style, 3690 overflow_style => overflow_style); 3691 return result; 3692 end if; 3693 end function resize; 3694 3695 -- Overloaded math functions for real 3696 function "+" ( 3697 l : UNRESOLVED_ufixed; -- fixed point input 3698 r : REAL) 3699 return UNRESOLVED_ufixed is 3700 begin 3701 return (l + to_ufixed (r, l'high, l'low)); 3702 end function "+"; 3703 3704 function "+" ( 3705 l : REAL; 3706 r : UNRESOLVED_ufixed) -- fixed point input 3707 return UNRESOLVED_ufixed is 3708 begin 3709 return (to_ufixed (l, r'high, r'low) + r); 3710 end function "+"; 3711 3712 function "+" ( 3713 l : UNRESOLVED_sfixed; -- fixed point input 3714 r : REAL) 3715 return UNRESOLVED_sfixed is 3716 begin 3717 return (l + to_sfixed (r, l'high, l'low)); 3718 end function "+"; 3719 3720 function "+" ( 3721 l : REAL; 3722 r : UNRESOLVED_sfixed) -- fixed point input 3723 return UNRESOLVED_sfixed is 3724 begin 3725 return (to_sfixed (l, r'high, r'low) + r); 3726 end function "+"; 3727 3728 function "-" ( 3729 l : UNRESOLVED_ufixed; -- fixed point input 3730 r : REAL) 3731 return UNRESOLVED_ufixed is 3732 begin 3733 return (l - to_ufixed (r, l'high, l'low)); 3734 end function "-"; 3735 3736 function "-" ( 3737 l : REAL; 3738 r : UNRESOLVED_ufixed) -- fixed point input 3739 return UNRESOLVED_ufixed is 3740 begin 3741 return (to_ufixed (l, r'high, r'low) - r); 3742 end function "-"; 3743 3744 function "-" ( 3745 l : UNRESOLVED_sfixed; -- fixed point input 3746 r : REAL) 3747 return UNRESOLVED_sfixed is 3748 begin 3749 return (l - to_sfixed (r, l'high, l'low)); 3750 end function "-"; 3751 3752 function "-" ( 3753 l : REAL; 3754 r : UNRESOLVED_sfixed) -- fixed point input 3755 return UNRESOLVED_sfixed is 3756 begin 3757 return (to_sfixed (l, r'high, r'low) - r); 3758 end function "-"; 3759 3760 function "*" ( 3761 l : UNRESOLVED_ufixed; -- fixed point input 3762 r : REAL) 3763 return UNRESOLVED_ufixed is 3764 begin 3765 return (l * to_ufixed (r, l'high, l'low)); 3766 end function "*"; 3767 3768 function "*" ( 3769 l : REAL; 3770 r : UNRESOLVED_ufixed) -- fixed point input 3771 return UNRESOLVED_ufixed is 3772 begin 3773 return (to_ufixed (l, r'high, r'low) * r); 3774 end function "*"; 3775 3776 function "*" ( 3777 l : UNRESOLVED_sfixed; -- fixed point input 3778 r : REAL) 3779 return UNRESOLVED_sfixed is 3780 begin 3781 return (l * to_sfixed (r, l'high, l'low)); 3782 end function "*"; 3783 3784 function "*" ( 3785 l : REAL; 3786 r : UNRESOLVED_sfixed) -- fixed point input 3787 return UNRESOLVED_sfixed is 3788 begin 3789 return (to_sfixed (l, r'high, r'low) * r); 3790 end function "*"; 3791 3792 function "/" ( 3793 l : UNRESOLVED_ufixed; -- fixed point input 3794 r : REAL) 3795 return UNRESOLVED_ufixed is 3796 begin 3797 return (l / to_ufixed (r, l'high, l'low)); 3798 end function "/"; 3799 3800 function "/" ( 3801 l : REAL; 3802 r : UNRESOLVED_ufixed) -- fixed point input 3803 return UNRESOLVED_ufixed is 3804 begin 3805 return (to_ufixed (l, r'high, r'low) / r); 3806 end function "/"; 3807 3808 function "/" ( 3809 l : UNRESOLVED_sfixed; -- fixed point input 3810 r : REAL) 3811 return UNRESOLVED_sfixed is 3812 begin 3813 return (l / to_sfixed (r, l'high, l'low)); 3814 end function "/"; 3815 3816 function "/" ( 3817 l : REAL; 3818 r : UNRESOLVED_sfixed) -- fixed point input 3819 return UNRESOLVED_sfixed is 3820 begin 3821 return (to_sfixed (l, r'high, r'low) / r); 3822 end function "/"; 3823 3824 function "rem" ( 3825 l : UNRESOLVED_ufixed; -- fixed point input 3826 r : REAL) 3827 return UNRESOLVED_ufixed is 3828 begin 3829 return (l rem to_ufixed (r, l'high, l'low)); 3830 end function "rem"; 3831 3832 function "rem" ( 3833 l : REAL; 3834 r : UNRESOLVED_ufixed) -- fixed point input 3835 return UNRESOLVED_ufixed is 3836 begin 3837 return (to_ufixed (l, r'high, r'low) rem r); 3838 end function "rem"; 3839 3840 function "rem" ( 3841 l : UNRESOLVED_sfixed; -- fixed point input 3842 r : REAL) 3843 return UNRESOLVED_sfixed is 3844 begin 3845 return (l rem to_sfixed (r, l'high, l'low)); 3846 end function "rem"; 3847 3848 function "rem" ( 3849 l : REAL; 3850 r : UNRESOLVED_sfixed) -- fixed point input 3851 return UNRESOLVED_sfixed is 3852 begin 3853 return (to_sfixed (l, r'high, r'low) rem r); 3854 end function "rem"; 3855 3856 function "mod" ( 3857 l : UNRESOLVED_ufixed; -- fixed point input 3858 r : REAL) 3859 return UNRESOLVED_ufixed is 3860 begin 3861 return (l mod to_ufixed (r, l'high, l'low)); 3862 end function "mod"; 3863 3864 function "mod" ( 3865 l : REAL; 3866 r : UNRESOLVED_ufixed) -- fixed point input 3867 return UNRESOLVED_ufixed is 3868 begin 3869 return (to_ufixed (l, r'high, r'low) mod r); 3870 end function "mod"; 3871 3872 function "mod" ( 3873 l : UNRESOLVED_sfixed; -- fixed point input 3874 r : REAL) 3875 return UNRESOLVED_sfixed is 3876 begin 3877 return (l mod to_sfixed (r, l'high, l'low)); 3878 end function "mod"; 3879 3880 function "mod" ( 3881 l : REAL; 3882 r : UNRESOLVED_sfixed) -- fixed point input 3883 return UNRESOLVED_sfixed is 3884 begin 3885 return (to_sfixed (l, r'high, r'low) mod r); 3886 end function "mod"; 3887 3888 -- Overloaded math functions for integers 3889 function "+" ( 3890 l : UNRESOLVED_ufixed; -- fixed point input 3891 r : NATURAL) 3892 return UNRESOLVED_ufixed is 3893 begin 3894 return (l + to_ufixed (r, l'high, 0)); 3895 end function "+"; 3896 3897 function "+" ( 3898 l : NATURAL; 3899 r : UNRESOLVED_ufixed) -- fixed point input 3900 return UNRESOLVED_ufixed is 3901 begin 3902 return (to_ufixed (l, r'high, 0) + r); 3903 end function "+"; 3904 3905 function "+" ( 3906 l : UNRESOLVED_sfixed; -- fixed point input 3907 r : INTEGER) 3908 return UNRESOLVED_sfixed is 3909 begin 3910 return (l + to_sfixed (r, l'high, 0)); 3911 end function "+"; 3912 3913 function "+" ( 3914 l : INTEGER; 3915 r : UNRESOLVED_sfixed) -- fixed point input 3916 return UNRESOLVED_sfixed is 3917 begin 3918 return (to_sfixed (l, r'high, 0) + r); 3919 end function "+"; 3920 3921 -- Overloaded functions 3922 function "-" ( 3923 l : UNRESOLVED_ufixed; -- fixed point input 3924 r : NATURAL) 3925 return UNRESOLVED_ufixed is 3926 begin 3927 return (l - to_ufixed (r, l'high, 0)); 3928 end function "-"; 3929 3930 function "-" ( 3931 l : NATURAL; 3932 r : UNRESOLVED_ufixed) -- fixed point input 3933 return UNRESOLVED_ufixed is 3934 begin 3935 return (to_ufixed (l, r'high, 0) - r); 3936 end function "-"; 3937 3938 function "-" ( 3939 l : UNRESOLVED_sfixed; -- fixed point input 3940 r : INTEGER) 3941 return UNRESOLVED_sfixed is 3942 begin 3943 return (l - to_sfixed (r, l'high, 0)); 3944 end function "-"; 3945 3946 function "-" ( 3947 l : INTEGER; 3948 r : UNRESOLVED_sfixed) -- fixed point input 3949 return UNRESOLVED_sfixed is 3950 begin 3951 return (to_sfixed (l, r'high, 0) - r); 3952 end function "-"; 3953 3954 -- Overloaded functions 3955 function "*" ( 3956 l : UNRESOLVED_ufixed; -- fixed point input 3957 r : NATURAL) 3958 return UNRESOLVED_ufixed is 3959 begin 3960 return (l * to_ufixed (r, l'high, 0)); 3961 end function "*"; 3962 3963 function "*" ( 3964 l : NATURAL; 3965 r : UNRESOLVED_ufixed) -- fixed point input 3966 return UNRESOLVED_ufixed is 3967 begin 3968 return (to_ufixed (l, r'high, 0) * r); 3969 end function "*"; 3970 3971 function "*" ( 3972 l : UNRESOLVED_sfixed; -- fixed point input 3973 r : INTEGER) 3974 return UNRESOLVED_sfixed is 3975 begin 3976 return (l * to_sfixed (r, l'high, 0)); 3977 end function "*"; 3978 3979 function "*" ( 3980 l : INTEGER; 3981 r : UNRESOLVED_sfixed) -- fixed point input 3982 return UNRESOLVED_sfixed is 3983 begin 3984 return (to_sfixed (l, r'high, 0) * r); 3985 end function "*"; 3986 3987 -- Overloaded functions 3988 function "/" ( 3989 l : UNRESOLVED_ufixed; -- fixed point input 3990 r : NATURAL) 3991 return UNRESOLVED_ufixed is 3992 begin 3993 return (l / to_ufixed (r, l'high, 0)); 3994 end function "/"; 3995 3996 function "/" ( 3997 l : NATURAL; 3998 r : UNRESOLVED_ufixed) -- fixed point input 3999 return UNRESOLVED_ufixed is 4000 begin 4001 return (to_ufixed (l, r'high, 0) / r); 4002 end function "/"; 4003 4004 function "/" ( 4005 l : UNRESOLVED_sfixed; -- fixed point input 4006 r : INTEGER) 4007 return UNRESOLVED_sfixed is 4008 begin 4009 return (l / to_sfixed (r, l'high, 0)); 4010 end function "/"; 4011 4012 function "/" ( 4013 l : INTEGER; 4014 r : UNRESOLVED_sfixed) -- fixed point input 4015 return UNRESOLVED_sfixed is 4016 begin 4017 return (to_sfixed (l, r'high, 0) / r); 4018 end function "/"; 4019 4020 function "rem" ( 4021 l : UNRESOLVED_ufixed; -- fixed point input 4022 r : NATURAL) 4023 return UNRESOLVED_ufixed is 4024 begin 4025 return (l rem to_ufixed (r, l'high, 0)); 4026 end function "rem"; 4027 4028 function "rem" ( 4029 l : NATURAL; 4030 r : UNRESOLVED_ufixed) -- fixed point input 4031 return UNRESOLVED_ufixed is 4032 begin 4033 return (to_ufixed (l, r'high, 0) rem r); 4034 end function "rem"; 4035 4036 function "rem" ( 4037 l : UNRESOLVED_sfixed; -- fixed point input 4038 r : INTEGER) 4039 return UNRESOLVED_sfixed is 4040 begin 4041 return (l rem to_sfixed (r, l'high, 0)); 4042 end function "rem"; 4043 4044 function "rem" ( 4045 l : INTEGER; 4046 r : UNRESOLVED_sfixed) -- fixed point input 4047 return UNRESOLVED_sfixed is 4048 begin 4049 return (to_sfixed (l, r'high, 0) rem r); 4050 end function "rem"; 4051 4052 function "mod" ( 4053 l : UNRESOLVED_ufixed; -- fixed point input 4054 r : NATURAL) 4055 return UNRESOLVED_ufixed is 4056 begin 4057 return (l mod to_ufixed (r, l'high, 0)); 4058 end function "mod"; 4059 4060 function "mod" ( 4061 l : NATURAL; 4062 r : UNRESOLVED_ufixed) -- fixed point input 4063 return UNRESOLVED_ufixed is 4064 begin 4065 return (to_ufixed (l, r'high, 0) mod r); 4066 end function "mod"; 4067 4068 function "mod" ( 4069 l : UNRESOLVED_sfixed; -- fixed point input 4070 r : INTEGER) 4071 return UNRESOLVED_sfixed is 4072 begin 4073 return (l mod to_sfixed (r, l'high, 0)); 4074 end function "mod"; 4075 4076 function "mod" ( 4077 l : INTEGER; 4078 r : UNRESOLVED_sfixed) -- fixed point input 4079 return UNRESOLVED_sfixed is 4080 begin 4081 return (to_sfixed (l, r'high, 0) mod r); 4082 end function "mod"; 4083 4084 -- overloaded ufixed compare functions with integer 4085 function "=" ( 4086 l : UNRESOLVED_ufixed; 4087 r : NATURAL) -- fixed point input 4088 return BOOLEAN is 4089 begin 4090 return (l = to_ufixed (r, l'high, l'low)); 4091 end function "="; 4092 4093 function "/=" ( 4094 l : UNRESOLVED_ufixed; 4095 r : NATURAL) -- fixed point input 4096 return BOOLEAN is 4097 begin 4098 return (l /= to_ufixed (r, l'high, l'low)); 4099 end function "/="; 4100 4101 function ">=" ( 4102 l : UNRESOLVED_ufixed; 4103 r : NATURAL) -- fixed point input 4104 return BOOLEAN is 4105 begin 4106 return (l >= to_ufixed (r, l'high, l'low)); 4107 end function ">="; 4108 4109 function "<=" ( 4110 l : UNRESOLVED_ufixed; 4111 r : NATURAL) -- fixed point input 4112 return BOOLEAN is 4113 begin 4114 return (l <= to_ufixed (r, l'high, l'low)); 4115 end function "<="; 4116 4117 function ">" ( 4118 l : UNRESOLVED_ufixed; 4119 r : NATURAL) -- fixed point input 4120 return BOOLEAN is 4121 begin 4122 return (l > to_ufixed (r, l'high, l'low)); 4123 end function ">"; 4124 4125 function "<" ( 4126 l : UNRESOLVED_ufixed; 4127 r : NATURAL) -- fixed point input 4128 return BOOLEAN is 4129 begin 4130 return (l < to_ufixed (r, l'high, l'low)); 4131 end function "<"; 4132 4133 function "?=" ( 4134 l : UNRESOLVED_ufixed; 4135 r : NATURAL) -- fixed point input 4136 return STD_ULOGIC is 4137 begin 4138 return (l ?= to_ufixed (r, l'high, l'low)); 4139 end function "?="; 4140 4141 function "?/=" ( 4142 l : UNRESOLVED_ufixed; 4143 r : NATURAL) -- fixed point input 4144 return STD_ULOGIC is 4145 begin 4146 return (l ?/= to_ufixed (r, l'high, l'low)); 4147 end function "?/="; 4148 4149 function "?>=" ( 4150 l : UNRESOLVED_ufixed; 4151 r : NATURAL) -- fixed point input 4152 return STD_ULOGIC is 4153 begin 4154 return (l ?>= to_ufixed (r, l'high, l'low)); 4155 end function "?>="; 4156 4157 function "?<=" ( 4158 l : UNRESOLVED_ufixed; 4159 r : NATURAL) -- fixed point input 4160 return STD_ULOGIC is 4161 begin 4162 return (l ?<= to_ufixed (r, l'high, l'low)); 4163 end function "?<="; 4164 4165 function "?>" ( 4166 l : UNRESOLVED_ufixed; 4167 r : NATURAL) -- fixed point input 4168 return STD_ULOGIC is 4169 begin 4170 return (l ?> to_ufixed (r, l'high, l'low)); 4171 end function "?>"; 4172 4173 function "?<" ( 4174 l : UNRESOLVED_ufixed; 4175 r : NATURAL) -- fixed point input 4176 return STD_ULOGIC is 4177 begin 4178 return (l ?< to_ufixed (r, l'high, l'low)); 4179 end function "?<"; 4180 4181 function maximum ( 4182 l : UNRESOLVED_ufixed; -- fixed point input 4183 r : NATURAL) 4184 return UNRESOLVED_ufixed is 4185 begin 4186 return maximum (l, to_ufixed (r, l'high, l'low)); 4187 end function maximum; 4188 4189 function minimum ( 4190 l : UNRESOLVED_ufixed; -- fixed point input 4191 r : NATURAL) 4192 return UNRESOLVED_ufixed is 4193 begin 4194 return minimum (l, to_ufixed (r, l'high, l'low)); 4195 end function minimum; 4196 4197 -- NATURAL to ufixed 4198 function "=" ( 4199 l : NATURAL; 4200 r : UNRESOLVED_ufixed) -- fixed point input 4201 return BOOLEAN is 4202 begin 4203 return (to_ufixed (l, r'high, r'low) = r); 4204 end function "="; 4205 4206 function "/=" ( 4207 l : NATURAL; 4208 r : UNRESOLVED_ufixed) -- fixed point input 4209 return BOOLEAN is 4210 begin 4211 return (to_ufixed (l, r'high, r'low) /= r); 4212 end function "/="; 4213 4214 function ">=" ( 4215 l : NATURAL; 4216 r : UNRESOLVED_ufixed) -- fixed point input 4217 return BOOLEAN is 4218 begin 4219 return (to_ufixed (l, r'high, r'low) >= r); 4220 end function ">="; 4221 4222 function "<=" ( 4223 l : NATURAL; 4224 r : UNRESOLVED_ufixed) -- fixed point input 4225 return BOOLEAN is 4226 begin 4227 return (to_ufixed (l, r'high, r'low) <= r); 4228 end function "<="; 4229 4230 function ">" ( 4231 l : NATURAL; 4232 r : UNRESOLVED_ufixed) -- fixed point input 4233 return BOOLEAN is 4234 begin 4235 return (to_ufixed (l, r'high, r'low) > r); 4236 end function ">"; 4237 4238 function "<" ( 4239 l : NATURAL; 4240 r : UNRESOLVED_ufixed) -- fixed point input 4241 return BOOLEAN is 4242 begin 4243 return (to_ufixed (l, r'high, r'low) < r); 4244 end function "<"; 4245 4246 function "?=" ( 4247 l : NATURAL; 4248 r : UNRESOLVED_ufixed) -- fixed point input 4249 return STD_ULOGIC is 4250 begin 4251 return (to_ufixed (l, r'high, r'low) ?= r); 4252 end function "?="; 4253 4254 function "?/=" ( 4255 l : NATURAL; 4256 r : UNRESOLVED_ufixed) -- fixed point input 4257 return STD_ULOGIC is 4258 begin 4259 return (to_ufixed (l, r'high, r'low) ?/= r); 4260 end function "?/="; 4261 4262 function "?>=" ( 4263 l : NATURAL; 4264 r : UNRESOLVED_ufixed) -- fixed point input 4265 return STD_ULOGIC is 4266 begin 4267 return (to_ufixed (l, r'high, r'low) ?>= r); 4268 end function "?>="; 4269 4270 function "?<=" ( 4271 l : NATURAL; 4272 r : UNRESOLVED_ufixed) -- fixed point input 4273 return STD_ULOGIC is 4274 begin 4275 return (to_ufixed (l, r'high, r'low) ?<= r); 4276 end function "?<="; 4277 4278 function "?>" ( 4279 l : NATURAL; 4280 r : UNRESOLVED_ufixed) -- fixed point input 4281 return STD_ULOGIC is 4282 begin 4283 return (to_ufixed (l, r'high, r'low) ?> r); 4284 end function "?>"; 4285 4286 function "?<" ( 4287 l : NATURAL; 4288 r : UNRESOLVED_ufixed) -- fixed point input 4289 return STD_ULOGIC is 4290 begin 4291 return (to_ufixed (l, r'high, r'low) ?< r); 4292 end function "?<"; 4293 4294 function maximum ( 4295 l : NATURAL; 4296 r : UNRESOLVED_ufixed) -- fixed point input 4297 return UNRESOLVED_ufixed is 4298 begin 4299 return maximum (to_ufixed (l, r'high, r'low), r); 4300 end function maximum; 4301 4302 function minimum ( 4303 l : NATURAL; 4304 r : UNRESOLVED_ufixed) -- fixed point input 4305 return UNRESOLVED_ufixed is 4306 begin 4307 return minimum (to_ufixed (l, r'high, r'low), r); 4308 end function minimum; 4309 4310 -- overloaded ufixed compare functions with real 4311 function "=" ( 4312 l : UNRESOLVED_ufixed; 4313 r : REAL) 4314 return BOOLEAN is 4315 begin 4316 return (l = to_ufixed (r, l'high, l'low)); 4317 end function "="; 4318 4319 function "/=" ( 4320 l : UNRESOLVED_ufixed; 4321 r : REAL) 4322 return BOOLEAN is 4323 begin 4324 return (l /= to_ufixed (r, l'high, l'low)); 4325 end function "/="; 4326 4327 function ">=" ( 4328 l : UNRESOLVED_ufixed; 4329 r : REAL) 4330 return BOOLEAN is 4331 begin 4332 return (l >= to_ufixed (r, l'high, l'low)); 4333 end function ">="; 4334 4335 function "<=" ( 4336 l : UNRESOLVED_ufixed; 4337 r : REAL) 4338 return BOOLEAN is 4339 begin 4340 return (l <= to_ufixed (r, l'high, l'low)); 4341 end function "<="; 4342 4343 function ">" ( 4344 l : UNRESOLVED_ufixed; 4345 r : REAL) 4346 return BOOLEAN is 4347 begin 4348 return (l > to_ufixed (r, l'high, l'low)); 4349 end function ">"; 4350 4351 function "<" ( 4352 l : UNRESOLVED_ufixed; 4353 r : REAL) 4354 return BOOLEAN is 4355 begin 4356 return (l < to_ufixed (r, l'high, l'low)); 4357 end function "<"; 4358 4359 function "?=" ( 4360 l : UNRESOLVED_ufixed; 4361 r : REAL) 4362 return STD_ULOGIC is 4363 begin 4364 return (l ?= to_ufixed (r, l'high, l'low)); 4365 end function "?="; 4366 4367 function "?/=" ( 4368 l : UNRESOLVED_ufixed; 4369 r : REAL) 4370 return STD_ULOGIC is 4371 begin 4372 return (l ?/= to_ufixed (r, l'high, l'low)); 4373 end function "?/="; 4374 4375 function "?>=" ( 4376 l : UNRESOLVED_ufixed; 4377 r : REAL) 4378 return STD_ULOGIC is 4379 begin 4380 return (l ?>= to_ufixed (r, l'high, l'low)); 4381 end function "?>="; 4382 4383 function "?<=" ( 4384 l : UNRESOLVED_ufixed; 4385 r : REAL) 4386 return STD_ULOGIC is 4387 begin 4388 return (l ?<= to_ufixed (r, l'high, l'low)); 4389 end function "?<="; 4390 4391 function "?>" ( 4392 l : UNRESOLVED_ufixed; 4393 r : REAL) 4394 return STD_ULOGIC is 4395 begin 4396 return (l ?> to_ufixed (r, l'high, l'low)); 4397 end function "?>"; 4398 4399 function "?<" ( 4400 l : UNRESOLVED_ufixed; 4401 r : REAL) 4402 return STD_ULOGIC is 4403 begin 4404 return (l ?< to_ufixed (r, l'high, l'low)); 4405 end function "?<"; 4406 4407 function maximum ( 4408 l : UNRESOLVED_ufixed; 4409 r : REAL) 4410 return UNRESOLVED_ufixed is 4411 begin 4412 return maximum (l, to_ufixed (r, l'high, l'low)); 4413 end function maximum; 4414 4415 function minimum ( 4416 l : UNRESOLVED_ufixed; 4417 r : REAL) 4418 return UNRESOLVED_ufixed is 4419 begin 4420 return minimum (l, to_ufixed (r, l'high, l'low)); 4421 end function minimum; 4422 4423 -- real and ufixed 4424 function "=" ( 4425 l : REAL; 4426 r : UNRESOLVED_ufixed) -- fixed point input 4427 return BOOLEAN is 4428 begin 4429 return (to_ufixed (l, r'high, r'low) = r); 4430 end function "="; 4431 4432 function "/=" ( 4433 l : REAL; 4434 r : UNRESOLVED_ufixed) -- fixed point input 4435 return BOOLEAN is 4436 begin 4437 return (to_ufixed (l, r'high, r'low) /= r); 4438 end function "/="; 4439 4440 function ">=" ( 4441 l : REAL; 4442 r : UNRESOLVED_ufixed) -- fixed point input 4443 return BOOLEAN is 4444 begin 4445 return (to_ufixed (l, r'high, r'low) >= r); 4446 end function ">="; 4447 4448 function "<=" ( 4449 l : REAL; 4450 r : UNRESOLVED_ufixed) -- fixed point input 4451 return BOOLEAN is 4452 begin 4453 return (to_ufixed (l, r'high, r'low) <= r); 4454 end function "<="; 4455 4456 function ">" ( 4457 l : REAL; 4458 r : UNRESOLVED_ufixed) -- fixed point input 4459 return BOOLEAN is 4460 begin 4461 return (to_ufixed (l, r'high, r'low) > r); 4462 end function ">"; 4463 4464 function "<" ( 4465 l : REAL; 4466 r : UNRESOLVED_ufixed) -- fixed point input 4467 return BOOLEAN is 4468 begin 4469 return (to_ufixed (l, r'high, r'low) < r); 4470 end function "<"; 4471 4472 function "?=" ( 4473 l : REAL; 4474 r : UNRESOLVED_ufixed) -- fixed point input 4475 return STD_ULOGIC is 4476 begin 4477 return (to_ufixed (l, r'high, r'low) ?= r); 4478 end function "?="; 4479 4480 function "?/=" ( 4481 l : REAL; 4482 r : UNRESOLVED_ufixed) -- fixed point input 4483 return STD_ULOGIC is 4484 begin 4485 return (to_ufixed (l, r'high, r'low) ?/= r); 4486 end function "?/="; 4487 4488 function "?>=" ( 4489 l : REAL; 4490 r : UNRESOLVED_ufixed) -- fixed point input 4491 return STD_ULOGIC is 4492 begin 4493 return (to_ufixed (l, r'high, r'low) ?>= r); 4494 end function "?>="; 4495 4496 function "?<=" ( 4497 l : REAL; 4498 r : UNRESOLVED_ufixed) -- fixed point input 4499 return STD_ULOGIC is 4500 begin 4501 return (to_ufixed (l, r'high, r'low) ?<= r); 4502 end function "?<="; 4503 4504 function "?>" ( 4505 l : REAL; 4506 r : UNRESOLVED_ufixed) -- fixed point input 4507 return STD_ULOGIC is 4508 begin 4509 return (to_ufixed (l, r'high, r'low) ?> r); 4510 end function "?>"; 4511 4512 function "?<" ( 4513 l : REAL; 4514 r : UNRESOLVED_ufixed) -- fixed point input 4515 return STD_ULOGIC is 4516 begin 4517 return (to_ufixed (l, r'high, r'low) ?< r); 4518 end function "?<"; 4519 4520 function maximum ( 4521 l : REAL; 4522 r : UNRESOLVED_ufixed) -- fixed point input 4523 return UNRESOLVED_ufixed is 4524 begin 4525 return maximum (to_ufixed (l, r'high, r'low), r); 4526 end function maximum; 4527 4528 function minimum ( 4529 l : REAL; 4530 r : UNRESOLVED_ufixed) -- fixed point input 4531 return UNRESOLVED_ufixed is 4532 begin 4533 return minimum (to_ufixed (l, r'high, r'low), r); 4534 end function minimum; 4535 4536 -- overloaded sfixed compare functions with integer 4537 function "=" ( 4538 l : UNRESOLVED_sfixed; 4539 r : INTEGER) 4540 return BOOLEAN is 4541 begin 4542 return (l = to_sfixed (r, l'high, l'low)); 4543 end function "="; 4544 4545 function "/=" ( 4546 l : UNRESOLVED_sfixed; 4547 r : INTEGER) 4548 return BOOLEAN is 4549 begin 4550 return (l /= to_sfixed (r, l'high, l'low)); 4551 end function "/="; 4552 4553 function ">=" ( 4554 l : UNRESOLVED_sfixed; 4555 r : INTEGER) 4556 return BOOLEAN is 4557 begin 4558 return (l >= to_sfixed (r, l'high, l'low)); 4559 end function ">="; 4560 4561 function "<=" ( 4562 l : UNRESOLVED_sfixed; 4563 r : INTEGER) 4564 return BOOLEAN is 4565 begin 4566 return (l <= to_sfixed (r, l'high, l'low)); 4567 end function "<="; 4568 4569 function ">" ( 4570 l : UNRESOLVED_sfixed; 4571 r : INTEGER) 4572 return BOOLEAN is 4573 begin 4574 return (l > to_sfixed (r, l'high, l'low)); 4575 end function ">"; 4576 4577 function "<" ( 4578 l : UNRESOLVED_sfixed; 4579 r : INTEGER) 4580 return BOOLEAN is 4581 begin 4582 return (l < to_sfixed (r, l'high, l'low)); 4583 end function "<"; 4584 4585 function "?=" ( 4586 l : UNRESOLVED_sfixed; 4587 r : INTEGER) 4588 return STD_ULOGIC is 4589 begin 4590 return (l ?= to_sfixed (r, l'high, l'low)); 4591 end function "?="; 4592 4593 function "?/=" ( 4594 l : UNRESOLVED_sfixed; 4595 r : INTEGER) 4596 return STD_ULOGIC is 4597 begin 4598 return (l ?/= to_sfixed (r, l'high, l'low)); 4599 end function "?/="; 4600 4601 function "?>=" ( 4602 l : UNRESOLVED_sfixed; 4603 r : INTEGER) 4604 return STD_ULOGIC is 4605 begin 4606 return (l ?>= to_sfixed (r, l'high, l'low)); 4607 end function "?>="; 4608 4609 function "?<=" ( 4610 l : UNRESOLVED_sfixed; 4611 r : INTEGER) 4612 return STD_ULOGIC is 4613 begin 4614 return (l ?<= to_sfixed (r, l'high, l'low)); 4615 end function "?<="; 4616 4617 function "?>" ( 4618 l : UNRESOLVED_sfixed; 4619 r : INTEGER) 4620 return STD_ULOGIC is 4621 begin 4622 return (l ?> to_sfixed (r, l'high, l'low)); 4623 end function "?>"; 4624 4625 function "?<" ( 4626 l : UNRESOLVED_sfixed; 4627 r : INTEGER) 4628 return STD_ULOGIC is 4629 begin 4630 return (l ?< to_sfixed (r, l'high, l'low)); 4631 end function "?<"; 4632 4633 function maximum ( 4634 l : UNRESOLVED_sfixed; 4635 r : INTEGER) 4636 return UNRESOLVED_sfixed is 4637 begin 4638 return maximum (l, to_sfixed (r, l'high, l'low)); 4639 end function maximum; 4640 4641 function minimum ( 4642 l : UNRESOLVED_sfixed; 4643 r : INTEGER) 4644 return UNRESOLVED_sfixed is 4645 begin 4646 return minimum (l, to_sfixed (r, l'high, l'low)); 4647 end function minimum; 4648 4649 -- integer and sfixed 4650 function "=" ( 4651 l : INTEGER; 4652 r : UNRESOLVED_sfixed) -- fixed point input 4653 return BOOLEAN is 4654 begin 4655 return (to_sfixed (l, r'high, r'low) = r); 4656 end function "="; 4657 4658 function "/=" ( 4659 l : INTEGER; 4660 r : UNRESOLVED_sfixed) -- fixed point input 4661 return BOOLEAN is 4662 begin 4663 return (to_sfixed (l, r'high, r'low) /= r); 4664 end function "/="; 4665 4666 function ">=" ( 4667 l : INTEGER; 4668 r : UNRESOLVED_sfixed) -- fixed point input 4669 return BOOLEAN is 4670 begin 4671 return (to_sfixed (l, r'high, r'low) >= r); 4672 end function ">="; 4673 4674 function "<=" ( 4675 l : INTEGER; 4676 r : UNRESOLVED_sfixed) -- fixed point input 4677 return BOOLEAN is 4678 begin 4679 return (to_sfixed (l, r'high, r'low) <= r); 4680 end function "<="; 4681 4682 function ">" ( 4683 l : INTEGER; 4684 r : UNRESOLVED_sfixed) -- fixed point input 4685 return BOOLEAN is 4686 begin 4687 return (to_sfixed (l, r'high, r'low) > r); 4688 end function ">"; 4689 4690 function "<" ( 4691 l : INTEGER; 4692 r : UNRESOLVED_sfixed) -- fixed point input 4693 return BOOLEAN is 4694 begin 4695 return (to_sfixed (l, r'high, r'low) < r); 4696 end function "<"; 4697 4698 function "?=" ( 4699 l : INTEGER; 4700 r : UNRESOLVED_sfixed) -- fixed point input 4701 return STD_ULOGIC is 4702 begin 4703 return (to_sfixed (l, r'high, r'low) ?= r); 4704 end function "?="; 4705 4706 function "?/=" ( 4707 l : INTEGER; 4708 r : UNRESOLVED_sfixed) -- fixed point input 4709 return STD_ULOGIC is 4710 begin 4711 return (to_sfixed (l, r'high, r'low) ?/= r); 4712 end function "?/="; 4713 4714 function "?>=" ( 4715 l : INTEGER; 4716 r : UNRESOLVED_sfixed) -- fixed point input 4717 return STD_ULOGIC is 4718 begin 4719 return (to_sfixed (l, r'high, r'low) ?>= r); 4720 end function "?>="; 4721 4722 function "?<=" ( 4723 l : INTEGER; 4724 r : UNRESOLVED_sfixed) -- fixed point input 4725 return STD_ULOGIC is 4726 begin 4727 return (to_sfixed (l, r'high, r'low) ?<= r); 4728 end function "?<="; 4729 4730 function "?>" ( 4731 l : INTEGER; 4732 r : UNRESOLVED_sfixed) -- fixed point input 4733 return STD_ULOGIC is 4734 begin 4735 return (to_sfixed (l, r'high, r'low) ?> r); 4736 end function "?>"; 4737 4738 function "?<" ( 4739 l : INTEGER; 4740 r : UNRESOLVED_sfixed) -- fixed point input 4741 return STD_ULOGIC is 4742 begin 4743 return (to_sfixed (l, r'high, r'low) ?< r); 4744 end function "?<"; 4745 4746 function maximum ( 4747 l : INTEGER; 4748 r : UNRESOLVED_sfixed) 4749 return UNRESOLVED_sfixed is 4750 begin 4751 return maximum (to_sfixed (l, r'high, r'low), r); 4752 end function maximum; 4753 4754 function minimum ( 4755 l : INTEGER; 4756 r : UNRESOLVED_sfixed) 4757 return UNRESOLVED_sfixed is 4758 begin 4759 return minimum (to_sfixed (l, r'high, r'low), r); 4760 end function minimum; 4761 4762 -- overloaded sfixed compare functions with real 4763 function "=" ( 4764 l : UNRESOLVED_sfixed; 4765 r : REAL) 4766 return BOOLEAN is 4767 begin 4768 return (l = to_sfixed (r, l'high, l'low)); 4769 end function "="; 4770 4771 function "/=" ( 4772 l : UNRESOLVED_sfixed; 4773 r : REAL) 4774 return BOOLEAN is 4775 begin 4776 return (l /= to_sfixed (r, l'high, l'low)); 4777 end function "/="; 4778 4779 function ">=" ( 4780 l : UNRESOLVED_sfixed; 4781 r : REAL) 4782 return BOOLEAN is 4783 begin 4784 return (l >= to_sfixed (r, l'high, l'low)); 4785 end function ">="; 4786 4787 function "<=" ( 4788 l : UNRESOLVED_sfixed; 4789 r : REAL) 4790 return BOOLEAN is 4791 begin 4792 return (l <= to_sfixed (r, l'high, l'low)); 4793 end function "<="; 4794 4795 function ">" ( 4796 l : UNRESOLVED_sfixed; 4797 r : REAL) 4798 return BOOLEAN is 4799 begin 4800 return (l > to_sfixed (r, l'high, l'low)); 4801 end function ">"; 4802 4803 function "<" ( 4804 l : UNRESOLVED_sfixed; 4805 r : REAL) 4806 return BOOLEAN is 4807 begin 4808 return (l < to_sfixed (r, l'high, l'low)); 4809 end function "<"; 4810 4811 function "?=" ( 4812 l : UNRESOLVED_sfixed; 4813 r : REAL) 4814 return STD_ULOGIC is 4815 begin 4816 return (l ?= to_sfixed (r, l'high, l'low)); 4817 end function "?="; 4818 4819 function "?/=" ( 4820 l : UNRESOLVED_sfixed; 4821 r : REAL) 4822 return STD_ULOGIC is 4823 begin 4824 return (l ?/= to_sfixed (r, l'high, l'low)); 4825 end function "?/="; 4826 4827 function "?>=" ( 4828 l : UNRESOLVED_sfixed; 4829 r : REAL) 4830 return STD_ULOGIC is 4831 begin 4832 return (l ?>= to_sfixed (r, l'high, l'low)); 4833 end function "?>="; 4834 4835 function "?<=" ( 4836 l : UNRESOLVED_sfixed; 4837 r : REAL) 4838 return STD_ULOGIC is 4839 begin 4840 return (l ?<= to_sfixed (r, l'high, l'low)); 4841 end function "?<="; 4842 4843 function "?>" ( 4844 l : UNRESOLVED_sfixed; 4845 r : REAL) 4846 return STD_ULOGIC is 4847 begin 4848 return (l ?> to_sfixed (r, l'high, l'low)); 4849 end function "?>"; 4850 4851 function "?<" ( 4852 l : UNRESOLVED_sfixed; 4853 r : REAL) 4854 return STD_ULOGIC is 4855 begin 4856 return (l ?< to_sfixed (r, l'high, l'low)); 4857 end function "?<"; 4858 4859 function maximum ( 4860 l : UNRESOLVED_sfixed; 4861 r : REAL) 4862 return UNRESOLVED_sfixed is 4863 begin 4864 return maximum (l, to_sfixed (r, l'high, l'low)); 4865 end function maximum; 4866 4867 function minimum ( 4868 l : UNRESOLVED_sfixed; 4869 r : REAL) 4870 return UNRESOLVED_sfixed is 4871 begin 4872 return minimum (l, to_sfixed (r, l'high, l'low)); 4873 end function minimum; 4874 4875 -- REAL and sfixed 4876 function "=" ( 4877 l : REAL; 4878 r : UNRESOLVED_sfixed) -- fixed point input 4879 return BOOLEAN is 4880 begin 4881 return (to_sfixed (l, r'high, r'low) = r); 4882 end function "="; 4883 4884 function "/=" ( 4885 l : REAL; 4886 r : UNRESOLVED_sfixed) -- fixed point input 4887 return BOOLEAN is 4888 begin 4889 return (to_sfixed (l, r'high, r'low) /= r); 4890 end function "/="; 4891 4892 function ">=" ( 4893 l : REAL; 4894 r : UNRESOLVED_sfixed) -- fixed point input 4895 return BOOLEAN is 4896 begin 4897 return (to_sfixed (l, r'high, r'low) >= r); 4898 end function ">="; 4899 4900 function "<=" ( 4901 l : REAL; 4902 r : UNRESOLVED_sfixed) -- fixed point input 4903 return BOOLEAN is 4904 begin 4905 return (to_sfixed (l, r'high, r'low) <= r); 4906 end function "<="; 4907 4908 function ">" ( 4909 l : REAL; 4910 r : UNRESOLVED_sfixed) -- fixed point input 4911 return BOOLEAN is 4912 begin 4913 return (to_sfixed (l, r'high, r'low) > r); 4914 end function ">"; 4915 4916 function "<" ( 4917 l : REAL; 4918 r : UNRESOLVED_sfixed) -- fixed point input 4919 return BOOLEAN is 4920 begin 4921 return (to_sfixed (l, r'high, r'low) < r); 4922 end function "<"; 4923 4924 function "?=" ( 4925 l : REAL; 4926 r : UNRESOLVED_sfixed) -- fixed point input 4927 return STD_ULOGIC is 4928 begin 4929 return (to_sfixed (l, r'high, r'low) ?= r); 4930 end function "?="; 4931 4932 function "?/=" ( 4933 l : REAL; 4934 r : UNRESOLVED_sfixed) -- fixed point input 4935 return STD_ULOGIC is 4936 begin 4937 return (to_sfixed (l, r'high, r'low) ?/= r); 4938 end function "?/="; 4939 4940 function "?>=" ( 4941 l : REAL; 4942 r : UNRESOLVED_sfixed) -- fixed point input 4943 return STD_ULOGIC is 4944 begin 4945 return (to_sfixed (l, r'high, r'low) ?>= r); 4946 end function "?>="; 4947 4948 function "?<=" ( 4949 l : REAL; 4950 r : UNRESOLVED_sfixed) -- fixed point input 4951 return STD_ULOGIC is 4952 begin 4953 return (to_sfixed (l, r'high, r'low) ?<= r); 4954 end function "?<="; 4955 4956 function "?>" ( 4957 l : REAL; 4958 r : UNRESOLVED_sfixed) -- fixed point input 4959 return STD_ULOGIC is 4960 begin 4961 return (to_sfixed (l, r'high, r'low) ?> r); 4962 end function "?>"; 4963 4964 function "?<" ( 4965 l : REAL; 4966 r : UNRESOLVED_sfixed) -- fixed point input 4967 return STD_ULOGIC is 4968 begin 4969 return (to_sfixed (l, r'high, r'low) ?< r); 4970 end function "?<"; 4971 4972 function maximum ( 4973 l : REAL; 4974 r : UNRESOLVED_sfixed) 4975 return UNRESOLVED_sfixed is 4976 begin 4977 return maximum (to_sfixed (l, r'high, r'low), r); 4978 end function maximum; 4979 4980 function minimum ( 4981 l : REAL; 4982 r : UNRESOLVED_sfixed) 4983 return UNRESOLVED_sfixed is 4984 begin 4985 return minimum (to_sfixed (l, r'high, r'low), r); 4986 end function minimum; 4987 4988 -- copied from std_logic_textio 4989 type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error); 4990 type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER; 4991 type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC; 4992 type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus; 4993 4994 constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-"; 4995 constant char_to_MVL9 : MVL9_indexed_by_char := 4996 ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z', 4997 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U'); 4998 constant char_to_MVL9plus : MVL9plus_indexed_by_char := 4999 ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z', 5000 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => error); 5001 constant NBSP : CHARACTER := CHARACTER'val(160); -- space character 5002 constant NUS : STRING(2 to 1) := (others => ' '); 5003 5004 -- purpose: Skips white space 5005 procedure skip_whitespace ( 5006 L : inout LINE) is 5007 variable c : CHARACTER; 5008 variable left : positive; 5009 begin 5010 while L /= null and L.all'length /= 0 loop 5011 left := L.all'left; 5012 c := L.all(left); 5013 if (c = ' ' or c = NBSP or c = HT) then 5014 read (L, c); 5015 else 5016 exit; 5017 end if; 5018 end loop; 5019 end procedure skip_whitespace; 5020 5021 -- purpose: writes fixed point into a line 5022 procedure write ( 5023 L : inout LINE; -- input line 5024 VALUE : in UNRESOLVED_ufixed; -- fixed point input 5025 JUSTIFIED : in SIDE := right; 5026 FIELD : in WIDTH := 0) is 5027 variable s : STRING(1 to VALUE'length +1) := (others => ' '); 5028 variable sindx : INTEGER; 5029 begin -- function write Example: 0011.1100 5030 sindx := 1; 5031 for i in VALUE'high downto VALUE'low loop 5032 if i = -1 then 5033 s(sindx) := '.'; 5034 sindx := sindx + 1; 5035 end if; 5036 s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i))); 5037 sindx := sindx + 1; 5038 end loop; 5039 write(L, s, JUSTIFIED, FIELD); 5040 end procedure write; 5041 5042 -- purpose: writes fixed point into a line 5043 procedure write ( 5044 L : inout LINE; -- input line 5045 VALUE : in UNRESOLVED_sfixed; -- fixed point input 5046 JUSTIFIED : in SIDE := right; 5047 FIELD : in WIDTH := 0) is 5048 variable s : STRING(1 to VALUE'length +1); 5049 variable sindx : INTEGER; 5050 begin -- function write Example: 0011.1100 5051 sindx := 1; 5052 for i in VALUE'high downto VALUE'low loop 5053 if i = -1 then 5054 s(sindx) := '.'; 5055 sindx := sindx + 1; 5056 end if; 5057 s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i))); 5058 sindx := sindx + 1; 5059 end loop; 5060 write(L, s, JUSTIFIED, FIELD); 5061 end procedure write; 5062 5063 procedure READ(L : inout LINE; 5064 VALUE : out UNRESOLVED_ufixed) is 5065 -- Possible data: 00000.0000000 5066 -- 000000000000 5067 variable c : CHARACTER; 5068 variable readOk : BOOLEAN; 5069 variable i : INTEGER; -- index variable 5070 variable mv : ufixed (VALUE'range); 5071 variable lastu : BOOLEAN := false; -- last character was an "_" 5072 variable founddot : BOOLEAN := false; -- found a "." 5073 begin -- READ 5074 VALUE := (VALUE'range => 'U'); 5075 skip_whitespace (L); 5076 if VALUE'length > 0 then -- non Null input string 5077 read (L, c, readOk); 5078 i := VALUE'high; 5079 while i >= VALUE'low loop 5080 if readOk = false then -- Bail out if there was a bad read 5081 report fixed_generic_pkg'instance_name & "READ(ufixed) " 5082 & "End of string encountered" 5083 severity error; 5084 return; 5085 elsif c = '_' then 5086 if i = VALUE'high then 5087 report fixed_generic_pkg'instance_name & "READ(ufixed) " 5088 & "String begins with an ""_""" severity error; 5089 return; 5090 elsif lastu then 5091 report fixed_generic_pkg'instance_name & "READ(ufixed) " 5092 & "Two underscores detected in input string ""__""" 5093 severity error; 5094 return; 5095 else 5096 lastu := true; 5097 end if; 5098 elsif c = '.' then -- binary point 5099 if founddot then 5100 report fixed_generic_pkg'instance_name & "READ(ufixed) " 5101 & "Two binary points found in input string" severity error; 5102 return; 5103 elsif i /= -1 then -- Seperator in the wrong spot 5104 report fixed_generic_pkg'instance_name & "READ(ufixed) " 5105 & "Decimal point does not match number format " 5106 severity error; 5107 return; 5108 end if; 5109 founddot := true; 5110 lastu := false; 5111 elsif c = ' ' or c = NBSP or c = HT then -- reading done. 5112 report fixed_generic_pkg'instance_name & "READ(ufixed) " 5113 & "Short read, Space encounted in input string" 5114 severity error; 5115 return; 5116 elsif char_to_MVL9plus(c) = error then 5117 report fixed_generic_pkg'instance_name & "READ(ufixed) " 5118 & "Character '" & 5119 c & "' read, expected STD_ULOGIC literal." 5120 severity error; 5121 return; 5122 else 5123 mv(i) := char_to_MVL9(c); 5124 i := i - 1; 5125 if i < mv'low then 5126 VALUE := mv; 5127 return; 5128 end if; 5129 lastu := false; 5130 end if; 5131 read(L, c, readOk); 5132 end loop; 5133 end if; 5134 end procedure READ; 5135 5136 procedure READ(L : inout LINE; 5137 VALUE : out UNRESOLVED_ufixed; 5138 GOOD : out BOOLEAN) is 5139 -- Possible data: 00000.0000000 5140 -- 000000000000 5141 variable c : CHARACTER; 5142 variable readOk : BOOLEAN; 5143 variable mv : ufixed (VALUE'range); 5144 variable i : INTEGER; -- index variable 5145 variable lastu : BOOLEAN := false; -- last character was an "_" 5146 variable founddot : BOOLEAN := false; -- found a "." 5147 begin -- READ 5148 VALUE := (VALUE'range => 'U'); 5149 skip_whitespace (L); 5150 if VALUE'length > 0 then 5151 read (L, c, readOk); 5152 i := VALUE'high; 5153 GOOD := false; 5154 while i >= VALUE'low loop 5155 if not readOk then -- Bail out if there was a bad read 5156 return; 5157 elsif c = '_' then 5158 if i = VALUE'high then -- Begins with an "_" 5159 return; 5160 elsif lastu then -- "__" detected 5161 return; 5162 else 5163 lastu := true; 5164 end if; 5165 elsif c = '.' then -- binary point 5166 if founddot then 5167 return; 5168 elsif i /= -1 then -- Seperator in the wrong spot 5169 return; 5170 end if; 5171 founddot := true; 5172 lastu := false; 5173 elsif (char_to_MVL9plus(c) = error) then -- Illegal character/short read 5174 return; 5175 else 5176 mv(i) := char_to_MVL9(c); 5177 i := i - 1; 5178 if i < mv'low then -- reading done 5179 GOOD := true; 5180 VALUE := mv; 5181 return; 5182 end if; 5183 lastu := false; 5184 end if; 5185 read(L, c, readOk); 5186 end loop; 5187 else 5188 GOOD := true; -- read into a null array 5189 end if; 5190 end procedure READ; 5191 5192 procedure READ(L : inout LINE; 5193 VALUE : out UNRESOLVED_sfixed) is 5194 variable c : CHARACTER; 5195 variable readOk : BOOLEAN; 5196 variable i : INTEGER; -- index variable 5197 variable mv : sfixed (VALUE'range); 5198 variable lastu : BOOLEAN := false; -- last character was an "_" 5199 variable founddot : BOOLEAN := false; -- found a "." 5200 begin -- READ 5201 VALUE := (VALUE'range => 'U'); 5202 skip_whitespace (L); 5203 if VALUE'length > 0 then -- non Null input string 5204 read (L, c, readOk); 5205 i := VALUE'high; 5206 while i >= VALUE'low loop 5207 if readOk = false then -- Bail out if there was a bad read 5208 report fixed_generic_pkg'instance_name & "READ(sfixed) " 5209 & "End of string encountered" 5210 severity error; 5211 return; 5212 elsif c = '_' then 5213 if i = VALUE'high then 5214 report fixed_generic_pkg'instance_name & "READ(sfixed) " 5215 & "String begins with an ""_""" severity error; 5216 return; 5217 elsif lastu then 5218 report fixed_generic_pkg'instance_name & "READ(sfixed) " 5219 & "Two underscores detected in input string ""__""" 5220 severity error; 5221 return; 5222 else 5223 lastu := true; 5224 end if; 5225 elsif c = '.' then -- binary point 5226 if founddot then 5227 report fixed_generic_pkg'instance_name & "READ(sfixed) " 5228 & "Two binary points found in input string" severity error; 5229 return; 5230 elsif i /= -1 then -- Seperator in the wrong spot 5231 report fixed_generic_pkg'instance_name & "READ(sfixed) " 5232 & "Decimal point does not match number format " 5233 severity error; 5234 return; 5235 end if; 5236 founddot := true; 5237 lastu := false; 5238 elsif c = ' ' or c = NBSP or c = HT then -- reading done. 5239 report fixed_generic_pkg'instance_name & "READ(sfixed) " 5240 & "Short read, Space encounted in input string" 5241 severity error; 5242 return; 5243 elsif char_to_MVL9plus(c) = error then 5244 report fixed_generic_pkg'instance_name & "READ(sfixed) " 5245 & "Character '" & 5246 c & "' read, expected STD_ULOGIC literal." 5247 severity error; 5248 return; 5249 else 5250 mv(i) := char_to_MVL9(c); 5251 i := i - 1; 5252 if i < mv'low then 5253 VALUE := mv; 5254 return; 5255 end if; 5256 lastu := false; 5257 end if; 5258 read(L, c, readOk); 5259 end loop; 5260 end if; 5261 end procedure READ; 5262 5263 procedure READ(L : inout LINE; 5264 VALUE : out UNRESOLVED_sfixed; 5265 GOOD : out BOOLEAN) is 5266 variable value_ufixed : UNRESOLVED_ufixed (VALUE'range); 5267 begin -- READ 5268 READ (L => L, VALUE => value_ufixed, GOOD => GOOD); 5269 VALUE := UNRESOLVED_sfixed (value_ufixed); 5270 end procedure READ; 5271 5272 -- octal read and write 5273 procedure owrite ( 5274 L : inout LINE; -- input line 5275 VALUE : in UNRESOLVED_ufixed; -- fixed point input 5276 JUSTIFIED : in SIDE := right; 5277 FIELD : in WIDTH := 0) is 5278 begin -- Example 03.30 5279 write (L => L, 5280 VALUE => TO_OSTRING (VALUE), 5281 JUSTIFIED => JUSTIFIED, 5282 FIELD => FIELD); 5283 end procedure owrite; 5284 5285 procedure owrite ( 5286 L : inout LINE; -- input line 5287 VALUE : in UNRESOLVED_sfixed; -- fixed point input 5288 JUSTIFIED : in SIDE := right; 5289 FIELD : in WIDTH := 0) is 5290 begin -- Example 03.30 5291 write (L => L, 5292 VALUE => TO_OSTRING (VALUE), 5293 JUSTIFIED => JUSTIFIED, 5294 FIELD => FIELD); 5295 end procedure owrite; 5296 5297 -- Note that for Octal and Hex read, you can not start with a ".", 5298 -- the read is for numbers formatted "A.BC". These routines go to 5299 -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3). 5300 procedure Char2TriBits (C : CHARACTER; 5301 RESULT : out STD_ULOGIC_VECTOR(2 downto 0); 5302 GOOD : out BOOLEAN; 5303 ISSUE_ERROR : in BOOLEAN) is 5304 begin 5305 case C is 5306 when '0' => RESULT := o"0"; GOOD := true; 5307 when '1' => RESULT := o"1"; GOOD := true; 5308 when '2' => RESULT := o"2"; GOOD := true; 5309 when '3' => RESULT := o"3"; GOOD := true; 5310 when '4' => RESULT := o"4"; GOOD := true; 5311 when '5' => RESULT := o"5"; GOOD := true; 5312 when '6' => RESULT := o"6"; GOOD := true; 5313 when '7' => RESULT := o"7"; GOOD := true; 5314 when 'Z' => RESULT := "ZZZ"; GOOD := true; 5315 when 'X' => RESULT := "XXX"; GOOD := true; 5316 when others => 5317 assert not ISSUE_ERROR 5318 report fixed_generic_pkg'instance_name 5319 & "OREAD Error: Read a '" & C & 5320 "', expected an Octal character (0-7)." 5321 severity error; 5322 RESULT := "UUU"; 5323 GOOD := false; 5324 end case; 5325 end procedure Char2TriBits; 5326 5327 -- purpose: Routines common to the OREAD routines 5328 procedure OREAD_common ( 5329 L : inout LINE; 5330 slv : out STD_ULOGIC_VECTOR; 5331 igood : out BOOLEAN; 5332 idex : out INTEGER; 5333 constant bpoint : in INTEGER; -- binary point 5334 constant message : in BOOLEAN; 5335 constant smath : in BOOLEAN) is 5336 5337 -- purpose: error message routine 5338 procedure errmes ( 5339 constant mess : in STRING) is -- error message 5340 begin 5341 if message then 5342 if smath then 5343 report fixed_generic_pkg'instance_name 5344 & "OREAD(sfixed) " 5345 & mess 5346 severity error; 5347 else 5348 report fixed_generic_pkg'instance_name 5349 & "OREAD(ufixed) " 5350 & mess 5351 severity error; 5352 end if; 5353 end if; 5354 end procedure errmes; 5355 variable xgood : BOOLEAN; 5356 variable nybble : STD_ULOGIC_VECTOR (2 downto 0); -- 3 bits 5357 variable c : CHARACTER; 5358 variable i : INTEGER; 5359 variable lastu : BOOLEAN := false; -- last character was an "_" 5360 variable founddot : BOOLEAN := false; -- found a dot. 5361 begin 5362 skip_whitespace (L); 5363 if slv'length > 0 then 5364 i := slv'high; 5365 read (L, c, xgood); 5366 while i > 0 loop 5367 if xgood = false then 5368 errmes ("Error: end of string encountered"); 5369 exit; 5370 elsif c = '_' then 5371 if i = slv'length then 5372 errmes ("Error: String begins with an ""_"""); 5373 xgood := false; 5374 exit; 5375 elsif lastu then 5376 errmes ("Error: Two underscores detected in input string ""__"""); 5377 xgood := false; 5378 exit; 5379 else 5380 lastu := true; 5381 end if; 5382 elsif (c = '.') then 5383 if (i + 1 /= bpoint) then 5384 errmes ("encountered ""."" at wrong index"); 5385 xgood := false; 5386 exit; 5387 elsif i = slv'length then 5388 errmes ("encounted a ""."" at the beginning of the line"); 5389 xgood := false; 5390 exit; 5391 elsif founddot then 5392 errmes ("Two ""."" encounted in input string"); 5393 xgood := false; 5394 exit; 5395 end if; 5396 founddot := true; 5397 lastu := false; 5398 else 5399 Char2TriBits(c, nybble, xgood, message); 5400 if not xgood then 5401 exit; 5402 end if; 5403 slv (i downto i-2) := nybble; 5404 i := i - 3; 5405 lastu := false; 5406 end if; 5407 if i > 0 then 5408 read (L, c, xgood); 5409 end if; 5410 end loop; 5411 idex := i; 5412 igood := xgood; 5413 else 5414 igood := true; -- read into a null array 5415 idex := -1; 5416 end if; 5417 end procedure OREAD_common; 5418 5419 -- Note that for Octal and Hex read, you can not start with a ".", 5420 -- the read is for numbers formatted "A.BC". These routines go to 5421 -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3). 5422 procedure OREAD (L : inout LINE; 5423 VALUE : out UNRESOLVED_ufixed) is 5424 constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1; 5425 constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3; 5426 variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits 5427 variable valuex : UNRESOLVED_ufixed (hbv downto lbv); 5428 variable igood : BOOLEAN; 5429 variable i : INTEGER; 5430 begin 5431 VALUE := (VALUE'range => 'U'); 5432 OREAD_common ( L => L, 5433 slv => slv, 5434 igood => igood, 5435 idex => i, 5436 bpoint => -lbv, 5437 message => true, 5438 smath => false); 5439 if igood then -- We did not get another error 5440 if not ((i = -1) and -- We read everything, and high bits 0 5441 (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then 5442 report fixed_generic_pkg'instance_name 5443 & "OREAD(ufixed): Vector truncated." 5444 severity error; 5445 else 5446 if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then 5447 assert no_warning 5448 report fixed_generic_pkg'instance_name 5449 & "OREAD(ufixed): Vector truncated" 5450 severity warning; 5451 end if; 5452 valuex := to_ufixed (slv, hbv, lbv); 5453 VALUE := valuex (VALUE'range); 5454 end if; 5455 end if; 5456 end procedure OREAD; 5457 5458 procedure OREAD(L : inout LINE; 5459 VALUE : out UNRESOLVED_ufixed; 5460 GOOD : out BOOLEAN) is 5461 constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1; 5462 constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3; 5463 variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits 5464 variable valuex : UNRESOLVED_ufixed (hbv downto lbv); 5465 variable igood : BOOLEAN; 5466 variable i : INTEGER; 5467 begin 5468 VALUE := (VALUE'range => 'U'); 5469 OREAD_common ( L => L, 5470 slv => slv, 5471 igood => igood, 5472 idex => i, 5473 bpoint => -lbv, 5474 message => false, 5475 smath => false); 5476 if (igood and -- We did not get another error 5477 (i = -1) and -- We read everything, and high bits 0 5478 (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then 5479 valuex := to_ufixed (slv, hbv, lbv); 5480 VALUE := valuex (VALUE'range); 5481 GOOD := true; 5482 else 5483 GOOD := false; 5484 end if; 5485 end procedure OREAD; 5486 5487 procedure OREAD(L : inout LINE; 5488 VALUE : out UNRESOLVED_sfixed) is 5489 constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1; 5490 constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3; 5491 variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits 5492 variable valuex : UNRESOLVED_sfixed (hbv downto lbv); 5493 variable igood : BOOLEAN; 5494 variable i : INTEGER; 5495 begin 5496 VALUE := (VALUE'range => 'U'); 5497 OREAD_common ( L => L, 5498 slv => slv, 5499 igood => igood, 5500 idex => i, 5501 bpoint => -lbv, 5502 message => true, 5503 smath => true); 5504 if igood then -- We did not get another error 5505 if not ((i = -1) and -- We read everything 5506 ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits 5507 or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or 5508 (slv(VALUE'high-lbv) = '1' and 5509 and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then 5510 report fixed_generic_pkg'instance_name 5511 & "OREAD(sfixed): Vector truncated." 5512 severity error; 5513 else 5514 if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then 5515 assert no_warning 5516 report fixed_generic_pkg'instance_name 5517 & "OREAD(sfixed): Vector truncated" 5518 severity warning; 5519 end if; 5520 valuex := to_sfixed (slv, hbv, lbv); 5521 VALUE := valuex (VALUE'range); 5522 end if; 5523 end if; 5524 end procedure OREAD; 5525 5526 procedure OREAD(L : inout LINE; 5527 VALUE : out UNRESOLVED_sfixed; 5528 GOOD : out BOOLEAN) is 5529 constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1; 5530 constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3; 5531 variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits 5532 variable valuex : UNRESOLVED_sfixed (hbv downto lbv); 5533 variable igood : BOOLEAN; 5534 variable i : INTEGER; 5535 begin 5536 VALUE := (VALUE'range => 'U'); 5537 OREAD_common ( L => L, 5538 slv => slv, 5539 igood => igood, 5540 idex => i, 5541 bpoint => -lbv, 5542 message => false, 5543 smath => true); 5544 if (igood -- We did not get another error 5545 and (i = -1) -- We read everything 5546 and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits 5547 or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or 5548 (slv(VALUE'high-lbv) = '1' and 5549 and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then 5550 valuex := to_sfixed (slv, hbv, lbv); 5551 VALUE := valuex (VALUE'range); 5552 GOOD := true; 5553 else 5554 GOOD := false; 5555 end if; 5556 end procedure OREAD; 5557 5558 -- hex read and write 5559 procedure hwrite ( 5560 L : inout LINE; -- input line 5561 VALUE : in UNRESOLVED_ufixed; -- fixed point input 5562 JUSTIFIED : in SIDE := right; 5563 FIELD : in WIDTH := 0) is 5564 begin -- Example 03.30 5565 write (L => L, 5566 VALUE => TO_HSTRING (VALUE), 5567 JUSTIFIED => JUSTIFIED, 5568 FIELD => FIELD); 5569 end procedure hwrite; 5570 5571 -- purpose: writes fixed point into a line 5572 procedure hwrite ( 5573 L : inout LINE; -- input line 5574 VALUE : in UNRESOLVED_sfixed; -- fixed point input 5575 JUSTIFIED : in SIDE := right; 5576 FIELD : in WIDTH := 0) is 5577 begin -- Example 03.30 5578 write (L => L, 5579 VALUE => TO_HSTRING (VALUE), 5580 JUSTIFIED => JUSTIFIED, 5581 FIELD => FIELD); 5582 end procedure hwrite; 5583 5584 -- Hex Read and Write procedures for STD_ULOGIC_VECTOR. 5585 -- Modified from the original to be more forgiving. 5586 5587 procedure Char2QuadBits (C : CHARACTER; 5588 RESULT : out STD_ULOGIC_VECTOR(3 downto 0); 5589 GOOD : out BOOLEAN; 5590 ISSUE_ERROR : in BOOLEAN) is 5591 begin 5592 case C is 5593 when '0' => RESULT := x"0"; GOOD := true; 5594 when '1' => RESULT := x"1"; GOOD := true; 5595 when '2' => RESULT := x"2"; GOOD := true; 5596 when '3' => RESULT := x"3"; GOOD := true; 5597 when '4' => RESULT := x"4"; GOOD := true; 5598 when '5' => RESULT := x"5"; GOOD := true; 5599 when '6' => RESULT := x"6"; GOOD := true; 5600 when '7' => RESULT := x"7"; GOOD := true; 5601 when '8' => RESULT := x"8"; GOOD := true; 5602 when '9' => RESULT := x"9"; GOOD := true; 5603 when 'A' | 'a' => RESULT := x"A"; GOOD := true; 5604 when 'B' | 'b' => RESULT := x"B"; GOOD := true; 5605 when 'C' | 'c' => RESULT := x"C"; GOOD := true; 5606 when 'D' | 'd' => RESULT := x"D"; GOOD := true; 5607 when 'E' | 'e' => RESULT := x"E"; GOOD := true; 5608 when 'F' | 'f' => RESULT := x"F"; GOOD := true; 5609 when 'Z' => RESULT := "ZZZZ"; GOOD := true; 5610 when 'X' => RESULT := "XXXX"; GOOD := true; 5611 when others => 5612 assert not ISSUE_ERROR 5613 report fixed_generic_pkg'instance_name 5614 & "HREAD Error: Read a '" & C & 5615 "', expected a Hex character (0-F)." 5616 severity error; 5617 RESULT := "UUUU"; 5618 GOOD := false; 5619 end case; 5620 end procedure Char2QuadBits; 5621 5622 -- purpose: Routines common to the HREAD routines 5623 procedure HREAD_common ( 5624 L : inout LINE; 5625 slv : out STD_ULOGIC_VECTOR; 5626 igood : out BOOLEAN; 5627 idex : out INTEGER; 5628 constant bpoint : in INTEGER; -- binary point 5629 constant message : in BOOLEAN; 5630 constant smath : in BOOLEAN) is 5631 5632 -- purpose: error message routine 5633 procedure errmes ( 5634 constant mess : in STRING) is -- error message 5635 begin 5636 if message then 5637 if smath then 5638 report fixed_generic_pkg'instance_name 5639 & "HREAD(sfixed) " 5640 & mess 5641 severity error; 5642 else 5643 report fixed_generic_pkg'instance_name 5644 & "HREAD(ufixed) " 5645 & mess 5646 severity error; 5647 end if; 5648 end if; 5649 end procedure errmes; 5650 variable xgood : BOOLEAN; 5651 variable nybble : STD_ULOGIC_VECTOR (3 downto 0); -- 4 bits 5652 variable c : CHARACTER; 5653 variable i : INTEGER; 5654 variable lastu : BOOLEAN := false; -- last character was an "_" 5655 variable founddot : BOOLEAN := false; -- found a dot. 5656 begin 5657 skip_whitespace (L); 5658 if slv'length > 0 then 5659 i := slv'high; 5660 read (L, c, xgood); 5661 while i > 0 loop 5662 if xgood = false then 5663 errmes ("Error: end of string encountered"); 5664 exit; 5665 elsif c = '_' then 5666 if i = slv'length then 5667 errmes ("Error: String begins with an ""_"""); 5668 xgood := false; 5669 exit; 5670 elsif lastu then 5671 errmes ("Error: Two underscores detected in input string ""__"""); 5672 xgood := false; 5673 exit; 5674 else 5675 lastu := true; 5676 end if; 5677 elsif (c = '.') then 5678 if (i + 1 /= bpoint) then 5679 errmes ("encountered ""."" at wrong index"); 5680 xgood := false; 5681 exit; 5682 elsif i = slv'length then 5683 errmes ("encounted a ""."" at the beginning of the line"); 5684 xgood := false; 5685 exit; 5686 elsif founddot then 5687 errmes ("Two ""."" encounted in input string"); 5688 xgood := false; 5689 exit; 5690 end if; 5691 founddot := true; 5692 lastu := false; 5693 else 5694 Char2QuadBits(c, nybble, xgood, message); 5695 if not xgood then 5696 exit; 5697 end if; 5698 slv (i downto i-3) := nybble; 5699 i := i - 4; 5700 lastu := false; 5701 end if; 5702 if i > 0 then 5703 read (L, c, xgood); 5704 end if; 5705 end loop; 5706 idex := i; 5707 igood := xgood; 5708 else 5709 idex := -1; 5710 igood := true; -- read null string 5711 end if; 5712 end procedure HREAD_common; 5713 5714 procedure HREAD(L : inout LINE; 5715 VALUE : out UNRESOLVED_ufixed) is 5716 constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1; 5717 constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4; 5718 variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits 5719 variable valuex : UNRESOLVED_ufixed (hbv downto lbv); 5720 variable igood : BOOLEAN; 5721 variable i : INTEGER; 5722 begin 5723 VALUE := (VALUE'range => 'U'); 5724 HREAD_common ( L => L, 5725 slv => slv, 5726 igood => igood, 5727 idex => i, 5728 bpoint => -lbv, 5729 message => true, 5730 smath => false); 5731 if igood then 5732 if not ((i = -1) and -- We read everything, and high bits 0 5733 (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then 5734 report fixed_generic_pkg'instance_name 5735 & "HREAD(ufixed): Vector truncated." 5736 severity error; 5737 else 5738 if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then 5739 assert no_warning 5740 report fixed_generic_pkg'instance_name 5741 & "HREAD(ufixed): Vector truncated" 5742 severity warning; 5743 end if; 5744 valuex := to_ufixed (slv, hbv, lbv); 5745 VALUE := valuex (VALUE'range); 5746 end if; 5747 end if; 5748 end procedure HREAD; 5749 5750 procedure HREAD(L : inout LINE; 5751 VALUE : out UNRESOLVED_ufixed; 5752 GOOD : out BOOLEAN) is 5753 constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1; 5754 constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4; 5755 variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits 5756 variable valuex : UNRESOLVED_ufixed (hbv downto lbv); 5757 variable igood : BOOLEAN; 5758 variable i : INTEGER; 5759 begin 5760 VALUE := (VALUE'range => 'U'); 5761 HREAD_common ( L => L, 5762 slv => slv, 5763 igood => igood, 5764 idex => i, 5765 bpoint => -lbv, 5766 message => false, 5767 smath => false); 5768 if (igood and -- We did not get another error 5769 (i = -1) and -- We read everything, and high bits 0 5770 (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then 5771 valuex := to_ufixed (slv, hbv, lbv); 5772 VALUE := valuex (VALUE'range); 5773 GOOD := true; 5774 else 5775 GOOD := false; 5776 end if; 5777 end procedure HREAD; 5778 5779 procedure HREAD(L : inout LINE; 5780 VALUE : out UNRESOLVED_sfixed) is 5781 constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1; 5782 constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4; 5783 variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits 5784 variable valuex : UNRESOLVED_sfixed (hbv downto lbv); 5785 variable igood : BOOLEAN; 5786 variable i : INTEGER; 5787 begin 5788 VALUE := (VALUE'range => 'U'); 5789 HREAD_common ( L => L, 5790 slv => slv, 5791 igood => igood, 5792 idex => i, 5793 bpoint => -lbv, 5794 message => true, 5795 smath => true); 5796 if igood then -- We did not get another error 5797 if not ((i = -1) -- We read everything 5798 and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits 5799 or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or 5800 (slv(VALUE'high-lbv) = '1' and 5801 and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then 5802 report fixed_generic_pkg'instance_name 5803 & "HREAD(sfixed): Vector truncated." 5804 severity error; 5805 else 5806 if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then 5807 assert no_warning 5808 report fixed_generic_pkg'instance_name 5809 & "HREAD(sfixed): Vector truncated" 5810 severity warning; 5811 end if; 5812 valuex := to_sfixed (slv, hbv, lbv); 5813 VALUE := valuex (VALUE'range); 5814 end if; 5815 end if; 5816 end procedure HREAD; 5817 5818 procedure HREAD(L : inout LINE; 5819 VALUE : out UNRESOLVED_sfixed; 5820 GOOD : out BOOLEAN) is 5821 constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1; 5822 constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4; 5823 variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits 5824 variable valuex : UNRESOLVED_sfixed (hbv downto lbv); 5825 variable igood : BOOLEAN; 5826 variable i : INTEGER; 5827 begin 5828 VALUE := (VALUE'range => 'U'); 5829 HREAD_common ( L => L, 5830 slv => slv, 5831 igood => igood, 5832 idex => i, 5833 bpoint => -lbv, 5834 message => false, 5835 smath => true); 5836 if (igood and -- We did not get another error 5837 (i = -1) and -- We read everything 5838 ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits 5839 or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or 5840 (slv(VALUE'high-lbv) = '1' and 5841 and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then 5842 valuex := to_sfixed (slv, hbv, lbv); 5843 VALUE := valuex (VALUE'range); 5844 GOOD := true; 5845 else 5846 GOOD := false; 5847 end if; 5848 end procedure HREAD; 5849 5850 -- TO_STRING functions. Useful in "report" statements. 5851 -- Example: report "result was " & TO_STRING(result); 5852 function TO_STRING (value : UNRESOLVED_ufixed) return STRING is 5853 variable s : STRING(1 to value'length +1) := (others => ' '); 5854 variable subval : UNRESOLVED_ufixed (value'high downto -1); 5855 variable sindx : INTEGER; 5856 begin 5857 if value'length < 1 then 5858 return NUS; 5859 else 5860 if value'high < 0 then 5861 if value(value'high) = 'Z' then 5862 return TO_STRING (resize (sfixed(value), 0, value'low)); 5863 else 5864 return TO_STRING (resize (value, 0, value'low)); 5865 end if; 5866 elsif value'low >= 0 then 5867 if Is_X (value(value'low)) then 5868 subval := (others => value(value'low)); 5869 subval (value'range) := value; 5870 return TO_STRING(subval); 5871 else 5872 return TO_STRING (resize (value, value'high, -1)); 5873 end if; 5874 else 5875 sindx := 1; 5876 for i in value'high downto value'low loop 5877 if i = -1 then 5878 s(sindx) := '.'; 5879 sindx := sindx + 1; 5880 end if; 5881 s(sindx) := MVL9_to_char(STD_ULOGIC(value(i))); 5882 sindx := sindx + 1; 5883 end loop; 5884 return s; 5885 end if; 5886 end if; 5887 end function TO_STRING; 5888 5889 function TO_STRING (value : UNRESOLVED_sfixed) return STRING is 5890 variable s : STRING(1 to value'length + 1) := (others => ' '); 5891 variable subval : UNRESOLVED_sfixed (value'high downto -1); 5892 variable sindx : INTEGER; 5893 begin 5894 if value'length < 1 then 5895 return NUS; 5896 else 5897 if value'high < 0 then 5898 return TO_STRING (resize (value, 0, value'low)); 5899 elsif value'low >= 0 then 5900 if Is_X (value(value'low)) then 5901 subval := (others => value(value'low)); 5902 subval (value'range) := value; 5903 return TO_STRING(subval); 5904 else 5905 return TO_STRING (resize (value, value'high, -1)); 5906 end if; 5907 else 5908 sindx := 1; 5909 for i in value'high downto value'low loop 5910 if i = -1 then 5911 s(sindx) := '.'; 5912 sindx := sindx + 1; 5913 end if; 5914 s(sindx) := MVL9_to_char(STD_ULOGIC(value(i))); 5915 sindx := sindx + 1; 5916 end loop; 5917 return s; 5918 end if; 5919 end if; 5920 end function TO_STRING; 5921 5922 function TO_OSTRING (value : UNRESOLVED_ufixed) return STRING is 5923 constant lne : INTEGER := (-value'low+2)/3; 5924 variable subval : UNRESOLVED_ufixed (value'high downto -3); 5925 variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + value'low) -1); 5926 variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0); 5927 begin 5928 if value'length < 1 then 5929 return NUS; 5930 else 5931 if value'high < 0 then 5932 if value(value'high) = 'Z' then 5933 return TO_OSTRING (resize (sfixed(value), 2, value'low)); 5934 else 5935 return TO_OSTRING (resize (value, 2, value'low)); 5936 end if; 5937 elsif value'low >= 0 then 5938 if Is_X (value(value'low)) then 5939 subval := (others => value(value'low)); 5940 subval (value'range) := value; 5941 return TO_OSTRING(subval); 5942 else 5943 return TO_OSTRING (resize (value, value'high, -3)); 5944 end if; 5945 else 5946 slv := to_sulv (value); 5947 if Is_X (value (value'low)) then 5948 lpad := (others => value (value'low)); 5949 else 5950 lpad := (others => '0'); 5951 end if; 5952 return TO_OSTRING(slv(slv'high downto slv'high-value'high)) 5953 & "." 5954 & TO_OSTRING(slv(slv'high-value'high-1 downto 0) & lpad); 5955 end if; 5956 end if; 5957 end function TO_OSTRING; 5958 5959 function TO_HSTRING (value : UNRESOLVED_ufixed) return STRING is 5960 constant lne : INTEGER := (-value'low+3)/4; 5961 variable subval : UNRESOLVED_ufixed (value'high downto -4); 5962 variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + value'low) -1); 5963 variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0); 5964 begin 5965 if value'length < 1 then 5966 return NUS; 5967 else 5968 if value'high < 0 then 5969 if value(value'high) = 'Z' then 5970 return TO_HSTRING (resize (sfixed(value), 3, value'low)); 5971 else 5972 return TO_HSTRING (resize (value, 3, value'low)); 5973 end if; 5974 elsif value'low >= 0 then 5975 if Is_X (value(value'low)) then 5976 subval := (others => value(value'low)); 5977 subval (value'range) := value; 5978 return TO_HSTRING(subval); 5979 else 5980 return TO_HSTRING (resize (value, value'high, -4)); 5981 end if; 5982 else 5983 slv := to_sulv (value); 5984 if Is_X (value (value'low)) then 5985 lpad := (others => value(value'low)); 5986 else 5987 lpad := (others => '0'); 5988 end if; 5989 return TO_HSTRING(slv(slv'high downto slv'high-value'high)) 5990 & "." 5991 & TO_HSTRING(slv(slv'high-value'high-1 downto 0)&lpad); 5992 end if; 5993 end if; 5994 end function TO_HSTRING; 5995 5996 function TO_OSTRING (value : UNRESOLVED_sfixed) return STRING is 5997 constant ne : INTEGER := ((value'high+1)+2)/3; 5998 variable pad : STD_ULOGIC_VECTOR(0 to (ne*3 - (value'high+1)) - 1); 5999 constant lne : INTEGER := (-value'low+2)/3; 6000 variable subval : UNRESOLVED_sfixed (value'high downto -3); 6001 variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + value'low) -1); 6002 variable slv : STD_ULOGIC_VECTOR (value'high - value'low downto 0); 6003 begin 6004 if value'length < 1 then 6005 return NUS; 6006 else 6007 if value'high < 0 then 6008 return TO_OSTRING (resize (value, 2, value'low)); 6009 elsif value'low >= 0 then 6010 if Is_X (value(value'low)) then 6011 subval := (others => value(value'low)); 6012 subval (value'range) := value; 6013 return TO_OSTRING(subval); 6014 else 6015 return TO_OSTRING (resize (value, value'high, -3)); 6016 end if; 6017 else 6018 pad := (others => value(value'high)); 6019 slv := to_sulv (value); 6020 if Is_X (value (value'low)) then 6021 lpad := (others => value(value'low)); 6022 else 6023 lpad := (others => '0'); 6024 end if; 6025 return TO_OSTRING(pad & slv(slv'high downto slv'high-value'high)) 6026 & "." 6027 & TO_OSTRING(slv(slv'high-value'high-1 downto 0) & lpad); 6028 end if; 6029 end if; 6030 end function TO_OSTRING; 6031 6032 function TO_HSTRING (value : UNRESOLVED_sfixed) return STRING is 6033 constant ne : INTEGER := ((value'high+1)+3)/4; 6034 variable pad : STD_ULOGIC_VECTOR(0 to (ne*4 - (value'high+1)) - 1); 6035 constant lne : INTEGER := (-value'low+3)/4; 6036 variable subval : UNRESOLVED_sfixed (value'high downto -4); 6037 variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + value'low) -1); 6038 variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0); 6039 begin 6040 if value'length < 1 then 6041 return NUS; 6042 else 6043 if value'high < 0 then 6044 return TO_HSTRING (resize (value, 3, value'low)); 6045 elsif value'low >= 0 then 6046 if Is_X (value(value'low)) then 6047 subval := (others => value(value'low)); 6048 subval (value'range) := value; 6049 return TO_HSTRING(subval); 6050 else 6051 return TO_HSTRING (resize (value, value'high, -4)); 6052 end if; 6053 else 6054 slv := to_sulv (value); 6055 pad := (others => value(value'high)); 6056 if Is_X (value (value'low)) then 6057 lpad := (others => value(value'low)); 6058 else 6059 lpad := (others => '0'); 6060 end if; 6061 return TO_HSTRING(pad & slv(slv'high downto slv'high-value'high)) 6062 & "." 6063 & TO_HSTRING(slv(slv'high-value'high-1 downto 0) & lpad); 6064 end if; 6065 end if; 6066 end function TO_HSTRING; 6067 6068 -- From string functions allow you to convert a string into a fixed 6069 -- point number. Example: 6070 -- signal uf1 : ufixed (3 downto -3); 6071 -- uf1 <= from_string ("0110.100", uf1'high, uf1'low); -- 6.5 6072 -- The "." is optional in this syntax, however it exist and is 6073 -- in the wrong location an error is produced. Overflow will 6074 -- result in saturation. 6075 function from_string ( 6076 bstring : STRING; -- binary string 6077 constant left_index : INTEGER; 6078 constant right_index : INTEGER) 6079 return UNRESOLVED_ufixed 6080 is 6081 variable result : UNRESOLVED_ufixed (left_index downto right_index); 6082 variable L : LINE; 6083 variable good : BOOLEAN; 6084 begin 6085 L := new STRING'(bstring); 6086 READ (L, result, good); 6087 deallocate (L); 6088 assert (good) 6089 report fixed_generic_pkg'instance_name 6090 & "from_string: Bad string "& bstring severity error; 6091 return result; 6092 end function from_string; 6093 6094 -- Octal and hex conversions work as follows: 6095 -- uf1 <= from_hstring ("6.8", 3, -3); -- 6.5 (bottom zeros dropped) 6096 -- uf1 <= from_ostring ("06.4", 3, -3); -- 6.5 (top zeros dropped) 6097 function from_ostring ( 6098 ostring : STRING; -- Octal string 6099 constant left_index : INTEGER; 6100 constant right_index : INTEGER) 6101 return UNRESOLVED_ufixed 6102 is 6103 variable result : UNRESOLVED_ufixed (left_index downto right_index); 6104 variable L : LINE; 6105 variable good : BOOLEAN; 6106 begin 6107 L := new STRING'(ostring); 6108 OREAD (L, result, good); 6109 deallocate (L); 6110 assert (good) 6111 report fixed_generic_pkg'instance_name 6112 & "from_ostring: Bad string "& ostring severity error; 6113 return result; 6114 end function from_ostring; 6115 6116 function from_hstring ( 6117 hstring : STRING; -- hex string 6118 constant left_index : INTEGER; 6119 constant right_index : INTEGER) 6120 return UNRESOLVED_ufixed 6121 is 6122 variable result : UNRESOLVED_ufixed (left_index downto right_index); 6123 variable L : LINE; 6124 variable good : BOOLEAN; 6125 begin 6126 L := new STRING'(hstring); 6127 HREAD (L, result, good); 6128 deallocate (L); 6129 assert (good) 6130 report fixed_generic_pkg'instance_name 6131 & "from_hstring: Bad string "& hstring severity error; 6132 return result; 6133 end function from_hstring; 6134 6135 function from_string ( 6136 bstring : STRING; -- binary string 6137 constant left_index : INTEGER; 6138 constant right_index : INTEGER) 6139 return UNRESOLVED_sfixed 6140 is 6141 variable result : UNRESOLVED_sfixed (left_index downto right_index); 6142 variable L : LINE; 6143 variable good : BOOLEAN; 6144 begin 6145 L := new STRING'(bstring); 6146 READ (L, result, good); 6147 deallocate (L); 6148 assert (good) 6149 report fixed_generic_pkg'instance_name 6150 & "from_string: Bad string "& bstring severity error; 6151 return result; 6152 end function from_string; 6153 6154 function from_ostring ( 6155 ostring : STRING; -- Octal string 6156 constant left_index : INTEGER; 6157 constant right_index : INTEGER) 6158 return UNRESOLVED_sfixed 6159 is 6160 variable result : UNRESOLVED_sfixed (left_index downto right_index); 6161 variable L : LINE; 6162 variable good : BOOLEAN; 6163 begin 6164 L := new STRING'(ostring); 6165 OREAD (L, result, good); 6166 deallocate (L); 6167 assert (good) 6168 report fixed_generic_pkg'instance_name 6169 & "from_ostring: Bad string "& ostring severity error; 6170 return result; 6171 end function from_ostring; 6172 6173 function from_hstring ( 6174 hstring : STRING; -- hex string 6175 constant left_index : INTEGER; 6176 constant right_index : INTEGER) 6177 return UNRESOLVED_sfixed 6178 is 6179 variable result : UNRESOLVED_sfixed (left_index downto right_index); 6180 variable L : LINE; 6181 variable good : BOOLEAN; 6182 begin 6183 L := new STRING'(hstring); 6184 HREAD (L, result, good); 6185 deallocate (L); 6186 assert (good) 6187 report fixed_generic_pkg'instance_name 6188 & "from_hstring: Bad string "& hstring severity error; 6189 return result; 6190 end function from_hstring; 6191 6192 -- Same as above, "size_res" is used for it's range only. 6193 function from_string ( 6194 bstring : STRING; -- binary string 6195 size_res : UNRESOLVED_ufixed) 6196 return UNRESOLVED_ufixed is 6197 begin 6198 return from_string (bstring, size_res'high, size_res'low); 6199 end function from_string; 6200 6201 function from_ostring ( 6202 ostring : STRING; -- Octal string 6203 size_res : UNRESOLVED_ufixed) 6204 return UNRESOLVED_ufixed is 6205 begin 6206 return from_ostring (ostring, size_res'high, size_res'low); 6207 end function from_ostring; 6208 6209 function from_hstring ( 6210 hstring : STRING; -- hex string 6211 size_res : UNRESOLVED_ufixed) 6212 return UNRESOLVED_ufixed is 6213 begin 6214 return from_hstring(hstring, size_res'high, size_res'low); 6215 end function from_hstring; 6216 6217 function from_string ( 6218 bstring : STRING; -- binary string 6219 size_res : UNRESOLVED_sfixed) 6220 return UNRESOLVED_sfixed is 6221 begin 6222 return from_string (bstring, size_res'high, size_res'low); 6223 end function from_string; 6224 6225 function from_ostring ( 6226 ostring : STRING; -- Octal string 6227 size_res : UNRESOLVED_sfixed) 6228 return UNRESOLVED_sfixed is 6229 begin 6230 return from_ostring (ostring, size_res'high, size_res'low); 6231 end function from_ostring; 6232 6233 function from_hstring ( 6234 hstring : STRING; -- hex string 6235 size_res : UNRESOLVED_sfixed) 6236 return UNRESOLVED_sfixed is 6237 begin 6238 return from_hstring (hstring, size_res'high, size_res'low); 6239 end function from_hstring; 6240 6241 -- Direct conversion functions. Example: 6242 -- signal uf1 : ufixed (3 downto -3); 6243 -- uf1 <= from_string ("0110.100"); -- 6.5 6244 -- In this case the "." is not optional, and the size of 6245 -- the output must match exactly. 6246 -- purpose: Calculate the string boundaries 6247 procedure calculate_string_boundry ( 6248 arg : in STRING; -- input string 6249 left_index : out INTEGER; -- left 6250 right_index : out INTEGER) is -- right 6251 -- examples "10001.111" would return +4, -3 6252 -- "07X.44" would return +2, -2 (then the octal routine would multiply) 6253 -- "A_B_._C" would return +1, -1 (then the hex routine would multiply) 6254 alias xarg : STRING (arg'length downto 1) is arg; -- make it downto range 6255 variable l, r : INTEGER; -- internal indexes 6256 variable founddot : BOOLEAN := false; 6257 begin 6258 if arg'length > 0 then 6259 l := xarg'high - 1; 6260 r := 0; 6261 for i in xarg'range loop 6262 if xarg(i) = '_' then 6263 if r = 0 then 6264 l := l - 1; 6265 else 6266 r := r + 1; 6267 end if; 6268 elsif xarg(i) = ' ' or xarg(i) = NBSP or xarg(i) = HT then 6269 report fixed_generic_pkg'instance_name 6270 & "Found a space in the input STRING " & xarg 6271 severity error; 6272 elsif xarg(i) = '.' then 6273 if founddot then 6274 report fixed_generic_pkg'instance_name 6275 & "Found two binary points in input string " & xarg 6276 severity error; 6277 else 6278 l := l - i; 6279 r := -i + 1; 6280 founddot := true; 6281 end if; 6282 end if; 6283 end loop; 6284 left_index := l; 6285 right_index := r; 6286 else 6287 left_index := 0; 6288 right_index := 0; 6289 end if; 6290 end procedure calculate_string_boundry; 6291 6292 -- Direct conversion functions. Example: 6293 -- signal uf1 : ufixed (3 downto -3); 6294 -- uf1 <= from_string ("0110.100"); -- 6.5 6295 -- In this case the "." is not optional, and the size of 6296 -- the output must match exactly. 6297 function from_string ( 6298 bstring : STRING) -- binary string 6299 return UNRESOLVED_ufixed 6300 is 6301 variable left_index, right_index : INTEGER; 6302 begin 6303 calculate_string_boundry (bstring, left_index, right_index); 6304 return from_string (bstring, left_index, right_index); 6305 end function from_string; 6306 6307 -- Direct octal and hex conversion functions. In this case 6308 -- the string lengths must match. Example: 6309 -- signal sf1 := sfixed (5 downto -3); 6310 -- sf1 <= from_ostring ("71.4") -- -6.5 6311 function from_ostring ( 6312 ostring : STRING) -- Octal string 6313 return UNRESOLVED_ufixed 6314 is 6315 variable left_index, right_index : INTEGER; 6316 begin 6317 calculate_string_boundry (ostring, left_index, right_index); 6318 return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3); 6319 end function from_ostring; 6320 6321 function from_hstring ( 6322 hstring : STRING) -- hex string 6323 return UNRESOLVED_ufixed 6324 is 6325 variable left_index, right_index : INTEGER; 6326 begin 6327 calculate_string_boundry (hstring, left_index, right_index); 6328 return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4); 6329 end function from_hstring; 6330 6331 function from_string ( 6332 bstring : STRING) -- binary string 6333 return UNRESOLVED_sfixed 6334 is 6335 variable left_index, right_index : INTEGER; 6336 begin 6337 calculate_string_boundry (bstring, left_index, right_index); 6338 return from_string (bstring, left_index, right_index); 6339 end function from_string; 6340 6341 function from_ostring ( 6342 ostring : STRING) -- Octal string 6343 return UNRESOLVED_sfixed 6344 is 6345 variable left_index, right_index : INTEGER; 6346 begin 6347 calculate_string_boundry (ostring, left_index, right_index); 6348 return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3); 6349 end function from_ostring; 6350 6351 function from_hstring ( 6352 hstring : STRING) -- hex string 6353 return UNRESOLVED_sfixed 6354 is 6355 variable left_index, right_index : INTEGER; 6356 begin 6357 calculate_string_boundry (hstring, left_index, right_index); 6358 return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4); 6359 end function from_hstring; 6360 6361end package body fixed_generic_pkg; 6362