4

我正在尝试在 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 转换为二进制补码,然后进行常规加法。我确定加法器的其余部分是正确的,我只是不知道我要转换的部分有什么问题。

4

3 回答 3

5
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. 如果使用 'not' 原语,我建议使用按位反转运算符 '~' 来反转 Y。综合工具可以更自由地以这种方式优化您的代码。
  4. 仔细检查结果是否正确,自从我构建加法器以来已经有一段时间了。
于 2009-06-17T06:41:45.057 回答
1

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

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

于 2008-10-27T01:56:21.230 回答
0

将 if 语句放在初始块中
http://www.asic-world.com/verilog/vbehave1.html

于 2008-10-27T02:26:21.043 回答