Forum: FPGA, VHDL & Co. Quelltext verkürzen VHDL


von Toni M. (Firma: Private) (toggle2)


Angehängte Dateien:

Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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.

von toggle2 (Gast)


Angehängte Dateien:

Lesenswert?

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...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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...

von Toni M. (Firma: Private) (toggle2)


Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Toni M. (Firma: Private) (toggle2)


Lesenswert?

okay, werd mich mal da rein arbeiten, thx

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
Noch kein Account? Hier anmelden.