问题描述
我正在编写一个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
问题如下:
- 当我们找到最高的函数时,如何突破该函数?我使用的关键字break是我在网上找到的,它是有效的SystemVerilog关键字,而不是Verilog关键字。
- 我过去知道向量中没有人的策略是,我已将返回整数初始化为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
,
您的代码有很多问题。
- 您不能使用
==
与x
进行比较-它总是返回false。您必须使用===
运算符 - 您正在初始化两个静态变量
a
和result
,并且初始化顺序未定义。它们不是程序性声明。 SystemVerilog已将程序代码内的隐式静态变量初始化定为非法,这是我能想到的与Verilog唯一的向后不兼容。 - 您的代码除
break
外还具有许多SystemVerilog构造- 在
for
循环中声明变量 - 没有开始/结束关键字的功能/任务主体。
- 在
- 您不应在代码中使用
x
值。它是不可综合的,如果您犯了一个错误,它将使您的代码调试更加困难。 - 您的循环条件与您所需要的相反。
如果您想要严格的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