1
0
mirror of https://github.com/ibm2030/IBM2030.git synced 2026-01-11 23:52:47 +00:00

Add Maxim external LED drivers, MAX7219 or MAX7951, for front panel lamps

This commit is contained in:
unknown 2015-11-25 09:22:31 +01:00
parent 321e0a8fd5
commit a48fa3d53d
4 changed files with 701 additions and 3 deletions

125
Testbench_panel_LEDs.vhd Normal file
View File

@ -0,0 +1,125 @@
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 13:16:46 06/18/2015
-- Design Name:
-- Module Name: C:/Users/lwilkinson/Documents/Xilinx/IBM2030/Testbench_panel_LEDs.vhd
-- Project Name: IBM2030
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: panel_LEDs
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY Testbench_panel_LEDs IS
END Testbench_panel_LEDs;
ARCHITECTURE behavior OF Testbench_panel_LEDs IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT panel_LEDs
PORT(
LEDs : IN std_logic_vector(0 to 255);
clk : IN std_logic;
MAX7219_CLK : OUT std_logic;
MAX7219_DIN0 : OUT std_logic;
MAX7219_DIN1 : OUT std_logic;
MAX7219_DIN2 : OUT std_logic;
MAX7219_DIN3 : OUT std_logic;
MAX7219_LOAD : OUT std_logic;
MAX6951_CLK : OUT std_logic;
MAX6951_DIN : OUT std_logic;
MAX6951_CS0 : OUT std_logic;
MAX6951_CS1 : OUT std_logic;
MAX6951_CS2 : OUT std_logic;
MAX6951_CS3 : OUT std_logic
);
END COMPONENT;
--Inputs
signal LEDs : std_logic_vector(0 to 255) := (1 => '1',3 => '1',5 => '1',7 => '1',9 => '1',11 => '1',13 => '1',15 => '1',17 => '1',others => '0');
signal clk : std_logic := '0';
--Outputs
signal MAX7219_CLK : std_logic;
signal MAX7219_DIN0 : std_logic;
signal MAX7219_DIN1 : std_logic;
signal MAX7219_DIN2 : std_logic;
signal MAX7219_DIN3 : std_logic;
signal MAX7219_LOAD : std_logic;
signal MAX6951_CLK : std_logic;
signal MAX6951_DIN : std_logic;
signal MAX6951_CS0 : std_logic;
signal MAX6951_CS1 : std_logic;
signal MAX6951_CS2 : std_logic;
signal MAX6951_CS3 : std_logic;
-- Clock period definitions
constant clk_period : time := 20 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: panel_LEDs PORT MAP (
LEDs => LEDs,
clk => clk,
MAX7219_CLK => MAX7219_CLK,
MAX7219_DIN0 => MAX7219_DIN0,
MAX7219_DIN1 => MAX7219_DIN1,
MAX7219_DIN2 => MAX7219_DIN2,
MAX7219_DIN3 => MAX7219_DIN3,
MAX7219_LOAD => MAX7219_LOAD,
MAX6951_CLK => MAX6951_CLK,
MAX6951_DIN => MAX6951_DIN,
MAX6951_CS0 => MAX6951_CS0,
MAX6951_CS1 => MAX6951_CS1,
MAX6951_CS2 => MAX6951_CS2,
MAX6951_CS3 => MAX6951_CS3
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
wait for 1ms;
-- insert stimulus here
wait;
end process;
END;

View File

@ -155,7 +155,7 @@ constant indLayout : screenIndicators :=
-- To convert ASCII to the internal 6-bit representation... -- To convert ASCII to the internal 6-bit representation...
-- Not all characters are needed, so some special ones are added -- Not all characters are needed, so some special ones are added
subtype characterCode is std_logic_vector(6 downto 0); subtype characterCode is std_logic_vector(6 downto 0);
type charArray is array(character'(' ') to character'('{')) of characterCode; type charArray is array(32 to 123) of characterCode;
constant charTranslate : charArray := ( constant charTranslate : charArray := (
-- 20->62, 21 ! ->61, 22-23->127, 24->59, 25-29->127, 2A->60, 2B-2F->127 -- 20->62, 21 ! ->61, 22-23->127, 24->59, 25-29->127, 2A->60, 2B-2F->127
"0111110","0111101","1111111","1111111","0111011","1111111","1111111","1111111", "0111110","0111101","1111111","1111111","0111011","1111111","1111111","1111111",
@ -1527,7 +1527,7 @@ function initScreen (constant screen : screenType) return screenCharacters is
begin begin
for r in lines loop for r in lines loop
for c in columns loop for c in columns loop
sc(r,c) := charTranslate(screen(r,c)); sc(r,c) := charTranslate(character'pos(screen(r,c)));
end loop; end loop;
end loop; end loop;
return sc; return sc;

View File

@ -174,6 +174,9 @@ signal N60_CY_TIMER_PULSE : STD_LOGIC; -- Used for the Interval Timer
signal Clock1ms : STD_LOGIC; -- 1kHz clock for single-shots etc. signal Clock1ms : STD_LOGIC; -- 1kHz clock for single-shots etc.
signal DEBUG : DEBUG_BUS; -- Passed to all modeles to probe signals signal DEBUG : DEBUG_BUS; -- Passed to all modeles to probe signals
signal LED_vector : std_logic_vector(0 to 255);
begin begin
cpu : entity cpu port map ( cpu : entity cpu port map (
@ -479,7 +482,7 @@ begin
-- Clocks etc. -- Clocks etc.
clk => clk, -- 50MHz clock clk => clk, -- 50MHz clock
Clock1ms => Clock1ms, -- Clock1ms => Clock1ms,
Timer => N60_CY_TIMER_PULSE -- Output from Switches is actually 50Hz Timer => N60_CY_TIMER_PULSE -- Output from Switches is actually 50Hz
); );
@ -503,7 +506,217 @@ begin
clk => clk clk => clk
); );
sramaddr(17) <= '0'; sramaddr(17) <= '0';
LED_vector <= (
0 => IND_SALS.SALS_PA,
1 => IND_SALS.SALS_CN(5),
2 => IND_SALS.SALS_CN(4),
3 => IND_SALS.SALS_CN(3),
4 => IND_SALS.SALS_CN(2),
5 => IND_SALS.SALS_CN(1),
6 => IND_SALS.SALS_CN(0),
7 => IND_SALS.SALS_PN,
8 => X_IND_P,
9 => WX_IND(4),
10 => WX_IND(3),
11 => WX_IND(2),
12 => WX_IND(1),
13 => WX_IND(0),
14 => W_IND_P,
15 => '0', -- LP
16 => WX_IND(12),
17 => WX_IND(11),
18 => WX_IND(10),
19 => WX_IND(9),
20 => WX_IND(8),
21 => WX_IND(7),
22 => WX_IND(6),
23 => WX_IND(5),
24 => IND_SALS.SALS_CL(2),
25 => IND_SALS.SALS_CL(1),
26 => IND_SALS.SALS_CL(0),
27 => IND_SALS.SALS_CH(3),
28 => IND_SALS.SALS_CH(2),
29 => IND_SALS.SALS_CH(1),
30 => IND_SALS.SALS_CH(0),
31 => IND_SALS.SALS_PA,
32 => IND_SALS.SALS_CB(1),
33 => IND_SALS.SALS_CB(0),
34 => IND_SALS.SALS_CA(3),
35 => IND_SALS.SALS_CA(2),
36 => IND_SALS.SALS_CA(1),
37 => IND_SALS.SALS_CA(0),
38 => IND_SALS.SALS_AA,
39 => IND_SALS.SALS_CL(3),
40 => IND_SALS.SALS_CK(0),
41 => IND_SALS.SALS_PK,
42 => IND_SALS.SALS_AK,
43 => IND_SALS.SALS_CU(1),
44 => IND_SALS.SALS_CU(0),
45 => IND_SALS.SALS_CM(2),
46 => IND_SALS.SALS_CM(1),
47 => IND_SALS.SALS_CM(0),
48 => IND_SALS.SALS_CD(3),
49 => IND_SALS.SALS_CD(2),
50 => IND_SALS.SALS_CD(1),
51 => IND_SALS.SALS_CD(0),
52 => IND_SALS.SALS_PC,
53 => IND_SALS.SALS_CK(3),
54 => IND_SALS.SALS_CK(2),
55 => IND_SALS.SALS_CK(1),
56 => IND_SALS.SALS_CC(0),
57 => IND_SALS.SALS_CV(1),
58 => IND_SALS.SALS_CV(0),
59 => IND_SALS.SALS_CG(1),
60 => IND_SALS.SALS_CG(0),
61 => IND_SALS.SALS_CF(2),
62 => IND_SALS.SALS_CF(1),
63 => IND_SALS.SALS_CF(0),
-- Count
-- SX1
-- SX2
160 => IND_ADDR_IN,
161 => IND_OPNL_IN,
168 => IND_FO_P,
169 => IND_SUPPR_OUT,
170 => IND_SERV_OUT,
171 => IND_CMMD_OUT,
172 => IND_ADDR_OUT,
173 => IND_SEL_OUT,
174 => IND_SERV_IN,
175 => IND_STATUS_IN,
176 => IND_FO(7),
177 => IND_FO(6),
178 => IND_FO(5),
179 => IND_FO(4),
180 => IND_FO(3),
181 => IND_FO(2),
182 => IND_FO(1),
183 => IND_FO(0),
184 => IND_M(6),
185 => IND_M(5),
186 => IND_M(4),
187 => IND_M(3),
188 => IND_M(2),
189 => IND_M(1),
190 => IND_M(0),
191 => IND_M(8),
192 => IND_N(5),
193 => IND_N(4),
194 => IND_N(3),
195 => IND_N(2),
196 => IND_N(1),
197 => IND_N(0),
198 => IND_N(8),
199 => IND_M(7),
200 => IND_MSDR(2),
201 => IND_MSDR(1),
202 => IND_MSDR(0),
203 => IND_MSDR_P,
204 => IND_LOC_STG,
205 => IND_MAIN_STG,
206 => IND_N(7),
207 => IND_N(6),
208 => IND_ALU(1),
209 => IND_ALU(0),
210 => IND_ALU(8),
211 => IND_MSDR(7),
212 => IND_MSDR(6),
213 => IND_MSDR(5),
214 => IND_MSDR(4),
215 => IND_MSDR(3),
216 => IND_B(0),
217 => IND_B(8),
218 => IND_ALU(7),
219 => IND_ALU(6),
220 => IND_ALU(5),
221 => IND_ALU(4),
222 => IND_ALU(3),
223 => IND_ALU(2),
224 => IND_A(8),
225 => IND_B(7),
226 => IND_B(6),
227 => IND_B(5),
228 => IND_B(4),
229 => IND_B(3),
230 => IND_B(2),
231 => IND_B(1),
232 => IND_A(7),
233 => IND_A(6),
234 => IND_A(5),
235 => IND_A(4),
236 => IND_A(3),
237 => IND_A(2),
238 => IND_A(1),
239 => IND_A(0),
240 => IND_CHK_B_REG,
241 => IND_1050_REQ,
242 => IND_1050_INTRV,
243 => IND_CHK_STOR_DATA,
244 => IND_CHK_STOR_ADDR,
245 => IND_ALLOW_WR,
246 => IND_CY_MATCH,
247 => IND_EX,
248 => IND_CHK_CTRL_REG,
249 => IND_CHK_ROS_SALS,
250 => IND_CHK_ROS_ADDR,
251 => IND_COMP_MODE,
252 => IND_SEL_CHNL,
253 => IND_MPX,
254 => IND_CHK_ALU,
255 => IND_CHK_A_REG,
others => '0');
front_panel : entity panel_LEDs
generic map(
clock_divider => 2,
number_LEDs => 256
)
port map(
clk => clk,
LEDs => LED_vector,
-- (
-- 0 => W_IND_P,
-- 0 => IND_SALS.SALS_PA,
-- 1 => IND_SALS.SALS_CN(5),
-- 2 => IND_SALS.SALS_CN(4),
-- 3 => IND_SALS.SALS_CN(3),
-- 4 => IND_SALS.SALS_CN(2),
-- 5 => IND_SALS.SALS_CN(1),
-- 6 => IND_SALS.SALS_CN(0),
-- 7 => IND_SALS.SALS_PN,
-- 16#01# to 16#0F# => '0',
-- 16#10# to 16#1F# => '0',
-- 16#20# to 16#2F# => '0',
-- 16#30# to 16#3F# => '0',
-- 16#40# to 16#4F# => '0',
-- 16#50# to 16#5F# => '0',
-- 16#60# to 16#6F# => '0',
-- 16#70# to 16#7F# => '0',
-- 16#80# to 16#8F# => '0',
-- 16#90# to 16#9F# => '0',
-- 16#A0# to 16#AF# => '0',
-- 16#B0# to 16#BF# => '0',
-- 16#C0# to 16#CF# => '0',
-- 16#D0# to 16#DF# => '0',
-- 16#E0# to 16#EF# => '0',
-- 16#F0# to 16#FF# => '0'
-- ),
-- MAX7219 is standard LED mux (full-size panel)
MAX7219_CLK => open,
MAX7219_LOAD => open,
MAX7219_DIN0 => open,
MAX7219_DIN1 => open,
MAX7219_DIN2 => open,
MAX7219_DIN3 => open,
-- MAX6951 is charlieplexed LED mux (miniature panel)
MAX6951_CLK => open,
MAX6951_CS0 => open,
MAX6951_CS1 => open,
MAX6951_CS2 => open,
MAX6951_CS3 => open,
MAX6951_DIN => open
);
DEBUG.Selection <= CONV_INTEGER(unsigned(SW_J)); DEBUG.Selection <= CONV_INTEGER(unsigned(SW_J));

360
panel_LEDs.vhd Normal file
View File

@ -0,0 +1,360 @@
---------------------------------------------------------------------------
-- Copyright © 2015 Lawrence Wilkinson lawrence@ljw.me.uk
--
-- This file is part of LJW2030, a VHDL implementation of the IBM
-- System/360 Model 30.
--
-- LJW2030 is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- LJW2030 is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with LJW2030 . If not, see <http://www.gnu.org/licenses/>.
--
---------------------------------------------------------------------------
--
-- File: panel_LEDs.vhd
-- Creation Date: 16:08:00 16/06/2015
-- Description:
-- 360/30 Front Panel LED lamp drivers
-- This drives 256 front panel LEDs via Maxim SPI/I2C multiplexed drivers
-- There are two options:
-- MAX7219 8 x 8 multiplexed LEDs
-- MAX7951 Charlieplexed LEDs
-- Page references like "5-01A" refer to the IBM Maintenance Diagram Manual (MDM)
-- for the 360/30 R25-5103-1
-- References like "02AE6" refer to coordinate "E6" on page "5-02A"
-- Logic references like "AB3D5" refer to card "D5" in board "B3" in gate "A"
-- Gate A is the main logic gate, B is the second (optional) logic gate,
-- C is the core storage and X is the CCROS unit
--
-- Revision History:
-- Revision 1.0 2010-07-09
-- Initial Release
--
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.Buses_package.all;
use work.Gates_package.EvenParity;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity panel_LEDs is
Generic (
Clock_divider : integer := 2; -- Default for 50MHz clock is 25MHz = 40ns = 20ns + 20ns
Number_LEDs : integer := 256
);
Port ( -- Lamp input vector
LEDs : in std_logic_vector(0 to Number_LEDs-1);
-- Other inputs
clk : in STD_LOGIC; -- 50MHz
-- Driver outputs
MAX7219_CLK : out std_logic;
MAX7219_DIN0 : out std_logic; -- LEDs 00-3F
MAX7219_DIN1 : out std_logic; -- LEDs 40-7F
MAX7219_DIN2 : out std_logic; -- LEDs 80-BF
MAX7219_DIN3 : out std_logic; -- LEDs C0-FF
MAX7219_LOAD : out std_logic; -- Data latched on rising edge
MAX6951_CLK : out std_logic;
MAX6951_DIN : out std_logic; --
MAX6951_CS0 : out std_logic; -- LEDs 00-3F Data latched on rising edge
MAX6951_CS1 : out std_logic; -- LEDs 40-7F Data latched on rising edge
MAX6951_CS2 : out std_logic; -- LEDs 80-BF Data latched on rising edge
MAX6951_CS3 : out std_logic -- LEDs C0-FF Data latched on rising edge
);
end panel_LEDs;
architecture Behavioral of panel_LEDs is
signal clk_out : std_logic := '0';
-- MAX7219 data is 8b address and 8b data
-- Address is:
-- 00 No-op (unused)
-- 01 Digit 0 (in position 0)
-- ...
-- 08 Digit 7 (in position 0)
-- 09 Decode mode (fixed at default)
-- 0A Intensity (fixed at 0F in position 8)
-- 0B Scan limit (fixed at 07 in position 9)
-- 0C Shutdown (fixed at 01 in position 10)
-- 0F Display test (fixed at 00 in position 11)
type registers7219 is array(0 to 3,0 to 11) of std_logic_vector(15 downto 0);
signal max7219_vector : registers7219 :=
(
0 => (
0 => "0000000000000000",
1 => "0000000100000000",
2 => "0000001000000000",
3 => "0000001100000000",
4 => "0000010000000000",
5 => "0000010100000000",
6 => "0000011000000000",
7 => "0000011100000000",
8 => "0000101000000000",
9 => "0000101100000111",
10 => "0000110000000001",
11 => "0000111100000000"
),
1 => (
0 => "0000000000000000",
1 => "0000000100000000",
2 => "0000001000000000",
3 => "0000001100000000",
4 => "0000010000000000",
5 => "0000010100000000",
6 => "0000011000000000",
7 => "0000011100000000",
8 => "0000101000000000",
9 => "0000101100000111",
10 => "0000110000000001",
11 => "0000111100000000"
),
2 => (
0 => "0000000000000000",
1 => "0000000100000000",
2 => "0000001000000000",
3 => "0000001100000000",
4 => "0000010000000000",
5 => "0000010100000000",
6 => "0000011000000000",
7 => "0000011100000000",
8 => "0000101000000000",
9 => "0000101100000111",
10 => "0000110000000001",
11 => "0000111100000000"
),
3 => (
0 => "0000000000000000",
1 => "0000000100000000",
2 => "0000001000000000",
3 => "0000001100000000",
4 => "0000010000000000",
5 => "0000010100000000",
6 => "0000011000000000",
7 => "0000011100000000",
8 => "0000101000000000",
9 => "0000101100000111",
10 => "0000110000000001",
11 => "0000111100000000"
)
);
-- MAX6951 data is 8b Address and 8b Data
-- Address is:
-- 00 No-op (unused)
-- 01 Decode mode (fixed at default)
-- 02 Intensity (fixed at 0F in position 8)
-- 03 Scan limit (fixed at 07 in position 9)
-- 04 Configuration (fixed at 01 in position 10)
-- 07 Display test (fixed at 00 in position 11)
-- 60 Digit 0 (in position 0)
-- ...
-- 67 Digit 7 (in position 0)
type registers6951 is array(0 to 3,0 to 11) of std_logic_vector(15 downto 0);
signal max6951_vector : registers6951 :=
(
0 => (
0 => "0110000000000000",
1 => "0110000100000000",
2 => "0110001000000000",
3 => "0110001100000000",
4 => "0110010000000000",
5 => "0110010100000000",
6 => "0110011000000000",
7 => "0110011100000000",
8 => "0000001000000000",
9 => "0000001100000111",
10 => "0000010000000001",
11 => "0000011100000000"
),
1 => (
0 => "0110000000000000",
1 => "0110000100000000",
2 => "0110001000000000",
3 => "0110001100000000",
4 => "0110010000000000",
5 => "0110010100000000",
6 => "0110011000000000",
7 => "0110011100000000",
8 => "0000001000000000",
9 => "0000001100000111",
10 => "0000010000000001",
11 => "0000011100000000"
),
2 => (
0 => "0110000000000000",
1 => "0110000100000000",
2 => "0110001000000000",
3 => "0110001100000000",
4 => "0110010000000000",
5 => "0110010100000000",
6 => "0110011000000000",
7 => "0110011100000000",
8 => "0000001000000000",
9 => "0000001100000111",
10 => "0000010000000001",
11 => "0000011100000000"
),
3 => (
0 => "0110000000000000",
1 => "0110000100000000",
2 => "0110001000000000",
3 => "0110001100000000",
4 => "0110010000000000",
5 => "0110010100000000",
6 => "0110011000000000",
7 => "0110011100000000",
8 => "0000001000000000",
9 => "0000001100000111",
10 => "0000010000000001",
11 => "0000011100000000"
)
);
begin
gen_clk : process (clk) is
variable divider : integer := Clock_divider;
begin
if rising_edge(clk) then
if (divider=0) then
divider := Clock_divider;
clk_out <= not clk_out;
MAX7219_CLK <= not clk_out;
MAX6951_CLK <= not clk_out;
else
divider := divider - 1;
end if;
end if;
end process;
max7219 : process (clk_out) is
variable reg_counter : integer := 0;
variable bit_counter : integer := 16;
variable shift_reg0,shift_reg1,shift_reg2,shift_reg3 : std_logic_vector(16 downto 0);
begin
if falling_edge(clk_out) then
if bit_counter=0 then
bit_counter := 16;
if reg_counter=9 then
reg_counter := 0;
else
if reg_counter=9 then
reg_counter := 0;
else
reg_counter := reg_counter + 1;
end if;
case reg_counter is
when 0 to 7 =>
shift_reg0 := '0' & max7219_vector(0,reg_counter)(15 downto 8) & LEDs(reg_counter*8+0 to reg_counter*8+7);
shift_reg1 := '0' & max7219_vector(1,reg_counter)(15 downto 8) & LEDs(reg_counter*8+64 to reg_counter*8+71);
shift_reg2 := '0' & max7219_vector(2,reg_counter)(15 downto 8) & LEDs(reg_counter*8+128 to reg_counter*8+135);
shift_reg3 := '0' & max7219_vector(3,reg_counter)(15 downto 8) & LEDs(reg_counter*8+192 to reg_counter*8+199);
when others =>
shift_reg0 := '0' & max7219_vector(0,reg_counter);
shift_reg1 := '0' & max7219_vector(1,reg_counter);
shift_reg2 := '0' & max7219_vector(2,reg_counter);
shift_reg3 := '0' & max7219_vector(3,reg_counter);
end case;
end if;
else
bit_counter := bit_counter - 1;
shift_reg0 := shift_reg0(15 downto 0) & '0';
shift_reg1 := shift_reg1(15 downto 0) & '0';
shift_reg2 := shift_reg2(15 downto 0) & '0';
shift_reg3 := shift_reg3(15 downto 0) & '0';
end if;
if bit_counter=16 then
MAX7219_LOAD <= '1';
else
MAX7219_LOAD <= '0';
end if;
MAX7219_DIN0 <= shift_reg0(16);
MAX7219_DIN1 <= shift_reg1(16);
MAX7219_DIN2 <= shift_reg2(16);
MAX7219_DIN3 <= shift_reg3(16);
end if;
end process;
max6951 : process (clk_out) is
variable dev_counter : integer := 3;
variable reg_counter : integer := 0;
variable bit_counter : integer := 16;
variable shift_reg : std_logic_vector(16 downto 0);
begin
if falling_edge(clk_out) then
if bit_counter=0 then
bit_counter := 16;
if reg_counter=9 then
if dev_counter=0 then
dev_counter := 3;
else
dev_counter := dev_counter - 1;
end if;
reg_counter := 0;
else
if reg_counter=9 then
reg_counter := 0;
else
reg_counter := reg_counter + 1;
end if;
case reg_counter is
when 0 to 7 =>
shift_reg := '0' & max6951_vector(dev_counter,reg_counter)(15 downto 8) & LEDs(dev_counter*64+reg_counter*8 to dev_counter*64+reg_counter*8+7);
when others =>
shift_reg := '0' & max6951_vector(dev_counter,reg_counter);
end case;
end if;
else
bit_counter := bit_counter - 1;
shift_reg := shift_reg(15 downto 0) & '0';
end if;
if bit_counter=16 then
MAX6951_CS0 <= '1';
MAX6951_CS1 <= '1';
MAX6951_CS2 <= '1';
MAX6951_CS3 <= '1';
else
if dev_counter=0 then
MAX6951_CS0 <= '0';
else
MAX6951_CS0 <= '1';
end if;
if dev_counter=1 then
MAX6951_CS1 <= '0';
else
MAX6951_CS1 <= '1';
end if;
if dev_counter=2 then
MAX6951_CS2 <= '0';
else
MAX6951_CS2 <= '1';
end if;
if dev_counter=3 then
MAX6951_CS3 <= '0';
else
MAX6951_CS3 <= '1';
end if;
end if;
MAX6951_DIN <= shift_reg(16);
end if;
end process;
end behavioral;