<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Blackhat-blade</id>
	<title>Mikrocontroller.net - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Blackhat-blade"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Blackhat-blade"/>
	<updated>2026-04-10T23:40:13Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Eisenwarenversender&amp;diff=41929</id>
		<title>Eisenwarenversender</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Eisenwarenversender&amp;diff=41929"/>
		<updated>2010-01-04T20:48:17Z</updated>

		<summary type="html">&lt;p&gt;Blackhat-blade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
Dies wird eine Auflistung im Stil von [[Elektronikversender]].&lt;br /&gt;
&lt;br /&gt;
Diese Liste erhebt keinerlei Anspruch auf Vollständigkeit. Wenn ihr einen Versender kennt, der hier noch nicht aufgeführt ist, dann fügt ihn einfach ein (alphabetische Sortierung). Den Rest können auch andere besorgen, die den Versender ebenfalls kennen.&lt;br /&gt;
&lt;br /&gt;
== Liste der Versender ==&lt;br /&gt;
&lt;br /&gt;
=== Alu-Verkauf.de ===&lt;br /&gt;
Homepage: http://www.alu-verkauf.de/&lt;br /&gt;
* Alu und Kupfer&lt;br /&gt;
* Versand bis 5 kg 6€&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== B&amp;amp;T Metall- u. Kunststoffhandel ===&lt;br /&gt;
Homepage: http://www.metall-kunststoffhandel.de/shop/index.php&lt;br /&gt;
*  Versand bis 2 kg 5€ zzgl. MwSt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Feld Maschinenbau ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.mein-stahlshop.de/&lt;br /&gt;
&lt;br /&gt;
*Bleche im Zuschnitt (Kupfer, Alu, Eisen, Edelstahl)&lt;br /&gt;
*Profile&lt;br /&gt;
*Versand ab 5,60€&lt;br /&gt;
*Relativ schnell&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== inox-schrauben.de ===&lt;br /&gt;
Homepage: http://www.inox-schrauben.de&lt;br /&gt;
*  Edelstahl-Schrauben und Werkzeug&lt;br /&gt;
*  Versand 6€&lt;br /&gt;
*  keine Mindestbestellmenge&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Metallstore ===&lt;br /&gt;
Homepage: http://metallstore.de/&lt;br /&gt;
* Halbzeuge &amp;amp; Lineartechnik&lt;br /&gt;
* Mindestbestellmenge 60€ sonst 18€ Mindermengenzuschlag&lt;br /&gt;
* Versand 8€??&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== metal made 4 you ===&lt;br /&gt;
Homepage: http://www.mm4u.de/&lt;br /&gt;
* Maßanfertigung von Blechteilen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Modellbauershop ===&lt;br /&gt;
Homepage: http://www.modellbauershop.de/&lt;br /&gt;
* sehr kleine Schrauben, Muttern, Scheiben, Nieten, Zahnräder, etc&lt;br /&gt;
* Versand ab 2,20€&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SCREWS &amp;amp; MORE ===&lt;br /&gt;
Homepage: http://www.screwsandmore.de/&lt;br /&gt;
* Hauptsächlich Schrauben, davon aber alle Variationen&lt;br /&gt;
* Versand 4,50 €&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Elektronikversender]]&lt;br /&gt;
* [[Platinenhersteller]]&lt;br /&gt;
* [[Lokale Elektroniklieferanten]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* http://www.xs4all.nl/~ganswijk/chipdir/ Suche nach integrierten Schaltkreisen&lt;br /&gt;
* http://www.alldatasheet.com                Datenblätter&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile|!]]&lt;/div&gt;</summary>
		<author><name>Blackhat-blade</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=L%C3%B6tkolben&amp;diff=41391</id>
		<title>Lötkolben</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=L%C3%B6tkolben&amp;diff=41391"/>
		<updated>2009-12-14T15:07:30Z</updated>

		<summary type="html">&lt;p&gt;Blackhat-blade: Änderung 41390 von 79.193.220.140 (Diskussion) wurde rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Löten]]&lt;br /&gt;
