4

ここで疑似コードを使用します。これらのスタイルには長所と短所があります:

add、and、or、および xor を実行できる alu があるとします。可能な答えを常に計算し、オペコードに基づいて答えを選択するコードを用意する方が良いですか (この場合は 1 つのホット):

alu_add = a + b;
alu_and = a & b;
alu_or  = a | b;
alu_xor = a ^ b;

...

if(opcode[0])      alu_out = alu_add;
else if(opcode[1]) alu_out = alu_and;
else if(opcode[2]) alu_out = alu_or;
else if(opcode[3]) alu_out = alu_xor;

別の方法は、次のようにコーディングすることです。

if(opcode[0])      alu_out = a + b;
else if(opcode[1]) alu_out = a & b;
else if(opcode[2]) alu_out = a | b;
else if(opcode[3]) alu_out = a ^ b;

私はそれを次のようにも見ました:

alu_add = a + b;
alu_and = a & b;
alu_or  = a | b;
alu_xor = a ^ b;

...

alu_out = 
  ( 8{opcode[0]} & alu_add ) |
  ( 8{opcode[1]} & alu_and ) | 
  ( 8{opcode[2]} & alu_or ) |
  ( 8{opcode[3]} & alu_xor );

どちらの方法にも長所と短所がありますか、それとも最終的にはほぼ同じ結果になりますか?

4

2 に答える 2

8

ロジックと読みやすさのレベルの観点からこれを考えてください。最初の2つの形式は読みやすさの点では問題ありませんが、どちらも不必要に優先順位を具体化しており、より多くのレベルのロジックが得られます。3番目の形式も、これらのメトリックのいずれによってもそれほど素晴らしいものではありません。最後に、ここでバイナリコーディングよりもワンホットコーディングを使用する明確な理由はありません。これをコーディングする方法は次のとおりです。

parameter ALU_ADD = 2'b00;
parameter ALU_AND = 2'b01;
parameter ALU_OR  = 2'b10;
parameter ALU_XOR = 2'b11;

reg [1:0]  opcode;  // 2 bits for binary coding vs. 4 for one-hot

//以降、alwaysブロックで:

case (opcode)  // synopsys parallel_case
    ALU_ADD: alu_out = a + b;
    ALU_AND: alu_out = a & b;
    ALU_OR:  alu_out = a | b;
    ALU_XOR: alu_out = a ^ b;
endcase

ここでは、ALUオペコードに値を明示的に割り当て、「マジックナンバー」を避け、他の人が何が起こっているのかを理解しやすくしています。また、caseステートメントを使用し、合成ツールに一致できる式は1つだけであるため、プライオリティエンコーダーが推測されないように指示するディレクティブを適用しました。中間信号(alu_addなど)は簡単な操作であるため名前を付けませんでしたが、これらの信号に簡単にアクセスしたい場合(たとえば、波形ビューアーでシミュレーション後に値を確認する場合)に頻繁に名前を付けます。

この記事では、優れたSunburst Designサイト(所属なし、元学生のみ)からケースステートメントを効果的に使用する方法について詳しく知ることができます。

最後に、「可能な回答を常に計算するコードを用意し、オペコードに基づいて回答を選択する方がよい」という質問について、Verilogはハードウェア記述言語であることを忘れないでください。このページのすべての実装は、とにかく常にすべてを計算しています。それらが異なるのは、ロジックと読みやすさのレベルです。このページを見てください。これは、私の実装には操作自体を超えた1レベルのロジックがあり、if-else実装には3つの追加レベルのロジックがあることを示しています。

于 2009-09-09T04:01:57.613 に答える
2

最初の 2 つは同じロジックを提供しますが、ブロック (プライオリティ エンコーダー) に final がないalu_outため、ラッチがかかります。(とにかく、これは verilog に当てはまります)。タイミングがタイトな場合、プライオリティ エンコーダーが意味する長いパスに問題がある可能性があります。if elseelse

3 番目のバージョンでは、より「並列」な構造になり、タイミングが向上する可能性があります。ラッチしません。

3 つのバージョンすべてで、オペコードに関係なく、4 つの操作のそれぞれがガタガタ音をたてて離れます。これには力の意味があります。

明確にするために最初のバージョンが優先され、デバッグ時に波形ビューアーで個別の操作のそれぞれを取得できるというのが私の意見です。タイミング、面積、または電力の制約が問題にならない限り、読みにくいものをコーディングしても意味がありません。

于 2009-09-08T19:11:25.750 に答える