如何流水线我的 2s 补码乘法器? [英] How to pipeline my 2s complement multiplier?

查看:26
本文介绍了如何流水线我的 2s 补码乘法器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 VHDL 中设计了一个 8x8 2s 补码乘法器,它似乎不符合我的 PSD 估算器的需求,我认为我必须将其转换为流水线.你有我的乘数.谁能告诉我如何应用管道使我的乘法器运行得更快?

I have designed a 8x8 2s complement multiplier in VHDL and it doesn't seem to fit the needs for my PSD estimator and I think I have to transform it into pipeline. Here you have my multiplier. Can anyone tell me how can I apply the pipeline for my multiplier to run faster?

问候

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;

推荐答案

它应该是这样的(未测试,但想法在这里).还有 8 个时钟周期需要计算,但乘法器现在已经流水线化了.

It should be something like this (not tested but the idea is here). There are still 8 clock cycles to calculate but the multiplier is now pipelined.

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;

这篇关于如何流水线我的 2s 补码乘法器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