使用LUT生成高延迟的输出成本

时间:2017-04-22 09:16:02

标签: vhdl synthesis

我正在设计一种采用LUT生成输出的架构。代码如下。

with resolvedOS select outBits <=
        (37 => parse(6), 36 => parse(5), 35 => parse(4), 34 => parse(3), 33 => parse(2), 32 => parse(1), 31 => parse(0), others => '0') when "00000",
        (37 => parse(6), 36 => not parse(6), 35 => parse(5), 34 => parse(4), 33 => parse(3), 32 => parse(2), 31 => parse(1), 30 => parse(0), others => '0') when "00001",
        (37 => parse(6), 36 downto 35 => not parse(6), 34 => parse(5), 33 => parse(4), 32 => parse(3), 31 => parse(2), 30 => parse(1), 29 => parse(0), others => '0') when "00010",
        (37 => parse(6), 36 downto 34 => not parse(6), 33 => parse(5), 32 => parse(4), 31 => parse(3), 30 => parse(2), 29 => parse(1), 28 => parse(0), others => '0') when "00011",
        (37 => parse(6), 36 downto 33 => not parse(6), 32 => parse(5), 31 => parse(4), 30 => parse(3), 29 => parse(2), 28 => parse(1), 27 => parse(0), others => '0') when "00100",
        (37 => parse(6), 36 downto 32 => not parse(6), 31 => parse(5), 30 => parse(4), 29 => parse(3), 28 => parse(2), 27 => parse(1), 26 => parse(0), others => '0') when "00101",
        (37 => parse(6), 36 downto 31 => not parse(6), 30 => parse(5), 29 => parse(4), 28 => parse(3), 27 => parse(2), 26 => parse(1), 25 => parse(0), others => '0') when "00110",
        (37 => parse(6), 36 downto 30 => not parse(6), 29 => parse(5), 28 => parse(4), 27 => parse(3), 26 => parse(2), 25 => parse(1), 24 => parse(0), others => '0') when "00111",
        (37 => parse(6), 36 downto 29 => not parse(6), 28 => parse(5), 27 => parse(4), 26 => parse(3), 25 => parse(2), 24 => parse(1), 23 => parse(0), others => '0') when "01000",
        (37 => parse(6), 36 downto 28 => not parse(6), 27 => parse(5), 26 => parse(4), 25 => parse(3), 24 => parse(2), 23 => parse(1), 22 => parse(0), others => '0') when "01001",
        (37 => parse(6), 36 downto 27 => not parse(6), 26 => parse(5), 25 => parse(4), 24 => parse(3), 23 => parse(2), 22 => parse(1), 21 => parse(0), others => '0') when "01010",
        (37 => parse(6), 36 downto 26 => not parse(6), 25 => parse(5), 24 => parse(4), 23 => parse(3), 22 => parse(2), 21 => parse(1), 20 => parse(0), others => '0') when "01011",
        (37 => parse(6), 36 downto 25 => not parse(6), 24 => parse(5), 23 => parse(4), 22 => parse(3), 21 => parse(2), 20 => parse(1), 19 => parse(0), others => '0') when "01100",
        (37 => parse(6), 36 downto 24 => not parse(6), 23 => parse(5), 22 => parse(4), 21 => parse(3), 20 => parse(2), 19 => parse(1), 18 => parse(0), others => '0') when "01101",
        (37 => parse(6), 36 downto 23 => not parse(6), 22 => parse(5), 21 => parse(4), 20 => parse(3), 19 => parse(2), 18 => parse(1), 17 => parse(0), others => '0') when "01110",
        (37 => parse(6), 36 downto 22 => not parse(6), 21 => parse(5), 20 => parse(4), 19 => parse(3), 18 => parse(2), 17 => parse(1), 16 => parse(0), others => '0') when "01111",
        (37 => parse(6), 36 downto 21 => not parse(6), 20 => parse(5), 19 => parse(4), 18 => parse(3), 17 => parse(2), 16 => parse(1), 15 => parse(0), others => '0') when "10000",
        (37 => parse(6), 36 downto 20 => not parse(6), 19 => parse(5), 18 => parse(4), 17 => parse(3), 16 => parse(2), 15 => parse(1), 14 => parse(0), others => '0') when "10001",
        (37 => parse(6), 36 downto 19 => not parse(6), 18 => parse(5), 17 => parse(4), 16 => parse(3), 15 => parse(2), 14 => parse(1), 13 => parse(0), others => '0') when "10010",
        (37 => parse(6), 36 downto 18 => not parse(6), 17 => parse(5), 16 => parse(4), 15 => parse(3), 14 => parse(2), 13 => parse(1), 12 => parse(0), others => '0') when "10011",
        (37 => parse(6), 36 downto 17 => not parse(6), 16 => parse(5), 15 => parse(4), 14 => parse(3), 13 => parse(2), 12 => parse(1), 11 => parse(0), others => '0') when "10100",
        (37 => parse(6), 36 downto 16 => not parse(6), 15 => parse(5), 14 => parse(4), 13 => parse(3), 12 => parse(2), 11 => parse(1), 10 => parse(0), others => '0') when "10101",
        (37 => parse(6), 36 downto 15 => not parse(6), 14 => parse(5), 13 => parse(4), 12 => parse(3), 11 => parse(2), 10 => parse(1), 9 => parse(0), others => '0') when "10110",
        (37 => parse(6), 36 downto 14 => not parse(6), 13 => parse(5), 12 => parse(4), 11 => parse(3), 10 => parse(2), 9 => parse(1), 8 => parse(0), others => '0') when "10111",
        (37 => parse(6), 36 downto 13 => not parse(6), 12 => parse(5), 11 => parse(4), 10 => parse(3), 9 => parse(2), 8 => parse(1), 7 => parse(0), others => '0') when "11000",
        (37 => parse(6), 36 downto 12 => not parse(6), 11 => parse(5), 10 => parse(4), 9 => parse(3), 8 => parse(2), 7 => parse(1), 6 => parse(0), others => '0') when "11001",
        (37 => parse(6), 36 downto 11 => not parse(6), 10 => parse(5), 9 => parse(4), 8 => parse(3), 7 => parse(2), 6 => parse(1), 5 => parse(0), others => '0') when "11010",
        (37 => parse(6), 36 downto 10 => not parse(6), 9 => parse(5), 8 => parse(4), 7 => parse(3), 6 => parse(2), 5 => parse(1), 4 => parse(0), others => '0') when "11011",
        (37 => parse(6), 36 downto 9 => not parse(6), 8 => parse(5), 7 => parse(4), 6 => parse(3), 5 => parse(2), 4 => parse(1), 3 => parse(0), others => '0') when "11100",
        (37 => parse(6), 36 downto 8 => not parse(6), 7 => parse(5), 6 => parse(4), 5 => parse(3), 4 => parse(2), 3 => parse(1), 2 => parse(0), others => '0') when "11101",
        (37 => parse(6), 36 downto 7 => not parse(6), 6 => parse(5), 5 => parse(4), 4 => parse(3), 3 => parse(2), 2 => parse(1), 1 => parse(0), others => '0') when "11110",
        (37 => parse(6), 36 downto 6 => not parse(6), 5 => parse(5), 4 => parse(4), 3 => parse(3), 2 => parse(2), 1 => parse(1), 0 => parse(0)) when others;

