2014-12-09 65 views
0

我设计了一个VHDL的8x8二进制补码乘法器,它似乎不适合我的PSD估计器的需求,我想我必须将它转换为流水线。这里你有我的乘数。任何人都可以告诉我,我怎样才能使用管道为我的乘数运行更快?如何管道我的二进制补码乘法器?

问候

library IEEE; 
use IEEE.std_logic_1164.all; 
use IEEE.std_logic_arith.all; 
use IEEE.std_logic_unsigned.all; 
use ieee.numeric_std.all; 
use ieee.std_logic_textio.all; 
use IEEE.STD_LOGIC_1164.ALL; 



entity mult_secv is 
    generic(
    Na : integer := 8; 
    Nb : integer := 8; 
    Nbcnt : integer := 4 
    ); 
    port(
    iCLK : in std_logic; 
    iRST : in std_logic; 
    iDV : in std_logic; 

    ia  : in std_logic_vector(Na-1 downto 0); 
    ib  : in std_logic_vector(Nb-1 downto 0); 

    oDV  : out std_logic; 
    oDATA : out std_logic_vector(Na+Nb-2 downto 0) 
    ); 
end mult_secv; 

architecture produs of mult_secv is 

signal sa, srez : std_logic_vector(Na+Nb-2 downto 0); 
signal sb : std_logic_vector(Nb-1 downto 0); 
signal scnt : std_logic_vector(Nbcnt-1 downto 0); 
signal scntmax : std_logic_vector(Nbcnt-1 downto 0) := "0111"; 


begin 

process(iCLK,iRST) 
begin 
    if iRST='1' then 
    sa <= (others => '0');  
    elsif rising_edge(iCLK) then 
    if iDV='1' then 
     sa <= (Na+Nb-2 downto Na => ia(Na-1)) & ia; 
    else 
     sa <= sa(Na+Nb-3 downto 0) & '0'; 
    end if; 
    end if; 
end process; 


process(iCLK,iRST) 
begin 
    if iRST='1' then 
    sb <= (others => '0');  
    elsif rising_edge(iCLK) then 
    if iDV='1' then 
     sb <= ib; 
    else 
     sb <= '0' & sb(Nb-1 downto 1); 
    end if; 
    end if; 
end process; 

process(iCLK,iRST) 
begin 
    if iRST='1' then 
    srez <= (others => '0');   
    elsif rising_edge(iCLK) then 
    if iDV='1' then 
     srez <= (others => '0'); 
     if ib(Nb-1)='1' then 
     srez <= not (ia & (Nb-2 downto 0 => '0')) + '1'; 
     else 
     srez <= (others => '0'); 
     end if; 
    elsif sb(0)='1' then   
     srez <= srez+sa; 
    else  
     srez <= srez; 
    end if; 
    end if; 
end process; 

process(iCLK,iRST) 
begin 
    if iRST='1' then 
    scnt <= (others =>'0'); 
    elsif rising_edge(iCLK) then 
    if iDV='1' then 
     scnt <= (Nbcnt-1 downto 1 => '0') & '1'; 
    elsif scnt=scntmax then 
     scnt <= (others => '0'); 
    else 
     scnt <= scnt +'1'; 
    end if; 
    end if; 
end process; 


oDATA <= srez; 


process(iCLK,iRST) 
begin 
    if iRST='1' then 
    oDV <= '0'; 
    elsif rising_edge(iCLK) then 
    if scnt=scntmax then 
     oDV <= '1'; 
    else 
     oDV <= '0'; 
    end if; 
    end if; 
end process; 


end; 

回答

0

综合工具,这些天将产生这一切都为您服务。它的字面意思就像这样简单:

use ieee.std_logic_textio.all; 
use IEEE.STD_LOGIC_1164.ALL; 



entity mult_secv is 
    generic(
    Na : integer := 8; 
    Nb : integer := 8; 
    Nbcnt : integer := 4 
    ); 
    port(
    iCLK : in std_logic; 
    iRST : in std_logic; 
    iDV : in std_logic; 

    ia  : in std_logic_vector(Na-1 downto 0); 
    ib  : in std_logic_vector(Nb-1 downto 0); 

    oDV  : out std_logic; 
    oDATA : out std_logic_vector(Na+Nb-2 downto 0) 
    ); 
end mult_secv; 

architecture produs of mult_secv is 

begin 

