对于“强势”解决者,我有一个棘手的问题:
我正在尝试合成VHDL行为代码,该代码显示在本问题的最后。
当我使用
行时m1Low:= m1Low / m0Low;
该电路正在合成并产生正确的结果。但是,这是针对给定的输入,在代码中固定为常量。当输入来自电路外部的信号(这里特别是输入hist是一个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;
答案 0 :(得分:1)
请注意,综合会从您的代码中生成硬件。代码看起来好像只是&#34;软件编程&#34;而不是用于合成;-) 例如一个VHDL&#34; for循环&#34;多次在块中生成代码。因此,您的代码会产生一个大型设计。考虑以更顺序的方式重写代码。使用
if rising_edge(clk) then
在您使用FF阶段的过程中。
BTW:如果你用常量测试它,你的合成器工具很可能为你做了除法并且只是实现了结果;这就是为什么它与常数一起工作的原因!答案 1 :(得分: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个触发器的所有逻辑?这是一种非常不平衡的设计,可能和糖蜜一样慢。管道寄存器 - 很多 - 都需要达到可接受的性能。