Hallo, hab ein Quelltext für die Ansteuerung eines Displays geschrieben. Dabei ist mir aufgefallen, dass dieser durch die Statemachine sehr lang ist. Kann man die Sache auch irgendwie verkürzen und vereinfachen, oder geht das nicht anders? THX for your ideas
Du könntest die Initialisierungssequenz incl. Steuersignale in ein konstantes Array stecken (das wird dann als ROM abgebildet) ...
1 | type Rom13x10 is array (0 to 12) of standard_logic_vector (9 downto 0); -- 8 Datenbits + 2 Steuerbits E und RS |
2 | LCDrom : Rom13x10 := (x"34"&'1'&'0', -- Data(7..4)=0x3, Data(3..0)= 0x4, E=1, RS=0 |
3 | x"34"&'0'&'0', |
4 | x"34"&'1'&'1', |
5 | x"34"&'0'&'1', |
6 | :
|
7 | x"34"&'1'&'0'); |
... und das mit einem Integer-Index schrittweise nacheinander abarbeiten. Wie der Zugriff auf so ein ROM funktioniert, kannst du an meinem DDFS-Beispiel sehen: http://www.lothar-miller.de/s9y/categories/31-DDFS Auf diese Art sollte der Quelltext auf eine Bildschirmseite zu reduzieren sein ;-) BTW: LCD_RW hängt statisch auf '0', das reicht, wenn es einmal gesetzt wird. Allerdings würde ich das Toggeln des LCD_E abseits abhandeln.
Hab jetz einfach mal ein array programmiert, synthetisiert wird das schon, aber es kommen folgende Warnungen: WARNING:Xst:790 - "C:/Users/Millers/Documents/Xilinx Projekte/display_01 - Kopie/array/array/daten.vhd" line 34: Index value(s) does not match array range, simulation mismatch. WARNING:Xst:1710 - FF/Latch <DOUT_int_1> (without init value) has a constant value of 0 in block <test_RAM>. This FF/Latch will be trimmed during the optimization process. WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <DOUT_int_2> (without init value) has a constant value of 0 in block <test_RAM>. This FF/Latch will be trimmed during the optimization process. WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <DOUT_int_3> (without init value) has a constant value of 0 in block <test_RAM>. This FF/Latch will be trimmed during the optimization process. WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <DOUT_int_5> (without init value) has a constant value of 0 in block <test_RAM>. This FF/Latch will be trimmed during the optimization process. WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <DOUT_int_7> (without init value) has a constant value of 0 in block <test_RAM>. This FF/Latch will be trimmed during the optimization process. Woran könnte das denn liegen? Hab schon ein paar Sachen ausprobiert, aber irgendwie will die Sache nicht so laufen...
> conv_integer(ADDR_int) ADDR_int kann mit 3 Bits die Werte von 0 bis 7 annehmen. Nimm doch als Index einen integer range 0 to 4, dann passt das besser zum array. > others => (x"00") Die Klammern kannst du hier weglassen. > ROM: process (takt, ADDR_int) Hier reicht takt aus, der Prozess muß nicht neu berechnet werden, wenn sich ADDR_int ändert. > (x"11", x"50", others => x"00") Mit diesen Intitialwerten sind natürlich DOUT_int_2, 3, 5 und 7 immer 0. Das sagt dir der Synthesizer mit den Warnungen...
Okay, jetzt hab ich es gerafft. Funktioniert jetzt ohne Warnungen. Wie kann ich denn die jeweiligen Adressen des array in der Statemachine ansprechen und auf die Ausgänge zuweisen und dadurch den Quelltext verkürzen?
Nimm mal diesen Code, leg mit einer simplen Testbench einen 50MHz-Takt an, und sieh dir an, was herauskommt (als Tipp: mindestens 15 ms laufen lassen):
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity LCD_Controller_16x2 is |
6 | Port ( -- Signale an LCD |
7 | rw : out STD_LOGIC; |
8 | rs : out STD_LOGIC; |
9 | en : out STD_LOGIC; |
10 | dout : out STD_LOGIC_VECTOR(7 downto 0); |
11 | -- der Takt
|
12 | clk : in STD_LOGIC |
13 | );
|
14 | end LCD_Controller_16x2; |
15 | |
16 | architecture Behavioral of LCD_Controller_16x2 is |
17 | type ramtyp is array (0 to 31) of std_logic_vector(11 downto 0); -- "00" & Delayzeit & RS Steuerbit & 8 Datenbits |
18 | signal ram : ramtyp := ( "0010" & x"f2", |
19 | "0000" & x"f3", |
20 | "0011" & x"f4", |
21 | "0001" & x"f5", |
22 | "0000" & x"e6", |
23 | "0000" & x"e7", |
24 | "0001" & x"e8", |
25 | "0001" & x"e9", |
26 | "0000" & x"da", |
27 | "0000" & x"db", |
28 | "0000" & x"dc", |
29 | "0001" & x"dd", |
30 | "0001" & x"ce", |
31 | "0000" & x"cf", |
32 | "0000" & x"c1", |
33 | "0000" & x"c2", |
34 | "0000" & std_logic_vector(to_unsigned(character'pos('h'),8)), |
35 | "0000" & std_logic_vector(to_unsigned(character'pos('a'),8)), |
36 | "0000" & std_logic_vector(to_unsigned(character'pos('l'),8)), |
37 | "0000" & std_logic_vector(to_unsigned(character'pos('l'),8)), |
38 | "0000" & std_logic_vector(to_unsigned(character'pos('o'),8)), |
39 | "0000" & std_logic_vector(to_unsigned(character'pos(' '),8)), |
40 | "0001" & std_logic_vector(to_unsigned(character'pos('w'),8)), |
41 | "0001" & std_logic_vector(to_unsigned(character'pos('e'),8)), |
42 | "0000" & std_logic_vector(to_unsigned(character'pos('l'),8)), |
43 | "0000" & std_logic_vector(to_unsigned(character'pos('t'),8)), |
44 | "0001" & std_logic_vector(to_unsigned(character'pos('!'),8)), |
45 | others => ("0000" & std_logic_vector(to_unsigned(character'pos('#'),8))) |
46 | );
|
47 | |
48 | constant fosc : integer := 50000000; |
49 | signal pre1us : integer range 0 to fosc/1000000 := 0; |
50 | constant longtime : integer := 5000; -- 5 ms |
51 | constant shorttime : integer := 20; -- 20 us |
52 | signal delay : integer range 0 to longtime := 0; |
53 | signal index : integer range 0 to 31 := 0; |
54 | begin
|
55 | |
56 | process begin |
57 | wait until rising_edge(clk); |
58 | if (pre1us<fosc/1000000) then |
59 | pre1us <= pre1us+1; |
60 | else -- 1us vorbei |
61 | pre1us <= 0; |
62 | if (delay<1) then en<='1'; -- 1us Latency --> tsu für Adressen |
63 | else en<='0'; |
64 | end if; |
65 | if ( (ram(index)(9)='1' and delay=longtime) or (ram(index)(9)='0' and delay=shorttime) ) then |
66 | delay <= 0; |
67 | if (index<31) then index <= index+1; end if; |
68 | else
|
69 | delay <= delay+1; |
70 | end if; |
71 | end if; |
72 | if (index=31) then en <= '0'; end if; -- fertig, kein enable mehr ausgeben |
73 | end process; |
74 | |
75 | dout <= ram(index)(dout'range); |
76 | rs <= ram(index)(8); |
77 | rw <= '0'; |
78 | |
79 | end Behavioral; |
Wenn du das dann so in etwa nachvollzogen hast, ist deine Frage automatisch beantwortet ;-) BTW: die ganzen Hex-Werte müssen noch an das Display angepasst werden...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.