这个简单的verilog〜^运算符发生了什么? [英] What happened to this simple verilog ~^ operator?

查看:61
本文介绍了这个简单的verilog〜^运算符发生了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这样写了一个简单的块,但是cnt值是任意更改的.结果不应该随cnt的大小而改变,但实际上是这样.

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

控制台结果为:

 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

推荐答案

我只是为一个稍有不同的示例解释了相同的问题发送给另一个用户—你必须在同一个班级.

I just explained this same problem for a slightly different example to another user— you must be in the same class.

问题在于,在应用运算符之前,表达式中的操作数将扩展为 cnt (CMP_WIDTH)的宽度.您希望 x [i]〜^ w [i] 的结果保持在1位.因此,请使用 == 运算符.在SystemVerilog中,您可以执行 1'(x [i]〜^ w [i]),但是 == 运算符要直观得多.

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.

这篇关于这个简单的verilog〜^运算符发生了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