Does Quartus II support line.all? - vhdl

I implemented some VHDL code to exports FSM state encodings at compile time, which can be read back by Xilinx ChipScope. This functionality is tested with Xilinx ISE 14.7, iSim 14.7 and Mentor Graphic's QuestaSim 10.2c. My design can be synthesized with an alternative top-level as well for Altera FPGAs, but Quartus II seems to have a problem with return line.all;.
Quartus II (14.0) error messages:
Error (10351): VHDL Subprogram Body error at sata_PhysicalLayer.vhdl(504): function "dbg_GenerateEncodings" does not always return a value
Error (10346): VHDL error at debug.vhdl(47): formal port or parameter "encodings" must have actual or default value
Error (10657): VHDL Subprogram error at sata_PhysicalLayer.vhdl(514): failed to elaborate call to subprogram "dbg_ExportEncoding"
In the following, I'll describe my code.
VHDL Code
The design uses 3 functions to export the FSM state encodings:
encode the current local FSM state as a binary value -> dbg_EncodeState
(the result of this function is connected to the ILA ports)
transform all states of the local FSM into a semicolon separated string -> dbg_GenerateEncodings
format this string and write it's elements into a token-file -> dbg_ExportEncoding
(this function is located in a package)
FSM declaration:
TYPE T_STATE IS (
ST_HOST_RESET,
ST_HOST_SEND_COMRESET,
ST_HOST_SEND_COMRESET_WAIT,
[...]
ST_HOST_SEND_ALIGN,
ST_HOST_TIMEOUT,
ST_HOST_LINK_OK
);
-- OOB-Statemachine
SIGNAL State : T_STATE := ST_HOST_RESET;
SIGNAL NextState : T_STATE;
local functions - per entity functions:
function dbg_EncodeState(st : T_STATE) return STD_LOGIC_VECTOR is
begin
return to_slv(T_STATE'pos(st), log2ceilnz(T_STATE'pos(T_STATE'high) + 1));
end function;
function dbg_GenerateEncodings return string is
variable l : STD.TextIO.line;
begin
for i in T_STATE loop
STD.TextIO.write(l, str_replace(T_STATE'image(i), "st_host_", ""));
STD.TextIO.write(l, ';');
end loop;
return l.all;
end function;
global function - defined in debug.pkg.vhdl:
impure function dbg_ExportEncoding(Name : STRING; encodings : string; tokenFileName : STRING) return BOOLEAN is
file tokenFile : TEXT open WRITE_MODE is tokenFileName;
variable cnt, base : integer;
variable l : line;
begin
report "Exporting encoding of '" & Name & "' to '" & tokenFileName & "'..." severity note;
report "dbg_ExportEncoding: '" & encodings & "'" severity note;
-- write file header
write(l, "# Encoding file for '" & Name & "'"); writeline(tokenFile, l);
write(l, "#"); writeline(tokenFile, l);
write(l, "# ChipScope Token File Version"); writeline(tokenFile, l);
write(l, "#FILE_VERSION=1.0.0"); writeline(tokenFile, l);
write(l, "#"); writeline(tokenFile, l);
write(l, "# Default token value"); writeline(tokenFile, l);
write(l, "#DEFAULT_TOKEN="); writeline(tokenFile, l);
write(l, "#"); writeline(tokenFile, l);
-- write state entires
cnt := 0;
base := encodings'left;
for i in encodings'range loop
if encodings(i) = ';' then
-- Leave the str_trim call in!
-- Otherwise, the new parser of ISE 14.7 fails to slice properly.
write(l, str_trim(encodings(base to i-1)));
write(l, character'('='));
write(l, raw_format_nat_hex(cnt));
writeline(tokenFile, l);
cnt := cnt + 1;
base := i+1;
end if;
end loop;
file_close(tokenFile);
return true;
end function;
The last portion of code is a dummy constant in the entity, which calls the export function:
CONSTANT test : boolean := dbg_ExportEncoding("OOBControl (Host)", dbg_GenerateEncodings, MY_PROJECT_DIR & "CSP/FSM_OOB_Host.tok");
used auxilary functions:
log2ceilnz(x) calculates the needed bits to encode x symbols in binary
to_slv converts everything into a std_logic_vector; in this case a integer to slv
str_replace replaces a string by a string
str_trim returns a string from str'low to the first occurrence of NUL
raw_format_nat_hex formats a natural to a hex string
Additional Notes:
All vhdl files are marked as VHDL-2008.
My Questions:
Has anyone experience with line.all in a Quartus environment?
Is there a workaround?
Is there a better solution to achieve the export task without using strings of constant length?
Work around:
I wrapped my function dbg_GenerateEncodings in a generate statement:
genXilinx : if (VENDOR = VENDOR_XILINX) generate
function dbg_GenerateEncodings return string is
[...]
constant test : boolean := dbg_ExportEncoding("OOBControl (Host)", dbg_GenerateEncodings, MY_PROJECT_DIR & "CSP/FSM_OOB_Host.tok");
begin
end generate;
In contrast to XST, Quartus does not check functions inside a generate block.

See Quartus II VHDL Support, Section 14 Predefined language environment, the table entry 14.3, Construct TEXTIO, the rightmost column VHDL 1993 Support:
Supported. File I/O cannot be synthesized; therefore, calls to TEXTIO
functions are ignored.
If you can't use TEXTIO for synthesis you could imagine a pointer to a line buffer might not be of any use either.
There's this issue of how you could write to a FILE from an FPGA. without any knowledge of the host operating system or specifying a physical interface.
You can manage to synthesize the remainder of your design by surrounding unsupported constructs with translate off and translate on directives. See VHDL Synthesis Attributes and Directives.

Related

How to write new line to file in VHDL?

I would like to separate my data with new line character in an output file, but the following codes result in error "can't resolve overload for procedure call":
write(out_line, "\n");
write(out_line, "");
write(out_line, '');
An example code how I want to use it:
ENTITY writer IS
PORT ( clk : IN STD_LOGIC := '0'; start : IN STD_LOGIC := '0');
END ENTITY;
ARCHITECTURE arch OF writer IS
SIGNAL vect : STD_LOGIC_VECTOR (2 downto 0) := "000";
TYPE state_type IS (init, write_file);
SIGNAL state : state_type := init;
BEGIN
PROCESS (clk, start)
FILE out_file : text;
VARIABLE out_line : line;
BEGIN
IF rising_edge(clk) THEN
CASE state IS
WHEN init =>
IF start = '1' THEN
state <= write_file;
ELSE
state <= init;
END IF;
WHEN write_file =>
state => init;
FOR i IN 0 TO 10 LOOP
write(out_line, vect);
writeline(out_file, out_line);
-- write(out_line, "\n"); <--
-- write(out_line, ""); <--
-- write(out_line, ''); <-- None of these work
writeline(out_file, out_line);
END LOOP;
END CASE;
END IF;
END PROCESS;
END ARCHITECTURE;
So I would like to know, is it possible in VHDL? If yes, how?
The following will consistently give you a single blank line:
write(out_line, string'(""));
writeline(out_file, out_line);
I suspect what #Dani posted may be tool dependent. For example while on one popular simulator, the following produces one line feed:
write(out_line, LF);
writeline(out_file, out_line);
However when I add a space after the LF, I get two lines:
write(out_line, LF & ' ');
writeline(out_file, out_line);
Creating a minimal, complete and verifiable example from the question's incomplete sample code:
library ieee; -- ADDED
use ieee.std_logic_1164.all; -- ADDED
use std.textio.all; -- ADDED
-- use ieee.std_logic_textio.all; -- ADDED for revisions earlier than -2008
ENTITY writer IS
-- PORT ( clk : IN STD_LOGIC := '0'; start : IN STD_LOGIC := '0');
END ENTITY;
ARCHITECTURE arch OF writer IS
SIGNAL vect : STD_LOGIC_VECTOR (2 downto 0) := "000";
-- TYPE state_type IS (init, write_file);
-- SIGNAL state : state_type := init;
BEGIN
PROCESS -- (clk, start)
FILE out_file : text;
VARIABLE out_line : line;
BEGIN
file_open(out_file, "some_file", WRITE_MODE); -- ADDED
-- IF rising_edge(clk) THEN
-- CASE state IS
-- WHEN init =>
-- IF start = '1' THEN
-- state <= write_file;
-- ELSE
-- state <= init;
-- END IF;
-- WHEN write_file =>
-- state => init;
FOR i IN 0 TO 10 LOOP
write(out_line, vect);
writeline(out_file, out_line);
-- write(out_line, "\n"); <--
-- write(out_line, ""); <--
-- write(out_line, ''); <-- None of these work
writeline(out_file, out_line);
END LOOP;
-- END CASE;
-- END IF;
wait; -- ADDED
END PROCESS;
END ARCHITECTURE;
demonstrates a way to get a blank line in the output:
some_file contents:
000
000
000
000
000
000
000
000
000
000
000
The second writeline procedure call produces an empty line without an intervening write procedure call.
Why is seen in IEEE Std 1076-2008 16.4 Package TEXTIO:
Procedures READLINE, WRITELINE, and TEE declared in package TEXTIO read and write entire lines of a file of type TEXT. Procedure READLINE causes the next line to be read from the file and returns as the value of parameter L an access value that designates an object representing that line. If parameter L contains a non-null access value at the start of the call, the procedure may deallocate the object designated by that value. The representation of the line does not contain the representation of the end of the line. It is an error if the file specified in a call to READLINE is not open or, if open, the file has an access mode other than read-only (see 5.5.2). Procedures WRITELINE and TEE each cause the current line designated by parameter L to be written to the file and returns with the value of parameter L designating a null string. Procedure TEE additionally causes the current line to be written to the file OUTPUT. If parameter L contains a null access value at the start of the call, then a null string is written to the file or files. If parameter L contains a non-null access value at the start of the call, the procedures may deallocate the object designated by that value. It is an error if the file specified in a call to WRITELINE or TEE is not open or, if open, the file has an access mode other than write-only.
The language does not define the representation of the end of a line. An implementation shall allow all possible values of types CHARACTER and STRING to be written to a file. However, as an implementation is permitted to use certain values of types CHARACTER and STRING as line delimiters, it might not be possible to read these values from a TEXT file.
A line feed (LF) format effector occurring as an element of a string written to a file of type TEXT, either using procedure WRITELINE or TEE, or using the WRITE operation implicitly defined for the type TEXT, is interpreted by the implementation as signifying the end of a line. The implementation shall transform the LF into the implementation-defined representation of the end of a line.
...
For each WRITE, OWRITE, and HWRITE procedure, after data is appended to the string value designated by the parameter L, L designates the entire line. The procedure may modify the value of the object designated by the parameter L at the start of the call or may deallocate the object.
If deallocation occurs out_line will have a value of null after a writeline call and a null string is written in the immediately following writeline call which also provides an end of line.
If the object value accessed by out_line is a null array (having no elements, 5.3.2.2 Index constraints and discrete ranges, a null string) the immediately following writeline call will result in an end of line being written to the file.
In essence your code example already contains one of these methods for writing a blank line, which depends on whether deallocation is used conditionally (may).
Variants of allocate() and free() can be relatively expensive in terms of execution time and when the size of the allocated object and it's element size is known a smaller 'allocated' object can be written to the same object space saving simulation time. The simulation kernel representation of an array object can have bounds separate from the array value, deallocation and re-allocation can be reserved for when the object size is larger than the previously allocated size or an explicit deallocate call occurs.
There's also a requirement that an implementation translate an LF character to an end of line in a write to a file. This is the other mechanism that allows you to write an LF character as the last or only character to a line and get a following blank line.
You could also explicitly write a null string to out_line
write(out_line, string'(""));
prior to the second writeline call. The qualified expression provides the type of the string literal unlike the attempt commented out in the original question where the type of the string literal can't be determined. See 9.3.2 Literals "... The type of a string or bit string literal shall be determinable solely from the context in which the literal appears, excluding the literal itself but using the fact that the type of the literal shall be a one-dimensional array of a character type. ...". The procedure write would be ambiguous in this context, failing overload resolution (12.5 The context of overload resolution).
Finally after a lot of searching and trying I found that the following code works:
write(out_line, lf);
writeline(out_file, out_line);
I found that write(out_line, cr); does the same thing, and write(out_line, nul); adds ' ' character between the outputs.

vhdl package export symbols it includes from another package

Let's say I have a package strkern (I do) which exports function: strlen
package strkern is
function strlen(s: string) return natural;
end package strkern;
I write a new package stdstring which defines lots of exciting new operators, but also wants to reexport strlen
use work.strkern.all;
package stdstring is
-- rexport strlen
-- define exciting new operators
end package stdstring
So if one codes
use work.stdstring.all;
You get strlen(), and the exciting new operators.
How does one "re export" a function/type import from a sub package?
Short of having a dummy implementation with a new name that just calls the "to be imported" implementation
function strlen(s: string) return natural is
return strkern.strlen(s);
end function strlen;
By providing a Minimal, Complete and Verifiable example:
package strkern is
function strlen(s: string) return natural;
end package strkern;
package body strkern is
function strlen(s: string) return natural is
begin
return s'length;
end function;
end package body;
use work.strkern.all; -- NOT USED in this foreshortened example
package stdstring is
-- rexport strlen
-- define exciting new operators
alias strlen is work.strkern.strlen [string return natural];
end package stdstring;
use work.stdstring.all;
entity foo is
end entity;
architecture fum of foo is
begin
assert false
report "strlen of ""abcde"" is " & integer'image(strlen("abcde"))
severity NOTE;
end architecture;
we can demonstrate the use of an alias in a package to provide visibility of a declaration of a function found in another package.
ghdl -r foo
std_flub_up.vhdl:25:5:#0ms:(assertion note): strlen of "abcde" is 5
The questions code snippets don't demonstrate any 'exciting new operators' where operator is specific to predefined operators in VHDL. See IEEE Std 1076-2008 9.2 Operators.
The method of using an alias to make name visible is shown in
6.6.3 Nonobject aliases. Note that an alias for a subprogram requires a signature.
Some readers may be curious why the selected name suffix strlen is visible in the above MCVe alias. See 12.3 Visibility:
Visibility is either by selection or direct. A declaration is visible by selection at places that are defined as follows:
a) For a primary unit contained in a library: at the place of the suffix in a selected name whose prefix denotes the library.
...
f) For a declaration given in a package declaration, other than in a package declaration that defines an uninstantiated package: at the place of the suffix in a selected name whose prefix denotes the package.
...
Basically a selected name (work.strkern.strlen) suffix (strlen) declaration occurs in a separate name space defined by the prefix which will designate a primary unit (package strkern here in library work). The package declaration is made visible by rule a. The suffix is made visible by rule f. The library work is made visible by an implicit library declaration (see 13.2 Design libraries).
You cannot re-export anything from one package in another. The only option is to use both the strkern package and the stdstring package.
use work.strkern.all;
use work.stdstring.all;
I would recommend against creating a dummy implementation, because if a user were to include both packages, the duplicate function signatures will cause both to be invisible as the compiler will not know which one to use. The user will have to be explicit about which function to use:
work.strkern.strlen("Hello world");
work.stdstring.strlen("Hello world");
You can create aliases to the functions in the first package, but they cannot have the same name as the original:
alias str_len is strlen[string];
Maybe you want to investigate context clauses from VHDL2008. These allow you use several libraries and packages in a single context, and can be included elsewhere to include all the clauses in the context. The only issue here is that you are not allowed to use work, because work only means the "current working library". If you were to include a context within a another library, the work reference is now incorrect.
context my_string_packages is
library my_string_lib;
use my_string_lib.strkern.all;
use my_string_lib.stdstring.all;
end context my_string_packages;
library my_string_lib;
context my_string_lib.my_string_packages;
Package strdemo is aliasing strlen, strncpy
package strdemo is
alias strlen is work.strkern.strlen[string return natural];
alias strncpy is work.strkern.strncpy [string, string, integer, natural, natural, boolean];
function "+"(a:string; b:string) return string;
function "-"(a:string; b:string) return boolean;
function "*"(a:integer; b:character) return string;
function "*"(a:boolean; b:string) return string;
end package strdemo;
Here's the full listing of strkern
package strkern is
constant STRING_EOF : character := nul; -- \0 string termination from c
-- We can't assign strings but can easily assign string_segments to variables
-- Making a record instead of array because a record has no operators defined for it.
-- An array already has the & operator.
type string_segment is record
start, stop: natural;
end record string_segment;
-- We have 3 kinds of string: string, cstring, vstring. All export functions return vstring
-- There is no functionality difference between the 3, just implementation.
-- All functions accept string and return vstring. They can accept any string type but will
-- always return a vstring.
subtype cstring is string; -- null terminated c strlen <= 'length 'left = 1
subtype vstring is string; -- vhdl string strlen = 'length 'left >= 1
function strlen(s: string) return natural;
function safeseg(s: string; ss: string_segment := (0, 0); doreport: boolean := false) return vstring;
procedure strncpy(dest: out cstring; src: string; n: integer := -2; at: natural := 1; from: natural := 1; doreport: boolean := false);
end package strkern;
package body strkern is
-- Error messages
constant safeseg_left: string := "right operand: ";
constant safeseg_right: string := " overflows strlen: ";
-- Borrow integer whenelse() from stdlib
function whenelse(a: boolean; b, c: integer) return integer is begin
if a then return b; else return c;
end if;
end function whenelse;
function ii(i: integer) return vstring is begin
return integer'image(i);
end function ii;
-- These 4 are the only functions/procedures that use & = or segment/index strings
-- strlen is fundamental. It gives the correct answer on any type of string
function strlen(s: string) return natural is
variable i: natural := s'left;
begin
while i < s'right and s(i) /= STRING_EOF loop
i := i+1;
end loop;
if s'length = 0 then
return 0;
elsif s(i) = STRING_EOF then
return i-s'left;
else
return i+1-s'left;
end if;
end function strlen;
-- safely segment a string. if a=0 convert a cstring to vhdl string
-- otherwise use strlen and 'left to return correct segment string.
function safeseg(s: string; ss: string_segment := (0, 0); doreport: boolean := false) return vstring is
constant len: natural := strlen(s); -- strlen is an expensive function with long strings
-- This is the reason for stdstring. Debug reports get very verbose.
impure function dump return vstring is begin
return " safeseg(s, (" & ii(ss.start) & ", " & ii(ss.stop) & ")) s'left=" & ii(s'left) & " strlen(s)=" & ii(len);
end function dump;
begin
if doreport then -- debug. invokers can switch on doreport
report dump;
end if;
if ss.start = 0 then -- if ss.start=0 return the entire string as defined by strlen()
if len=0 then -- cannot use whenelse here
return "";
else
return s(s'left to s'left + len-1);
end if;
else
assert ss.stop <= len report safeseg_left & natural'image(ss.stop) & safeseg_right & dump;
return s(s'left + ss.start-1 to s'left + whenelse(ss.stop=0, s'length, ss.stop) -1);
end if;
end function safeseg;
-- The only way to assign strings
-- strncpy(dest, src) is effectively strcpy(dest, src) from C
-- It will non fail assert on overflow followed by an array out of bounds error
procedure strncpy(dest: out cstring; src: string; n: integer := -2; at: natural := 1; from: natural := 1; doreport: boolean := false) is
constant srclen: natural := strlen(src);
constant destspace: integer := dest'length + 1 - at;
variable copylen: integer := srclen + 1 - from;
impure function dump return vstring is begin
return " strncpy(str(" & ii(dest'length) & "), str(" & ii(srclen) & "), " & ii(n) & ", " & ii(at) & ", " & ii(from) & ")";
end function dump;
begin
if doreport then
report dump;
end if;
if n >= 0 and copylen > n then
copylen := n;
end if;
if n = -1 and copylen > destspace then
copylen := destspace;
end if;
assert copylen <= destspace report "overrun" & dump;
if copylen > 0 then
dest(at to at + copylen - 1) := src(from to from + copylen - 1);
end if;
if copylen < destspace then
dest(at + copylen) := STRING_EOF;
end if;
end procedure strncpy;
end package body strkern;

Best way to modify strings in VHDL

I'm currently writing a test bench for a VHDL design I made and I need to write a message to a text file. The message is of the format
[instance_name];[simulation_time]
(i.e. U0;700 ns) and the filename must be [instance_name].log. Getting the instance name and simulation time is no problem, but writing to a custom filename has been problematic. Under simulation, the instance name will be given in the format:
"U0\ComponentX\test\"
and I would like to replace the slashes with underscores. Is there an easy way to do this?
Our PoC Library has quite a big collection on string operations/functions. There is a str_replace function in PoC.strings that should solve your question. There is also the PoC.utils package with non string related functions, that could also be helpful in handling strings and file I/O.
A simple implementation:
function replace(str : STRING) return STRING
variable Result : STRING(str'range) := str;
begin
for i in str'range loop
if (Result(i) = '\') then
Result(i) := '_';
end if;
loop;
return Result;
end function;
Usage:
constant original : STRING := "U0\ComponentX\test\";
constant replaced : STRING := replace(original);
Simple replace character function that is a bit more versatile and does the same job would be (nothing wrong with #Paebbels's answer)
function fReplaceChar(
a : character;
x : character;
s : string) return string
is
variable ret : string(s'range) := s;
begin
for i in ret'range loop
if(ret(i) = a) then
ret(i) := x;
end if;
end loop;
return ret;
end function fReplaceChar;
If there are more than one character to replace, one can always stack the function:
function fReplaceChar(
a : character;
b : character;
x : character;
s : string) return string
is
begin
return fReplaceChar(b, x, fReplaceChar(a, x, s));
end function fReplaceChar;
or function call:
fReplaceChar(')','_',fReplaceChar(':','(','_',tb'instance_name));
So for example:
process
begin
report lf & tb'instance_name & lf &
fReplaceChar(')','_',fReplaceChar(':','(','_',tb'instance_name));
wait;
end process;
gives:
# ** Note:
# :tb(sim):
# _tb_sim__

Is it possible to check the length of an input text file?

In my VHDL project, my input is going to be extracted from a text file containing n bits of 1's and 0's. I am trying to make it as general as possible. I am familiar with how to read and write on a text file using test-bench, but I don't know how to check its length.
My code normally takes 64 bit as input, pass them through all the blocks and generate an output. If the remaining bits length is less than 64 then it passes through a specific block.
Let's say the text file contains 1000 bits. 15 x 64 = 960. 960 bits will pass through all blocks, the remaining 40 will pass by a specific block. This looks straight forward but in order for me to do such operations i need to know the length of the text file. If anyone can help that would be very beneficial.
The VHDL data structure length should be considered, not the file length since that is implementation specific and not VHDL specified.
If the bits are in one long string that is to be chopped up into 64-bit pieces with a remainder, then the entire string can be read into a VHDL line type, and reading from that line to a std_logic_vector type can then depend on the remaining bits (characters) in the line.
Below is a code example doing so:
library ieee;
use std.textio.all;
use ieee.std_logic_textio.all; -- Synopsys package; required for VHDL-2002 only
architecture syn of tb is
begin
process is
variable myl_v : line;
file txt_file : text;
variable slv_v : std_logic_vector(63 downto 0);
begin
file_open(txt_file, "input.txt", read_mode);
readline(txt_file, myl_v);
while myl_v'length > 0 loop
if myl_v'length >= slv_v'length then -- Full slv_v
report "Full...: " & myl_v.all(1 to slv_v'length);
read(myl_v, slv_v);
else -- Reduced slv_v
report "Reduced: " & myl_v.all(1 to myl_v'length);
read(myl_v, slv_v(myl_v'length - 1 downto 0)); -- Place reduced at LSBs
end if;
end loop;
file_close(txt_file);
wait;
end process;
end architecture;
Btw, to answer the question of "length of an input text file", then the length in characters can be determined by reading as many characters from the file as possible, for example with code like:
impure function file_length_in_characters(filename : string) return natural is
type char_file_t is file of character;
file char_file : char_file_t;
variable char_v : character;
variable res_v : natural;
begin
res_v := 0;
file_open(char_file, filename, read_mode);
while not endfile(char_file) loop
read(char_file, char_v);
res_v := res_v + 1;
end loop;
file_close(char_file);
return res_v;
end function;

No function declarations for operator + error in VHDL

In this piece of code I get this error for the line with +
function func (bv1 : in bit_vector; bv2 : in integer) return bit_vector is
variable temp : natural := 2**bv2;
variable result : bit_vector(1 to 32);
begin
report "asd" & natural'image(temp);
result <= bv1 + temp; // this line causes the error
return result;
end func;
The error is :
No function declarations for operator +
How can I solve this? I also get a similar error for "=" as well.
Don't use bit_vectors (or std_logic_vectors, really) for anything you want to do arithmetic on.
Use the ieee.numeric_std library and then declare your signals (or whatever) to be of type signed ot unsigned depending on what type of vector you want. (Or of course, you can just use integers and the subtypes of that)
It's because you try to add a natural to a bit_vector which does not work because they are of different types. So you'll have to use a converter, e.g. as shown here within one of the functions. The other method is to stick to all the same types, but that isn't always possible.
Some initial problems with the code are that VHDL comments markup is --, not
//, and assign to result variable must use :=, since <= is for assign
to signal.
Then, the reason for the error:
No function declarations for operator +
is that VHDL is a strong typed language, so it is not possible just to add a
natural type and a bit_vector type, as attempted in result <= bv1 + temp.
Instead you need to use the package numeric_bit_unsigned, and for example
convert temp to bit_vector using function to_bitvector before adding.
Resulting code can then be:
library ieee;
use ieee.numeric_bit_unsigned.all;
...
function func (bv1 : in bit_vector; bv2 : in integer) return bit_vector is
variable temp : natural := 2**bv2;
variable result : bit_vector(1 to 32);
begin
report "asd" & natural'image(temp);
result := bv1 + to_bitvector(temp, result'length); -- this line causes the error
return result;
end func;
You should check that the length is enough to handle the required values.
However, instead of using bit_vector type, you may consider the
std_logic_vector (depending on the design), since the std_logic_vector has
additional values that may reveal design problem in simulation.

Resources