AND(000)、OR(001)、ADD(010)、SUB(110)、SLT(111)、および BEQ(100) のオペコードを使用して、構造 Verilog で 32 ビット ALU を作成する必要があります。これらのそれぞれがゲートレベルで個別にどのように機能するかを理解していますが、オペコードを使用して目的の出力を得る方法について混乱しています。たとえば、高級言語の場合、if opcode == 100 {output = branch} のように記述します。これがばかげた質問である場合は申し訳ありませんが、私はVerilogを初めて使用し、オンラインの回答の多くは動作Verilogを使用しているか、非常に混乱しています。
1 に答える
Verilogで説明したのと同じ手法を使用できます...if
ステートメントを使用するには、次のalways
ようにブロック内にある必要があります。
always @ (*) begin
if (operation == 3'b000) begin
alu_result = and_result;
end else if (operation == 3'b001) begin
alu_result = or_result;
end else if (operation == 3'b010) begin
alu_result = add_result;
// ...repeat this pattern for the other operations except BEQ...
end else begin
alu_result = beq_result;
end
end
この例では、*_result
ワイヤは個々の操作の結果の値です。コードは、個々の結果値 ( に依存) を選択し、最終的な ALU 出力であるoperation
を駆動するマルチプレクサに合成されます。alu_result
ステートメントを使用する代わりに、このアプリケーションでは、次のようにif
使用する方がよいでしょう。case
always @ (*) begin
case (operation)
3'b000: alu_result = and_result;
3'b001: alu_result = or_result;
3'b010: alu_result = add_result;
// ...repeat this pattern for the other operations except BEQ...
default: alu_result = beq_result;
endcase
end
ご覧のとおり、これはもう少しコンパクトで読みやすいです。正しく記述されていれば、両方のバリアントがまったく同じマルチプレクサ ロジックにつながるはずです。どちらのバリアントでも、ブロック内で代入しているためalu_result
、型である必要があることに注意してください。ただし、必要に応じて使用する方法があります。reg [31:0]
always
wire
alu_result = operation == 3'b000 ? and_result
: operation == 3'b001 ? or_result
: operation == 3'b010 ? add_result
// ...repeat this pattern for the other operations except BEQ...
: beq_result;
編集
OPは、ビットレベルの構造的マルチプレクサコードが必要であることを示しました。
AND、OR、および NOT ゲートから非常に単純なマルチプレクサを作成できます。たとえば、双方向マルチプレクサは次のように作成できます。
not(select_inv,select);
and(selected_signal_a,signal_a,select_inv);
and(selected_signal_b,signal_b,select);
or(selected_result,selected_signal_a,selected_signal_b);
この例では、 はとselect
のどちらが最終的な出力 に到達するかを決定します。signal_a
signal_b
selected_result
たとえば、複数のマルチプレクサを直列に積み重ねることによって、複数の選択ビットに同じパターンを使用できます (ヒント: 3 つ必要です)。