Hallo,
ich möchte einen "Umsetzer" erstellen, der serielle Daten in ein SRAM
schreibt. Der Baustein EPM3032 ist vorgegeben.
Die seriellen Daten kommen via SPI - ich habe also eine Takt- und eine
Datenleitung.
Die seriellen Daten laufen in ein Schieberegister und über einen Zähler
wollte ich den Trigger für "Byte voll" generieren. Zwischen
Schieberegister und Ausgabepins wollte ich noch ein Latch platzieren,
damit die Daten während der 8 Takte stabil sind.
Allerdings wollte ich auch die Speicheradresse "automatisch" hochzählen
lassen.
Jetzt komme ich aber nicht mit der Kombinatorik des Zählers klar. Den
Takt durch 8 teilen ist ja kein Problem. Allerdings wollte ich mit dem
8tel Takt auch das Latch steuern und den Schreibvorgang initialisieren.
Hierzu müsste ich den 8tel Takt wieder unterteilen. Allerdings soll
gewährleistet sein, dass das Latch vor dem Schreibvorgang speichert und
dass der Schreibvorgang nur einmal pro 8tel Takt angestoßen wird.
Mir geht es nicht um irgendeine Sprache, sondern um die Logikbausteine,
die ich im Composer kombinieren kann.
Gibt es z.B. Module, mit denen ich 2 gleiche Flanken erkennen kann (z.B.
ein AND, das auf Flanke und nicht auf Level reagiert)?
Für Nachsicht, bzw. Anfängergerechte Tips wäre ich sehr dankbar.
> Die seriellen Daten kommen via SPI - ich habe also eine Takt- und eine> Datenleitung.
Und eine Slave-Select-Leitung. Erst dann ist es so richtig SPI.
> über einen Zähler wollte ich den Trigger für "Byte voll" generieren.
du könntest aber auch den Slave-Select nehmen... :-/
Irgendeine Art der Synchronisierung wirst du brauchen, denn eine einzige
falsch erkannte Takt-Flanke zerlegt dir sonst dein ganzes Protokoll.
> Allerdings wollte ich auch die Speicheradresse "automatisch" hochzählen> lassen.
Da gibt es einige Möglichkeiten:
1) Lass doch einfach mit jedem Bit einen Zähler um 1 hochzählen,
und nimm erst ab dem 3. Bit die Adresse.
2) zähl die Adresse mit der steigenden Flanke vom SS hoch.
> Hierzu müsste ich den 8tel Takt wieder unterteilen. Allerdings soll> gewährleistet sein, dass das Latch vor dem Schreibvorgang speichert und> dass der Schreibvorgang nur einmal pro 8tel Takt angestoßen wird.
Nimm deinen Bit-Zähler (den du sowieso ab Bit 3 als Adresse verwendest)
und decodier die unteren 8 Zählerstände aus:
wenn 0: Daten speichern
wenn 1: Adressen un Daten an SRAM ausgeben
wenn 2: wr am Ram aktivieren
wenn 3: wr deaktivieren
usw. usf...
> Gibt es z.B. Module, mit denen ich 2 gleiche Flanken erkennen kann> (z.B. ein AND, das auf Flanke und nicht auf Level reagiert)?
Du willst behaupten, dass du zwei zeitgleiche Flanken hinbekommst?
Ein Flanken-AND wäre ja nur dann eines, wenn es nur (und nur dann)
reagiert, wenn gleichzeitig zwei Flanken (die per Definition die
Zeitdauer 0 brauchen) auftreten würden.
Du wirst solche Flanken nicht generieren können (und auch sonst
niemand), und deshalb wird es ein solches Bauteil nicht geben.
Hallo Lothar,
danke für Deine Antwort!
Slave-Select - klar gehört die zu SPI. Die wollte ich auf einen Pin
legen, der dann als enable für alle internen Logik-Elemente dient.
>> über einen Zähler wollte ich den Trigger für "Byte voll" generieren.> du könntest aber auch den Slave-Select nehmen... :-/
Nee, ich möchte von außen keine weiteren Signale haben - dann hätte ich
ja wieder ein Synchronisationsproblem.
Weiß ja nicht, ob mein Vorhaben umgesetzt werden kann - der serielle
Datenstrom kommt von einem Sensor und soll in einen Speicher mit
parallelem Interface geschrieben werden.
Also quasi auf Tastendruck wird die Protokollierung gestartet und endet
wenn Speicher voll ist.
>> Allerdings wollte ich auch die Speicheradresse "automatisch" hochzählen>> lassen.> Da gibt es einige Möglichkeiten:> 1) Lass doch einfach mit jedem Bit einen Zähler um 1 hochzählen,> und nimm erst ab dem 3. Bit die Adresse.> 2) zähl die Adresse mit der steigenden Flanke vom SS hoch.
Hm - weiß jetzt nicht, wie ich das 3. Bit erkennen soll. SS kann und
will ich nicht verwenden, da es ja bereits für den Baustein verwendet
wird.
>> Gibt es z.B. Module, mit denen ich 2 gleiche Flanken erkennen kann>> (z.B. ein AND, das auf Flanke und nicht auf Level reagiert)?> Du willst behaupten, dass du zwei zeitgleiche Flanken hinbekommst?
Ich will garnix behaupten!
Nur wenn ich mir den Datenstrom anschaue, der mir zur Verfügung steht,
...
Mir ist noch nicht (ganz) klar, wie ich alleine über den SPI-Takt die
ganze Logik steuern kann.
Wie gesagt, ich wollte den Clock von SPI als Clock für die Logik nehmen.
Wenn ich dann eine Möglichkeit hätte, den Flankenwechsel von 2
Ausgangspins eines Zählers zu vergleichen, also z.B. wenn O0 und O2
"gleichzeitig" eine fallende Flanke haben, dann hätte ich den Trigger
für's Latch und alle Ram-Operationen.
Das "gleichzeitig" könnte ja auch eine Zeiteinheit kleiner dem SPI-Takt
sein.
Wie sieht das denn aus, wenn ich einen EPM3032 mit 4ns habe, ist dann
die kleinste Zeiteinheit 4ns oder könnte ich "gleichzeitig" auch als
innerhalb von 2ns festlegen?
Wenn alle Logik-Elemente des CPLD mit dem gleichen Takt gesteuert
werden, in wie weit kann man dann von einer Gleichzeitigkeit der Flanken
ausgehen?
> der serielle Datenstrom kommt von einem Sensor
Der Sensor sendet also dauernd?
Wie markiert der Anfang und Ende eines Datenworts?
Wer ist Master, wer ist Slave?
Und wie spielt da der SlaveSelect mit?
> Mir ist noch nicht (ganz) klar, wie ich alleine über den SPI-Takt die> ganze Logik steuern kann.
Genau das wird schwierig, denn wenn die SPI-Übertragung fertig ist, gibt
es keinen Takt mehr. Und erst dann kannst du eigentlich loslegen und in
den Speicher schreiben. Das ist aber schwierig, so ganz ohne Takt... :-/
Meine Idee war daher, die Statemachine, die das Datenwort in den
Speicher schreibt, mit dem nächsten eingehenden Datenbyte
durchzuschalten.
Also nehme ich einen Binär-Zähler, der mit jedem eintreffenden Bit um
eins hochgezählt wird. Dann kannst du mit den untern 3 Bit die
Statemachine durchschlten, die darüber sind dann deine Adresse:
Addr State
0000 000 --> 1.Bit
0000 001
0000 010
0000 011
0000 100
0000 101
0000 110
0000 111 --> 8.Bit, das Byte ist komplett.
0001 000 --> 9. Bit = 1.Bit vom nächsten Datenbyte
0001 001
0001 010
0001 011
0001 100
0001 101
0001 110
0001 111 --> 8.Bit, das Byte ist komplett.
0010 000 --> 1.Bit
0010 001
0010 010
0010 011
0010 100
0010 101
0010 110
0010 111 --> 8.Bit, das Byte ist komplett.
0011 000 --> 1.Bit
0011 001
:
:
Aber wie gesagt: da sind noch einige Fragen offen
(siehe Anfang dieses Posts ;-)
>> der serielle Datenstrom kommt von einem Sensor> Der Sensor sendet also dauernd?> Wie markiert der Anfang und Ende eines Datenworts?> Wer ist Master, wer ist Slave?> Und wie spielt da der SlaveSelect mit?
Hm, das sind Fragen, die ich außerhalb des CPLD zu lösen gedenke.
Das CPLD soll auf jeden Fall ein Slave sein, der mit SS aktiviert wird.
Dementsprechend geht die Übertragung mit SS los, also Takt und Daten.
Die Datenworte sind nicht markiert, es ist ein Bitstrom ohne Framedaten.
Es gibt zwar Frameinformationen, die liegen aber auf einer separaten
Leitung und betragen mehrere Bytes. Die Information hilft mir beim CPLD
nicht wirklich weiter.
> Genau das wird schwierig, denn wenn die SPI-Übertragung fertig ist, gibt> es keinen Takt mehr. Und erst dann kannst du eigentlich loslegen und in> den Speicher schreiben. Das ist aber schwierig, so ganz ohne Takt... :-/
Genau. Deshalb muss es gleich losgehen. Um bei dem Speicher auch
langsamere Modelle verwenden zu können, dachte ich, ich beschreibe den
Speicher unabhängig vom SPI-Takt und habe dann (theoretisch) 8 SPI-Takte
Zeit, um ein Byte zu schreiben.
> Also nehme ich einen Binär-Zähler
Ich habe mich bisher am Timing-Diagram des 74HC4040 orientiert.
Der Zähler schaltet jeweils bei der fallenden Taktflanke, d.h. das 8te
Bit ist verfügbar, wenn der Zähler wieder den Wert 0 hat.
Deshalb wollte ich die Flankenerkennung verwenden. Aber ok, Deine
Ausführung hat mich drauf gebracht, ich könnte ja auch ein 3fach Nand
nehmen und die Leitungen mit Vcc initialisieren. Dann müsste es auch
klappen.
Danke auf jeden Fall für Deine Unterstützung!
> und habe dann (theoretisch) 8 SPI-Takte Zeit, um ein Byte zu schreiben.
Ja, schon, aber du hast nichts, das dir die Zeit innerhalb der 8 Takte
verwaltet. Zeichne dir mal ein Timing-Diragramm mit den eingehenden und
zu schreibenden Daten mit den zum Schreiben nötigen Steuersignalen
auf, dann siehst du, was ich meine:
Es reicht nicht aus, 9 Takte Zeit zu haben, man muß sie auch nutzen
können. Und dazu brauchst du einen Takt. Das ist das einzige
Zeitelement, das du in Programmierbaren Bausteinen hast.
Ich wuerd den guenstigsten Controller nehmen, zB ein Mega8, der bietet
mehr Flexibilitaet wie ein 32 Flip-flop CPLD und ist guenstiger. Falls
im Laufe der Inbetriebnahme noch eine Aenderung kommt, die ploetzlich
ein 33. Flipflop erfordern wuerde, so kannste alles in die Tonne
druecken.
Ein Vorteil des CPLD, die nahezu unbegrenzte Geschwindigkeit scheint
hier eh nicht gebraucht zu werden.
> Ich wuerd den guenstigsten Controller nehmen, zB ein Mega8, der bietet> mehr Flexibilitaet wie ein 32 Flip-flop CPLD und ist guenstiger.
Wenn es gehen würde, würde ich das auch tun. Da hätte ich zumindest
keine Verständnisprobleme und der mega hat Pinchange-Interrupts, die auf
Flanken reagieren :)
Aber zum einen hat der mega8 oder auch mega88 nicht die Pin-Anzahl und
zum Anderen liegt die Bitrate bei ca. 10 MBit/s (evtl. sogar drüber),
das packt der mega8 (ungepimpt) eher nicht.
XMega ist auch Neuland für mich, sodass ich denke, dass der gewählte
Baustein adäquat wäre. Wie gesagt - CPLD ist absolutes Neuland für mich
- freiwillig würde ich mir das nicht geben.
hmm... schrieb:
> Dann nimm den 3064, der hat dann noch was an Reserve
Das Design passt jetzt sowieso nicht mehr in 32 FFs:
20 Bit Adresszähler
3 Bit Zustandsautomat
8 Bit Schieberegister
8 Bit Latch
sind 39 Speicherglieder.
Hallo Lothar,
was meinst Du zum Design?
Könnte man noch was eindampfen, um auf die 32 Zellen zu kommen, oder
muss ich den nächst größeren (3064) nehmen?
Mal abgesehen vom Chip - wenn's reinpassen würde, könnte das Design so
passen, oder sind noch andere Schnitzer drin?
Anfänger schrieb:
> So, habe es mal gemalt.>> Könnte es so wie im Anhang funktionieren?
lpm_counter0, guck dir dein clk_enable und clock an, die sind
kurzgeschlossen irgendwie :)
Das passiert wenn du etwas verscheibst im Quartus, immer danach gucken
ob design sich nciht geändert hat - Quartus neigt dazu.
Hallo Thomas,
> lpm_counter0, guck dir dein clk_enable und clock an, die sind> kurzgeschlossen irgendwie :)> Das passiert wenn du etwas verscheibst im Quartus, immer danach gucken> ob design sich nciht geändert hat - Quartus neigt dazu.
Danke für die Hinweise!
Als ich schrieb, dass er übersetzt hat, hieß das leider nur, dass er
keine Fehler hatte, die zum Abbruch führten. Als ich mich dann mit den
Warnungen beschäftigte, merkte ich, dass es garnicht funzen kann - er
hatte schlicht die Hälfte wegoptimiert (wegen Fehler von mir).
Bin jetzt auf den 3064 gegangen, weil Lothar natürlich Recht hat, dass
es nicht rein passt. Bin aktuell bei 40 Zellen, aber die Warnungen
bekomme ich nicht weg.
Könntet Ihr mir nochmal bitte unter die Arme greifen?
Das NOR-Gatter im Takt-pfad scheint ihm nicht zu gefallen. Gibt es eine
Möglichkeit, dass mit anderen Bausteinen zu realisieren, die auf Clock
reagieren?
Ich hänge mal den aktuellen Plan und die Warnungen an.
> Das NOR-Gatter im Takt-pfad scheint ihm nicht zu gefallen.
Einen Takt sollte man nicht aus/über Kombinatorik generieren.
Deine NOR-Gatter fragen den Zustand 000 des unteren Zählers ab. Was
könnte passieren, wenn der jetzt z.B. von 001 nach 010 zählt, und das
LSB am schnellsten umkippt? Dann ist die Folge z.B. so 001 -> 000 -> 010
Die 000 ist zwar nur ein paar ps da, trotzdem gilt:
Hurra, ein Glitch im Takt :-/
Warum machst du nicht einfach aus dem lpm_counter0 und lpm_counter1
einen einzigen lpm_counter?
> Warum machst du nicht einfach aus dem lpm_counter0 und lpm_counter1> einen einzigen lpm_counter?
Woher soll ein dummer Mensch denn wissen, dass das geht?
Ich hangel mich von einem Problem zum nächsten und hoffe, dass ich
unterwegs nix übersehe ...
> Woher soll ein dummer Mensch denn wissen, dass das geht?
Du hast doch schonmal einen 3-Bit Counter hinbekommen und einen 20-Bit
Counter. Da wirst du doch auch einen 23-Bit Counter hinbekommen? :-o
Und dann gibst du die Bits 0-2 auf dein NOR, und die Bits 4-22 auf das
RAM.
>> Woher soll ein dummer Mensch denn wissen, dass das geht?> Du hast doch schonmal einen 3-Bit Counter hinbekommen und einen 20-Bit> Counter. Da wirst du doch auch einen 23-Bit Counter hinbekommen? :-o>> Und dann gibst du die Bits 0-2 auf dein NOR, und die Bits 4-22 auf das> RAM.lach - wenn man weiß wie, ist alles einfach :D
Danke Dir!
Was ist denn mit den restlichen Warnungen?
Bedeuten die, dass die Schaltung mit dem Chip nicht funktioniert, oder
was kann ich tun, um die zu eliminieren?
> Was ist denn mit den restlichen Warnungen?
Ein Latch ist per Definition eine kombinatorische Schleife. Diese
Warnungen kannst du ignorieren.
Das mit dem Reset kannst du auch ignorieren, SCK ist bereits synchron.
Und das mit dem Gated Clock sollte jetzt ja sowieso weg sein.
> Bedeuten die, dass die Schaltung mit dem Chip nicht funktioniert
Die Schaltung wird genau das machen, was du hingemalt hast. Ob das
allerdings auch das ist, was du willst/brauchst, das können dir die
Design-Tools nicht sagen... :-/
Hallo Lothar,
danke für Deine Unterstützung!
> Die Schaltung wird genau das machen, was du hingemalt hast. Ob das> allerdings auch das ist, was du willst/brauchst, das können dir die> Design-Tools nicht sagen... :-/
Yepp - so ist das mit computer-unterstützung. Denken und Können können
die nicht abnehmen.
Deiner Formulierung habe ich entnommen, dass ich nen Stuss hingepinselt
habe - und deshalb nochmals genauer hingeschaut.
Einen Fehler denke ich gefunden zu haben. Wenn ich den Zähler mit 111...
initialisiere ist nach dem ersten Takt der Zählerstand 0 und nicht 1 -
dementsprechend müsste ich das NOR gegen ein AND tauschen.
Was ich jetzt nicht weiß:
- ob bei den Adressen A0 LSB entspricht (nicht theoretisch, sonder
praktisch)
- ob bei den Daten D0 LSB entspricht (nicht theoretisch, sonder
praktisch)
- ob das erste Bit, das ins Schieberegister reinläuft bei Data_0 landet
Dann gefällt mir die Latch-Ansteuerung noch nicht. Soweit ich verstanden
habe reagieren alle getakteten Logikbausteine auf die steigende Flanke.
Dementsprechend würde ich das Latch gerne auf der fallenden Flanke
aktivieren, bevor das erste neue Bit im Schieberegister angekommen ist.
Da das Latch über ein Logik-Gatter angesteuert wird, schaltet es auf
jeden Fall später, als das Schieberegister.
Hier weiß ich jetzt nicht, welche Möglichkeiten es gibt, das in den
Griff zu bekommen.
Was das restliche Zeitverhalten betrifft, schreibe ich im nächsten Post.
Mit dem Protokoll-Umsetzer möchte ich mehrere SRAM vom Typ IDT71V124SA
beschreiben. Dieser Baustein braucht 17 Adressleitungen.
Ist es richtig, wenn ich die 17 Adressleitungen als Bus an alle
Speicherbausteine führe und die weiteren Adressleitungen für das
Schalten vom Chipselect verwende (die erste Adressleitung mit externem
NOT für 2 Speicherbausteine verwendet)?
Laut Datenblatt sind Adress-Setup-Time (tAS), Write-Recovery-Time (tWR)
und Data-Hold-Time (tDH) jeweils 0.
Dem entnahm ich, dass die einzige Zeit, die ich beachten muss, die
Data-Valid-to-End-of-Write (tDW) ist.
Dementsprechend sollte !WE! einen Clock-Zyklus high sein, ansonsten low.
Der Pegelwechsel von !WE! sollte synchron mit Adress- und Datenwechsel
sein.
Falls die Überlegungen falsch sind, bzw. nicht mit der entworfenen Logik
realisiert werden, bitte ich um entsprechende Hinweise.
Hallo Dirk,
danke für das Zauberwort - allerdings muss ich gestehen, dass ich keinen
Ansatz gefunden habe, wie mich das Zauberwort bei meinem Problem weiter
bringen könnte.
In der Quartus Hilfe gibt es keinen Treffer für das Zauberwort.
Tante Kugel meinte was von versetzter Logic - allerdings ist mein
Eingangs-Bitstrom gegeben - auf den habe ich keinen Einfluss.
Wolltest Du mir mit dem Zauberwort durch die Blume sagen, dass ich das
Problem per Designer nicht gelöst bekomme?
... dass ich doch alles von Hand schreiben muss?
Wäre für ausführlichere Anleitung bzw. Hinweise sehr verbunden.
> dass ich das Problem per Designer nicht gelöst bekomme?> ... dass ich doch alles von Hand schreiben muss?
Du kannst (fast) jede Schaltung auf die eine oder die andere Art
beschreiben. Nur die Syntaxelemente sind andere (mal Bilder, mal Texte).
BTW:
> ... dass ich doch alles von Hand schreiben muss?
Das geht schneller, ist kompakter, lässt sich besser simulieren und
einfacher archivieren und ist protierbar. Warum also nicht?
Hier mal meine textuelle VHDL-Beschreibung deines Schaltplans:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.NUMERIC_STD.ALL;
4
5
entityserparis
6
Port(cs:inSTD_LOGIC;
7
sclk:inSTD_LOGIC;
8
sdata:inSTD_LOGIC;
9
nwe:outSTD_LOGIC;
10
data:outSTD_LOGIC_VECTOR(7downto0);
11
addr:outSTD_LOGIC_VECTOR(18downto0));
12
endserpar;
13
14
architectureBehavioralofserparis
15
signallpm_cnt:STD_LOGIC_VECTOR(21downto0);
16
signallpm_sr:STD_LOGIC_VECTOR(7downto0);
17
signaldo:STD_LOGIC_VECTOR(7downto0);
18
begin
19
-- der Zähler
20
process(sclk,cs)begin
21
if(cs='0')then
22
lpm_cnt<=(others=>'0');
23
elsifrising_edge(sclk)then
24
if(cs='1')then
25
lpm_cnt<=std_logic_vector(unsigned(lpm_cnt)+1);
26
endif;
27
endif;
28
endprocess;
29
30
-- das Schieberegister
31
process(sclk)begin
32
ifrising_edge(sclk)then
33
if(cs='1')then
34
lpm_sr<=lpm_sr(6downto0)&sdata;
35
endif;
36
endif;
37
endprocess;
38
39
-- ein Latch
40
do<="00000000"whencs='0'else
41
lpm_srwhenlpm_cnt(2downto0)="111"else
42
do;
43
44
-- ein wenig Kombinatorik
45
nwe<='1'whenlpm_cnt(2downto0)="111"else'0';
46
addr<=lpm_cnt(21downto3);
47
data<=do;
48
49
endBehavioral;
Der generierte RTL-Schaltplan ist (abgesehen von unnötigen
Invertierungen) genau gleich wie deiner :-o
Zeitaufwand <10 Minuten (incl. Anlegen eines neuen Projekts bei Xilinx)
BTW: mit etwas Übung sieht man dann auch gleich noch eine eklatante
Designschwäche ;-)
(das Latch wird über Kombinatorik geladen, auch da kann es Glitches
geben)
Hallo Lothar,
ich danke Dir für Deine ausführliche Antwort!
Nimm's mir bitte nicht krumm, aber Deine Antwort ist ungefär so, als
hättest Du mir einen Satz auf chinesisch geschrieben und gesagt, der
würde einen Fehler enthalten, bei dem sich jeder Chinese vor Lachen in
die Hose macht.
Ich kann weder chinesisch, noch VHDL oder sonst eine
HW-Beschreibungssprache.
Das Schaltungsproblem hatte ich ursprünglich mit Gattern der 74*er Reihe
aufgebaut und erhielt dann von einem Kumpel den Tip, dass dies ein
typischer Anwendungsfall für ein CPLD wäre und er schenkte mir ein paar
EPM3032 aus einer Überlieferung, deshalb auch meine Einschränkung auf
die Bausteine. Wenn sich jetzt herausstellen sollte, dass es mit denen
nicht geht, ist das auch kein Beinbruch ;)
SW installieren und ausprobieren - ok. Die Symbole im Grafik-Designer
sind ja ähnlich, wie die in den Datenblättern der 74er Reihe.
Damit war mein Wissen bereits am Ende. Welche Bausteine man wie
optimieren, bzw. kombinieren oder weglassen kann ...
Sorry, aber ich bin ja noch nicht mal sicher, dass das Teil das macht,
was ich vorhabe.
Ein weiser Mann meinte mal: first make it work, then optimise :)
Deine VHDL-Variante ist eine Super-Vorlage, um mich in die Sprache, bzw.
Thematik einzuarbeiten. Aber die Designschwäche zu erkennen, wenn Du sie
mir nicht um die Ohren haust, dazu bin ich noch nicht in der Lage.
Was den Zeitaufwand von < 10 min anbelangt: in der Zeit habe ich
vielleicht den download-Link zur Software bei Altera gefunden.
Installieren, ausprobieren, Hilfe lesen, Details der Elemente einlesen -
da gingen locker einige Tage/Wochen ins Land (das war, bevor ich diesen
Thread startete). Dann muss ich auch gestehen, dass ich zwar vieles
gelesen, aber mit Sicherheit nicht alles verstanden habe.
Wie gesagt, es ist mein erster Kontakt mit CPLD und der Thematik
überhaupt. Deshalb war der Designer das einzig mögliche Instrument ...
Aber klar, wenn ich schon auf VHDL-Niveau abtauche, dann kann ich auch
beide Flanken des seriellen Taktes abfragen.
> wenn ich schon auf VHDL-Niveau abtauche,
"Aufsteige" heißt das ;-)
> dann kann ich auch beide Flanken des seriellen Taktes abfragen.
Da bin ich mir jetzt noch nicht so ganz sicher...
Du kannst wie gesagt alles in VHDL oder als Schaltplan beschreiben. Zur
Auswertung der steigenden und der fallenden Flanke wirst du kein
Bauteil finden (bestenfalls an den IO-Port als DDR-Interface).
> Ein weiser Mann meinte mal: first make it work, then optimise :)
Das wäre auch mein Tipp. Einfach mal implementieren, und schauen, was
dabei rauskommt. Du kannst Fehler ja wieder "rausprogrammieren" ;-)
Hallo Lothar,
> Das wäre auch mein Tipp. Einfach mal implementieren, und schauen, was> dabei rauskommt. Du kannst Fehler ja wieder "rausprogrammieren" ;-)
Nach Deiner Steilvorlage in VHDL hat mich natürlich der Ehrgeiz gepackt,
wenigstens Deine Zeilen zu verstehen lernen. Bin also schon VHDL
Einführungen am lesen ...
>> dann kann ich auch beide Flanken des seriellen Taktes abfragen.> Da bin ich mir jetzt noch nicht so ganz sicher...> Du kannst wie gesagt alles in VHDL oder als Schaltplan beschreiben. Zur> Auswertung der steigenden und der fallenden Flanke wirst du kein> Bauteil finden (bestenfalls an den IO-Port als DDR-Interface).
Muss ja nicht ein Bauteil sein. Ich habe nur den Anspruch, verstehen zu
wollen, was ich tue und ebenso die Kombinationsmöglichkeiten verstanden
zu haben ;)
Hallo Lothar,
habe inzwischen gelesen, dass nach dem Logikgatter noch ein FF mit
CE-Steuerung fehlt, um das Latch taktrichtig zu steuern.
(könnte das nicht auf fallende Flanke reagieren?)
Den Zähler und die Ansteuerung des Gatters habe ich noch nicht
geschluckt.
Entweder ist sitze auf der Leitung, oder es gibt Seiteneffekte, die mir
noch verborgen sind.
Du fängst mit dem Zähler bei 0 an und hast trotzdem ein AND3 nach dem
Zähler. Nach meinem Verständnis sind bei einem Zählerstand von 111
(binär) erst 7 Bit im Schieberegister gelandet. Wenn jetzt das Latch
anzieht, fehlt ein Bit.
Sehe ich das falsch, oder ist das Gatter so langsam, dass man es schon
einen Takt vorher ansteuern muss/soll?
> dass nach dem Logikgatter noch ein FF mit> CE-Steuerung fehlt, um das Latch taktrichtig zu steuern.
Richtig: Es muß ein Register zwischen der Logik und dem Latch sein.
> Wenn jetzt das Latch anzieht, fehlt ein Bit.
Das mag sein...
Ich habe das jetzt natürlich noch nicht simuliert.
Aber der Vorteil von programmierbarer Logik ist, dass sie jederzeit eine
andere Funktion ausführen kann. Wenn der Zähler anders initialisiert
werden muß, dann ist das ohne Probleme möglich, ich setze einfach den
Initialwert anders.
Hallo Lothar,
irgendwie komme ich nicht zurecht.
Habe mir das (hier) empfohlene Simili installiert und ein Projekt mit
Deiner VHDL-Vorlage erstellt.
Die Datei lässt sich zwar übersetzen, aber in der Simulation kommt nur
der Initialzustand. Wo kann ich denn Eingangsdaten eingeben, um die zu
simulieren?
Du hast in Deinem obigen Post geschrieben, dass man sich das Bild auf
dem VHDL auch generieren lassen kann. Welche SW braucht man dazu, bzw.
welche (freien) Werkzeuge könntest Du empfehlen?
> Du hast in Deinem obigen Post geschrieben, dass man sich das Bild auf> dem VHDL auch generieren lassen kann.
Das ist ein RTL-Schaltplan (Register-Transfer-Level). Den kann
eigentlich jede Toolchain ausspucken.
> Welche SW braucht man dazu, bzw. welche (freien) Werkzeuge> könntest Du empfehlen?
Ich arbeite mit Xilinx, für Lattice gibts auch was.
Und für Altera sollte es auch eine freie Edidtion vom Quartus geben.
> Wo kann ich denn Eingangsdaten eingeben, um die zu simulieren?
Jetzt kommt der Trick:
Du mußt eine VHDL-Beschreibung (aka. Testbench) erstellen, die deine zu
simulierende Schaltung als Komponente beinhaltet. Und dann kannst du in
dieser Testbench an den Eingangspins deiner Schaltung herumwackeln.
Eine Testbench ist leicht zu erkennen: sie hat keine Ports nach aussen.
1
LIBRARYieee;
2
USEieee.std_logic_1164.ALL;
3
USEieee.numeric_std.ALL;
4
5
ENTITYtestbenchIS
6
-- keine Ports
7
ENDtestbench;
8
9
ARCHITECTUREbehaviorOFtestbenchIS
10
11
COMPONENTserpar-- deine Schaltung als Komponente bekanntmachen
12
Port(cs:inSTD_LOGIC;
13
sclk:inSTD_LOGIC;
14
sdata:inSTD_LOGIC;
15
nwe:outSTD_LOGIC;
16
data:outSTD_LOGIC_VECTOR(7downto0);
17
addr:outSTD_LOGIC_VECTOR(18downto0)
18
);
19
ENDCOMPONENT;
20
21
-- Signale zur Verdrahtung
22
-- Inputs
23
SIGNALcs:std_logic:='0';
24
SIGNALsclk:std_logic:='0';
25
SIGNALsdata:std_logic:='0';
26
27
-- Outputs
28
SIGNALdata:std_logic_vector(7downto0);
29
SIGNALaddr:std_logic_vector(18downto0);
30
SIGNALnwe:std_logic;
31
32
BEGIN
33
34
-- deine Schaltung anschliessen
35
uut:serparPORTMAP(
36
cs=>cs,
37
:
38
new=>nwe);
39
40
-- Simulations-Signale erzeugen, hier beginnt deine Arbeit...
Hallo,
habe mir inzwischen die 6er Version der Xilinx-ISE installiert.
Jetzt ließen sich Deine Beispiele übersetzen und ich bekam auch ein
RTL-Diagram - soweit so gut.
Den Weg, die Testbench auszuführen habe ich allerdings noch nicht
gefunden.
... und wie kann ich mir so Timings ala Logik-Analysator anzeigen, bzw.
erzeugen lassen?
Anfänger schrieb:
> Das Schaltungsproblem hatte ich ursprünglich mit Gattern der 74*er Reihe> aufgebaut und erhielt dann von einem Kumpel den Tip, dass dies ein> typischer Anwendungsfall für ein CPLD wäre und er schenkte mir ein paar> EPM3032 aus einer Überlieferung, deshalb auch meine Einschränkung auf> die Bausteine
Hmm, das was Lothar Miller mit dir macht ist natürlich viel besser als
das was cih vorschlagen werde. Ich finde sein weg besser, es macht IMMER
mehr sinn zu lernen wie man einen feuer macht anstatt zu lernen wo man
feuer findet ( irgendwie ging der satz, oder ? )
Wenn dein seriell-parallel umsetzer als 74'er logik funktioniert hat,
dann nimmt Altera Quartus, mach neues design, neues block
diagram/schematic file, und baue es genau wie du mit dem 74'er geamcht
hast ( die sind im Symbol tool - others - maxplus 2 library ).
So wirst du zwar nciht wirklich lernen, hilft dir aber vielleicht.
Wenn funktioniert, kannst du dann falls du VHDL lernen möchtest die
74'34 in deinem design durch generic funktionen ersetzen, dann geht auch
die generic ins VHDL zu wandeln ( mit einem klick :P ) ... so wirst du
einzelne 'teile' besser verstehen können.