1

我正在制作一个有符号乘法器,为此我创建了半加器​​、全加器、波纹进位加法器,最后是一个乘法器。代码如下所示。我怎样才能让它更快以获得更好的时机。我的最后一项任务是制作一个以 100Mhz 运行的冷杉滤波器。此过滤器使用多重乘法运算(通过使用我的乘数)。那么你能通过流水线或并行等一些优化技术帮助我改进我的设计吗?

   //half adder
    entity half_adder is
    port (
    a, b : in std_logic ;
    sum, cout : out std_logic );
    end half_adder;

    architecture version1 of half_adder is
    begin
    sum <= a xor b;
    cout <= a and b;
    end version1;

-- 全加器

    entity full_adder is

    port(

    a       : in  std_logic; 
    b       : in  std_logic; 
    cin     : in  std_logic; 
    sum    : out  std_logic; 
    cout    : out  std_logic
    );
    end full_adder;


    architecture structural of full_adder is
    component half_adder
    port (
    a, b : in std_logic ;
    sum, cout : out std_logic );
    end component;
    signal s1, c1, c2 : std_logic ;
    begin -- structural
    half_adder1 : half_adder
    port map (
    a => a, b => b,
    sum => s1, cout => c1);
    half_adder2 : half_adder
    port map (
    a =>cin, b => s1,
    sum => sum, cout => c2);
    cout <= c1 or c2;

    end structural ;

-- 波纹进位加法器 40 位

    entity rca40bit is
  generic (
          width: integer := 40
          );
    port(
        a         :    in  std_logic_vector(width-1 downto 0);
        b         :    in  std_logic_vector(width-1 downto 0);
        cin     :    in  std_logic;
        sum     :    out std_logic_vector(width-1 downto 0);
        cout     :    out std_logic
        );
    end rca40bit;

architecture Behavioral of rca40bit is
component full_adder 
port(

    a       : in  std_logic; 
    b       : in  std_logic; 
    cin     : in  std_logic; 
    sum    : out  std_logic; 
    cout    : out  std_logic
    );
    end component;
    signal s: std_logic_vector(width downto 0);

    begin
    s(0)<=cin; 
    FA:for i in 0 to width-1 generate
    FA_i:full_adder 
    port map 
    (
    a=>a(i),b=>b(i),cin=>s(i),sum=>sum(i),cout=>s(i+1)
    );

    end generate;

    cout<=s(width);

    end Behavioral;

-- 乘数,我先计算部分乘积,然后通过 rca 加法器相加。

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use ieee.numeric_std.all;


    entity signed_mult is
    generic (

          m   : integer := 24;    -- Multiplicand

          n   : integer := 16 ; -- multiplier;

         bit1 :integer := 39      -- size of the adder

          );


    port(

        a         :    in    std_logic_vector(m - 1 downto 0)      ;
        b         :    in    std_logic_vector(n - 1 downto 0)      ;
        prod      :    out   std_logic_vector(bit1 downto 0)

        );
    end entity signed_mult;

    architecture Behavioral of signed_mult is


component rca40bit 

 port(
                  a         :    in  std_logic_vector(bit1 downto 0);
                  b         :    in  std_logic_vector(bit1 downto 0);
                  cin       :    in  std_logic;
                  sum       :    out std_logic_vector(bit1 downto 0);
                  cout      :    out std_logic
                );




     end component;

