全球布局阶段8.8无限期运行,Xilinx

时间:2013-11-20 09:37:44

标签: hardware vhdl fpga xilinx

我再次与Xilinx工具进行战斗。我在PlanAhead-14.7中运行Zynq7020上的设计实现。该设计在PL上使用大约15-20%的设备利用率,实施过程似乎停留在全球布局上,到目前为止已经运行了12个多小时(并且仍在运行),我只期望最多一小时,这是非常不方便,因为我需要在星期五之前设计和测试这个设计,这让我感觉很干,因为任何改进都需要12小时+再次放置!

我正在使用64位14.7设计套件,并且读到以前的版本对64位工具有类似的问题。我有什么办法可以加快全球布局吗?我已经检查过所有的放置标志都设置为尽可能快地放置。

- 更新2-- 我现在处于精神错乱的边缘,因此这是整个过程(以及Brian提到的设计改进),这让我感到悲伤,并且它与使用state = fwrd_init和state = bkwrd_init <的OR语句有关。 / p>

input : process(clk, rst, dz_ready, row_ready, d_div_stts, counter, bkwrd_stts, state, cd_empty, zd_empty) 
    begin
        if(clk'event and clk='1') then 
        stack_en <='0';
        bkwrd_drdy <= '0';
        d_rdy <= '0';
        dz_read <='0';
        read_row <='0';
        result_ready <='0';
        --delay dz_ready by one clock to correctly sync with  other signals
        dz_ready_p <= dz_ready;

        --d and z register read and write logic--
        if (state = fwrd_init or rst = '1' ) then
                -- reset to all 1's so the initial division a_n/d_(n-1) = 0 ; a=0, n=0
                d_reg <= (others=>'1');
                z_reg <= (others=>'0');
                dz_ready <= '0';
            elsif(d_stts = '1') then
                d_reg <= d_out;
                z_reg <= z_out;
                dz_ready <= '1';
        end if;

        --fwrd it logic---
        if (dz_ready = '1' or state = fwrd_init) then
            if(row_ready = '1') then
                d_rdy <= '1' ;
                dz_read <='1';
                read_row <= '1';
                dz_ready <='0';
                --register the c value
            end if;
        end if;

        --bkwrd it logic and stack logic -- read has priority over push
        if(bkwrd_stts = '1' or state = bkwrd_init) then
            if (cd_empty = '0' and zd_empty = '0') then
                bkwrd_drdy <= '1';
                 --pop from stack 
                stack_en <= '1';
                stack_pshp <= '0';
            end if;
        end if;

        --Set initial values        
        if(state = bkwrd_init) then
           bkwrd_v <= (others=>'0');
        else
            bkwrd_v <= result;
        end if;

        --Drive result output from the bkwrd iteration
        if(bkwrd_stts = '1') then
            result_ready <= '1';
            x <= result;
        else
            x <= (others=>'0');
        end if;

      if(d_div_stts = '1' and state = fwrd_it) then
            counter <= counter_next;
    --push data onto the stack 
            stack_en <='1';
            stack_pshp <='1';
            stack_din <= cd;
            zdstck_din <= zd;
        end if;
--      
        ---NEXT STATE LOGIC---
        case state is
                when idle => 
                                if (row_ready = '1') then
                                    state <= fwrd_init ;
                                 end if;

                when fwrd_init => 
                                state <= fwrd_it;

                when fwrd_it => 

                                if (counter = N) then
                                    state <= bkwrd_init;
                                else
                                    state <= fwrd_it;
                                end if;

                when bkwrd_init => 
                                state <= bkwrd_it;
                when bkwrd_it =>
                                    if(cd_empty = '1' and zd_empty = '1') then
                                        state <= idle;
                                    else
                                        state <= bkwrd_it;
                                    end if;
                when others => NULL;
            end case;
        end if;

    end process;

所有其他信号由同一时钟域内的其他同步模块驱动,因为这是我设计的主要路由逻辑。

但如果我将OR更改为AND,则运行全局放置很好。显然,对于我的设计而言,而不是ors将不起作用,那么为什么它会显示这种行为呢? (我已经扩展了原来的单行if语句也没有用)

萨姆

3 个答案:

答案 0 :(得分:2)

放宽主时间约束。如果您的目标(和当前约束)是200MHz,则运行P&amp; R 50 MHz。可能需要几分钟而不是几小时。

结果似乎没用,因为它太慢了:现阶段的重点是找到

  • 如果P&amp; R完全适用于您的设计
  • 最慢的路径。

随着设计对于时序约束而言太紧,工具会大幅减速。 (它在工具版本之间有所不同,而较新的版本通常会更好,但你可能遇到了一个病态的情况,工具只是不知道放弃的地方)。

无论如何;假设松弛的P&amp; R在(例如)78 MHz处给出结果,您还将获得最慢路径的详细信息;重新管理此路径并再次尝试,在改进设计时推动约束。

如果没有,马丁已经很好地覆盖了其他几个基地。

编辑更新后的问题:

这些“if”语句本身没有任何内在错误:错误必须在别处,但在此表现出来。

当然,如果这些陈述是时钟流程的一部分,特别是如果这是SM的“单一流程”风格,那么我希望这会起作用。如果它是一个单独的非时钟过程,则存在大量不当行为的空间。

(评论只是突然说这是一个时钟进程:我不相信它是主SM的一部分,因为我看不到状态分配)

怀疑这些if表达式的所有输入;特别是and工作的地方。这些是非时钟信号中的任何信号,还是来自其他时钟域的信号?我开始怀疑。如果是这样的话,可能会有一些不可思议的紧张时间随and消失,因为关键术语可以通过逻辑最小化来消除。

这里的Asynch输入无效。

将它们重新同步到此时钟域,然后将它们送入比锁定之前的OR门更复杂的任何东西。如有必要,将信号输出到另一个时钟域并消除那里的冲突。

设计不添加时钟周期或两个延迟的复杂重新同步器是HARD。 Xilinx FPGA提供异步FIFOS作为替代方案,因此大多数人不必......

这些只是基于猜测的指导原则...希望他们有所帮助。

我会添加if (some cond ) if some cond可能if dz_ready = '1' or state = fwrd_init then的次要挑剔,但不会产生混乱,但这与手头的问题无关。

再次编辑(试图跟上问题:-)
第二个过程是非时钟的:你可以消除它并写入 dz_ready 但如果另一个术语input : process(clk) begin if rising_edge(clk) then if rst = '1' then -- reset to all all 1's so the initial division a_n/d_(n-1) = 0 ; a=0, n=0 d_reg <= (others=>'1'); z_reg <= (others=>'0'); dz_ready <= '0'; -- state <= ???; -- Good idea to define initial state here else -- default assignments, overridden where necessary stack_en <='0'; bkwrd_drdy <= '0'; d_rdy <= '0'; dz_read <='0'; read_row <='0'; result_ready <='0'; --delay dz_ready by one clock to correctly sync with other signals dz_ready_p <= dz_ready; bkwrd_v <= result; -- will be overridden in bkwrd_init if d_stts = '1' then -- will be overridden in fwrd_init d_reg <= d_out; z_reg <= z_out; dz_ready <= '1'; end if; --fwrd it logic--- if dz_ready = '1' then if row_ready = '1' then d_rdy <= '1' ; dz_read <='1'; read_row <= '1'; dz_ready <='0'; --register the c value end if; end if; --bkwrd it logic and stack logic -- read has priority over push if bkwrd_stts = '1' then if cd_empty = '0' and zd_empty = '0' then bkwrd_drdy <= '1'; --pop from stack stack_en <= '1'; stack_pshp <= '0'; end if; result_ready <= '1'; x <= result; else x <= (others=>'0'); end if; -- STATE LOGIC -- case state is when idle => if (row_ready = '1') then state <= fwrd_init ; end if; when fwrd_init => -- actions d_reg <= (others=>'1'); z_reg <= (others=>'0'); dz_ready <= '0'; if(row_ready = '1') then d_rdy <= '1' ; dz_read <='1'; read_row <= '1'; dz_ready <='0'; --register the c value end if; -- state state <= fwrd_it; when fwrd_it => if d_div_stts = '1' then counter <= counter_next; --push data onto the stack stack_en <='1'; stack_pshp <='1'; stack_din <= cd; zdstck_din <= zd; end if; if (counter = N) then state <= bkwrd_init; end if; when bkwrd_init => if cd_empty = '0' and zd_empty = '0' then bkwrd_drdy <= '1'; --pop from stack stack_en <= '1'; stack_pshp <= '0'; end if; bkwrd_v <= (others=>'0'); state <= bkwrd_it; when bkwrd_it => if(cd_empty = '1' and zd_empty = '1') then state <= idle; end if; when others => NULL; end case; end if; end if; end process; 是异步的,那将无济于事。

我冒昧地将流程重写为更常见的“单一流程SM”形式。它的行为(我很确定)与原作相当,但它暴露了一些奇怪的动作重复,这在风格上是不寻常的。这可能会让你看到一些无意识的东西,或者可能不那么混淆综合工具。 (在状态fwrd_init中对dz_ready的双重赋值可能是无害的,但看起来很可疑!)

{{1}}

答案 1 :(得分:2)

通过将逻辑移动到case语句中来修复逻辑之后,实际上看起来很长的放置时间是由于Coregen 3.0分频器中仍然存在的错误。 http://forums.xilinx.com/t5/Implementation/divider-generator-3-0-problem-with-Virtex-6/m-p/230379#M4737

答案 2 :(得分:1)

你能试试32位工具吗?

另一件令人想到的事情是,这种行为通常来自一个你曾期望在BlockRAM中实现的大内存,但由于某种原因,编译器决定用LUT和触发器来做。

  • 检查您的综合日志文件中是否有您希望有RAM的模块。
  • 检查技术视图,看看您期望的RAM是否存在
  • 在FPGA编辑器中检查MAP后网表(或Planahead,我忘了你是否可以在MAP后进行)

太痛苦了!


现在您已经隔离了一些代码,您是否可以仅合成该模块(因此模块IO成为引脚)。无论是内部还是外部,这可能会缩小范围。您有时也可以在该级别更轻松地跟踪RTL查看器中的信号。