问题
I wrote a simple block like this, but the cnt value is changed arbitrarily. The result is not supposed to change with size of cnt, but actually it is.
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
The console result is:
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
I attach the whole code as below:
`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
回答1:
I just explained this same problem for a slightly different example to another user— you must be in the same class.
The problem is the operands in your expression get extended to the width of cnt
(CMP_WIDTH) before the operators are applied. You want the result of x[i] ~^ w[i]
to remain at 1 bit. So use the ==
operator instead. In SystemVerilog, you could do 1'(x[i] ~^ w[i])
, but the ==
operator is much more intuitive.
来源:https://stackoverflow.com/questions/61966920/what-happened-to-this-simple-verilog-operator