2014-12-09 63 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