www.mikrocontroller.net

Forum: FPGA, VHDL & Co. seriell-parallel Umsetzer mit EPM3032


Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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 ;-)

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> 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!

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, habe es mal gemalt.

Könnte es so wie im Anhang funktionieren?

Autor: hmm... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: hmm... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann nimm den 3064, der hat dann noch was an Reserve

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, habe es jetzt mit 18 Adressleitungen übersetzt bekommen.

Danke für Eure Unterstützung.

Autor: Thomas R. (tinman) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
... und hier noch die Warnungen.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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?

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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 ...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> 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!

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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... :-/

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zauberwort zu deiner ersten Frage heisst: Interleaved

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
> 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:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity serpar is
    Port ( cs : in  STD_LOGIC;
           sclk : in  STD_LOGIC;
           sdata : in  STD_LOGIC;
           nwe : out  STD_LOGIC;
           data : out  STD_LOGIC_VECTOR (7 downto 0);
           addr : out  STD_LOGIC_VECTOR (18 downto 0));
end serpar;

architecture Behavioral of serpar is
signal lpm_cnt : STD_LOGIC_VECTOR (21 downto 0);
signal lpm_sr : STD_LOGIC_VECTOR (7 downto 0);
signal do : STD_LOGIC_VECTOR (7 downto 0);
begin
   -- der Zähler
   process (sclk,cs) begin
      if (cs = '0') then
         lpm_cnt <= (others=>'0');
      elsif rising_edge(sclk) then
         if (cs='1') then
            lpm_cnt <= std_logic_vector(unsigned(lpm_cnt) + 1);
         end if;
      end if;
   end process;

   -- das Schieberegister
   process (sclk) begin
      if rising_edge(sclk) then
         if (cs='1') then
            lpm_sr <= lpm_sr(6 downto 0) & sdata;
         end if;
      end if;
   end process;

   -- ein Latch
   do <=   "00000000" when cs = '0' else
           lpm_sr when lpm_cnt(2 downto 0) = "111" else 
           do;
           
   -- ein wenig Kombinatorik        
   nwe  <= '1' when lpm_cnt(2 downto 0) = "111" else '0';
   addr <= lpm_cnt(21 downto 3);
   data <= do;
   
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)

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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"  ;-)

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;)

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY testbench IS
-- keine Ports
END testbench;

ARCHITECTURE behavior OF testbench IS 

  COMPONENT serpar -- deine Schaltung als Komponente bekanntmachen
    Port ( cs : in  STD_LOGIC;
           sclk : in  STD_LOGIC;
           sdata : in  STD_LOGIC;
           nwe : out  STD_LOGIC;
           data : out  STD_LOGIC_VECTOR (7 downto 0);
           addr : out  STD_LOGIC_VECTOR (18 downto 0)
          );
  END COMPONENT;

  -- Signale zur Verdrahtung
  -- Inputs
  SIGNAL cs :  std_logic := '0';
  SIGNAL sclk :  std_logic := '0';
  SIGNAL sdata :  std_logic := '0';

  -- Outputs
  SIGNAL data :  std_logic_vector(7 downto 0);
  SIGNAL addr :  std_logic_vector(18 downto 0);
  SIGNAL nwe :  std_logic;

BEGIN
 
  -- deine Schaltung anschliessen
  uut: serpar PORT MAP(
         cs => cs,
         :
         new => nwe);

  -- Simulations-Signale erzeugen, hier beginnt deine Arbeit...
  tb : PROCESS
  BEGIN
     cs <= '1';
     sclk <= '1';
     sdata <= '0';
     wait for 10 ns;

     cs <= '1';
     sclk <= '0';
     sdata <= '0';
     wait for 10 ns;

      :
      :
  END PROCESS;
END;

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Thomas R. (tinman) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.