我在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;
答案 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;