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.
So, habe es mal gemalt. Könnte es so wie im Anhang funktionieren?
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?
Ok, habe es jetzt mit 18 Adressleitungen übersetzt bekommen. Danke für Eure Unterstützung.
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 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity serpar is |
6 | Port ( cs : in STD_LOGIC; |
7 | sclk : in STD_LOGIC; |
8 | sdata : in STD_LOGIC; |
9 | nwe : out STD_LOGIC; |
10 | data : out STD_LOGIC_VECTOR (7 downto 0); |
11 | addr : out STD_LOGIC_VECTOR (18 downto 0)); |
12 | end serpar; |
13 | |
14 | architecture Behavioral of serpar is |
15 | signal lpm_cnt : STD_LOGIC_VECTOR (21 downto 0); |
16 | signal lpm_sr : STD_LOGIC_VECTOR (7 downto 0); |
17 | signal do : STD_LOGIC_VECTOR (7 downto 0); |
18 | begin
|
19 | -- der Zähler
|
20 | process (sclk,cs) begin |
21 | if (cs = '0') then |
22 | lpm_cnt <= (others=>'0'); |
23 | elsif rising_edge(sclk) then |
24 | if (cs='1') then |
25 | lpm_cnt <= std_logic_vector(unsigned(lpm_cnt) + 1); |
26 | end if; |
27 | end if; |
28 | end process; |
29 | |
30 | -- das Schieberegister
|
31 | process (sclk) begin |
32 | if rising_edge(sclk) then |
33 | if (cs='1') then |
34 | lpm_sr <= lpm_sr(6 downto 0) & sdata; |
35 | end if; |
36 | end if; |
37 | end process; |
38 | |
39 | -- ein Latch
|
40 | do <= "00000000" when cs = '0' else |
41 | lpm_sr when lpm_cnt(2 downto 0) = "111" else |
42 | do; |
43 | |
44 | -- ein wenig Kombinatorik
|
45 | nwe <= '1' when lpm_cnt(2 downto 0) = "111" else '0'; |
46 | addr <= lpm_cnt(21 downto 3); |
47 | data <= do; |
48 | |
49 | end Behavioral; |
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 | LIBRARY ieee; |
2 | USE ieee.std_logic_1164.ALL; |
3 | USE ieee.numeric_std.ALL; |
4 | |
5 | ENTITY testbench IS |
6 | -- keine Ports
|
7 | END testbench; |
8 | |
9 | ARCHITECTURE behavior OF testbench IS |
10 | |
11 | COMPONENT serpar -- deine Schaltung als Komponente bekanntmachen |
12 | Port ( cs : in STD_LOGIC; |
13 | sclk : in STD_LOGIC; |
14 | sdata : in STD_LOGIC; |
15 | nwe : out STD_LOGIC; |
16 | data : out STD_LOGIC_VECTOR (7 downto 0); |
17 | addr : out STD_LOGIC_VECTOR (18 downto 0) |
18 | );
|
19 | END COMPONENT; |
20 | |
21 | -- Signale zur Verdrahtung
|
22 | -- Inputs
|
23 | SIGNAL cs : std_logic := '0'; |
24 | SIGNAL sclk : std_logic := '0'; |
25 | SIGNAL sdata : std_logic := '0'; |
26 | |
27 | -- Outputs
|
28 | SIGNAL data : std_logic_vector(7 downto 0); |
29 | SIGNAL addr : std_logic_vector(18 downto 0); |
30 | SIGNAL nwe : std_logic; |
31 | |
32 | BEGIN
|
33 | |
34 | -- deine Schaltung anschliessen
|
35 | uut: serpar PORT MAP( |
36 | cs => cs, |
37 | :
|
38 | new => nwe); |
39 | |
40 | -- Simulations-Signale erzeugen, hier beginnt deine Arbeit...
|
41 | tb : PROCESS |
42 | BEGIN
|
43 | cs <= '1'; |
44 | sclk <= '1'; |
45 | sdata <= '0'; |
46 | wait for 10 ns; |
47 | |
48 | cs <= '1'; |
49 | sclk <= '0'; |
50 | sdata <= '0'; |
51 | wait for 10 ns; |
52 | |
53 | :
|
54 | :
|
55 | END PROCESS; |
56 | END; |
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.