process(iCLK,iRST) 
begin 
    if iRST='1' then 
    oDV <= '0'; 
    oDATA <= (others => '0');  
    elsif rising_edge(iCLK) then 
    if iDV='1' then 
     oDV <= '1'; 
     oDATA <= ia*ib; 
    else 
     oDV <= '0'; 
    end if; 
    end if; 
end process; 
+2

综合工具将生成一个流水线乘法器?多少个流水线阶段,即什么等待时间? – fru1tbat 2014-12-09 16:05:07

+1

实际上你还没有提供一个使用条款,使乘法运算符可见并带有[std_logic_vector,std_logic_vector return std_logic_vector]的签名。 – user1155120 2014-12-09 16:30:37

+0

这也不是一个有符号的乘数。 – QuantumRipple 2014-12-09 16:32:52

0

它应该是这样的东西(未经测试,但想法在这里)。仍然有8个时钟周期可以计算,但现在乘法器是流水线的。

library IEEE; 
use IEEE.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity mult_secv is 
    generic(
    Na : integer := 8; 
    Nb : integer := 8; 
    Nbcnt : integer := 4 
    ); 
    port(
    iCLK : in std_logic; 
    iRST : in std_logic; 
    iDV : in std_logic; 

    ia  : in std_logic_vector(Na-1 downto 0); 
    ib  : in std_logic_vector(Nb-1 downto 0); 

    oDV  : out std_logic; 
    oDATA : out std_logic_vector(Na+Nb-2 downto 0) 
    ); 
end mult_secv; 

architecture produs of mult_secv is 

-- 8 stage array 
signal sa, srez : array (1 to 8) of std_logic_vector(Na+Nb-2 downto 0); 
signal sb : array (1 to 8) of std_logic_vector(Nb-1 downto 0); 
signal dv : array (1 to 8) of std_logic; 

constant scntmax : integer := 8; 


begin 

-- for each pipeline stage 
for scnt in 1 to scntmax generate 

process(iCLK,iRST) 
begin 
    if iRST='1' then 
    sa <= (others => (others => '0')); 
    elsif rising_edge(iCLK) then 
    -- first stage 
    if (scnt = 1) then 
     sa(scnt) <= (Na+Nb-2 downto Na => ia(Na-1)) & ia; 
    -- other stages 
    else 
     sa(scnt) <= sa(scnt-1)(Na+Nb-3 downto 0) & '0'; 
    end if; 
    end if; 
end process; 


process(iCLK,iRST) 
begin 
    if iRST='1' then 
    sb <= (others => (others => '0')); 
    elsif rising_edge(iCLK) then 
    if (scnt = 1) then 
     sb(scnt) <= ib; 
    else 
     sb(scnt) <= '0' & sb(scnt-1)(Nb-1 downto 1); 
    end if; 
    end if; 
end process; 

process(iCLK,iRST) 
begin 
    if iRST='1' then 
    srez <= (others => (others => '0')); 
    elsif rising_edge(iCLK) then 
    if (scnt = 1) then 
     if ib(Nb-1)='1' then 
     srez(scnt) <= not (ia & (Nb-2 downto 0 => '0')) + '1'; 
     else 
     srez(scnt) <= (others => '0'); 
     end if; 
    elsif sb(scnt-1)(0)='1' then   
     srez(scnt) <= srez(scnt-1)+sa(scnt-1); 
    else  
     srez(scnt) <= srez(scnt-1); 
    end if; 
    end if; 
end process;  

process(iCLK,iRST) 
begin 
    if iRST='1' then 
    dv <= (others => '0'); 
    elsif rising_edge(iCLK) then 
    if (scnt = 1) then 
     dv(scnt) <= iDV; 
    else 
     dv(scnt) <= dv(scnt-1); 
    end if; 
    end if; 
end process; 

end generate; 

oDATA <= srez(scntmax); 
oDv <= dv(scntmax); 

end; 
+0

谢谢!我认为我理解了这个数组的想法,但我认为它必定有点不同,因为这似乎是一个冲突,这里'sa(scnt)<=(Na + Nb-2 downto Na => ia(Na-1 ))& ia;'因为'sa'是数组类型,'ia'是一个信号。任何人都可以告诉我如何以这样的方式替换数组,我的冲突不存在? – 2014-12-13 10:11:34

+0

试试这个:'sa(scnt)<= std_logic_vector(resize(signed(ia),Na + Nb-2));'resize函数会自动复制高位的符号位。 sa(cnt)是一个std_logic_vector。 – grorel 2014-12-13 13:53:42

+0

没关系。我认为问题是为了for的标签。但它不起作用,当我尝试乘11101111 11111101,例如 – 2014-12-13 14:31:15