⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wbm.vhd

📁 用walsh算法实现的符号数乘法器,asic流片时,可以不用公司的付费乘法器的ip core.
💻 VHD
字号:
  

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_signed.all;

 	
--------------------------------------------------------------- 

ENTITY wbm IS

   GENERIC (n : INTEGER :=12 ;  m : INTEGER :=11);  
     
   PORT( Input_x  : IN   STD_LOGIC_VECTOR (n-1   DOWNTO 0);
         Input_y  : IN   STD_LOGIC_VECTOR (m-1   DOWNTO 0);
         Result   : OUT  STD_LOGIC_VECTOR (m+n-1 DOWNTO 0)); 

END wbm;

--------------------------------------------------------------- 


ARCHITECTURE Behavioural OF wbm IS
 
TYPE  matrix IS ARRAY (n/2 DOWNTO 0) OF STD_LOGIC_VECTOR (m+n-1 DOWNTO 0);


PROCEDURE Generate_PP_Booth (x  : IN    STD_LOGIC_VECTOR (n-1 DOWNTO 0);
                             y  : IN    STD_LOGIC_VECTOR (m-1 DOWNTO 0); 
                             PP : INOUT matrix )  IS
 
   FUNCTION Adder_cla ( input1, input2  : STD_LOGIC_VECTOR (m-1 DOWNTO 0);
                        carry_in        : STD_LOGIC )
   RETURN STD_LOGIC_VECTOR  IS 
                   
      VARIABLE carry      : STD_LOGIC;
      VARIABLE generat    : STD_LOGIC_VECTOR (m-1 DOWNTO 0) ;
      VARIABLE propagate  : STD_LOGIC_VECTOR (m-1 DOWNTO 0) ;
      VARIABLE sum        : STD_LOGIC_VECTOR (m-1 DOWNTO 0) ;
 
   BEGIN
      carry := carry_in;
      FOR i IN 0 TO (m-1) LOOP
         generat (i)   := input1(i) AND input2(i);
         propagate(i)  := input1(i) XOR input2(i);
         sum (i)       := propagate(i) XOR carry;
         carry := generat(i) OR (propagate(i) AND carry);
      END LOOP;
      RETURN sum ;
   END; 

                ---------------------------------

   VARIABLE  i, j, k       : INTEGER;
   VARIABLE  nb_pp         : INTEGER;  
   VARIABLE  Intermediate  : STD_LOGIC_VECTOR (m-1 DOWNTO 0);
   VARIABLE  Null_Vector   : STD_LOGIC_VECTOR (m-1 DOWNTO 0);
   VARIABLE  x_coded       : STD_LOGIC_VECTOR (n+1 DOWNTO 0);
   VARIABLE  Selector      : STD_LOGIC_VECTOR (3   DOWNTO 1);

