I have this code for driving a seven segment display for hex. From my understanding its logically correct, but when I try and run it on my Nexsys 3 board I never get the correct output, it seems that the segments are almost running together when I run it, (ie. the same thing appears across all or some of them and all of the segment are always at least partially illuminated while the segments pertaining to the correct display just have a higher intensity).
below is my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SSD_driver is
Port ( hex0 : in STD_LOGIC_VECTOR (3 downto 0);
hex1 : in STD_LOGIC_VECTOR (3 downto 0);
hex2 : in STD_LOGIC_VECTOR (3 downto 0);
hex3 : in STD_LOGIC_VECTOR (3 downto 0);
clock : in STD_LOGIC;
reset : in STD_LOGIC;
SEG : out STD_LOGIC_VECTOR (7 downto 0);
AN : out STD_LOGIC_VECTOR (3 downto 0));
end SSD_driver;
architecture Behavioral of SSD_driver is
signal count : std_logic_vector(15 downto 0):=(others=>'0');
signal mux_sel: std_logic_vector(1 downto 0):=(others=>'0');
signal mux_out: std_logic_vector(3 downto 0):=(others=>'0');
signal dec_out: std_logic_vector(3 downto 0):=(others=>'0');
signal OC: std_logic_vector(3 downto 0):=(others=>'0');
signal SS_cathode:STD_LOGIC_VECTOR(7 downto 0):=(others=>'0');
begin
counter: process(clock,reset)
begin
if reset = '1' then
count<=(others=>'0');
else
if rising_edge(clock) then
count<=count+1;
end if;
end if;
end process counter;
mux_sel<=count(15 downto 14);
with mux_sel select
mux_out<=hex0 when "00",
hex1 when "01",
hex2 when "10",
hex3 when "11",
"0000" when others;
with mux_sel select
dec_out<="0001" when "00",
"0010" when "01",
"0100" when "10",
"1000" when "11",
"0000" when others;
with mux_out select
SS_cathode(7 downto 0) <= x"C0" when "0000", -- 0
x"F9" when "0001", -- 1
x"A4" when "0010", -- 2
x"B0" when "0011", -- 3
x"99" when "0100", -- 4
x"92" when "0101", -- 5
x"82" when "0110", -- 6
x"F8" when "0111", -- 7
x"80" when "1000", -- 8
x"90" when "1001", -- 9
x"88" when "1010", -- a
x"83" when "1011", -- b
x"C6" when "1100", -- c
x"A1" when "1101", -- d
x"86" when "1110", -- e
x"8E" when others; -- f
SEG<=SS_cathode;
AN<=not(dec_out);
end Behavioral;
Any help would be appreciated, thanks in advance!
Best Answer
You obviously figured out your issue via the comments, but for those finding this question in the future, the answer lies in the Nexys datasheet. In short, yes, the 7-seg display digits are multiplexed, and as such, there is a setup and hold time when interfacing with those common anode/cathode transistors.
In this case, however, you have to switch between them slow enough for our human eyes to see the light, but fast enough so that there is no flicker. Think PWM: if you're switching between digits too quickly, the light will be dim.
The Digilent data sheet for the Nexys board answers this exact question. Check out section 9.1 which talks about interfacing with the seven-segment display. In particular...
So there you go.