-4

对于“强大”的求解器,我有一个难题:

我正在尝试综合本问题末尾显示的 VHDL 行为代码。

当我使用这条线时

m1Low := m1Low/m0Low;

该电路正在合成并产生正确的结果。但是,这是针对给定输入的,在代码中固定为常量。当输入作为来自电路外部的信号(这里特别是输入 hist 是 std_logic_vector 的数组)时,它不再合成。我必须用除法函数替换 / :

m1Low := to_integer(除法(to_unsigned(m1Low,32),to_unsigned(m0Low,32)));

电路合成了很长时间。我把它放了一夜,它没有完成合成。

你建议我做什么?

谢谢哈里斯

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.ALL;


use IEEE.NUMERIC_STD.ALL;

library work;
use work.declarations.all;


entity behavioral_code is
generic ( NHIST : integer := 32 );
port (clk        : in  std_logic;   
      en         : in  std_logic;   
          hist       : in  vector_array;
          thres      : out std_logic_vector ( 31 downto 0) );
end behavioral_code;

architecture Behavioral of behavioral_code is

begin

process(en,clk)

    type int_array is array (1 to NHIST) of integer;    
    variable m0Low : integer := 0;
    variable m1Low : integer := 0;
    variable m0High : integer := 0;
    variable m1High : integer := 0;
    variable varLow : integer := 0;
    variable varHigh : integer := 0;
    variable varWithin : integer := 0;
    variable varWMin : integer := 900000000;
    variable hist_var : int_array;
    variable invertFlag: integer := 0;             
    variable nHistM1: integer := 0;
    variable i: integer := 0;
    variable j: integer := 0;
    variable k: integer := 0;
    variable l: integer := 0;
    variable m: integer := 0;
    variable n: integer := 0;
    variable o: integer := 0;
    variable p: integer := 0;
    variable q: integer := 0;
    variable temp: integer :=0;
    variable thres_var: integer :=0;



    begin
    if(en = '1') then

            for k in 1 to NHIST loop   
                hist_var(k) :=to_integer(unsigned(hist(k-1)));
    end loop;


    --for k in 1 to NHIST loop          --COMMENT: OLD FIXED INPUT
    --  hist_var(k) :=k;
    --end loop;



    nHistM1 := NHIST-1;
    for i in 1 to  nHistM1 loop     
        m0Low   :=0;
        m1Low   :=0;
        m0High  :=0;
        m1High  :=0;
        varLow  :=0;
        varHigh :=0;        

        for j in 1 to i loop
            m0Low := m0Low + hist_var(j);
            m1Low := m1Low + (j-1) * hist_var(j);
        end loop;


        if m0Low = 0 then
        m1Low := i;
        else
                    --m1Low := m1Low/m0Low;
        m1Low := to_integer(divide(to_unsigned(m1Low,32),to_unsigned(m0Low,32)));
        end if;

        for m in i + 1 to  NHIST loop
            m0High := m0High + hist_var(m);
            m1High := m1High + (m-1) * hist_var(m);
        end loop;

        if m0High = 0 then
        m1High := i;
        else
                    --m1High := m1High /m0High;
        m1High :=to_integer(divide(to_unsigned(m1High,32),to_unsigned(m0High,32)));
        end if;


        for n in 1 to i loop
            varLow := varLow + (n - 1- m1Low) * (n -1- m1Low) * hist_var(n);
        end loop;



        for o in i+1 to NHIST loop
            varHigh := varHigh +(o -1- m1High) * (o -1- m1High) * hist_var(o);
        end loop;




            varWithin := m0Low * varLow + m0High * varHigh;

        if varWithin < varWMin then
            varWMin := varWithin;
            thres_var := i-1;
        end if;


    end loop;


    thres <= std_logic_vector(to_unsigned(thres_var, 32));

    end if;
    end process;

end Behavioral;

声明包如下:

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;

package declarations is
--generic ( NHIST : integer := 6 );
  type vector_array is array (23 downto 0) of std_logic_vector(7 downto 0);
  function  divide  (a : UNSIGNED; b : UNSIGNED) return UNSIGNED;
end package declarations;

package body declarations is

