如何在verilog中将数字转换为二进制补码?

发布于 2024-07-07 17:57:24 字数 747 浏览 8 评论 0原文

我正在尝试用 verilog 设计一个 4 位加法器减法器。 这只是我用 verilog 编写的第二件事,而且我还不知道所有正确的语法。 这是我迄今为止拥有的模块:

module Question3(carryin, X, Y, Z, S, carryout, overflow);
    parameter n = 4;
    input carryin, Z;
    input [n-1:0]X, Y;
    output reg [n-1:0]S;
    output reg carryout, overflow;

    if(Z==0)
    begin
        Y = not(y) + 4'b0001;
    end

    always @(X, Y, carryin)
        begin
            {carryout, S} = X + Y + carryin;
            overflow = carryout ^ X[n-1]^Y[n-1]^S[n-1];
        end

endmodule

我的编译器(xilinx 10.1)不断显示“if 附近的语法错误”。 我尝试了许多不同的转换方法,包括仅使用以 Y 作为参数的 Case,然后检查所有可能的 4 位组合,并将它们转换为二进制补码。

Z 决定加法器是否执行减法或加法。 如果是0,就意味着减法,我想把y转成补码,然后做正则加法就可以了。 我确信加法器的其余部分是正确的,我只是不知道我尝试转换的部分出了什么问题。

I am trying to design a 4-bit adder subtracter in verilog. This is only the second thing I have ever written in verilog, and I don't know all the correct syntax yet. This is the module I have so far:

module Question3(carryin, X, Y, Z, S, carryout, overflow);
    parameter n = 4;
    input carryin, Z;
    input [n-1:0]X, Y;
    output reg [n-1:0]S;
    output reg carryout, overflow;

    if(Z==0)
    begin
        Y = not(y) + 4'b0001;
    end

    always @(X, Y, carryin)
        begin
            {carryout, S} = X + Y + carryin;
            overflow = carryout ^ X[n-1]^Y[n-1]^S[n-1];
        end

endmodule

My compiler (xilinx 10.1), keeps saying "Syntax error near if." I have tried many different ways of doing the conversion, including just using a Case that takes Y as an argument, then checks all the possible 4-bit combinations, and converts them to two's complement.

Z is what determines if the adder does subtraction or addition. If it's 0, it means subtraction, and I want to convert y to two's complement, then just do regular addition. I'm sure the rest of the adder is correct, I just do not know what is wrong with the part where I'm trying to convert.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

森林散布 2024-07-14 17:57:24
reg [n-1:0] Y_compl;

always @( Z, Y, X, carryin ) begin
  Y_ = ( ~Y + 4'b0001 );
  if ( Z == 1'b0 ) begin
    {carryout, S} = X + Y_compl + carryin;
    overflow = carryout ^ X[n-1] ^ Y_compl[n-1] ^ S[n-1];
  end
  else begin
    {carryout, S} = X + Y + carryin;
    overflow = carryout ^ X[n-1] ^ Y[n-1] ^ S[n-1];
  end

end

有几点很重要。

  1. 将 if 语句放在always 块中。 不要使用两个always块,您将在模拟器中创建竞争条件。
  2. 我创建了一个新变量 Y_,因为使用 Y(记住,它是一个输入)在赋值的左侧可能会推断出锁存器或在综合时执行其他令人讨厌的操作。
  3. 我建议使用按位反转运算符 '~' 来反转 Y,而不是如果 'not'
    原始。 综合工具可以更自由地以这种方式优化您的代码。
  4. 仔细检查结果是否正确,自从我构建加法器以来已经有一段时间了。
reg [n-1:0] Y_compl;

always @( Z, Y, X, carryin ) begin
  Y_ = ( ~Y + 4'b0001 );
  if ( Z == 1'b0 ) begin
    {carryout, S} = X + Y_compl + carryin;
    overflow = carryout ^ X[n-1] ^ Y_compl[n-1] ^ S[n-1];
  end
  else begin
    {carryout, S} = X + Y + carryin;
    overflow = carryout ^ X[n-1] ^ Y[n-1] ^ S[n-1];
  end

end

A couple of important points.

  1. Put the if statement inside the always block. Do not use two always blocks, you'll create a race condition in the simulator.
  2. I created a new variable, Y_ because using Y, which is an input, remember, on the left hand side of an assignment will probably infer latches or do something else nasty when you synthesize.
  3. I suggest using the bitwise inversion operator '~' to invert Y instead if the 'not'
    primitive. The synthesis tool has more freedom to optimize your code this way.
  4. Double check for correct results, it's been awhile since I built an adder.
谜兔 2024-07-14 17:57:24

您在“Y = not(y) + 4'b0001;”中使用小写“y”

此外,您使用的添加物超出了您的需要。 XY 与 NOT(NOT(X)+Y) 相同。

You are using a lower case "y" in "Y = not(y) + 4'b0001;"

Also, you're using more additions than you need to. X-Y is the same thing as NOT(NOT(X)+Y).

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