【问题标题】:Two's complement in verilogVerilog中的二进制补码
【发布时间】:2021-07-27 19:20:35
【问题描述】:

我一直在尝试构建一个模块,该模块返回(3 位)输入的二进制补码表示(第一位是符号)。我认为以下代码在概念上是正确的,但我可能遗漏了它的结构:当我尝试编译时,出现以下错误:

(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".

搜索该错误表明它通常在同时使用变量作为输入和输出时出现,但我的情况并非如此。你能指出错误在哪里吗?

module ca2 (a_i,f_o);
  input  [2:0] a_i;
  output [2:0] f_o;

  always @(a_i[2:0] or f_o[2:0])
  begin
    if (a_i[2] == 1)
    begin
      f_o[2]   = a_i[2];
      f_o[1:0] = (~a_i[1:0] + 'b1);
    end
    else
    begin
      f_o = a_i;
    end
  end
endmodule

【问题讨论】:

    标签: verilog


    【解决方案1】:

    在 Verilog 中,在大多数情况下,未声明的标识符被视为隐式连线声明。由于 f_o 没有被声明,编译器认为它是一个连线,而不是一个变量。这会导致编译器抱怨所有的赋值。

    // What was typed
    module ca2 (a_i,f_o);
      input  [2:0] a_i;
      output [2:0] f_o;
    
    // What the compiler implicitly declares
      wire   [2:0] a_i;
      wire   [2:0] f_o;
    

    要修复它,您可以声明变量或同时声明端口和变量。

    module ca2 (a_i,f_o);
      input  [2:0] a_i;
      output [2:0] f_o; 
      reg [2:0] f_o;
    
    module ca2 (a_i,f_o);
      input      [2:0] a_i;
      output reg [2:0] f_o; 
    

    【讨论】:

      【解决方案2】:

      f_o 需要声明为 reg。 output reg [2:0] f_o.

      我也不确定你在计算什么,这不是标准的二进制补码。

      module ca2 (
        input      [2:0] a_i,
        output     [2:0] twos_comp,
        output     [2:0] also_twos_comp
      );
      
        assign      twos_comp = ~a_i + 1'b1;
        assign also_twos_comp = -a_i ;
      endmodule
      

      您可能正在处理编码输入,但 twos_complement 是要否定我希望符号位 (MSB) 改变的数字。尽管我们将其称为符号位,但它也包含有关值的信息,因此不能仅仅将其剥离并保持数字不变。

      【讨论】:

      • 也谢谢你,问题的解决方法和Adam12一样。关于您的其他评论,基本上我所做的是,如果输入为正,则保持数字不变,如果确实为负,则更改为 ca2 表示(即:如果输入为 101,则表示 -3,ca2 为 011) .我不知道我是否对这个例子有意义,但无论如何,代码可以满足我的需要。
      • 啊,就是将符号 (MSB) 幅度 (LSB) 转换为二进制补码。
      【解决方案3】:

      第一种解决方案 -> 在时序电路中,输出必须是 reg 的形式。 接下来我们需要知道,在二进制补码中,我们从零位开始到最后,所以条件不正确。 如果零位为一,则零位不变,其余位不变。

      module ca2 (input  [2:0] a_i,output reg [2:0] f_o);
        always @(a_i[2:0] or f_o[2:0]) begin
          if (a_i[0] == 1'b1) begin
            f_o[0] = a_i[0];
            f_o[2:1] = (~a_i[2:1]);
          end
          else
          if(a_i[1]==1'b1) begin
            f_o[1:0] = a_i[1:0];
            f_o[2] = (~a_i[2]);
          end
          else
          if(a_i[2] == 1'b1) begin
            f_o = a_i ;
           end
        end
      endmodule
      

      第二个解决方案 -> 在二进制数中,如果我们从零中减去数字,我们会得到二进制补码。

      module ca2 (input [2:0] a_i,output reg [2:0] f_o);
        always @(a_i[2:0] or f_o[2:0]) begin
          f_o = 3'b000 - a_i ;
        end
      endmodule
      

      第三种解决方案->所有位都变为非和最后,将它们添加到数字一(3'b000 = 3'b0)

      module ca2 (input [2:0] a_i,output reg [2:0] f_o);
        reg [2:0] finish ;
        always @(a_i[2:0] or f_o[2:0]) begin
          finish = (~a_i);
          f_o = finish + 3'b001 ;
        end
      endmodule
      

      【讨论】:

        猜你喜欢
        • 2012-11-23
        • 1970-01-01
        • 1970-01-01
        • 2010-12-08
        • 1970-01-01
        • 1970-01-01
        • 2015-04-12
        • 1970-01-01
        相关资源
        最近更新 更多