dlx/bv_arithmetic-body.vhdl

    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