结构 Verilog 8 函数 ALU
Structural Verilog 8-Function ALU
我知道如何使用行为风格编写 ALU,但我完全不知道如何使用结构设计来编写代码。我需要一个 8 函数位片结构 ALU,这样我就可以通过传递的参数更改字长,但它仍然有效。我找到了一个 2 函数 ALU 的原理图,但是有人能告诉我如何将它转换为 8 函数或者 link 我可以将它转换为 Verilog 示例吗?这是 2 功能 ALU 原理图:
我不太记得真值表、k-map 等,甚至无法尝试自己找出逻辑。不知道从哪里开始。非常感谢任何帮助,谢谢!
除非你试图将逻辑简化为最小形式(老实说这是浪费精力,因为综合工具本身非常擅长这样做,至少在组合术语以获得更小的功能等效逻辑时), 你可以进一步分解这个问题。在编写行为 Verilog 时,您通常应该以这种方式思考,因为这样做会使您的设计更有可能综合成一个可行的、可靠的网表。
你有一个原理图,所以从设计的主要部分开始,并实现模块来完成这些功能。例如,您在设计中有许多 2x1 多路复用器。因此,我们应该实现从正确输入中进行选择的逻辑。现在,什么是多路复用器?嗯,这是一个基本的组合函数,看起来像这样:
S A B O
----------
0 0 x 0
0 1 x 1
1 x 0 0
1 x 1 1
即,如果S
为0,则O = A
,如果S
为1,则O = B
。所以,我们可以将它们重新格式化为逻辑表达式:O = ~S & A | S & B
(注意,如果 S = 0
,我们将传递 A
并且 B
项将被置为 0,反之亦然相反,如果 S
是 1).
现在只需在 Verilog 门原语中实现它:
module mux2x1(input A,
input B,
input S,
output O);
wire AO, BO, NOT_S;
not n1(NOT_S, S); // NOT_S = ~S;
and a1(AO, A, NOT_S), // AO = A & ~S;
a2(BO, B, S); // BO = B & S;
or o1(O, BO, AO); // O = (A & ~S) | (B & S);
endmodule
现在,为了增加 A
、B
和 O
的宽度,我们只需要为 A
的每一位制作一堆这样的多路复用器, B
和 O
。我们可以做到这一点,但会生成大量的 mux 模块,或者像这样对模块内部的逻辑执行此操作:
module mux2x1 #(parameter W = 1)
(input [W-1:0] A,
input [W-1:0] B,
input S,
output [W-1:0] O);
wire [W-1:0] AO, BO;
wire NOT_S;
genvar i;
not n1(NOT_S, S); // NOT_S = ~S;
generate begin
for (i = 0; i < W; i = i + 1) begin : mux_w
and a1(AO[i], A[i], NOT_S), // AO[i] = A[i] & ~S;
a2(BO[i], B[i], S); // BO[i] = B[i] & S;
or o1(O[i], BO[i], AO[i]); // O[i] = (A[i] & ~S) | (B[i] & S);
end
end
endmodule
既然您已经看到了一个完整的例子,我希望您能以同样的方式完成其他模块(比如加法器和 4x1 多路复用器)。这确实不是一种正式的方式,但它有助于把事情想清楚。另请注意,如果您在弄清逻辑时遇到问题,可以在线找到大量加法器架构。
我知道如何使用行为风格编写 ALU,但我完全不知道如何使用结构设计来编写代码。我需要一个 8 函数位片结构 ALU,这样我就可以通过传递的参数更改字长,但它仍然有效。我找到了一个 2 函数 ALU 的原理图,但是有人能告诉我如何将它转换为 8 函数或者 link 我可以将它转换为 Verilog 示例吗?这是 2 功能 ALU 原理图:
我不太记得真值表、k-map 等,甚至无法尝试自己找出逻辑。不知道从哪里开始。非常感谢任何帮助,谢谢!
除非你试图将逻辑简化为最小形式(老实说这是浪费精力,因为综合工具本身非常擅长这样做,至少在组合术语以获得更小的功能等效逻辑时), 你可以进一步分解这个问题。在编写行为 Verilog 时,您通常应该以这种方式思考,因为这样做会使您的设计更有可能综合成一个可行的、可靠的网表。
你有一个原理图,所以从设计的主要部分开始,并实现模块来完成这些功能。例如,您在设计中有许多 2x1 多路复用器。因此,我们应该实现从正确输入中进行选择的逻辑。现在,什么是多路复用器?嗯,这是一个基本的组合函数,看起来像这样:
S A B O
----------
0 0 x 0
0 1 x 1
1 x 0 0
1 x 1 1
即,如果S
为0,则O = A
,如果S
为1,则O = B
。所以,我们可以将它们重新格式化为逻辑表达式:O = ~S & A | S & B
(注意,如果 S = 0
,我们将传递 A
并且 B
项将被置为 0,反之亦然相反,如果 S
是 1).
现在只需在 Verilog 门原语中实现它:
module mux2x1(input A,
input B,
input S,
output O);
wire AO, BO, NOT_S;
not n1(NOT_S, S); // NOT_S = ~S;
and a1(AO, A, NOT_S), // AO = A & ~S;
a2(BO, B, S); // BO = B & S;
or o1(O, BO, AO); // O = (A & ~S) | (B & S);
endmodule
现在,为了增加 A
、B
和 O
的宽度,我们只需要为 A
的每一位制作一堆这样的多路复用器, B
和 O
。我们可以做到这一点,但会生成大量的 mux 模块,或者像这样对模块内部的逻辑执行此操作:
module mux2x1 #(parameter W = 1)
(input [W-1:0] A,
input [W-1:0] B,
input S,
output [W-1:0] O);
wire [W-1:0] AO, BO;
wire NOT_S;
genvar i;
not n1(NOT_S, S); // NOT_S = ~S;
generate begin
for (i = 0; i < W; i = i + 1) begin : mux_w
and a1(AO[i], A[i], NOT_S), // AO[i] = A[i] & ~S;
a2(BO[i], B[i], S); // BO[i] = B[i] & S;
or o1(O[i], BO[i], AO[i]); // O[i] = (A[i] & ~S) | (B[i] & S);
end
end
endmodule
既然您已经看到了一个完整的例子,我希望您能以同样的方式完成其他模块(比如加法器和 4x1 多路复用器)。这确实不是一种正式的方式,但它有助于把事情想清楚。另请注意,如果您在弄清逻辑时遇到问题,可以在线找到大量加法器架构。