Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20704 Discussions

[VHDL] integer to std_logic or std_logic_vector conversion

Altera_Forum
Honored Contributor II
11,598 Views

Hello, 

I've some issues to convert integer to std_logic or std_logic_vector. 

I need to do so for a testbench which reads stimuli (binary or positive integers) in a text file, stores it as integer and needs to translate it to std_logic or std_logic_vector. 

I can store stimuli as integer but I can't translate it to std_logic or std_logic_vector. I try first to cast them to unsigned and cast after the result to std_logic or std_logic_vector. 

I use the ieee.numeric_std package because I read that using the ieee.std_logic_unsigned package could lead to errors (then, i do not use the conv_std_logic_vector function). 

Here is an extract of my code.  

Please provide any advice or ideas to solve my problem. 

LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; USE work.txt_util.all; &#12288; ENTITY read_conv IS PORT( clk : in std_logic; rst_n : in std_logic; start_in : in std_logic; --- std_logic inputs --- reset_hw_i : in integer; wdogInitDelay_i : in integer; --- std_logic outputs --- reset_hw_o : out std_logic; wdogInitDelay_o : out std_logic_vector(15 downto 0) ); END read_conv; ARCHITECTURE arch_read_conv OF read_conv IS &#12288; &#12288; BEGIN &#12288; conv : PROCESS (clk, rst_n) VARIABLE reset_hwVar : std_logic; VARIABLE wdogInitDelayVar : std_logic_vector(15 downto 0); BEGIN if rst_n='0' then reset_hwVar := '0'; reset_hw_o <= '0'; wdogInitDelayVar := (others=>'0'); wdogInitDelay_o <= (others=>'0'); else -- Cast an integer to an unsigned on 1 bit and cast it again to std_logic reset_hwVar := std_logic_vector(to_unsigned(reset_hw_i, 1)); print("Integer read : 0x" & str(reset_hw_i, 16)); print("std_logic_vector 0x" & str(reset_hwVar)); reset_hw_o <= reset_hwVar; -- Cast an integer to an unsigned on 16 bit and cast it again to std_logic_vector wdogInitDelayVar := std_logic_vector(to_unsigned(wdogInitDelay_i, 16)); print("Integer read : 0x" & str(wdogInitDelay_i, 16)); print("std_logic_vector 0x" & hstr(wdogInitDelayVar)); wdogInitDelay_o <= wdogInitDelayVar; end if; END PROCESS conv; &#12288; &#12288; &#12288; END arch_read_conv;
0 Kudos
18 Replies
Altera_Forum
Honored Contributor II
6,523 Views

Sorry, I posted two times this thread... I though it failed at first time. 

If an admin could remove the second:  

Ok I'can't post links... great rule! 

I don't find how to do it by myself...
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

Hi, 

 

First, you could try to work only with unsigned signals and to ban all std_logic_vector. I don't know if it's the very good idea but it works great for me.  

 

Then to create an std_logic signal, something like this should work : 

 

reset_hwVar := to_unsigned(reset_hw_i, 1)(0);
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

Thank you for your answer... 

First, the device under test needs std_logic signals as input signals, then, I'll need to convert unsigned to std_logic_vector. 

I tried your trick reset_hwVar := to_unsigned(reset_hw_i, 1)(0); but it doesn't work.  

If you've any other idea, don't hesitate...
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

Looking at your code, I think you are getting a little confused. Basically, you seem to misunderstand the difference between std_logic and std_logic_vector. 

 

A std_logic_vector is an array of std_logic. Therefore, they are NOT the same type, and you cannot assing a std_logic from a std_logic_vector, but you can assign one from an individual element of a std_logic_vector. 

 

So, in this case: 

 

signal a: std_logic_vector(0 downto 0); 

signal b : std_logic; 

 

you cannot do this, even though the length is only 1: 

 

b <= a; 

 

you have to do this: 

 

b <= a(0); 

 

Now, also know that unsigned and signed are also arrays of std_logic, hence why you can do a simple type conversion between them rather than need a conversion function (like to_unsigned) because they are similar type. 

 

So the problem you have is this line: 

 

reset_hwVar := std_logic_vector(to_unsigned(reset_hw_i, 1)); 

 

because reset_hwVar is a std_logic (not a vector). To solve this, all you need to do is select the 0th bit of the output of the conversion function to unsigned(because it is an array of std_logic) 

 

so you can change it to this 

reset_hwVar := to_unsigned(reset_hw_i, 1)(0);
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

Secondly, with your process, did you realise the process is going to run whenever clk changes from anything to anything? so as well as '0' to '1', it will execute from '1' to '0' too?

0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

Hello Tricky, 

 

First, thanks for your time and interest... 

 

Next, I indeed though that  

signal a: std_logic_vector(0 downto 0); signal b : std_logic; b <= a; 

was correct. I changed it. 

 

However, 

reset_hwVar := to_unsigned(reset_hw_i, 1)(0); 

produces an error : "Range constraint violation", whatever the value I store in my text file (0 or 1). 

 

Shouldn't I store it to a temporary value because VHDL doesn't understand the statement? 

VARIABLE reset_hwTemp : unsigned(0 downto0); ... reset_hwTemp:= to_unsigned(reset_hw_i, 1); reset_hwVar := reset_hwTemp(0);  