--partial products signals 

     signal p0 : std_logic_vector(bit1 downto 0):=(others =>'0') ;  --1st 
    `enter code here`partial product size m-1 bits (24 bit)
    signal p1: std_logic_vector (bit1 downto 0):=(others =>'0'); --2nd 
      partial product size m bits (25 bit) 
    signal p2 : std_logic_vector (bit1 downto 0):=(others =>'0');  --3rd partial 
    product size m+1 bits (26 bit)  
    signal p3 : std_logic_vector (bit1 downto 0):=(others =>'0');  --4th partial 
    product size m+2 bits (27 bit)  
    signal p4 : std_logic_vector (bit1 downto 0):=(others =>'0');   --5th 
    partial product size m+3 bits (28 bit)
    signal p5 : std_logic_vector (bit1 downto 0):=(others =>'0');   --6th 
    partial product size m+4 bits (29 bit)
    signal p6 : std_logic_vector (bit1 downto 0):=(others =>'0');   --7th 
    partial product size m+5 bits (30 bit)
    signal p7 : std_logic_vector (bit1 downto 0):=(others =>'0');   --8th 
    partial product size m+6 bits (31 bit)
    signal p8 : std_logic_vector (bit1 downto 0):=(others =>'0');   --9th 
    partial product size m+7 bits (32 bit)
    signal p9 : std_logic_vector (bit1 downto 0):=(others =>'0');  --10th 
    partial product size m+8 bits (33 bit)
    signal p10 : std_logic_vector (bit1 downto 0):=(others =>'0');   --11th 
    partial product size m+9 bits (34 bit)
    signal p11 : std_logic_vector (bit1 downto 0):=(others =>'0');  --12th 
    partial product size m+10 bits (35 bit)
    signal p12 : std_logic_vector (bit1 downto 0):=(others =>'0');   --13th 
    partial product size m+11 bits (36 bit)
    signal p13 : std_logic_vector (bit1 downto 0):=(others =>'0');   --14th 
       partial product size m+12 bits (37 bit)
    signal p14 : std_logic_vector (bit1 downto 0):=(others =>'0');   --15th 
      partial product size m+13 bits (38 bit)
     signal p15 : std_logic_vector (bit1 downto 0);   --16th partial product 
             size m+14 bits (39 bit)
     signal p16 : std_logic_vector (bit1 downto 0);
     signal p17 : std_logic_vector (bit1 downto 0):=(others =>'0');   



    signal extc0 :std_logic_vector (bit1 downto 0) ;




--constants and  carry


 signal  zeros :std_logic_vector (bit1 downto 0) :=(others =>'0');
 signal c : std_logic := '0' ; 
 signal c0 : std_logic :='0' ; 
  signal c12 : std_logic :='0' ; 
 signal c23 : std_logic :='0' ; 
 signal c34 ,c45,c56,c67,c78,c89,c910,c1011,c1112,c1213,c1314,c1415,c1516 ,c1617: std_logic := '0'; 
  signal c15 : std_logic_vector (bit1 downto 0):=(others =>'0'); 


 --sum only


    signal sum12 : std_logic_vector   (bit1 downto 0); 
    signal sum23 : std_logic_vector   (bit1 downto 0); 

   signal sum34, sum45,sum56,sum67,sum78, 
   sum89,sum910,sum1011,sum1112,sum1213,sum1314,sum1415,sum1516,sum1617,ps0: 
   std_logic_vector   (bit1 downto 0);


 --signal f_sum: std_logic_vector   (bit1 downto 0);   --sum of p0 and P1
 --signal tpp1 : std_logic_vector   (bit1 downto 0); 



 begin 

pp0: process is 
begin 
 fst_partial_product :for i in 0 to m-1 loop  -- 0 to 23


p0(i)<= (a(i) and b(0)) ; 


if i=m-1 then 

p0(i)<=not ( a(i) and b(0)); --msb=m=24

end if ;
 end loop  fst_partial_product ;



n2d_partial_product : for i in 0 to m-1 loop -- 24

 p1(0)<='0';
 p1(i+1)<=a(i) and b(1) ;

if i=m-1 then 
p1(i+1)<=not (a(i) and b(1)); --msb=m=24


 end if ;
 end loop n2d_partial_product;


r3d_partial_product : for i in 0 to m-1 loop

p2(0)<='0';
p2(1)<='0';
p2(i+2)<=a(i) and b(2) ;
if  i=m-1 then
p2(i+2)<=not( a(i) and b(2)); --msb=25

 end if ;
 end loop r3d_partial_product;

