How to return an array from a function with the same name as that of the function in system verilog? - system-verilog

module rev_array;
int array_in[10]={0,1,2,3,4,5,6,7,8,9};
typedef integer array[9:0];
function array reverse(int array_in[10]);
for(int j=$size(array_in)-1,int i=0;j>=0;j--,i++)
begin
reverse[j]=array_in[i];
end
// working for(integer k=0;k<$size(array_in)-1;k++)
// working $display("reverse[%0d]:%0d", k, reverse[k]);
$display("inside function");
endfunction:reverse
initial
begin
reverse(array_in);
for(integer k=0;k<$size(array_in)-1;k++)
begin
$display("reverse[%0d]:%0d", k, reverse[k]);
end
end
endmodule
Error-[IUS] Illegal use of scope
testbench.sv, 22
rev_array, "rev_array.reverse"
Scope cannot be used in this context
Error-[XMRIBS] Illegal bit select
testbench.sv, 22
Error is found in following cross-module reference, illegal bit select on
the target.
Source info: $display("reverse[%0d]:%0d", k, rev_array.reverse[k]);
I am trying to reverse an array and return it in system verilog function, I am able to see the reversed array inside the function by printing it but
when I try to print it using $display outside the function, I think it is
not being returned properly somehow, in the 4th line from end, getting
errorError-[IUS]

your both issues are related to the line where you use reverse function name as an array within $display.
$display("reverse[%0d]:%0d", k, reverse[k]);
--------------------------------^^^^^^^^^^
this is an illegal syntax causing both messages.
your initial block should look like the following.
initial
begin
array result;
result = reverse(array_in);
//^^^^^^^^^^^^^^^^^^^^^^^^^//
for(integer k=0;k<$size(array_in)-1;k++)
begin
$display("reverse[%0d]:%0d", k, result[k]);
// ^^^^^^ //
end
end
call the function and use returned results for display.

Related

Converting arrays from signed to integer in VHDL?

