4

我使用 xilinx 在 VHDL 中编写了 80c51 架构。为了增加时钟频率,我将所有 80c51 指令流水线化。指令能够根据需要执行,例如。当第一条指令被处理时,第二条指令被获取。

但是,尽管从综合报告中创建了 3 的流水线深度,但我只得到了稍高的时钟频率(大约 +/-10Hz)。我发现瓶颈是由于综合报告指定的一项操作,但我无法理解综合报告。

请问从 'SEQ/decode_3 到 SEQ/i_ram_addr_7' 的数据路径是什么?(根据我的猜测,我推断用例,when 语句检查 100 多个相关操作码,但不确定这是否是瓶颈。但我一无所知)

因此,我仅有的两个查询是:

首先,流水线是否可能不会增加时钟频率,而测试台是解释时序减少的唯一方法?

其次,我如何推断我的代码中的哪个路径是从“SEQ/decode_3 到 SEQ/i_ram_addr_7”的瓶颈。

感谢任何可以帮助解释我的疑问的人!

Timing Summary:
---------------
Speed Grade: -4

   Minimum period: 12.542ns (Maximum Frequency: 79.730MHz)
   Minimum input arrival time before clock: 10.501ns
   Maximum output required time after clock: 5.698ns
   Maximum combinational path delay: No path found

Timing Detail:
--------------
All values displayed in nanoseconds (ns)

=========================================================================
Timing constraint: Default period analysis for Clock 'clk'
  Clock period: 12.542ns (frequency: 79.730MHz)
  Total number of paths / destination ports: 113114 / 2670
-------------------------------------------------------------------------
Delay:               12.542ns (Levels of Logic = 10)
  Source:            SEQ/decode_3 (FF)
  Destination:       SEQ/i_ram_addr_7 (FF)
  Source Clock:      clk rising
  Destination Clock: clk rising

  Data Path: SEQ/decode_3 to SEQ/i_ram_addr_7
                                Gate     Net
    Cell:in->out      fanout   Delay   Delay  Logical Name (Net Name)
    ----------------------------------------  ------------
     FDC:C->Q            102   0.591   1.364  SEQ/decode_3 (SEQ/decode_3)
     LUT4_D:I1->O         10   0.643   0.885  SEQ/de_state_cmp_eq002111 (N314)
     LUT4:I3->O            7   0.648   0.740  SEQ/de_state_cmp_eq00711 (SEQ/de_state_cmp_eq0071)
     LUT4:I2->O            3   0.648   0.534  SEQ/i_ram_addr_mux0000<0>11111 (N2301)
     LUT4:I3->O            1   0.648   0.000  SEQ/i_ram_addr_mux0000<0>11270_SW0_SW0_F (N1284)
     MUXF5:I0->O           1   0.276   0.423  SEQ/i_ram_addr_mux0000<0>11270_SW0_SW0 (N955)
     LUT4_D:I3->O          6   0.648   0.701  SEQ/i_ram_addr_mux0000<0>11270 (SEQ/i_ram_addr_mux0000<0>11270)
     LUT3_L:I2->LO         1   0.648   0.103  SEQ/i_ram_addr_mux0000<7>221_SW2_SW0 (N1208)
     LUT4:I3->O            1   0.648   0.423  SEQ/i_ram_addr_mux0000<7>351_SW1 (N1085)
     LUT4:I3->O            1   0.648   0.423  SEQ/i_ram_addr_mux0000<7>2 (SEQ/i_ram_addr_mux0000<7>2)
     LUT4:I3->O            1   0.648   0.000  SEQ/i_ram_addr_mux0000<7>167 (SEQ/i_ram_addr_mux0000<7>)
     FDE:D                     0.252          SEQ/i_ram_addr_7
    ----------------------------------------
    Total                     12.542ns (6.946ns logic, 5.596ns route)
                                       (55.4% logic, 44.6% route)

=========================================================================
Timing constraint: Default OFFSET IN BEFORE for Clock 'clk'
  Total number of paths / destination ports: 154 / 154
-------------------------------------------------------------------------
Offset:              8.946ns (Levels of Logic = 6)
  Source:            rst (PAD)
  Destination:       SEQ/i_ram_diByte_1 (FF)
  Destination Clock: clk rising

  Data Path: rst to SEQ/i_ram_diByte_1
                                Gate     Net
    Cell:in->out      fanout   Delay   Delay  Logical Name (Net Name)
    ----------------------------------------  ------------
     IBUF:I->O           444   0.849   1.392  rst_IBUF (REG/ext_int/fd_out1_0__or0000)
     BUF:I->O            445   0.648   1.425  rst_IBUF_1 (rst_IBUF_1)
     LUT3:I2->O            4   0.648   0.730  ROM/data<1>1 (i_rom_data<1>)
     LUT4:I0->O            1   0.648   0.500  SEQ/i_ram_diByte_mux0000<1>17_SW0 (N1262)
     LUT4:I1->O            1   0.643   0.563  SEQ/i_ram_diByte_mux0000<1>32 (SEQ/i_ram_diByte_mux0000<1>32)
     LUT4:I0->O            1   0.648   0.000  SEQ/i_ram_diByte_mux0000<1>60 (SEQ/i_ram_diByte_mux0000<1>)
     FDE:D                     0.252          SEQ/i_ram_diByte_1
    ----------------------------------------
    Total                      8.946ns (4.336ns logic, 4.610ns route)
                                       (48.5% logic, 51.5% route)

=========================================================================

为了让我更具体,我将在 1 个操作码的解码阶段给出一个示例代码的片段。

以下是解码 opdcode(mov 指令)时的 1 个此类情况。大约有 100+ 个操作码(100+ 条指令),这意味着这个 case 语句有超过 100 个 when 语句。

案例操作码是

--MOV A, Rn
当“11101000” | "11101001" | "11101010" | "11101011" | "11101100" | "11101101" | "11101110" | "11101111" => case de_state 是 E7 =>

              de_state <= E8;

          when E8 =>


              de_state <= E9;

          when E9 =>


              de_state <= E10;
          when E10 =>
              --Draw PSW
              i_ram_addr <= xD0;
              i_ram_rdByte <= '1';

              de_state <= E11;
          when E11 =>
              --Draw from Rn
              i_ram_addr <= "000" & i_ram_doByte(4 downto 3)& opcode(2 downto 0);
              i_ram_rdByte <= '1';

              de_state <= E12;

          when E12 =>
              --Place into EDR
              EDR <= i_ram_doByte;
              --close rdByte
              i_ram_rdByte <= '0';

          when others =>

          end case;

我希望你能更好地了解我的 vhdl 代码。我将不胜感激任何形式的帮助。谢谢!

4

2 回答 2

1

由于您使用的是 Xilinx,我想您也可以访问 PlanAhead?尝试“Analyze Timing / Floorplan Design (PlanAhead)”(在“Implement Design”->“Place & Route”下)。

PlanAhead 应该打开,并在底部为您提供计时结果的视图。选择关键路径(松弛最小的路径),右键单击它并选择“示意图”,这将显示相​​关图元的图形视图。然后,您可以右键单击图元并选择“Expand Cone”->“To Flops”,也可以查看周围的组件。

这应该可以帮助您更好地了解所涉及的信号。尝试将输入和输出信号跟踪到您的 VHDL 代码,并专注于优化路径。

于 2012-11-13T07:18:54.957 回答
1

仅从这些信息中不会有好的答案;我们只能猜测是什么源代码产生了这个硬件。

但很明显,您需要检查源头,假设它为什么慢,采取行动纠正问题,并测试解决方案。

并重复直到足够快。

我的猜测,鉴于您暗示有一个案例语句来解码操作码......

其中一个手臂是这样的:

when <some expression involving decode>  =>
   address <= <some address calculation>;

问题是这两个表达式通常是相互关联的,因此它们在同一个循环中被评估。一个示例解决方案是将地址表达式(即在前一个周期中)预先计算到一个寄存器中,并将 case arm 重写为:

when <some expression involving decode>  =>
   address <= register;

如果您猜对了,结果会稍微快一些,并且您还有另一个(类似的)瓶颈需要修复。重复直到足够快...

但是如果没有源和时序分析,不要指望更具体的答案。

编辑:发布了一小部分源代码后,图片更清晰了:您有两个嵌套的 Case 语句,每个都很大。你显然需要一些简化......

我注意到只有 2 个内壳臂分配给 i_ram_addr,但时序分析显示 i_ram_addr 上有一个巨大而复杂的多路复用器;很明显,还有很多其他的 case arm 为 i_ram_addr 贡献了术语......

我建议您可能必须将 i_ram_addr 与主要的 Case 语句分开处理,并编写最简单的机器来单独生成 i_ram_addr。例如,我会注意到 OPCODE 案例臂相当于:

if OPCODE(7 downto 3) = "11101" then ...

并询问单独为 i_ram_addr 获取解码器有多简单。您可能会发现许多其他 case arm 使用 i_ram_addr 做非常相似的事情(最初的 8051 设计者会抓住机会简化逻辑!)。综合工具在简化逻辑方面可能非常聪明,但是当事情变得过于复杂时,它们可能会错失良机。

(在这个阶段,我将注释掉 i_ram_addr 分配,并单独留下解码器的其余部分)

于 2012-11-13T13:18:01.810 回答