From a48fa3d53d33a233dd61e32c0122abd6b7c206cb Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Nov 2015 09:22:31 +0100 Subject: [PATCH] Add Maxim external LED drivers, MAX7219 or MAX7951, for front panel lamps --- Testbench_panel_LEDs.vhd | 125 ++++++++++++++ ibm2030-vga.vhd | 4 +- ibm2030.vhd | 215 ++++++++++++++++++++++- panel_LEDs.vhd | 360 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 701 insertions(+), 3 deletions(-) create mode 100644 Testbench_panel_LEDs.vhd create mode 100644 panel_LEDs.vhd diff --git a/Testbench_panel_LEDs.vhd b/Testbench_panel_LEDs.vhd new file mode 100644 index 0000000..1ffecac --- /dev/null +++ b/Testbench_panel_LEDs.vhd @@ -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; diff --git a/ibm2030-vga.vhd b/ibm2030-vga.vhd index 4055bb7..535a60a 100644 --- a/ibm2030-vga.vhd +++ b/ibm2030-vga.vhd @@ -155,7 +155,7 @@ constant indLayout : screenIndicators := -- To convert ASCII to the internal 6-bit representation... -- Not all characters are needed, so some special ones are added 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 := ( -- 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", @@ -1527,7 +1527,7 @@ function initScreen (constant screen : screenType) return screenCharacters is begin for r in lines 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; return sc; diff --git a/ibm2030.vhd b/ibm2030.vhd index 648b3b1..b038147 100644 --- a/ibm2030.vhd +++ b/ibm2030.vhd @@ -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 DEBUG : DEBUG_BUS; -- Passed to all modeles to probe signals + +signal LED_vector : std_logic_vector(0 to 255); + begin cpu : entity cpu port map ( @@ -479,7 +482,7 @@ begin -- Clocks etc. clk => clk, -- 50MHz clock - Clock1ms => Clock1ms, +-- Clock1ms => Clock1ms, Timer => N60_CY_TIMER_PULSE -- Output from Switches is actually 50Hz ); @@ -503,7 +506,217 @@ begin clk => clk ); 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)); diff --git a/panel_LEDs.vhd b/panel_LEDs.vhd new file mode 100644 index 0000000..7048b36 --- /dev/null +++ b/panel_LEDs.vhd @@ -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 . +-- +--------------------------------------------------------------------------- +-- +-- 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; +