Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17266 Discussions

Issue when converting between multiple data types

Altera_Forum
Honored Contributor II
6,481 Views

Hello everybody I have an issue with this one line of code here: 

 

output(to_integer(unsigned(msbd) + unsigned(lsb)) downto 0) <= bit_field(to_integer(unsigned(msbd) + unsigned(lsb)) downto to_integer(lsb));  

 

bit_field and output are 32 bit std_logic_vector 

msbd and lsb are 5 bit std_logic_vectors 

 

Issue is when I convert the VHDL file to a symbol file I get this: 

 

Error (10405): VHDL error at aluvhdl_entities.vhd(896): can't determine type of object at or near identifier "to_integer" -- found 0 possible types  

 

Can some one tell me what the issue is?
0 Kudos
28 Replies
Altera_Forum
Honored Contributor II
3,547 Views

use ieee.numeric_std.all;

0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

Im assuming lsb is a std_logic_vector? you forgot to cast it to an unsigned at the end of the line before using the to_integer conversion. 

 

PS. I dont think you'll get the circuit to synthesise if msbd and lsb are signals.
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

 

--- Quote Start ---  

use ieee.numeric_std.all; 

--- Quote End ---  

 

 

The thing is that I am using IEEE.NUMERIC_STD.ALL 

 

EDIT: I casted the std_logic_vector to unsigned and then integer. It created a bsf but now I will test synthesis 

 

EDIT2: I got this error during synthesis 

 

Error (10779): VHDL error at ALUVHDL_entities.vhd(896): expression is not constant
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

as I suggested - you cannot do this if msbd or lsb are signals and not constants.

0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

 

--- Quote Start ---  

as I suggested - you cannot do this if msbd or lsb are signals and not constants. 

--- Quote End ---  

 

Is there any way how to circumvent that without resorting to a different design?
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

Yes - you'll need to use a for loop to check to see if each individual bit should be assigned,.

0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

Then will I just need to use one for loop or will I possibly require more?

0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

one should do it.

0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

 

--- Quote Start ---  

 

output(to_integer(unsigned(msbd) + unsigned(lsb)) downto 0) <= bit_field(to_integer(unsigned(msbd) + unsigned(lsb)) downto to_integer(lsb));  

 

bit_field and output are 32 bit std_logic_vector 

msbd and lsb are 5 bit std_logic_vectors 

 

--- Quote End ---  

 

 

Basically you are trying to do this: LHS(msb + lsb downto 0) <= RHS(msb + lsb downto lsb) ; which doesn't work as the LHS is wider than the RHS. 

Using for-loop won't work either as a for-loop needs constant boundaries as well. 

You could use a barrel shifter to dynamically align data.
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

 

--- Quote Start ---  

Basically you are trying to do this: LHS(msb + lsb downto 0) <= RHS(msb + lsb downto lsb) ; which doesn't work as the LHS is wider than the RHS. 

Using for-loop won't work either as a for-loop needs constant boundaries as well. 

You could use a barrel shifter to dynamically align data. 

--- Quote End ---  

 

 

Could it work if I pad the zeros in the beginning and the end? 

 

EDIT: I figured out that having two shifters will do it.
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

It is not clear to me what you are trying to achieve, but padding the RHS either end (adding zeros at the top or bottom or both) will pass.

0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

 

--- Quote Start ---  

It is not clear to me what you are trying to achieve, but padding the RHS either end (adding zeros at the top or bottom or both) will pass. 

--- Quote End ---  

 

 

I did mess up my explanation there. Sorry about that.
0 Kudos
Altera_Forum
Honored Contributor II
3,546 Views

I have a similar issue right now with this: 

 

left_shift_amount <= 32 - unsigned(msbd) - unsigned(lsb); right_shift_amount <= left_shift_amount + unsigned(lsb); output <= std_logic_vector(Shift_right(Shift_left(unsigned(bit_field), left_shift_amount), right_shift_amount));  

 

