Forum Discussion
[VHDL] integer to std_logic or std_logic_vector conversion
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;
 
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
 
 
BEGIN
 
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;
 
 
 
END arch_read_conv;
18 Replies
- Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
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 ;-) - Altera_Forum
Honored Contributor
--- 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 ); - Altera_Forum
Honored Contributor
Indeed, but I need std_logic/std_logic_vector signals because it's the input signal type of my device under test...
- Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
--- 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 - Altera_Forum
Honored Contributor
I agree with FvM, a simple conversion function would make more sense to another reader.
--- Quote Start ---
--- 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.VARIABLE wdogInitDelayVar : std_logic_vector(15 downto 0); ... wdogInitDelayVar := to_unsigned(wdogInitDelay_i, 16)(15 downto 0); - Altera_Forum
Honored Contributor
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'? - Altera_Forum
Honored Contributor
I'm using Cadence NC-VHDL actually... No station with Quartus free right now...
About my process, here is the actual version :
I still have a problem with the lineconv : 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've the following error :reset_hwTemp := to_unsigned(reset_hw_i, 1);
If needed, I can always use an if statement on the binary integer to produce std_logic signals, something likerange constraint violation
About the second part of the process, I'll try to use the following statement...IF int_bin=0 THEN std_log <='0'; ELSEIF int_bin=1 THEN std_log <='1'; ELSE assert FALSE report "wrong input"VARIABLE wdogInitDelayVar : std_logic_vector(15 downto 0); ... wdogInitDelayVar := to_unsigned(wdogInitDelay_i, 16)(15 downto 0); - Altera_Forum
Honored Contributor
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.