我必须使用 AND(000)、OR(001)、ADD(010)、SUB(110)、SLT(111) 和 BEQ(100) 的操作码在结构 verilog 中创建一个 32 位 ALU。我了解这些中的每一个如何在门级单独工作我只是对如何使用操作码来获得我想要的输出感到困惑。例如,如果它是一种高级语言,我会写一些类似 if opcode == 100 {output = branch} 的东西。如果这是一个愚蠢的问题,我很抱歉,我只是 verilog 的新手,网上的许多答案要么使用行为 verilog,要么非常令人困惑。
问问题
1539 次
1 回答
0
您可以使用您在 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
连线是各个操作的结果值。代码将综合到一个多路复用器,该多路复用器在各个结果值(取决于operation
)之间进行选择,并驱动alu_result
最终的 ALU 输出。
而不是 usingif
语句,对于这个应用程序,它可能更好地使用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 门创建一个非常简单的多路复用器。例如,可以按如下方式创建 2 路多路复用器:
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
。
您可以将相同的模式用于多个选择位(提示:您需要三个),例如将多个多路复用器串联堆叠。
于 2016-11-20T23:55:21.870 回答