如何管道我的2s补码乘数?

时间:2014-12-09 13:14:13

标签: vhdl

我在VHDL中设计了一个8x8 2s补码乘法器,它似乎不符合我的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;

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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;