I have declared an array
type datastream is array(0 to 10) of signed (5 downto 0);
For simulation, I want to display the array as integer-numbers
So I created
type datastream_int is array(0 to 10) of integer;
and
signal DIN_ARRAY: datastream;
signal DIN_ARRAY_int: datastream_int;
...
DIN_ARRAY_real <= datastream_int(DIN_ARRAY);
But it fails. How to convert it? Dont want to use a for loop
The numeric_std package, that I assume you are using, provides a to_integer function to convert from a single signed value to a single integer object. For an array, you're going to have to use a for loop. Something like this:
for i in DIN_ARRAY'range loop
DIN_ARRAY_int <= to_integer(DIN_ARRAY(i));
end loop;
You could also provide a conversion function (it will also contain a for loop)
function datastream_to_datastream_int( d : datastream ) return datastream_int is
variable r : datastream_int;
begin
for i in d'range loop
r(i) := to_integer(d(i));
end loop;
return r;
end function;
....
--no loop required
DIN_ARRAY_int <= datastream_to_datastream_int(DIN_ARRAY);
So, there will be a for loop somewhere.
Your code fails because you have attempted a type conversion, which is only allowed between similar types - ie. array or record types where the element types match between the two types.
PS. VHDL 2008 provides an integer_vector type in the std.standard library (which is included by default) which may help by allowing you to do this:
signal DIN_ARRAY_int: integer_vector(DIN_ARRAY'range);
If you did decide to keep datastream_int as per your original, you could type convert it to an integer_vector, because the types are similar:
my_iv <= integer_vector(DIN_ARRAY_int);

I want to reverse and return an array in a function in system verilog, i tried below code and i am getting following error

module rev_array;
initial
begin
int array_in[10]={0,1,2,3,4,5,6,7,8,9};
typedef integer array[9:0];
function array reverse(int array_in[10]);
array reverse;
for(integer i=0;i<$size(array_in)-1;i++)
begin
for(int j=$size(array_in)-1;j>=0;j--)
begin
reverse[j]=array_in[i];
end
end
return reverse;
endfunction:reverse
reverse(array_in);
for(integer k=0;k<$size(array_in)-1;k++)
begin
$display("reverse[%0d]:%0d", k, reverse[k]);
end
end
endmodule
For the above code, I am getting error
Error-[SE] Syntax error
Following verilog source has syntax error :
"testbench.sv", 7: token is 'function'
function array reverse(int array_in[10]);
I want to return an array named reverse(same name as the function ) which has 10 elements, each element being an integer, what am I doing wrong here ?
You cannot define a function in the middle of a procedural block. Move it to the top level of the module. You have many other problems. Note there is a built-in reverse array method.

Error (10686): SystemVerilog error at file.sv(8): InstAddress has an aggregate value

I am trying to compile the following SystemVerilog, and I get the following error "Error (10686): SystemVerilog error at InstRom.sv(8): InstAddress has an aggregate value."
module InstRom#(parameter A = 16, parameter W = 9)
(
input InstAddress[A-1:0],
output logic InstOut[W-1:0]
);
logic[W-1:0] instr_rom[2**(A)];
always_comb InstOut = instr_rom[InstAddress];
initial begin
$readmemb("cordic.txt", instr_rom);
end
endmodule
What am I doing wrong?
InstAddress is an unpacked array of bit, not a bit vector (i.e. a packed array). The same applies to InstOut. Change the declaration to
input logic [A-1:0] InstAddress,
output logic [W-1:0] InstOut
and your code should work.

Lua - Function That Creates Detours

I need to make several detours to various functions and doing it one by one is just not an option. I'm looking for a function that will take a table, ideally, and this table is class. Loop through it and for each key, value pair that is a function make a function pointer with a prefix before the original function name. I have tried several variations to achieve this effect, but they all yield different problems. Some simply will not make detour pointer no matter what you give to them, others make detour pointers but they don't work, and some will overflow the stack or simply not be recognized.
I want to know if there is a way, ie rawsets, metatable overrides, constant looping until they do match, etc to make it so the function can get a table (or a string that has the same name as the table, thus a loadstring method would work here too) and loop through each function and make a working detour pointer...no matter what.
I prefer using the self:prefix_orig_name(...) syntax [... can be replaced with actual args].
Here's 2 variations I have tried with example useage.
-- 1st Method
detours = detours or {}
function detour(object, class) -- Class is an extra arg that I would send if for some reason just sending an object didn't work...it was theory oh'ed
if detours[object] then -- Check if the detour already exists...might be worth remaking it especially if the function gets overridden several times in different places?
print("detour: Previous " .. object .. " detour found, using previous detour")
return
end
for name, func in pairs(class and class or loadstring("return " .. object)()) do
-- the loadstring method here is used because the argument received is a string of the same name as the table...thus loading it will yield a table
if type(func) == "function" then
local execute, error = loadstring(object .. ".custom_detour_" .. name .. " = " .. object .. "." .. name) -- This makes the actual pointer
if error then
print("detour Error: " .. " Failed to detour: " .. object .. " Error: " .. error)
end
local luanch, assert = pcall(execute)
if not luanch then
print("detour Error: " .. " Failed to detour: " .. object .. " Error: " .. assert)
end
end
end
print("Table: " .. object .. " successfully detourd")
detours[object] = true -- tells us we made a detour of this table/string
end
-- 2nd Method
function detour(object) -- Takes a table
for k, v in pairs(object) do
if type(v) == "function" and not detours[k] then
if not object.custom_detour_ then
object.custom_detour_ = clone(object) -- use a simple cloning function (shallow) to put a clone of the main table into a sub table of the main table
end
if object["custom_detour_" .. k] ~= object.custom_detour_[k] then
object["custom_detour_" .. k] = object.custom_detour_[k] -- this makes it so the self:custom_detour_orig_name(...) syntax can be used, if I am not mistaken
end
end
end
end
-- Example Usage:
MyClass = class() -- class function is relatively OOP standard
function MyClass:init()
self._something = true
end
function MyClass:change(value)
self._something = value
end
function MyClass:table_print(tbl) -- just making funcs up
for k, v in pairs(tbl) do
print(v)
end
end
my_class = MyClass:new()
-- 1st Method
detour("MyClass")
--2nd Method
detour(MyClass)
I personally prefer the 1st method or at least a string, because I can log each detour and if a problem arises later on, it makes debugging easier...but I am for whatever will work.
Simple detouring is easy to do with closures; no need for loadstring:
function detour(cls)
local detours = {}
for key, value in pairs(cls) do
if type(value) == "function" then -- note: ignores objects with __call metamethod
detours["custom_detour_"..key] = function(...)
-- Do whatever you want here
return value(...)
end
end
end
for key, value in pairs(detours) do
cls[key] = value
end
end

How can we define a 3-dimensional array of geometry?

I want to write a code for postgis in pgAdmin that is based on postgresql. It defines a 3-dimensional array of geometry.
I used this code for it:
DECLARE
G geometry[9][9][9];
BEGIN
for i IN 1..9 LOOP
for j IN 1..9 LOOP
for k IN 1..9 LOOP
G[i][j][k] := [value that I want];
END LOOP;
END LOOP;
END LOOP;
But it returned this error:
"array subscript out of range"
I used this instead:
DECLARE
G geometry[9][9][9];
BEGIN
for i IN array_lower(G, 1)..array_upper(G, 1) LOOP
for j IN array_lower(G, 1)..array_upper(G, 1) LOOP
for k IN array_lower(G, 1)..array_upper(G, 1) LOOP
G[i][j][k] := [value that I want];
END LOOP;
END LOOP;
END LOOP;
I have a different error this time:
"lower bound of FOR loop cannot be null"
I used this in BEGIN Part and solved all the errors:
G[1][1][1] := '01010000200400000000000000000000000000000000000000';
But I think this is not true and doesn't calculate all of the iterations for loops. I think this takes in account only the G[1][1][1]. What should I do now?
In PostgreSQL, simply declaring the array dimensions does not initialize or pre-allocate anything. The array is dynamic in all its dimensions. That differs significantly from the multi-dimensional array implementations found in general programming language like C.
To mimic the logic of these languages, you may first initialize the 9x9x9 array with a statement like this:
G:=array_fill('point(0 0)'::geometry, array[9,9,9]);
Then the rest of the code will just work when refering to G[i][j][k] either as source or destination of assignments.