It says that left_shift_amount and right_shift_amount do not agree as being natural types.
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

 

--- Quote Start ---  

Basically you are trying to do this: LHS(msb + lsb downto 0) <= RHS(msb + lsb downto lsb) ; which doesn't work as the LHS is wider than the RHS. 

Using for-loop won't work either as a for-loop needs constant boundaries as well. 

You could use a barrel shifter to dynamically align data. 

--- Quote End ---  

 

 

It would work if you loop through the whole of the output and see if the current bit should be assigned a specific bit from the bit_field.
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

 

--- Quote Start ---  

It would work if you loop through the whole of the output and see if the current bit should be assigned a specific bit from the bit_field. 

--- Quote End ---  

 

 

Agree. Worth trying once and see what the RTL looks like.
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

 

--- Quote Start ---  

Agree. Worth trying once and see what the RTL looks like. 

--- Quote End ---  

 

 

I believe it unrolls the loop. I will try it now 

 

Edit: 

 

I have this so far but I get an error that bit_location is not a natural type: 

output <= (others => '0'); for i in 0 to 31 loop bit_location <= i - unsigned(lsb); if (i >= unsigned(lsb)) AND (i <= unsigned(msbd)) then output(bit_location) <= bit_field(i); end if; end loop; 

 

Edit2:  

 

I also tried this but its the same error: 

for i in 0 to 31 loop bit_location <= i + unsigned(lsb); if (bit_location >= unsigned(lsb)) AND (bit_location <= unsigned(msbd)) then output(i) <= bit_field(bit_location); end if; end loop;
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

i is an integer. unsigned(lsb) is an unsigned. You need to convert lsb to an integer: 

 

to_integer( unsigned( lsb) ) 

 

I would also make bit_location a variable, otherwise it is always going to be set to 31 + Lsb as signals are only updated when a process halts.
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

Ok it compiled this: 

 

for i in 0 to 31 loop bit_location <= i + unsigned(lsb); if (bit_location >= unsigned(lsb)) AND (bit_location <= unsigned(msbd)) then output(i) <= bit_field(bit_location); end if; end loop;  

 

and I got this: 

 

https://www.alteraforum.com/forum/attachment.php?attachmentid=6527  

 

It looks like it is not done properly
0 Kudos
Altera_Forum
Honored Contributor II
3,547 Views

It isn't. As Tricky says you have to declare bit_location as a variable, local to the process: process( bit_field , msbd , lsb ) variable bit_location : natural ; begin output <= (others => '0') ; for i in 0 to 31 loop bit_location := i + to_integer( unsigned(lsb) ); if (bit_location >= unsigned(lsb)) AND (bit_location <= unsigned(msbd)) then output(i) <= bit_field(bit_location); end if; end loop; end process ;  

The RTL now is a lot bigger, but also very difficult to understand, if at all :) 

It uses 308 LCs. 

A solution using one or more barrel shifters will be smaller.
0 Kudos
Altera_Forum
Honored Contributor II
3,462 Views

Ok so it works, now I am working on a similar piece which is more complicated. I once again tried doing it a simpler method but it didn't work. My guess is that I will need some really elaborate for loop combination to do this one. 

insert_value_index := to_integer(unsigned(msbd) - unsigned(lsb)); insert_value := to_integer(unsigned(source_register(insert_value_index downto 0))); destination_register_upper := to_integer(unsigned(destination_register(31 downto 1 + to_integer(unsigned(msbd))))); destination_register_lower := to_integer(unsigned(destination_register( to_integer(unsigned(lsb)) - 1 downto 0))); output <= std_logic_vector(to_unsigned(destination_register_upper, 31 - to_integer(unsigned(msbd)))) & std_logic_vector(to_unsigned(insert_value, insert_value_index)) & std_logic_vector(to_unsigned(destination_register_lower, to_integer(unsigned(lsb)))) ;
0 Kudos
Reply