Integer Range to vector - vhdl

I've had an issue converting a vectors inputs to integers in my code. I am new to VHDL but the below code works with the integer RANGE commented out code but there is an error when I try to convert the vector values to an integers. Here is a copy of my code and error:
Update1:
I've tried your fix and it takes care of one of the errors but the new error message and code looks like this:

In according to your declaration in follow line type mem is array (...) of std_logic_vector(...) your memory waits for std_logic_vector type rather than unsigned like in your assignment RAMArray(unsigned(addr)) <= unsigned(din).
Here it is not sufficient to only use a type conversion to unsigned, but you have to add type conversion function to_integer in the argument. In other words
RAMArray(to_integer(unsigned(addr))) <= din
The second error is in the follow line qout <= RAMArray(addr). Here you should also use both the type conversion to unsigned as well as the type conversion function to_integer. The location parameter would be of the integer type. Example:
qout <= RAMArray(to_integer(unsigned(addr)))
Try to fix your code with my suggestions and I think it will work.

Related

Error (10327) can't determine definition of operator ""=""

For this VHDL design description:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity four_bit_counter is
port (
count_out : out unsigned (3 downto 0);
clk : in std_logic;
enable:in std_logic;
reset: in std_logic) ;
end four_bit_counter;
architecture arc of four_bit_counter is
signal count : unsigned (3 downto 0);
begin
process (clk, reset, enable)
begin
if (reset = '1') then
count <= "0000";
elsif (clk' event and clk = '1') then
if (enable = '1') then
if (count="1010") then
count<="0000";
else
count <= count +1;
end if;
end ;
end if;
end process;
count_out <= count;
end arc;
I have the error
Error (10327): VHDL error at four_bit_counter.vhd(22): can't determine definition of operator ""="" -- found 2 possible definitions
and I don't know how to fix this.
The two possible definitions are both from package std_logic_arith
function "="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
function "="(L: SIGNED; R: UNSIGNED) return BOOLEAN;
The ambiguity comes from overload resolution for the equality operator due to the package providing the second definition and how the type of the right operand a string literal is determined.
See IEEE Std 1076-2008 9.3.2 Literals:
String and bit string literals are representations of one-dimensional arrays of characters. 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 lexical structure of string and bit string literals is defined in Clause 15.
Here the context is the equality operator, where 12.5 The context of overload resolution specifies the error:
Overloading is defined for names, subprograms, and enumeration literals.
For overloaded entities, overload resolution determines the actual meaning that an occurrence of an identifier or a character literal has whenever the visibility rules have determined that more than one meaning is acceptable at the place of this occurrence; overload resolution likewise determines the actual meaning of an occurrence of an operator or basic operation (see 5.1).
At such a place, all visible declarations are considered. The occurrence is only legal if there is exactly one interpretation of each constituent of the innermost complete context. ...
Overloads for operators are provided by function declarations (
4.5.2 Operator overloading). For a binary operator the left operand is association with the first function parameter and the right parameter is associated with the second parameter. The return value is a Boolean (again from context, it's an if statement's condition which is a Boolean expression).
The type of the right operand can't be determined from context.
There are several possible solutions
Use the IEEE's numeric_std package instead where functions implementing operators don't have both signed and unsigned operands. Package numeric_std is incorporated into the standard's -2008 revision leading to package std_logic_arith's eventual deprecation.
Use a qualified expression (9.3.5) to specifically state the type of the operand.
if count = unsigned'("1010") then
(the redundant parentheses around the condition have been removed for clarity)
Rely on an abstract literal (15.5) where the ambiguity doesn't exist. This can either be of the form of a decimal literal (15.5.2) or based literal (15.5.3).
Use a function call to the overloaded operator's declaration with a selected name noting that named association can't be used for operator overloads.
Define an object (here a constant) with that value provided by a value expression. The type is inherent in an object declaration.

Convert enum type to std_logic_vector VHDL

I want to know if it is possible to convert a enum type, like FSM states to std_logic_vector or integer. I'm doing a testbench with OSVVM for a FSM and I want to use the scoreboard package to automatically compare the expected state with the actual one.
Thanks!
To convert to integer, use:
IntVal := StateType'POS(State) ;
From there, it is easy to convert to std_logic_vector, but I prefer to work with integers when possible as they are smaller in storage than std_logic_vector. For verification, it will be easier if you start to think more about integers when the value is less than 32 bits.
If you need it as std_logic_vector, using only numeric_std you can:
Slv8Val := std_logic_vector(to_unsigned(IntVal, Slv8Val'length)) ;
For verification, I liberally use numeric_std_unsigned, so the conversion is a easier:
Slv8Val := to_slv(IntVal, Slv8Val'length) ;
In the event you have an integer and want to convert it back to a enumerated value, you can use 'VAL.
State := StateType'VAL(IntVal) ;
In OSVVM, we use records with resolved values to create a transaction interface. We have a resoled types for integers (osvvm.ResolutionPkg.integer_max). We transfer enumerated values through the record using 'POS (as we put it in) and 'VAL (as we get it out).
Note don't confuse 'VAL with 'VALUE. 'VALUE converts a string to a value - opposite to 'IMAGE.
You of course learn all of this in SynthWorks' OSVVM class :).
Maybe like this...
function my_func(inp : t_my_enum) return integer is
begin
case inp is
when stateA =>
return 1;
when stateB =>
return 2;
when others =>
return 0;
end case;
end function my_func;
... <= my_func(stateB);`

Why couldn't I convert this integer into a logic_vector?

I have been trying to convert this Signal of type integer into an std_logic vector and assign the converted value into another signal that has the same width as a VHDL integer
signal temp : std_LOGIC_VECTOR(31 downto 0) := (others => '0');
signal FrameCumulative : integer :=0;
temp <= to_stdlogicvector(to_unsigned(FrameCumulative));
However I get this error:
Error (10346): VHDL error at vga.vhd(107): formal port or parameter
"SIZE" must have actual or default value
I am using use IEEE.NUMERIC_STD.ALL; and use IEEE.STD_LOGIC_1164.ALL;
First I made the mistake of not checking the integer size within VHDL and tried to assign an integer into a 14-bit vector but after I gave it some thought I relised my mistake.
Now according to many on-line resources, what I am doing should work but my synthesiser complains about it.
If you do know the cause for this would you mind ellaborating on your answer rather than just posting the correct code, Thanks!
The function to_unsigned must be provided with a parameter specifying the width of the vector that you want it to produce. The function to_stdlogicvector is also not the correct thing to be using. Your line should look like this:
temp <= std_logic_vector(to_unsigned(FrameCumulative, temp'length));
The function to_unsigned is a conversion function, it must be provided with the target width. Here, as suggested by #BrianDrummond, the width is specified by taking the length attribute from the target vector itself (temp). The std_logic_vector is a type cast, where the unsigned value is simply interpreted directly as an std_logic_vector.

convert hex number to std_logic_vector

I have a question on converting a hex number into a std_logic_vector. I need the bit representation of the hex numbers because they are my data the simulated keyboard is sending to my board (later). At now i am in development phase:
Here is the code example that doesn't work within ISE:
Subtype ScanCode is std_logic_vector(39 downto 0);
variable binaryRep : ScanCode;
binaryRep := std_logic_vector(16#70F070#);
the conversion in the last line is where the problem appears the Compiler tells me Cannot convert type universal_integer to type std_logic_vector
I have also tried that code but got another error i don't understand
binayRep <= to_stdlogicvector(x"FC");
this was the error message i got:
Near to_stdlogicvector ; 2 visible identifiers match here
I also searched the web for other solutions but i couldn't solve the problem.
Has anyone an Idea how to fix the code ?
16#70F070# is a numerical literal and isn't appropriate directly, it needs a conversion routine. You don't have an appropriate conversion routine that matches the signature [integer return std_logic_vector].
This
binaryRep <= to_stdlogicvector(x"FC");
wouldn't work anyway because the equivalent bit string to x"FC" has a length of 8, while binaryRep has a length of 40 and you don't specify the length std_logic_vector to produce. (And x"FC" already get's converted to an equivalent bit map).
The only to_stdlogicvector function declarations I found are in package fixed_generic_pkg and aren't appropriate.
you could:
binaryRep <= x"00000000FC";
Which matches the bit string length.
Or by including package numeric_std in a use clause:
binaryRep <= std_logic_vector(to_unsigned(16#70F070#,binaryRep'length));
Which converts a natural (an integer subtype) to an unsigned which is then type converted to std_logic_vector with the length derived from binaryRep.
Or using Mentor's std_logic_arith package
binaryRep <= to_std_logicvector(16#70F070#,binaryRep'length);
Which takes an integer argument and a natural length and converts the result to a std_logic_vector.
Or using Synopsys's std_logic_arith package
binaryRep <= conv_std_logic_vector(16#70F070#,binaryRep'length);
Where both arguments are type integer.
(And there are a couple more ways, dependent on VHDL-2008 support).
According to:
https://www.altera.com/support/support-resources/design-examples/design-software/vhdl/v_hex.html
signal A : std_logic_vector(31 downto 0) := x"00000017";
Worked for me :)

VHDL for loop type error and shift error

I'm trying to write a for loop in VHDL, but I believe there is some type issue in the loop statement. I have a block that receives a 16-bit word, A, as input that indicates the number times I should shift another input, B. The output, C, shows the shifted version of B. My code looks like this:
TEMP_C := B;
FOR I IN 1 TO UNSIGNED(A) LOOP
TEMP_C := TEMP_C(15) & TEMP_C(15 DOWNTO 1);
END LOOP;
C <= TEMP_C;
The compiler is complaining about the second line, and says "Range left bound type Integer is not the same as right bound type". Can someone explain to me why this line is wrong, and how do I fix it?
On the left side you have '1', being an 'integer'. On the right side you have 'unsigned(std_logic_vector?)', being an 'unsigned'. An unsigned is still not the same as an 'integer'. An unsigned is still a collection of bits. Here for more info about 'unsigned'.
Anyhow this solution will help you more...
FOR I IN 1 TO to_integer(UNSIGNED(A)) LOOP
An unsigned vector is not the same as an integer. This is not Verilog!

Resources