ALU 的 Verilog HDL 行为编码调用模块
Verilog HDL behavioral coding calling modules for ALU
这是我第一次在 verilog hdl 中编程,我无法弄清楚我的代码有什么问题。我需要在行为代码中设计一个简单的 ALU。
到目前为止,我已经创建了一个减法器和加法器模块。(我需要添加更多模块,但我希望在添加其他模块之前让它们在 ALU 模块中工作)。
我在同一个项目的单独 .v 文件中有以下模块(很确定这是行为?):
module adder3bit( sum, co, a, b);
parameter n = 2;
output reg [n:0] sum;
output reg co;
input [n:0] a;
input [n:0] b;
always @(a, b)
{co, sum} = a + b;
endmodule
module subtract3bit(diff, bo, a, b);
parameter n = 2;
output reg [n:0] diff;
output reg bo;
input [n:0] a;
input [n:0] b;
always @(a, b)
{bo, diff} = a - b;
endmodule
我测试了这些,发现它们在工作。
现在我试图在主 ALU 模块中调用它们:
module alu( out, overflow, a, b,sel);
input [2:0] a, b;
input sel;
output [2:0] out;
output overflow;
always @(a,b,sel)
begin
if(sel=='b0)
adder3bit A1(out,overflow,a,b);
if(sel=='b1)
subtract3bit S1( out, overflow, a, b);
end
endmodule
我的语法可能有误,但显示错误。我只是非常不熟悉verilog。我感觉我第一次学习 C 的感觉。非常感谢帮助。
我知道它正在正确调用模块,但我认为这与 if 语句有关。
谢谢,希望能学到新东西!
您不能在 verilog 中的 always 块内实例化模块。相反,您可以将模块 adder3bit 和 substract3bit 更改为任务,您可以使用您现在编写的代码。
解决方案将是这样的
task adder3bit;
parameter n = 2;
input [n:0] a;
input [n:0] b;
output reg [n:0] sum;
output reg co;
begin
always @(*) {co, sum} = a + b;
endtask
task subtract3bit;
parameter n = 2;
input [n:0] a;
input [n:0] b;
output reg [n:0] diff;
output reg bo;
begin
always @(*) {bo, diff} = a - b;
endtask
module alu( out, overflow, a, b,sel);
input [2:0] a, b;
input sel;
output [2:0] out;
output overflow;
always @(a,b,sel)
begin
if(sel=='b0)
adder3bit (a,b,out,overflow);
if(sel=='b1)
subtract3bit ( a,b,out,overflow);
end
endmodule
主要问题是你要调用模块。模块不是您不能调用它们的函数或任务。您可以并且应该对模块做的是在另一个模块(在本例中为 ALU 模块)中实例化它。模块不能在程序块内实例化(e.x。总是在你的代码中)。加法器和减法器都会在其输入的每次更改时产生新结果,因此您只需要正确驱动该模块的输入并读取其输出即可。
我建议您以更具可读性的方式声明模块的端口:
module adder3bit #(
parameter N = 2
) (
output reg [N:0] sum,
output reg co,
input [N:0] a,
input [N:0] b
);
always @(a, b)
{co, sum} = a + b;
endmodule
在 ALU 中,您可以像这样实例化 adder3bit:
module alu (
input [2:0] a,
input [2:0] b,
input sel,
output [2:0] out,
output overflow
)
localparam SIZE = 3;
wire [SIZE - 1 : 0] diff;
wire [SIZE - 1 : 0] sum;
wire co;
wire bo;
adder3bit #(
.N(SIZE)
) adder (
.a(a),
.b(b),
.sum(sum),
.co(co)
);
subtract3bit #(
.N(SIZE)
) subtractor (
.a(a),
.b(b),
.diff(diff),
.bo(bo)
);
always @(*)
begin
if(sel=='b0)
{out,overflow) = {sum, co};
if(sel=='b1)
{out,overflow) = {diff, bo};
end
endmodule
还有一件事,您的模块具有定义其输入和输出大小的参数,但它的名称表明它固定为三个,这可能会造成混淆。
这是我第一次在 verilog hdl 中编程,我无法弄清楚我的代码有什么问题。我需要在行为代码中设计一个简单的 ALU。
到目前为止,我已经创建了一个减法器和加法器模块。(我需要添加更多模块,但我希望在添加其他模块之前让它们在 ALU 模块中工作)。
我在同一个项目的单独 .v 文件中有以下模块(很确定这是行为?):
module adder3bit( sum, co, a, b);
parameter n = 2;
output reg [n:0] sum;
output reg co;
input [n:0] a;
input [n:0] b;
always @(a, b)
{co, sum} = a + b;
endmodule
module subtract3bit(diff, bo, a, b);
parameter n = 2;
output reg [n:0] diff;
output reg bo;
input [n:0] a;
input [n:0] b;
always @(a, b)
{bo, diff} = a - b;
endmodule
我测试了这些,发现它们在工作。
现在我试图在主 ALU 模块中调用它们:
module alu( out, overflow, a, b,sel);
input [2:0] a, b;
input sel;
output [2:0] out;
output overflow;
always @(a,b,sel)
begin
if(sel=='b0)
adder3bit A1(out,overflow,a,b);
if(sel=='b1)
subtract3bit S1( out, overflow, a, b);
end
endmodule
我的语法可能有误,但显示错误。我只是非常不熟悉verilog。我感觉我第一次学习 C 的感觉。非常感谢帮助。
我知道它正在正确调用模块,但我认为这与 if 语句有关。
谢谢,希望能学到新东西!
您不能在 verilog 中的 always 块内实例化模块。相反,您可以将模块 adder3bit 和 substract3bit 更改为任务,您可以使用您现在编写的代码。 解决方案将是这样的
task adder3bit;
parameter n = 2;
input [n:0] a;
input [n:0] b;
output reg [n:0] sum;
output reg co;
begin
always @(*) {co, sum} = a + b;
endtask
task subtract3bit;
parameter n = 2;
input [n:0] a;
input [n:0] b;
output reg [n:0] diff;
output reg bo;
begin
always @(*) {bo, diff} = a - b;
endtask
module alu( out, overflow, a, b,sel);
input [2:0] a, b;
input sel;
output [2:0] out;
output overflow;
always @(a,b,sel)
begin
if(sel=='b0)
adder3bit (a,b,out,overflow);
if(sel=='b1)
subtract3bit ( a,b,out,overflow);
end
endmodule
主要问题是你要调用模块。模块不是您不能调用它们的函数或任务。您可以并且应该对模块做的是在另一个模块(在本例中为 ALU 模块)中实例化它。模块不能在程序块内实例化(e.x。总是在你的代码中)。加法器和减法器都会在其输入的每次更改时产生新结果,因此您只需要正确驱动该模块的输入并读取其输出即可。
我建议您以更具可读性的方式声明模块的端口:
module adder3bit #(
parameter N = 2
) (
output reg [N:0] sum,
output reg co,
input [N:0] a,
input [N:0] b
);
always @(a, b)
{co, sum} = a + b;
endmodule
在 ALU 中,您可以像这样实例化 adder3bit:
module alu (
input [2:0] a,
input [2:0] b,
input sel,
output [2:0] out,
output overflow
)
localparam SIZE = 3;
wire [SIZE - 1 : 0] diff;
wire [SIZE - 1 : 0] sum;
wire co;
wire bo;
adder3bit #(
.N(SIZE)
) adder (
.a(a),
.b(b),
.sum(sum),
.co(co)
);
subtract3bit #(
.N(SIZE)
) subtractor (
.a(a),
.b(b),
.diff(diff),
.bo(bo)
);
always @(*)
begin
if(sel=='b0)
{out,overflow) = {sum, co};
if(sel=='b1)
{out,overflow) = {diff, bo};
end
endmodule
还有一件事,您的模块具有定义其输入和输出大小的参数,但它的名称表明它固定为三个,这可能会造成混淆。