Hallo!
Ich baue gerade einen XC9572XL basierten Anodencontroller für LED
Matrizen.
Der CPLD lauscht an der Clockleitung des SPI Busses mit dem die
Shiftregister mit integrierten Konstantstromsenken mit Daten beladen
werden.
Jede 2592 Clocks muss folgendes passieren:
Es sollen 8 Anodenausgänge durchgeschaltet werden, es soll jeweils 1
Anodenausgang low sein, während die anderen High-Z sind.
Der CPLD soll auch ein Latchsignal für die Shiftregister generieren.
Dabei muss der Latch mindestens 10ns nach der letzten ansteigenden
Clockflanke und mindestens 100ns vor der nächsten ansteigenden
Clockflanke kommen.
Außerdem soll ein Reset vorhanden sein welcher die Register auf bekannte
Startwerte setzt und alle Ausgänge auf High-Z schaltet.
Im Moment habe ich das ganze wie folgt implementiert:
1 | library IEEE;
|
2 | use IEEE.STD_LOGIC_1164.ALL;
|
3 |
|
4 | entity rgbledmatrix is
|
5 | Port ( reset : in STD_LOGIC;
|
6 | clock : in STD_LOGIC;
|
7 | latch : out STD_LOGIC := '0';
|
8 | anodes : out STD_LOGIC_VECTOR (7 downto 0):= "0ZZZZZZZ");
|
9 | end rgbledmatrix;
|
10 |
|
11 | architecture Behavioral of rgbledmatrix is
|
12 | constant clock_div: integer:=2592; -- 12 Bit pro Kanal * 24 Kanäle * 9 TLC5947 = 2592
|
13 | signal counter: integer range 0 to clock_div-1;
|
14 | signal output: STD_LOGIC_VECTOR (7 downto 0):= "0ZZZZZZZ";
|
15 |
|
16 | begin
|
17 |
|
18 | process(clock,reset)
|
19 | begin
|
20 | if rising_edge(clock) then
|
21 | if reset='0' then -- Synchroner reset: Counter zurücksetzen und Outputregister auf Startwert
|
22 | counter <= 0;
|
23 | output <= "0ZZZZZZZ";
|
24 | elsif counter=clock_div-1 then
|
25 | counter <= 0;
|
26 | output(6 downto 0) <= output(7 downto 1); --Anodenbits vorbereiten
|
27 | output(7) <= output(0);
|
28 | else
|
29 | counter <= counter + 1;
|
30 | end if;
|
31 | end if;
|
32 | end process;
|
33 |
|
34 | process(clock,reset)
|
35 | begin
|
36 | if falling_edge(clock) then
|
37 | if reset='0' then -- Synchroner reset: Ausgänge auf High-Z
|
38 | latch <= 'Z';
|
39 | anodes <= "ZZZZZZZZ";
|
40 | elsif counter=0 then
|
41 | anodes(7 downto 0) <= output(7 downto 0); --Anodenbits ausgeben
|
42 | latch <= '1';
|
43 | elsif counter=1 then
|
44 | latch <= '0';
|
45 | end if;
|
46 | end if;
|
47 | end process;
|
48 |
|
49 | end Behavioral;
|
Im behavioral Sim scheint es richtig zu funktionieren, da ich aber nicht
all zu viel Erfahrung mit VHDL und CPLDs habe vermute ich, dass man den
Code auch eleganter schreiben könnte.
Ich würde mich freuen wenn ihr kurz drüber schauen und mir
Verbesserungsvorschläge geben könntet.