r4th_partial_product : for i in 0 to m-1 loop
p3(0)<='0';
p3(1)<='0';
p3(2)<='0';
p3(i+3)<=a(i) and b(3);
 if i=m-1 then 
p3(i+3)<=not(  a(i) and b(3)); --msb=26

end if ;
end loop r4th_partial_product;

r5d_partial_product : for i in 0 to m-1 loop

p4(0)<='0';
p4(1)<='0';
p4(2)<='0';
p4(3)<='0';
p4(i+4)<=a(i) and b(4) ;
if i=m-1 then 
p4(i+4)<=not( a(i) and b(4)); --msb=27
end if ;
end loop r5d_partial_product;

t6hpartial_product : for i in 0 to m-1 loop
p5(0)<='0';
p5(1)<='0';
p5(2)<='0';
p5(3)<='0';
p5(4)<='0';
p5(i+5)<=a(i) and b(5) ;
if i=m-1 then 
p5(i+5)<=not( a(i) and b(5)); --msb28

end if;
end loop t6hpartial_product ;

t7h_partial_product : for i in 0 to m-1 loop

p6(0)<='0';
p6(1)<='0';
p6(2)<='0';
p6(3)<='0';
p6(4)<='0';
p6(5)<='0';
p6(i+6)<=a(i) and b(6) ;
if i=m-1 then 
p6(i+6)<=not (a(i) and b(6)); --msb=29
end if;
end loop t7h_partial_product;

t8th_partial_product : for i in 0 to m-1 loop
p7(0)<='0';
p7(1)<='0';
p7(2)<='0';
p7(3)<='0';
p7(4)<='0';
p7(5)<='0';
p7(6)<='0';
p7(i+7)<=a(i) and b(7) ;
if i=m-1 then 
p7(i+7)<=not( a(i) and b(7)); --msb=30

end if;
end loop t8th_partial_product ;


t9th_partial_product : for i in 0 to m-1 loop

p8(0)<='0';
p8(1)<='0';
p8(2)<='0';
p8(3)<='0';
p8(4)<='0';
p8(5)<='0';
p8(6)<='0';
p8(7)<='0';
p8(i+8)<=a(i) and b(8); 
if i=m-1 then
p8(i+8)<=not( a(i) and b(8)); --msb=31
end if;
end loop t9th_partial_product;

t10th_partial_product : for i in 0 to m-1 loop
p9(0)<='0';
p9(1)<='0';
p9(2)<='0';
p9(3)<='0';
p9(4)<='0';
p9(5)<='0';
p9(6)<='0';
p9(7)<='0';
p9(8)<='0';
p9(i+9)<=a(i) and b(9) ;
if i=m-1 then
 p9(i+9)<=not( a(i) and b(9)); --msb=32

end if;
end loop t10th_partial_product ;

t11th_partial_product : for i in 0 to m-1 loop

p10(0)<='0';
p10(1)<='0';
p10(2)<='0';
p10(3)<='0';
p10(4)<='0';
p10(5)<='0';
p10(6)<='0';
p10(7)<='0';
p10(8)<='0';
p10(9)<='0';
p10(i+10)<=a(i) and b(10) ;
if i=m-1 then
p10(i+10)<=not( a(i) and b(10)); --msb=31

end if;
end loop t11th_partial_product;

t12th_partial_product : for i in 0 to m-1 loop

p11(0)<='0';
p11(1)<='0';
p11(2)<='0';
p11(3)<='0';
p11(4)<='0';
p11(5)<='0';
p11(6)<='0';
p11(7)<='0';
p11(8)<='0';
p11(9)<='0';
p11(10)<='0';
p11(i+11)<=a(i) and b(11) ;
if i=m-1 then
 p11(i+11)<=not( a(i) and b(11)); --msb=32

end if;
end loop t12th_partial_product;
t13th_partial_product : for i in 0 to m-1 loop

