A better way than using std_logic_vector and the non-standard std_logic_arith
and std_logic_signed
libraries is to use IEEE.numeric_std.all;
and make the counter unsigned
(or signed in other contexts where you need negative values).
signal hcount : unsigned(7 downto 0);
And you can perform conversions to and from integer, and bitwise operations:
hcount <= to_unsigned(123,hcount'length);
signal somereg : std_logic_vector(7 downto 0);
...
somereg(to_integer(hcount(2 downto 0)) <= <a bit value>;
However in the given example, the bitwise operations turn out to be unnecessary: instead of masking bits to extract a 3-bit register address, you could use division and mod operations. Synthesis tools (mostly) aren't stupid : divide and mod by powers of 2 are optimised into the obvious field extractions and don't even generate "and" gates.
signal hcount : natural range 0 to 235;
signal reg_addr : natural range 0 to 7;
signal somereg : std_logic_vector(7 downto 0);
...
reg_addr <= hcount mod 8;
somereg(reg_addr) <= <a bit value>;
One benefit of this (apart from fewer ugly type conversions) is that you still profit from the integer subtype you declared for hcount
: incrementing it to 236 will raise an overflow error in simulation, allowing you to catch and correct logic errors early.
VHDL accepts the ISO 8859-1 character set, this is UTF-8.
Your VHDL analyzer is having problems with some of the characters as a result of you copying the text directly from a book.
Your comments aren't delineated by two dashes (e.g. --
), your double quotation marks all need to be replaced with "
.
After which the VHDL code analyzes.
There's no discernible reason why d3
, d2
, d1
, and d0
can't be replaced with a bit_vector. There may uses with the present port interface in the book.
Formal ports are associated with actual signals in an association list. It's possible to associate individual elements of a vector with a base element.
Converting between non-closely related types can be done with conversion routines:
-- bcd_7seg.vhd
-- bcd-to-seven-segment decoder
entity bcd_7seg is
port(
d3, d2, d1, d0: in bit;
a, b, c, d, e, f, g: out bit
);
end entity;
architecture seven_segment of bcd_7seg is
signal input : bit_vector (3 downto 0);
signal output: bit_vector (6 downto 0);
begin
input <= d3 & d2 & d1 & d0;
with input select
output <= "0000001" when "0000",
"1001111" when "0001",
"0010010" when "0010",
"0000110" when "0011",
"1001100" when "0100",
"0100100" when "0101",
"1100000" when "0110",
"0001111" when "0111",
"0000000" when "1000",
"0001100" when "1001",
"1111111" when others;
-- separate the output vector to make individual pin outputs.
a <= output(6);
b <= output(5);
c <= output(4);
d <= output(3);
e <= output(2);
f <= output(1);
g <= output(0);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity bcd_tb is
end entity;
architecture foo of bcd_tb is
signal d: std_logic_vector (3 downto 0) := "0100";
signal output: std_logic_vector (6 downto 0);
begin
DUT:
entity work.bcd_7seg
port map (
d3 => to_bit(d(3)),
d2 => to_bit(d(2)),
d1 => to_bit(d(1)),
d0 => to_bit(d(0)),
to_stdulogic(a) => output(6),
to_stdulogic(b) => output(5),
to_stdulogic(c) => output(4),
to_stdulogic(d) => output(3),
to_stdulogic(e) => output(2),
to_stdulogic(f) => output(1),
to_stdulogic(g) => output(0)
);
end architecture;
You can also associate individual elements of an array type port with the base element type or use conversion functions as are shown above for converting between type bit and the element type for std_logic_vector.
Best Answer
As others said, use
ieee.numeric_std
, neverieee.std_logic_unsigned
, which is not really an IEEE package.However, if you are using tools with VHDL 2008 support, you can use the new package
ieee.numeric_std_unsigned
, which essentially makesstd_logic_vector
behave like unsigned.Also, since I didn't see it stated explicitly, here's actual code example to convert from an (unsigned) integer to an
std_logic_vector
: