1 -------------------------------------------------------------------------- 2 -- 3 -- Copyright (C) 1993, Peter J. Ashenden 4 -- Mail: Dept. Computer Science 5 -- University of Adelaide, SA 5005, Australia 6 -- e-mail: petera@cs.adelaide.edu.au 7 -- 8 -- This program is free software; you can redistribute it and/or modify 9 -- it under the terms of the GNU General Public License as published by 10 -- the Free Software Foundation; either version 1, or (at your option) 11 -- any later version. 12 -- 13 -- This program is distributed in the hope that it will be useful, 14 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 15 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 -- GNU General Public License for more details. 17 -- 18 -- You should have received a copy of the GNU General Public License 19 -- along with this program; if not, write to the Free Software 20 -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 -- 22 -------------------------------------------------------------------------- 23 -- 24 -- $RCSfile: bv_arithmetic-body.vhdl,v $ $Revision: 1.2 $ $Date: 2000/05/08 15:00:11 $ 25 -- 26 -------------------------------------------------------------------------- 27 -- 28 -- Bit vector arithmetic package body. 29 -- 30 -- Does arithmetic and logical operations on bit vectors, treating them 31 -- as either unsigned or signed (2's complement) integers. Leftmost bit 32 -- is most significant or sign bit, rightmost bit is least significant 33 -- bit. Dyadic operations need the two arguments to be of the same 34 -- length, however their index ranges and directions may differ. Results 35 -- must be of the same length as the operands. 36 -- 37 -------------------------------------------------------------------------- 38 39 package body bv_arithmetic is 40 41 ---------------------------------------------------------------- 42 -- Type conversions 43 ---------------------------------------------------------------- 44 45 ---------------------------------------------------------------- 46 -- bv_to_natural 47 -- 48 -- Convert bit vector encoded unsigned integer to natural. 49 ---------------------------------------------------------------- 50 51 function bv_to_natural(bv : in bit_vector) return natural is 52 53 variable result : natural := 0; 54 55 begin 56 for index in bv'range loop 57 result := result * 2 + bit'pos(bv(index)); 58 end loop; 59 return result; 60 end bv_to_natural; 61 62 63 ---------------------------------------------------------------- 64 -- natural_to_bv 65 -- 66 -- Convert natural to bit vector encoded unsigned integer. 67 -- (length is used as the size of the result.) 68 ---------------------------------------------------------------- 69 70 function natural_to_bv(nat : in natural; 71 length : in natural) return bit_vector is 72 73 variable temp : natural := nat; 74 variable result : bit_vector(0 to length-1); 75 76 begin 77 for index in result'reverse_range loop 78 result(index) := bit'val(temp rem 2); 79 temp := temp / 2; 80 end loop; 81 return result; 82 end natural_to_bv; 83 84 85 ---------------------------------------------------------------- 86 -- bv_to_integer 87 -- 88 -- Convert bit vector encoded signed integer to integer 89 ---------------------------------------------------------------- 90 91 function bv_to_integer(bv : in bit_vector) return integer is 92 93 variable temp : bit_vector(bv'range); 94 variable result : integer := 0; 95 96 begin 97 if bv(bv'left) = '1' then -- negative number 98 temp := not bv; 99 else 100 temp := bv; 101 end if; 102 for index in bv'range loop -- sign bit of temp = '0' 103 result := result * 2 + bit'pos(temp(index)); 104 end loop; 105 if bv(bv'left) = '1' then 106 result := (-result) - 1; 107 end if; 108 return result; 109 end bv_to_integer; 110 111 112 ---------------------------------------------------------------- 113 -- integer_to_bv 114 -- 115 -- Convert integer to bit vector encoded signed integer. 116 -- (length is used as the size of the result.) 117 ---------------------------------------------------------------- 118 119 function integer_to_bv(int : in integer; 120 length : in natural) return bit_vector is 121 122 variable temp : integer; 123 variable result : bit_vector(0 to length-1); 124 125 begin 126 if int < 0 then 127 temp := -(int+1); 128 else 129 temp := int; 130 end if; 131 for index in result'reverse_range loop 132 result(index) := bit'val(temp rem 2); 133 temp := temp / 2; 134 end loop; 135 if int < 0 then 136 result := not result; 137 result(result'left) := '1'; 138 end if; 139 return result; 140 end integer_to_bv; 141 142 143 ---------------------------------------------------------------- 144 -- Arithmetic operations 145 ---------------------------------------------------------------- 146 147 ---------------------------------------------------------------- 148 -- bv_add 149 -- 150 -- Signed addition with overflow detection 151 ---------------------------------------------------------------- 152 153 procedure bv_add (bv1, bv2 : in bit_vector; 154 bv_result : out bit_vector; 155 overflow : out boolean) is 156 157 alias op1 : bit_vector(1 to bv1'length) is bv1; 158 alias op2 : bit_vector(1 to bv2'length) is bv2; 159 variable result : bit_vector(1 to bv_result'length); 160 variable carry_in : bit; 161 variable carry_out : bit := '0'; 162 163 begin 164 assert bv1'length = bv2'length and bv1'length = bv_result'length 165 report "bv_add: operands of different lengths" 166 severity failure; 167 for index in result'reverse_range loop 168 carry_in := carry_out; -- of previous bit 169 result(index) := op1(index) xor op2(index) xor carry_in; 170 carry_out := (op1(index) and op2(index)) 171 or (carry_in and (op1(index) xor op2(index))); 172 end loop; 173 bv_result := result; 174 overflow := carry_out /= carry_in; 175 end bv_add; 176 177 178 ---------------------------------------------------------------- 179 -- "+" 180 -- 181 -- Signed addition without overflow detection 182 ---------------------------------------------------------------- 183 184 function "+" (bv1, bv2 : in bit_vector) return bit_vector is 185 186 alias op1 : bit_vector(1 to bv1'length) is bv1; 187 alias op2 : bit_vector(1 to bv2'length) is bv2; 188 variable result : bit_vector(1 to bv1'length); 189 variable carry_in : bit; 190 variable carry_out : bit := '0'; 191 192 begin 193 assert bv1'length = bv2'length 194 -- use concatenation to work around Synthesia MINT code gen bug 195 report '"' & '+' & '"' & ": operands of different lengths" 196 severity failure; 197 for index in result'reverse_range loop 198 carry_in := carry_out; -- of previous bit 199 result(index) := op1(index) xor op2(index) xor carry_in; 200 carry_out := (op1(index) and op2(index)) 201 or (carry_in and (op1(index) xor op2(index))); 202 end loop; 203 return result; 204 end "+"; 205 206 207 ---------------------------------------------------------------- 208 -- bv_sub 209 -- 210 -- Signed subtraction with overflow detection 211 ---------------------------------------------------------------- 212 213 procedure bv_sub (bv1, bv2 : in bit_vector; 214 bv_result : out bit_vector; 215 overflow : out boolean) is 216 217 -- subtraction implemented by adding ((not bv2) + 1), ie -bv2 218 219 alias op1 : bit_vector(1 to bv1'length) is bv1; 220 alias op2 : bit_vector(1 to bv2'length) is bv2; 221 variable result : bit_vector(1 to bv_result'length); 222 variable carry_in : bit; 223 variable carry_out : bit := '1'; 224 225 begin 226 assert bv1'length = bv2'length and bv1'length = bv_result'length 227 report "bv_sub: operands of different lengths" 228 severity failure; 229 for index in result'reverse_range loop 230 carry_in := carry_out; -- of previous bit 231 result(index) := op1(index) xor (not op2(index)) xor carry_in; 232 carry_out := (op1(index) and (not op2(index))) 233 or (carry_in and (op1(index) xor (not op2(index)))); 234 end loop; 235 bv_result := result; 236 overflow := carry_out /= carry_in; 237 end bv_sub; 238 239 240 ---------------------------------------------------------------- 241 -- "-" 242 -- 243 -- Signed subtraction without overflow detection 244 ---------------------------------------------------------------- 245 246 function "-" (bv1, bv2 : in bit_vector) return bit_vector is 247 248 -- subtraction implemented by adding ((not bv2) + 1), ie -bv2 249 250 alias op1 : bit_vector(1 to bv1'length) is bv1; 251 alias op2 : bit_vector(1 to bv2'length) is bv2; 252 variable result : bit_vector(1 to bv1'length); 253 variable carry_in : bit; 254 variable carry_out : bit := '1'; 255 256 begin 257 assert bv1'length = bv2'length 258 -- use concatenation to work around Synthesia MINT code gen bug 259 report '"' & '-' & '"' & ": operands of different lengths" 260 severity failure; 261 for index in result'reverse_range loop 262 carry_in := carry_out; -- of previous bit 263 result(index) := op1(index) xor (not op2(index)) xor carry_in; 264 carry_out := (op1(index) and (not op2(index))) 265 or (carry_in and (op1(index) xor (not op2(index)))); 266 end loop; 267 return result; 268 end "-"; 269 270 271 ---------------------------------------------------------------- 272 -- bv_addu 273 -- 274 -- Unsigned addition with overflow detection 275 ---------------------------------------------------------------- 276 277 procedure bv_addu (bv1, bv2 : in bit_vector; 278 bv_result : out bit_vector; 279 overflow : out boolean) is 280 281 alias op1 : bit_vector(1 to bv1'length) is bv1; 282 alias op2 : bit_vector(1 to bv2'length) is bv2; 283 variable result : bit_vector(1 to bv_result'length); 284 variable carry : bit := '0'; 285 286 begin 287 assert bv1'length = bv2'length and bv1'length = bv_result'length 288 report "bv_addu: operands of different lengths" 289 severity failure; 290 for index in result'reverse_range loop 291 result(index) := op1(index) xor op2(index) xor carry; 292 carry := (op1(index) and op2(index)) 293 or (carry and (op1(index) xor op2(index))); 294 end loop; 295 bv_result := result; 296 overflow := carry = '1'; 297 end bv_addu; 298 299 300 ---------------------------------------------------------------- 301 -- bv_addu 302 -- 303 -- Unsigned addition without overflow detection 304 ---------------------------------------------------------------- 305 306 procedure bv_addu (bv1, bv2 : in bit_vector; 307 bv_result : out bit_vector) is 308 309 alias op1 : bit_vector(1 to bv1'length) is bv1; 310 alias op2 : bit_vector(1 to bv2'length) is bv2; 311 variable result : bit_vector(1 to bv_result'length); 312 variable carry : bit := '0'; 313 314 begin 315 assert bv1'length = bv2'length and bv1'length = bv_result'length 316 report "bv_addu: operands of different lengths" 317 severity failure; 318 for index in result'reverse_range loop 319 result(index) := op1(index) xor op2(index) xor carry; 320 carry := (op1(index) and op2(index)) 321 or (carry and (op1(index) xor op2(index))); 322 end loop; 323 bv_result := result; 324 end bv_addu; 325 326 327 ---------------------------------------------------------------- 328 -- bv_subu 329 -- 330 -- Unsigned subtraction with overflow detection 331 ---------------------------------------------------------------- 332 333 procedure bv_subu (bv1, bv2 : in bit_vector; 334 bv_result : out bit_vector; 335 overflow : out boolean) is 336 337 alias op1 : bit_vector(1 to bv1'length) is bv1; 338 alias op2 : bit_vector(1 to bv2'length) is bv2; 339 variable result : bit_vector(1 to bv_result'length); 340 variable borrow : bit := '0'; 341 342 begin 343 assert bv1'length = bv2'length and bv1'length = bv_result'length 344 report "bv_subu: operands of different lengths" 345 severity failure; 346 for index in result'reverse_range loop 347 result(index) := op1(index) xor op2(index) xor borrow; 348 borrow := (not op1(index) and op2(index)) 349 or (borrow and not (op1(index) xor op2(index))); 350 end loop; 351 bv_result := result; 352 overflow := borrow = '1'; 353 end bv_subu; 354 355 356 ---------------------------------------------------------------- 357 -- bv_subu 358 -- 359 -- Unsigned subtraction without overflow detection 360 ---------------------------------------------------------------- 361 362 procedure bv_subu (bv1, bv2 : in bit_vector; 363 bv_result : out bit_vector) is 364 365 alias op1 : bit_vector(1 to bv1'length) is bv1; 366 alias op2 : bit_vector(1 to bv2'length) is bv2; 367 variable result : bit_vector(1 to bv_result'length); 368 variable borrow : bit := '0'; 369 370 begin 371 assert bv1'length = bv2'length and bv1'length = bv_result'length 372 report "bv_subu: operands of different lengths" 373 severity failure; 374 for index in result'reverse_range loop 375 result(index) := op1(index) xor op2(index) xor borrow; 376 borrow := (not op1(index) and op2(index)) 377 or (borrow and not (op1(index) xor op2(index))); 378 end loop; 379 bv_result := result; 380 end bv_subu; 381 382 383 ---------------------------------------------------------------- 384 -- bv_neg 385 -- 386 -- Signed negation with overflow detection 387 ---------------------------------------------------------------- 388 389 procedure bv_neg (bv : in bit_vector; 390 bv_result : out bit_vector; 391 overflow : out boolean) is 392 393 CONSTANT zero : bit_vector(bv'range) := (others => '0'); 394 395 begin 396 bv_sub( zero, bv, bv_result, overflow ); 397 end bv_neg; 398 399 400 ---------------------------------------------------------------- 401 -- "-" 402 -- 403 -- Signed negation without overflow detection 404 ---------------------------------------------------------------- 405 406 function "-" (bv : in bit_vector) return bit_vector is 407 408 CONSTANT zero : bit_vector(bv'range) := (others => '0'); 409 410 begin 411 return zero - bv; 412 end "-"; 413 414 415 ---------------------------------------------------------------- 416 -- bv_mult 417 -- 418 -- Signed multiplication with overflow detection 419 ---------------------------------------------------------------- 420 421 procedure bv_mult (bv1, bv2 : in bit_vector; 422 bv_result : out bit_vector; 423 overflow : out boolean) is 424 425 variable negative_result : boolean; 426 variable op1 : bit_vector(bv1'range) := bv1; 427 variable op2 : bit_vector(bv2'range) := bv2; 428 variable multu_result : bit_vector(bv1'range); 429 variable multu_overflow : boolean; 430 -- constant abs_min_int : bit_vector(bv1'range) 431 -- := (bv1'left => '1', others => '0'); 432 -- causes Synthesia MINT code generator to prang. Work around: 433 variable abs_min_int : bit_vector(bv1'range) := (others => '0'); 434 435 begin 436 assert bv1'length = bv2'length and bv1'length = bv_result'length 437 report "bv_mult: operands of different lengths" 438 severity failure; 439 abs_min_int(bv1'left) := '1'; -- Synthesia work around 440 negative_result := (op1(op1'left) = '1') xor (op2(op2'left) = '1'); 441 if (op1(op1'left) = '1') then 442 op1 := - bv1; 443 end if; 444 if (op2(op2'left) = '1') then 445 op2 := - bv2; 446 end if; 447 bv_multu(op1, op2, multu_result, multu_overflow); 448 if (negative_result) then 449 overflow := multu_overflow or (multu_result > abs_min_int); 450 bv_result := - multu_result; 451 else 452 overflow := multu_overflow or (multu_result(multu_result'left) = '1'); 453 bv_result := multu_result; 454 end if; 455 end bv_mult; 456 457 458 ---------------------------------------------------------------- 459 -- "*" 460 -- 461 -- Signed multiplication without overflow detection 462 ---------------------------------------------------------------- 463 464 function "*" (bv1, bv2 : in bit_vector) return bit_vector is 465 466 variable negative_result : boolean; 467 variable op1 : bit_vector(bv1'range) := bv1; 468 variable op2 : bit_vector(bv2'range) := bv2; 469 variable result : bit_vector(bv1'range); 470 471 begin 472 assert bv1'length = bv2'length 473 -- use concatenation to work around Synthesia MINT code gen bug 474 report '"' & '*' & '"' & ": operands of different lengths" 475 severity failure; 476 negative_result := (op1(op1'left) = '1') xor (op2(op2'left) = '1'); 477 if (op1(op1'left) = '1') then 478 op1 := - bv1; 479 end if; 480 if (op2(op2'left) = '1') then 481 op2 := - bv2; 482 end if; 483 bv_multu(op1, op2, result); 484 if (negative_result) then 485 result := - result; 486 end if; 487 return result; 488 end "*"; 489 490 491 ---------------------------------------------------------------- 492 -- bv_multu 493 -- 494 -- Unsigned multiplication with overflow detection 495 ---------------------------------------------------------------- 496 497 procedure bv_multu (bv1, bv2 : in bit_vector; 498 bv_result : out bit_vector; 499 overflow : out boolean) is 500 501 -- Based on shift&add multiplier in Appendix A of Hennessy & Patterson 502 503 constant bv_length : natural := bv1'length; 504 constant accum_length : natural := bv_length * 2; 505 constant zero : bit_vector(accum_length-1 downto bv_length) 506 := (others => '0'); 507 variable accum : bit_vector(accum_length-1 downto 0); 508 variable addu_overflow : boolean; 509 variable carry : bit; 510 511 begin 512 assert bv1'length = bv2'length and bv1'length = bv_result'length 513 report "bv_multu: operands of different lengths" 514 severity failure; 515 accum(bv_length-1 downto 0) := bv1; 516 accum(accum_length-1 downto bv_length) := zero; 517 for count in 1 to bv_length loop 518 if (accum(0) = '1') then 519 bv_addu( accum(accum_length-1 downto bv_length), bv2, 520 accum(accum_length-1 downto bv_length), addu_overflow); 521 carry := bit'val(boolean'pos(addu_overflow)); 522 else 523 carry := '0'; 524 end if; 525 accum := carry & accum(accum_length-1 downto 1); 526 end loop; 527 bv_result := accum(bv_length-1 downto 0); 528 overflow := accum(accum_length-1 downto bv_length) /= zero; 529 end bv_multu; 530 531 532 ---------------------------------------------------------------- 533 -- bv_multu 534 -- 535 -- Unsigned multiplication without overflow detection 536 ---------------------------------------------------------------- 537 538 procedure bv_multu (bv1, bv2 : in bit_vector; 539 bv_result : out bit_vector) is 540 541 -- Use bv_multu with overflow detection, but ignore overflow flag 542 543 variable tmp_overflow : boolean; 544 545 begin 546 -- following procedure asserts bv1'length = bv2'length 547 bv_multu(bv1, bv2, bv_result, tmp_overflow); 548 end bv_multu; 549 550 551 ---------------------------------------------------------------- 552 -- bv_div 553 -- 554 -- Signed division with divide by zero and overflow detection 555 ---------------------------------------------------------------- 556 557 procedure bv_div (bv1, bv2 : in bit_vector; 558 bv_result : out bit_vector; 559 div_by_zero : out boolean; 560 overflow : out boolean) is 561 562 -- Need overflow, in case divide b"10...0" (min_int) by -1 563 -- Don't use bv_to_int, in case size bigger than host machine! 564 565 variable negative_result : boolean; 566 variable op1 : bit_vector(bv1'range) := bv1; 567 variable op2 : bit_vector(bv2'range) := bv2; 568 variable divu_result : bit_vector(bv1'range); 569 570 begin 571 assert bv1'length = bv2'length 572 report "bv_div: operands of different lengths" 573 severity failure; 574 negative_result := (op1(op1'left) = '1') xor (op2(op2'left) = '1'); 575 if (op1(op1'left) = '1') then 576 op1 := - bv1; 577 end if; 578 if (op2(op2'left) = '1') then 579 op2 := - bv2; 580 end if; 581 bv_divu(op1, op2, divu_result, div_by_zero); 582 if (negative_result) then 583 overflow := false; 584 bv_result := - divu_result; 585 else 586 overflow := divu_result(divu_result'left) = '1'; 587 bv_result := divu_result; 588 end if; 589 end bv_div; 590 591 592 ---------------------------------------------------------------- 593 -- "/" 594 -- 595 -- Signed division without divide by zero and overflow detection 596 ---------------------------------------------------------------- 597 598 function "/" (bv1, bv2 : in bit_vector) return bit_vector is 599 600 variable negative_result : boolean; 601 variable op1 : bit_vector(bv1'range) := bv1; 602 variable op2 : bit_vector(bv2'range) := bv2; 603 variable result : bit_vector(bv1'range); 604 605 begin 606 assert bv1'length = bv2'length 607 -- use concatenation to work around Synthesia MINT code gen bug 608 report '"' & '/' & '"' & ": operands of different lengths" 609 severity failure; 610 negative_result := (op1(op1'left) = '1') xor (op2(op2'left) = '1'); 611 if (op1(op1'left) = '1') then 612 op1 := - bv1; 613 end if; 614 if (op2(op2'left) = '1') then 615 op2 := - bv2; 616 end if; 617 bv_divu(op1, op2, result); 618 if (negative_result) then 619 result := - result; 620 end if; 621 return result; 622 end "/"; 623 624 625 ---------------------------------------------------------------- 626 -- bv_divu 627 -- 628 -- Unsigned division with divide by zero detection 629 ---------------------------------------------------------------- 630 631 procedure bv_divu (bv1, bv2 : in bit_vector; 632 bv_result : out bit_vector; 633 div_by_zero : out boolean) is 634 635 -- based on algorithm in Sun Sparc architecture manual 636 637 constant len : natural := bv1'length; 638 variable zero, one, 639 big_value : bit_vector(len-1 downto 0) 640 := (others => '0'); 641 variable dividend : bit_vector(bv1'length-1 downto 0) := bv1; 642 variable divisor : bit_vector(bv2'length-1 downto 0) := bv2; 643 variable quotient : bit_vector(len-1 downto 0); -- unsigned 644 variable remainder : bit_vector(len-1 downto 0); -- signed 645 variable shifted_divisor, 646 shifted_1 : bit_vector(len-1 downto 0); 647 variable log_quotient : natural; 648 variable ignore_overflow : boolean; 649 650 begin 651 assert bv1'length = bv2'length 652 report "bv_divu: operands of different lengths" 653 severity failure; 654 one(0) := '1'; 655 big_value(len-2) := '1'; 656 -- 657 -- check for zero divisor 658 -- 659 if (divisor = zero) then 660 div_by_zero := true; 661 return; 662 else 663 div_by_zero := false; 664 end if; 665 -- 666 -- estimate log of quotient 667 -- 668 log_quotient := 0; 669 shifted_divisor := divisor; 670 loop 671 exit when (log_quotient >= len) 672 or (shifted_divisor > big_value) 673 or (shifted_divisor >= dividend); 674 log_quotient := log_quotient + 1; 675 shifted_divisor := bv_sll(shifted_divisor, 1); 676 end loop; 677 -- 678 -- perform division 679 -- 680 remainder := dividend; 681 quotient := zero; 682 shifted_divisor := bv_sll(divisor, log_quotient); 683 shifted_1 := bv_sll(one, log_quotient); 684 for iter in log_quotient downto 0 loop 685 if bv_ge(remainder, zero) then 686 bv_sub(remainder, shifted_divisor, remainder, ignore_overflow); 687 bv_addu(quotient, shifted_1, quotient, ignore_overflow); 688 else 689 bv_add(remainder, shifted_divisor, remainder, ignore_overflow); 690 bv_subu(quotient, shifted_1, quotient, ignore_overflow); 691 end if; 692 shifted_divisor := '0' & shifted_divisor(len-1 downto 1); 693 shifted_1 := '0' & shifted_1(len-1 downto 1); 694 end loop; 695 if (bv_lt(remainder, zero)) then 696 bv_add(remainder, divisor, remainder, ignore_overflow); 697 bv_subu(quotient, one, quotient, ignore_overflow); 698 end if; 699 bv_result := quotient; 700 end bv_divu; 701 702 703 ---------------------------------------------------------------- 704 -- bv_divu 705 -- 706 -- Unsigned division without divide by zero detection 707 ---------------------------------------------------------------- 708 709 procedure bv_divu (bv1, bv2 : in bit_vector; 710 bv_result : out bit_vector) is 711 712 -- Use bv_divu with divide by zero detection, 713 -- but ignore div_by_zero flag 714 715 variable tmp_div_by_zero : boolean; 716 717 begin 718 -- following procedure asserts bv1'length = bv2'length 719 bv_divu(bv1, bv2, bv_result, tmp_div_by_zero); 720 end bv_divu; 721 722 723 ---------------------------------------------------------------- 724 -- Logical operators 725 -- (Provided for VHDL-87, built in for VHDL-93) 726 ---------------------------------------------------------------- 727 728 ---------------------------------------------------------------- 729 -- bv_sll 730 -- 731 -- Shift left logical (fill with '0' bits) 732 ---------------------------------------------------------------- 733 734 function bv_sll (bv : in bit_vector; 735 shift_count : in natural) return bit_vector is 736 737 constant bv_length : natural := bv'length; 738 constant actual_shift_count : natural := shift_count mod bv_length; 739 alias bv_norm : bit_vector(1 to bv_length) is bv; 740 variable result : bit_vector(1 to bv_length) := (others => '0'); 741 742 begin 743 result(1 to bv_length - actual_shift_count) 744 := bv_norm(actual_shift_count + 1 to bv_length); 745 return result; 746 end bv_sll; 747 748 749 ---------------------------------------------------------------- 750 -- bv_srl 751 -- 752 -- Shift right logical (fill with '0' bits) 753 ---------------------------------------------------------------- 754 755 function bv_srl (bv : in bit_vector; 756 shift_count : in natural) return bit_vector is 757 758 constant bv_length : natural := bv'length; 759 constant actual_shift_count : natural := shift_count mod bv_length; 760 alias bv_norm : bit_vector(1 to bv_length) is bv; 761 variable result : bit_vector(1 to bv_length) := (others => '0'); 762 763 begin 764 result(actual_shift_count + 1 to bv_length) 765 := bv_norm(1 to bv_length - actual_shift_count); 766 return result; 767 end bv_srl; 768 769 770 ---------------------------------------------------------------- 771 -- bv_sra 772 -- 773 -- Shift right arithmetic (fill with copy of sign bit) 774 ---------------------------------------------------------------- 775 776 777 function bv_sra (bv : in bit_vector; 778 shift_count : in natural) return bit_vector is 779 780 constant bv_length : natural := bv'length; 781 constant actual_shift_count : natural := shift_count mod bv_length; 782 alias bv_norm : bit_vector(1 to bv_length) is bv; 783 variable result : bit_vector(1 to bv_length) := (others => bv(bv'left)); 784 785 begin 786 result(actual_shift_count + 1 to bv_length) 787 := bv_norm(1 to bv_length - actual_shift_count); 788 return result; 789 end bv_sra; 790 791 792 ---------------------------------------------------------------- 793 -- bv_rol 794 -- 795 -- Rotate left 796 ---------------------------------------------------------------- 797 798 function bv_rol (bv : in bit_vector; 799 rotate_count : in natural) return bit_vector is 800 801 constant bv_length : natural := bv'length; 802 constant actual_rotate_count : natural := rotate_count mod bv_length; 803 alias bv_norm : bit_vector(1 to bv_length) is bv; 804 variable result : bit_vector(1 to bv_length); 805 806 begin 807 result(1 to bv_length - actual_rotate_count) 808 := bv_norm(actual_rotate_count + 1 to bv_length); 809 result(bv_length - actual_rotate_count + 1 to bv_length) 810 := bv_norm(1 to actual_rotate_count); 811 return result; 812 end bv_rol; 813 814 815 ---------------------------------------------------------------- 816 -- bv_ror 817 -- 818 -- Rotate right 819 ---------------------------------------------------------------- 820 821 function bv_ror (bv : in bit_vector; 822 rotate_count : in natural) return bit_vector is 823 824 constant bv_length : natural := bv'length; 825 constant actual_rotate_count : natural := rotate_count mod bv_length; 826 alias bv_norm : bit_vector(1 to bv_length) is bv; 827 variable result : bit_vector(1 to bv_length); 828 829 begin 830 result(actual_rotate_count + 1 to bv_length) 831 := bv_norm(1 to bv_length - actual_rotate_count); 832 result(1 to actual_rotate_count) 833 := bv_norm(bv_length - actual_rotate_count + 1 to bv_length); 834 return result; 835 end bv_ror; 836 837 838 ---------------------------------------------------------------- 839 -- Arithmetic comparison operators. 840 -- Perform comparisons on bit vector encoded signed integers. 841 -- (For unsigned integers, built in lexical comparison does 842 -- the required operation.) 843 ---------------------------------------------------------------- 844 845 ---------------------------------------------------------------- 846 -- bv_lt 847 -- 848 -- Signed less than comparison 849 ---------------------------------------------------------------- 850 851 function bv_lt (bv1, bv2 : in bit_vector) return boolean is 852 853 variable tmp1 : bit_vector(bv1'range) := bv1; 854 variable tmp2 : bit_vector(bv2'range) := bv2; 855 856 begin 857 assert bv1'length = bv2'length 858 report "bv_lt: operands of different lengths" 859 severity failure; 860 tmp1(tmp1'left) := not tmp1(tmp1'left); 861 tmp2(tmp2'left) := not tmp2(tmp2'left); 862 return tmp1 < tmp2; 863 end bv_lt; 864 865 866 ---------------------------------------------------------------- 867 -- bv_le 868 -- 869 -- Signed less than or equal comparison 870 ---------------------------------------------------------------- 871 872 function bv_le (bv1, bv2 : in bit_vector) return boolean is 873 874 variable tmp1 : bit_vector(bv1'range) := bv1; 875 variable tmp2 : bit_vector(bv2'range) := bv2; 876 877 begin 878 assert bv1'length = bv2'length 879 report "bv_le: operands of different lengths" 880 severity failure; 881 tmp1(tmp1'left) := not tmp1(tmp1'left); 882 tmp2(tmp2'left) := not tmp2(tmp2'left); 883 return tmp1 <= tmp2; 884 end bv_le; 885 886 887 ---------------------------------------------------------------- 888 -- bv_gt 889 -- 890 -- Signed greater than comparison 891 ---------------------------------------------------------------- 892 893 function bv_gt (bv1, bv2 : in bit_vector) return boolean is 894 895 variable tmp1 : bit_vector(bv1'range) := bv1; 896 variable tmp2 : bit_vector(bv2'range) := bv2; 897 898 begin 899 assert bv1'length = bv2'length 900 report "bv_gt: operands of different lengths" 901 severity failure; 902 tmp1(tmp1'left) := not tmp1(tmp1'left); 903 tmp2(tmp2'left) := not tmp2(tmp2'left); 904 return tmp1 > tmp2; 905 end bv_gt; 906 907 908 ---------------------------------------------------------------- 909 -- bv_ge 910 -- 911 -- Signed greater than or equal comparison 912 ---------------------------------------------------------------- 913 914 function bv_ge (bv1, bv2 : in bit_vector) return boolean is 915 916 variable tmp1 : bit_vector(bv1'range) := bv1; 917 variable tmp2 : bit_vector(bv2'range) := bv2; 918 919 begin 920 assert bv1'length = bv2'length 921 report "bv_ged: operands of different lengths" 922 severity failure; 923 tmp1(tmp1'left) := not tmp1(tmp1'left); 924 tmp2(tmp2'left) := not tmp2(tmp2'left); 925 return tmp1 >= tmp2; 926 end bv_ge; 927 928 929 ---------------------------------------------------------------- 930 -- Extension operators - convert a bit vector to a longer one 931 ---------------------------------------------------------------- 932 933 ---------------------------------------------------------------- 934 -- bv_sext 935 -- 936 -- Sign extension - replicate the sign bit of the operand into 937 -- the most significant bits of the result. Length parameter 938 -- determines size of result. If length < bv'length, result is 939 -- rightmost length bits of bv. 940 ---------------------------------------------------------------- 941 942 function bv_sext (bv : in bit_vector; 943 length : in natural) return bit_vector is 944 945 alias bv_norm : bit_vector(1 to bv'length) is bv; 946 variable result : bit_vector(1 to length) := (others => bv(bv'left)); 947 variable src_length : natural := bv'length; 948 949 begin 950 if src_length > length then 951 src_length := length; 952 end if; 953 result(length - src_length + 1 to length) 954 := bv_norm(bv'length - src_length + 1 to bv'length); 955 return result; 956 end bv_sext; 957 958 959 ---------------------------------------------------------------- 960 -- bv_zext 961 -- 962 -- Zero extension - replicate zero bits into the most significant 963 -- bits of the result. Length parameter determines size of result. 964 -- If length < bv'length, result is rightmost length bits of bv. 965 ---------------------------------------------------------------- 966 967 function bv_zext (bv : in bit_vector; 968 length : in natural) return bit_vector is 969 970 alias bv_norm : bit_vector(1 to bv'length) is bv; 971 variable result : bit_vector(1 to length) := (others => '0'); 972 variable src_length : natural := bv'length; 973 974 begin 975 if src_length > length then 976 src_length := length; 977 end if; 978 result(length - src_length + 1 to length) 979 := bv_norm(bv'length - src_length + 1 to bv'length); 980 return result; 981 end bv_zext; 982 983 984 end bv_arithmetic; 985
This page was generated using GHDL 0.14 (20040829) [Sokcho edition], a program written by Tristan Gingold