function  divide  (a : UNSIGNED; b : UNSIGNED) return UNSIGNED is
variable a1 : unsigned(a'length-1 downto 0):=a;
variable b1 : unsigned(b'length-1 downto 0):=b;
variable p1 : unsigned(b'length downto 0):= (others => '0');
variable i : integer:=0;

begin
for i in 0 to b'length-1 loop
p1(b'length-1 downto 1) := p1(b'length-2 downto 0);
p1(0) := a1(a'length-1);
a1(a'length-1 downto 1) := a1(a'length-2 downto 0);
p1 := p1-b1;
if(p1(b'length-1) ='1') then
a1(0) :='0';
p1 := p1+b1;
else
a1(0) :='1';
end if;
end loop;
return a1;

end divide;

end package body;

测试台如下:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;

ENTITY testbench1 IS
END testbench1;

ARCHITECTURE behavior OF testbench1 IS 

-- Component Declaration for the Unit Under Test (UUT)

COMPONENT behavioral_code
 port ( clk        : in  std_logic; 
         en         : in  std_logic;    
       hist       : in  vector_array;
           --debug1      : out std_logic_vector ( 31 downto 0);
           --debug10      : out std_logic_vector ( 31 downto 0);
           --debug11     : out std_logic_vector ( 31 downto 0);
           --debug2     : out std_logic_vector ( 31 downto 0);
           --debug3     : out std_logic_vector ( 31 downto 0);
           --debug4     : out std_logic_vector ( 31 downto 0);
           --debug5     : out std_logic_vector ( 31 downto 0);
           --debug6     : out std_logic_vector ( 31 downto 0);
           --debug7     : out std_logic_vector ( 31 downto 0);
           --debug8     : out std_logic_vector ( 31 downto 0);
           --debug50    : out std_logic_vector ( 31 downto 0);
          -- debug60    : out std_logic_vector ( 31 downto 0);
       thres      : out std_logic_vector ( 31 downto 0) );
 end component;




 --Inputs
  signal en : std_logic := '0';
  signal hist : vector_array := (others => '0');
  signal clk: std_logic := '0';
--Outputs
   signal thres : std_logic_vector(31 downto 0);
  --signal debug1 : std_logic_vector(31 downto 0);
  --signal debug10 : std_logic_vector(31 downto 0);
  --signal debug11 : std_logic_vector(31 downto 0);
  --signal debug2  :  std_logic_vector ( 31 downto 0);
-- signal debug3  :  std_logic_vector ( 31 downto 0);
 --signal   debug4  :  std_logic_vector ( 31 downto 0);
 --signal   debug5  :  std_logic_vector ( 31 downto 0);
 --signal   debug6  :  std_logic_vector ( 31 downto 0);
 -- signal  debug7  :  std_logic_vector ( 31 downto 0);
 --signal   debug8  :  std_logic_vector ( 31 downto 0);
 --signal   debug50 :  std_logic_vector ( 31 downto 0);
 --signal   debug60 :  std_logic_vector ( 31 downto 0);


  -- No clks detected in port list. Replace <clk> below with 
  -- appropriate port name 

 constant clk_period : time := 10 ns;

 BEGIN

-- Instantiate the Unit Under Test (UUT)
 uut: behavioral_code PORT MAP (
      en => en,
      clk => clk,
     -- debug1 => debug1,
     -- debug10 => debug10,
     -- debug11 => debug11,
     -- debug2 => debug2,
      --debug3 => debug3,
      --debug4 => debug4,
      --debug5 => debug5,
      --debug6 => debug6,
      --debug7 => debug7,
      --debug8 => debug8,
      --debug50 => debug50,
      --debug60 => debug60,
      hist => hist,
      thres  => thres
    );

  clk_process :process
  begin
 clk <= '0';
 wait for clk_period/2;
 clk <= '1';
 wait for clk_period/2;
  end process;


  -- Stimulus process
  stim_proc: process
  begin     
  -- hold reset state for 100 ns.
  wait for 10 ns;
        en<='1';

  --wait for <clk>_period*10;

  -- insert stimulus here 

  wait;
 end process;

 END;
4

2 回答 2

1

请注意,综合会从您的代码中生成硬件。该代码看起来好像只是“软件编程”而不是用于综合;-) 例如,VHDL“for循环”在块内生成代码多次。因此,您的代码会产生非常大的设计。考虑以更顺序的方式重写代码。用一个

if rising_edge(clk) then

在您使用 FF 阶段的过程中。

顺便说一句:如果您使用常量对其进行测试,您的合成器工具很可能会为您完成除法并执行结果;这就是为什么它使用常量!

于 2013-05-17T17:47:32.017 回答
1

按照 Baldy 的回答中关于提供丢失的时钟边缘语句的建议,并对丢失的包的内容进行猜测,我发现您省略了提供“除法”功能。

所以,恢复内在分裂,让我们看看综合报告:

    =========================================================================
    Advanced HDL Synthesis Report

    Macro Statistics
    # Multipliers                                          : 2072
     31x2-bit multiplier                                   : 1
     31x3-bit multiplier                                   : 3
     31x4-bit multiplier                                   : 7
     31x5-bit multiplier                                   : 15
     32x32-bit multiplier                                  : 1986
     33x32-bit multiplier                                  : 60
    # Adders/Subtractors                                   : 4349
     32-bit adder                                          : 1373
     32-bit adder carry in                                 : 1984
     32-bit subtractor                                     : 992
    # Adder Trees                                          : 88
     32-bit / 10-inputs adder tree                         : 1
   ...
     32-bit / 7-inputs adder tree                          : 1
     32-bit / 8-inputs adder tree                          : 1
     32-bit / 9-inputs adder tree                          : 1
    # Registers                                            : 96
     Flip-Flops                                            : 96
    # Comparators                                          : 2077
     32-bit comparator greater                             : 31
     32-bit comparator lessequal                           : 62
   ...
     64-bit comparator lessequal                           : 62
    # Multiplexers                                         : 61721
     1-bit 2-to-1 multiplexer                              : 61536
     32-bit 2-to-1 multiplexer                             : 185

    =========================================================================

然后继续尝试优化需要相当长的时间。但真正的综合已经足够告诉你你需要知道的:这确实是一个非常大的设计;远远大于任务的合理性。

我只能同意他的建议,即您必须跨多个时钟周期重新组织计算,直到其大小可以接受。然后,合成时间也将减少到可接受的限度。

还有......只有 96 个触发器的所有逻辑?这是一个非常不平衡的设计,可能和糖蜜一样慢。流水线寄存器——其中很多——将需要达到可接受的性能。

于 2013-05-19T18:24:31.847 回答