Verilog 模块实例化 reg 输入输出
Verilog module instantiation reg input output
在行为建模中实施 Verilog 代码时,我们使用 reg
作为输出。但是,当我必须使用模块实例化并使用电线连接它时,它在实现时显示错误。有没有其他方法可以使用模块实例化来连接不同模块实例的输出以实现组合逻辑,因为将先前模型的 reg
输出连接到电线是非法的?请注意,我必须应用行为建模,因此不允许赋值语句。这是一个将两个半加器连接到一个全加器的例子。
module half_adder(input wire a,b,output reg sum,output reg carry);
always@(a or b)
begin
sum = a^b ;
carry= a & b ;
end
endmodule
module full_adder(input wire a,b,c,output reg sum,output reg carry);
wire s1,c1,c2;
half_adder gate1(a,b,s1,c1);
half_adder gate2(s1,c,sum,c2);
always@(a or b or c)
begin
carry = c1|c2;
end
endmodule
Error (10663): Verilog HDL Port Connection error at full_adder.v(14):
output or inout port "sum" must be connected to a structural net
expression
您不应在 full_adder
模块中将 sum
声明为 reg
,因为它未在程序块(例如 always
)内分配。 reg
不是“网络”类型。变化:
module full_adder(input wire a,b,c,output reg sum,output reg carry);
至:
module full_adder(input wire a,b,c,output sum,output reg carry);
您的敏感度列表也不正确。变化:
always@(a or b or c)
至:
always @*
现在,always
块将在分配的 RHS 上的信号发生变化时触发。
在标准的旧 verilog 中,无法使用模块连接或连续分配将 reg
连接到 reg
。 System verilog 允许。因此,解决方案之一可能是切换到系统 verilog。
至于 verilog,在 half_adder 端口 sum
被声明为 reg。实例 gate2 将类型 reg 的变量连接到类型 reg 的端口。这是非法的。这种类型的分配只能发生在程序(即始终)块内。实例 gate1 通过将端口连接到线路 s1.
绕过了这个问题
因此,您可以遵循类似的路径。创建另一条电线 s2,如下例所示。
module full_adder(input wire a,b,c,output reg sum,output reg carry);
wire s1,c1, s2, c2;
half_adder gate1(a,b,s1,c1);
half_adder gate2(s1,c,s2,c2); // use s2 here
always@*
carry = c1|c2;
always @*
sum = s2; // now you can s2 assign to the 'sum' port
endmodule
另一种方法是将 'sum' 端口声明为 wire。寄存器可以连接到电线,使用端口连接或连续赋值。
module full_adder(input wire a,b,c,
output sum, // declares it as a wire
output reg carry);
...
half_adder gate2(s1,c,sum,c2); // now it works this way.
顺便说一句,不要使用 @(a,b,c)。它总是容易出错,在您的情况下只是错误。应该是@(c1,c2)。但是使用 @*
.
会好很多
在行为建模中实施 Verilog 代码时,我们使用 reg
作为输出。但是,当我必须使用模块实例化并使用电线连接它时,它在实现时显示错误。有没有其他方法可以使用模块实例化来连接不同模块实例的输出以实现组合逻辑,因为将先前模型的 reg
输出连接到电线是非法的?请注意,我必须应用行为建模,因此不允许赋值语句。这是一个将两个半加器连接到一个全加器的例子。
module half_adder(input wire a,b,output reg sum,output reg carry);
always@(a or b)
begin
sum = a^b ;
carry= a & b ;
end
endmodule
module full_adder(input wire a,b,c,output reg sum,output reg carry);
wire s1,c1,c2;
half_adder gate1(a,b,s1,c1);
half_adder gate2(s1,c,sum,c2);
always@(a or b or c)
begin
carry = c1|c2;
end
endmodule
Error (10663): Verilog HDL Port Connection error at full_adder.v(14): output or inout port "sum" must be connected to a structural net expression
您不应在 full_adder
模块中将 sum
声明为 reg
,因为它未在程序块(例如 always
)内分配。 reg
不是“网络”类型。变化:
module full_adder(input wire a,b,c,output reg sum,output reg carry);
至:
module full_adder(input wire a,b,c,output sum,output reg carry);
您的敏感度列表也不正确。变化:
always@(a or b or c)
至:
always @*
现在,always
块将在分配的 RHS 上的信号发生变化时触发。
在标准的旧 verilog 中,无法使用模块连接或连续分配将 reg
连接到 reg
。 System verilog 允许。因此,解决方案之一可能是切换到系统 verilog。
至于 verilog,在 half_adder 端口 sum
被声明为 reg。实例 gate2 将类型 reg 的变量连接到类型 reg 的端口。这是非法的。这种类型的分配只能发生在程序(即始终)块内。实例 gate1 通过将端口连接到线路 s1.
因此,您可以遵循类似的路径。创建另一条电线 s2,如下例所示。
module full_adder(input wire a,b,c,output reg sum,output reg carry);
wire s1,c1, s2, c2;
half_adder gate1(a,b,s1,c1);
half_adder gate2(s1,c,s2,c2); // use s2 here
always@*
carry = c1|c2;
always @*
sum = s2; // now you can s2 assign to the 'sum' port
endmodule
另一种方法是将 'sum' 端口声明为 wire。寄存器可以连接到电线,使用端口连接或连续赋值。
module full_adder(input wire a,b,c,
output sum, // declares it as a wire
output reg carry);
...
half_adder gate2(s1,c,sum,c2); // now it works this way.
顺便说一句,不要使用 @(a,b,c)。它总是容易出错,在您的情况下只是错误。应该是@(c1,c2)。但是使用 @*
.