通常情况下,LUT不会占用很多延迟,但对于这一点,合成结果会产生非常高的延迟。该设计在Synopsis DC中编译,使用NANGATE 45nm。

U619/ZN (NAND2_X1)                                      0.05       0.67 f
  U618/ZN (INV_X1)                                        0.04       0.72 r
  U613/ZN (OAI21_X1)                                      0.03       0.75 f
  U612/ZN (OAI21_X1)                                      0.04       0.79 r
  U610/ZN (XNOR2_X1)                                      0.07       0.86 r
  U607/ZN (NAND3_X1)                                      0.09       0.95 f
  U565/ZN (OAI211_X1)                                     0.11       1.06 r
  U564/ZN (INV_X1)                                        0.08       1.13 f
  U563/ZN (NAND2_X1)                                      0.09       1.22 r
  U562/ZN (INV_X1)                                        0.06       1.28 f
  U561/ZN (NAND2_X1)                                      0.08       1.36 r
  U534/ZN (NAND2_X1)                                      0.04       1.41 f
  U531/ZN (OR2_X1)                                        0.06       1.47 f
  U528/ZN (NOR2_X1)                                       0.05       1.52 r
  U521/ZN (NAND2_X1)                                      0.04       1.55 f
  U480/ZN (NOR2_X1)                                       0.05       1.60 r
  U474/ZN (NAND2_X1)                                      0.04       1.64 f
  U465/ZN (NOR2_X1)                                       0.05       1.69 r
  U458/ZN (NAND2_X1)                                      0.04       1.72 f
  U449/ZN (OAI21_X1)                                      0.05       1.77 r
  U448/ZN (OAI21_X1)                                      0.03       1.80 f
  U447/ZN (AOI221_X1)                                     0.09       1.89 r
  U446/ZN (OAI211_X1)                                     0.04       1.93 f
  outBits[15] (out)                                       0.00       1.93 f
  data arrival time                                                  1.93

你们能解释一下为什么这个会有如此高的延迟吗?或者建议我使用其他一些输出延迟较小的方法?

1 个答案:

答案 0 :(得分:2)

我不知道你的代码中有parse,但我怀疑这是问题所在。 为什么不把所有值都放到正确类型的数组中?我最近这样做了,它起作用了:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity lut is

port (
   address_i : in integer range 0 to 255;
   data_o    : out std_logic_vector(31 downto 0)
);
end lut;

architecture Behavioral of lut is

type rom_t is array (0 to 255) of std_logic_vector(31 downto 0);
    signal rom: rom_t := (
    x"00000000", x"0000005f", x"00000064", x"0000006a", 
    x"00000071", x"00000077", x"0000007e", x"00000086", 
    x"0000008e", x"00000096", x"0000009f", x"000000a9", 
    (...)
    x"0aa4951c", x"0b46062d", x"0bf10824", x"0ca62c1d"
);

begin

data_o <= rom(address_i);

end Behavioral;

如果您不喜欢端口实体中的整数,可以使用vector,并将其更改为实体内的整数。