我写了这样一个简单的代码块,但是cnt的值是任意改变的。结果不应该随着cnt的大小而改变,但实际上是这样的。
always @* begin
cnt = 0;
$display(" Now cnt is reset as %d", cnt);
for (i = 0; i < IN_NUM; i = i+1)begin
$display ("x[i] ~^ w[i] value: %d ", (x[i] ~^ w[i]));
$display ("Count value before: %d ", cnt);
cnt = cnt + (x[i] ~^ w[i]);
$display ("Count value after: %d ", cnt);
end
end
控制台的结果是。
Now cnt is reset as 0
x[i] ~^ w[i] value: 1
Count value before: 0
Count value after: 1048575
x[i] ~^ w[i] value: 1
Count value before: 1048575
Count value after: 1048574
x[i] ~^ w[i] value: 1
Count value before: 1048574
Count value after: 1048573
我把整个代码附在下面
`timescale 1ns / 1ps
module tb_xnor_net();
localparam IN_WIDTH = 31;
localparam CMP_WIDTH = 20;
reg [IN_WIDTH-1:0] w;
reg [IN_WIDTH-1:0] x;
reg [CMP_WIDTH-1:0] th;
wire [CMP_WIDTH-1:0] cnt;
wire y;
initial begin
$display(" time, th, y, cnt, x ");
// monitors checks and print the transitions
// $monitor("%d, %d, %b, %b, %h", $time, th, y, cnt, x);
w <= 0; x <= 0; th <= 0;
#20 x <= 'h0; w <= 'h0; th <= 'd10;
#20 x <= 'hff; w <= 'h0; th <= 'd10;
#20 $finish;
end
xnor_kernel
#(
.CMP_WIDTH(CMP_WIDTH),
.IN_NUM(IN_WIDTH)
)
test
(
.x(x),
.w(w),
.th(th),
.y(y),
.cnt(cnt)
);
endmodule
module xnor_kernel
#(
parameter CMP_WIDTH = 9,
parameter IN_NUM = (1<<CMP_WIDTH)
)
(
input wire [IN_NUM-1:0] x,
input wire [IN_NUM-1:0] w,
input wire [CMP_WIDTH-1:0] th,
output wire y,
output reg [CMP_WIDTH-1:0] cnt
);
wire v;
integer i;
always @* begin
cnt = 0;
$display(" Now cnt is reset as %d", cnt);
for (i = 0; i < IN_NUM; i = i+1)begin
$display ("x[i] ~^ w[i] value: %d ", (x[i] ~^ w[i]));
$display ("Count value before: %d ", cnt);
cnt = cnt + (x[i] ~^ w[i]);
$display ("Count value after: %d ", cnt);
end
end
assign y = (cnt >= th);
endmodule
我只是 在一个稍有不同的例子中,解释了这个同样的问题 到另一个用户--你们必须在同一个类中。
问题是你的表达式中的操作数会被扩展到以下类的宽度 cnt
(CMP_WIDTH) 之前 的运算符。你想要的结果是 x[i] ~^ w[i]
保持在1位。所以使用 ==
操作符来代替。在SystemVerilog中,您可以用 1'(x[i] ~^ w[i])
但是 ==
操作员更直观。