Forum: FPGA, VHDL & Co. Beschreibung eines Srams Fehler in VHDL-Code?


von Mike (Gast)


Lesenswert?

Hallo zusammen,

ich schreibe gerade an einem VHDL-Code, der das SRAM auf meinem Altera 
DE2-115 beschreiben soll und später die gespeicherten Daten auf das LCD 
senden soll.

Alles klappt auch soweit, wenn ich einen statischen Buchstaben in das 
Sram einlese, bei einem Satz funktioniert es leider nicht mehr und ich 
weiß nicht, wo der Fehler liegt.
1
architecture behv of lcd_control is
2
3
...
4
5
SUBTYPE ascii1 IS STD_LOGIC_VECTOR(7 DOWNTO 0);
6
TYPE charArray IS array(1 to 27) OF ascii1;
7
8
constant satz1: charArray         := (X"48", X"65", X"6c", X"6c", X"6f", X"20", X"57", X"6f", X"72", X"6c", X"72", X"6c", X"64", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20" );
9
10
11
...
12
13
-- das funktioniert, das Zeichen wird auf den LCD-Screen angezeigt
14
15
sram_data(7 downto 0) <=  satz1(3);-- plus 8 bit zahl;
16
17
-- **********************************************************************
18
-- (das funktioniert leider nicht, obwohl der Counter counter_buch hochgezählt wird)
19
20
sram_data(7 downto 0) <=  satz1(counter_buch);-- plus 8 bit zahl;

Weiß jemand, warum das mit der variable nicht funktioniert?
Danke an alle hilfreichen Antworten...

LG

Mike

von Klaus (Gast)


Lesenswert?

Mike schrieb:
> funktioniert es leider nicht mehr

Mike schrieb:
> warum das mit der variable nicht funktioniert?

Mike schrieb:
> -- (das funktioniert leider nicht,

Das sind alles keine Fehlerbeschreibungen. WAS funktioniert nicht, 
bzw. welches Verhalten beobachtest du stattdessen?


Und wo kommt counter_buch  her? Signalquelle und Deklaration bitte.

von August (Gast)


Lesenswert?

bau dir mal ein array mit einer zweier potenz (in diesem fall eine 
erweiterung auf 32 element) und dann ein std logic vector mit 5 bits für 
den zugriff und teste das nochmal.

von Duke Scarring (Gast)


Lesenswert?

Mike schrieb:
> ich schreibe gerade an einem VHDL-Code, der das SRAM auf meinem Altera
> DE2-115 beschreiben soll und später die gespeicherten Daten auf das LCD
> senden soll.
Hast Du auch eine Testbench dazu?

Duke

von Mike (Gast)


Lesenswert?

Sorry, meine Fehlerbeschreibung war wirklich etwas ungenau. Hier ein 
Auszug meines Codes, habe die problematische Stelle mit einem Kommentar 
versehen.

Ziel meines Codes: Einlesen von verschiedenen Buchstaben in das SRAM und 
im 2. Schritt auslesen und auf dem LCD anzeigen.



1
------------------------------------------------------------------- 
2
--                        ASCII HEX TABLE
3
--  Hex            Low Hex Digit
4
-- Value  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
5
------\----------------------------------------------------------------
6
--H  2 |  SP  !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /
7
--i  3 |  0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?
8
--g  4 |  @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
9
--h  5 |  P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _
10
--   6 |  `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
11
--   7 |  p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~ DEL
12
-----------------------------------------------------------------------
13
14
LIBRARY IEEE;
15
USE  IEEE.STD_LOGIC_1164.all;
16
USE  IEEE.STD_LOGIC_ARITH.all;
17
USE  IEEE.STD_LOGIC_UNSIGNED.all;
18
19
20
entity lcd_control is
21
  port
22
  (
23
    trigger, sw_an, reset, clk   : in  std_logic;
24
    ascii                     : in  std_logic_vector(7 downto 0);
25
    lcd_rs, lcd_e, lcd_rw       : out std_logic;
26
    lcd_data                 : out std_logic_vector(7 downto 0);
27
    led_test1                   : out std_logic := '0';
28
    lcd_an                      : out std_logic;
29
    
30
    sram_adress             : out std_logic_vector(19 downto 0);
31
    sram_data             : inout std_logic_vector(15 downto 0);
32
    sram_chip_enable         : out std_logic;
33
    sram_write_enable_input     : out std_logic;
34
    sram_output_enable_input    : out std_logic;
35
    sram_lower_byte             : out std_logic;
36
    sram_upper_byte             : out std_logic;
37
    sram_power                  : out std_logic; 
38
    sram_nc                     : out std_logic
39
    
40
    );
41
end lcd_control;
42
43
architecture behv of lcd_control is
44
45
type state_type is (RESET1, RESET2, RESET3, 
46
                    DROP_E, HOLD,
47
                    FUNC_SET, DISP_ON, DISP_CLEAR, MODE_SET,
48
                    WAIT_CHAR, DISP_CLEAR_WAIT,
49
                    WAIT_TRIGGER_RESET,
50
                    CHK_CNT, LINE2, HOME);
51
                    
52
type state_type_sram is ( SET_ADRESS, SET_DATA);
53
signal state_ram  : state_type_sram := SET_ADRESS;
54
signal state_ram_next : state_type_sram;
55
56
signal state, next_command, satz_1, satz_2, satz_3 : state_type;
57
signal char_cnt                   : std_logic_vector(5 downto 0);
58
signal counter_buch               : integer range 1 to 99 := 1;
59
signal wait_cnt, pause, pause2    : std_logic_vector(24 downto 0);
60
signal ascii_sig                  : std_logic_vector(7 downto 0);
61
signal satz1ende              : std_logic := '1';
62
63
signal schreibeprozess_ende       : std_logic :='0';
64
signal sram_adress_counter       : std_logic_vector(19 downto 0) := "00000000000000000001";
65
signal up_or_low             : std_logic;
66
signal esgehtlos                  : std_logic;
67
68
69
SUBTYPE ascii1 IS STD_LOGIC_VECTOR(7 DOWNTO 0);
70
TYPE charArray IS array(1 to 27) OF ascii1;
71
constant satz1: charArray         := (X"48", X"65", X"6c", X"6c", X"6f", X"20", X"57", X"6f", X"72", X"6c", X"72", X"6c", X"64", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20" );
72
signal leerzeichen : std_logic_vector(7 DOWNTO 0) := "00000000";  
73
  
74
begin
75
   lcd_rw<='0';
76
  
77
  process   
78
  begin
79
  wait until rising_edge(clk);
80
  
81
  if schreibeprozess_ende= '0' then -- Beginn des Scheibeprozesses auf das SRAM
82
    
83
    if counter_buch < 28 then
84
85
        case state_ram is
86
        
87
          when SET_ADRESS =>
88
      
89
            sram_adress<= sram_adress_counter;
90
            
91
            sram_write_enable_input<= '1';
92
            sram_chip_enable<= '0';
93
            sram_output_enable_input<='0';
94
            sram_data(7 downto 0) <=  satz1(counter_buch); 
95
96
-- HIER IST DAS PROBLEM. BEI DER ZUWEISUNG "<= SATZ1(3)" SCHREIBT ER DEN 3 BUCHSTABEn VON SATZ1 IN DEN SPEICHER, DAS ZEICHEN WIR AUCH ERFOLGREICH BEIM AUSLESEN AUF DAS LCD GESCHRIEBEN
97
-- BEI SATZ1(COUNTER_BUCH) WERDEN NUR LEERZEICHEN IN DEN SPEICHER GESCHRIEBEN UND AUF DEM LCD ANGEZEIGT, OBWOHL DER COUNTER LAUT MODELSIM HOCHGEZAEHLT WIRD.
98
 
99
            sram_data(15 downto 8) <= leerzeichen(7 downto 0);
100
            sram_lower_byte<='1';
101
            sram_upper_byte<='1';
102
            
103
104
            if wait_cnt < X"2710" then      
105
              wait_cnt <= wait_cnt +1;
106
              state_ram <= SET_ADRESS;
107
            else
108
              wait_cnt <= "0000000000000000000000000";
109
              counter_buch<= counter_buch+1;
110
              sram_adress_counter<= sram_adress_counter + 1; 
111
              state_ram <= SET_DATA;
112
                             -- wait counter reset
113
            end if;
114
                
115
                
116
          when SET_DATA =>
117
      
118
            sram_write_enable_input<= '0';
119
            sram_lower_byte<='0';
120
            sram_upper_byte<='0';
121
            
122
            if wait_cnt < X"2710" then      -- warten für 10000 Cycle, 200 ms 
123
              wait_cnt <= wait_cnt +1;
124
              state_ram <= SET_DATA;
125
            else
126
              wait_cnt <= "0000000000000000000000000";
127
128
              state_ram <= SET_ADRESS;
129
                             -- wait counter reset
130
            end if;
131
            
132
          end case;
133
 
134
    else
135
136
--- Beginn des Ausleseprozesses und weiterleitung der Daten an das LCD...

von Mike (Gast)


Lesenswert?

@ August:

Was genau soll das in dem Falle bringen? Vielleicht erklärst du mir 
deinen Vorschlag noch ein wenig genauer, denn ich möchte doch ein 
8Bit-Zeichen einlesen und kein 5 Bit...

@Duke,

Sorry Duke, keine Testbench vorhanden...


Aber rein theoretisch sollte doch eine Variabel in dem Array in einer 
Signalzuweisung funktionieren, oder?

LG

Mike...

von Pako (Gast)


Lesenswert?

Mike schrieb:
> -- BEI SATZ1(COUNTER_BUCH) WERDEN NUR LEERZEICHEN IN DEN SPEICHER GESCHRIEBEN 
UND AUF DEM LCD ANGEZEIGT, OBWOHL DER COUNTER LAUT MODELSIM HOCHGEZAEHLT WIRD.

Meinst Du mit "Leerzeichen" x"00" oder x"20"?

von Mike (Gast)


Lesenswert?

das weiß ich nicht genau, es wir halt nur Leerzeichen auf dem LCD 
angezeigt. Wenn ich dem SRAm ein statisches X"48" für alle 
Speicherplätze zuweise, dann wird dieses Zeichen beim Ausleseprozess 
auch vom LCD angezeigt...

von Duke Scarring (Gast)


Lesenswert?

Mike schrieb:
> Sorry Duke, keine Testbench vorhanden...
Sehr schade. Das ist wie Autofahren ohne Airbag und ohne 
Sicherheitsgurt.

Mit Testbench kann man so ein Problem leicht im Simulator 
nachvollziehen.
Ich empfehle Dir dringend Dich dem Thema Simulation zu widmen.

Duke

von Lupensucher (Gast)


Lesenswert?

signal counter_buch               : integer range 1 to 99 := 1;

die range für den counter ist größer als das rom-array? (1 ... 27) was 
dieser counter addressiert. daren könnte die synthese scheitern da die 
bitvektoren unterschiedliche breite haben, besser beides auf 0 .. 26 
schreiben. Noch besser könnte 0 ... 31 sein.

Schau mal im synthesereport, was das synthesetool an diese Stelle sagt

MfG,

von O_- (Gast)


Lesenswert?

Mike schrieb:
> @ August:
>
> Was genau soll das in dem Falle bringen? Vielleicht erklärst du mir
> deinen Vorschlag noch ein wenig genauer, denn ich möchte doch ein
> 8Bit-Zeichen einlesen und kein 5 Bit...
>

die 5bit sind für die adressierung von 2^5 = 32 elementen
1
signal address : std_ulogic_vector(4 downto 0);
2
signal my_array : t_array_type(0 to 31);
3
4
-- read 
5
output_data <= my_array(to_integer(unsigned(my_addr)));
6
7
-- write
8
my_array(to_integer(unsigned(my_addr))) <= input_data;

solltest du weniger als 32 elemente haben, dann musste du die eben mit 
platzhaltern füllen. sollte dein adresszeiger mehr als 5 bit haben (zB 
wenn du den irgendwo anders zum zählen benutzt, dann musst du beim 
read/write eben mit einer range arbeiten.

von SuperWilly (Gast)


Lesenswert?

>> Sorry Duke, keine Testbench vorhanden...
>Sehr schade. Das ist wie Autofahren ohne Airbag und ohne
>Sicherheitsgurt.

Das ist sogar Autofahren mit geschlossenen Augen -


VG, SuperWilly

von Lupensucher (Gast)


Lesenswert?

ich seh grad August als weiterem leser ist das selbe aufgefallen. Sollte
es wirklich ein problem mit synthesegerechten Code sei hilft dir eine 
simu nicht weiter, ein Blick in den Synthesereport dagegen schon. Bitte 
mal als File-anhängsel hier posten.

von Pako (Gast)


Lesenswert?

Mike schrieb:
> das weiß ich nicht genau, es wir halt nur Leerzeichen auf dem LCD
> angezeigt. Wenn ich dem SRAm ein statisches X"48" für alle
> Speicherplätze zuweise, dann wird dieses Zeichen beim Ausleseprozess
> auch vom LCD angezeigt...

Das Problem könnte ja auch gaaanz wo anders liegen, z.B. bei Timing 
Constrains des LCDs, aber das siehst Du nicht, wenn die Daten statisch 
anliegen (immer nur x"48"). Erst dann, wenn sie sich ändern, kommt 
nichts sinnvolles mehr bei raus.

von Mike (Gast)


Angehängte Dateien:

Lesenswert?

Leider hat das Anpassen der Variabel Counter_buch nichts gebracht, aber 
ich weiß nun, wo mein wirkliches Problem liegt bzw. warum nur 
Leerzeichen ausgegeben werden.

Im 2. Schritt versuche ich die Daten wieder auszulesen, was aber nicht 
klappt, weil ich im Leseprozess des SRAMS und beim Schreibprozess beim 
LCD folgendes deklarieren:


lcd_data <= sram_data(7 downto 0);

Da sram_data(7 downto 0) den Wert das letzte Element meines Arrays (in 
dem Fall ein x"20") nach dem Schreibeprozess in das SRAM noch 
beinhaltet, wird dieses Element dann Zeilenweise auf das Display 
gedruckt.

Daher 2 mögliche Fehlerquellen: Es werden keine Daten ins SRAM 
geschrieben, oder der Ausleseprozess aus dem SRAM funzt nicht (was ich 
viel eher vermute).

Habe mal den kompletten Quellcode und das Datenblatt des SRAMs mal 
hinzugefügt und bei der Programmierung den READ CYCLE #1 auf Seite 11 
genommen.

@ O_-
tnx, hab ich nun verstanden, wird implementiert und getestet...

P.s.: Ich weiß, stylistisch ist der Code nicht vom feinsten....
1
------------------------------------------------------------------- 
2
--                        ASCII HEX TABLE
3
--  Hex            Low Hex Digit
4
-- Value  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
5
------\----------------------------------------------------------------
6
--H  2 |  SP  !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /
7
--i  3 |  0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?
8
--g  4 |  @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
9
--h  5 |  P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _
10
--   6 |  `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
11
--   7 |  p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~ DEL
12
-----------------------------------------------------------------------
13
14
LIBRARY IEEE;
15
USE  IEEE.STD_LOGIC_1164.all;
16
USE  IEEE.STD_LOGIC_ARITH.all;
17
USE  IEEE.STD_LOGIC_UNSIGNED.all;
18
19
20
entity lcd_control is
21
  port
22
  (
23
    trigger, sw_an, reset, clk   : in  std_logic;
24
    ascii                     : in  std_logic_vector(7 downto 0);
25
    lcd_rs, lcd_e, lcd_rw       : out std_logic;
26
    lcd_data                 : out std_logic_vector(7 downto 0);
27
    led_test1                   : out std_logic := '0';
28
    lcd_an                      : out std_logic;
29
    
30
    sram_adress             : out std_logic_vector(19 downto 0);
31
    sram_data             : inout std_logic_vector(15 downto 0);
32
    sram_chip_enable         : out std_logic;
33
    sram_write_enable_input     : out std_logic;
34
    sram_output_enable_input    : out std_logic;
35
    sram_lower_byte             : out std_logic;
36
    sram_upper_byte             : out std_logic;
37
    sram_power                  : out std_logic; 
38
    sram_nc                     : out std_logic
39
    
40
    );
41
end lcd_control;
42
43
architecture behv of lcd_control is
44
45
type state_type is (RESET1, RESET2, RESET3, 
46
                    DROP_E, HOLD,
47
                    FUNC_SET, DISP_ON, DISP_CLEAR, MODE_SET,
48
                    WAIT_CHAR, DISP_CLEAR_WAIT,
49
                    WAIT_TRIGGER_RESET,
50
                    CHK_CNT, LINE2, HOME);
51
                    
52
type state_type_sram is ( SET_ADRESS, SET_DATA);
53
signal state_ram  : state_type_sram := SET_ADRESS;
54
signal state_ram_next : state_type_sram;
55
56
                    
57
                    
58
signal state, next_command, satz_1, satz_2, satz_3 : state_type;
59
signal char_cnt                   : std_logic_vector(5 downto 0);
60
signal counter_buch               : integer range 0 to 31 := 0;
61
signal wait_cnt, pause, pause2    : std_logic_vector(24 downto 0);
62
signal ascii_sig                  : std_logic_vector(7 downto 0);
63
signal satz1ende              : std_logic := '1';
64
65
signal schreibeprozess_ende       : std_logic :='0';
66
signal sram_adress_counter       : std_logic_vector(19 downto 0) := "00000000000000000001";
67
signal up_or_low             : std_logic;
68
signal esgehtlos                  : std_logic;
69
70
71
SUBTYPE ascii1 IS STD_LOGIC_VECTOR(7 DOWNTO 0);
72
TYPE charArray IS array(0 to 31) OF ascii1;
73
constant satz1: charArray         := (X"48", X"65", X"6c", X"6c", X"6f", X"20", X"57", X"6f", X"72", X"6c", X"72", X"6c", X"64", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20", X"20",X"20",X"20", X"20" );
74
signal leerzeichen : std_logic_vector(7 DOWNTO 0) := "00000000";  
75
  
76
begin
77
   lcd_rw<='0';
78
  
79
   process   -- Das ist die State Machine f?rs LCD
80
  begin
81
  wait until rising_edge(clk);
82
  
83
  if schreibeprozess_ende= '0' then
84
    
85
    if counter_buch < 28 then
86
87
        case state_ram is
88
        
89
          when SET_ADRESS =>
90
      
91
            sram_adress<= sram_adress_counter;
92
            
93
            sram_write_enable_input<= '1';
94
            sram_chip_enable<= '0';
95
            sram_output_enable_input<='0';
96
            sram_data(7 downto 0) <=  satz1(counter_buch);-- plus 8 bit zahl;
97
            sram_data(15 downto 8) <= leerzeichen(7 downto 0);
98
            sram_lower_byte<='1';
99
            sram_upper_byte<='1';
100
            
101
102
            if wait_cnt < X"2710" then      -- warten für 10000 Cycle, 200 ms 
103
              wait_cnt <= wait_cnt +1;
104
              state_ram <= SET_ADRESS;
105
            else
106
              wait_cnt <= "0000000000000000000000000";
107
              counter_buch<= counter_buch+1;
108
              sram_adress_counter<= sram_adress_counter + 1; 
109
              state_ram <= SET_DATA;
110
                             -- wait counter reset
111
            end if;
112
                
113
                
114
          when SET_DATA =>
115
      
116
            sram_write_enable_input<= '0';
117
            sram_lower_byte<='0';
118
            sram_upper_byte<='0';
119
            
120
            if wait_cnt < X"2710" then      -- warten für 10000 Cycle, 200 ms 
121
              wait_cnt <= wait_cnt +1;
122
              state_ram <= SET_DATA;
123
            else
124
              wait_cnt <= "0000000000000000000000000";
125
126
              state_ram <= SET_ADRESS;
127
                             -- wait counter reset
128
            end if;
129
            
130
          end case;
131
 
132
    else
133
    schreibeprozess_ende <= '1';
134
    sram_adress_counter<= "00000000000000000000";
135
    counter_buch<= 1;
136
  end if;  
137
  
138
  else      
139
      if sw_an = '1' then
140
        lcd_an<='1';
141
       else
142
        lcd_an<='0';
143
       end if;    
144
          
145
      if (reset = '0') then
146
      
147
        state <= RESET1;
148
        next_command <= RESET2;              
149
        wait_cnt <= "0000000000000000000000000";
150
        lcd_data <= X"38"; -- 111000 - 8 bit - 2 Zeilen
151
        char_cnt <= "000000";
152
        lcd_e<='0';
153
        
154
      elsif reset = '1' then
155
        state <= RESET1;
156
157
        case state is
158
        
159
          when RESET1 =>                  -- erstes Kommando an LCD, mind. 16ms nach Einschalten
160
          
161
            lcd_rs <= '0';
162
            sram_write_enable_input<='1';
163
            lcd_data <= X"38"; -- 111000 - 8 bit - 2 Zeilen
164
            lcd_e <= '0';
165
            led_test1<='1';
166
            wait_cnt <= "0000000000000000000000000";
167
            pause <= "0000000000000000000000000";
168
169
            
170
            if wait_cnt < X"F4240" then      -- warten für 10000 Cycle, 200 ms 
171
              wait_cnt <= wait_cnt +1;
172
              state <= RESET1;
173
             else
174
              state <= DROP_E;            -- Kommando an LCD
175
              next_command <= RESET2;
176
              wait_cnt <= "0000000000000000000000000";            -- wait counter reset
177
            end if;
178
            
179
          when RESET2 =>
180
           
181
            lcd_rs <= '0';
182
            lcd_data <= X"38";
183
            lcd_e <= '0';
184
            
185
            if wait_cnt < X"F4240" then      -- Warteschleife für 200 ms --989680 --F4240
186
              wait_cnt <= wait_cnt +1;
187
              state <= RESET2;
188
            else
189
              state <= DROP_E;            
190
              next_command <= RESET3;
191
              wait_cnt <= "0000000000000000000000000";          
192
            end if;
193
            
194
          when RESET3 =>
195
          
196
            lcd_rs <= '0';
197
            lcd_data <= X"38";
198
            lcd_e <= '0';
199
            
200
            if wait_cnt < X"F4240" then      -- Warteschleife für 200 ms
201
              wait_cnt <= wait_cnt +1;
202
              state <= RESET3;
203
            else
204
              state <= DROP_E;            
205
              next_command <= FUNC_SET;
206
              wait_cnt <= "0000000000000000000000000";          
207
            end if;
208
            
209
          when FUNC_SET =>
210
            lcd_rs <= '0';
211
            lcd_data <= X"38";
212
            lcd_e <= '0';
213
            
214
            if wait_cnt < X"F4240" then      -- Warteschleife für 200 ms
215
              wait_cnt <= wait_cnt +1;
216
              state <= FUNC_SET;
217
            else
218
              state <= DROP_E;            
219
              next_command <= DISP_ON;
220
              wait_cnt <= "0000000000000000000000000";          
221
            end if;      
222
      
223
            
224
          when DISP_ON =>
225
            lcd_rs <= '0';
226
            lcd_data <= X"0F";
227
            lcd_e <= '0';
228
            
229
            if wait_cnt < X"F4240" then      -- Warteschleife für 200 ms
230
              wait_cnt <= wait_cnt +1;
231
              state <= DISP_ON;
232
            else
233
              state <= DROP_E;            
234
              next_command <= DISP_CLEAR;
235
              wait_cnt <= "0000000000000000000000000";          
236
            end if;  
237
            
238
            
239
            
240
          when DISP_CLEAR =>
241
          
242
            lcd_rs <= '0';
243
            lcd_data <= X"01";
244
            lcd_e <= '0';
245
            wait_cnt <= "0000000000000000000000000";
246
            state <= DROP_E;            
247
            next_command <= DISP_CLEAR_WAIT;
248
            
249
250
          when DISP_CLEAR_WAIT =>
251
            if wait_cnt < X"F4240" then      -- clk period 1msec, warte 3 msec
252
              wait_cnt <= wait_cnt +1;
253
              state <= DISP_CLEAR_WAIT;
254
            else
255
              state <= MODE_SET;            -- Kommando an LCD
256
              wait_cnt <= "0000000000000000000000000";          
257
            end if;
258
            
259
          when MODE_SET =>
260
            lcd_rs <= '0';
261
            lcd_data <= X"06";
262
            lcd_e <= '0';
263
          --  counter_buch<=1;
264
            char_cnt<="000000";
265
            
266
            if wait_cnt < X"F4240" then      -- Warteschleife für 200 ms
267
              wait_cnt <= wait_cnt +1;
268
              state <= MODE_SET;
269
            else
270
              state <= DROP_E;            
271
              next_command <= WAIT_CHAR;
272
              wait_cnt <= "0000000000000000000000000";  
273
              esgehtlos<='1';
274
        
275
            end if;  
276
            
277
    ---------------- Initialisierung beendet, Arbeitsloop -------------------------------------------
278
279
    --   WAIT_CHAR -> DROP_E -> HOLD -> WAIT_TRIGGER_RESET -> CHK_CNT -> LINE2 -> DROP_E -> HOLD -> |
280
    --                                                                |                              |
281
    --        ^                                                       -> HOME  -> DROP_E -> HOLD -> |
282
    --        |                                                       |                              |
283
    --        |                                                       v                             v
284
    --        |----------------------------------------<<-------------------------------------------|
285
286
    -------------------------------------------------------------------------------------------------
287
            
288
            when WAIT_CHAR =>
289
          
290
            if pause < X"F4240" then      -- warten für 10000 Cycle, 200 ms 
291
              pause <= pause +1;
292
              state <= WAIT_CHAR;
293
              
294
              elsif char_cnt < X"1B" then
295
              
296
              pause <= "0000000000000000000000000";            -- wait counter reset
297
              
298
              lcd_rs<='1';
299
               lcd_data <= sram_data(7 downto 0);
300
            
301
              sram_chip_enable<='0';
302
                sram_output_enable_input<='0';
303
              sram_lower_byte<='0';
304
                 sram_upper_byte<='0';
305
              
306
              
307
              
308
              char_cnt <= char_cnt +1;
309
              counter_buch<= counter_buch+1;
310
              
311
              lcd_e <= '0';
312
              state <= DROP_E;
313
              next_command <= WAIT_TRIGGER_RESET;
314
              
315
              
316
    --          elsif pause2 < X"1C9C380" then      -- warten für 10000 Cycle, 200 ms 
317
      --         pause2 <= pause2 +1;
318
        --       state <= WAIT_CHAR;
319
  
320
  
321
              else
322
              
323
            --  counter_buch<=1;
324
              state <= DROP_E;
325
              next_command <= DISP_CLEAR;
326
              char_cnt <= "000000";
327
            --  pause2<="0000000000000000000000000";
328
329
330
              end if;      
331
                            
332
          when WAIT_TRIGGER_RESET =>
333
            if trigger = '0' then
334
              state <= WAIT_TRIGGER_RESET;
335
            else
336
337
              state<=DROP_E;
338
              next_command <= CHK_CNT;
339
            end if;
340
            
341
          when CHK_CNT =>
342
            if char_cnt = X"11" then
343
             state <= DROP_E;
344
             next_command <= LINE2;
345
             
346
            elsif char_cnt = X"20" then
347
              state <= HOME;
348
            else
349
              state <= WAIT_CHAR;
350
            end if;
351
            
352
            when LINE2 =>
353
            lcd_rs <= '0';
354
            lcd_data <= X"C0";
355
            lcd_e <= '0';          
356
            state <= DROP_E;
357
            next_command <= WAIT_CHAR;
358
            
359
          when HOME =>
360
            lcd_rs <= '0';
361
            lcd_data <= X"80";  -- Befehl Cursor wieder auf Start setzten
362
            char_cnt <= "000000";
363
            lcd_e <= '0';
364
            state <= DROP_E;
365
            next_command <= WAIT_CHAR;
366
                  
367
          when DROP_E =>  
368
          
369
          lcd_e<='1';
370
           if wait_cnt < X"F4240" then      -- warten für 10000 Cycle, 200 ms 
371
            wait_cnt <= wait_cnt +1;
372
            state<=DROP_E;
373
            
374
            sram_adress<= "00000000000000100010"; -- <=sram_adress_counter;
375
            else
376
            wait_cnt<="0000000000000000000000000";
377
            
378
            if esgehtlos = '1' then 
379
            sram_adress_counter<=sram_adress_counter+1;
380
            end if;
381
382
            state <= HOLD; 
383
            end if; 
384
385
          when HOLD =>
386
            state <= next_command;
387
          
388
        end case;
389
      end if;
390
    end if;
391
  end process;
392
  
393
394
end behv;

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

Mike schrieb:
> USE  IEEE.STD_LOGIC_ARITH.all;
> USE  IEEE.STD_LOGIC_UNSIGNED.all;
Erstmal ersetzt man die Libs mit der folgenden:
1
use IEEE.NUMERIC_STD.ALL;
Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

Zweitens: Mach Dir eine Testbench. Du hast hier ein Display und ein 
SRAM. Das ist evtl. noch überschaubar. Das nächste Projekt dann nicht 
mehr.
Hier ist Deine Testbench noch trivial. Für den Anfang reichen ein paar 
Stimuli.


Lupensucher schrieb:
> Sollte
> es wirklich ein problem mit synthesegerechten Code sei hilft dir eine
> simu nicht weiter,
Ja und wenn es funktionaler Fehler ist, hilft Dir der Sysnthesereport 
auch nicht weiter.
Ich mache 99,9% funktionale Fehler. Bei Dir scheint das ja anders zu 
sein...

So. Los geht's mit der Testbench:
1
$ vlib work
2
$ vcom lcd_control.vhd
3
$ vcom lcd_control_tb.vhd
4
$ vsim -gui lcd_control_tv
5
# ** Warning: (vsim-8683) Uninitialized out port /lcd_control_tb/dut/sram_power has no driver.
6
# ** Warning: (vsim-8683) Uninitialized out port /lcd_control_tb/dut/sram_nc has no driver.
7
> add wave *
8
> run 20 ms

Das sieht ma die ganze Zeit was am SRAM wackeln, aber nicht am Display.
Kurzer Blick in den Code. "trigger" is offenbar low aktiv.
Um mir nicht selber ins Knie zu schiessen, haben alle meine low aktiven 
Signale ein _n als Suffix --> trigger_n

Trotzdem scheint da nix weiter loszugehen...

Ah, reset ist offenbar auch low aktiv...

So und wenn man jetz noch länger als 200 ms simuliert sieht man auch 
was:

Nämlich hübsche Glitches auf der enable-Leitung vom LCD...

Ergo, solange die Simulation nicht ungefähr so aussieht wie die 
Diagramme im Datenblatt, braucht man gar nicht erst auf der Hardware 
anzufangen.

Duke

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


Lesenswert?

Mike schrieb:
> Habe mal den kompletten Quellcode und das Datenblatt des SRAMs mal
> hinzugefügt
Und dann ellenlange, ewige Scrollerei, statt das zu tun, was im 
Eingabefeld empfohlen wird:
1
Antwort schreiben
2
Wichtige Regeln - erst lesen, dann posten!
3
  * Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Duke Scarring schrieb:
> So und wenn man jetz noch länger als 200 ms simuliert sieht man auch
> was:
> Nämlich hübsche Glitches auf der enable-Leitung vom LCD...
Böse Sache...

Mike schrieb:
> if (reset = '0') then
>       ...
>  elsif reset = '1' then
>       ...
Was sollte reset denn sonst noch werden können ausser '0' und '1'?

Dieser reset ist 1. unnötig und hat 2. seinen Namen nicht verdient, 
weil ja sogar schreibeprozess_ende eine höhere Priorität hat...   :-o

> if wait_cnt < X"F4240" then      -- Warteschleife für 200 ms
Warum verwendest du nicht einen Integer für wait_cnt und lässt dir den 
Vergleichswert vom Synthesizer berechnen?
1
constant onems : integer := 50000; -- Anzahl Takte für 1 Millisekunde bei 50MHz (auch das könnte man ausrechnen lassen)
2
  :
3
  :
4
  if wait_cnt < (200 * onems) then 
5
     :
6
     wait_cnt <= 0;
7
  :
Und wie gesagt: nimm die numeric_std.
http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html

Und wenn dir das zu umständlich ist, dann schreib wenigstens:
1
  wait_cnt <= (others =>'0');

von Lupensucher (Gast)


Lesenswert?

Duke Scarring schrieb:
>Lupensucher schrieb:
>> Sollte
>> es wirklich ein problem mit synthesegerechten Code sei hilft dir eine
>> simu nicht weiter,
>Ja und wenn es funktionaler Fehler ist, hilft Dir der Sysnthesereport
>auch nicht weiter.
>Ich mache 99,9% funktionale Fehler. Bei Dir scheint das ja anders zu
>sein...

Was willst Du? Mit verhaltens-Simu kann mensch nicht alle Fehler 
erfassen, den hier genannten bspw. nicht. Ist auch nicht der einzige im 
Code.  Und gerade bei Anfängern ist mindestens ein Synthesefehler im 
Code. Dazu kommt meist ein weiterer im UCF. Und dann noch zwei in der 
Beschaltung.

Ich bin ja nicht gegen behavorioul Simulation, aber manche Fehler findet 
man auch durch konzentriertes Code-Review. Und  systematische 
Fehlersuche: Was sind die möglichen Fehlerquellen? welches Vorgehen ist 
bei welcher Fehlerquelle angetan? Wie erreiche ich 100% Testabdeckung? 
Wie kann ich die Simulation erweitern um auch synthesefehler zu 
erkennen. Und wenn man den fehler gefunden hat, wie und wo ändere ich 
den Code um den Fehler rauszukicken?

Merke: Simu ist täglich Brot aber kein Allheilmittel.

MfG

von Robert K. (Firma: Medizintechnik) (robident)


Lesenswert?

Duke Scarring schrieb:
>> Sorry Duke, keine Testbench vorhanden...
>
> Sehr schade. Das ist wie Autofahren ohne Airbag und ohne
>
> Sicherheitsgurt.

eher wie Fahren ohne Navi, Plan oder Routenkarte.

von Mike (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,


nach ein paar Änderungen bin ich nun weiter im Code und habe ein paar 
konkrete Fragen an euch:

1. Wenn ich meine Librarys mit der "use IEEE.NUMERIC_STD.ALL;" ersetze, 
dann bekomme  ich bei der Codezeile "wait_cnt <= wait_cnt +1;" folgende 
Fehlermeldung:

Error (10327): VHDL error at lcd_control_e_invers.vhd(101): can't 
determine definition of operator ""+"" -- found 0 possible definitions

KAnn mir das einer genauer erklären?

2.

In meinem Code habe ich 2 Schritte. Schritt 1 ist das Schreiben meines 
Arrays ins SRAM und Schritt 2 ist das Auslesen des SRAMS und das Senden 
des Inhalts an das LCD.

Ich habe nun den ersten Schritt herausgenommen d.h. ich definiere meine 
16Bit Variabel "sram_data" als IN und lese die auf dem SRAM vorhanden 
Daten aus. Mein LCD gibt nun lauter schwarzer Zeichen aus, was ja einem 
x"FF" entspricht. Ich denke nun mal, dass das Auslesen des SRAMS 
funktioniert?!

Wenn ich aber "sram_data" als "INOUT" definiere, geht es wieder nicht 
bzw. beinhaltet die Variabel "sram_data" immer noch das letzte Zeichen 
meines Arrays im Einleseprozesses in Schritt 1.


Habe nun den geänderten Sourcecode als text-datei angehängt.


*****************************
Kommentare zu den Kommentaren:

@ Pako:

Das dirkekte Auslesen des Arrays über das LCD funktioniert einwandfrei. 
Denke also nicht, dass es Timing-Probleme
beim LCD-Code gibt.

@ Duke:
Vielen Dank fürs Simulieren und das Thema Testbench muss ich auch bald 
angehen. Ansonsten wird das in Zukufkt sehr schwierig...
Zitat: Das sieht ma die ganze Zeit was am SRAM wackeln, aber nicht am 
Display.

Was genau wackelt da am SRAM? Hab da deinen Punkt nicht ganz verstanden.
Enable-Signal ist gefixt, war ein Fehler im Source-Code... Falsche 1 am 
falschen Ort..

@ Lothar:
Jep, wird in Zukuft nicht mehr gepostet.

Reset kann raus, habe ich nur beim Zusammenfügen des Codes vergessen 
herauszunehmen.

Wegen den numeric_std siehe meine Frage etwas weiter oben..

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


Lesenswert?

Mike schrieb:
>       code.txt
Und jetzt wäre es toll, wenn du statt eines *.txt Files ein *.vhdl File 
posten würdest. Von wegen Syntax-Highlighting und so....

Mike schrieb:
> 1. Wenn ich meine Librarys mit der "use IEEE.NUMERIC_STD.ALL;" ersetze,
> dann bekomme  ich bei der Codezeile "wait_cnt <= wait_cnt +1;" folgende
> Fehlermeldung:
> Error (10327): VHDL error at lcd_control_e_invers.vhd(101): can't
> determine definition of operator ""+"" -- found 0 possible definitions
1
   signal wait_cnt    : std_logic_vector(24 downto 0);
2
       :
3
       wait_cnt <= wait_cnt +1;
Der Synthesizer findet in der numeric_std keine Rechenregel zur Addition 
eines Integers (die Zahl 1) und eines std_logic_vector (wait_cnt).

> KAnn mir das einer genauer erklären?
Ja. Mit uneingeschränkten Vektoren rechnet man nicht!
In die Praxis umgesetzt: man rechnet nicht mit std_logic_vector, sondern 
mit den Datentypen unsigned, signed oder integer.

Sieh dir einfach den Link da noch mal genauer an...
Lothar Miller schrieb:
> Und wie gesagt: nimm die numeric_std.
> http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html

Zum Hintergrund:
Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

von Mike (Gast)


Angehängte Dateien:

Lesenswert?

@lothar, danke für die Erklärung...

Ich habe nun mal auch die Warnungen von Quartus zu meinem Code 
hinzugefügt. Nach ein paar Recherchen sieht es wohl aus, als wenn der 
Fehler bei der Handhabung meines INOUT Port liegt.

Vielleicht kann ja jemand über die Warnungen schauen?! Vielleicht kann 
er das Problem durch Expertise und Erfahrung schneller erkennen als 
ich...

Vielen, vielen Dank an alle hilfreichen Antworten...

LG

Mike

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


Lesenswert?

Mike schrieb:
> Nach ein paar Recherchen sieht es wohl aus, als wenn der
> Fehler bei der Handhabung meines INOUT Port liegt.
>>> Pin sram_data[0] has a permanently enabled output enable
Ja, nun, der Port wird niemals hochohmig, und kann deshalb auch niemals 
etas einlesen. Hier:
   lcd_data <= sram_data(7 downto 0);
Wird also nur genau das zurückgelesen, was irgendwann mal hier auf den 
Porttreiber geschrieben wurde:
   sram_data(7 downto 0) <=  satz1(counter_buch);
Und bestenfalls gibt es noch einen Buskonflikt, weil das FPGA den Bus 
nie freigibt (mit others => 'Z') und gleichzeitig das externe RAM auf 
den Bus losgelassen wird:
   sram_output_enable_input <= '0';

Bevor du das RAM auf den Bus lässt, musst du die Ausgangstreiber im FPGA 
abschalten. So etwa:
1
   sram_data(7 downto 0) <= deinedatenzumram when sram_output_enable_input='1' else (others=>'Z');

BTW: das hier ist sehr, sehr unglücklich
   sram_output_enable_input <= '0';
denn ein normaler Mensch denkt, irgenwas sei aktiv oder ein oder 
selektiert, wenn eine 1 da steht.

von Mike (Gast)


Lesenswert?

Genau DAS ist mein Problem. Das LCD gibt das letzte Zeichen raus, was 
ich eingelesen habe.

Das heißt, sram_data muss hochohmig sein, damit ich etwas vom Sram lesen 
kann?

Wenn du es sagst, wird das schon richtig sein, aber dennoch die Frage: 
Wie kann das Sinn machen, zumal ja über diese 8-Bit-Leitungen die Daten 
eingelesen werden sollen...

Wegen:    sram_output_enable_input <= '0';

Das heißt, ich sollte low_active_Signale besser als not definieren, um 
spätere Missverständnisse zu vermeiden?

Vielen Dank, endlich komm ich der Sache näher...

von Duke Scarring (Gast)


Lesenswert?

Mike schrieb:
> Was genau wackelt da am SRAM? Hab da deinen Punkt nicht ganz verstanden.
> Enable-Signal ist gefixt, war ein Fehler im Source-Code... Falsche 1 am
> falschen Ort..

Mike schrieb:
> Genau DAS ist mein Problem. Das LCD gibt das letzte Zeichen raus, was
> ich eingelesen habe.

Eigne Dir das Simulieren an!
Dein SRAM wird Zeichen für Zeichen ausgelesen, da ist Dein Display noch 
gar nicht mit dem Reset fertig...

Duke

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


Lesenswert?

Mike schrieb:
> Wenn du es sagst, wird das schon richtig sein
So ein wenig Fatalismus liebe ich... ;)

> Das heißt, sram_data muss hochohmig sein, damit ich etwas vom Sram lesen
> kann?
Ja. Es darf nur 1 Teilnehmer auf dem Datenbus aktiv sein. Alles andere 
nennt man Buskollision. Und Kollisionen haben schon im Volksmund nicht 
umsonst einen negativen Touch...

von Mike (Gast)


Lesenswert?

@Godfather of VDHL, eine (hoffendlich) letzte Frage habe ich zu dem 
Thema "bidirectional bus" ;-)

Ich habe diesen Code bei Altera auf der Seite gefunden, wo über 2 DFF (a 
und b) der Input-Wert und der Out-Wert als Buffer zwischen gespeichert 
werden.

Warum wird der Wert nicht direkt über "inp" oder "outp" abgegriffen, 
sondern der "Umweg" über "a" und "b"?
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.ALL;
3
4
ENTITY bidir IS
5
    PORT(
6
        bidir   : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0);
7
        oe, clk : IN STD_LOGIC;
8
        inp     : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
9
        outp    : OUT STD_LOGIC_VECTOR (7 DOWNTO 0));
10
END bidir;
11
12
ARCHITECTURE maxpld OF bidir IS
13
SIGNAL  a  : STD_LOGIC_VECTOR (7 DOWNTO 0);  -- DFF that stores 
14
                                             -- value from input.
15
SIGNAL  b  : STD_LOGIC_VECTOR (7 DOWNTO 0);  -- DFF that stores 
16
BEGIN                                        -- feedback value.
17
    PROCESS(clk)
18
    BEGIN
19
    IF clk = '1' AND clk'EVENT THEN  -- Creates the flipflops
20
        a <= inp;                    
21
        outp <= b;                  
22
        END IF;
23
    END PROCESS;    
24
    PROCESS (oe, bidir)          -- Behavioral representation 
25
        BEGIN                    -- of tri-states.
26
        IF( oe = '0') THEN
27
            bidir <= "ZZZZZZZZ";
28
            b <= bidir;
29
        ELSE
30
            bidir <= a; 
31
            b <= bidir;
32
        END IF;
33
    END PROCESS;
34
END maxpld;

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.