BEGIN
                
   FOR i IN 0 TO (n-1) LOOP x_coded(i+1) := x(i);  END LOOP;

   IF (n rem 2 = 0) THEN           
      nb_pp := n/2;                
   ELSE 
      nb_pp := n/2 +1;
      x_coded(n+1) := x_coded(n);  
   END IF;

   x_coded(0):='0';                
            
   FOR i IN 0 TO (m-1) LOOP Null_Vector(i) := '0';  END LOOP;

   j := 0;                         
   FOR i IN 0 TO (nb_pp-1) LOOP

      selector := x_coded(j+2) & x_coded(j+1) & x_coded(j);

      CASE Selector IS
 
         
         WHEN "000" => FOR k IN 0 TO (m+n-1) LOOP 
                          PP(i)(k) :='0'; 
                       END LOOP;


         
         WHEN "001" => FOR k IN 0 TO (m-1) LOOP 
                          PP(i)(k) := y(k);        
                       END LOOP;

                       FOR k IN m TO (m+n-1) LOOP 
                          PP(i)(k) := PP(i)(m-1);  
                       END LOOP;


         
         WHEN "010" => FOR k IN 0 TO (m-1) LOOP 
                          PP(i)(k) := y(k);        
                       END LOOP;

                       FOR k IN m TO (m+n-1) LOOP 
                          PP(i)(k) := PP(i)(m-1);   
                       END LOOP;


         
         WHEN "011" => PP(i)(0) := '0';
                       FOR k IN 0 TO (m-1) LOOP     
                          PP(i)(k+1) := y(k);       
                       END LOOP;

                       FOR k IN m+1 TO (m+n-1) LOOP 
                          PP(i)(k) := PP(i)(m);      
                       END LOOP;


               
         WHEN "100" => FOR k IN 0 TO (m-1) LOOP  
                          Intermediate(k) := y(k) XOR '1'; 
                       END LOOP;

                       Intermediate := Adder_cla (Intermediate, Null_Vector, '1');

                       PP(i)(0) := '0';
                       FOR k IN 0 TO (m-1) LOOP          
                          PP(i)(k+1) := Intermediate(k); 
                       END LOOP; 

                       FOR k IN m+1 TO (m+n-1) LOOP 
                          PP(i)(k) := PP(i)(m);          
                       END LOOP;


         
         WHEN "101" => FOR k IN 0 TO (m-1) LOOP  
                          Intermediate(k) := y(k) XOR '1'; 
                       END LOOP;

                       -- add 1 to the previous result to obtain the 2's compl.
                       Intermediate := Adder_cla (Intermediate, Null_Vector,'1');

                       FOR k IN 0 TO (m-1) LOOP 
                          PP(i)(k) := Intermediate(k);     
                       END LOOP; 

                       FOR k IN m TO (m+n-1) LOOP 
                          PP(i)(k) := PP(i)(m-1);             
                       END LOOP;


         
         WHEN "110" => FOR k IN 0 TO (m-1) LOOP  
                          Intermediate(k) := y(k) XOR '1';   
                       END LOOP;

                       -- add 1 to the previous result to obtain the 2's compl.
                       Intermediate := Adder_cla (Intermediate, Null_Vector,'1');

                       FOR k IN 0 TO (m-1) LOOP 
                          PP(i)(k) := Intermediate(k);     
                       END LOOP; 

                       FOR k IN m TO (m+n-1) LOOP 
                          PP(i)(k) := PP(i)(m-1);         
                       END LOOP;


         
         WHEN "111" => FOR k IN 0 TO (m+n-1) LOOP 
                          PP(i)(k) :='0'; 
                       END LOOP;


         WHEN OTHERS => NULL;


      END CASE;

      j:=j+2;
   END LOOP;
                                  
END;



PROCEDURE Shiftleft_PP ( p      : IN     INTEGER ;  
                         Vector : INOUT  STD_LOGIC_VECTOR (m+n-1 DOWNTO 0)) IS
   VARIABLE i : INTEGER;
   VARIABLE T : STD_LOGIC_VECTOR (m+n-1 DOWNTO 0);

BEGIN
 
   FOR i IN 0 TO (m+n-1)    LOOP  T(i)      := '0';        END LOOP;   
   FOR i IN 0 TO (m+n-1-p)  LOOP  T(i+p)    := Vector(i);  END LOOP;
   FOR i IN 0 TO (m+n-1)    LOOP  Vector(i) := T(i);       END LOOP;

END;


         
PROCEDURE Wallace_Tree ( PP, Sum, Carry : INOUT matrix)  IS
 



   PROCEDURE Bits_Full_Adder ( a, b, c    : IN  STD_LOGIC;
                               Sum, Carry : OUT STD_LOGIC ) IS
   BEGIN
      Sum   :=  a XOR b XOR c ;
      Carry :=  (a AND b) OR (a AND c) OR (b AND c) ;  	
   END;




   PROCEDURE Vectors_Full_Adder ( a, b, c : IN  STD_LOGIC_VECTOR (m+n-1 DOWNTO 0);
                                  Sum     : OUT STD_LOGIC_VECTOR (m+n-1 DOWNTO 0);
                                  Carry   : OUT STD_LOGIC_VECTOR (m+n-1 DOWNTO 0)) IS
   
   BEGIN
      FOR i IN 2 TO (m+n-1) LOOP  
         Bits_Full_Adder (a(i), b(i), c(i), sum(i), carry(i));
      END LOOP;
   END;		




