Reputation: 191
I am Writing a Verilog function to Locate the index of the first one on the right in the vector.If the vector has no ones, the function should returns the value to the vector’s highest index + 1. Here is the code :
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
Th questions are as follows :
Upvotes: 0
Views: 6312
Reputation: 42623
There are a number of problems with your code.
==
to compare with x
—it always returns false. you must use the ===
operatora
and result
and the order of initializations is not defined. They are not procedural statements. SystemVerilog has made implicitly static variable initializations inside procedural code illegal, and that is the only backward incompatibility with Verilog I can think of.break
for
loopx
values in your code. It's not synthesizable, and it makes debugging your code more difficult if you made a mistake.You can use a disable
statement to get functionality similar to a break
if you want strict Verilog compatibility.
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
Here is the SystemVerilog code
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
Upvotes: 1
Reputation: 354
I would go with a temp variable inside the function block, indicating if the "1" has been found. It wasn't necessary to initialise the index variable with X's, this should do the work: (I believe this is for simulation purposes as there are no input/output ports)
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
This can be tested with icarus verilog:
iverilog first_one.v -o first_one.tb
vvp first_one.tb
Upvotes: 1