Der Lötkolben ist das zur manuellen Erstellung von Lötverbindungen vorwiegend benutzte Werkzeug.&lt;br /&gt;
&lt;br /&gt;
Da im professionellen Bereich sowie unter erfahrenen Elektronikern das entsprechende Know-How sicher vorhanden ist, wendet sich diese Seite in erster Linie an Hobbyisten und andere Einsteiger, etwa solche, die als ehemalige &amp;quot;reine&amp;quot; Software-Entwickler nun im hardwarenahen Bereich ihre ersten Schritte mit Mikrocontroller-Aufbauten machen möchten.&lt;br /&gt;
&lt;br /&gt;
== Arten von Lötkolben ==&lt;br /&gt;
&lt;br /&gt;
Um elektronische Schaltungen erfolgreich aufzubauen, sollte man zunächst wissen, welche Arten von Lötkolben es gibt, und wozu sie geeignet sind.&lt;br /&gt;
&lt;br /&gt;
=== Lötnadeln (ca. 5 bis 10 Watt) ===&lt;br /&gt;
&lt;br /&gt;
Diese &amp;quot;Miniatur-Lötkolben&amp;quot; sind nur für feinste Arbeiten, bei denen man oft auch eine Lupe einsetzen wird, sinnvoll. Beispiele dafür sind:&lt;br /&gt;
* Anlöten extrem dünner Drähte, z. B. solche aus der &amp;quot;Wire-Wrap&amp;quot;-Wickeltechnik;&lt;br /&gt;
* Korrektur- und Nachlötungen bei beengten Verhältnissen, z. B. an SMD-Bauteilen;&lt;br /&gt;
* Reparatur schmaler Leiterbahnen mit einem Haarriss (oder vorsorgliches Verzinnen beim Verdacht auf einen solchen).&lt;br /&gt;
&lt;br /&gt;
Lötnadeln werden häufig mit Niederspannung versorgt (z. B. 12 Volt) und können daher mit Hilfe eines einstellbaren Netzteils auch mit etwas Unter- oder Übertemperatur betrieben werden. Generell sind sie aber eher ein Werkzeug für den &amp;quot;fortgeschrittenen&amp;quot; (Hobby-) Elektroniker und nicht so gut geeignet, um überhaupt erst einmal Übung im Löten zu bekommen.&lt;br /&gt;
&lt;br /&gt;
=== Feinlötkolben (ca. 15 bis 20 Watt) ===&lt;br /&gt;
Diese kleinen, leichten Lötkolben kommen zum Einsatz, wenn es um die Bestückung von Platinen oder das An- und Ablöten dünner Drähte und Litzen geht. Lediglich für das Herstellen von Verbindungen, über die später stärkere Ströme (im Bereich einiger Ampere) fließen sollen, also z. B. zum Auflöten einer Litze höheren Querschnitts auf eine größere Kupferfläche sind sie etwas schwach. Für Anfänger, die wenig Geld ausgeben wollen, sind Feinlötkolben am ehesten zu empfehlen.&lt;br /&gt;
&lt;br /&gt;
Auch diese Art von Lötkolben gibt es für Niederspannung. Man braucht dann zwar zum Betrieb ein entsprechendes Netzteil, kann dafür aber (bei einstellbarer Ausgangsspannung des Netzteils) die Leistung des Lötkolbens innerhalb gewisser Grenzen variieren.&lt;br /&gt;
&lt;br /&gt;
=== Elektronik-Universallötkolben (ca. 30 Watt) ===&lt;br /&gt;
Sie sind das &amp;quot;Standardwerkzeug&amp;quot; des Elektronikers, aber für alle, die hauptsächlich Schaltungsaufbauten im Bereich Mikrocontroller erstellen, fast schon unnötig groß. Ausgestattet mit unterschiedlichen Lötspitzen (siehe unten) sind Lötkolben dieser Klasse für viele Arbeiten geeignet, wenn auch meist etwas unhandlicher als Feinlötkolben.&lt;br /&gt;
&lt;br /&gt;
Auszunehmen sind lediglich die oben unter &amp;quot;Lötnadel&amp;quot; beschriebenen Arbeiten - es sei denn man hat wirklich großes Geschick und eine sehr ruhige Hand. Am anderen Ende der Skala denkbarer Arbeiten wird man sich allenfalls für das zügige An- und Ablöten sehr dicker Drähte oder Litzen auf/von massiven Metallteilen manchmal mehr Leistungsreserve wünschen, kommt in der Regel aber auch mit einem 30 Watt Lötkolben zum Erfolg.&lt;br /&gt;
&lt;br /&gt;
Da solche Lötkolben typischerweise an 230 Volt betrieben werden, erübrigt sich auch ein eigenes Netzteil (bzw. man kann die Spannung seines Labor-Netzteils stets für den Versuchsaufbau passend eingestellt lassen), auf der anderen Seite entfällt damit die Möglichkeit, die Leistung des Lötkolbens in einem gewissen Umfang zu variieren.&lt;br /&gt;
&lt;br /&gt;
=== Temperaturgeregelte Lötkolben (ca. 60 Watt) ===&lt;br /&gt;
&amp;quot;Mehr&amp;quot; ist nicht immer automatisch &amp;quot;besser&amp;quot;, und so ist eine höhere Leistung bei Lötkolben problematisch, weil der Lötkolben &amp;quot;im Leerlauf&amp;quot; oder bei kleineren Lötstellen zu heiß werden kann. Aus diesem Grund sollte man in der Leistungsklasse oberhalb 30 Watt besser gleich in einen temperaturgeregelten Lötkolben investieren. Zwar sind diese deutlich teurer als Lötkolben der ersten drei Kategorien, aber zerstörte Bauteile oder verdorbene Platinen verursachen auf Dauer noch höhere Kosten und sind auf jeden Fall ärgerlich.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer Vorteil der Investition in einen solchen Lötkolben ist, dass sich damit auch schon mal kleinere Reparaturarbeiten außerhalb des Elektronikbereichs durchführen lassen (etwa Spielzeug etc.).&lt;br /&gt;
&lt;br /&gt;
Fuer den Einstieg reicht die &amp;quot;Analog 60&amp;quot; oder Weller &amp;quot;Temptronic&amp;quot; allemal:&lt;br /&gt;
&lt;br /&gt;
Analog 60&lt;br /&gt;
+ Betrieb direkt aus dem soliden Blechkoffer heraus &lt;br /&gt;
+ heisse Lötspitze mit Zange problemlos wechselbar (ein Handgriff)&lt;br /&gt;
- Regelung teilweise hörbar (leises Klacken)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weller Temptronic&lt;br /&gt;
+&lt;br /&gt;
- um eine heiße Loetspitze zu wechseln muss erst das Röhrchen vom Thermoelement entfernt werden und dann die Spitze. Vorsicht alles heiss&lt;br /&gt;
&lt;br /&gt;
siehe: http://www.mikrocontroller.net/forum/read-1-369049.html#new&lt;br /&gt;
&lt;br /&gt;
=== Große Lötkolben (über 60 Watt) ===&lt;br /&gt;
Diese sind in der Regel kein Werkzeug für den Elektroniker - es sei denn man denkt an das Verlöten von Metallgehäusen zur Abschirmung oder an das Löten von Akkus oder Solarzellen - und eher für allgemeine Reparaturen im Haushalt geeignet. Aber wenn man durch die Beschäftigung mit der Elektronik schon mal &amp;quot;das Löten gelernt hat&amp;quot;, will man diese Fähigkeiten vielleicht auch anderweitig einsetzen...ij&lt;br /&gt;
&lt;br /&gt;
== Arten von Lötspitzen ==&lt;br /&gt;
Bei den meisten Lötkolben kann die eigentliche Lötspitze ausgwechselt werden. Dies ist zum einen erforderlich, weil sich die Spitze im Lauf der Zeit abnutzt (was aber je nach Nutzungshäufigkeit des Lötkolbens und Materialqualität der Spitze Jahre dauern kann). Zum anderen wird man insbesondere bei stärkeren Lötkolben abhängig von der Arbeit, die man durchführen möchte, unterschiedlich geformte Spitzen benötigen. &lt;br /&gt;
&lt;br /&gt;
=== Kegelförmig ===&lt;br /&gt;
Leicht kegelförmige Spitzen, die vorne in einer Halbkugel (Durchmesser meist unter 1 mm) auslaufen, eignen sich besonders für &amp;quot;beengte Verhältnisse&amp;quot;, also nahe beieinander liegende Pins, geringen Leiterbahnabstand usw. Das Problem solcher Spitzen bei anderen Arbeiten ist, dass die Kontaktfläche zu den zu verlötenden Teilen recht gering ist. Da beim Löten - wie unter &amp;quot;[[Löten (praktisch)]]&amp;quot; ausgeführt - stets die zu verlötenden Teile und nicht das Lötzinn erwärmt werden sollte, kann das Herstellen größerer Lötverbindungen mit solchen Spitzen länger als nötig dauern. Die Folge können durch Hitze zerstörte Bauteile sein (wenn die Spitze so gehalten wurde, dass vor allem das Bauteil, nicht aber die Leiterbahn erwärmt wurde) oder sich ablösende Leiterbahnen (im umgekehrten Fall).&lt;br /&gt;
&lt;br /&gt;
=== Breit und Flach ===&lt;br /&gt;
Mit diesen, etwa nach der Art eines Schraubendrehers (aka. &amp;quot;Schraubenzieher&amp;quot; - aber nicht nach DIN! :-)) geformten Lötspitzen lässt sich je nach dem, wie man sie ansetzt, ein größerer oder kleinerer Kontakt zu den zu verlötenden Teilen herstellen. Unter beengten Verhältnissen ist aber, selbst wenn man sie &amp;quot;hochkant&amp;quot; hält, die Gefahr gegeben, Lötzinn an Stellen zu verschmieren, wo es nicht hingehört und z.B. zu einem Kurzschluss führt.&lt;br /&gt;
&lt;br /&gt;
=== Zylindrisch/Angeschrägt ===&lt;br /&gt;
Es ist sicher auch eine Geschmacks- und Übungssache, aber Spitzen, die eine zylindrische Grundform haben (Durchmesser etwa 1,5..2,5 mm) und vorne im Winkel von ca. 45 Grad angeschnitten sind, bieten eine überraschend große Bandbreite von Einsatzmöglichkeiten. Insbesondere für etwas &amp;quot;faule&amp;quot; und &amp;quot;ungeduldige&amp;quot; Naturen, die nicht dauernd zwischen den verschiedenen Lötspitzen ihres Lötkolbens wechseln wollen, sind solche Spitzen günstig. Aufgrund der Asymmetrie findet man ferner - etwas Übung vorausgesetzt - mit solchen Spitzen fast immer einen Ansatzpunkt, der es erlaubt, die beiden zu verlötenden Teile gleichmäßig schnell zu erwärmen. (Achtung: Gleichmäßig bedeutet hier vor allem, dass man ggf. das Teil mit der geringeren thermischen Masse, das sich also &#039;&#039;schneller&#039;&#039; erwärmen wird, auch nur mit der &#039;&#039;kleineren&#039;&#039; Fläche der Spitze in Kontakt bringen wird!)&lt;br /&gt;
&lt;br /&gt;
=== Abgewinkelt vs. Gerade ===&lt;br /&gt;
Auch hier mag Erfahrung, Übung und Geschick eine Rolle spielen, aber im Bereich der (Fein-) Elektronik werden meist gerade Spitzen bevorzugt. Insbesondere beim Löten auf gedruckten Schaltungen erlaubt die &amp;quot;bleistiftähnliche&amp;quot; Haltung eines Lötkolbens mit gerader Spitze eine präzisere Positionierung.&lt;br /&gt;
&lt;br /&gt;
=== Spezielle Spitzen ===&lt;br /&gt;
Für temperaturgeregelte Lötkolben gibt es als Sonderzubehör meist spezielle Lötspitzen zum Entlöten, z.B. solche, die sämtliche Pins eines ICs auf einmal erhitzen, oder Spitzen mit einer Bohrung im Inneren und einem aufgesetzten Gummiball, durch die man Lötzinn absaugen kann.&lt;br /&gt;
&lt;br /&gt;
== Noch etwas &amp;quot;Theorie&amp;quot; ==&lt;br /&gt;
An dieser Stelle noch einmal kurz zum Einfluss von Leistung und Temperatur auf das Lötergebnis.&lt;br /&gt;
&lt;br /&gt;
=== Einfluss der Leistung ===&lt;br /&gt;
Ein Lötkolben höherer Leistung ist vor allem dann angebracht, wenn größere Metallteile (z.B. großflächige Masse-Leiterbahnen) erwärmt werden müssen. Dass ein Lötkolben für eine bestimmte Arbeit &amp;quot;deutlich zu schwach&amp;quot; ist, merkt man daran, dass die Lötspitze nach dem ersten Aufsetzen kurz &amp;quot;anklebt&amp;quot;, weil die große kalte Fläche das an der Spitze des Lötkolbens hängende, geschmolzene Lötzinn wieder fest werden lässt.&lt;br /&gt;
&lt;br /&gt;
Bei ungeregelten Lötkolben wird hier zusätzlich die &amp;quot;thermische Masse&amp;quot; der Lötspitze ins Spiel kommen, d.h. mit einer massiven Spitze, die selbst sehr viel mehr Wärme speichert als die zu verlötenden Teile, wird sich dieser Effekt kaum einstellen, mit der dünnen Spitze einer sehr feinen Lötnadel schon eher. Bei einem Niederspannungslötkolben, den man über ein einstellbares Netzteil betreibt, kann man in diesem Fall über die Spannung die Leistung etwas erhöhen. Aber Achtung: Der Zusammenhang ist nicht linear, 10% mehr Spannung sind rund 21% mehr Leistung, 20% mehr Spannung rund 45% mehr Leistung(*1,*2).&lt;br /&gt;
&lt;br /&gt;
=== Einfluss der Temperatur ===&lt;br /&gt;
Bekanntlich vertragen Halbleiterbauteile es nicht, wenn sie zu heiß werden. Das gilt nicht nur für die Wärme, die sie im laufenden Betrieb selbst entwickeln, sondern auch für die Erhitzung ihrer Anschlussdrähte oder -pins beim Löten.&lt;br /&gt;
&lt;br /&gt;
Ein Fehlschluss wäre es nun aber anzunehmen, dass man durch eine geringere Temperatur des Lötkolbens dieser Gefahr vorbeugen könnte. Bis die über einen Draht oder Pin zugeführte Wärme das Innere des Bauteils erreicht (wo die hohe Temperatur ihre schädlichen Auswirkungen entfaltet), vergehen einige Sekunden. Braucht man aufgrund verringerter Temperatur nun für den gesamten Lötvorgang doppelt oder dreimal so lang, wird dies die Gefahr für das Halbleiterbauelement sogar erhöhen - ob die Lötspitze dann eine Temperatur 350 Grad oder &amp;quot;nur&amp;quot; 280 Grad hat, ändert nicht viel. Merke: Weniger die geringe Temperatur als ein zügiger Lötvorgang sollte das Ziel sein! (Allerdings wird sich bei zu hoher Temperatur das Flussmittel im Lötzinn möglicherweise verflüchtigen, ohne ausreichend Wirkung entfaltet zu haben!)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
* 1: Wieviel Mehrleistung man dem Lötkolben zumuten darf, bevor er kaputt geht, ist schwer zu sagen. Der Autor dieser Zeilen verwendet seit über 30 Jahren für die meisten seiner Aufbauten einen Lötkolben von 12 Watt, der &amp;quot;offiziell&amp;quot; mit 6 Volt zu betreiben ist. Tatsächlich wird der Lötkolben aber je nach Bedarf mit 5, 6 oder 7 Volt betrieben, entsprechend einer Mehr- und Minderleistung von etwa 30%.&lt;br /&gt;
&lt;br /&gt;
* 2: Obacht bei solchen Rechnungen: Das Heizelement eines Lötkolbens dürfte einen erheblichen positiven Temperaturkoeffizienten haben, der den Einfluss der Betriebsspannung auf die Leistung deutlich reduziert.&lt;/div&gt;</summary>
		<author><name>Blackhat-blade</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Verilog&amp;diff=41074</id>
		<title>Verilog</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Verilog&amp;diff=41074"/>
		<updated>2009-12-02T11:53:03Z</updated>

		<summary type="html">&lt;p&gt;Blackhat-blade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einleitung =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Verilog ist eine Hardwarebeschreibungssprache (Hardware Description Language: HDL) die es ermöglicht ein digitales System in einem recht weiten Spektrum an Abstraktion zu spezifizieren.&lt;br /&gt;
&lt;br /&gt;
== Geschichte ==&lt;br /&gt;
Verilog wurde im Winter 1983/84 (&amp;quot;The Verilog Hardware&lt;br /&gt;
Description Language&amp;quot;, Thomas &amp;amp; Moorby) als ein proprietäres&lt;br /&gt;
Produkt zur Verifikation und Simulation von digitaler Logik entwickelt.&lt;br /&gt;
&lt;br /&gt;
Verilog wurde erstmals vom [http://ieee.org IEEE] 1995 standardisiert in IEEE 1364-1995.&lt;br /&gt;
Eine Erweiterung wurde dann 2001 durchgeführt mit IEEE 1364-2001 und&lt;br /&gt;
später IEEE 1364-2005.&lt;br /&gt;
&lt;br /&gt;
Mit erscheinen des letzten Standards hat die [http://www.verilog.com/IEEEVerilog.html IEEE P1364 Arbeitsgruppe] ihre Arbeit eingestellt und die Pflege des Standards der [http://www.eda.org/sv-ieee1800/ IEEE P1800 Arbeitsgruppe] übergeben, die sich mit der Standardisierung von System Verilog befasst.&lt;br /&gt;
&lt;br /&gt;
== Entwicklung der Hardwarebeschreibungssprache ==&lt;br /&gt;
&lt;br /&gt;
Das Besondere an einer Hardwarebeschreibungssprache sind die zwei unterschiedlichen Ansätze mit der die Sprache eingesetzt wird. Bei einer Programmiersprache gibt es den Sprachsyntax und in Abhängigkeit der Sprache gibt es eine Philosophie wie diese Sprache und alle verfügbaren Konstrukte eingesetzt werden. So gibt es z.B. prozedurale Programmiersprachen, wie C, bei denen teilt man mit Hilfe von Funktionsaufrufen große Problem in viele kleine Probleme. Bei objektorientierten Sprachen, wie z.B. C++, nimmt man Objekte und unterteilt ein Problem in die verschieden Objekte und wie diese miteinander kommunizieren.&lt;br /&gt;
&lt;br /&gt;
[[Hardwarebeschreibungssprachen]] wurden ursprünglich zur Spezifikation und Verifikation mit einem Simulator entwickelt. In diesem Bereich kann man auch den gesamten Syntax der Sprache einsetzen. Unterschieden werden die beiden Modellierungsarten&lt;br /&gt;
&lt;br /&gt;
* Modellierung des Verhaltens (engl. Behavioral modeling)&lt;br /&gt;
* Modellierung auf Register-Transfer-Ebene (engl. Register-Transfer-Level  (RTL) modeling)&lt;br /&gt;
&lt;br /&gt;
Bei der Modellierung des Verhaltens werden oft noch keine zeitlichen Aspekte verwendet. Es geht darum in einer abstrakten Form die Funktion des zu entwickelten digitalen Schaltkreises zu simulieren.&lt;br /&gt;
&lt;br /&gt;
Mit der RTL-Modellierung wird dann das Design Taktgenau simuliert.&lt;br /&gt;
&lt;br /&gt;
Später dann kamen einige Electronic Design Automation (EDA) - Firmen auf die Idee, eine Hardwarebeschreibungssprache nicht nur für die Simulation, sondern auch für die Synthese der eigentlichen Hardware zu benutzen. Für diesen Ansatz waren aber die [[Hardwarebeschreibungssprachen]] viel zu mächtig und so wurden nur einfache Sprachkonstrukte genommen, die das Synthesetool unterstützt.&lt;br /&gt;
&lt;br /&gt;
Aus dieser Entwicklung heraus haben sich die beiden Sichtweisen einer Hardwarebeschreibungssprache für Simulation und Synthese entwickelt. Ein Benutzer muss also immer im Hinterkopf haben, welchen Teil der Sprache er für seine Entwicklung nutzen kann. Für die Simulation sind in der Regel keine Grenzen gesetzt. Für die Entwicklung synthetisierbarer Logik dagegen sind nur einige Sprachkonstrukte erlaubt. Der Verilog Standard IEEE 1394 hat dazu einen Zusatz, in dem ein einheitlicher synthetisierbarer Syntax spezifiziert wird. Für eine spezielle Synthesesoftware bietet natürlich auch das entsprechende Benutzerhandbuch Aufschluss. Für Xilinx ist das z.B. das [http://www.google.de/search?q=xilinx+xst+user+guide XST User&#039;s Guide].&lt;br /&gt;
&lt;br /&gt;
== Gliederung ==&lt;br /&gt;
&lt;br /&gt;
Dieser Artikel gibt eine Einführung in die [[Hardwarebeschreibungssprachen|Hardwarebeschreibungssprache]] Verilog, mit der Zielsetzung, ein Verständnis für die unterschiedliche Nutzung der Sprache für Simulation und Synthese zu geben.&lt;br /&gt;
&lt;br /&gt;
Der Artikel gliedert sich in die drei Teile:&lt;br /&gt;
&lt;br /&gt;
* Sprachübersicht&lt;br /&gt;
* Simulation/Verifikation&lt;br /&gt;
* Synthetisierbare Konstrukte&lt;br /&gt;
&lt;br /&gt;
In der Sprachübersicht werden grundlegende Sprachelemente vermittelt. Dieser Teil ist bewusst klein gehalten und versucht nur die Teile der Sprache zu besprechen, die für Neueinsteiger(innen) erst mal wichtig sind.&lt;br /&gt;
&lt;br /&gt;
Daran schließt sich ein Teil mit dem Schwerpunkt der Simulation synthetisierbarer Logik. Zwar wissen wir an der Stelle noch nicht viel von synthetisierbarer Logik, dieser Teil wurde aber bewusst vorgezogen, da es hier keine Beschränkungen in der Nutzung der Sprache und der Art der Modellierung gibt. Auch ist es der Teil, bei dem erste praktische Erfolge mit dem Simulator erzielt werden.&lt;br /&gt;
&lt;br /&gt;
Darauf folgt dann der Teil in dem die synthetisierbaren Konstrukte der Sprache erläutert werden.&lt;br /&gt;
&lt;br /&gt;
= Sprachübersicht =&lt;br /&gt;
&lt;br /&gt;
== module ==&lt;br /&gt;
&lt;br /&gt;
Die grundlegende Gruppierung wird in Verilog durch &#039;&#039;module&#039;&#039; durchgeführt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
// Einzeiliger Kommentar, wie C++&lt;br /&gt;
&lt;br /&gt;
module MeinModulName ( input a, output b, inout data);&lt;br /&gt;
&lt;br /&gt;
/* Mehrzeiliger Kommentar&lt;br /&gt;
   Wie von C bekannt&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Signale werden durch Ports dem Modul übergeben. Für Signale in das Modul&lt;br /&gt;
gibt es den &#039;&#039;input&#039;&#039; Port. Ausgänge werden durch &#039;&#039;output&#039;&#039;&lt;br /&gt;
spezifiziert und ein bidirektionaler Bus durch &#039;&#039;inout&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wie oben gezeigt sind ein- oder mehrzeilige Kommentar wie bei C/C++ möglich.&lt;br /&gt;
&lt;br /&gt;
== Datentypen: &#039;&#039;&#039;wire, reg&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
Die grundlegenden Datentypen mit denen in Verilog modelliert wird, sind &#039;&#039;wire&#039;&#039; und &#039;&#039;reg&#039;&#039;. Analog zum elektrischen Draht können mit dem &#039;&#039;wire&#039;&#039; Verbindungen durchgeführt werden. Wie ein Draht, kann aber ein &#039;&#039;wire&#039;&#039; keinen Signalzustand speichern. Für die Modellierung digitaler Logik ist es aber auch nötig Signaltreiber zu haben. Hier kommt der Datentyp &#039;&#039;reg&#039;&#039; ins Spiel. Mit ihm können Signalzustände gespeichert werden und er findet damit als Signaltreiber Verwendung.&lt;br /&gt;
&lt;br /&gt;
Verilog unterstützt die Signalzustände:&lt;br /&gt;
&lt;br /&gt;
* 0 --&amp;gt; logisch null&lt;br /&gt;
* 1 --&amp;gt; logisch eins&lt;br /&gt;
* z --&amp;gt; hochohmig&lt;br /&gt;
* x --&amp;gt; undefiniert&lt;br /&gt;
&lt;br /&gt;
Mit dem &#039;&#039;assign&#039;&#039; Konstrukt können die Signalzustände wie folgt einem &#039;&#039;wire&#039;&#039; zugewiesen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module;&lt;br /&gt;
&lt;br /&gt;
  wire a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
  assign a = 0;&lt;br /&gt;
  assign b = 1;&lt;br /&gt;
  assign c = x;&lt;br /&gt;
  assign d = z;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;assign&#039;&#039;-Anweisung kann als eine Art Verdrahtungsregel angesehen werden, mit der die Verbindung des &#039;&#039;wire&#039;&#039; beschrieben wird. Im obigen Beispiel werden die vier Drähte jeweils mit konstante Werte verdrahtet. Diese Konstanten sind die Signaltreiber für die Drähte.&lt;br /&gt;
&lt;br /&gt;
Mit dem &#039;&#039;assign&#039;&#039; Konstrukt können nur einem &#039;&#039;wire&#039;&#039; Signale zugewiesen werden. Ein &#039;&#039;reg&#039;&#039; muss innerhalb eines &#039;&#039;always&#039;&#039; oder &#039;&#039;initial&#039;&#039; Blocks seine Werte zugewiesen bekommen. Mehr dazu in dem Abschnitt über &#039;&#039;initial&#039;&#039; und &#039;&#039;always&#039;&#039; Blöcke.&lt;br /&gt;
&lt;br /&gt;
== Ereignissteuerung mit @ ==&lt;br /&gt;
&lt;br /&gt;
Im vorherigen Abschnitt haben wir schon mit den Signalzuständen &#039;&#039;x&#039;&#039; und &#039;&#039;z&#039;&#039; eine Eigenart von [[Hardwarebeschreibungssprachen]] kennen gelernt. Mit der Ereignissteuerung, die durch das &#039;&#039;&#039;@&#039;&#039;&#039;-Zeichen beschrieben wird, lernen wir jetzt eine weitere kennen. &lt;br /&gt;
&lt;br /&gt;
Mit der Ereignissteuerung ist es möglich den Zustand von einem Signal überwachen zu lassen und dann in Abhängigkeit davon eine Zuweisung auszulösen.&lt;br /&gt;
&lt;br /&gt;
Nehmen wir als Beispiel einen Schalter, bei dessen Betätigung eine LED eingeschaltet wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module led_steuerung( input schalter );&lt;br /&gt;
&lt;br /&gt;
 reg  led       = 0;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 @(schalter) led = 1;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie bereits erwähnt wird die Ereignissteuerung mit dem Klammeraffen beschrieben.  Nach dem Klammeraffen folgt die Ereignisliste. Sie ist eingebettet in Klammern, eine Liste von ein oder mehreren Signalen, die bestimmen wann die folgende Operation ausgeführt wird. Im obigen Beispiel ist der &#039;&#039;wire&#039;&#039; &#039;&#039;&#039;schalter&#039;&#039;&#039; in der Ereignisliste und bei einem Signalwechsel von diesem wird dem &#039;&#039;reg&#039;&#039; &#039;&#039;&#039;led&#039;&#039;&#039; der Wert 1 zugewiesen.&lt;br /&gt;
&lt;br /&gt;
Neben Signaländerungen kann der Konstrukt auch genutzt werden um auf steigenden oder fallende Flanken zu reagieren. Hierzu werden die Schlüsselwörter &#039;&#039;posedge&#039;&#039; für steigende Flanke und &#039;&#039;negedge&#039;&#039; für fallende Flanke benutzt.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel wird &#039;&#039;&#039;led&#039;&#039;&#039; der Wert 1 zugewiesen wenn &#039;&#039;&#039;schalter&#039;&#039;&#039; einen Signalwechsel von 0 nach 1 oder 1 auf 0 macht. Soll das z.B. eingegrenzt werden und eine Zuweisung nur beim Wechsel von 0 auf 1 stattfinden, kann das Beispiel wie folgt geändert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module led_steuerung( input schalter );&lt;br /&gt;
&lt;br /&gt;
 reg  led       = 0;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 @(posedge schalter) led = 1;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt wird die Zuweisung erst bei einer steigenden Flanke von &#039;&#039;&#039;schalter&#039;&#039;&#039; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Die Ereignissteuerung ist einer der grundlegenden Sprachkonstrukte in der Hardwarebeschreibung um die parallele Natur der Hardware zu beschreiben. Im nächsten Abschnitt werden wir sie im Zusammenhang mit &#039;&#039;always&#039;&#039; Blöcken kennen lernen. Diese Blöcke erlauben es, parallel ablaufende Prozesse zu beschreiben und mit Hilfe der Ereignissteuerung deren Abläufe zu kontrollieren.&lt;br /&gt;
&lt;br /&gt;
== always, initial ==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;always&#039;&#039; und &#039;&#039;initial&#039;&#039; Blöcke werden verwendet um die parallele Natur von Hardware zu beschreiben. Jeder dieser Blöcke wird parallel ausgeführt, wobei ein &#039;&#039;initial&#039;&#039; Block nur einmal durchlaufen wird und ein &#039;&#039;always&#039;&#039; Block, wie eine Endlosschleife, ständig wiederholt wird.&lt;br /&gt;
&lt;br /&gt;
Nehmen wir mal einen &#039;&#039;initial&#039;&#039; Block als Beispiel und kommen auf das Problem zurück, dass einem &#039;&#039;reg&#039;&#039; nur in einem &#039;&#039;always&#039;&#039; oder &#039;&#039;initial&#039;&#039; Block Werte zugewiesen werden können:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module;&lt;br /&gt;
&lt;br /&gt;
  reg a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
  initial begin&lt;br /&gt;
&lt;br /&gt;
    a = 0;&lt;br /&gt;
    b = 1;&lt;br /&gt;
    c = z;&lt;br /&gt;
    d = x;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Was in dem Beispiel neu dazu gekommen ist, ist die Gruppierung durch &#039;&#039;begin&#039;&#039; und &#039;&#039;end&#039;&#039;. Vergleichbar mit den geschweiften Klammern in der Programmierung mit C/C++, können Segmente mit &#039;&#039;begin&#039;&#039; und &#039;&#039;end&#039;&#039; zusammengefasst werden.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel wird der &#039;&#039;initial&#039;&#039; Block einmal durchlaufen und die Ausführung endet dann nach dem Abarbeiten der letzten Operation.&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;initial&#039;&#039; Konstrukt wird vorwiegend in der Simulation für Testbenches verwendet. In der Beschreibung synthetisierbarer Logik findet er weniger Verwendung.&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;always&#039;&#039; Konstrukt kann sowohl in Testbenches als auch in synthetisierbarer Logik verwendet werden. Hier erst mal ein Beispiel aus einer Testbench zum Generieren eines Taktsignals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module;&lt;br /&gt;
&lt;br /&gt;
reg clk = 0;&lt;br /&gt;
&lt;br /&gt;
always&lt;br /&gt;
  #10 clk = ~clk;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als neuer Sprachkonstrukt kommt hier das Verzögerungszeichen &#039;&#039;#&#039;&#039;, das die Ausführung in diesen Fall für 10 Zeiteinheiten verzögert und dann mit der Ausführung des ihm folgenden Konstruktes weiter fortfährt. Was also in dem &#039;&#039;always&#039;&#039; Block geschieht ist, dass die Zuweisung clk = ~clk; im Simulator vom momentanen Zeitpunkt um 10 Zeiteinheiten verzögert ausgeführt wird. Bei der Zuweisung selber wird dann dem &#039;&#039;&#039;clk&#039;&#039;&#039; Signal das invertierte &#039;&#039;&#039;clk&#039;&#039;&#039; Signal zugewiesen. Der &#039;&#039;always&#039;&#039; Block toggelt also das &#039;&#039;&#039;clk&#039;&#039;&#039; Signal alle 10 Zeiteinheiten.&lt;br /&gt;
&lt;br /&gt;
Die anfängliche Initialisierung von &#039;&#039;&#039;clk&#039;&#039;&#039; auf 0 ist sehr wichtig, da das Toggeln nur von 0 auf 1, bzw. 1 auf 0 funktioniert. Wird sie weggelassen ist &#039;&#039;&#039;clk&#039;&#039;&#039; undefiniert, also &#039;&#039;x&#039;&#039;, und das Toggeln würde nicht funktionieren.&lt;br /&gt;
&lt;br /&gt;
Vielleicht ist es ganz sinnvoll an dieser Stelle noch mal zu erwähnen, dass das Verzögerungszeichen nicht synthetisierbar ist.&lt;br /&gt;
&lt;br /&gt;
Im vorherigen Abschnitt haben wir die Ereignissteuerung kennen gelernt. Jetzt werden wir diese mit einem &#039;&#039;always&#039;&#039; kombinieren und damit steuern, wann der &#039;&#039;always&#039;&#039; Block durchlaufen werden soll.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module;&lt;br /&gt;
&lt;br /&gt;
  reg y, a, b, c;&lt;br /&gt;
&lt;br /&gt;
  always @(a, b, c)&lt;br /&gt;
    y = a &amp;amp; b &amp;amp; c;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die logische UND Verknüpfung von &#039;&#039;&#039;a&#039;&#039;&#039;, &#039;&#039;&#039;b&#039;&#039;&#039; und &#039;&#039;&#039;c&#039;&#039;&#039; wird &#039;&#039;&#039;y&#039;&#039;&#039; zugewiesen. Durch die Ereignissteuerung wird der &#039;&#039;always&#039;&#039; Block jedesmal durchlaufen, wenn sich der Signalzustand von &#039;&#039;&#039;a&#039;&#039;&#039;, &#039;&#039;&#039;b&#039;&#039;&#039; oder &#039;&#039;&#039;c&#039;&#039;&#039; geändert hat. D.h. wenn sich einer der Signalzustände ändert, wird die Zuweisung ausgeführt und &#039;&#039;&#039;y&#039;&#039;&#039; auf den neusten Stand gebracht. Danach wartet die Ausführung wieder bis sie durch die Ereignissteuerung erneut ausgelöst wird. So viel sei vorweg genommen, diesen Konstrukt nennt man kombinatorische Logik und in dem Abschnitt über synthetisierbare Logik wird noch mal näher darauf eingegangen.&lt;br /&gt;
&lt;br /&gt;
Seit Verilog 2001 kann die Ereignisliste auch vereinfacht werden und einfach durch (*) ersetzen. Der Konstrukt heißt dann also &#039;&#039;&#039;always @(*)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wenn wir bisher von Signaländerungen im Zusammenhang mit der Ereignissteuerung gesprochen haben, dann sind wir immer davon ausgegangen das diese Änderung irgendwie von außen initiiert wurde. Gehen wir jetzt mal etwas mehr auf die parallele Beschreibung von Hardware ein und erweitern das vorherige Beispiel, um die Signaländerung mit in dem &#039;&#039;module&#039;&#039; auszuführen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module;&lt;br /&gt;
&lt;br /&gt;
  reg y;&lt;br /&gt;
  reg a = 1;&lt;br /&gt;
  reg b = 1;&lt;br /&gt;
  reg c = 0;&lt;br /&gt;
&lt;br /&gt;
  always&lt;br /&gt;
    #10 c = ~c;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  always @(a, b, c)&lt;br /&gt;
    y = a &amp;amp; b &amp;amp; c;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier haben wir jetzt zwei &#039;&#039;always&#039;&#039; Blöcke die in Parallel ausgeführt werden. Der erste &#039;&#039;always&#039;&#039; Block ist basiert auf dem Taktgenerator von zuvor. Eine kleine Abänderung ist, dass jetzt hier das Signal &#039;&#039;&#039;c&#039;&#039;&#039; an Stelle von clk alle 10 Zeiteinheiten in seinem Zustand geändert wird. Der Block hat keine Ereignissteuerung, er wird also ständig durchlaufen. Nur der &#039;&#039;&#039;#10&#039;&#039;&#039; Konstrukt hält ihn jeweils für 10 Zeiteinheiten an.&lt;br /&gt;
&lt;br /&gt;
Der zweite &#039;&#039;always&#039;&#039; Block wird wie vorher von der Ereignissteuerung immer dann ausgelöst, wenn sich eins der Signale in seiner Ereignisliste ändert. Hier haben wir &#039;&#039;&#039;a&#039;&#039;&#039; und &#039;&#039;&#039;b&#039;&#039;&#039; einen festen Wert zugewiesen. Das Signal &#039;&#039;&#039;c&#039;&#039;&#039; hingegen ändert sich ständig und löst die Ereignissteuerung und damit den Durchlauf des &#039;&#039;always&#039;&#039; Blockes aus. Die Zuweisung von &#039;&#039;&#039;y&#039;&#039;&#039; wird also immer dann auf den neusten Stand gebracht wenn sich &#039;&#039;&#039;c&#039;&#039;&#039; ändert.&lt;br /&gt;
&lt;br /&gt;
== Skalar, Vektor, Bit-Splitting, Verkettung, Wiederholung ==&lt;br /&gt;
&lt;br /&gt;
Bisher haben wir nur einfache Signale benutzt, d.h. Signale die ein Bit breit sind. Ein Bus aus &#039;&#039;wire&#039;&#039; z.B. wird in der Form &#039;&#039;wire [msb:lsb] &amp;lt;wire_name&amp;gt;&#039;&#039; spezifiziert und wird in Verilog &#039;&#039;&#039;Vektor&#039;&#039;&#039; genannt. Entsprechend kann auch ein &#039;&#039;reg&#039;&#039; Vektor spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  wire [15:0] data;&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
  data[0]   = 1;          // Setzt nur Bit 0&lt;br /&gt;
&lt;br /&gt;
  data[15:13] = 3&#039;b110;   // Setzt Bits 15, 14 = 1, Bit 13 = 0, Wert ist binär&lt;br /&gt;
  data[13:11] = 3&#039;d2;     // Setzt Bits 13-11, Wert ist dezimal&lt;br /&gt;
  data[10:1]  = 9&#039;h0a;    // Setzt Bits 10-1, Wert ist hexadezimal&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Beispiel zeigt wie ein 16 Bit breiter Vektor spezifiziert wird und anschließend einzelne Bits davon gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Bei der Zuweisung wird hier erstmals bei Werten die Bitbreite festgelegt und verschiedene Zahlenrepräsentationen verwendet. Die Bitbreite wird in der Form &#039;&#039;&#039;&amp;lt;Zahl&amp;gt;&amp;lt;Hochkomma&amp;gt;&#039;&#039;&#039; beschrieben. Für die verschiedenen Zahlenformate gibt es die Buchstaben &#039;&#039;b, d, h&#039;&#039;, die für binär, dezimal, bzw. hexadezimal stehen.&lt;br /&gt;
&lt;br /&gt;
Aufmerksamen Lesern ist vielleicht aufgefallen, dass die Art der Zuweisung eigentlich in einen &#039;&#039;initial&#039;&#039; oder &#039;&#039;always&#039;&#039; Block hätte gepackt werden müssen um so zu funktionieren. Eine andere Möglichkeit währe ein &#039;&#039;assign&#039;&#039; Konstrukt daraus zu machen. Aus Übersichtlichkeit wurde hierbei darauf verzichtet.&lt;br /&gt;
&lt;br /&gt;
In diesen Zusammenhang passt es auch die Verkettung von Signalen zu erklären. Sie wird mit geschweiften Klammern erreicht:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  wire [7:0] data;&lt;br /&gt;
  wire [3:0] nibble;&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
  data = {4&#039;b0000, nibble}; &lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem &#039;&#039;wire&#039;&#039; &#039;&#039;&#039;data&#039;&#039;&#039; wird ein 8 Bit breites Wort zugewiesen, bei dem die oberen 4 Bit auf Null gesetzt sind und die unteren 4 Bit den Signalzustand von &#039;&#039;&#039;nibble&#039;&#039;&#039; erhalten.&lt;br /&gt;
&lt;br /&gt;
Die Wiederholung wird auch mit geschweiften Klammern beschrieben und hat die Form &#039;&#039;&#039;{r{num}}&#039;&#039;&#039;. Hierbei wird num, r mal wiederholt.&lt;br /&gt;
&lt;br /&gt;
Um bei dem letzten Beispiel zu bleiben, eine Abänderung bei der die oberen 4 Bit nicht auf Null gesetzt werden, sondern auch den Signalzustand von &#039;&#039;&#039;nibble&#039;&#039;&#039; erhalten kann folgendermaßen erreicht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  data = {2{nibble}};&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird &#039;&#039;&#039;nibble&#039;&#039;&#039; zwei mal wiederholt und damit auf 8 Bit Länge gebracht.&lt;br /&gt;
&lt;br /&gt;
== Speicher Modellierung durch Felder ==&lt;br /&gt;
&lt;br /&gt;
Mit der Modellierung von Speicher wird der Indizierung noch eins drauf gesetzt. Aus der Programmiersprache C sind z.B. Felder bekannt, um Elemente mit gleichem Datentyp zusammen zu fassen. Der gleiche Konstrukt ist in Verilog möglich und wird z.B. zur Modellierung von Speicher genutzt.&lt;br /&gt;
&lt;br /&gt;
Mit dem folgenden Konstrukt wird ein 8 Bit breiter Speicher mit 64 Speicherzellen und der Bezeichnung &#039;&#039;&#039;meinMem&#039;&#039;&#039; definiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  reg [7:0] meinMem [0:63];&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eigentlich nur eine Verschmelzung von Vektor Definition (Bit breite vor Namen) mit Definition von Felder (Anzahl der Elemente nach Namen).&lt;br /&gt;
&lt;br /&gt;
Auf ein Element kann jetzt mit der bekannten Indizierung von Feldern zugegriffen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  meinMem[0] = 8&#039;h7f;&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird in die ersten Speicherstelle der hexadezimale Wert &#039;&#039;&#039;7f&#039;&#039;&#039; geschrieben.&lt;br /&gt;
&lt;br /&gt;
Wird versucht von einem Speicherelement außerhalb des spezifizierten Indexbereiches zu lesen ist das Ergebnis &#039;&#039;x&#039;&#039;. Ein Schreibversuch auf ein Element außerhalb des spezifizierten Indexbereichs hat keine Auswirkung.&lt;br /&gt;
&lt;br /&gt;
Neben eindimensionalen ist auch möglich mehrdimensionale Speicher zu definieren wie z.B. mit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  reg [7:0] zweiDmem [0:15][0:63];&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analog zum eindimensionalen Feld erfolgt der Zugriff mit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  zweiDmem[0][7] = 8&#039;h2a;&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== =, &amp;lt;=; blockierende und nicht-blockierende Zuweisung ==&lt;br /&gt;
&lt;br /&gt;
In Verilog gibt es die zwei Zuweisungsarten:&lt;br /&gt;
&lt;br /&gt;
* =&lt;br /&gt;
* &amp;lt;=&lt;br /&gt;
&lt;br /&gt;
Erstere wird als blockierende Zuweisung (blocking assignment) bezeichnet. Letztere als nicht-blockierend (nonblocking assignment).&lt;br /&gt;
&lt;br /&gt;
Im Standard werden die folgenden zwei Richtlinien für deren Verwendung gegeben:&lt;br /&gt;
&lt;br /&gt;
* (=) Benutze blockierende Zuweisungen in &#039;&#039;always&#039;&#039; Blöcken die kombinatorische Logik modellieren.&lt;br /&gt;
* (&amp;lt;=) Benutze nicht-blockierende Zuweisungen in &#039;&#039;always&#039;&#039; Blöcken die sequentielle Logik modellieren.&lt;br /&gt;
&lt;br /&gt;
Nähere Details über den Hintergrund können in dem Artikel [http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf &amp;quot;Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!&amp;quot;, Cliff Cummings, SNUG 2000] nachgelesen werden.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle möchte ich auf einen Kommentar von Jan Decaluwe, dem Entwickler von [http://www.myhdl.org MyHDL] hinweisen, der die Regelung als nicht notwendig erachtet und für die Mischung der beiden Zuweisungsarten eintritt:&lt;br /&gt;
&lt;br /&gt;
http://article.gmane.org/gmane.comp.python.myhdl/827&lt;br /&gt;
&lt;br /&gt;
== Logische Bit-Operationen ==&lt;br /&gt;
&lt;br /&gt;
Die grundlegenden logischen Bit-Operation sind:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;|&#039;&#039;&#039;     --&amp;gt; OR&lt;br /&gt;
*&#039;&#039;&#039;&amp;amp;&#039;&#039;&#039;     --&amp;gt; AND&lt;br /&gt;
*&#039;&#039;&#039;~&#039;&#039;&#039;     --&amp;gt; NOT&lt;br /&gt;
*&#039;&#039;&#039;^&#039;&#039;&#039;     --&amp;gt; XOR&lt;br /&gt;
&lt;br /&gt;
Sie werden erweitert durch:&lt;br /&gt;
*&#039;&#039;&#039;~&amp;amp;&#039;&#039;&#039;    --&amp;gt; NAND&lt;br /&gt;
*&#039;&#039;&#039;~|&#039;&#039;&#039;    --&amp;gt; NOR&lt;br /&gt;
*&#039;&#039;&#039;^~&#039;&#039;&#039; oder &#039;&#039;&#039;~^&#039;&#039;&#039;      --&amp;gt; XNOR&lt;br /&gt;
&lt;br /&gt;
Verilog unterstützt einen sogenannten Reduktions-Operator, bei dem mit&lt;br /&gt;
einem Operator mehrere Signale zusammen geführt werden. Damit kann z.B.&lt;br /&gt;
eine logische AND-Verknüpfung von 8 Signalen wie folgt durchgeführt&lt;br /&gt;
werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module MeinUnd8 (  input   [7:0] a,&lt;br /&gt;
                   output        y);&lt;br /&gt;
&lt;br /&gt;
  assign y = &amp;amp;a;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Arithmetische Operationen, signed, $signed ==&lt;br /&gt;
&lt;br /&gt;
Bevor wir kurz über die grundlegenden arithmetischen Operationen sprechen kehren wir noch mal zu den Datentypen &#039;&#039;wire&#039;&#039; und &#039;&#039;reg&#039;&#039; zurück. Diese werden in Verilog als vorzeichenlos, also &#039;&#039;&#039;unsigned&#039;&#039;&#039; angesehen.&lt;br /&gt;
&lt;br /&gt;
Entsprechend folgen arithmetische Operationen mit &#039;&#039;wire&#039;&#039; und &#039;&#039;reg&#039;&#039; dem Modulo 2^n, wobei n die Bitbreite des Vektors ist.&lt;br /&gt;
&lt;br /&gt;
Verilog unterstützt die bekannten arithmetischen Operation:&lt;br /&gt;
&lt;br /&gt;
* +&lt;br /&gt;
* -&lt;br /&gt;
* *&lt;br /&gt;
* /&lt;br /&gt;
&lt;br /&gt;
Mit der entsprechend bekannten Präzedenz das Multiplikation und Division vor Addition und Subtraktion geht. Für Klarheit können, wie so oft bei Programmiersprachen, Operationen mit Klammern gruppiert werden.&lt;br /&gt;
&lt;br /&gt;
Leider unterstützt Verilog nicht eine Vereinfachung, die z.B. von der Programmiersprache C bekannt ist, bei der die Zuweisung und der Operator zusammengeschrieben werden und damit ein Operand eingespart werden kann.&lt;br /&gt;
&lt;br /&gt;
Die Schreibweise:&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
a = a + 12;&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
Kann also nicht abgekürzt werden. Auch ist kein Inkrement oder Dekrement Operator bekannt. In &#039;&#039;for&#039;&#039; Schleifen ist es also immer nötig zu schreiben:&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
i=i+1;&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um jetzt auch mit 2&#039;s Komplement zahlen rechnen zu können wird der Konstrukt &#039;&#039;signed&#039;&#039; benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  reg signed [3:0] a;&lt;br /&gt;
  reg        [3:0] b;&lt;br /&gt;
&lt;br /&gt;
  a = 2 - 4;          // a = -2&lt;br /&gt;
  b = 2 - 4;          // b = 13&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Erinnern wir uns das es sich um Modulo 2^n Arithmetik handelt. Im dem Fall wo a als signed spezifiziert wird, ist der Zahlenbereich von a [-8 .. 7]. Für den Fall von b ist er [0..15] und damit entsteht für 2-4 ein Unterlauf und die Berechnung ist 15-2.&lt;br /&gt;
&lt;br /&gt;
In diesem Zusammenhang ist es wichtig zu betrachten was passiert wenn bei arithmetischen Operationen gemischte Operanden, also einer ist unsigned der andere signed, genommen werden. &#039;&#039;&#039;Eine Operation zwischen einem signed und einem unsigned Datentyp resultiert in einen unsigned Datentyp.&#039;&#039;&#039; Da dieses Verhalten nicht immer gewünscht ist, gibt es die $signed() System Funktion. Auf System Funktionen und System Tasks wird später noch näher eingegangen. Der $signed() System Task wandelt einen unsigned Datentypen in einen signed um.&lt;br /&gt;
&lt;br /&gt;
Um jetzt eine arithmetische Operation mit a und b aus dem vorherigen Beispiel durchzuführen und das Ergebnis auch als signed zu haben, muss der unsigned Operand erst mit $signed() in einen signed gewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  reg signed [3:0] a;&lt;br /&gt;
  reg        [3:0] b;&lt;br /&gt;
  reg signed [4:0] c;&lt;br /&gt;
&lt;br /&gt;
  a = 2 - 4;          // a = -2&lt;br /&gt;
  b = 2 - 4;          // b = 13&lt;br /&gt;
&lt;br /&gt;
  c = a + $signed(b);&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vergleichs Operationen; ==, ===, !=, !==, &amp;lt;, &amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Analog zu anderen Programmiersprachen stellt Verilog die Vergleichsoperatoren ==, !=, &amp;lt;, &amp;gt; zur Verfügung. Erinnern wir uns aber daran das ein Signal neben 0 und 1 auch noch die Zustände x oder z annehmen kann. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eine Vergleichsoperation bei der ein Bit den Zustand x oder z hat, ist im Ergebnis x und das wird als FALSCH angesehen.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  4&#039;b1100 == 4&#039;b1100;    // = 1 --&amp;gt; WAHR&lt;br /&gt;
  4&#039;b1100 == 4&#039;b11xx;    // = x --&amp;gt; FALSCH&lt;br /&gt;
  4&#039;b11xx == 4&#039;b11xx;    // = x --&amp;gt; FALSCH&lt;br /&gt;
  4&#039;b110z == 4&#039;b110z;    // = x --&amp;gt; FALSCH&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im gleichen Sinn werden größer oder kleiner Operationen immer FALSCH wenn ein x oder z Zustand vorhanden ist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  4&#039;b1100 &amp;gt; 4&#039;b11xx;      // = x --&amp;gt; FALSCH&lt;br /&gt;
  4&#039;b110z &amp;gt; 4&#039;b1100;      // = x --&amp;gt; FALSCH&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um einen exakten Vergleich durch zu führen gibt es den sogenannten case equality operator (===). Hier werden auch die Zustände x und z mit in den Vergleich einbezogen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  4&#039;b1100 === 4&#039;b1100;    // = 1 --&amp;gt; WAHR&lt;br /&gt;
  4&#039;b1100 === 4&#039;b11xx;    // = 0 --&amp;gt; FALSCH&lt;br /&gt;
  4&#039;b11xx === 4&#039;b11xx;    // = 1 --&amp;gt; WAHR&lt;br /&gt;
  4&#039;b110z === 4&#039;b110z;    // = 1 --&amp;gt; WAHR&lt;br /&gt;
  4&#039;b110x === 4&#039;b110z;    // = 0 --&amp;gt; FALSCH&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Logische Operationen ==&lt;br /&gt;
&lt;br /&gt;
Die im letzten Abschnitt beschriebenen Vergleichsoperationen können mit logischen Operationen verknüpft werden. Wie von den gängigen Programmiersprachen bekannt, unterstützt Verilog die logischen Operationen:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;&amp;amp;&amp;amp;&#039;&#039;&#039;  --&amp;gt; AND&lt;br /&gt;
* &#039;&#039;&#039;||&#039;&#039;&#039;  --&amp;gt; OR&lt;br /&gt;
* &#039;&#039;&#039;!&#039;&#039;&#039;   --&amp;gt; NOT&lt;br /&gt;
&lt;br /&gt;
== Entscheidungsoperation mit if-else und ? : ==&lt;br /&gt;
&lt;br /&gt;
Bisher haben wir nur die sequentielle Abarbeitung von Operationen besprochen. Oft ist es nötig, basierend auf Signalzustände verschiedene Blöcke abzuarbeiten. Der von Programmiersprachen bekannte &#039;&#039;if&#039;&#039; und &#039;&#039;else&#039;&#039; Konstrukt ist hierzu hilfreich und wird von Verilog unterstütz.&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird in Abhängigkeit von einem &#039;&#039;&#039;reset&#039;&#039;&#039; Signal entweder der eine oder der andere Anweisungsblock ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  if(reset)&lt;br /&gt;
    dout &amp;lt;= 0;&lt;br /&gt;
  else&lt;br /&gt;
    dout &amp;lt;= din;&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn in dem obigen Beispiel &#039;&#039;&#039;reset&#039;&#039;&#039; 1 ist, dann wird &#039;&#039;&#039;dout&#039;&#039;&#039; der Wert 0 zugewiesen. Ist &#039;&#039;&#039;reset&#039;&#039;&#039; 0 wird &#039;&#039;&#039;dout&#039;&#039;&#039; der Wert von &#039;&#039;&#039;din&#039;&#039;&#039; zugewiesen.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer Sprachkonstrukt der Form &#039;&#039;if-else&#039;&#039; ist der Entscheidungsoperator &#039;&#039;?:&#039;&#039;, der auch von der Programmiersprache C bekannt ist. Er wird benutzt in der Form &#039;&#039;&#039;Test ? Wert_WAHR : Wert_FALSCH&#039;&#039;&#039;. &#039;&#039;&#039;Test&#039;&#039;&#039; kann hier eine logische Operation sein und wenn diese WAHR ist, dann wird &#039;&#039;&#039;Wert_WAHR&#039;&#039;&#039; zurück gegeben, andernfalls wird &#039;&#039;&#039;Wert_FALSCH&#039;&#039;&#039; zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
Die Nutzung soll hier am Beispiel eines Multiplexers erläutert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 wire dout;&lt;br /&gt;
 wire d0, d1, sel;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 assign dout = sel ? d0 : d1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;wire&#039;&#039; nehmen wir einen &#039;&#039;assign&#039;&#039; Konstrukt und die Zuweisung an &#039;&#039;&#039;dout&#039;&#039;&#039; hängt jetzt von dem &#039;&#039;&#039;sel&#039;&#039;&#039; Signal ab. Ist es 1, wird &#039;&#039;&#039;dout&#039;&#039;&#039; der Wert von &#039;&#039;&#039;d0&#039;&#039;&#039; zugewiesen. Ist &#039;&#039;&#039;sel&#039;&#039;&#039; 0, wird &#039;&#039;&#039;dout&#039;&#039;&#039; der Wert von &#039;&#039;&#039;d1&#039;&#039;&#039; zugewiesen.&lt;br /&gt;
&lt;br /&gt;
== Mehrwegeentscheidung mit case ==&lt;br /&gt;
&lt;br /&gt;
Die Erweiterung der Entscheidungsoperation ist die Mehrwegeentscheidung, die mit &#039;&#039;case&#039;&#039; durchgeführt wird.&lt;br /&gt;
&lt;br /&gt;
Um das vorherige Beispiel mit dem Multiplexer zu erweitern:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  wire [1:0] sel;&lt;br /&gt;
  reg        dout;&lt;br /&gt;
  wire       d0, d1, d2, d3;&lt;br /&gt;
&lt;br /&gt;
  always@(*)&lt;br /&gt;
   case (sel)&lt;br /&gt;
     2&#039;b00: dout = d0;&lt;br /&gt;
     2&#039;b01: dout = d1;&lt;br /&gt;
     2&#039;b10: dout = d2;&lt;br /&gt;
     2&#039;b11: dout = d3;&lt;br /&gt;
   endcase&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier werden jetzt vier Eingangssignale in Abhängigkeit von &#039;&#039;sel&#039;&#039; auf den Ausgang gemultiplext.&lt;br /&gt;
&lt;br /&gt;
Manchmal ist die Entscheidungsliste größer und es müssen nicht immer alle Fälle behandelt werden. Dafür kann dann der &#039;&#039;default&#039;&#039; Konstrukt verwendet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  wire [1:0] sel;&lt;br /&gt;
  reg        dout;&lt;br /&gt;
  wire       d0, d1, d2, d3;&lt;br /&gt;
&lt;br /&gt;
  always@(*)&lt;br /&gt;
   case (sel)&lt;br /&gt;
     2&#039;b00:   dout = d0;&lt;br /&gt;
     2&#039;b01:   dout = d1;&lt;br /&gt;
     2&#039;b10:   dout = d2;&lt;br /&gt;
     default: dout = d3;&lt;br /&gt;
   endcase&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für alle nicht gelisteten Ereignisse wird jetzt die Zuweisung für den &#039;&#039;default&#039;&#039; Fall durchgeführt.&lt;br /&gt;
&lt;br /&gt;
== Schleifen mit for, while, und repeat ==&lt;br /&gt;
&lt;br /&gt;
Für die wiederholte Ausführung von Codesegmenten, bei denen eine Zählervariable nötig ist, stellte Verilog die &#039;&#039;for&#039;&#039;-Schleife zur Verfügung. Die einfache Anwendung erfolgt folgendermaßen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  integer i;&lt;br /&gt;
  reg [3:0] mem[0:63];&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  for(i=0; i&amp;lt;64; i=i+1)&lt;br /&gt;
    mem[i] = 4&#039;d0;&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In dem Beispiel wird allen Speicherplätzen von &#039;&#039;&#039;mem&#039;&#039;&#039; der Wert 0 zugewiesen. Neu ist hier der Datentype &#039;&#039;integer&#039;&#039; der für die Zähler variable genutzt wird und laut Definition 32 Bit groß ist.&lt;br /&gt;
&lt;br /&gt;
Für die wiederholte Ausführung von Codesegmenten bei denen keine Zählervariable nötig ist kann der &#039;&#039;repeat&#039;&#039; Konstrukt genutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  reg reset = 0;&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  repeat(2) begin&lt;br /&gt;
&lt;br /&gt;
    #10 reset = 1;&lt;br /&gt;
    #10 reset = 0;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird zehn Zeiteinheiten gewartet und dann &#039;&#039;&#039;reset&#039;&#039;&#039; auf 1 gesetzt. Anschließend wieder 10 Zeiteinheiten gewartet und &#039;&#039;&#039;reset&#039;&#039;&#039; auf 0 gesetzt. Das ganze zwei mal wiederholt, so das ein doppelter &#039;&#039;&#039;reset&#039;&#039;&#039; Impuls entsteht.&lt;br /&gt;
&lt;br /&gt;
Eine bedingte Schleife kann mit &#039;&#039;while&#039;&#039; ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  integer i;&lt;br /&gt;
&lt;br /&gt;
  while(i &amp;lt; 10) begin&lt;br /&gt;
    ...&lt;br /&gt;
    i = i + 1;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Schleifenkörper wird solange ausgeführt so lange die Bedingung WAHR ist.&lt;br /&gt;
&lt;br /&gt;
== Parametrisierung durch Konstanten mit &#039;&#039;parameter&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
Bisher haben wir konstante Werte immer direkt in den Code eingeführt. Um Konstante Werte einheitlich über ein größeres Design zu verändern ist es sinnvoll für den Parameter einen einheitlichen Namen zu wählen und den Wert nur an einer Stelle im Design zu zu weisen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  parameter DW = 8;&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
  reg [DW-1:0] data_bus;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hierarchie ==&lt;br /&gt;
&lt;br /&gt;
Um ein komplexeres Design zu kreieren ist die Instantiierung von Modulen sehr hilfreich. Nehmen wir das Modul &#039;&#039;module mux(input a, input b, input sel, ouput y)&#039;&#039;, ohne genauer auf dessen Innenleben einzugehen, und instantiieren es mehrmals in dem &#039;&#039;module top(...)&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module top (input a, &lt;br /&gt;
            input b, &lt;br /&gt;
            input c, &lt;br /&gt;
            input d,&lt;br /&gt;
            input s1,&lt;br /&gt;
            input s2,&lt;br /&gt;
            input s3,&lt;br /&gt;
            output y);&lt;br /&gt;
&lt;br /&gt;
  wire w1, w2;&lt;br /&gt;
&lt;br /&gt;
  mux m1 ( .a(a),  .b(b),  .sel(s1), .y(w1) );&lt;br /&gt;
  mux m2 ( .a(c),  .b(d),  .sel(s2), .y(w2) );&lt;br /&gt;
  mux m3 ( .a(w1), .b(w2), .sel(s3), .y(y)  );&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Verknüpfung findet statt durch die explizite Nennung der Ports. Der Port von dem instantiierten Modul wird in der Form &#039;&#039;&#039;.PortName()&#039;&#039;&#039; geschrieben. Das Signal mit dem er verknüpft wird schreibt man in die Klammern des Ports. Mit der Verknüpfung &#039;&#039;&#039;.y(w1)&#039;&#039;&#039; wird also der Ausgangsport &#039;&#039;&#039;y&#039;&#039;&#039; von der Instanz &#039;&#039;&#039;m1&#039;&#039;&#039; des Modules &#039;&#039;&#039;mux&#039;&#039;&#039; mit dem &#039;&#039;wire&#039;&#039; &#039;&#039;&#039;w1&#039;&#039;&#039; im Modul &#039;&#039;&#039;top&#039;&#039;&#039; verknüpft.&lt;br /&gt;
&lt;br /&gt;
Eine andere Variante der Verknüpfung wird durch die Position der Ports in der Definition des Modules erreicht. In unserem Fall ist Port a der erste Port, also wird der &#039;&#039;wire&#039;&#039; der an erste Stelle bei der Instantiierung geschrieben wird, mit Port a des Moduls verbunden. Das vorherige Beispiel wird in diesem Fall dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  mux m1 ( a,  b,  s1, w1 );&lt;br /&gt;
  mux m2 ( c,  d,  s2, w2 );&lt;br /&gt;
  mux m3 ( w1, w2, s3, y  );&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Vorteil ist, dass hier nicht noch explizit der Port des Modules genannte werden muss. Das wird jedoch schnell unübersichtlich mit Modulen, die eine lange Portliste haben.&lt;br /&gt;
&lt;br /&gt;
Die Instantiierung kann jetzt noch durch die Überladung von &#039;&#039;parameter&#039;&#039; erweitert werden. Nehmen wir das vorherige Beispiel und schauen uns das &#039;&#039;module&#039;&#039; &#039;&#039;&#039;mux&#039;&#039;&#039; etwas näher an.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module mux #(parameter DW=8)&lt;br /&gt;
            ( input [DW-1:0]  a, &lt;br /&gt;
              input [DW-1:0]  b, &lt;br /&gt;
              input           sel, &lt;br /&gt;
              output [DW-1:0] y);&lt;br /&gt;
&lt;br /&gt;
  assign y = sel ? a : b;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der &#039;&#039;module&#039;&#039; Definition wird jetzt noch eine Parameterliste vor die Portdefinition eingefügt, die mit dem Lattenzaun &#039;&#039;#&#039;&#039; gekennzeichnet ist. Dadurch ist es möglich die Parameter in der Portliste zu nutzen.&lt;br /&gt;
&lt;br /&gt;
Soll das Modul nun instantiiert werden kann die Parameterliste verändert und damit das instantiierte Modul angepasst werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
 &lt;br /&gt;
  parameter NeueDW=16;&lt;br /&gt;
&lt;br /&gt;
  wire [DW-1:0] w1;&lt;br /&gt;
  wire [DW-1:0] w2;&lt;br /&gt;
&lt;br /&gt;
  mux m1 #(.DW(NeueDW))( .a(a),  .b(b),  .sel(s1), .y(w1) );&lt;br /&gt;
  mux m2 #(.DW(NeueDW))( .a(c),  .b(d),  .sel(s2), .y(w2) );&lt;br /&gt;
  mux m3 #(.DW(NeueDW))( .a(w1), .b(w2), .sel(s3), .y(y)  );&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Parameterüberladung erfolgt wie bei der expliziten Portverknüpfung in der Form &#039;&#039;&#039;.ZielParameter(NeuerParameter)&#039;&#039;&#039;. Im obigen Beispiel werden nun also drei Multiplexer mit der neuen Datenbreite von 16 Bit instantiiert.&lt;br /&gt;
&lt;br /&gt;
= Verilog für Simulation =&lt;br /&gt;
&lt;br /&gt;
Soweit haben wir die Sprache in Anlehnung an eine Programmiersprache beschrieben. Dabei sind schon einige Sonderheiten wie die Vierwertigkeit von &#039;&#039;wire&#039;&#039; und &#039;&#039;reg&#039;&#039; oder die Ereignissteuerung durch &#039;&#039;@&#039;&#039; im Zusammenhang mit der parallelen Abarbeitung von &#039;&#039;always&#039;&#039;, bzw. &#039;&#039;initial&#039;&#039; Blöcken erschienen. Auch hatten wir die Verzögerungsoperation &#039;&#039;#&#039;&#039; klammheimlich eingeführt, ohne wirklich tiefer darauf einzugehen wie das ganze im Hintergrund funktioniert.&lt;br /&gt;
&lt;br /&gt;
Der grundlegende Unterschied zwischen einer Programmiersprache und einer Hardwarbeschreibungssprache ist, dass letztere ein Simulationsmodel zu Grunde liegt. In der Praxis sieht der Unterschied folgendermaßen aus. Bei einer kompilierten Programmiersprache wird der Quellcode durch den Compiler in ein ausführbares Programm umgesetzt, das dann auf dem Computer ausgeführt werden kann. Bei der Hardwarebeschreibungssprache wird der Quellcode in eine für einen Simulator ausführbares Format umgewandelt. Nach dem Kompilieren kann dies dann mit dem Simulator ausgeführt werden. Der Simulator arbeitet den übersetzten Quellcode in Zeitschritten ab. Dadurch kann die parallele Funktion von Hardware simuliert werden.&lt;br /&gt;
&lt;br /&gt;
In diesem Abschnitt werden jetzt Sprachkonstrukte beschrieben die nicht synthetisierbar sind und nur für die Verifikation im Zusammenhang mit einem Simulator sinnvoll sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== System Tasks und Functions ==&lt;br /&gt;
&lt;br /&gt;
System Tasks und Functions sind ein Weg einen Verilog Simulator mit Funktionen zu erweitern. In diesem Abschnitt werden einige gängige System Tasks beschrieben die im Verilog Standard spezifiziert sind und somit in allen bekannten Simulatoren implementiert sind.&lt;br /&gt;
&lt;br /&gt;
System Tasks und Functions beginnen immer mit einem Dollarzeichen ($) und werden in der Regel von Synthesis-Tools ignoriert.&lt;br /&gt;
&lt;br /&gt;
=== $display ===&lt;br /&gt;
&lt;br /&gt;
Der $display Task wird verwendet um Informationen zum stdout zu schreiben. Die Form der Benutzung ist sehr an die printf() Funktion von C angelehnt. Ein wesentlicher Unterschied ist, dass mit der $display Funktion automatisch ein Zeilenvorschub angehängt wird und so kein extra &amp;quot;\n&amp;quot; am Ende des Strings gesetzt werden muss.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt; &lt;br /&gt;
  integer i;&lt;br /&gt;
  ...&lt;br /&gt;
  i = 10;&lt;br /&gt;
  $display(&amp;quot;Hallo Welt Nr. %d&amp;quot;, i);&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Task ausgeführt wird, ersetzt der Simulator %d mit dem Wert von i. Die Darstellung kann unterschiedlich formatiert werden und es gibt folgende Formatierungsbefehle:&lt;br /&gt;
&lt;br /&gt;
*%d - dezimal&lt;br /&gt;
*%h - hexadezimal&lt;br /&gt;
*%b - binär&lt;br /&gt;
*%o - oktal&lt;br /&gt;
*%s - string&lt;br /&gt;
*%c - ASCII Zeichen&lt;br /&gt;
*%v - Signalstärke&lt;br /&gt;
*%m - Hierarchischer Name&lt;br /&gt;
&lt;br /&gt;
Einen zusätzlichen Zeilenvorschub erhält man durch \n, Tab z.B. durch \t.&lt;br /&gt;
&lt;br /&gt;
Ein weitere Unterschied zu printf ist, dass mit $display die Zahlen rechtsbündig ausgerichtet werden. In manchen Fälle mag das nicht erwünscht sein und so besteht die Möglichkeit den Formatierungsbefehl %d z.B. in der Form %0d zu schreiben. Jetzt wird die Zahl linksbündig ausgerichtet.&lt;br /&gt;
&lt;br /&gt;
Am Beispiel eines integer Datentyp sei das verdeutlicht:&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
  integer i;&lt;br /&gt;
  ...&lt;br /&gt;
  $display(&amp;quot;Hallo Welt Nr. %d&amp;quot;, i);&lt;br /&gt;
  $display(&amp;quot;Hallo Welt Nr. %0d&amp;quot;, i);&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im ersten Fall werden so viele Leerzeichen nach dem Wort &#039;Nr.&#039; eingefügt, damit die Zahl rechtsbündig dargestellt wird. Mit der %0d Version wird die Zahl linksbündig dargestellt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
Hallo Welt Nr.          10&lt;br /&gt;
Hallo Welt Nr. 10&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die linksbündige Darstellung wird von den Formatierungsbefehlen %d, %o, und %h unterstützt.&lt;br /&gt;
&lt;br /&gt;
=== $monitor ===&lt;br /&gt;
&lt;br /&gt;
Ähnlich dem $display Task schreibt der $monitor Task den Text zum stdout. Einziger Unterschied ist, dass der Task automatisch überprüft ob eines der Signal sich geändert hat und jedes mal bei einer Änderung einen neuen Ausdruck durchführt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wird das folgende Beispiel simuliert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module monitor_tb;&lt;br /&gt;
&lt;br /&gt;
 reg clk    = 0;&lt;br /&gt;
 reg reset  = 0;&lt;br /&gt;
&lt;br /&gt;
 initial&lt;br /&gt;
   $monitor(&amp;quot;Zeit: %t Takt: %b reset: %b&amp;quot;, $time, clk, reset);&lt;br /&gt;
&lt;br /&gt;
 always&lt;br /&gt;
   #10 clk =~clk;&lt;br /&gt;
&lt;br /&gt;
 initial begin&lt;br /&gt;
   $display(&amp;quot;Kleiner $monitor test&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   #15 reset = 1;&lt;br /&gt;
   #22 reset = 0;&lt;br /&gt;
&lt;br /&gt;
   #10 $display(&amp;quot;#%0t Fertig&amp;quot;, $time);&lt;br /&gt;
   $finish;&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Erhält man folgenden Ausdruck:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
Kleiner $monitor test&lt;br /&gt;
Zeit:                    0 Takt: 0 reset: 0&lt;br /&gt;
Zeit:                   10 Takt: 1 reset: 0&lt;br /&gt;
Zeit:                   15 Takt: 1 reset: 1&lt;br /&gt;
Zeit:                   20 Takt: 0 reset: 1&lt;br /&gt;
Zeit:                   30 Takt: 1 reset: 1&lt;br /&gt;
Zeit:                   37 Takt: 1 reset: 0&lt;br /&gt;
Zeit:                   40 Takt: 0 reset: 0&lt;br /&gt;
#47 Fertig&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt 0 wird der &#039;&#039;$display&#039;&#039; Task ausgeführt und druckt den Text &#039;&#039;&#039;&amp;quot;Kleiner $monitor test&amp;quot;&#039;&#039;&#039; aus. Alle Signale sind zu dem Zeitpunkt auf 0 und der &#039;&#039;$monitor&#039;&#039; Task druckt zum ersten mal den Signalzustand aus.&lt;br /&gt;
&lt;br /&gt;
Der nächste Aufruf erfolgt wenn clk nach 10 Zeiteinheiten seinen Zustand wechselt. Dieser Wechsel wird autonom in dem &#039;&#039;always&#039;&#039; Block alle 10 Zeiteinheiten durchgeführt. Parallel dazu wird in dem &#039;&#039;initial&#039;&#039; Block nach 15 Zeiteinheiten der reset auf 1 gesetzt. Dazwischen kommt wieder der Wechsel von clk, der um 20 auf 0 und um 30 wieder auf 1 gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Im &#039;&#039;initial&#039;&#039; Block wird reset 22 Zeiteinheiten nach dem Setzen wieder zurück gesetzt. Das Setzen fand um 15 statt, plus 22 Zeiteinheiten, somit wird reset um 37 zurück gesetzt. Dann folgt noch mal ein clk Wechsel, bevor die Simulation um 47 beendet wird. Zu der Zeit findet kein Signalwechsel mehr statt, so das der &#039;&#039;$monitor&#039;&#039; Task nicht mehr aufgerufen wird. So haben wir vor dem &#039;&#039;$finish&#039;&#039; Task noch mal einen &#039;&#039;$display&#039;&#039; Task gesetzt, der die Zeit mit dem Wort &#039;&#039;&#039;&amp;quot;Fertig&amp;quot;&#039;&#039;&#039; ausdruckt.&lt;br /&gt;
&lt;br /&gt;
=== $finish ===&lt;br /&gt;
&lt;br /&gt;
Beendet die Simulation. Jede Testbench sollte einen $finish System Task haben um die Simulation zu beenden.&lt;br /&gt;
&lt;br /&gt;
=== $dumpfile, $dumpvars ===&lt;br /&gt;
&lt;br /&gt;
Ein Value Change Dump (VCD) Files ist ein text basiertes File in dem Signalzustandsänderungen von der Simulation geschrieben werden. Die Datei kann dann z.B. von einem Programm eingelesen und dargestellt werden. Ein solches Programm ist z.B. [http://home.nc.rr.com/gtkwave/ gtkwave].&lt;br /&gt;
&lt;br /&gt;
Der Simulator generiert in der Regel so ein VCD File nicht von selbst, sondern muss dazu instruiert werden. Eine Form die von Simulatoren unterstützt wird ist durch die beiden Verilog System Tasks &#039;&#039;$dumpfile&#039;&#039; und &#039;&#039;$dumvars&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module top_tb;&lt;br /&gt;
&lt;br /&gt;
  initial begin&lt;br /&gt;
    $dumpfile(&amp;quot;top_tb.vcd&amp;quot;);&lt;br /&gt;
    $dumpvars(0, top_tb);&lt;br /&gt;
  end&lt;br /&gt;
  ...&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;$dumpfile(&amp;quot;top_tb.vcd&amp;quot;)&#039;&#039; wird der Dateiname des VCD Files spezifiziert. Gerade bei der Simulation von großen Designs ist es sinnvoll die Anzahl der Signale die in das Dumpfile geschrieben werden zu beschränken. Der &#039;&#039;$dumpvars&#039;&#039; System Task erlaubt dazu die Hierarchieebene mit zu spezifizieren. Mit dem Befehl &#039;&#039;$dumpvars(0, top_tb)&#039;&#039; werden alle Signale von der spezifizierten Ebene an nach unten in das Dumpfile geschrieben. Sollen z.B. nur die Signale in top_tb in das Dumpfile geschrieben werden, dann kann dies mit der Ebene 1, also &#039;&#039;$dumpvars(1, top_tb)&#039;&#039; beschränkt werden.&lt;br /&gt;
&lt;br /&gt;
== Zeit in der Simulation ==&lt;br /&gt;
&lt;br /&gt;
Wenn wir im Zusammenhang mit der Simulation von Zeit gesprochen haben, dann bisher nur von Zeiteinheiten. Der Simulator arbeitet mit Simulationsschritte, die erst mal dimensionslos sind. Um dem Verzögerungsoperator eine Dimension zu geben stellt Verilog die &#039;&#039;`timescale&#039;&#039; Anweisung zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
&#039;&#039;`timescale&#039;&#039; 10ns / 1ns&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Zahl bestimmt die Einheit für den Verzögerungsoperator. Die zweite Zahl die Auflösung mit der die Simulation durchgeführt wird. Beide Zahlen werden als Integer angegeben und können die Werte 1, 10, oder 100 haben.&lt;br /&gt;
&lt;br /&gt;
Als Zeiteinheiten werden die folgenden Werte unterstütz:&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Zeiteinheit&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Abkürzung&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Sekunden&lt;br /&gt;
|s&lt;br /&gt;
|-&lt;br /&gt;
|Millisekunden&lt;br /&gt;
|ms&lt;br /&gt;
|-&lt;br /&gt;
|Microsekunden&lt;br /&gt;
|us&lt;br /&gt;
|-&lt;br /&gt;
|Nanosekunden&lt;br /&gt;
|ns&lt;br /&gt;
|-&lt;br /&gt;
|Picosekunden&lt;br /&gt;
|ps&lt;br /&gt;
|-&lt;br /&gt;
|Femtosekunden&lt;br /&gt;
|fs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll die Nutzung von &#039;&#039;`timescale&#039;&#039; verdeutlichen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module test;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
&lt;br /&gt;
  $display(&amp;quot;%t Start um 0&amp;quot;, $time);&lt;br /&gt;
&lt;br /&gt;
  #10 $display(&amp;quot;%t Nach 10 Zeiteinheiten&amp;quot;, $time);&lt;br /&gt;
&lt;br /&gt;
  $finish();&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn wir den obigen Quellcode in eine Datei time.v packen und dann mit Icarus Verilog simulieren, erhalten wir folgenden Ausdruck:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&amp;gt;iverilog -o time.vvp time.v&lt;br /&gt;
&amp;gt;vvp time.vvp&lt;br /&gt;
                   0 Start um 0&lt;br /&gt;
                  10 Nach 10 Zeiteinheiten&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Verzögerungsoperation von 10 Zeiteinheiten wird direkt umgesetzt. D.h., nach einer Verzögerung von 10 sind auch 10 Simulationsschritte ausgeführt worden.&lt;br /&gt;
&lt;br /&gt;
Wenn wir jetzt die Zeitskala verändern, z.B. nach &#039;&#039;&#039;`timescale 10ns/1ns&#039;&#039;&#039; indem wir den Code wie folgt ändern:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
`timescale 10ns/1ns&lt;br /&gt;
&lt;br /&gt;
module test;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
&lt;br /&gt;
  $display(&amp;quot;%t Start um 0&amp;quot;, $time);&lt;br /&gt;
&lt;br /&gt;
  #10 $display(&amp;quot;%t Nach 10 Zeiteinheiten&amp;quot;, $time);&lt;br /&gt;
&lt;br /&gt;
  $finish();&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So erhalten wir mit der Simulation folgende Ausgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&amp;gt;iverilog -o time.vvp time.v&lt;br /&gt;
&amp;gt;vvp time.vvp&lt;br /&gt;
                   0 Start um 0&lt;br /&gt;
                 100 Nach 10 Zeiteinheiten&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Zeiteinheit entspricht jetzt 10ns und entsprechend wartet die Simulation jetzt 100ns bevor die zweite &#039;&#039;$display&#039;&#039;-Anweisung ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
Die Präzision gibt nun an, mit welcher Genauigkeit die Verzögerungsoperation erfolgt. Bisher haben wir ganzzahlige Werte verwendet. Für die Verzögerungsoperation können aber auch reale Zahlen verwendet werden. Die Simulationszeit wird errechnet, indem der Wert des Verzögerungsoperators mit der Zeiteinheit multipliziert wird und dann, basierend auf der spezifizierten Präzision gerundet wird.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;Zeiteinheit /&amp;lt;br&amp;gt; Präzision &#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;Verzögerungswert&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;Verzögerungszeit&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|10ns/1ns&lt;br /&gt;
|#3&lt;br /&gt;
|30ns&lt;br /&gt;
|-&lt;br /&gt;
|10ns/1ns&lt;br /&gt;
|#3.345&lt;br /&gt;
|33ns&lt;br /&gt;
|-&lt;br /&gt;
|10ns/100ps&lt;br /&gt;
|#3.345&lt;br /&gt;
|33.5ns&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Funktionsaufrufe mit function und task ==&lt;br /&gt;
&lt;br /&gt;
Analog zu Funktionen und Prozeduren in der Software-Programmierung stellt Verilog &#039;&#039;function&#039;&#039; und &#039;&#039;task&#039;&#039; zur Verfügung um komplexere Systeme in kleiner Einheiten aufzuteilen. Zu beachten ist das Verilog schon den &#039;&#039;module&#039;&#039;-Konstrukt für die Aufteilung hat. Aufrufe von &#039;&#039;function&#039;&#039; und &#039;&#039;task&#039;&#039; können im Rahmen von &#039;&#039;initial&#039;&#039;-, bzw. &#039;&#039;always&#039;&#039;-Blöcken in &#039;&#039;module&#039;&#039;-Blöcken eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei wesentliche Unterschiede bei der Verwendung von &#039;&#039;function&#039;&#039; und &#039;&#039;task&#039;&#039; im Zusammenhang mit der Simulation:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;function&#039;&#039;&lt;br /&gt;
* der Aufruf liefert einen Rückgabewert&lt;br /&gt;
* es können keine Zeit- oder Ereignissteuerungen (#, @ und wait) eingesetzt werden&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;task&#039;&#039;&lt;br /&gt;
* der Aufruf liefert keinen Rückgabewert&lt;br /&gt;
* es können Zeit- oder Ereignissteuerungen eingesetzt werden&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parallele Prozesse mit join/fork ==&lt;br /&gt;
&lt;br /&gt;
= Synthetisierbare Konstrukte =&lt;br /&gt;
&lt;br /&gt;
== Kombinatorische Logik ==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt einen 2:1 Multiplexer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module Mein2zu1Mux ( input [3:0] d0, d1,&lt;br /&gt;
                     input       sel,&lt;br /&gt;
                     output      y);&lt;br /&gt;
&lt;br /&gt;
  assign y = sel ? d1 : d0;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein neuer Operator der hier vorgestellt wird ist der Entscheidungsoperator (?:), im Englischen als conditional operator bezeichnet. Für bedingte Zuweisungen kann er an Stelle von der &#039;&#039;if&#039;&#039; oder &#039;&#039;case&#039;&#039; Anweisung verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Dem Signal y wird in Abhängigkeit von sel entweder d1 oder d0 zugewiesen. Ist sel wahr wird d1 zugewiesen, ist es falsch wird d0 zugewiesen.&lt;br /&gt;
&lt;br /&gt;
Natürlich kann der Operator auch verschachtelt werden, irgendwann macht das aber keine Sinn mehr und wird unübersichtlich. Der Entscheidungsoperator kann dann durch ein &#039;&#039;case&#039;&#039; Anweisung ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module mux ( input sel,&lt;br /&gt;
             input d0,&lt;br /&gt;
             input d1,&lt;br /&gt;
             input d2,&lt;br /&gt;
             input d3,&lt;br /&gt;
             output y);&lt;br /&gt;
  &lt;br /&gt;
  always @(*)&lt;br /&gt;
    case (sel)&lt;br /&gt;
      2&#039;b00: y = d0;&lt;br /&gt;
      2&#039;b01: y = d1;&lt;br /&gt;
      2&#039;b10: y = d2;&lt;br /&gt;
      2&#039;b11: y = d3;&lt;br /&gt;
    endcase&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Getreu der Empfehlung für die Zuweisung kombinatorischer Logik wurde hier die blockierende Zuweisung verwendet.&lt;br /&gt;
&lt;br /&gt;
In Bezug auf die Synthese ist zu beachten, dass alle Kombinationen von sel in der case-Anweisung enthalten sein müssen, sonst ist es möglich das durch die Synthese ein Latch entsteht. Näheres kann dazu im Synthesis User&#039;s Guide des jeweiligen FPGA Herstellers gefunden werden.&lt;br /&gt;
&lt;br /&gt;
== Sequentielle Logik ==&lt;br /&gt;
&lt;br /&gt;
Analog zum VHDL &#039;&#039;process&#039;&#039; wird in Verilog die &#039;&#039;always&#039;&#039; Anweisung verwendet. Ein einfaches Register synchron zur steigenden Flanke des Taktsignals wird wie folgt beschrieben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module Flop (input            clk,&lt;br /&gt;
             input [3:0]      d,&lt;br /&gt;
             output reg [3:0] q);&lt;br /&gt;
&lt;br /&gt;
  always @ (posedge clk)&lt;br /&gt;
    q &amp;lt;= d;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analog zur steigenden flanke kann auch auf die fallende Flanke mit &#039;&#039;negedge&#039;&#039; getriggert werden.&lt;br /&gt;
&lt;br /&gt;
= Open-Source Simulatoren =&lt;br /&gt;
&lt;br /&gt;
Für Verilog gibt es die folgenden Simulatoren als Open-Source:&lt;br /&gt;
&lt;br /&gt;
*[http://icarus.com/eda/verilog/ Icarus Verilog]&lt;br /&gt;
*[http://www.pragmatic-c.com/gpl-cver/ CVER]&lt;br /&gt;
&lt;br /&gt;
Im folgenden wird etwas näher auf die Nutzung mit Icarus Verilog eingegangen.&lt;br /&gt;
&lt;br /&gt;
== Icarus Verilog ==&lt;br /&gt;
&lt;br /&gt;
Icarus Verilog ist eine Simulations- und Synthese-Software für Verilog. Bei der Software handelt es sich um eine Kommandozeilen-basierte Applikationen. In diesem Abschnitt werden wir uns auf die Funktion als Simulator beschränken.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ist verteilt auf die zwei Applikationen:&lt;br /&gt;
&lt;br /&gt;
* iverilog  (Compiler)&lt;br /&gt;
* vvp       (Simulator)&lt;br /&gt;
&lt;br /&gt;
Basierend auf dem Beispiel von der [http://iverilog.wikia.com/wiki/Getting_Started  Icarus Verilog Dokumentation] nehmen wir das &amp;quot;Hallo Welt&amp;quot; Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
module main;&lt;br /&gt;
  initial &lt;br /&gt;
    begin&lt;br /&gt;
      $display(&amp;quot;Hallo, Welt&amp;quot;);&lt;br /&gt;
      $finish;&lt;br /&gt;
    end&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Kompilieren wird das Kommando &#039;&#039;iverilog&#039;&#039; verwendet. Mit dem -o Parameter spezifiziert man den Namen der Ausgabedatei.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&amp;gt; iverilog -o main.vvp main.v&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der kompilierte Quellcode wird dann mit der Applikation &#039;&#039;vvp&#039;&#039; simuliert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&amp;gt; vvp main.vvp&lt;br /&gt;
Hallo Welt&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für größere Projekte ist ein sinnvoller Einsatz den Aufruf durch ein Makefile auszuführen. Im Mai 2008 hat Larry Doolittle auf der gEDA users mailing list ein Makefile zur Verfügung gestellt, das hier folgend beschrieben werden soll.&lt;br /&gt;
&lt;br /&gt;
Das &#039;&#039;&#039;Makefile&#039;&#039;&#039; besteht aus einem allgemeinen Teil der sich nicht ändert und einem projektspezifischen Teil in dem die Abhängigkeiten für das spezielle Projekt festgelegt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Hier werden die Abhängigkeiten festgelegt&lt;br /&gt;
#&lt;br /&gt;
foo_tb: foo.v bar.v&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#####################################################################&lt;br /&gt;
# Allgemeiner Teil der sich nicht ändert&lt;br /&gt;
#&lt;br /&gt;
%_tb: %_tb.v&lt;br /&gt;
	iverilog -Wall -DSIMULATE ${VFLAGS_$@} $^ -o $@&lt;br /&gt;
#&lt;br /&gt;
# Generic regression test&lt;br /&gt;
%_check: %_tb testcode.awk&lt;br /&gt;
	vvp $&amp;lt;&lt;br /&gt;
#&lt;br /&gt;
%.vcd: %_tb&lt;br /&gt;
	vvp $&amp;lt;&lt;br /&gt;
#&lt;br /&gt;
# Useful for those testbenches that have a corresponding .sav file&lt;br /&gt;
%_view: %.vcd %.sav&lt;br /&gt;
	gtkwave $^&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *_tb *.vcd&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel ist eine Datei &#039;&#039;&#039;foo.v&#039;&#039;&#039; vorhanden die ein Modul von &#039;&#039;&#039;bar.v&#039;&#039;&#039; instantiiert. Die Testbench ist in der Datei &#039;&#039;&#039;foo_tb.v&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Das Projekt wird compiliert und simuliert mit dem Kommando:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&amp;gt; make foo_check&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vorausgesetzt das [http://home.nc.rr.com/gtkwave/ gtkwave] installiert ist, kann im Zusammenhang mit einem generierten &#039;&#039;&#039;foo.vcd&#039;&#039;&#039;-Dumpfile und einem &#039;&#039;&#039;foo.sav&#039;&#039;&#039;-File dieses mit folgendem Kommando aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&amp;gt; make foo_view&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &#039;&#039;&#039;foo.vcd&#039;&#039;&#039;-Dumpfile erhält man durch folgenden Konstrukt in der Testbench:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verilog&amp;gt;&lt;br /&gt;
 initial begin&lt;br /&gt;
   $dumpfile(&amp;quot;foo.vcd&amp;quot;);&lt;br /&gt;
   $dumpvars (0, foo_tb);&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/verilog&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zu diesem Aufruf des Makefiles sei noch folgende Anmerkung gemacht. Der normale Aufruf von &#039;&#039;&#039;foo.vcd&#039;&#039;&#039; mit gtkwave erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&amp;gt; gtkwave foo.vcd&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Kommando hätte keinen Vorteil gegenüber &#039;&#039;&#039;make foo_view&#039;&#039;&#039;. Mit gtkwave ist es nun möglich ein sogenanntes .sav-File zu kreieren, in dem abgespeichert wird, welche Signale in der Anzeige gerade angezeigt werden. Startet man gtkwave mit diesem .sav-File bzw. lädt es später nach, wird die Anzeige wieder so dargestellt wie zu dem Zeitpunkt wenn das .sav-File erstellt wurde. Wird gtkwave nur mit einem .vcd-File gestartet, ist die Anzeige immer leer und die Signale müssen erst in die Anzeige gebracht werden. Wenn eine .sav-Datei vorhanden ist, dann muss gtkwave wie folgt aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&amp;gt; gtkwave foo.vcd foo.sav&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Behält man nun diese Datei als Teil des Projektes, ist es möglich beim nächsten mal mit &#039;&#039;&#039;make foo_view&#039;&#039;&#039; die gleiche Ansicht wieder zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Das ursprüngliche Makefile von Larry Doolittle hatte noch einen Test mit [http://de.wikipedia.org/wiki/Awk awk], der das Testergebnis an das Makefile zurück gibt. Den Test habe ich herausgenommen, da der Aufwand meines Erachtens größer als der Nutzen war.&lt;br /&gt;
&lt;br /&gt;
= Referenz =&lt;br /&gt;
&lt;br /&gt;
== Bücher ==&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;The Verilog Hardware Description Language&amp;quot;, Thomas &amp;amp; Moorby, Kluwer Academic Publisher&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.asic-world.com/verilog/index.html ASIC World Verilog Tutorial]&lt;br /&gt;
*[http://www.sunburst-design.com Cliff Cummings Verilog &amp;amp; System Verilog Seite]&lt;br /&gt;
**[http://www.sunburst-design.com/papers/ Veröffentlichungen von Cliff Cummings]&lt;br /&gt;
&lt;br /&gt;
*[http://www.sutherland-hdl.com/ Sutherland HDL]&lt;br /&gt;
** [http://sutherland-hdl.com/online_verilog_ref_guide/verilog_2001_ref_guide.pdf Verilog 2001 Referenz als PDF]&lt;br /&gt;
** [http://www.sutherland-hdl.com/papers-by-sutherland.php Veröffentlichungen von Stuart Sutherland]&lt;br /&gt;
*[http://doolittle.icarus.com/~larry/vhd2vl/ VHDL to Verilog Konverter] unter Linux, Programme FLEX und Gnu-Bison müssen installiert sein&lt;br /&gt;
[[Category:FPGA und Co]]&lt;/div&gt;</summary>
		<author><name>Blackhat-blade</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Wer_hat_was&amp;diff=40231</id>
		<title>Wer hat was</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Wer_hat_was&amp;diff=40231"/>
		<updated>2009-10-27T20:58:01Z</updated>

		<summary type="html">&lt;p&gt;Blackhat-blade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wer hat was und wo? :)&lt;br /&gt;
http://www.mikrocontroller.net/topic/155083&lt;br /&gt;
Erstmal sollen sich hier nur Mitmachwillige ihren Wohnort aufschreiben, um zu sehen ob die Sache lohnt. Also fang ich an:&lt;br /&gt;
&lt;br /&gt;
*volatile, Oldenburg, AVRs, RC 0805 und 0603 usw usw bla&lt;br /&gt;
*deadbuglabs, Nürnberg, Atmega: m8, m328P, m168, m32, RC bedrahtet + SMD&lt;br /&gt;
*blackhat-blade, Karlsruhe: Widerstände THT (E12 ~1R - 1M), AVRs, Trafos, 1Nxxx Dioden, diverses&lt;/div&gt;</summary>
		<author><name>Blackhat-blade</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=40054</id>
		<title>Entprellung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=40054"/>
		<updated>2009-10-19T18:03:52Z</updated>

		<summary type="html">&lt;p&gt;Blackhat-blade: typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mechanische Schalter prellen beim Ein- und Ausschalten, d.h sie schalten schnell aus und ein, verursacht durch mechanisches Vibrationen des Schaltkontaktes. Vereinfacht dargestellt sieht eine von einem Schalter oder Taster geschaltete Spannung beim Schalten wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Entprellen.png]]&lt;br /&gt;
&lt;br /&gt;
Für die Auswertung dieses unsauberen Signals gibt es verschiedene Ansätze:&lt;br /&gt;
&lt;br /&gt;
== Hardwareentprellung ==&lt;br /&gt;
&lt;br /&gt;
===Wechselschalter===&lt;br /&gt;
&lt;br /&gt;
Für die Entprellung von Wechselschaltern (engl. Double Throw Switch) kann ein klassisches RS-[[FlipFlop]] genutzt werden. Bei dieser Variante werden neben zwei NAND-Gattern nur noch zwei Pull-Up Widerstände benötigt.&lt;br /&gt;
&lt;br /&gt;
[[Bild:NAND_debouncer.png|framed|left|&#039;&#039;&#039;Taster entprellen mit NAND-RS-FlipFlop&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der gezeigten Schalterstellung liegt an der Position /S der Pegel 0 an. Damit ist das FlipFlop gesetzt und der Ausgang auf dem Pegel 1. Schließt der Schalter zwischen den Kontakten 2 und 3, liegt an der Postion /R der Pegel 0 an. Dies bedeutet das der Ausgang des FlipFlops auf den Pegel 0 geht. Sobald der Schalter von einem zum anderen Kontakt wechselt beginnt er in der Regel zu prellen. Während des Prellens wechselt der Schalter zwischen den beiden Zuständen &amp;quot;Schalter berührt Kontakt&amp;quot; und &amp;quot;Schalter ist frei in der Luft&amp;quot;. Der Ausgang des FlipFlop bleibt in dieser Prellzeit aber stabil, da der Schalter während des Prellens nie den gegenüberliegenden Kontakt berührt und das RS-FlipFlop seinen Zustand allein halten kann. Die Prellzeit ist stark vom Schaltertyp abhängig und liegt zwischen 0,1..10ms. Die Dimensionierung der Widerstände ist relativ unkritisch. Als Richtwert können hier 100k Ohm verwendet werden.&lt;br /&gt;
&lt;br /&gt;
===Einfacher Taster===&lt;br /&gt;
&lt;br /&gt;
Auch wenn das RS-FlipFlop sehr effektiv ist, wird diese Variante der Entprellung nur selten angewendet. Grund dafür ist, dass in Schaltungen häufiger einfache Taster eingesetzt werden. Diese sind oft kleiner und preisgünstiger. Um einfache Taster (engl. Single Throw Switch) zu entprellen kann ein einfacher RC-Tiefpass eingesetzt werden. Hierbei wird ein Kondensator über einen Widerstand je nach Schalterstellung auf- oder entladen. Das RC-Glied bildet einen Tiefpass, sodass die Spannung über den Kondensator nicht von einen Pegel auf den anderen springen kann.&lt;br /&gt;
&lt;br /&gt;
[[Bild:RC_debouncer.png|framed|left|&#039;&#039;&#039;Taster entprellen mit RC-Entpreller&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Schalter geöffnet ist, lädt sich der Kondensator langsam über die beiden Widerstände R&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; auf V&amp;lt;sub&amp;gt;cc&amp;lt;/sub&amp;gt; auf. Beim Erreichen der Umschaltschwelle springt der Ausgang auf den Pegel 0. Wird der Schalter geschlossen, entlädt sich der Kondensator langsam über den Widerstand R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;. Demnach ändert sich der Ausgang des Inverters auf den Pegel 1. Während der Taster prellt kann sich die Spannung über dem Kondensator nicht sprunghaft ändern, da das Auf- und Entladen eher langsam über die Widerstände erfolgt. Ausserdem sind die Schaltschwellen für den Übergang LOW-&amp;gt;HIGH und HIGH-&amp;gt;LOW stark verschieden (Hysterese, siehe Artikel [[Schmitt-Trigger]]). Bei richtiger Dimensionierung der Bauelemente wird somit erreicht, dass der Ausgang des Inverters prellfrei wird.&lt;br /&gt;
&lt;br /&gt;
Zu beachten ist, dass der Inverter &#039;&#039;&#039;unbedingt&#039;&#039;&#039; einer mit [[Schmitt-Trigger]] Eingängen sein muss. Standard Logikeingänge haben am Eingang einen Bereich (üblicherweise 0,8V-2,0V), in dem der Ausgang nicht definiert ist. Da die meisten Eingänge von digitalen Schaltungen keine Schmitt-Trigger Eingänge haben, ist dieser unbedingt erforderlich. Als Inverter kann zum Beispiel der 74HC14 eingesetzt werden. Alternativ kann auch ein CD4093 eingesetzt werden. Hierbei handelt es sich um NAND-Gatter mit Schmitt-Trigger Eingängen. Um aus einem NAND-Gatter einen Inverter zu machen, müssen einfach nur die beiden Eingänge verbunden werden oder ein Eingang fest auf HIGH gelegt werden.&lt;br /&gt;
&lt;br /&gt;
Um eine geeignete Dimensionierung zu erhalten, müssen wir etwas mit den Standardformeln für einen Kondensator jonglieren. Die Spannung über den Kondensator beim Entladen berechnet sich nach:&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t) = U_0 \cdot e^{\frac{-t}{R_2 C_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit der Ausgang des Inverters stabil ist, muss die Spannung über den Kondensator und damit die Spannung am Eingang des Inverters, über der Spannungs bleiben, bei welcher der Inverter umschaltet. Diese Schwellwertspannung ist genau die zeitabhängige Spannung über den Kondensator.&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t)\!\ = U_{th}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Umstellen der Formel ergibt sich nun:&lt;br /&gt;
:&amp;lt;math&amp;gt;R_2=\frac{-t}{C_1 \cdot ln\left(\frac{U_{th}}{U_0} \right)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Taster prellt üblicherweise etwa 10ms. Zur Sicherheit kann bei der Berechnung der Widerstandes eine Prellzeit von 20ms angenommen werden. U_0 ist die Betriebsspannung also Vcc. Die Schwellwertspannung muss aus dem Datenblatt des eingesetzten Schmitt-Triggers abgelesen werden. Für den 74HC14 lassen sich 2,0V aus dem Datenblatt ablesen. Nimmt man für den Kondensator einen mit einer Kapazität von 1µF und eine Betriebsspannung von 5V ergibt sich für den Widerstand der Wert etwa 22kOhm.&lt;br /&gt;
&lt;br /&gt;
Wird der Schalter geöffnet lädt sich der Kondensator nach folgender Formel:&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t) = U_0 \cdot \left( 1-e^{\frac{-t}{(R_1+R_2)\cdot C_1}} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit U_th=U_C ergibt das Umstellen nach (R_1+R_2):&lt;br /&gt;
:&amp;lt;math&amp;gt;R_1+R_2 = \frac{-t}{C_1 \cdot ln\left(1-\frac{U_{th}}{U_0} \right)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die Schwellspannung lässt sich aus dem Datenblatt von 2,3V ablesen. Mit diesem Wert und den Annahmen von oben ergibt sich für R_1+R_2 der Wert 32kOhm. Somit ergibt sich für R_1 ein Wert von etwa 10kOhm.&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Beim 74LS14 von Hitachi z.B. sind die oberen und unteren Schaltschwellwerte unterschiedlich. Es muss darauf geachtet werden, dass U_{th} beim Endladen die untere Schwelle und U_{th} beim Laden die obere Schwelle einnimmt.&lt;br /&gt;
&lt;br /&gt;
== Softwareentprellung ==&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung eines Mikrocontrollers kann man sich die zusätzliche Hardware sparen, da die Entprellung genau so gut in Software funktioniert. Dabei ist zu beachten, dass zusätzliche Rechenleistung und je nach Umsetzung auch Hardwareressourcen benötigt werden (z. B. Timer).&lt;br /&gt;
&lt;br /&gt;
=== Flankenerkennung ===   &lt;br /&gt;
Bei einem Taster gibt es insgesamt 4 Zustände:   &lt;br /&gt;
&lt;br /&gt;
* 1. war nicht gedrückt und ist nicht gedrückt   &lt;br /&gt;
* 2. war nicht gedrückt und ist gedrückt (steigende Flanke)   &lt;br /&gt;
* 3. war gedrückt und ist immer noch gedrückt   &lt;br /&gt;
* 4. war gedrückt und ist nicht mehr gedrückt (fallende Flanke)   &lt;br /&gt;
    &lt;br /&gt;
Diese einzelnen Zustände lassen sich jetzt bequem abfragen/durchlaufen. Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms.   &lt;br /&gt;
    &lt;br /&gt;
Die Taster werden hierbei als Active-Low angeschlossen um die internen Pull-Ups zu nutzen.   &lt;br /&gt;
    &lt;br /&gt;
Diese Routine gibt für den Zustand &amp;quot;steigende Flanke&amp;quot; den Wert &amp;quot;1&amp;quot; zurück, sonst &amp;quot;0&amp;quot;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;c&amp;gt;   &lt;br /&gt;
#define TASTERPORT PINC   &lt;br /&gt;
#define TASTERBIT PINC1   &lt;br /&gt;
   &lt;br /&gt;
char taster(void)   &lt;br /&gt;
{   &lt;br /&gt;
  static unsigned char zustand;   &lt;br /&gt;
  char rw = 0;   &lt;br /&gt;
   &lt;br /&gt;
  if(zustand == 0 &amp;amp;&amp;amp; !(TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT))) //Taster wird gedrueckt (steigende Flanke)   &lt;br /&gt;
  {   &lt;br /&gt;
    zustand = 1;   &lt;br /&gt;
    rw = 1;   &lt;br /&gt;
  }   &lt;br /&gt;
  else if (zustand == 1 &amp;amp;&amp;amp; !(TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT))) //Taster wird gehalten   &lt;br /&gt;
  {   &lt;br /&gt;
    zustand = 2;   &lt;br /&gt;
    rw = 0;   &lt;br /&gt;
  }&lt;br /&gt;
  else if (zustand == 2 &amp;amp;&amp;amp; (TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT))) //Taster wird losgelassen (fallende Flanke)&lt;br /&gt;
  {&lt;br /&gt;
    zustand = 3;&lt;br /&gt;
    rw = 0;&lt;br /&gt;
  }&lt;br /&gt;
  else if (zustand == 3 &amp;amp;&amp;amp; (TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))	//Taster losgelassen&lt;br /&gt;
  {&lt;br /&gt;
    zustand = 0;&lt;br /&gt;
    rw = 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return rw;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Warteschleifen-Verfahren ===&lt;br /&gt;
&lt;br /&gt;
Siehe [[AVR-GCC-Tutorial#.28Tasten-.29Entprellung|Abschnitt (Tasten-)Entprellung im AVR-GCC-Tutorial]].&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;DEBOUNCE&#039;&#039; Befehl in dem BASIC-Dialekt BASCOM für AVR ist ebenfalls nach dem Warteschleifen-Verfahren programmiert. Die Wartezeit beträgt defaultmässig 25 ms, kann aber vom Anwender überschrieben werden. Vgl.  [http://avrhelp.mcselec.com/bascom-avr.html?DEBOUNCE BASCOM Online-Manual zu DEBOUNCE].&lt;br /&gt;
&lt;br /&gt;
Der Nachteil dieses Verfahrens ist, dass der Controller durch die Warteschleife blockiert wird. Günstiger ist die Implementierung mit einem Timer-Interrupt.&lt;br /&gt;
&lt;br /&gt;
==== Warteschleifenvariante mit Maske und Pointer (nach Christian Riggenbach) ====&lt;br /&gt;
&lt;br /&gt;
Hier eine weitere Funktion um Taster zu entprellen. Durch den zusätzlichen Code kann eine Entprellzeit von durchschnittlich 1-3ms (mindestens 8*150us = 1ms) erreicht werden. Grundsätzlich prüft die Funktion den Pegel der Pins auf einem bestimmten Port. Wenn die/der Pegel 8 mal konstant war, wird die Schleife verlassen. Diese Funktion kann sehr gut gebraucht werden, um in einer Endlosschleife Taster anzufragen, da sie, wie erwähnt, eine kurze Wartezeit hat.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void entprellung( volatile uint8_t *port, uint8_t maske ) {&lt;br /&gt;
  uint8_t   port_puffer;&lt;br /&gt;
  uint8_t   entprellungs_puffer;&lt;br /&gt;
&lt;br /&gt;
  for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {&lt;br /&gt;
    entprellungs_puffer&amp;lt;&amp;lt;=1;&lt;br /&gt;
    port_puffer = *port;&lt;br /&gt;
    _delay_us(150);&lt;br /&gt;
    if( (*port &amp;amp; maske) == (port_puffer &amp;amp; maske) )&lt;br /&gt;
      entprellungs_puffer |= 0x01;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Die Funktion wird wie folgt aufgerufen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
entprellung( PINB, (1&amp;lt;&amp;lt;PINB2) );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Als Maske kann ein beliebiger Wert übergeben werden. Sie verhindert, dass nicht verwendete Taster die Entprellzeit negativ beeinflussen.&lt;br /&gt;
&lt;br /&gt;
=== Interrupt-Verfahren (nach Peter Dannegger) ===&lt;br /&gt;
&lt;br /&gt;
==== Grundroutine (AVR Assembler) ====&lt;br /&gt;
&lt;br /&gt;
Siehe dazu: [http://www.mikrocontroller.net/forum/read-4-20435.html#new Forum] &lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* besonders kurzer Code&lt;br /&gt;
* schnell&lt;br /&gt;
* sicher (4-fach-Abtastung) &lt;br /&gt;
&lt;br /&gt;
Außerdem können 8 Tasten gleichzeitig bearbeitet werden, es dürfen also&lt;br /&gt;
alle exakt zur selben Zeit gedrückt werden. Andere Routinen können z.B. nur eine Taste verarbeiten, d.h. die zuerst oder zuletzt gedrückte gewinnt oder es kommt Unsinn heraus.&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Einlese- und Entprellroutine ist nur 8 Instruktionen&lt;br /&gt;
kurz. Der entprellte Tastenzustand ist im Register &amp;quot;key_state&amp;quot;. Mit nur 2 weiteren Instruktionen wird dann der Wechsel von Taste offen zu&lt;br /&gt;
Taste gedrückt erkannt und im Register &amp;quot;key_press&amp;quot; abgelegt. Im Beispielcode werden dann damit 8 LEDs ein- und ausgeschaltet. Jede Taste entspricht einem Bit in den Registern, d.h. die Verarbeitung erfolgt bitweise mit logischen Operationen. Zum Verständnis empfiehlt es sich daher, die Logikgleichungen mit Gattern für ein Bit = eine Taste aufzumalen. Die Register kann man sich als Flip-Flops denken, die mit der Entprellzeit als Takt arbeiten. D.h. man kann das auch so z.B. in einem GAL22V10 realisieren.&lt;br /&gt;
&lt;br /&gt;
Als Kommentar sind neben den einzelnen Instruktionen alle 8 möglichen&lt;br /&gt;
Kombinationen der 3 Signale dargestellt.&lt;br /&gt;
&lt;br /&gt;
Beispielcode für AVR (Assembler):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;c:\avr\inc\1200def.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
.def  save_sreg         = r0&lt;br /&gt;
.def  iwr0              = r1&lt;br /&gt;
.def  iwr1              = r2&lt;br /&gt;
&lt;br /&gt;
.def  key_old           = r3&lt;br /&gt;
.def  key_state         = r4&lt;br /&gt;
.def  key_press         = r5&lt;br /&gt;
&lt;br /&gt;
.def  leds              = r16&lt;br /&gt;
.def  wr0               = r17&lt;br /&gt;
&lt;br /&gt;
.equ  key_port          = pind&lt;br /&gt;
.equ  led_port          = portb&lt;br /&gt;
&lt;br /&gt;
      rjmp   init&lt;br /&gt;
.org OVF0addr		;timer interrupt 24ms&lt;br /&gt;
      in     save_sreg, SREG&lt;br /&gt;
get8key:                               ;/old      state     iwr1      iwr0&lt;br /&gt;
      mov    iwr0, key_old             ;00110011  10101010            00110011&lt;br /&gt;
      in     key_old, key_port         ;11110000&lt;br /&gt;
      eor    iwr0, key_old             ;                              11000011&lt;br /&gt;
      com    key_old                   ;00001111&lt;br /&gt;
      mov    iwr1, key_state           ;                    10101010&lt;br /&gt;
      or     key_state, iwr0           ;          11101011&lt;br /&gt;
      and    iwr0, key_old             ;                              00000011&lt;br /&gt;
      eor    key_state, iwr0           ;          11101000&lt;br /&gt;
      and    iwr1, iwr0                ;                    00000010&lt;br /&gt;
      or     key_press, iwr1           ;store key press detect&lt;br /&gt;
;&lt;br /&gt;
;			insert other timer functions here&lt;br /&gt;
;&lt;br /&gt;
      out    SREG, save_sreg&lt;br /&gt;
      reti&lt;br /&gt;
;-------------------------------------------------------------------------&lt;br /&gt;
init:&lt;br /&gt;
      ldi    wr0, 0xFF&lt;br /&gt;
      out    ddrb, wr0&lt;br /&gt;
      ldi    wr0, 1&amp;lt;&amp;lt;CS02 | 1&amp;lt;&amp;lt;CS00    ;divide by 1024 * 256&lt;br /&gt;
      out    TCCR0, wr0&lt;br /&gt;
      ldi    wr0, 1&amp;lt;&amp;lt;TOIE0             ;enable timer interrupt&lt;br /&gt;
      out    TIMSK, wr0&lt;br /&gt;
&lt;br /&gt;
      clr    key_old&lt;br /&gt;
      clr    key_state&lt;br /&gt;
      clr    key_press&lt;br /&gt;
      ldi    leds, 0xFF&lt;br /&gt;
main: cli&lt;br /&gt;
      eor    leds, key_press           ;toggle LEDs&lt;br /&gt;
      clr    key_press                 ;clear, if key press action done&lt;br /&gt;
      sei&lt;br /&gt;
      out    led_port, leds&lt;br /&gt;
      rjmp   main&lt;br /&gt;
;-------------------------------------------------------------&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Komfortroutine (C für AVR) ====&lt;br /&gt;
&lt;br /&gt;
Siehe dazu: [http://www.mikrocontroller.net/forum/read-4-310276.html Forum]&lt;br /&gt;
&lt;br /&gt;
Funktionsprinzip wie oben plus zusätzliche Features:  &lt;br /&gt;
* Kann Tasten sparen durch unterschiedliche Aktionen bei kurzem oder langem Drücken&lt;br /&gt;
* Wiederholfunktion, z.B. für die Eingabe von Werten&lt;br /&gt;
&lt;br /&gt;
Das Programm ist für avr-gcc/avr-libc geschrieben, kann aber mit ein paar Anpassungen auch mit anderen Compilern und Mikrocontrollern verwendet werden. Eine Portierung für den AT91SAM7 findet man [http://www.google.com/codesearch?q=show:ac2viP-2E2Y:pzkOO5QRsoc:RPICuprYy-A&amp;amp;sa=N&amp;amp;cd=1&amp;amp;ct=rc&amp;amp;cs_p=svn://mikrocontroller.net/mp3dec/trunk&amp;amp;cs_f=keys.c#a0 hier] (aus dem Projekt [[ARM MP3/AAC Player]]).&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*                      Debouncing 8 Keys                               */&lt;br /&gt;
/*                      Sampling 4 Times                                */&lt;br /&gt;
/*                      With Repeat Function                            */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*              Author: Peter Dannegger                                 */&lt;br /&gt;
/*                      danni@specs.de                                  */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU           1000000                   // processor clock frequency&lt;br /&gt;
#warning kein F_CPU definiert&lt;br /&gt;
#endif&lt;br /&gt;
 &lt;br /&gt;
#define KEY_DDR         DDRB&lt;br /&gt;
#define KEY_PORT        PORTB&lt;br /&gt;
#define KEY_PIN         PINB&lt;br /&gt;
#define KEY0            0&lt;br /&gt;
#define KEY1            1&lt;br /&gt;
#define KEY2            2&lt;br /&gt;
#define ALL_KEYS        (1&amp;lt;&amp;lt;KEY0 | 1&amp;lt;&amp;lt;KEY1 | 1&amp;lt;&amp;lt;KEY2)&lt;br /&gt;
 &lt;br /&gt;
#define REPEAT_MASK     (1&amp;lt;&amp;lt;KEY1 | 1&amp;lt;&amp;lt;KEY2)       // repeat: key1, key2&lt;br /&gt;
#define REPEAT_START    50                        // after 500ms&lt;br /&gt;
#define REPEAT_NEXT     20                        // every 200ms&lt;br /&gt;
&lt;br /&gt;
#define LED_DDR         DDRA&lt;br /&gt;
#define LED_PORT        PORTA&lt;br /&gt;
#define LED0            0&lt;br /&gt;
#define LED1            1&lt;br /&gt;
#define LED2            2&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t key_state;                                // debounced and inverted key state:&lt;br /&gt;
                                                  // bit = 1: key pressed&lt;br /&gt;
volatile uint8_t key_press;                                // key press detect&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t key_rpt;                                  // key long press and repeat&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
ISR( TIMER0_OVF_vect )                            // every 10ms&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t ct0, ct1, rpt;&lt;br /&gt;
  uint8_t i;&lt;br /&gt;
 &lt;br /&gt;
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms&lt;br /&gt;
 &lt;br /&gt;
  i = key_state ^ ~KEY_PIN;                       // key changed ?&lt;br /&gt;
  ct0 = ~( ct0 &amp;amp; i );                             // reset or count ct0&lt;br /&gt;
  ct1 = ct0 ^ (ct1 &amp;amp; i);                          // reset or count ct1&lt;br /&gt;
  i &amp;amp;= ct0 &amp;amp; ct1;                                 // count until roll over ?&lt;br /&gt;
  key_state ^= i;                                 // then toggle debounced state&lt;br /&gt;
  key_press |= key_state &amp;amp; i;                     // 0-&amp;gt;1: key press detect&lt;br /&gt;
 &lt;br /&gt;
  if( (key_state &amp;amp; REPEAT_MASK) == 0 )            // check repeat function&lt;br /&gt;
     rpt = REPEAT_START;                          // start delay&lt;br /&gt;
  if( --rpt == 0 ){&lt;br /&gt;
    rpt = REPEAT_NEXT;                            // repeat delay&lt;br /&gt;
    key_rpt |= key_state &amp;amp; REPEAT_MASK;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key has been pressed. Each pressed key is reported&lt;br /&gt;
// only once&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_press( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read and clear atomic !&lt;br /&gt;
  key_mask &amp;amp;= key_press;                          // read key(s)&lt;br /&gt;
  key_press ^= key_mask;                          // clear key(s)&lt;br /&gt;
  sei();&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key has been pressed long enough such that the&lt;br /&gt;
// key repeat functionality kicks in. After a small setup delay&lt;br /&gt;
// the key is reported beeing pressed in subsequent calls&lt;br /&gt;
// to this function. This simulates the user repeatedly&lt;br /&gt;
// pressing and releasing the key.&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_rpt( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read and clear atomic !&lt;br /&gt;
  key_mask &amp;amp;= key_rpt;                            // read key(s)&lt;br /&gt;
  key_rpt ^= key_mask;                            // clear key(s)&lt;br /&gt;
  sei();&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_short( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read key state and key press atomic !&lt;br /&gt;
  return get_key_press( ~key_state &amp;amp; key_mask );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_long( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  return get_key_press( get_key_rpt( key_mask ));&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
  KEY_DDR &amp;amp;= ~ALL_KEYS;                // konfigure key port for input&lt;br /&gt;
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors&lt;br /&gt;
&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;CS02)|(1&amp;lt;&amp;lt;CS00);			// divide by 1024&lt;br /&gt;
  TIMSK = 1&amp;lt;&amp;lt;TOIE0;				// enable timer interrupt&lt;br /&gt;
 &lt;br /&gt;
  LED_PORT = 0xFF;&lt;br /&gt;
  LED_DDR = 0xFF;                     &lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    if( get_key_short( 1&amp;lt;&amp;lt;KEY1 ))&lt;br /&gt;
      LED_PORT ^= 1&amp;lt;&amp;lt;LED1;&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_long( 1&amp;lt;&amp;lt;KEY1 ))&lt;br /&gt;
      LED_PORT ^= 1&amp;lt;&amp;lt;LED2;&lt;br /&gt;
 &lt;br /&gt;
                                                  // single press and repeat&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_press( 1&amp;lt;&amp;lt;KEY2 ) || get_key_rpt( 1&amp;lt;&amp;lt;KEY2 )){&lt;br /&gt;
      uint8_t i = LED_PORT;&lt;br /&gt;
 &lt;br /&gt;
      i = (i &amp;amp; 0x07) | ((i &amp;lt;&amp;lt; 1) &amp;amp; 0xF0);&lt;br /&gt;
      if( i &amp;lt; 0xF0 )&lt;br /&gt;
        i |= 0x08;&lt;br /&gt;
      LED_PORT = i;      &lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das single-press-und-repeat Beispiel geht nicht in jeder Beschaltung, folgendes Beispiel sollte universeller sein (einzelne LED an/aus):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
                                                 // single press and repeat&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_press( 1&amp;lt;&amp;lt;KEY2 ) || get_key_rpt( 1&amp;lt;&amp;lt;KEY2 )){&lt;br /&gt;
    &lt;br /&gt;
	LED_PORT ^=0x08;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [[AVR-Tutorial: Tasten]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#.28Tasten-.29Entprellung|AVR-GCC-Tutorial Tastenentprellung]]&lt;br /&gt;
* http://www.mikrocontroller.net/forum/read-4-20435.html (AVR Assembler)&lt;br /&gt;
* http://www.mikrocontroller.net/forum/read-1-140056.html#140946 (AVR-ASM 1 Taste)&lt;br /&gt;
* http://www.ganssle.com/debouncing.pdf A guide to debouncing (engl.), praktische Erläuterungen zum Entprellen in Soft- und Hardware&lt;br /&gt;
* http://www.mikrocontroller.net/forum/read-1-242461.html&lt;br /&gt;
* http://www.mikrocontroller.net/topic/94829&lt;br /&gt;
* http://www.mikrocontroller.net/topic/18764#135843&lt;br /&gt;
* [http://www.pololu.com/docs/0J16/all Understanding Destructive LC Voltage Spikes]&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Blackhat-blade</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ATEVK1105&amp;diff=40022</id>
		<title>ATEVK1105</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ATEVK1105&amp;diff=40022"/>
		<updated>2009-10-18T11:43:17Z</updated>

		<summary type="html">&lt;p&gt;Blackhat-blade: typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Daniel Wolf (&amp;lt;b&amp;gt;danie&amp;lt;/b&amp;gt;)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Das ATEVK1105 ist ein Applikations-board mit dem Atmel die Audio-Funktionalität der AVR32: UC3A-Familie demonstriert.&lt;br /&gt;
Die aufgespielte Beispielapplikation demonstriert das Dekodieren von MP3 oder WMA in Software.&lt;br /&gt;
Bevor das Board mit eigener Software bespielt wird, sollte die aufgespielte Software gesichert werden, um notfalls den Ursprungszustand des Boards wiederherstellen zu können.&lt;br /&gt;
&lt;br /&gt;
Komponenten:&lt;br /&gt;
* AVR32 (Haupt-CPU): AT32UC3A0512&lt;br /&gt;
* AVR32 (USB-&amp;gt;Seriell | USB-&amp;gt;JTAG): AT32UC3B1256-AUT&lt;br /&gt;
* Ethernet PHY: DP83848I&lt;br /&gt;
* Farbdisplay (TFT mit BackLight): ET024006DHU&lt;br /&gt;
* 32MB SDRAM: MT48LC16M16A2&lt;br /&gt;
* 8MB DataFlash: AT45DB642D-CNU&lt;br /&gt;
* SD/MMC-Slot&lt;br /&gt;
* PWM-Audio mit Kopfhörer-Verstärker: TPA6130A2RTJ&lt;br /&gt;
* DAC-Audio + Mikrofon: TLV320AIC23B&lt;br /&gt;
* Debug und Trace-Interface (JTAG + NEXUS)&lt;br /&gt;
* 5 QTouch-Sensoren: QT1081&lt;br /&gt;
* 4 Leds am UC3A, 2 Leds am UC3B, 1 Power-Led&lt;br /&gt;
&lt;br /&gt;
== Packungsinhalt ==&lt;br /&gt;
          [[Bild:ATEVK1105_packung.jpg]]&lt;br /&gt;
# ATEVK1105 Board&lt;br /&gt;
# Ethernet-Leitung&lt;br /&gt;
# USB-Leitung (Typ-A auf Mini-B 5Pol.) (2 Stück)&lt;br /&gt;
# USB-OTG-Adapter (Mini-B 5Pol. auf USB-Master-Buchse)&lt;br /&gt;
# DVD: Technical Libary&lt;br /&gt;
# CD: IAR Embedded Workbench&lt;br /&gt;
# Kurzanleitung: &#039;&#039;AVR32913: EVK1105 Getting Started Guide&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
* [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4428 ATEVK1105 auf Atmel.com]&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/EVK1105-Schematics_BOM.zip Schaltplan]&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc7745.pdf Offizielle Beschreibung des werkseitigen Bootloaders (DFU)]&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc7817.pdf AVR32709: AVR32 UC3 Audio Decoder Over USB on AT32UC3A0512]&lt;br /&gt;
* [http://alvidi.de/data_sheets/erster_schritt.pdf Ein gutes einsteiger Tutorial zu einem AVR32 Modul (deutsch)]&lt;br /&gt;
* [http://www.edtc.com/edt/Products/tft_subsearch.asp?search=240+(RGB)+x+320&amp;amp;page=2 Link zum Hersteller des Displays]&lt;br /&gt;
&lt;br /&gt;
== Erste Inbetriebnahme der vorinstallierten Beispielsoftware ==&lt;br /&gt;
[http://www.avrtv.com/2009/03/17/evk1105-uc3-audio-player-kit/ Eindrucksvolle Demonstration von Atmel mittels eines Videos]&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
=== Installieren der Entwicklungsumgebung ===&lt;br /&gt;
&lt;br /&gt;
# AVR32 Studio laden und installieren&lt;br /&gt;
# AVR32 GNU Toolchain laden und installieren&lt;br /&gt;
# FLIP-Tool laden und installieren&lt;br /&gt;
# AVR32-Studio ausführen&lt;br /&gt;
Das auf der Eclipse-IDE basierende Studio fragt beim ersten Start nach einem Ziel für den &amp;quot;Workspace&amp;quot;, welches das Verzeichnis für Sourcen und Projekte sein wird, dies kann nach belieben gewählt werden.&lt;br /&gt;
siehe auch:&lt;br /&gt;
* [[AVR32 Studio]]&lt;br /&gt;
* [[AVR32 Studio Einstiegshilfe]]&lt;br /&gt;
&lt;br /&gt;
=== Anlegen des neuen Target (ATEVK1105) ===&lt;br /&gt;
* Auf den New-Target Button klicken&lt;br /&gt;
          [[Bild:ATEVK1105_target_window_0003.png]]&lt;br /&gt;
* Im Property-Window die Eigenschaften konfigurieren:&lt;br /&gt;
** General&lt;br /&gt;
*** Name: &#039;&#039;&#039;ATEVK1105&#039;&#039;&#039;&lt;br /&gt;
*** Binaries: hier muss nichts eingetragen werden&lt;br /&gt;
** Details&lt;br /&gt;
*** Debugger/Programmer: &#039;&#039;&#039;USB DFU&#039;&#039;&#039; auswählen&lt;br /&gt;
*** Mikrocontroller: &#039;&#039;&#039;UC3A0512&#039;&#039;&#039; auswählen&lt;br /&gt;
*** Clock Source: &#039;&#039;&#039;Crystal connected to OSC0&#039;&#039;&#039; auswählen&lt;br /&gt;
*** Board: &#039;&#039;&#039;ATEVK1105&#039;&#039;&#039; eingeben&lt;br /&gt;
*** Connection: hier kann nichts eingetragen werden&lt;br /&gt;
*** Clock: hier kann nichts eingetragen werden&lt;br /&gt;
*** Voltage: hier kann nichts eingetragen werden&lt;br /&gt;
** Daisy Chain&lt;br /&gt;
*** Der DFU-Mechanismus unterstützt kein Daisy Chain, daher kann nichts eingetragen werden&lt;br /&gt;
** Information&lt;br /&gt;
*** Memory: hier kann nichts eingetragen werden&lt;br /&gt;
          [[Bild:ATEVK1105_target_propertie_0000.png]]&lt;br /&gt;
&lt;br /&gt;
=== Vorbereiten des Boards ===&lt;br /&gt;
Da bei Auslieferung des Boards der Pfostenstecker &#039;&#039;&#039;J16&#039;&#039;&#039; nicht bestückt ist, dieser jedoch benötigt wird um den UC3A in den DFU-Modus zu bringen, muss er noch aufgelötet werden. bei Verwendung eines JTAG- oder NEXUS-Interfaces ist dies nicht zwingend nötig.&lt;br /&gt;
          [[Bild:ATEVK1105_J16.jpg]]&lt;br /&gt;
&lt;br /&gt;
Manche Boards wurden mit einer fehlerhaften Firmware auf dem UC3B Prozessor ausgeliefert. Eine FAQ zur Behebung des Problems ist unter folgendem Link zu finden:&lt;br /&gt;
[http://support.atmel.no/bin/customer?=&amp;amp;action=viewKbEntry&amp;amp;id=740 EVK1105 - USB Virtual COM Port does not work ]&lt;br /&gt;
&lt;br /&gt;
=== UC3A im DFU-Modus starten ===&lt;br /&gt;
==== Allgemeines ====&lt;br /&gt;
Um den Prozessor im DFU-Modus (&amp;lt;b&amp;gt;D&amp;lt;/b&amp;gt;evice &amp;lt;b&amp;gt;F&amp;lt;/b&amp;gt;irmware &amp;lt;b&amp;gt;U&amp;lt;/b&amp;gt;pdate) zu starten muss der Pin &amp;lt;b&amp;gt;PA9&amp;lt;/b&amp;gt; auf GND gezogen werden. &amp;lt;b&amp;gt;PA9&amp;lt;/b&amp;gt; ist auf der Pfostenleiste &amp;lt;b&amp;gt;J16-1 (WLESS)&amp;lt;/b&amp;gt; zu finden, &amp;lt;b&amp;gt;GND&amp;lt;/b&amp;gt; ist auf &amp;lt;b&amp;gt;J16-9&amp;lt;/b&amp;gt;. Da dies zu Beginn die erste Wahl des Programmierens ist, macht man sich am besten einen Pfostenverbinder mit Taster. Für fortgeschrittenes Entwickeln mit Debug-Möglichkeit wird dann das JTAG-Interface verwendet. Wenn es professionell mit Debug- und Trace-Möglichkeit zu Werke geht, wird das NEXUS-Interface genutzt.&lt;br /&gt;
          [[Bild:ATEVK1105_DFU.jpg]]&lt;br /&gt;
&lt;br /&gt;
==== Vorgehensweise ====&lt;br /&gt;
# Das Board über die &amp;lt;b&amp;gt;USB-User&amp;lt;/b&amp;gt;-Schnittstelle mit dem PC verbinden.&lt;br /&gt;
# &amp;lt;b&amp;gt;PA9&amp;lt;/b&amp;gt; auf GND ziehen (und halten)&lt;br /&gt;
# &amp;lt;b&amp;gt;Reset&amp;lt;/b&amp;gt;-Taster drücken (und loslassen)&lt;br /&gt;
# &amp;lt;b&amp;gt;PA9&amp;lt;/b&amp;gt; loslassen&lt;br /&gt;
# Windows-Meldung abwarten:&amp;lt;br /&amp;gt;          [[Bild:ATEVK1105_neue_HW.png]]&lt;br /&gt;
# Auf die Nachfrage ob man sich mit Windows-Update verbinden will, mit &amp;lt;b&amp;gt;Nein, diesmal nicht&amp;lt;/b&amp;gt; anworten&lt;br /&gt;
# Es erscheint die Windows-Meldung um den Treiber zu installieren, diesen manuell aus dem FLIP-Installationsverzeichniss auswählen&amp;lt;br /&amp;gt;          [[Bild:ATEVK1105_neue_treiber.png]]&lt;br /&gt;
# den evtl. geforderten Neustart des Systems ausführen&lt;br /&gt;
Nun sollte das Board durch den Target-Dialog in AVR32-Studio angesprochen werden können.&lt;br /&gt;
&lt;br /&gt;
== Auslesen von programmierter Software ==&lt;br /&gt;
=== Die vorprogrammierte Beispielapplikation stand unter NDA ===&lt;br /&gt;
Die bei Auslieferung des ATEVK1105 aufgespielte Beispielsoftware (mp3-Player) ist im Sourcecode von Atmel erhältlich, bis vor kurzem jedoch leider nur unter NDA.&lt;br /&gt;
Dies hat es nötig gemacht die aufgespielte Software vom Prozessor zu sichern.&lt;br /&gt;
Es ist mir gelungen die aufgespielte Software vom Prozessor herunter zu laden und als *.hex File zu speichern. Die Nützlichkeit des ganzen sei jedoch in Frage gestellt, da auf diese Weise ja kein Sourcecode verfügbar ist, anhand dem irgendwelche Mechanismen erklärt werden. Diese Beschreibung zeigt allgemein das Auslesen Software, die bereits auf den Prozessor gespielt wurde.&lt;br /&gt;
&amp;lt;!-- Ehemaliger Download, veraltet!&lt;br /&gt;
Eine [http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1462179&amp;amp;bbs_page_no=1&amp;amp;bbs_id=1030 alte Version der Sourcen] kann von einer Chinesischen Seite geladen werden. Ich habe es jedoch nicht geschafft diese zu Übersetzen, da sie vermutlich für die alte Version der Toolchain gedacht ist. Ich weiss nicht ob der Download legal ist, da ja das NDA umgangen wird.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Application Note AVR32709 enthält seit Juli 2009 den komletten Source-Code.&lt;br /&gt;
Link: [http://www.atmel.com/dyn/products/app_notes.asp?family_id=682 Application Notes zum AVR32].&lt;br /&gt;
&lt;br /&gt;
=== Herunterladen der Beispielsoftware vom Board ===&lt;br /&gt;
* Starten von AVR32-Studio&lt;br /&gt;
* Verbinden des PC mit dem Board (PC:USB nach Board:User-USB)&lt;br /&gt;
* Haupt-CPU des Boards im DFU-Modus starten&lt;br /&gt;
* Herunterladen und speichern des ROM-Images als hex-File:&lt;br /&gt;
* Es wird ein korrekt konfiguriertes Target-Window benötigt (wichtig ist nur das Target ATEVK1105)&lt;br /&gt;
          [[Bild:ATEVK1105_target_window_0000.png]]&lt;br /&gt;
&lt;br /&gt;
* Rechtsklick auf das ATEVK1105-Target und auswählen von &#039;&#039;&#039;Read...&#039;&#039;&#039;&lt;br /&gt;
          [[Bild:ATEVK1105_target_window_0001.png]]&lt;br /&gt;
&lt;br /&gt;
* Eingabe des Speicherorts, des Dateiformats, des Offset (0x0 passt), der Länge (0x4ffff passt, habe dies empirisch ermittelt in dem ich mehrfach ausgelesen habe, bis die letzen bytes im hex-File 0x00 waren&lt;br /&gt;
          [[Bild:ATEVK1105_read_window_0000.png]]&lt;br /&gt;
* Die Datei &#039;&#039;&#039;readout.hex&#039;&#039;&#039; enthält nun das Image der Beispielapplikation&lt;br /&gt;
&lt;br /&gt;
== Beispielcode aus AVR32-Studio verwenden ==&lt;br /&gt;
Im AVR32-Studio sind einige Beispiele zum ATEVK1105 enthalten, die Verwendung soll hier beschrieben werden.&lt;br /&gt;
=== Aufsetzen eines neuen Beispiel-Projekts ===&lt;br /&gt;
* Die Erzeugung der Beispielcodes wird über: &amp;lt;b&amp;gt;File-&amp;gt;New-&amp;gt;Example...&amp;lt;/b&amp;gt; aufgerufen:&amp;lt;br /&amp;gt;&lt;br /&gt;
          [[Bild:ATEVK1105_file_new_example.png]]&lt;br /&gt;
* Im folgenden Dialog wählt man das gewünschte Beispiel-Projekt aus:&amp;lt;br /&amp;gt;&lt;br /&gt;
          [[Bild:ATEVK1105_examples.png]]&lt;br /&gt;
* Nun wird man aufgefordert einen Namen für das Projekt einzugeben, dieser kann frei gewählt werden. Als Workspace sollte &amp;lt;b&amp;gt;Use default location&amp;lt;/b&amp;gt; aktiv sein.&lt;br /&gt;
* Das neue Beispiel-Projekt ist nun im &amp;lt;b&amp;gt;Project-Explorer&amp;lt;/b&amp;gt; unter dem vorher vergebenen Namen verfügbar:&lt;br /&gt;
          [[Bild:ATEVK1105_project_explorer.png]]&lt;br /&gt;
=== Übersetzen des Beispielprojekts ===&lt;br /&gt;
* Das Projekt das Übersetzt werden soll im &amp;lt;b&amp;gt;Project-Explorer&amp;lt;/b&amp;gt; markieren&lt;br /&gt;
* Durch drücken des &amp;lt;b&amp;gt;Build&amp;lt;/b&amp;gt;-Hammers wird das Projekt übesetzt:&lt;br /&gt;
          [[Bild:ATEVK1105_build.png]]&lt;br /&gt;
* Ein Fenster mit dem fortlaufenden Build-Prozess-Balken wird eingeblendet:&lt;br /&gt;
          [[Bild:ATEVK1105_build_project.png]]&lt;br /&gt;
* In der &amp;lt;b&amp;gt;Console&amp;lt;/b&amp;gt; kann überprüft werden ob der Übersetzungsvorgang erfolgreich verlaufen ist:&lt;br /&gt;
          [[Bild:ATEVK1105_build_console.png]]&lt;br /&gt;
&lt;br /&gt;
== Programmieren des UC3A ==&lt;br /&gt;
=== Programmieren über USB ===&lt;br /&gt;
* Laden des Bootloaders (DFU-Modus) (siehe &amp;lt;b&amp;gt;6.4.2: UC3A im DFU-Modus starten - Vorgehensweise&amp;lt;/b&amp;gt;)&lt;br /&gt;
* Schreiben der Software mit AVR32-Studio&lt;br /&gt;
** Rechtsklick auf das Target ATEVK1105 und auswählen von &amp;lt;b&amp;gt;Program...&amp;lt;/b&amp;gt;&lt;br /&gt;
** Folgendes Fenster erscheint: &amp;lt;br /&amp;gt;          [[Bild:ATEVK1105_program.png]]&lt;br /&gt;
** Hier ist &amp;lt;b&amp;gt;file.elf&amp;lt;/b&amp;gt; durch das zu programmierende File mit Pfad zu ersetzen, verwende hierzu den &amp;lt;b&amp;gt;Browse...&amp;lt;/b&amp;gt; - Dialog&lt;br /&gt;
** Der Offset muss &amp;lt;b&amp;gt;0x0&amp;lt;/b&amp;gt; betragen.&lt;br /&gt;
** Die Dateilänge automatisch mit &amp;lt;b&amp;gt;Entire file&amp;lt;/b&amp;gt; ermitteln lassen&lt;br /&gt;
** Bei &amp;lt;b&amp;gt;Options&amp;lt;/b&amp;gt; müssen alle Haken gesetzt sein&lt;br /&gt;
** mit &amp;lt;b&amp;gt;OK&amp;lt;/b&amp;gt; bestätigen&lt;br /&gt;
* Das Herunterladen abwarten (rechts unten warten bis folgende Meldung verschwindet: &amp;lt;br /&amp;gt;          [[Bild:ATEVK1105_program_process.png]]&lt;br /&gt;
* Der Programmiervorgang kann im &amp;lt;b&amp;gt;Console&amp;lt;/b&amp;gt;n-Fenster kontrolliert werden: &amp;lt;br /&amp;gt;          [[Bild:ATEVK1105_program_console.png]]&lt;br /&gt;
* Das Board wird durch den Bootlader nach dem Programmieren automatisch gestartet (haben wir vorher in den &amp;lt;b&amp;gt;Options&amp;lt;/b&amp;gt; angegeben)&lt;br /&gt;
&lt;br /&gt;
=== Programmieren über JTAG ===&lt;br /&gt;
Beim Programmieren über JTAG muss darauf geachtet werden, dass der DFU-Bootloader nicht unbeabsichtigt überschrieben wird. Ein gelöschter Bootloader kann nur unter Einsatz des JTAGICE-MKII oder des AVR-One! wieder in den Prozessor geschrieben werden!&lt;br /&gt;
&lt;br /&gt;
==== Erzeugen des JTAG-Target ====&lt;br /&gt;
* Verbinden des JTAG MKII mit dem PC (evtl. Treiber installieren)&lt;br /&gt;
* Rechtsklick ins Target-Window und Auswahl von &amp;lt;b&amp;gt;Scan Targets&amp;lt;/b&amp;gt; -&amp;gt; Es wird ein neues Target angelegt&lt;br /&gt;
* Umbenennen des Targets (&amp;lt;b&amp;gt;Properties&amp;lt;/b&amp;gt;-Window) in ATEVK1105-JTAG&lt;br /&gt;
* Ausfüllen der restlichen Eigenschaften analog zum DFU-Target&lt;br /&gt;
&lt;br /&gt;
==== Reprogrammieren des DFU-Bootloaders ====&lt;br /&gt;
* Rechtsklick auf das JTAG-Target und auswahl von &amp;lt;b&amp;gt;Program Bootloader...&amp;lt;/b&amp;gt;&lt;br /&gt;
* Konfiguration der Pins etc.&lt;br /&gt;
&lt;br /&gt;
== Beispielcode ==&lt;br /&gt;
Im AVR32Studio sind zahlreiche Beispielcodes enthalten, diese sind erreichbar über...&lt;br /&gt;
/*ToDo*/&lt;br /&gt;
* Für ein vollständiges Projekt (OS, TCP/IP Stack, Grafik-Bibliothek usw.) sowie AVR32 Simulator - [http://www.utasker.com/avr32.html http://www.utasker.com/avr32.html]&lt;br /&gt;
&lt;br /&gt;
== Notizen ==&lt;br /&gt;
Um Mathematische Funktion zu nutzen müssen folgende Punkte eingebaut werden:&lt;br /&gt;
* #include &amp;lt;math.h&amp;gt;&lt;br /&gt;
* die Linkeroptionen müssen um ein -lm erweitert werden (wobei -l von avrstudio hinzugefügt wird)&lt;br /&gt;
hierzu: rechtsklick auf das projekt und dann Properties\C/C++Build\Settings\AVR32/GNU C Linker\Libaries\im obigen Feld ein m hinzufügen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Starterkits]]&lt;br /&gt;
[[Category:AVR32-Boards]]&lt;/div&gt;</summary>
		<author><name>Blackhat-blade</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=FPGA&amp;diff=40013</id>
		<title>FPGA</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=FPGA&amp;diff=40013"/>
		<updated>2009-10-17T20:01:55Z</updated>

		<summary type="html">&lt;p&gt;Blackhat-blade: typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;FPGA ist die Abkürzung für &amp;quot;&#039;&#039;&#039;F&#039;&#039;&#039;ield &#039;&#039;&#039;P&#039;&#039;&#039;rogrammable &#039;&#039;&#039;G&#039;&#039;&#039;ate &#039;&#039;&#039;A&#039;&#039;&#039;rray&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Aufbau ==&lt;br /&gt;
&lt;br /&gt;
=== Grundelemente  ===&lt;br /&gt;
Ein FPGA besteht, ähnlich wie ein [[CPLD]], aus vielen Logikelementen, hauptsächlich Flip-Flops (FF) und davor geschalteten Logikelementen. Diese Logikelemente sind entweder Verschaltungen verschiedener Logikgatter (Actel) oder aber kleine LUTs (LUT = Lookup-Table), die über elektronische &amp;quot;Schalter&amp;quot; entsprechend der vom Entwickler gewünschten Funktion miteinander verknüpft werden können.&lt;br /&gt;
&lt;br /&gt;
Eine &#039;&#039;&#039;LUT&#039;&#039;&#039; kann eine beliebige kombinatorische Funktion (NAND, XOR, AND, Multiplexer etc.) aus den Eingangssignalen realisieren. Die Anzahl der Eingangssignale pro LUT ist vom FPGA abhängig und liegt meist zwischen 4 und 6. Für Funktionen, die mehr Eingänge erfordern, als eine einzige LUT besitzt (hohes Fan-In), werden mehrere LUTs direkt miteinander verschaltet. Die &#039;&#039;&#039;Flip-Flops&#039;&#039;&#039; dienen dazu, Signalwerte zwischenzuspeichern, um sie im nächsten Takt weiterverarbeiten zu können. Das Verhältnis zwischen der Anzahl der LUTs und der Anzahl der Flip-Flops ist meist 1:1. Aktuelle FPGAs bestehen aus bis zu einigen zehntausend Logikelementen.&lt;br /&gt;
&lt;br /&gt;
Die logischen Schalter und Speicher sind in den meisten FPGAs durch SRAM-Speicherzellen (Ausnahme: Actel ProASIC und Fusion, dort bilden die Flashzellen diese Funktion direkt ab) realisiert, welche beim Bootprozess passend geladen werden. Das Laden dieser Konfigurationsdaten bzw. Verknüpfungsregeln geschieht dabei in der Regel aus einem speziellen Flash-ROM-Baustein heraus. Es kann aber auch ein Mikrocontroller benutzt werden. Die meisten (SRAM-basierten) FPGAs bieten daher für diesen Konfigurationsvorgang mehrere Modi (seriell, parallel, Master/Slave) an. Da die SRAM-Zellen ihren Inhalt beim Abschalten der Versorgungsspannung verlieren, muss ein SRAM-basierter FPGA bei jedem Einschalten neukonfiguriert werden. Daher benötigt ein solcher FPGA einige Millisekunden bis zur Betriebsbereitschaft.&lt;br /&gt;
&lt;br /&gt;
Eine FPGA-Familie beinhaltet Typen mit unterschiedlicher Anzahl und Komplexität von Logikzellen. So enthält ein Spartan3-1000 ca. 2,5 mal mehr Logik (FF, LUTs) als ein Spartan3-400.  &lt;br /&gt;
&lt;br /&gt;
FPGAs mit nichtflüchtigem Speicher basieren auf EEPROM-, Flash- (einige Familien von Lattice und Actel) oder AntiFuse- (Actel) Technologie. Die sogenannten AntiFuse FPGAs sind einmalig programmierbar.&lt;br /&gt;
&lt;br /&gt;
=== I/O Anschlüsse ===&lt;br /&gt;
FPGAs unterstützen als universal einsetzbare Digital-ICs eine Vielzahl von Signalstandards. Üblich sind verschiedene TTL-Pegel (5V, 3,3V, 2,5V), differentielle Signalstandards (LVDS, GTL) und im Hochpreisbereich serielle Standards bis zu 4 Gbps. Oftmals sind weitere Eigenschaften wie Treiberstärke und Flankensteilheit für jeden benutzerdefinierbaren Anschluss (User-IO) einstellbar. Meist sind die Pins zu Bänken mit gleichem I/O Standard zusammengefasst. Innerhalb einer solchen Bank arbeiten alle Pins im gleichen I/O Standard und mit der selben I/O Spannung (H-Pegel).&lt;br /&gt;
&lt;br /&gt;
Ebenso können FPGA-interne Pull-Up und Pull-Down-Widerstände zugeschaltet werden, Terminierung wird ebenfalls unterstützt. Zudem befinden sich hinter vielen IO-Pads sog. [[boundary scan]] Zellen.&lt;br /&gt;
&lt;br /&gt;
Das I/O Verhalten wird mit den IO-Constraints in einem setting-File (Xilinx *.ucf, Altera *.acf, Lattice *.lpf) festgelegt. Alternativ können diese auch als Syntheseoption im Kommentarfeld des Verilog/VHDL Codes mit angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Einige Pins übernehmen besondere Funktionen und sind somit vom Anwender nicht uneingeschränkt oder z.T. auch gar nicht nutzbar. Dazu zählen neben der JTAG-Schnittstelle z.B. die Pins zum Einlesen der Konfigurationsdaten. &lt;br /&gt;
&lt;br /&gt;
Ferner sind einige wenige Pins (2 - 8) zum Einspeisen des Taktes für das Design vorgesehen. Für schnelle Schaltung müssen diese reservierten Pins benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Hersteller bieten FPGAs mit gleicher Anzahl von Logikelementen in unterschiedlichen Gehäusen an. So kann der FPGA mit der passenden Anzahl von Pins eingesetzt werden. Das obere Ende markieren Chips mit über 1000 I/Os, die kleinsten bieten ca. 80 User-I/O. Oft werden nur BGA und QFP Gehäuse (bis ca. 240(?) Pins) angeboten.&lt;br /&gt;
&lt;br /&gt;
=== Komplexere Blöcke (Multiplizierer, RAM, PLL/DLL) ===&lt;br /&gt;
Neben den einfachen Flip-Flops beinhalten FPGAs darüber hinaus komplexe Routing- und Speicherkonfigurationsoptionen innerhalb und außerhalb der logischen Elemente (LEs), die es gestatten, komplexe Schalt- und Rechenstrukturen aufzubauen. Für rechenintensive Designs, z.B. in der Signalverarbeitung, enthalten viele FPGAs Multiplizierer direkt auf dem Chip, die in einem einzigen Taktzyklus Multiplikationen durchführen können.&lt;br /&gt;
&lt;br /&gt;
Ferner haben FPGAs oft einen von den LEs getrennt verfügbaren RAM-Bereich integriert, der sich in vielfältiger Weise ansprechen lässt. So können damit Single- oder Dualport-RAMs mit variabler Bitbreite erzeugt werden. Üblich sind mehrere (4 - 30) kleinere Dualport RAM-Blöcke von 4 - 16 kbit. Einige Familien besitzen einen größeren internen RAM, andere spezielle FIFO-Blöcke.&lt;br /&gt;
&lt;br /&gt;
Zur Generierung spezieller Takte sind PLL-Komponenten (phase locked loop) auf dem FPGA integriert. Einige Hersteller setzen mit dem selben Ziel DLL-Blöcke (delay locked loop) ein. Mittels dieser Blöcke können aus einem Taktsignal weitere erzeugt werden. Typisch sind Taktverdopplung oder -vervielfachung. Ebenso kann der Takt geteilt werden oder ein Signal gleicher Frequenz, aber um eine halbe, viertel usw. Periode verschoben erzeugt werden. Typische Anwendungen sind die Ansteuerung von DDR-RAMs oder die Kompensation von Laufzeitunterschieden zwischen Takt und mit diesem getakteten Steuersignalen. Meist sind 2 - 8 Taktnetzwerke und PLL/DLLs gleicher Anzahl integriert. Siehe auch [[Taktung FPGA/CPLD]].&lt;br /&gt;
&lt;br /&gt;
=== CPU im FPGA ===&lt;br /&gt;
&lt;br /&gt;
Programmierbare Prozessoren sind auch bei FPGA Designs häufig unverzichtbar. CPUs sind zwar im Allgemeinen langsamer und weniger effizient, als eine vollständige Implementation aus Logik-Primitiven - aber bei komplexen Abläufen auch deutlich einfacher zu entwickeln. Insbesondere bei sequentiellen Aufgaben (Benutzerinterface, komplexe Steueraufgaben etc.) wird man gerne auf eine&lt;br /&gt;
klassische CPU zurückgreifen. &lt;br /&gt;
&lt;br /&gt;
Manche FPGAs integrieren dazu einen oder mehrere Prozessorkerne (z. B. [[AVR]] bei Atmels FPSLIC oder PowerPC bei Xilinx&#039; Virtex) als &#039;&#039;HardCores&#039;&#039; auf einem IC.&lt;br /&gt;
&lt;br /&gt;
Auf der anderen Seite gibt es auch &#039;&#039;SoftCores&#039;&#039; (z. B. ARM-Cortex-M1 bei IGLOO-FPGA von [http://www.actel.com ACTEL]), Prozessorkerne die als Quelltext oder als vor-synthetisierte Netzliste vorliegen. In Abhängigkeit von den zur Verfügung stehenden Ressourcen können diese &#039;&#039;SoftCores&#039;&#039; beliebig instanziiert werden. Es gibt eine Vielzahl verschiedener &#039;&#039;SoftCores&#039;&#039;. &lt;br /&gt;
 &lt;br /&gt;
Teilweise kompatibel zu etablierten Prozessorarchitekturen (MIPS, SPARC, AVR), zum Teil optimiert auf die FPGAs einzelner Hersteller. Auch auf vergleichsweise &lt;br /&gt;
kleine aktuelle FPGAs kann man problemlos eine 32bit-RISC-CPU integrieren.&lt;br /&gt;
Unter [[FPGA Soft Core]] findet man eine Liste einiger weit verbreiteter &#039;&#039;SoftCores&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Als Programmspeicher werden die FPGA-internen RAM-Blöcke oder externe Speicher-ICs (SDRAM, SRAM) genutzt. Für einige Prozessorkerne stehen Hochsprachen wie C, C++ etc. zur Verfügung, andere werden in Assembler programmiert.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften ==&lt;br /&gt;
=== Geschwindigkeit ===&lt;br /&gt;
Die maximale „Geschwindigkeit“ eines FPGAs ist von der verwendeten Halbleitertechnologie (Prozess, Strukturgrößen), der internen Schaltungstopologie (Komplexität der LEs), Vorhandensein von harten Strukturen und vor allem vom Design abhängig. Dabei sind der sogenannte Datendurchsatz und die rein maximale Systemtaktfrequenz zu unterscheiden. Die erreichbare Taktfrequenz lässt sich ohne detaillierte Kenntnis des Designs nicht abschätzen, möglich sind je nach »Speed Grade« des ICs typischerweise Taktfrequenzen von 300-600 MHz für die Schaltgeschwindigkeit der reinen Logikelemente. Je nach der Anzahl und Komplexität der pro Takt durchzuführenden Operationen ergeben sich dann reale Systemtaktfrequenzen von meist 10-100 MHz für global operierende Einheiten und bis zu 300 MHz für schnelle lokale Module. Maßgeblich ist, in wieweit das Design auf Fläche bzw. Geschwindigkeit hin optimiert und vom Tool synthetisiert wurde: Durch das Einbringen von zusätzlichen Registerstufen lassen sich z.B. zeitkritische Pfade entschärfen, sodass die Frequenz des Chips angehoben werden kann und somit der effektive Datendurchsatz erhöht wird, mit dem Nachteil der gesteigerten Latenz durch das Mehr an Takten. Der Datendurchsatz lässt sich darüber hinaus durch die Nutzung paralleler Architekturen verbessern.&lt;br /&gt;
&lt;br /&gt;
Die Systemfrequenz kann-, muss aber nicht der Frequenz entsprechen, mit der Daten zyklisch eingetaktet und verarbeitet werden; zudem sind Schaltungsteile mit unterschiedlichen Taktfrequenzen zu unterscheiden: Mit einem Systemtakt1 von 20 MHz lassen sich z.B. 18-Bit AD-Wandler auslesen, die so z.B. alle 1 µs neue Daten liefern, die verarbeitet werden müssen. Bei der Nutzung von 5 solchen Wandlern, die sequentiell verarbeitet werden, lägen 5 MHz Datenfrequenz vor. Für andere Schaltungsteile, die z.B. asynchron an die Peripherie andocken, sowie reine »state machines« können Schaltungsteile auf der 2-4 fachen Frequenz betrieben werden.&lt;br /&gt;
&lt;br /&gt;
Generell sind Fläche und Geschwindigkeit konkurrierende Größen, zwischen denen ein Optimum gefunden werden muss. Für die preiswerten FPGA-Serien wie Spartan (Xilinx) und Cyclone (Altera) sind aufgrund technologischer Randbedingungen etwa 10-30% weniger Taktgeschwindigkeit bei gleichem Design zu erwarten, bzw. muss mit mehr Verbrauch an Logikelementen und Taktzyklen gerechnet werden (weniger Routingreserven, geringere Zahl von LUT-Eingängen, weniger hard-ressourcen). Ferner kommen diese Familien mit grundsätzlich geringeren Schaltgeschwindigkeiten.&lt;br /&gt;
&lt;br /&gt;
Funktionstechnisch identische Chips werden oft in 2 oder mehr Geschwindigkeitsklassen angeboten, die sich meist durch Bauteilselektion bei der Produktion ergeben. Grob kann man ca. 5%-10% höhere Taktung zwischen zwei Speedgrades erwarten.&lt;br /&gt;
&lt;br /&gt;
== Hersteller ==&lt;br /&gt;
Die größten Hersteller von FPGAs sind Altera und Xilinx. Weitere Hersteller sind Lattice, Actel und Atmel.&lt;br /&gt;
&lt;br /&gt;
* [http://www.actel.com Actel]&lt;br /&gt;
* [http://www.altera.com Altera]&lt;br /&gt;
* [http://www.latticesemi.com/ Lattice]&lt;br /&gt;
* [http://www.xilinx.com Xilinx]&lt;br /&gt;
* [http://www.atmel.com Atmel]&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
&lt;br /&gt;
Der Aufbau komplizierter, applikationsnaher Strukturen wird meist durch automatische Routing- und Synthesewerkzeuge erledigt, welche mit einer logischen, funktionellen Beschreibung der Architektur in einer Hardwarebeschreibungssprache wie z.B. VHDL &amp;quot;gefüttert&amp;quot; werden. Die Hardwarebeschreibung in VHDL gelingt ihrerseits z.B. mit VHDL-generierenden Werkzeugen, mittels derer zuvor Logikstrukturen, hardwarenahe Strukturen, Ablaufdiagramme und Zustandsautomaten formuliert wurden.&lt;br /&gt;
&lt;br /&gt;
Durch die Standardisierung der Architektur einerseits und die Entkoppplung von applikationsorientierter Beschreibung sowie Chip- und Hersteller-spezifischer Synthese andererseits, wird die Hardware quasi als Software gebaut. Dies wiederum schafft alle Optionen der Wiederverwendung und Austausch von &amp;quot;Hardwareteilen&amp;quot;. So stehen inzwischen komplett nutzbare Schaltungen wie serielle Bausteine, RAM-Controller und vieles mehr als Open Source zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
== Entwicklungsboards und Starterkits ==&lt;br /&gt;
=== Boards für Xilinx-FPGAs ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;fpgaevalboards&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichn.&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! FPGA&lt;br /&gt;
! RAM (MByte)&lt;br /&gt;
! Flash (MByte)&lt;br /&gt;
! USB&lt;br /&gt;
! Ethernet&lt;br /&gt;
! RS-232&lt;br /&gt;
! µC&lt;br /&gt;
! Eingabe&lt;br /&gt;
! sonst.&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.knjn.com/board_Xylo.html Xylo-L]&lt;br /&gt;
| 130&lt;br /&gt;
| XC3S500E&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 2.0&lt;br /&gt;
| 10base-T&lt;br /&gt;
| -&lt;br /&gt;
| LPC213x&lt;br /&gt;
| -&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| [http://www.xilinx.com/s3estarter Spartan3e Starter Kit]&lt;br /&gt;
| 180&lt;br /&gt;
| XC3S500E&lt;br /&gt;
| 64 MB DDR-SDRAM&lt;br /&gt;
| 16&lt;br /&gt;
| (JTAG)&lt;br /&gt;
| 10/100&lt;br /&gt;
| 2x&lt;br /&gt;
| -&lt;br /&gt;
| 4 Taster, 1 Drehgeber, 4 Schalter&lt;br /&gt;
| Coolrunner CPLD, LCD, 3-Bit VGA, PS/2&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.digilentinc.com/Products/Detail.cfm?Nav1=Products&amp;amp;Nav2=Programmable&amp;amp;Prod=S3BOARD Digilent Spartan-3]&lt;br /&gt;
| 100&lt;br /&gt;
| XC3S200/400/1000&lt;br /&gt;
| 1&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 1x&lt;br /&gt;
| -&lt;br /&gt;
| 4 Taster, 8 Schalter&lt;br /&gt;
| VGA, PS/2, 7seg&lt;br /&gt;
|-&lt;br /&gt;
| [[Digilent Nexys]]&lt;br /&gt;
| 100&lt;br /&gt;
| XC3S200/400/1000&lt;br /&gt;
| 16&lt;br /&gt;
| 4&lt;br /&gt;
| 2.0&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 4 Taster, 8 Schalter&lt;br /&gt;
| 7seg, Programmierung &amp;amp; Stromversorgung über USB&lt;br /&gt;
|-&lt;br /&gt;
| [[Digilent Nexys 2]]&lt;br /&gt;
| 121&lt;br /&gt;
| XC3S500E/1200E&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 1x&lt;br /&gt;
| Cypress FX2 &lt;br /&gt;
| 4 Taster, 8 Schalter, 8 LEDs&lt;br /&gt;
| 4x7Seg, Programmierung &amp;amp; Stromversorgung über USB oder über Netzteil (5V-15V)&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.uxibo.de Uxibo]&lt;br /&gt;
| 88&lt;br /&gt;
| XC2S200E&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 1.1&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 4 Taster, 8 Schalter&lt;br /&gt;
| VGA I/O, Videomux, dual PS/2, 7seg, Buzzer, IOs auf Pinleisten, dual-channel FTDI2232C, 48 MHz + prog. Oszillator, Programmierung &amp;amp; Stromversorgung über USB&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.fpgaz.com/wiki/doku.php?id=fpgaz:usbp:hw FPGAz USBP]&lt;br /&gt;
| $135&lt;br /&gt;
| XC3S400&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 2.0&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| Cypress FX2&lt;br /&gt;
| 2 Taster&lt;br /&gt;
| 8 LEDs, I2C-EEPROM&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.cesys.com/fpga/spartan/efm01_de.html EFM 01] Embedded FPGA Modul &lt;br /&gt;
| ~173,-&lt;br /&gt;
| XC3S500E&lt;br /&gt;
| -&lt;br /&gt;
| 4&lt;br /&gt;
| 2.0&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| FX-2&lt;br /&gt;
| -&lt;br /&gt;
| 28 x 44mm, 50 I/O auf 2.54mm Stiftleiste, WIN und LINUX Treiber&lt;br /&gt;
|-&lt;br /&gt;
| [http://shop.trenz-electronic.de/catalog/product_info.php?products_id=456 Avnet Spartan 3A Evaluation Kit]&lt;br /&gt;
| 50&lt;br /&gt;
| XC3S400A&lt;br /&gt;
| -&lt;br /&gt;
| 16&lt;br /&gt;
| 2.0&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| WIN und LINUX Treiber&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raggedstone 1 - Spartan-3 Development PCI-Karte ====&lt;br /&gt;
* Spartan-3 FPGA FG456-Package&lt;br /&gt;
* 32 bit, 33 MHz, 3.3/5V PCI interface&lt;br /&gt;
* 4Mbit Flash Memory&lt;br /&gt;
* 16KBit serielles EEprom&lt;br /&gt;
* 4 x 7 Segment Anzeigen LED, abnehmbar&lt;br /&gt;
* LM75 Temperatursensor&lt;br /&gt;
* viele DIL-Header für eigene Erweiterungen, verschiedene werden auch durch Hersteller angeboten&lt;br /&gt;
* 2 Drucktaster&lt;br /&gt;
* Mit dem PCI-Interface kann bei entsprechender Programmierung des FPGA auf den PCI-Bus eines Hostrechners zugegriffen werden, Beispieldesign unter http://projects.varxec.net/raggedstone1&lt;br /&gt;
* Webseite: http://www.enterpoint.co.uk/moelbryn/raggedstone1.html&lt;br /&gt;
* Preis mit XC3S400 ca. €145,- (inkl MwSt.)&lt;br /&gt;
* Preis mit XC3S1500 ca. €255,-  (inkl. MwSt.)&lt;br /&gt;
&lt;br /&gt;
==== LiveDesign Evaluation Board von Altium ====&lt;br /&gt;
* Kompatibel mit den LiveDesign-fähigen Entwicklungstools von Altium&lt;br /&gt;
* Xilinx-Version direkt mit ISE Webpack nutzbar&lt;br /&gt;
* Xilinx XC3S1000-4FG456C, wahlweise aber auch mit Altera EP1C12F324C8 (s.u.)&lt;br /&gt;
* Mit Flachbandkabel für PC-Verbindung (Druckerport) sowie weiteren Kabeln und Verbindern &lt;br /&gt;
* Peripherie: LEDs, Dip-Schalter, 6-stellige Siebensegmentanzeige, Taster, Stereo-DAC, zwei 256K x 16 RAMs&lt;br /&gt;
* &#039;&#039;kein&#039;&#039; on-board Flash RAM für FPGA-Konfiguration, diese muss nach dem Einschalten neu geladen werden&lt;br /&gt;
* Ports: PS2-Maus &amp;amp; -Tastatur, RS232, VGA (512 Farben), 2x18 IO-Pins für allgemeine Zwecke &lt;br /&gt;
* Listenpreis $99,- Endpreis: ~150 Euro (inkl. MwSt. und Versand)&lt;br /&gt;
&lt;br /&gt;
==== BurchED ====&lt;br /&gt;
http://www.burched.com/index.html&lt;br /&gt;
australischer Anbieter von Xilinx-Evaluationsboards&lt;br /&gt;
zur Zeit Webseite im Umbau&lt;br /&gt;
&lt;br /&gt;
==== Trenz-Electronic ====&lt;br /&gt;
http://www.trenz-electronic.de/products.html&lt;br /&gt;
* Kleines FPGA Board mit ucLinux und Virtex-II PowerPC, optional: ucLinux und Microblaze Softprozessor im Spartan-3 FPGA&lt;br /&gt;
* Spartan-3 FPGA Mikromodul mit 200K bis 1000K Systemgattern&lt;br /&gt;
* Pal/Gal kompatible FPGA und CPLD Module&lt;br /&gt;
&lt;br /&gt;
==== Simple-Solutions ====&lt;br /&gt;
http://www.simple-solutions.de/de/products/index.php&lt;br /&gt;
Mehrere Spartan3-FPGAs - Boards&lt;br /&gt;
&lt;br /&gt;
==== CESYS ====&lt;br /&gt;
http://www.cesys.com&lt;br /&gt;
&lt;br /&gt;
Cesys ist Entwickler und Hersteller von FPGA-boards mit Sitz in Deutschland.&lt;br /&gt;
&lt;br /&gt;
* Verschiedene FPGA boards mit USB, PCI und PCIe Schnittstellen im Lieferprogramm&lt;br /&gt;
* Je nach Ausführung mit Spartan-2/3/3E, Virtex2/2PRO/4&lt;br /&gt;
* verschiedene Speicherkonfigurationen (SO-DIMM, SRAM, SDRAM, DDR2)&lt;br /&gt;
&lt;br /&gt;
=== Boards für Altera-FPGAs ===&lt;br /&gt;
==== LiveDesign Evaluation Board von Altium ====&lt;br /&gt;
* Kompatibel mit den LiveDesign-fähigen Entwicklungstools von Altium&lt;br /&gt;
* * Wahlweise mit Altera EP1C12F324C8 oder Xilinx XC3S1000-4FG456C&lt;br /&gt;
* Mit Flachbandkabel für PC-Verbindung (Druckerport) sowie weiteren Kabeln und Verbindern &lt;br /&gt;
* Peripherie: LEDs, Dip-Schalter, 6-stellige Siebensegmentanzeige, Taster, Stereo-DAC, zwei 256K x 16 RAMs&lt;br /&gt;
* &#039;&#039;kein&#039;&#039; on-board Flash RAM für FPGA-Konfiguration, diese muss nach dem Einschalten neu geladen werden&lt;br /&gt;
* Ports: PS2-Maus &amp;amp; -Tastatur, RS232, VGA (512 Farben), 2x18 IO-Pins für allgemeine Zwecke &lt;br /&gt;
* Endpreis: ~150 Euro (inkl. MwSt. und Versand)&lt;br /&gt;
&lt;br /&gt;
==== Terasic TREX C1 Multimedia Development Kit ====&lt;br /&gt;
* Altera EP1C6Q240C8 &amp;amp; EP1S Serial Configuration Device&lt;br /&gt;
* Built-in USB Blaster programming circuitry (JTAG and AS mode)&lt;br /&gt;
* 1 MiB Flash Memory &amp;amp; 8 MiB SDRAM (1M x 4 x 16)&lt;br /&gt;
* CF Card Socket, 16-bit CD-quality Audio DAC&lt;br /&gt;
* TV Encoder, VGA, RS-232, PS/2, and more&lt;br /&gt;
* Many reference designs and C++ applications&lt;br /&gt;
* [http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&amp;amp;CategoryNo=39&amp;amp;No=14 www.terasic.com.tw]&lt;br /&gt;
* fertiger Core eines CPC6128 (8-Bit Homecomputer von 1984) für dieses Board, inlusive Sourcecode (eigener Z80 in AHDL, mit 24MHz eingesetzt): [http://www.symbos.de/trex.htm http://www.symbos.de/trex.htm]&lt;br /&gt;
* Listenpreis $149,-&lt;br /&gt;
&lt;br /&gt;
==== Altera Cyclone II 2C20 ====&lt;br /&gt;
* Altera Cyclone II EP2C20F484C7N FPGA mit 20000 LEs&lt;br /&gt;
* USB-BlasterTM download cable (integriert)&lt;br /&gt;
* EPCS4 serial configuration Flash&lt;br /&gt;
* 8-Mbyte SDRAM, 512-Kb SRAM, 4-Mbyte flash &lt;br /&gt;
* externer SMA - Clock-Eingang&lt;br /&gt;
* 24-bit Audio coder/decoder (CODEC) &lt;br /&gt;
* 10 Schalter, 4 Druckknöpfe inkl Reset &lt;br /&gt;
* 4St. 7-Segmentanzeigen, 10 rote LEDs + 8 grüne LEDs&lt;br /&gt;
* VGA, RS-232, and PS/2 Stecker&lt;br /&gt;
* Zwei 40-pin expansion ports + SD/MMC socket&lt;br /&gt;
* USB-Kabel, externes Steckernetztteil, CD-Rom&lt;br /&gt;
* Reference designs&lt;br /&gt;
* Qartus II Web Edition + NIOS II Web Edition&lt;br /&gt;
* http://www.altera.com/products/devkits/altera/kit-cyc2-2C20N.html&lt;br /&gt;
* Listenpreis $150,-&lt;br /&gt;
&lt;br /&gt;
==== Hpe Mini AC II - Altera Cyclone board von Gleichmann Research ====&lt;br /&gt;
* Altera Cyclone II EP2C35 FPGA (speed grade 6)&lt;br /&gt;
* Mit reprogrammierbarem Flash zur automatischen FPGA-Konfiguration&lt;br /&gt;
* 25 pin SUB-D connector (parallel) für direktes FPGA-Programmieren&lt;br /&gt;
* RS232 (9 pin SUB-D) &lt;br /&gt;
* VGA (15 pin SUB-D) mit 64 möglichen Farben&lt;br /&gt;
* Ethernet 10/100 Mbit/s, full/half duplex&lt;br /&gt;
* 1 USB 2.0 compatible full-speed target connector&lt;br /&gt;
* 3 USB 2.0 compatible full-speed host connectors&lt;br /&gt;
* Santa Cruz connector mit 40 nutzbaren I/Os&lt;br /&gt;
* Audio interface (line-in and line-out) mit CODEC&lt;br /&gt;
* SODIMM144 Sockel für (SDRAM) 256MB&lt;br /&gt;
* SDRAM-Speichersockel mit nur 32-Bit angebunden, die Hälfte des Speichers bleibt nicht nutzbar&lt;br /&gt;
* 25 MHz oscillator&lt;br /&gt;
* Prototyping area, Lötfläche&lt;br /&gt;
* 8 LEDs, grün, blau, 3x4 key matrix, 4-bit DIP switch&lt;br /&gt;
* LCD connector, 2-character 7-segment display&lt;br /&gt;
* Single step Knopf und Reset Knopf&lt;br /&gt;
* Parallelportkabel für PC&lt;br /&gt;
* Beispieldesign, Testprogramme, Datenblätter&lt;br /&gt;
* LEON3-CPU Design inkl. Source Code, Quartus IDE, SnapGear Linux&lt;br /&gt;
* Je nach Ausführung des Flashs €399,- bis €499,-&lt;br /&gt;
&lt;br /&gt;
==== Altera DE2 - Development and Education Board ====&lt;br /&gt;
* Altera Cyclone II 2C35 FPGA mit 35000 LEs&lt;br /&gt;
* Altera Serial Configuration devices (EPCS16) für Cyclone II 2C35&lt;br /&gt;
* USB Blaster board zur Programmierung und User API&lt;br /&gt;
* 8 MB SDRAM, 4 MB Flash Memory, 512KB SRAM&lt;br /&gt;
* SD Card Sockel, RS-232, Ethernet, 10-bit VGA, 24-bit Audio CODEC&lt;br /&gt;
* TV Decoder (NTSC/PAL), IrDA, USB (Host + Slave)&lt;br /&gt;
* Viele Besipiel mit Source Code wie TV, SD Music Player)&lt;br /&gt;
* [http://wwwab.fh-wedel.de/bause/handouts/vhdl/VhdlEinfuehrung.pdf Kleines aber nettes Tutorial zum Altera DE2 Dev. Board]&lt;br /&gt;
* Listenpreis US $495,-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Cyclone III embedded Development Kit====&lt;br /&gt;
* Altera Cyclone III EP3C25 FPGA&lt;br /&gt;
* 640x480 LCD Display mit touch screen function&lt;br /&gt;
* MiniSD-Card Sockel&lt;br /&gt;
* Audio Interface ADC CODEC&lt;br /&gt;
* 10/100 Mbit Fast Ethernet Schnittstelle&lt;br /&gt;
* FPGA-Konfiguration über USB&lt;br /&gt;
* NIOS II EVAL Lizenz&lt;br /&gt;
* IP LIB Altera&lt;br /&gt;
* Listenpreis US $495,-  über ALtera Webseite&lt;br /&gt;
* Bei EBV €349,- inkl. MwSt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== NanoBoard-NB1 von Altium ====&lt;br /&gt;
* kompatibel mit den LiveDesign-fähigen Entwicklungstools von Altium&lt;br /&gt;
* Unterstützt eine breite Palette von Ziel-FPGAs durch Aufsteckplatinen &lt;br /&gt;
* Altera Cyclone (EP1C12-Q240C7) Aufsteckplatine enthalten &lt;br /&gt;
* Xilinx Spartan IIE (XC2S300E-PQ208) im Lieferumfang enthalten &lt;br /&gt;
* Enthält Stromversorgung mit verschiedenen Steckern für unterschiedliche Konfigurationen &lt;br /&gt;
* Mit Flachbandkabel für PC-Verbindung sowie weiteren Kabeln und Verbindern &lt;br /&gt;
* NanoBoard-NB1 Reference-Handbuch zur Hardware &lt;br /&gt;
* Peripherie: LCD, LEDs, Dip-Schalter, Tastenblock, Summer, ADC/DAC, 256K x 8 RAM, 8 MiB Serial Flash RAM, on-board Serial Flash RAM für FPGA-Konfig.&lt;br /&gt;
* Ports: PS2-Maus &amp;amp; -Tastatur, RS232, CAN, VGA, I2C, IO Stecker für allg. Zwecke &lt;br /&gt;
* Upgradefähige NanoBoard Controller Firmware &lt;br /&gt;
* Stabiler NanoBard-Sockel&lt;br /&gt;
* Listenpreis €995,-&lt;br /&gt;
&lt;br /&gt;
=== Boards für Lattice-FPGAs ===&lt;br /&gt;
==== www.hardware-design.de ====&lt;br /&gt;
* bietet verschiedene einfache Boards mit Lattice-Bausteinen an&lt;br /&gt;
* FPGA-Board mit XP2-17/XP2-8/XP2-5 -&amp;gt; 113,- bis 101,- Euro&lt;br /&gt;
* CPLD-Boards u.a. mit MachXO640 -&amp;gt; 89,- Euro&lt;br /&gt;
&lt;br /&gt;
=== Debugging-Hilfen ===&lt;br /&gt;
Gerade beim [[Debugging]] größerer FPGA-Designs ist es oft notwendig, auf interne Signale und Busse zuzugreifen, die aus routing- oder Platzgründen nicht an Pins des FPGAs gelegt - und mit konventionellen Analysatoren beobachtet werden können. Nebst den einschlägigen Tools der Hersteller, welche Signal probing über JTAG gestatten (z.B. ChipsScope und SignalTap), werden in FPGAs oft mehr oder weniger komplexe [[Logic Analyzer]] integriert, welche die internen Signale in vielfältiger Weise aufzeichnen. Diese werden in Block-RAMs oder FIFOs gespeichert und durch externe Master ausgelesen. Hier kommen auf der Platine befindliche MCUs oder fremd zugreifende FPGAs / CPUs in Betracht, welche über unterschiedliche Kommunikationsverbindungen (seriell, parallel, LVDS) angeschlossen sind. Dazu werden in die FPGAs entsprechende Cores / Treiber eininstanziiert.&lt;br /&gt;
&lt;br /&gt;
Nachfolgend einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
====Proprietärer serieller Logic Analyzer ====&lt;br /&gt;
&lt;br /&gt;
Die einfachste Möglichkeit ist die direkte Instanziierung eines Blockrams als FIFO mit &amp;quot;breitem&amp;quot; Busanschluss: Linksseitig besitzt das FIFO eine Breite von z.B. 256 Bit (Xilinx-Rams lassen sich ohne weitere Umbeschaltung über den Wizzard mit bis zu 1024 Bits deklarieren und nutzen). Rechtsseitig einen 16- oder 32 Bit breiten Busanschluss für einen Prozessor bzw Parallelinterface oder einen 1 Bit breiten Anschluss für ein serielles streaming interface. Mit einem FiFo-enable können die zu sampelnden Zeiten (Busphasen) festgelegt werden, z.B. anhand eines Kriteriums wie die Erfüllung einer bestimmten mathematischen Bedingung, die man in VHDL formuliert, oder es wird einfach ein Trigger gesetzt. Solange das FiFo nicht voll ist, kann geschrieben werden, was durch die interne FiFo-Verwaltung selbst bereits komplett geregelt wird.&lt;br /&gt;
&lt;br /&gt;
Beim einfachen seriellen Logic Analyzer benötigt man nur noch einen kleinen Core, der permanent das FiFo liest, und den seriellen Overhead (Startbit, Stoppbit, Parity und gfs CRC) hinzufügt. Mit einem einfach Pegelwandler kann so ein PC direkt angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Auch denkbar ist die Anbindung an ein fremdes FPGA-board mit viel Speicher über (LV-)DS-Kommunikation. In komplexeren Systemen wird ein CAN- oder USB-Core eingesetzt.&lt;br /&gt;
&lt;br /&gt;
Wenn mittels des Kriteriums nur ganz bestimmte kritische Phasen herausgesampelt werden (z.B. das Auftauchen eines bestimmten Rechenfehlers im FPGA) und so das Datenaufkommen je Zeiteinheit über längere Zeit betrachtet eher gering ist, kann bei geeignetem Datendurchsatz in Echtzeit dauerhaft mitprotokolliert werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== BusProbe, der Debugging Core von abaxor engineering  ====&lt;br /&gt;
Mit der BusProbe kann der Entwickler den Signalfluss im FPGA-Design auch über einen längeren Zeitraum überwachen und am PC aufzeichnen. Der Core verarbeitet an jedem Eingang einen kompletten Bus. &lt;br /&gt;
&lt;br /&gt;
Die Daten werden gemultiplext zum PC geschickt und dort per Software demultiplext. Im PC erfolgt auch die Auswertung mit beliebigen Analyse-Tools.&lt;br /&gt;
&lt;br /&gt;
Gegenüber dem Betriebssystem verhält sich die BusProbe wie eine Festplatte, von der die Daten mit gewöhnlichen Zugriffen gelesen werden können.&lt;br /&gt;
&lt;br /&gt;
* Streaming der Daten zum PC mit mehr als 20 MByte/s&lt;br /&gt;
* keine Treiber im PC da Nutzung von Standardschnittstellen (USB oder IDE)&lt;br /&gt;
* Hot-Plugging&lt;br /&gt;
* Visualisierung mit beliebigen Programmen&lt;br /&gt;
* geringer Logikaufwand&lt;br /&gt;
&lt;br /&gt;
[http://www.abaxor.de/produkte.html abaxor.de-Webseite]&lt;br /&gt;
&lt;br /&gt;
==== open source Logikanalysator von sump.org====&lt;br /&gt;
Ein einfacher, übersichtlicher Logikanalysator findet sich auf sump.org. Er liegt im Quelltext vor wird mit ins Design einsynthetisiert. Als Speicher dient wahlweise SRAM oder intern RAM. Es können 32 Kanäle mit 100 MHz (oder weniger) gesampelt werden. Die Bediensoftware läuft platformunabhängig unter Java und benötigt eine serielle Schnittstelle (auch über USB-seriell Wandler) zum Core.&lt;br /&gt;
&lt;br /&gt;
[http://de.sump.org/projects/analyzer/ sump.org-Webseite]&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Hardwarebeschreibungssprachen]]&lt;br /&gt;
* [[Reset für FPGA/CPLD]]&lt;br /&gt;
* [[Taktung FPGA/CPLD]]&lt;br /&gt;
* Projekt [[Audio-DSP mit Spartan 3-FPGA]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.fpga4fun.com/index.html FPGA4Fun] - FPGA-Projekte, größtenteils mit Altera und Verilog&lt;br /&gt;
* [http://video.google.com/videoplay?docid=-4969729965240981475 Ein Vortrag, auf Englisch: General Purpose, Low Power Supercomputing Using Reconfiguration Logic]&lt;br /&gt;
* http://www.opencores.org - FPGA-Projekte, Opensource, jeder kann seine Eigenen einstellen und an anderen mitarbeiten. U.a. gibt es verschiedene CPUs für FPGAs.&lt;br /&gt;
* [http://members.optushome.com.au/jekent/FPGA.htm John&#039;s FPGA Page]&lt;br /&gt;
* [http://www.embedded.com/columns/whatsnew/197003073 More about designing with embedded FPGAs] by Bernard Cole, Embedded.com&lt;br /&gt;
&lt;br /&gt;
[[Category:FPGA und Co]]&lt;/div&gt;</summary>
		<author><name>Blackhat-blade</name></author>
	</entry>
</feed>