Verilog 代码可以编译,但为什么仿真无法运行?
我的代码由两个文件组成。一个文件包含所有模块,一个文件包含测试平台。当我尝试在测试台上运行模拟时,我的一个模块中的这一行出现未解决的引用错误:
Add_half (p[3], g[3], in_a[3], in_b[3]);
此行出现在我的测试台调用的模块中。
可能是什么问题?
这是测试台的代码。 `timescale 1ns/100ps
module CARRYLOOKAHEAD_TB;
reg [3:0] in_a_tb;
reg [3:0] in_b_tb;
reg in_c0_tb;
wire [3:0] s_tb;
wire c4_tb;
CarryLookAheadAdder DUT (.in_a(in_a_tb), .in_b(in_b_tb), .in_c0(in_c0_tb), .out_s(s_tb), .out_c4(c4_tb));
initial
begin
in_a_tb = 4'b0000;
in_a_tb = 4'b0001;
in_c0_tb = 1'b0;
#50
in_a_tb = 4'b0000;
in_a_tb = 4'b0001;
in_c0_tb = 1'b1;
#50
in_a_tb = 4'b0001;
in_a_tb = 4'b0001;
in_c0_tb = 1'b0;
#50
in_a_tb = 4'b1111;
in_a_tb = 4'b0001;
in_c0_tb = 1'b0;
#50
in_a_tb = 4'b1111;
in_a_tb = 4'b0000;
in_c0_tb = 1'b1;
#50 $stop;
#20 $finish;
end
endmodule
这是模块的代码
module Add_half (sum, c_out, a, b);
input a, b;
output c_out, sum;
assign sum = a ^ b;
assign c_out = a & b;
endmodule
这是测试台调用的代码
module CarryLookAheadAdder (in_a, in_b, in_c0, out_s, out_c4);
input [3:0] in_a;
input [3:0] in_b;
input in_c0;
output reg [3:0] out_s;
output reg out_c4;
reg [3:0] p;
reg [3:0] g;
reg [3:0] c;
always@(in_a, in_b, in_c0)
begin
out_s[0] = (in_a[0] ^ in_b[0]) ^ in_c0;
Add_half (p[3], g[3], in_a[3], in_b[3]);
Add_half (p[2], g[2], in_a[2], in_b[2]);
Add_half (p[1], g[1], in_a[1], in_b[1]);
Add_half (p[0], g[0], in_a[0], in_b[0]);
out_c4 = c[4];
out_s[3] = p[3] ^ c[3];
out_s[2] = p[2] ^ c[2];
out_s[1] = p[1] ^ c[1];
out_s[0] = p[0] ^ c[0];
end
endmodule
My code consists of two files. One file has all the modules and one file has the test bench. When I try to run a simulation on the test bench, I get an unresolved reference error on this line in one of my modules:
Add_half (p[3], g[3], in_a[3], in_b[3]);
This line occurs in the module that my test bench calls.
What could be the problem?
This is the code for the test bench.
`timescale 1ns/100ps
module CARRYLOOKAHEAD_TB;
reg [3:0] in_a_tb;
reg [3:0] in_b_tb;
reg in_c0_tb;
wire [3:0] s_tb;
wire c4_tb;
CarryLookAheadAdder DUT (.in_a(in_a_tb), .in_b(in_b_tb), .in_c0(in_c0_tb), .out_s(s_tb), .out_c4(c4_tb));
initial
begin
in_a_tb = 4'b0000;
in_a_tb = 4'b0001;
in_c0_tb = 1'b0;
#50
in_a_tb = 4'b0000;
in_a_tb = 4'b0001;
in_c0_tb = 1'b1;
#50
in_a_tb = 4'b0001;
in_a_tb = 4'b0001;
in_c0_tb = 1'b0;
#50
in_a_tb = 4'b1111;
in_a_tb = 4'b0001;
in_c0_tb = 1'b0;
#50
in_a_tb = 4'b1111;
in_a_tb = 4'b0000;
in_c0_tb = 1'b1;
#50 $stop;
#20 $finish;
end
endmodule
This is the code for the module
module Add_half (sum, c_out, a, b);
input a, b;
output c_out, sum;
assign sum = a ^ b;
assign c_out = a & b;
endmodule
This is what gets called by the test bench
module CarryLookAheadAdder (in_a, in_b, in_c0, out_s, out_c4);
input [3:0] in_a;
input [3:0] in_b;
input in_c0;
output reg [3:0] out_s;
output reg out_c4;
reg [3:0] p;
reg [3:0] g;
reg [3:0] c;
always@(in_a, in_b, in_c0)
begin
out_s[0] = (in_a[0] ^ in_b[0]) ^ in_c0;
Add_half (p[3], g[3], in_a[3], in_b[3]);
Add_half (p[2], g[2], in_a[2], in_b[2]);
Add_half (p[1], g[1], in_a[1], in_b[1]);
Add_half (p[0], g[0], in_a[0], in_b[0]);
out_c4 = c[4];
out_s[3] = p[3] ^ c[3];
out_s[2] = p[2] ^ c[2];
out_s[1] = p[1] ^ c[1];
out_s[0] = p[0] ^ c[0];
end
endmodule
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您缺少实例名称。您的模拟器可能认为该语句是一个 UDP 实例,因此它在设计细化过程中给出了未解决的参考错误。编译不会解析具有定义的模块/UDP 实例,因此这些错误不会导致编译失败。
尝试
Add_half add_half_inst(p[3], g[3], in_a[3], in_b[3]);
编辑:
Add_half 不是函数或任务,不能放置在always 块中。它是一个模块,因此是实例化的,而不是调用的。请记住,您正在此处对逻辑电路进行建模。
请注意,每个实例都有一个唯一的名称。您将同一电路实例化 4 次,并简单地连接输入和输出。实例名称是必需的,以便可以使用分层标识符唯一地解析它们。
这不起作用,因为 c is [3:0]
有人可能会提到循环,但我认为您现在应该忽略它们,即使它们在这里是合适的。
You're missing an instance name. Your simulator probably thinks that statement is a UDP instance so it gives an unresolved reference error during design elaboration. Compilation does not resolve module/UDP instances with definitions so these errors won't cause the compile to fail.
Try
Add_half add_half_inst(p[3], g[3], in_a[3], in_b[3]);
EDIT:
Add_half is not a function or a task and can't be placed in an always block. It is a module and thus is instanced, not called. Remember you're modeling a logic circuit here.
Notice each instance has a unique name. You're instancing the same circuit 4 times and simply wiring the inputs and outputs. The instance name is required so they can be uniquely resolved using hierarchical identifiers.
This won't work as c is [3:0]
Someone might mention a loop but I think you should ignore those for now even though they are appropriate here.
除了 Adam12 & guanoloco,只是一些一般性说明:
您将 out_s[0] 分配为 CarryLookAheadAdder 模块的两倍
out_s[0] = (in_a[0] ^ in_b[0]) ^ in_c0;
...
out_s[0] = p[0] ^ c[0];
您没有在任何地方使用“g”变量输出。你可能希望这是你的“c”,因为我猜这是你的进位。
In addition to Adam12 & GuanoLoco, just some general notes:
You are assign out_s[0] twice your CarryLookAheadAdder module
out_s[0] = (in_a[0] ^ in_b[0]) ^ in_c0;
...
out_s[0] = p[0] ^ c[0];
You aren't using your "g" variable output anywhere. You probably want this to be your "c", as I'm guessing this is your carry.
除了 Adam12 的答案中提到的步骤(添加实例名称、移出始终块)之外,您还需要更改连接线上的类型。
应该是
这是因为这些是直接连接到模块上的端口的。您只能将 reg 用于在always 块中分配的内容。
In addition to the steps mentioned in Adam12's answer (add instance names, move out of always block), you need to change the type on your connection wires.
should be
This is because these are connected directly to the ports on the module. You would only use reg for something that was assigned in the always block.