编写一个 Verilog 函数来定位向量中右侧第一个的索引
Writing a Verilog function to Locate the index of the first one on the right in the vector
我正在编写一个 Verilog 函数来定位 vector.If 向量中右边第一个的索引,该函数应该 return 将值设为向量的最高值index + 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 关键字。
- 我曾经知道向量中没有一个的策略是我已经将 return 整数初始化为 X 然后我在函数结束时将变量与 X 进行了比较.这是这样做的好方法还是有另一种更好的方法来进行比较?
我会在功能块内使用一个临时变量,指示是否已找到“1”。没有必要用 X 初始化索引变量,这应该可以完成工作:(我相信这是为了模拟目的,因为没有 input/output 端口)
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
进行比较——它总是 returns 错误。您必须使用 ===
运算符
- 您正在初始化两个静态变量
a
和 result
,并且未定义初始化顺序。它们不是程序性陈述。 SystemVerilog 已将过程代码中的隐式静态变量初始化设为非法,这是我能想到的唯一与 Verilog 的向后不兼容。
- 除了
break
之外,您的代码还有很多 SystemVerilog 结构
- 在
for
循环中声明一个变量
- 一个 function/task 没有 begin/end 关键字的正文。
- 您不应在代码中使用
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
我正在编写一个 Verilog 函数来定位 vector.If 向量中右边第一个的索引,该函数应该 return 将值设为向量的最高值index + 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 关键字。
- 我曾经知道向量中没有一个的策略是我已经将 return 整数初始化为 X 然后我在函数结束时将变量与 X 进行了比较.这是这样做的好方法还是有另一种更好的方法来进行比较?
我会在功能块内使用一个临时变量,指示是否已找到“1”。没有必要用 X 初始化索引变量,这应该可以完成工作:(我相信这是为了模拟目的,因为没有 input/output 端口)
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
进行比较——它总是 returns 错误。您必须使用===
运算符 - 您正在初始化两个静态变量
a
和result
,并且未定义初始化顺序。它们不是程序性陈述。 SystemVerilog 已将过程代码中的隐式静态变量初始化设为非法,这是我能想到的唯一与 Verilog 的向后不兼容。 - 除了
break
之外,您的代码还有很多 SystemVerilog 结构- 在
for
循环中声明一个变量 - 一个 function/task 没有 begin/end 关键字的正文。
- 在
- 您不应在代码中使用
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