p12(0)<='0';
p12(1)<='0';
p12(2)<='0';
p12(3)<='0';
p12(4)<='0';
p12(5)<='0';
p12(6)<='0';
p12(7)<='0';
p12(8)<='0';
p12(9)<='0';
p12(10)<='0';
p12(11)<='0';

p12(i+12)<=a(i) and b(12) ;
if i=m-1 then
 p12(i+12)<=not( a(i) and b(12)); --msb=32

end if;
end loop t13th_partial_product ;
t14th_partial_product : for i in 0 to m-1 loop

p13(0)<='0';
p13(1)<='0';
p13(2)<='0';
p13(3)<='0';
p13(4)<='0';
p13(5)<='0';
p13(6)<='0';
p13(7)<='0';
p13(8)<='0';
p13(9)<='0';
p13(10)<='0';
p13(11)<='0';
p13(12)<='0';
p13(i+13)<=a(i) and b(13) ;
if i=m-1 then
 p13(i+13)<=not( a(i) and b(13)); --msb=32
end if;
end loop t14th_partial_product ;
t15th_partial_product : for i in 0 to m-1 loop

p14(0)<='0';
p14(1)<='0';
p14(2)<='0';
p14(3)<='0';
p14(4)<='0';
p14(5)<='0';
p14(6)<='0';
p14(7)<='0';
p14(8)<='0';
p14(9)<='0';
p14(10)<='0';
p14(11)<='0';
p14(12)<='0';
p14(13)<='0';
p14(14)<='0';
p14(i+14)<=a(i) and b(14) ;

if i=m-1 then 

p14(i+14)<=not( a(i) and b(14)); --msb=32
end if;
end loop t15th_partial_product;

t16th_partial_product : for i in 0 to m-1 loop

p15(0)<='0';
p15(1)<='0';
p15(2)<='0';
p15(3)<='0';
p15(4)<='0';
p15(5)<='0';
p15(6)<='0';
p15(7)<='0';
p15(8)<='0';
p15(9)<='0';
p15(10)<='0';
p15(11)<='0';
p15(12)<='0';
p15(13)<='0';
p15(14)<='0';
p15(i+15)<=not (a(i) and b(15)) ;


if i=m-1 then 
 p15(i+15)<= (a(i) and b(15));

end if;



end loop t16th_partial_product ;


wait on a,b;
end process pp0;

p16(39)<='1';
p16(38 downto 0)<=p15(38 downto 0);
--sum 

extc0(39 downto 0 )<=zeros(39 downto 24) & '1' & zeros(22 downto 0 ); -- just store 1 on msb of 1st pp
c15(39 downto 0 )<=zeros(39 downto 16) & '1' &  zeros(14 downto 0 )  ; -- just store 1 on msb of 1st pp



--sum temp p0
tmp1st_pp:rca40bit 
port map(a=>extc0 , b=>p0, cin=>c, sum=>ps0 ,cout=>c0); ---carry + p0
--sum temp p0
--ttmp1st_pp:rca40bit 
--port map(a=>extc0 , b=>p0, cin=>c, sum=>ps1 ,cout=>c0); ---carry + p0


--sum  1st and 2nd row of pp
s1tnd_pp:rca40bit 
port map(a=>ps0 , b=>p1, cin=>c, sum=>sum12 ,cout=>c12);

--adding sum of s12   and 3rd row of pp

t3rd_pp:rca40bit 
port map(a=>sum12, b=>p2, cin=>c, sum=>sum23 ,cout=>c23);

--adding sum of s23   and 4rt row of pp

t4rh_pp:rca40bit 
port map(a=>sum23, b=>p3, cin=>c, sum=>sum34 ,cout=>c34);


t5rh_pp:rca40bit 
port map(a=>sum34, b=>p4, cin=>c, sum=>sum45 ,cout=>c45);

t6rh_pp:rca40bit 
port map(a=>sum45, b=>p5, cin=>c, sum=>sum56 ,cout=>c56);


