I have spent countless hours on this and I just finally decided I really need some help..so here I am.
Basically what I am doing is taking an 8 bit input from an ADC and then converting this value to BCD to display on a seven segment board. SO here is my code so far:
Library IEEE ;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use IEEE.std_logic_unsigned.all;
entity Voltage_LUT is
Port ( scaled_value : in unsigned(7 downto 0);
true_value : out STD_LOGIC_VECTOR (15 downto 0)
);
end Voltage_LUT;
architecture Behavioral of Voltage_LUT is
function divide (a : UNSIGNED; b : UNSIGNED) return unsigned is
variable a1 : unsigned(a'length-1 downto 0):=a;
variable b1 : unsigned(b'length-1 downto 0):=b;
variable p1 : unsigned(b'length downto 0):= (others => '0');
variable i : integer:=0;
begin
for i in 0 to b'length-1 loop
p1(b'length-1 downto 1) := p1(b'length-2 downto 0);
p1(0) := a1(a'length-1);
a1(a'length-1 downto 1) := a1(a'length-2 downto 0);
p1 := p1-b1;
if(p1(b'length-1) ='1') then
a1(0) :='0';
p1 := p1+b1;
else
a1(0) :='1';
end if;
end loop;
return a1;
end divide;
signal adj: unsigned(7 downto -2); --adjusted to max 90
signal max_value: unsigned(7 downto 0):= "11111111" ; --adjusted to max 90
signal MSB_int: integer; -- integer form of MSB
signal LSB_int: integer; --integer form of LSB
signal adj2: unsigned(15 downto 0); --converted from adjusted integer to binary
signal LSB: STD_LOGIC_VECTOR (3 downto 0); --BCD for LSB
signal MSB: STD_LOGIC_VECTOR (3 downto 0); --BCD for MSB
signal OFF: STD_LOGIC_VECTOR (3 downto 0):="1010"; --defined to be segment OFF
signal V: STD_LOGIC_VECTOR (3 downto 0):="1011"; --defined to be letter V
begin
adj <= divide ( scaled_value , max_value );
adj2 <= adj* "00001001" ;
end Behavioral;
Essentially what I am doing is taking an 8 bit value from the ADC then expressing it as a fraction of the max value (which is 9) and then I have to convert this to BCD... but when I am running this code I am getting an error stating:
Line 38: Index value <-2> is out of range [0:2147483647] of array
I need the answer of the division to be a binary number (with decimals eg 11001.110) so that it would be accurate when I multiply it by 9...
The offending line is:
signal adj: unsigned(7 downto -2);
The type unsigned
does not support negative ranges. If you want to treat your result as a fixed-point value with a fractional component, you have a couple choices, including:
If you have VHDL-2008 compliant tools, you can use ieee.fixed_pkg
, which includes the type ufixed
, which does support negative indices, as you tried to do with unsigned
.
If you don't have VHDL-2008 compliant tools, you can always just manage the binary point virtually, i.e. declare:
signal adj: unsigned(9 downto 0);
With this method, you will need to do the bookkeeping manually, unfortunately. Since you only appear to be doing multiplies and divides, you don't have to worry about aligning the binary point, though. Whether the value is "accurate" or not depends on how you use it in subsequent logic.