4

ザイリンクスを使用して VHDL で 80c51 アーキテクチャをコーディングしました。クロック周波数を上げようとして、すべての 80c51 命令をパイプライン処理しました。命令は、たとえば、必要に応じて実行できました。最初の命令が処理されているときに、2 番目の命令がフェッチされます。

ただし、合成レポートによると、パイプラインの深さを 3 に設定したにもかかわらず、わずかに高いクロック周波数 (約 +/-10Hz) しか得られません。ボトルネックは合成レポートで指定された1つの操作によるものであることがわかりましたが、合成レポートを理解できませんでした。

「SEQ/decode_3 から SEQ/i_ram_addr_7」へのデータ パスは何をしようとしているのですか? (私の推測では、100 以上の関連するオペコードをチェックするステートメントを使用すると推測されますが、それがボトルネックであるかどうかはわかりません。しかし、私は無知です)

したがって、私の唯一の2つのクエリは次のとおりです。

まず、パイプライン化によってクロック周波数が増加せず、テストベンチがタイミングの減少を説明する唯一の方法である可能性はありますか?

次に、「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 オペコードのデコード フェーズのサンプル コードのスニペットを示します。

以下は、mov 命令である opdcode をデコードする場合の 1 つのケースです。約 100 以上のオペコード (100 以上の命令) があります。つまり、この case ステートメントには 100 を超える when ステートメントがあります。

ケース OPCODE は

--MOV A、Rn
「11101000」の場合 | "11101001" | "11101010" | "11101011" | "11101100" | "11101101" | "11101110" | "11101111" => 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

ザイリンクスを使用しているので、PlanAheadにもアクセスできると思いますか?「AnalyzeTiming/Floorplan Design(PlanAhead)」(「ImplementDesign」->「Place&Route」の下)を試してください。

PlanAheadが開き、下部にタイミング結果が表示されます。クリティカルパス(たるみが最も少ないパス)を選択し、それを右クリックして[Schematic]を選択すると、関連するプリミティブのグラフィカルビューが表示されます。次に、プリミティブを右クリックし、[円錐の拡張]-> [フロップへ]を選択して、周囲のコンポーネントも表示できます。

これは、どの信号が関係しているかをよりよく理解するのに役立つはずです。入力信号と出力信号をVHDLコードまでトレースし、最適化のためにそのパスに焦点を合わせてみてください。

于 2012-11-13T07:18:54.957 に答える
1

この情報だけでは良い答えは得られません。このハードウェアを作成したソース コードを推測することしかできません。

しかし、ソースを調査し、なぜ遅いのかという仮説を立て、問題を修正するための措置を講じ、解決策をテストする必要があることは明らかです。

そして、十分に速くなるまで繰り返します。

私の推測では、オペコードをデコードするための case ステートメントがあるというあなたのヒントを考えると...

腕の1つは次のようなものです:

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

問題は、多くの場合、2 つの式が相互に関連しているため、同じサイクルで評価されることです。解決策の例は、アドレス式 (つまり、前のサイクル) をレジスタに事前計算し、ケース アームを次のように書き換えることです。

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

推測が正しければ、結果はわずかに速くなり、別の (同様の) ボトルネックを修正する必要があります。十分速くなるまで繰り返します...

ただし、ソースとタイミング分析がなければ、より具体的な回答は期待できません。

編集:ソースコードの一部を投稿したので、画像は少し明確になります:2つの入れ子になった Case ステートメントがあり、それぞれがかなり大きいです。明らかに単純化が必要です...

i_ram_addr に割り当てられる内側のケース アームは 2 つだけですが、タイミング解析では i_ram_addr の巨大で複雑なマルチプレクサが示されています。明らかに、i_ram_addr に用語を提供する他のケースアームがたくさんあります...

i_ram_addr をメインの Case ステートメントとは別に扱い、i_ram_addr だけを生成できる最も単純なマシンを作成する必要があるかもしれないことをお勧めします。たとえば、OPCODE ケース アームは次と同等であることに注意してください。

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

そして、i_ram_addr だけのデコーダーをどれだけ簡単に入手できるかを尋ねてください。他の多くのケース アームが i_ram_addr で非常によく似た処理を行うことに気付くかもしれません (オリジナルの 8051 の設計者は、ロジックを単純化する機会に飛びついたでしょう!)。合成ツールはロジックを単純化する点で非常に優れていますが、複雑すぎるとチャンスを逃してしまう可能性があります。

(この段階で、i_ram_addr の割り当てをコメントアウトし、残りのデコーダーはそのままにしておきます)

于 2012-11-13T13:18:01.810 に答える