TYPE Int_Vect IS ARRAY (n-1 DOWNTO 0) OF INTEGER;

VARIABLE nb_level               : INTEGER;  
VARIABLE num_level              : INTEGER;  
VARIABLE num_col                : INTEGER;  
VARIABLE nb_Vectors_Full_Adder  : Int_Vect;  
VARIABLE num_Vectors_Full_Adder : Int_Vect;  
VARIABLE nb_output              : Int_Vect; 
VARIABLE vect                   : STD_LOGIC_VECTOR (m+n-1 DOWNTO 0);
VARIABLE nb_PP                  : INTEGER ; 


BEGIN

   IF (n rem 2 = 0) THEN          
      nb_PP := n/2;                    
   ELSE                           
      nb_PP := n/2 +1;            
   END IF;                        


   IF    nb_PP = 3   THEN nb_level := 1;     
   ELSIF nb_PP = 4   THEN nb_level := 2;     
   ELSIF nb_PP <=6   THEN nb_level := 3;     
   ELSIF nb_PP <=9   THEN nb_level := 4;     
   ELSIF nb_PP <=13  THEN nb_level := 5;     
   ELSIF nb_PP <=19  THEN nb_level := 6;
   ELSIF nb_PP <=28  THEN nb_level := 7;     
   ELSIF nb_PP <=42  THEN nb_level := 8;
   ELSIF nb_PP <=63  THEN nb_level := 9;
   ELSE  NULL;                        
   END IF;           

                             
   FOR num_level IN 1 TO nb_level LOOP
       
      nb_Vectors_Full_Adder (num_level) := nb_PP / 3 ;

      nb_output (num_level) := (nb_PP rem 3) + 2*nb_Vectors_Full_Adder (num_level);


     num_col := 0 ;
      FOR num_Vectors_Full_Adder IN 1 TO nb_Vectors_Full_Adder(num_level) LOOP
         Vectors_Full_Adder ( PP(num_col), PP(num_col+1), PP(num_col+2),
                              Sum(num_Vectors_Full_Adder), Carry(num_Vectors_Full_Adder));
         num_col := num_col + 3 ;    
      END LOOP;                    

       
     FOR num_Vectors_Full_Adder IN 1 TO nb_Vectors_Full_Adder(num_level) LOOP      
         FOR i IN 0 TO (m+n-2) LOOP                 
            vect(i+1) := Carry(num_Vectors_Full_Adder)(i);          
         END LOOP;                                            
         carry (num_Vectors_Full_Adder)    := vect;          
         carry (num_Vectors_Full_Adder)(0) := '0' ;        
      END LOOP;


      num_col:=0 ;
      FOR num_Vectors_Full_Adder IN 1 TO nb_Vectors_Full_Adder(num_level) LOOP             
         PP (num_col)   :=  Sum   (num_Vectors_Full_Adder) ;
         PP (num_col+1) :=  Carry (num_Vectors_Full_Adder) ;
         num_col        :=  num_col + 2 ;
      END LOOP;


      CASE (nb_PP rem 3) IS   
         WHEN  2      =>  PP(num_col)   := PP(nb_PP-2) ;
                          PP(num_col+1) := PP(nb_PP-1) ;
         WHEN  1      =>  PP(num_col)   := PP(nb_PP-1) ;
         WHEN OTHERS  =>  NULL ;  
      END CASE;

      nb_PP := nb_output(num_level) ;
            
   END LOOP;
  	   

