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.
Mike schrieb:> funktioniert es leider nicht mehrMike 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.
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.
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
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.
ifschreibeprozess_ende='0'then-- Beginn des Scheibeprozesses auf das SRAM
82
83
ifcounter_buch<28then
84
85
casestate_ramis
86
87
whenSET_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(7downto0)<=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(15downto8)<=leerzeichen(7downto0);
100
sram_lower_byte<='1';
101
sram_upper_byte<='1';
102
103
104
ifwait_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
endif;
114
115
116
whenSET_DATA=>
117
118
sram_write_enable_input<='0';
119
sram_lower_byte<='0';
120
sram_upper_byte<='0';
121
122
ifwait_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
endif;
131
132
endcase;
133
134
else
135
136
--- Beginn des Ausleseprozesses und weiterleitung der Daten an das LCD...
@ 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...
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"?
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...
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
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,
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
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.
>> 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
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.
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.
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....
Mike schrieb:> USE IEEE.STD_LOGIC_ARITH.all;> USE IEEE.STD_LOGIC_UNSIGNED.all;
Erstmal ersetzt man die Libs mit der folgenden:
1
useIEEE.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
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
constantonems:integer:=50000;-- Anzahl Takte für 1 Millisekunde bei 50MHz (auch das könnte man ausrechnen lassen)
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
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.
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..
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
signalwait_cnt:std_logic_vector(24downto0);
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"
@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
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:
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.
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...
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
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...
@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
LIBRARYieee;
2
USEieee.std_logic_1164.ALL;
3
4
ENTITYbidirIS
5
PORT(
6
bidir:INOUTSTD_LOGIC_VECTOR(7DOWNTO0);
7
oe,clk:INSTD_LOGIC;
8
inp:INSTD_LOGIC_VECTOR(7DOWNTO0);
9
outp:OUTSTD_LOGIC_VECTOR(7DOWNTO0));
10
ENDbidir;
11
12
ARCHITECTUREmaxpldOFbidirIS
13
SIGNALa:STD_LOGIC_VECTOR(7DOWNTO0);-- DFF that stores
14
-- value from input.
15
SIGNALb:STD_LOGIC_VECTOR(7DOWNTO0);-- DFF that stores