Verilog 代码可以编译,但为什么仿真无法运行?

发布于 2024-10-21 02:47:28 字数 1588 浏览 8 评论 0原文

我的代码由两个文件组成。一个文件包含所有模块,一个文件包含测试平台。当我尝试在测试台上运行模拟时,我的一个模块中的这一行出现未解决的引用错误:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

弱骨蛰伏 2024-10-28 02:47:28

您缺少实例名称。您的模拟器可能认为该语句是一个 UDP 实例,因此它在设计细化过程中给出了未解决的参考错误。编译不会解析具有定义的模块/UDP 实例,因此这些错误不会导致编译失败。

尝试

Add_half add_half_inst(p[3], g[3], in_a[3], in_b[3]);

编辑:
Add_half 不是函数或任务,不能放置在always 块中。它是一个模块,因此是实例化的,而不是调用的。请记住,您正在此处对逻辑电路进行建模。

Add_half add_half_0(p[3], g[3], in_a[3], in_b[3]);
Add_half add_half_1(p[3], g[3], in_a[3], in_b[3]);
...

请注意,每个实例都有一个唯一的名称。您将同一电路实例化 4 次,并简单地连接输入和输出。实例名称是必需的,以便可以使用分层标识符唯一地解析它们。

这不起作用,因为 c is [3:0]

out_c4 = c[4];

有人可能会提到循环,但我认为您现在应该忽略它们,即使它们在这里是合适的。

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.

Add_half add_half_0(p[3], g[3], in_a[3], in_b[3]);
Add_half add_half_1(p[3], g[3], in_a[3], in_b[3]);
...

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]

out_c4 = c[4];

Someone might mention a loop but I think you should ignore those for now even though they are appropriate here.

拔了角的鹿 2024-10-28 02:47:28

除了 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.

软糖 2024-10-28 02:47:28

除了 Adam12 的答案中提到的步骤(添加实例名称、移出始终块)之外,您还需要更改连接线上的类型。

reg [3:0] p;
reg [3:0] g;

应该是

wire [3:0] p;
wire [3:0] g;

这是因为这些是直接连接到模块上的端口的。您只能将 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.

reg [3:0] p;
reg [3:0] g;

should be

wire [3:0] p;
wire [3:0] g;

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文