试图在VHDL中找到Fmax,但获得额外的延迟周期

时间:2016-07-26 12:52:11

标签: vhdl intel-fpga quartus

我希望看到我的VHDL设计的速度。据我所知,Quartus II软件中的Fmax表示了它。编译完我的设计后,它显示出一个653.59 MHz的Fmax。我编写了一个测试平台并进行了一些测试,以确保设计按预期工作。我对设计的问题是,在时钟的上升沿,输入设置正确,但输出仅在一个周期之后出现。

我的问题是:如何检查我的设计速度(输入端口和输出端口之间的最长延迟),并在输入加载/同一周期的同时获得加法的输出?

我的测试平台结果如下:

a:0001和b:0101给出XXXX
a:1001和b:0001给出0110(前一个的预期结果 计算)
a:1001和b:1001给出1010(前一个的预期结果 计算)

代码:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity adder is 
    port( 
        clk : in STD_LOGIC; 
        a : in unsigned(3 downto 0); 
        b : in unsigned(3 downto 0); 
        sum : out unsigned(3 downto 0)
    );  
end adder; 

architecture rtl of adder is 

signal a_r, b_r, sum_r : unsigned(3 downto 0); 

begin 
    sum_r <= a_r + b_r; 
    process(clk) 
    begin 
        if (rising_edge(clk)) then 
            a_r <= a;
            b_r <= b;
            sum <= sum_r;
        end if; 
    end process;
end rtl; 

测试平台:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity testbench is
end entity;

architecture behavioral of testbench is
    component adder is
        port( 
            clk : in STD_LOGIC; 
            a : in unsigned(3 downto 0); 
            b : in unsigned(3 downto 0); 
            sum : out unsigned(3 downto 0)
        ); 
    end component;
    signal a, b, sum : unsigned(3 downto 0);
    signal clk : STD_LOGIC;
begin
    uut: adder
        port map(
            clk => clk,
            a => a,
            b => b,
            sum => sum
        );
    stim_process : process
    begin
        wait for 1 ns;
        clk <= '0';
        wait for 1 ns;
        clk <= '1';
        a <= "0001";
        b <= "0101";
        wait for 1 ns;
        clk <= '0';
        wait for 1 ns;
        clk <= '1';
        a <= "1001";
        b <= "0001";
        wait for 1 ns;
        clk <= '0';
        wait for 1 ns;
        clk <= '1';
        a <= "1001";
        b <= "1001";
    end process;
end behavioral;

1 个答案:

答案 0 :(得分:1)

使用sum_r作为输出有什么问题吗?

如果将此ALU视为纯组合逻辑,则不需要输入和输出寄存器。一旦你删除了Fmax,它们就会消失,然后依赖它,它连接的是什么以及它连接的是什么,只有来自寄存器和传出寄存器才是寄存器。如果它只是从输入引脚到输出引脚和输出引脚的逻辑,我认为很难说传播延迟是什么,像Altera和其他现代供应商这样的供应商软件没有适合这种类型的工具。分析

这就是为什么你会听到人们谈论设计异步逻辑中的困难。

我认为这种精细分析难以确定和准确地执行。因为对你而言,传播延迟将以皮秒为单位。甚至文献也很难找到关于传播延迟的任何定量答案。

为什么这很困难?请记住,传播延迟是由总路径电容决定的,有一种方法可以估算晶体管的传播延迟,但我不知道LUT如何在内部构造的深层细节,所以我不能给你一个好的估计。因此,它在很大程度上取决于系列,制造过程,FPGA的构造以及负载是否连接到IO。

然而,您可以通过转到逻辑规划器进行自己的估算,查看路径并假设每个LUT传输的传播延迟大约为20-100ps

见下图。

enter image description here

您要设计的是ALU。根据定义,ALU理论上应该只是一个组合逻辑。

因此,严格地说,您的加法器代码应该只是这个。

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity adder is 
    port( 
        a : in unsigned(3 downto 0); 
        b : in unsigned(3 downto 0); 
        sum : out unsigned(3 downto 0)
    );  
end adder; 

architecture rtl of adder is 
begin 
    sum <= a + b; 
end rtl; 

由于此功能实际上是一个组合过程,因此不需要时钟。

但是如果你想让你的ALU进入我所描述的阶段,你应该做的事实上就是这个

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity adder is 
    port( 
        clk : in STD_LOGIC; 
        a : in unsigned(3 downto 0); 
        b : in unsigned(3 downto 0); 
        sum : out unsigned(3 downto 0)
    );  
end adder;

architecture rtl of adder is 

signal a_r, b_r, sum_r : unsigned(3 downto 0); 
signal internal_sum : unsigned(3 downto 0);

begin 
    sum <= sum_r;
    internal_sum <= a_r + b_r; 

    process(clk) 
    begin 
        if (rising_edge(clk)) then 
            a_r <= a;
            b_r <= b;
            sum_r <= internal_sum;
        end if; 
    end process;
end rtl; 

你没有提到过执行,所以我不会在这里讨论。

最后,如果你正在使用Altera,他们有一个非常好的RTL查看器,你可以看看你的综合设计。在工具 - &gt;网表查看器 - &gt;下RTL Viewer。