END; 

   PROCEDURE Addition_cla ( input1, input2 : IN  STD_LOGIC_VECTOR (m+n-1 DOWNTO 2);
                            output         : OUT STD_LOGIC_VECTOR (m+n-1 DOWNTO 2)) IS 
                   
      VARIABLE carry      : STD_LOGIC;
      VARIABLE generat    : STD_LOGIC_VECTOR (m+n-1 DOWNTO 2) ;
      VARIABLE propagate  : STD_LOGIC_VECTOR (m+n-1 DOWNTO 2) ;
      VARIABLE sum        : STD_LOGIC_VECTOR (m+n-1 DOWNTO 2) ;
 
   BEGIN
      carry := '0';
      FOR i IN 2 TO (m+n-1) LOOP
         generat(i)    := input1(i) AND input2(i);
         propagate(i)  := input1(i) XOR input2(i);
         sum (i)       := propagate(i) XOR carry;
         carry := generat(i) OR (propagate(i) AND carry);
      END LOOP;
      output := sum ;
   END; 



BEGIN

   Multiplication : PROCESS ( Input_x, Input_y )

      VARIABLE  x                         :  STD_LOGIC_VECTOR (n-1   DOWNTO 0) ;
      VARIABLE  y                         :  STD_LOGIC_VECTOR (m-1   DOWNTO 0) ;
      VARIABLE  Reduced_PP_1              :  STD_LOGIC_VECTOR (m+n-1 DOWNTO 2) ;
      VARIABLE  Reduced_PP_2              :  STD_LOGIC_VECTOR (m+n-1 DOWNTO 2) ;
      VARIABLE  Reduced_Final_Sum         :  STD_LOGIC_VECTOR (m+n-1 DOWNTO 2) ;
      VARIABLE  Reduced_Output_Wallace_1  :  STD_LOGIC_VECTOR (m+n-1 DOWNTO 2) ;
      VARIABLE  Reduced_Output_Wallace_2  :  STD_LOGIC_VECTOR (m+n-1 DOWNTO 2) ;
      VARIABLE  PP                        :  matrix ;
      VARIABLE  Sum, Carry                :  matrix ;
      VARIABLE  LSB0, LSB1                :  STD_LOGIC ;
      VARIABLE  nb_PP                     :  INTEGER ;


   BEGIN

      x := Input_x ; 
      y := Input_y ; 

      IF n=1 THEN   

         FOR i IN 0 to (m-1) LOOP 
            Result(i) <= x(0) AND y(i); 
         END LOOP;
         FOR i IN m to (m+n-1) LOOP 
            Result(i) <= x(0) AND y(m-1);     
         END LOOP;

      ELSE
          
         Generate_PP_Booth (x, y, PP);

         IF n=2 THEN              
                                   
            Result <= PP(0); 
   
         ELSE

            IF n rem 2 = 0 THEN nb_PP := n/2;      
            ELSE nb_PP := n/2 +1;                
            END IF;
        
            FOR i IN 0 TO (nb_PP-1) LOOP       
               Shiftleft_PP (2*i, PP(i));      
            END LOOP;                
  
            LSB0 := PP(0)(0);   
            LSB1 := PP(0)(1);   

            IF n<=4 THEN   
                           

               FOR i IN 2 to (m+n-1) LOOP         
                  Reduced_PP_1 (i) := PP(0)(i);   
               END LOOP;                          
               FOR i IN 2 to (m+n-1) LOOP         
                  Reduced_PP_2 (i) := PP(1)(i);  
               END LOOP;
               Addition_cla (Reduced_PP_1, Reduced_PP_2,Reduced_Final_Sum);

            ELSE 

               Wallace_tree (PP, Sum, Carry);

               FOR i IN 2 to (m+n-1) LOOP 
                  Reduced_Output_Wallace_1 (i) := Sum(1)(i);  
               END LOOP;
               FOR i IN 2 to (m+n-1) LOOP 
                  Reduced_Output_Wallace_2 (i) := Carry (1)(i);  
               END LOOP;
               Addition_cla (Reduced_output_wallace_1,
                             Reduced_Output_Wallace_2,
                             Reduced_Final_Sum);

                               
            END IF;

          Result <=  (Reduced_Final_Sum  & LSB1 & LSB0);

         END IF;

      END IF;
         

   END PROCESS Multiplication;	

END Behavioural;

     

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -