... | ... | @@ -9,6 +9,40 @@ |
|
|
もちろん、プロセッサの性能を上げる以外の好きなことをするのも全くかまいません。
|
|
|
せっかく自分でプロセッサを作ってみたのですから、ベンチマークを動かすだけではなく、自作プログラムを動かしてみるなどの余興もよいでしょう。
|
|
|
|
|
|
### 周波数の限界に挑戦する
|
|
|
|
|
|
* 難易度:1~4
|
|
|
|
|
|
プロセッサの性能を上げる最も簡単な方法はクロック周波数を上げることです。クロック周波数を上げるためには、回路が複雑でないことが要求されます。Vivadoでクリティカルパス(レジスタからレジスタへの経路のうちで、最も長い遅延を生み出す経路)を探しながらソースコードを書き換えていくことになります。
|
|
|
|
|
|
以下に、大きな高速化ポイントのヒントを示します。
|
|
|
|
|
|
**RAMが大量の分散RAMで構築されている場合、それをBlockRAMに置き換えてみる**
|
|
|
|
|
|
* 難易度:1
|
|
|
|
|
|
非常に効果が高いです。シングルサイクルプロセッサだと不可能そうに見えますが、`negedge`で駆動することで可能です(本当は、素直にマルチサイクル化orパイプライン化するのが正しい)。
|
|
|
|
|
|
**`always`文で書かれている組み合わせ論理回路を、条件演算子とfunctionに書き換えてみる**
|
|
|
|
|
|
* 難易度:1
|
|
|
|
|
|
巨大な`always`文がある場合、Vivadoは最適化をあきらめてしまいます。細かい単位で計算結果を`wire`に束縛することで、合成系へのヒントとできます。束縛した`wire`の名前のおかげで、クリティカルパスがどこなのかを判読することが容易になります。
|
|
|
|
|
|
|
|
|
**Don't careな信号はどれか、考慮に入れる**
|
|
|
|
|
|
* 難易度:2
|
|
|
|
|
|
ある命令でしか使われない信号線は、他の命令の時にどんな値が入っていてもよいです。いいかえると、全ての命令の時にその値が入っていても問題ありません。このようにすると条件分岐が減り、LUT数を削減することができます。クリティカルパスは変わらないかもしれませんが、LUT数を削減により回路面積が小さくなると、配線遅延が小さくなることがあります。
|
|
|
|
|
|
**FPGAが一スライスでできることを考慮に入れる**
|
|
|
|
|
|
* 難易度:4
|
|
|
|
|
|
FPGAの中身がどのような構成になっているかを勉強すると、FPGAが得意なことと不得意なことがあることが分かります。その知識を使って、限界まで周波数を上げてみましょう。
|
|
|
参考:[FPGAの詳しい中身](FPGAAbyss)
|
|
|
|
|
|
### パイプライン化
|
|
|
|
|
|
* 難易度:2
|
... | ... | @@ -69,3 +103,4 @@ CPU の実行すべき命令は、必ずしも直前の命令の結果を使う |
|
|
インオーダーのスーパースカラでは、既に実行可能な命令が後ろの方にあっても、前から順番に実行していかないといけないという制約の都合上、その命令を実行することができません。そのような場合、Exec Unit(ALUや乗算器などの演算器およびメモリアクセスに必要な資源)が遊んでいることになり、もったいないです。アウトオブオーダー実行できれば、そのような命令を先に実行することができ、遊んでいる Exec Unit が有効活用されるため、性能が向上します。
|
|
|
|
|
|
Exec Unit 以外はほとんど書き直しになってしまうので、実装量は多くなります。外から見た結果が、命令の順番通り(インオーダーに)実行した時と必ず一致する必要があるため、考えることがたくさんあります。
|
|
|
|