编写Verilog函数以在向量中找到第一个索引

问题描述

我正在编写一个Verilog函数,以找到向量右边第一个索引。如果向量没有,则该函数应将值返回向量的最高索引+1。这是代码

module m ();
 parameter n = 3;
  function integer Locate_one (input [n-1:0] a );
    Locate_one ='dx;
    for (integer i =n-1 ; i<=0 ; i=i-1)
      begin
        if(a[i] == 1'b1)
          begin
          Locate_one=i;
            break; 
          end
    end
  
    if (Locate_one=='dx)
      Locate_one=n;
  
  
  
  endfunction
initial begin 
  reg [n-1:0] a = 3'b111;
integer result =  Locate_one (a);
  
  $display("output is %d ",result);
end 
endmodule

问题如下:

  1. 当我们找到最高的函数时,如何突破该函数?我使用的关键字break是我在网上找到的,它是有效的SystemVerilog关键字,而不是Verilog关键字。
  2. 我过去知道向量中没有人的策略是,我已将返回整数初始化为X,然后在函数末尾将变量与X进行了比较。是这样做的一种好方法,还是还有另一种更好的方法可以进行这种比较?

解决方法

我将在功能块中使用一个temp变量,指示是否已找到“ 1”。不必用X初始化索引变量,这应该可以完成工作:(我相信这是出于仿真目的,因为没有输入/输出端口)

module first_one ();

  parameter n = 3;
  reg [n-1:0] a;

  function integer locate_one;
    input [n-1:0] a;
    integer i;
    reg found_temp;
    begin
    found_temp = 0;
    for (i=0; i<n; i=i+1) begin
      if(a[i] == 1'b1 & ~found_temp) begin
        locate_one = i;
        found_temp = 1;
      end
    end
    if(~found_temp)
      locate_one = n;
    end
  endfunction

  initial begin
    a = 0;
    $monitor("a = %b : index = %d",a,result);
    #100 $finish;
  end

  wire [$clog2(n)-1:0] result = locate_one(a);

  always
    #1 a = $urandom;

endmodule

这可以用icarus verilog进行测试:

iverilog first_one.v -o first_one.tb
vvp first_one.tb
,

您的代码有很多问题。

  1. 您不能使用==x进行比较-它总是返回false。您必须使用===运算符
  2. 您正在初始化两个静态变量aresult,并且初始化顺序未定义。它们不是程序性声明。 SystemVerilog已将程序代码内的隐式静态变量初始化定为非法,这是我能想到的与Verilog唯一的向后不兼容。
  3. 您的代码除break外还具有许多SystemVerilog构造
    1. for循环中声明变量
    2. 没有开始/结束关键字的功能/任务主体。
  4. 您不应在代码中使用x值。它是不可综合的,如果您犯了一个错误,它将使您的代码调试更加困难。
  5. 您的循环条件与您所需要的相反。

如果您想要严格的Verilog兼容性,则可以使用disable语句获得与break类似的功能。

module m ();
 parameter n = 5;
  function integer Locate_one (input [n-1:0] a );
    integer i;
    begin : block
    Locate_one = n;
      for (i =n-1 ; i>=0 ; i=i-1)
      begin
        if(a[i] == 1'b1)
          begin
          Locate_one=i;
            disable block; 
          end
    end
    end 
  endfunction
  
    reg [n-1:0] a = 3'b111;
initial begin 
integer result;  
  result =  Locate_one (a);     
  $display("output is %d ",result);
end 
endmodule

这是SystemVerilog代码

module m ();
 parameter n = 5;
  function int Locate_one (input [n-1:0] a );
    Locate_one = n;
      for (int i =n-1 ; i>=0 ; i=i-1)
      begin
        if(a[i] == 1'b1)
          begin
          Locate_one=i;
            break; 
          end
    end
  endfunction
    logic [n-1:0] a = 3'b111;
    int result;
initial begin 
  result =  Locate_one (a);     
  $display("output is %d ",result);
end 
endmodule