(I tried, I've the same error) 

 

What concerns the process, indeed, It will run on every clock event... 

Didn't pay attention to it yet. I just put 'WAIT UNTIL' statements.
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

using the temporary variable should work fine. Is it because you forgot a space between downto and 0? 

 

And in your origional post, there are no wait until statements in your code. But note that you cannot have a sensitivity list and wait statements, its one or the other.
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

btw, what are you trying to compile this code in? You cannot compile this code in Quartus, which is probably why you're getting a range constraint violation, because Quartus wants to map integers to 32 bits, and you only asked for 1 bit. (As well as non of the textio stuff being appropriate). 

 

The first line should work fine in Modelsim.
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

I'm using Cadence NC-VHDL actually... No station with Quartus free right now... 

 

About my process, here is the actual version : 

conv : PROCESS VARIABLE reset_hwTemp : unsigned(31 downto 0); VARIABLE reset_hwVar : std_logic; VARIABLE wdogInitDelayVar : std_logic_vector(15 downto 0); BEGIN if rst_n='0' then reset_hwVar := '0'; reset_hw_o <= '0'; reset_hwTemp := (others=>'0'); wdogInitDelayVar := (others=>'0'); wdogInitDelay_o <= (others=>'0'); WAIT until rst_n='1'; else -- Cast an integer to an unsigned on 1 bit and cast it again to std_logic --print("Integer read : " & str(reset_hw_i)); reset_hwTemp := to_unsigned(reset_hw_i, 32); reset_hwVar := reset_hwTemp(0); --print("std_logic_vector " & str(reset_hwVar)); --reset_hw_o <= reset_hwVar; -- Cast an integer to an unsigned on 16 bit and cast it again to std_logic_vector --wdogInitDelayVar := std_logic_vector(to_unsigned(wdogInitDelay_i, 16)); --print("Integer read : 0x" & str(wdogInitDelay_i, 16)); --print("std_logic_vector 0x" & hstr(wdogInitDelayVar)); --wdogInitDelay_o <= wdogInitDelayVar; WAIT until rst_n='1'or (clk'event and clk='1'); end if;  

I still have a problem with the line 

reset_hwTemp := to_unsigned(reset_hw_i, 1);  

I've the following error : 

 

range constraint violation 

 

If needed, I can always use an if statement on the binary integer to produce std_logic signals, something like  

IF int_bin=0 THEN std_log <='0'; ELSEIF int_bin=1 THEN std_log <='1'; ELSE assert FALSE report "wrong input"  

 

About the second part of the process, I'll try to use the following statement... 

VARIABLE wdogInitDelayVar : std_logic_vector(15 downto 0); ... wdogInitDelayVar := to_unsigned(wdogInitDelay_i, 16)(15 downto 0);
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

Looks like a pretty long thread about a trivial VHDL problem. 

 

Why don't you simply write a conversion function that returns '0'= for input = 0 otherwise '1'?
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

I agree with FvM, a simple conversion function would make more sense to another reader. 

 

 

--- Quote Start ---  

 

VARIABLE wdogInitDelayVar : std_logic_vector(15 downto 0); ... wdogInitDelayVar := to_unsigned(wdogInitDelay_i, 16)(15 downto 0); 

--- Quote End ---  

 

 

That wont work, because you're trying to assign an unsigned to a std_logic_vector. You need this: 

 

wdogInitDelayVar := std_logic_vector( to_unsigned(wdogInitDelay_i, 16) ); 

 

There is no problem with this code. If Cadence keeps giving you an error about range constraints, get a better simulator.
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

 

--- Quote Start ---  

Looks like a pretty long thread about a trivial VHDL problem. 

 

Why don't you simply write a conversion function that returns '0'= for input = 0 otherwise '1'? 

--- Quote End ---  

 

 

Thanks for the "trivial VHDL problem", I'm trying to solve it for 3 days. :-P 

 

If you look at the process, I could do it for the integer which is 0 or 1 (reset_hw_i signal), but first it's not a clean solution. I come from Verilog and if there is no way to convert it cleanly, my opinion on VHDL would be quite bad ;-) 

 

But there are not just a "binary" integer, there is also an unsigned integer (wdogInitDelay_i on 16 bits) and I don't want to code an if statement for the 2^16 converion possibilities :-D
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

You have to remember that integers have no individual bits. Hence why they need converting to an unsigned type (which is an array of std_logic). 

 

You can easily have a range of integer that is 0 or 1 like this: 

 

subtype int_bool is integer range 0 to 1; 

signal my_very_short_integer : int_bool; 

 

then an assignment like this: 

 

my_very_short_integer <= 2; 

 

will throw an error.
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

Indeed, but I need std_logic/std_logic_vector signals because it's the input signal type of my device under test...

0 Kudos
Altera_Forum
Honored Contributor II
6,522 Views

 

--- Quote Start ---  

Indeed, but I need std_logic/std_logic_vector signals because it's the input signal type of my device under test... 

--- Quote End ---  

 

 

I was just answering your question about why integers were not binary. 

 

Anyway - thats not a problem, we've said a conversion function isnt really that hard to do: 

 

function int_to_sl(x : integer) return std_logic is begin if x > 0 then return '1'; else return '0'; end if; end function int_to_sl; a <= int_to_sl( my_input );
0 Kudos
Altera_Forum
Honored Contributor II
6,523 Views

Ok, I think I'll try a better simulator monday because this one has issues. 

Thank you all for your help, I might come back monday ;-)
0 Kudos
Altera_Forum
Honored Contributor II
6,522 Views

Referring to the said verilog identity of bool, bit and (integer value != 0), I would pefer x /= 0 as an exact VHDL equivalent, because integers can be negative as well. 

 

The necessity to perform a type conversion is brought up by the strict typification of VHDL. Coming from Verilog, it may be annoying for you, but it serves a purpose.
0 Kudos
Reply