t7th_pp:rca40bit 
port map(a=>sum56, b=>p6, cin=>c, sum=>sum67 ,cout=>c67);


t8th_pp:rca40bit 
port map(a=>sum67, b=>p7, cin=>c, sum=>sum78 ,cout=>c78);

t9th_pp:rca40bit 
port map(a=>sum78, b=>p8, cin=>c, sum=>sum89 ,cout=>c89);

t10th_pp:rca40bit 
port map(a=>sum89, b=>p9, cin=>c, sum=>sum910 ,cout=>c910);

t11th_pp:rca40bit 
port map(a=>sum910, b=>p10, cin=>c, sum=>sum1011 ,cout=>c1011);

t12th_pp:rca40bit 
port map(a=>sum1011, b=>p11, cin=>c, sum=>sum1112 ,cout=>c1112);

t13th_pp:rca40bit 
port map(a=>sum1112, b=>p12, cin=>c, sum=>sum1213 ,cout=>c1213);

t14th_pp:rca40bit 
port map(a=>sum1213, b=>p13, cin=>c, sum=>sum1314 ,cout=>c1314);

t15th_pp:rca40bit 
port map(a=>sum1314, b=>p14, cin=>c, sum=>sum1415,cout=>c1415);

carryaddwith15th_pp:rca40bit 
port map(a=>sum1415, b=>p16, cin=>c, sum=>sum1516,cout=>c1617);

t16th_pp:rca40bit 

port map(a=>c15, b=>sum1516, cin=>c, sum=>sum1617,cout=>c1516);

 prod <=sum1617;



 end Behavioral;

过滤器设计

library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity your_filter is
    Generic (
        constant PIPELINE_DEPTH   : positive := 2;
        constant DATA_WIDTH       : positive := 24;
        constant FIR_ORDER        : positive := 34;
        constant COEFF_WIDTH      : positive := 16      
    );
    Port ( 
        clk           : in  STD_LOGIC;
        rst           : in  STD_LOGIC;
        data_in       : in  STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
        data_out      : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0)
    );
end your_filter;

architecture Behavioral of your_filter is



component ripple_ca is
port(
       a         :    in  std_logic_vector(DATA_WIDTH+COEFF_WIDTH-1 downto 0);
       b         :    in  std_logic_vector(DATA_WIDTH+COEFF_WIDTH-1 downto 0);
       cin     :    in  std_logic;
       sum     :    out std_logic_vector(DATA_WIDTH+COEFF_WIDTH-1 downto 0);
       cout     :    out std_logic
);
end component;

component signed_mult is
 port(

       a         :    in    std_logic_vector(DATA_WIDTH - 1 downto 0)      ;
       b         :    in    std_logic_vector(COEFF_WIDTH - 1 downto 0)      ;
       prod      :    out   std_logic_vector(DATA_WIDTH+COEFF_WIDTH-1 downto 0)

       );

