following is my code, note that I tried a few methods of zeroing dg array:
-- Class Assignment 2: Display and Keyboard Driver
-- Ex9a in VHDL
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY ***_Ch9 IS
PORT
(
clk,init, load :IN BIT; -- clk,init: for D-flip-flops; load: HIGH for displaying on the four 7-Segment Displays, LOW for inputed data capturing and Key pressing detection
data :IN STD_LOGIC; -- data: for D-flip-flops
Key_av :BUFFER BIT; -- Key_av is Key available/pressed output pulse...Key_av is high at certain clock cycle for Key pressed
d,e,f,g :OUT BIT; -- d,e,f,g: Output (four of eight) for 7-Segment Displays
Dig_Col :BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); -- Dig_Col=E for Dig0,Dig_Col=D for Dig1,Dig_Col=B for Dig2,Dig_Col=7 for Dig3; Dig_Col=1 for Col0,Dig_Col=2 for Col1,Dig_Col=4 for Col2,Dig_Col=8 for Col3
b,a,c,h :INOUT STD_LOGIC -- Output (other four of eight) for 7-Segment Displays; Input for 16-Key Keyboard
);
END ***_Ch9;
ARCHITECTURE Ex9a OF ***_Ch9 IS
TYPE arr IS ARRAY(3 DOWNTO 0) OF STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL Row :INTEGER RANGE 3 DOWNTO 0; -- Row=0 for Row0,Row=1 for Row1,Row=2 for Row2,Row=3 for Row3
SIGNAL dg :arr; -- storage of Data to be Displayed on 7-Segment Displays
SIGNAL ib,ia,ic,ih :STD_LOGIC; -- value to output on b,a,c,h
SIGNAL dx :arr; -- holds values for dg (placed in dg on rising edge of clock)
BEGIN
-- testing ARRAY use
--dg(2)(1) <= '1';
--dg(3) <= "1001";
--dg <= (" ");
PROCESS (init, clk)
BEGIN
--IF init = '0' THEN dg <= (OTHERS => B"0000");
--IF init = '0' THEN dg <= (others => (others => '0'));
--for n IN 0 TO 3 LOOP dg(n) <=X"0"; End LOOP;
--IF init = '0' THEN dg(3) <= X"0";-- & dg(2) <= X"0" & dg(1) <= X"0" & dg(0) <= X"0";
IF init = '0' THEN dg <= (X"0",X"0",X"0",X"0");
-- dg(0) <= X"0";
-- dg(1) <= X"0";
-- dg(2) <= X"0";
-- dg(3) <= X"0";
ELSIF clk'EVENT AND clk = '1' THEN
dg <= dx; --
-- Column Controls
IF load = '1' THEN
CASE Dig_Col IS
WHEN B"1110" => Dig_Col <= B"1101"; -- Dig0 becomes Dig1
WHEN B"1101" => Dig_Col <= B"1011"; -- Dig1 becomes Dig2
WHEN B"1011" => Dig_Col <= B"0111"; -- Dig2 becomes Dig3
WHEN OTHERS => Dig_Col <= B"1110"; -- (Dig3) becomes Dig0
END CASE;
ELSE -- load = '0'
CASE Dig_Col IS
WHEN B"0001" => Dig_Col <= B"0010"; -- Col0 becomes Col1
WHEN B"0010" => Dig_Col <= B"0100"; -- Col1 becomes Col2
WHEN B"0100" => Dig_Col <= B"1000"; -- Col2 becomes Col3
WHEN OTHERS => Dig_Col <= B"0001"; -- (Col3) becomes Col0
END CASE;
END IF;
-- Keyboard Read Row Counter
IF Dig_Col = B"1000" THEN Row <= Row + 1; END IF; -- count only on last column state, increments on next clock rising edge!
-- Key Available
IF load = '0' THEN
IF ((Row=0 AND b='1') OR (Row=1 AND a='1') OR (Row=2 AND c='1') OR (Row=3 AND h='1')) THEN
Key_av <= '1';
ELSE Key_av <= '0';
END IF;
END IF;
END IF;
END PROCESS;
PROCESS (Dig_Col,Row,load,data)
BEGIN
-- Display-Data-Storage and Load inputed Data
FOR n IN 1 TO 3 LOOP
-- LSB of Digit n
IF (load = '1') THEN dx(n)(0) <= dg(n-1)(0); -- Display-Data Storage
ELSIF ((Dig_Col = B"0001") AND (Row = n)) THEN dx(n)(0) <= data; -- Load inputed Data
ELSE dx(n)(0) <= dg(n)(0); -- Load previous data
END IF;
-- 2nd LSB of Digit n
IF (load = '1') THEN dx(n)(1) <= dg(n-1)(1); -- Display-Data Storage
ELSIF ((Dig_Col = B"0010") AND (Row = n)) THEN dx(n)(1) <= data; -- Load inputed Data
ELSE dx(n)(1) <= dg(n)(1); -- Load previous data
END IF;
-- 2nd MSB of Digit n
IF (load = '1') THEN dx(n)(2) <= dg(n-1)(2); -- Display-Data Storage
ELSIF ((Dig_Col = B"0100") AND (Row = n)) THEN dx(n)(2) <= data; -- Load inputed Data
ELSE dx(n)(2) <= dg(n)(2); -- Load previous data
END IF;
-- MSB of Digit n
IF (load = '1') THEN dx(n)(3) <= dg(n-1)(3); -- Display-Data Storage
ELSIF ((Dig_Col = B"1000") AND (Row = n)) THEN dx(n)(3) <= data; -- Load inputed Data
ELSE dx(n)(3) <= dg(n)(3); -- Load previous data
END IF;
END LOOP;
-- this was only from 1 to 3. Digit 0 is fed from the Digit 3 outputs
-- LSB of Digit 0
IF (load = '1') THEN dx(0)(0) <= dg(3)(0); -- Display-Data Storage
ELSIF ((Dig_Col = B"0001") AND (Row = 0)) THEN dx(0)(0) <= data; -- Load inputed Data
ELSE dx(0)(0) <= dg(0)(0); -- Load previous data
END IF;
-- 2nd LSB of Digit 0
IF (load = '1') THEN dx(0)(1) <= dg(3)(1); -- Display-Data Storage
ELSIF ((Dig_Col = B"0010") AND (Row = 0)) THEN dx(0)(1) <= data; -- Load inputed Data
ELSE dx(0)(1) <= dg(0)(1); -- Load previous data
END IF;
-- 2nd MSB of Digit 0
IF (load = '1') THEN dx(0)(2) <= dg(3)(2); -- Display-Data Storage
ELSIF ((Dig_Col = B"0100") AND (Row = 0)) THEN dx(0)(2) <= data; -- Load inputed Data
ELSE dx(0)(2) <= dg(0)(2); -- Load previous data
END IF;
-- MSB of Digit 0
IF (load = '1') THEN dx(0)(3) <= dg(3)(3); -- Display-Data Storage
ELSIF ((Dig_Col = B"1000") AND (Row = 0)) THEN dx(0)(3) <= data; -- Load inputed Data
ELSE dx(0)(3) <= dg(0)(3); -- Load previous data
END IF;
END PROCESS;
-- Data Decode and Output
-- 7-Segment Display segments ON when segment letter LOW, therefore:
-- segment letter HIGH(TRUE) for hexadecimal numbers (0->F) NOT using that segment
ia <= '1' WHEN (dg(3) = X"1") OR (dg(3) = X"4") OR (dg(3) = X"B") OR (dg(3) = X"D") ELSE '0';
ib <= '1' WHEN (dg(3) = X"5") OR (dg(3) = X"6") OR (dg(3) = X"B") OR (dg(3) = X"C") OR (dg(3) = X"E") OR (dg(3) = X"F") ELSE '0';
ic <= '1' WHEN (dg(3) = X"2") OR (dg(3) = X"C") OR (dg(3) = X"E") OR (dg(3) = X"F") ELSE '0';
d <= '1' WHEN (dg(3) = X"1") OR (dg(3) = X"4") OR (dg(3) = X"7") OR (dg(3) = X"A") OR (dg(3) = X"F") ELSE '0';
e <= '1' WHEN (dg(3) = X"1") OR (dg(3) = X"3") OR (dg(3) = X"4") OR (dg(3) = X"5") OR (dg(3) = X"7") OR (dg(3) = X"9") ELSE '0';
f <= '1' WHEN (dg(3) = X"1") OR (dg(3) = X"2") OR (dg(3) = X"3") OR (dg(3) = X"7") OR (dg(3) = X"D") ELSE '0';
g <= '1' WHEN (dg(3) = X"0") OR (dg(3) = X"1") OR (dg(3) = X"7") OR (dg(3) = X"C") ELSE '0';
ih <= '1'; -- decimal point OFF
b <= 'Z' WHEN load = '0' ELSE ib;
a <= 'Z' WHEN load = '0' ELSE ia;
c <= 'Z' WHEN load = '0' ELSE ic;
h <= 'Z' WHEN load = '0' ELSE ih;
END Ex9a;
edited - added code tags