如何流水线我的 2s 补码乘法器? [英] How to pipeline my 2s complement multiplier?
本文介绍了如何流水线我的 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屋!
查看全文