end component;

        type REG_TYPE is array (0 to FIR_ORDER-1) of signed (DATA_WIDTH+COEFF_WIDTH-1 downto 0);
        type COEFF_ARRAY_TYPE is array (0 to FIR_ORDER) of signed(COEFF_WIDTH-1 downto 0);

        type REG_TYPE2 is array (0 to FIR_ORDER-1) of std_logic_vector (DATA_WIDTH-1 downto 0);
        type sum is array (0 to FIR_ORDER) of std_logic_vector(DATA_WIDTH+COEFF_WIDTH-1 downto 0); 
        signal sum1 : sum;
        signal c1 : std_logic;
        signal c : std_logic :='0';
         type COEFF_ARRAY1 is array (0 to FIR_ORDER) of std_logic_vector(COEFF_WIDTH-1 downto 0); 
        signal coeff : COEFF_ARRAY1;
        signal reg          : REG_TYPE2;
        signal next_reg     : REG_TYPE2;
        signal reg1          : REG_TYPE2; 
        type REG_TYPE1 is array (0 to FIR_ORDER-1) of std_logic_vector (DATA_WIDTH+COEFF_WIDTH-1 downto 0);
        signal next_reg1     : REG_TYPE1; 
        signal data_out_temp       : std_logic_vector(DATA_WIDTH+COEFF_WIDTH-1 downto 0);
        signal tempmult : sum;
        signal  data_in_reg       :  STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
        signal  next_data_out      :  STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);



        constant coeff_array : COEFF_ARRAY_TYPE := (
        "0000000101011111",
        "0000000001100001",
        "0000000000110011",
        "1111111111011010",
        "1111111101011111",
        "1111111011011001",
        "1111111001100101",
        "1111111000100101",
        "1111111000111011",
        "1111111010111111",
        "1111111110111001",
        "0000000100100000",
        "0000001011011000",
        "0000010010110011",
        "0000011001111010",
        "0000011111110010",
        "0000100011101011",
        "0000100101000010",
        "0000100011101011",
        "0000011111110010",
        "0000011001111010",
        "0000010010110011",
        "0000001011011000",
        "0000000100100000",
        "1111111110111001",
        "1111111010111111",
        "1111111000111011",
        "1111111000100101",
        "1111111001100101",
        "1111111011011001",
        "1111111101011111",
        "1111111111011010",
        "0000000000110011",
        "0000000001100001",
        "0000000101011111"  
                                                    );

begin



    --synchronous process
    sync_proc : process (clk)
    begin
        if rising_edge(clk) then
            if rst = '0' then
                reg             <= (others=>(others=>'0'));
                data_in_reg     <= (others=>'0'); 
                data_out        <= (others=>'0');
             else
                reg             <= next_reg;
                data_in_reg     <= data_in;
                data_out        <= next_data_out;
            end if;
        end if;
    end process;

    --asynchronous process
    async_proc : process (reg, data_in_reg)
        variable sum : signed(DATA_WIDTH+COEFF_WIDTH-1 downto 0) := (others => '0');
    begin
       for i in 0 to FIR_ORDER -2 loop
           next_reg(i+1) <= reg(i);
                  end loop;
           next_reg(0) <= (data_in_reg);

--      data_out_temp <= std_logic_vector(sum + signed(data_in_reg)*coeff_array(0));--std_logic_vector(sum);--(sum);--

for i in 0 to FIR_ORDER-1 loop
        coeff(i)<= std_logic_vector (coeff_array(i));
        reg1(i)<= std_logic_vector (reg(i));
        --next_reg1(i)<= std_logic_vector (next_reg(i));
     end loop;
coeff(FIR_ORDER)<= std_logic_vector (coeff_array(FIR_ORDER));


end process;

  --next_reg(i) <= reg(i+1)+(signed(data_in_reg))*coeff_array(i+1);
  nextreg :   for i in 0 to FIR_ORDER -1 generate

       accumumlator : signed_mult
          port map ( a => reg1(i), b => coeff(i+1), prod => tempmult(i) );          
     end generate nextreg;

     sum1(0) <= (others => '0');
     addition :   for i in 0 to FIR_ORDER -1 generate
     addition01 : ripple_ca
               port map ( a => sum1(i),b => tempmult(i) , cin=>c, sum => sum1(i+1),cout => c1 );
end generate  addition;
    -- data_out_temp <= std_logic_vector(reg(0) + signed(data_in_reg)*coeff_array(0));--std_logic_vector(sum);--(sum);--

      dataout : signed_mult
       port map (

       a => data_in_reg,
       b => coeff(0),
       prod => tempmult(FIR_ORDER)
       );

  addition_2 : ripple_ca
   port map (a => sum1(FIR_ORDER),b => tempmult(FIR_ORDER) ,cin=>c , sum => data_out_temp ,cout => c1);                         


        next_data_out <= data_out_temp(DATA_WIDTH+COEFF_WIDTH-1  downto COEFF_WIDTH);


end Behavioral;
4

0 回答 0