VHDL 布局布线路径分析
VHDL Place and route path analysis
我的问题是,当我使用 Xilinx ISE 14.7 + XPS 实现我的设计时,我经常在静态时序分析中获得非常不同数量的分析路径,在 .vhd 文件中也几乎没有差异。
特别是,我更改(或我想更改...)的唯一文件类似于:
entity my_entity is(
...
data_in : in std_logic_vector(N*B-1 downto 0);
...
);
end entity my_entity;
architecture bhv of my_entity is
signal data : std_logic_vector(B-1 downto 0);
signal idx_vect : std_logic_vector(log2(N)-1 downto 0);
signal idx : integer range 0 to N-1;
...
begin
process(clk)
begin
if(rising_edge(clk))then
idx_vect <= idx_vect + 1;
end if;
end process;
idx <= to_integer(unsigned(idx_vect));
data <= data_in((idx+1)*B-1 downto idx*B);
end architecture bhv;
我不确定问题出在哪里,但我没有找到任何其他可能导致分析路径数量减少五倍的原因。为了获得正确的实现,是否有一些必须避免的语法?是否有可能使用整数索引数组(如示例编解码器中所示)以某种方式分解路径,使它们不被分析?
代码更改如下:
process(shift_reg, data_in)
for i in range 0 to N-1 loop
if(shift_reg(i) = '1')then
data <= data_in((i+1)*B-1 downto i*B);
end if;
end loop;
end process;
其中我有一个 N 位循环单热移位寄存器,而不是递增 idx_vect。
提前致谢。
该行多路复用器的编码风格
data <= data_in((idx+1)*B-1 downto idx*B);
会严重影响逻辑综合。这导致要分析时序的路径数量非常不同。
原始多路复用器
我首先用这个小例子检查了上面那行的合成:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux1 is
generic (
B : positive := 32;
M : positive := 7); -- M := ceil(log_2 N)
port (
d : in STD_LOGIC_VECTOR ((2**M)*B-1 downto 0); -- input data
s : in STD_LOGIC_VECTOR (M-1 downto 0); -- selector
y : out STD_LOGIC_VECTOR(B-1 downto 0)); -- result
end mux1;
architecture Behavioral of mux1 is
constant N : positive := 2**M;
signal idx : integer range 0 to N-1;
begin
idx <= to_integer(unsigned(s));
y <= d((idx+1)*B-1 downto idx*B);
end Behavioral;
如果有人为 Spartan-6 合成这个,XST 会报告这个(摘录):
Macro Statistics
# Adders/Subtractors : 2
13-bit subtractor : 1
8-bit adder : 1
...
Number of Slice LUTs: 1516 out of 5720 26%
...
Timing constraint: Default path analysis
Total number of paths / destination ports: 139264 / 32
因此,没有检测到多路复用器,时序分析器必须分析大量路径。
逻辑利用率还可以。
优化实施
可以通过以下方式实现相同的多路复用:(编辑:错误修正和简化)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux2 is
generic (
B : positive := 32;
M : positive := 7); -- M := ceil(log_2 N)
port (
d : in STD_LOGIC_VECTOR ((2**M)*B-1 downto 0);
s : in STD_LOGIC_VECTOR (M-1 downto 0);
y : out STD_LOGIC_VECTOR(B-1 downto 0));
end mux2;
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-- !! The entire architecture has been FIXED and simplified. !!
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
architecture Behavioral of mux2 is
constant N : positive := 2**M;
type matrix is array (N-1 downto 0) of std_logic_vector(B-1 downto 0);
signal dd : matrix;
begin
-- reinterpret 1D vector 'd' as 2D matrix, i.e.
-- row 0 holds d(B-1 downto 0) which is selected in case s = 0
row_loop: for row in 0 to N-1 generate
dd(row) <= d((row+1)*B-1 downto row*B);
end generate;
-- select the requested row
y <= dd(to_integer(unsigned(s)));
end Behavioral;
现在,XST 报告看起来好多了:
Macro Statistics
# Multiplexers : 1
32-bit 128-to-1 multiplexer : 1
...
Number of Slice LUTs: 1344 out of 5720 23%
...
Timing constraint: Default path analysis
Total number of paths / destination ports: 6816 / 32
它检测到每个输出位都需要一个 128 比 1 的多路复用器。这种宽多路复用器的优化合成内置于合成工具中。 LUT 的数量仅略有减少。但是,时序分析器要处理的路径数量显着减少 20 倍!
使用单热选择器实现
以上示例使用二进制编码的选择器信号。
我还检查了单热编码的变体:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux3 is
generic (
B : positive := 32;
N : positive := 128);
port ( d : in STD_LOGIC_VECTOR (N*B-1 downto 0);
s : in STD_LOGIC_VECTOR (N-1 downto 0);
y : out STD_LOGIC_VECTOR(B-1 downto 0));
end mux3;
architecture Behavioral of mux3 is
begin
process(d, s)
begin
y <= (others => '0'); -- avoid latch!
for i in 0 to N-1 loop
if s(i) = '1' then
y <= d((i+1)*B-1 downto i*B);
end if;
end loop;
end process;
end Behavioral;
现在,XST 报告又不一样了:
Macro Statistics
# Multiplexers : 128
32-bit 2-to-1 multiplexer : 128
...
Number of Slice LUTs: 2070 out of 5720 36%
...
Timing constraint: Default path analysis
Total number of paths / destination ports: 13376 / 32
检测到 2 对 1 多路复用器,因为描述了类似于此方案的优先多路复用器:
if s(127) = '1' then
y <= d(128*B-1 downto 127*B);
else
if s(126) = '1' then
y <= d(127*B-1 downto 126*B);
else
...
if s(0) = '1' then
y <= d(B-1 downto 0);
else
y <= (others => '0');
end if;
end if; -- s(126)
end if; -- s(127)
出于教学原因,我没有在这里使用 elsif
。每个 if-else
级都是一个 32 位宽的 2 对 1 多路复用器。这里的问题是,综合不知道 s
是一个单热编码信号。因此,在我的优化实现中需要更多的逻辑。
分析时序的路径数量再次发生显着变化。
该数字比原始实现低 10 倍,但比我优化后的高 2 倍。
我的问题是,当我使用 Xilinx ISE 14.7 + XPS 实现我的设计时,我经常在静态时序分析中获得非常不同数量的分析路径,在 .vhd 文件中也几乎没有差异。 特别是,我更改(或我想更改...)的唯一文件类似于:
entity my_entity is(
...
data_in : in std_logic_vector(N*B-1 downto 0);
...
);
end entity my_entity;
architecture bhv of my_entity is
signal data : std_logic_vector(B-1 downto 0);
signal idx_vect : std_logic_vector(log2(N)-1 downto 0);
signal idx : integer range 0 to N-1;
...
begin
process(clk)
begin
if(rising_edge(clk))then
idx_vect <= idx_vect + 1;
end if;
end process;
idx <= to_integer(unsigned(idx_vect));
data <= data_in((idx+1)*B-1 downto idx*B);
end architecture bhv;
我不确定问题出在哪里,但我没有找到任何其他可能导致分析路径数量减少五倍的原因。为了获得正确的实现,是否有一些必须避免的语法?是否有可能使用整数索引数组(如示例编解码器中所示)以某种方式分解路径,使它们不被分析?
代码更改如下:
process(shift_reg, data_in)
for i in range 0 to N-1 loop
if(shift_reg(i) = '1')then
data <= data_in((i+1)*B-1 downto i*B);
end if;
end loop;
end process;
其中我有一个 N 位循环单热移位寄存器,而不是递增 idx_vect。 提前致谢。
该行多路复用器的编码风格
data <= data_in((idx+1)*B-1 downto idx*B);
会严重影响逻辑综合。这导致要分析时序的路径数量非常不同。
原始多路复用器
我首先用这个小例子检查了上面那行的合成:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux1 is
generic (
B : positive := 32;
M : positive := 7); -- M := ceil(log_2 N)
port (
d : in STD_LOGIC_VECTOR ((2**M)*B-1 downto 0); -- input data
s : in STD_LOGIC_VECTOR (M-1 downto 0); -- selector
y : out STD_LOGIC_VECTOR(B-1 downto 0)); -- result
end mux1;
architecture Behavioral of mux1 is
constant N : positive := 2**M;
signal idx : integer range 0 to N-1;
begin
idx <= to_integer(unsigned(s));
y <= d((idx+1)*B-1 downto idx*B);
end Behavioral;
如果有人为 Spartan-6 合成这个,XST 会报告这个(摘录):
Macro Statistics
# Adders/Subtractors : 2
13-bit subtractor : 1
8-bit adder : 1
...
Number of Slice LUTs: 1516 out of 5720 26%
...
Timing constraint: Default path analysis
Total number of paths / destination ports: 139264 / 32
因此,没有检测到多路复用器,时序分析器必须分析大量路径。 逻辑利用率还可以。
优化实施
可以通过以下方式实现相同的多路复用:(编辑:错误修正和简化)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux2 is
generic (
B : positive := 32;
M : positive := 7); -- M := ceil(log_2 N)
port (
d : in STD_LOGIC_VECTOR ((2**M)*B-1 downto 0);
s : in STD_LOGIC_VECTOR (M-1 downto 0);
y : out STD_LOGIC_VECTOR(B-1 downto 0));
end mux2;
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-- !! The entire architecture has been FIXED and simplified. !!
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
architecture Behavioral of mux2 is
constant N : positive := 2**M;
type matrix is array (N-1 downto 0) of std_logic_vector(B-1 downto 0);
signal dd : matrix;
begin
-- reinterpret 1D vector 'd' as 2D matrix, i.e.
-- row 0 holds d(B-1 downto 0) which is selected in case s = 0
row_loop: for row in 0 to N-1 generate
dd(row) <= d((row+1)*B-1 downto row*B);
end generate;
-- select the requested row
y <= dd(to_integer(unsigned(s)));
end Behavioral;
现在,XST 报告看起来好多了:
Macro Statistics
# Multiplexers : 1
32-bit 128-to-1 multiplexer : 1
...
Number of Slice LUTs: 1344 out of 5720 23%
...
Timing constraint: Default path analysis
Total number of paths / destination ports: 6816 / 32
它检测到每个输出位都需要一个 128 比 1 的多路复用器。这种宽多路复用器的优化合成内置于合成工具中。 LUT 的数量仅略有减少。但是,时序分析器要处理的路径数量显着减少 20 倍!
使用单热选择器实现
以上示例使用二进制编码的选择器信号。 我还检查了单热编码的变体:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux3 is
generic (
B : positive := 32;
N : positive := 128);
port ( d : in STD_LOGIC_VECTOR (N*B-1 downto 0);
s : in STD_LOGIC_VECTOR (N-1 downto 0);
y : out STD_LOGIC_VECTOR(B-1 downto 0));
end mux3;
architecture Behavioral of mux3 is
begin
process(d, s)
begin
y <= (others => '0'); -- avoid latch!
for i in 0 to N-1 loop
if s(i) = '1' then
y <= d((i+1)*B-1 downto i*B);
end if;
end loop;
end process;
end Behavioral;
现在,XST 报告又不一样了:
Macro Statistics
# Multiplexers : 128
32-bit 2-to-1 multiplexer : 128
...
Number of Slice LUTs: 2070 out of 5720 36%
...
Timing constraint: Default path analysis
Total number of paths / destination ports: 13376 / 32
检测到 2 对 1 多路复用器,因为描述了类似于此方案的优先多路复用器:
if s(127) = '1' then
y <= d(128*B-1 downto 127*B);
else
if s(126) = '1' then
y <= d(127*B-1 downto 126*B);
else
...
if s(0) = '1' then
y <= d(B-1 downto 0);
else
y <= (others => '0');
end if;
end if; -- s(126)
end if; -- s(127)
出于教学原因,我没有在这里使用 elsif
。每个 if-else
级都是一个 32 位宽的 2 对 1 多路复用器。这里的问题是,综合不知道 s
是一个单热编码信号。因此,在我的优化实现中需要更多的逻辑。
分析时序的路径数量再次发生显着变化。 该数字比原始实现低 10 倍,但比我优化后的高 2 倍。