-4

「強力な」ソルバーには難しい質問があります。

この質問の最後に示されている VHDL 動作コードを合成しようとしています。

ラインを使ったとき

m1Low := m1Low/m0Low;

回路は正しい結果を合成して生成していました。ただし、これは特定の入力に対するものであり、コード内で定数として固定されていました。入力が回路の外部からの信号 (ここでは具体的には std_logic_vector の配列である入力ヒスト) として来る場合、これはもう合成されません。/ を除算関数に置き換える必要があります。

m1Low := to_integer(divide(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 に答える