Verilog行为建模中模块实例化reg输出连接wire报错如何解决
报错原因
- Verilog语法明确规定:
reg类型的变量只能在过程块(always/initial)内被赋值,不能被模块实例的输出端口直接驱动。你遇到的报错核心问题是:第二个半加器实例的sum输出,直接连接到了全加器的output reg sum端口,相当于用模块实例输出直接驱动reg变量,属于语法非法。 - 补充说明:子模块的
reg型输出本质是驱动源,上层模块用wire类型承接是合法的,你代码里的s1、c1、c2定义为wire不存在问题。
解决方法
因为要求必须用行为级建模、不允许使用assign语句,你只需要新增一个中间变量承接第二个半加器的sum输出,再在组合逻辑always块内把中间变量赋值给全加器的输出端口即可。
修改后的可编译代码
// 半加器代码无需改动 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, s_temp; half_adder gate1(a,b,s1,c1); // 半加器sum输出先接中间wire变量s_temp half_adder gate2(s1,c,s_temp,c2); // 用行为级always块完成赋值,不使用assign always@(*) begin sum = s_temp; carry = c1 | c2; end endmodule
说明
- 用
always@(*)替代手动列敏感列表,可避免组合逻辑漏写敏感变量导致的锁存器问题,完全符合行为级建模要求,没有用到assign语句。 - 修改后所有
reg变量的赋值都在过程块内完成,符合Verilog语法规则,不会再抛出端口连接错误。
内容的提问来源于stack exchange,提问作者rubenskx
相关产品推荐
相关产品推荐

