<?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=80.146.250.2</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=80.146.250.2"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/80.146.250.2"/>
	<updated>2026-04-10T23:38:39Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Verilog&amp;diff=45824</id>
		<title>Verilog</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Verilog&amp;diff=45824"/>
		<updated>2010-04-07T12:30:00Z</updated>

		<summary type="html">&lt;p&gt;80.146.250.2: /* Arithmetische Operationen, signed, $signed */&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.&amp;amp;nbsp;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.&amp;amp;nbsp;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.&amp;amp;nbsp;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; // ??? Widerspruch zu &amp;quot;Ein reg muss innerhalb eines always oder initial Blocks seine Werte zugewiesen bekommen&amp;quot;&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 nun in diesem Beispiel die Zuweisung nur beim Wechsel von 0 auf 1 stattfinden, kann es 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 wird von dem &#039;&#039;wire&#039;&#039;-Statement abgeleitet. Er wird in der Form &#039;&#039;wire [msb:lsb] &amp;lt;wire_name&amp;gt;&#039;&#039; spezifiziert und 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;          // Setze nur Bit 0&lt;br /&gt;
&lt;br /&gt;
  data[15:13] = 3&#039;b110;   // Setze Bits 15, 14 = 1, Bit 13 = 0, Wert ist binär&lt;br /&gt;
  data[13:11] = 3&#039;d2;     // Setze Bits 13-11, Wert ist dezimal&lt;br /&gt;
  data[10:1]  = 9&#039;h0a;    // Setze 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.&amp;amp;nbsp;B. Felder bekannt, um Elemente mit gleichem Datentyp zusammen zu fassen. Der gleiche Konstrukt ist in Verilog möglich und wird z.&amp;amp;nbsp;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.&amp;amp;nbsp;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.&amp;amp;nbsp;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.&amp;amp;nbsp;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 = 14&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 16-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 = 14&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.&amp;amp;nbsp;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.&amp;amp;nbsp;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.&amp;amp;nbsp;B. von einem Programm eingelesen und dargestellt werden. Ein solches Programm ist z.&amp;amp;nbsp;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.&amp;amp;nbsp;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.&amp;amp;nbsp;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>80.146.250.2</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Logic_Analyzer-Projekt:_Ideen_zur_Hardware&amp;diff=21733</id>
		<title>Logic Analyzer-Projekt: Ideen zur Hardware</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Logic_Analyzer-Projekt:_Ideen_zur_Hardware&amp;diff=21733"/>
		<updated>2007-05-24T10:44:50Z</updated>

		<summary type="html">&lt;p&gt;80.146.250.2: /* Lastenheft */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel gehört zum Projekt &#039;Logic Analyzer&#039;, das von einigen Nutzern dieser Seite gemeinsam entwickelt wird. Eine Übersicht über verschiedene Projekte, die die Entwicklung eines Logikanalysators zum Ziel haben, gibt es unter [[Logic Analyzer Project]].&lt;br /&gt;
&lt;br /&gt;
Ein Logikanalysator dient zur Analyse von digitalen, logischen Signalen an zumeist mehreren Datenleitungen (Bussysteme), über die einzelne Bauteile/Komponenten kommunizieren.&lt;br /&gt;
&lt;br /&gt;
Ein [[Oszilloskop]] hingegen dient überwiegend zur Analyse von analogen Signalverläufen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Lastenheft =&lt;br /&gt;
&lt;br /&gt;
Hier mal das Lastenheft für den Logic Analyser (LA). Bitte je nach Anforderung einen Strich mittels ALT GR + &amp;lt;&amp;gt; Taste links neben dem Ypsilon.&lt;br /&gt;
Die Aufteilung könnt ihr ja ändern/erweitern falls was fehlt. Ich gebe mal meine Maximalanforderungen ein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Kanalanzahl&#039;&#039;&#039;&lt;br /&gt;
* .8 Kanäle: |||&lt;br /&gt;
* 16 Kanäle: ||||| ||||| ||||&lt;br /&gt;
* 20 Kanäle: |&lt;br /&gt;
* 24 Kanäle: |&lt;br /&gt;
* 32 Kanäle: ||||| &lt;br /&gt;
* Modular (erweiterbar X mal 8/16 Kanäle): |||&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Samplingfrequenz&#039;&#039;&#039;&lt;br /&gt;
* ...8 MHz : ||&lt;br /&gt;
* ..16 MHz : |&lt;br /&gt;
* ..32 MHz : ||||&lt;br /&gt;
* .&amp;gt;32 MHz : ||||| ||||| ||||| ||&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Speichertiefe&#039;&#039;&#039;&lt;br /&gt;
*....32 kByte: |&lt;br /&gt;
*....64 kByte:&lt;br /&gt;
*...128 kByte: |&lt;br /&gt;
*...256 kByte: ||||| &lt;br /&gt;
*...512 kByte: &lt;br /&gt;
*..1024 kByte: ||&lt;br /&gt;
*..Konfigurierbar ||&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Wäre es nicht sinnvoller, die Speichertiefe in &amp;quot;Samples&amp;quot; anzugeben. So macht das nicht viel Sinn, da die Anzahl der Samples wenn man immer nur 8 Bits abspeichert ne andere ist als wie wenn man 32 Bits pro Sample speichert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;integrierter Pattern Generator&#039;&#039;&#039;&lt;br /&gt;
* .8 Kanäle : ||||&lt;br /&gt;
* 16 Kanäle: &lt;br /&gt;
* &amp;gt;16 |&lt;br /&gt;
&lt;br /&gt;
Anm.: könnte bis zu einer gewissen Geschwindigkeit vom AVR erledigt werden... =&amp;gt; u.U. Mega16 drauf&lt;br /&gt;
--[[Benutzer:Hans|Hans]] 14:16, 20. Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Schnittstelle zum Computer&#039;&#039;&#039;&lt;br /&gt;
* Seriell syncron..........: ||&lt;br /&gt;
* Seriell asyncron (RS232).: ||||| |||&lt;br /&gt;
* USB......................: ||||| ||||| ||||| |||&lt;br /&gt;
* Parallelport.............: ||||&lt;br /&gt;
* Ethernet.................: ||&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Am PC läuft/wird laufen&#039;&#039;&#039;&lt;br /&gt;
* Windows .: ||||| ||||| ||||| &lt;br /&gt;
* Linux   .: ||||| ||||| ||||&lt;br /&gt;
* MacOS X .: |&lt;br /&gt;
* Solaris .: |&lt;br /&gt;
* Anderes .: &lt;br /&gt;
&lt;br /&gt;
Anmerkung: Wenn man über WxWidgets/Fox-Toolkit/Qt programmiert, hätte man Win, Linux und MAC erschlagen. COM ist kein Problem, bei USB muss man sehen. Da ist noch nicht viel realisiert. Einen einfachen Treiber sollte man aber hinbekommen können, zumal die Hardware und das Protokoll bekannt sind.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Status =&lt;br /&gt;
&lt;br /&gt;
(-- [[Benutzer:Ope|Ope]] 20:51, 10. M?2006 (CET))&lt;br /&gt;
&lt;br /&gt;
Da der Logic Analyzer (LA) Thread schnell wächst und entsprechend schwer zu verfolgen ist, ständig sich irgend etwas ändert, kommt hier eine Zusammenfassung der Diskussion. Ich versuche sie halbwegs aktuell zu halten, öfteres Vorbeischauen lohnt sich also.&lt;br /&gt;
&lt;br /&gt;
Eine fertige Lösung existiert jedoch noch nicht und einer alleine macht sich tot, zumal derjenige ja auch ein Real-Life hat und kein professioneller Designer für LA ist - daher ist das Projekt auf aktive Hilfe angewiesen sonst wird es sterben!&lt;br /&gt;
&lt;br /&gt;
Auch sind die Threads dazu etwas verteilt (thematisch). Hier die großen:&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-204570.html#new Logic Analyzer bauen] (Initialthread)&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-208137.html#new Pegelkomparator für High-Speed-Digital (Logic Analyzer)]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-9-234597.html#new Logic Analyzer Core (Logic Analyzer)]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-9-207389.html#new CPLD und AVR Kombo (Logic Analyzer)]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-9-221618.html#new Diverse Fragen bezüglich SRAM Anbindung]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-4-228557.html#new Programmieren des CPLDs über den AVR]&lt;br /&gt;
&lt;br /&gt;
Eine reine AVR Lösung scheint sich hier abzuzeichnen:&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-225498.html#new Logic Analyzer bauen, die 2.]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Stand z.Zt.: Es ist nicht tot, aber in einem Dämmerzustand, siehe dazu [#VHDL_LA_Core].&lt;br /&gt;
&lt;br /&gt;
= Das Ziel =&lt;br /&gt;
&lt;br /&gt;
Nun ja, preiswert und universell und für den Großteil der Probleme brauchbar soll er sein. Zudem sollen die Bauteile z.B. auch in Schweiz/Österreich gut verfügbar sein. Dass er sich mit einem LA der großen Hersteller messen lassen kann, ist aufgrund des Hobby Bereiches bzw. Proof-on-Concepts eher unwahrscheinlich. Unter den eben genannten Prämissen sollen die verfügbaren Mittel optimal genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Je nach Ergebnis, Lust und Laune wird es irgendwann evtl. eine Fortsetzung geben - aber das ist Zukunftsmusik.&lt;br /&gt;
&lt;br /&gt;
= Grundlegende Überlegungen =&lt;br /&gt;
&lt;br /&gt;
Im Internet kann man verschiedene, einfache Konzepte für einen LA finden, z.B. mittels Parallelport. Forumgerecht, reicht für einen einfachen LA bereits ein Mikrocontroller aus, der seine Ports pollt um so die Logik Pegel mitzuschneiden. Allerdings ist diese Lösung begrenzt, wenn es um höhere Taktraten geht.&lt;br /&gt;
&lt;br /&gt;
Eine erschwingliche Alternative stellt ein CPLD (Complex programmable logic devices) mit Mikrocontroller/AVR dar. Die CPLD z.B. von Xilinx können mit über 100 MHz arbeiten und sind somit für diese Aufgabe prädestiniert. Leider ist die Anzahl der Macro Zellen zu gering, um eine hohe Speichertiefe zu erreichen. Daher werden die Daten vom CPLD in einen externen SRAM geschrieben. Damit ist der CPLD für die Triggerbedingungen des LA, das Speicherinterface und natürlich das eigentliche sampeln der Eingänge verantwortlich. Der Mikrocontroller liest die Daten des SRAM über den CPLD aus und schickt sie an den Computer, übernimmt also die Kommunikation. Die Software stellt die gesampleten Daten sinnvoll und ansprechend dar.&lt;br /&gt;
&lt;br /&gt;
Um die Störungen gering zu halten, wird als Versorgungspannung 3,3V Vorzug gegeben - ironischer Weise sind die Xilinx CPLDs der XC95000XL Serie mit dieser Spannung preiswerter als in der 5V Version.&lt;br /&gt;
&lt;br /&gt;
Allerdings baut die Lösung mit dem CPLD und externen SRAM sowie Mikrocontroller entsprechend groß und es sollte ja kein Tischgerät werden (CPLD + AVR + SRAM +&lt;br /&gt;
FT245 + EEPROM + Spannungsregler kämen ungefähr auf Europa-Format). Als Abmessungen wurde die Größe einer Zigarettenschachtel als Ziel für gut befunden. Neben den Abmessungen gibt es auch beim Routen des PCB zwischen CPLD und SRAM keine befriedigende Lösung, insbesondere wenn mehrere SRAMs für&#039;s Interleave eingesetzt oder gar Transitional Timing Analysis Mode implementiert wird.&lt;br /&gt;
&lt;br /&gt;
Entsprechend dieser Erkenntnis reicher, ist ein FPGA als eine Komponente des LA in&#039;s Gespräch gekommen. Diese haben genug Platz für Logik und internen SRAM, konkret die Spartan-2 Serie. Diese gibt es in einem lötbaren TQFP Gehäuse - kommt also ohne BGA aus - zu moderaten Preisen.&lt;br /&gt;
&lt;br /&gt;
Da künftig die RS232 Schnittstellen wegfallen und nur noch USB in Hardware unterstützt wird, wird der LA ein USB Interface haben. Dies deckt sich auch mit der Umfrage oben und ist unabhängig von der CPLD+AVR- und FPGA-Lösung.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird im Anhang auf die CPLD-Lösung eingegangen, einfach um die Gedankengänge festzuhalten - auch wenn es an sich überholt ist.&lt;br /&gt;
&lt;br /&gt;
= Hardware Komponenten =&lt;br /&gt;
&lt;br /&gt;
== Interface LA &amp;lt;-&amp;gt; DUT (Device under Test) ==&lt;br /&gt;
&lt;br /&gt;
Prinzipiell gibt es zwei Wege, wie der LA an seine Informationen kommt:&lt;br /&gt;
* Der rein digitale Weg geht z.B. über 74AHC245 oder 74ACT14 o.ä. womit allerdings die Logikpegel feststehen. &lt;br /&gt;
* Ein anderer Weg geht über Analog-Komparatoren, bei denen die Logikpegel (Threshold) variabel sind und somit auch am flexibelsten für die verschiedenen Logikfamilien [http://www.mikrocontroller.net/attachment.php/209385/Scan0004.png] ist.&lt;br /&gt;
&lt;br /&gt;
=== Analoge Komparator Lösung ===&lt;br /&gt;
&lt;br /&gt;
Für die Komparatorlösung steht momentan der [http://pdfserv.maxim-ic.com/en/ds/MAX961-MAX999.pdf MAX964] und&lt;br /&gt;
[http://www.analog.com/UploadedFiles/Data_Sheets/155150085AD8564_a.pdf AD8564] &lt;br /&gt;
zur Debatte. Allerdings ist der MAX964 schwer zu beschaffen und bereits in der Dualvariante teurer als der AD8564 (ca. 10 Euro). Auch müssen diese mit 5V betrieben werden (wegen der TTL-Eingänge und da der Eingangsspannungsbereich von der VCC abhängt), wodurch Pegelwandler wie der 74LVC245 zum CPLD notwendig werden. Auch die Threshold-Reference muss in diesem Bereich liegen. Diese Schwelle wird durch einen DAC vorgegeben, der vom µC über SPI gesteuert wird. Dieser sollte eine interne Referenz besitzen um mit möglichst wenig Bauelementen auszukommen. Zudem sollte er über zwei Kanäle verfügen, da aktuell der LA über 2 pods mit jeweils einem 8 Bit-Channel verfügen soll. Z.Zt. scheint die beste Wahl hinsichtlich Parameter, Preis und Verfügbarkeit die   [http://focus.ti.com/lit/ds/symlink/tlv5626.pdf TLV5626], [http://focus.ti.com/lit/ds/symlink/tlv5637.pdf TLV5637] und [http://focus.ti.com/lit/ds/symlink/tlv5638.pdf TLV5638] mit 8, 10 bzw. 12 Bit zu sein. Der Einsatz eines DAC wird wesentlich einfacher als eine PWM per µC mit anschließendem Tiefpass mit OPVs, welches die Fehlerrate steigen lassen kann. &lt;br /&gt;
&lt;br /&gt;
Alles in allem eine komplexe Angelegenheit, weshalb sie in der ersten Version des LA fallen gelassen wurde.&lt;br /&gt;
&lt;br /&gt;
=== Digitale Lösung ===&lt;br /&gt;
&lt;br /&gt;
Die einfachste Lösung besteht in einem Levelshifter wie dem 74LVC4245 [http://www.standardics.philips.com/products/levelshifters/alvc164245a/]. Er wird mit 2 Betriebsspannungen versorgt - die FPGA-Seite mit 3,3 V und die Eingangsseite mit variabler Spannung bzw. 3,3 V oder 5 V. Diese Spannung kann per PWM durch den Mikrocontroller erzeugt werden und ermöglicht so, variable Logikpegel am DUT abzugreifen.&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Betrachtungen ===&lt;br /&gt;
&lt;br /&gt;
Weiterhin besteht Einigkeit in der notwendigen Schutzschaltung, damit die Eingangsspannung den max. Input Voltage Range (je nach Typ) bzw. Strom nicht überschreiten kann:&lt;br /&gt;
* Dioden-Array (bringt Speed-Probleme aufgrund der Sperrschichtkapazität, sofern man keine teuren Spezialdioden verwendet) &lt;br /&gt;
* Serienwiderstand&lt;br /&gt;
&lt;br /&gt;
== FPGA ==&lt;br /&gt;
&lt;br /&gt;
Momentan ist der XC2S100 bzw. XC2S200 (prefered)&lt;br /&gt;
(http://direct.xilinx.com/bvdocs/publications/ds001.pdf)&lt;br /&gt;
&lt;br /&gt;
Das externe SRAM entfällt durch den internen des FPGA, da die größeren FPGAs ausreichend interne Speichermöglichkeit haben und das Platinenlayout durch einen&lt;br /&gt;
externen SRAM um ein vielfaches komplizierter werden würde. &lt;br /&gt;
Für den FPGA haben wir derzeit das PQ208-Gehäuse im Auge, dort ist der&lt;br /&gt;
FPGA etwa 2/3 so teuer wie im TQ144 und kann noch nach oben erweitert&lt;br /&gt;
werden - für die, die mehr Speicher brauchen.&lt;br /&gt;
&lt;br /&gt;
Der interne Speicher ist 40k bzw 56k, wobei nur&lt;br /&gt;
Sample-Änderungen abgespeichert werden um den Block-RAM (echter interner&lt;br /&gt;
RAM) besser ausnützen zu können. Yep, er ist veraltet etc., aber&lt;br /&gt;
verfügbar und im TQ144 oder PQ208 (prefered, da derzeitig bestellbar)&lt;br /&gt;
verhältnissmäßig preiswert zu bekommen. Siehe auch&lt;br /&gt;
http://www.mikrocontroller.net/forum/read-1-204570.html#new.&lt;br /&gt;
&lt;br /&gt;
Der FPGA LA Core wird in VHDL geschrieben.&lt;br /&gt;
&lt;br /&gt;
== Interface zwischen LA und PC == &lt;br /&gt;
&lt;br /&gt;
In der FPGA-Lösung bietet sich der FTDI FT2232C [http://www.ftdichip.com/Documents/DataSheets/ds2232c_14.pdf] (Dual USB UART/FIFO) an, wie er auch im UXIBO [http://www.uxibo.de/] Verwendung findet. Damit kann der FPGA per USB über die erste Schnittstelle im Bit-Bang-Mode geflasht werden und über die zweite mit dem PC kommunizieren.&lt;br /&gt;
&lt;br /&gt;
Die erste Begeisterung verschwand, nachdem die Preise bekannt waren. Daher wurde  ein AT91SAM7S321/64 mit internen USB gewählt, welcher preiswerter ist und zudem die Mikrocontroller-Fähigkeiten in den LA bringt. Der AT91SAM7S wird per USB (nur Buchse und Widerstände erforderlich) über SPI an den FPGA angebunden.&lt;br /&gt;
&lt;br /&gt;
Zudem hat der AT91SAM7 den Vorteil, dass er über USB programmierbar ist via SAM Boot Assistant (SAM-BA) (User Guide [http://www.atmel.com/dyn/resources/prod_documents/doc6132.pdf]).&lt;br /&gt;
&lt;br /&gt;
== Stromversorgung ==&lt;br /&gt;
&lt;br /&gt;
Der FPGA benötigt 2,5 V für den Core selbst und eine weitere Spannung für die I/O. Hier bietet sich 3,3 V an, da dann der SAM7 und der Levelshifter 74LVC4245 damit betrieben werden können. TI bietet hierzu den TPS70358 [http://focus.ti.com/lit/ds/symlink/tps70358.pdf] (2.5/2A + 3.3V/1A) an. Dieser besitzt ein Powerpad unter dem Chip, welches die meisten wohl kaum anlöten können. Aber dafür ist die Strombelastbarkeit total überdimensioniert, d.h. etwas Wärmeleitpaste sollte das Problem (hoffentlich) lösen.&lt;br /&gt;
&lt;br /&gt;
Für die variable Spannung auf der Probenseite bzw. 74LVC4245 scheint der TPS62222 [http://focus.ti.com/docs/prod/folders/print/tps62220.html] eine Lösung zu bieten. Er kann eine einstellbare Spannung erzeugen. Die Vorgabe geschieht entweder mit per PWM erzeugter Sollspannung durch den SAM7 (analog zum STK500 [http://www.avrfreaks.net/Tools/ToolFiles/115/STK500_Schematics.pdf]) oder durch ein digitales Potentiometer bzw. analogem Switch und Widerständen und Ähnlichen, wobei die PWM-Lösung die preiswertere Alternative darstellt.&lt;br /&gt;
&lt;br /&gt;
Indirekt heißt dies aber auch, dass mit einem Bus powered LA nicht zu rechnen ist...&lt;br /&gt;
&lt;br /&gt;
= Software =&lt;br /&gt;
&lt;br /&gt;
== VHDL LA Core ==&lt;br /&gt;
&lt;br /&gt;
Dieser ist in VHDL geschrieben und imo die Hauptarbeit. Bisher sind:&lt;br /&gt;
&lt;br /&gt;
* die Trigger komplett geschrieben und getestet (pattern/edge on Low, High und Don&#039;t Care und Condition length),&lt;br /&gt;
* die Probe ist registered wegen der Meta-Stabilität,&lt;br /&gt;
* die Speicherorganisiation des internen RAMs, &lt;br /&gt;
* das handling der Timestamps und &lt;br /&gt;
* eine FSM mit Registerset zur rudimentären Steuerung,&lt;br /&gt;
* ein arithmetischer Trigger existiert auch, ist aber nicht eingebunden (z.B. für Addressvergleiche als Trigger).&lt;br /&gt;
* Clk Management per DLL.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung FPGA zum Mikrocontroller per SPI fehlt komplett (SPI Cores z.B. von Jörn sind im Forum aber vorhanden). &lt;br /&gt;
&lt;br /&gt;
Mit dem VHDL LA Core gehen die eigentlichen Probleme des LA los. Da ich (ope) als einziger LA-Projekt-Programmierer und VHDL-Neuling (bisher nur C/C++) mir das Coden auf die Fahnen geschrieben habe, dauert es entsprechend lange. Das ursprüngliche Ziel, den Core bis Ende 2005 fertig zu bekommen, ist an vielen kleinen Problemen und am Zeitaufwand gescheitert (eben ein Feierabend-Projekt). Viel Zeit nimmt das Schreiben der Testbenches in Anspruch. Weitere Zeit vergeht für die Fehlersuche im Source, aber auch als Bug-Hunter in XST (das übersteigt dann doch meine derzeitigen Fähigkeiten).&lt;br /&gt;
&lt;br /&gt;
Da der Speicher intern nur begrenzt ist, wurde ein Transitional Timing Analysis Mode realisiert d.h. nur Bit-Änderungen werden mit einem Timestamp gespeichert. Dummerweise sind 3 Samples beim Auslesen des Speichers am falschen Ende (oberste 3 Addressen), obwohl sie am Anfang sein sollten (unterste 3 Adressen). Irgendwann habe ich dann die Lust verloren, da auch keiner helfen konnte...&lt;br /&gt;
&lt;br /&gt;
== ARM Core ==&lt;br /&gt;
&lt;br /&gt;
Keine konkreten Überlegungen bisher?&lt;br /&gt;
&lt;br /&gt;
== PC Frontend ==&lt;br /&gt;
&lt;br /&gt;
Nichts passiert. Für C++ ist WxWindows, Qt und eben Fox-Toolkit interessant. Aber Fox Toolkit [http://www.fox-toolkit.org],&lt;br /&gt;
[http://wiki.wxwidgets.org/wiki.pl?WxWidgets_Compared_To_Other_Toolkits],&lt;br /&gt;
[http://lists.trolltech.com/qt-interest/2002-06/msg01202.html] ist imo die Alternative zu WxWindows/Qt und von mit (ope) favorisiert.&lt;br /&gt;
&lt;br /&gt;
WxWindows/WxWidgets hat Altlasten, die gehen bis Win 3.1 zurück, Qt&lt;br /&gt;
behagt mir die Geschichte mit den Moc Compiler nicht; auch wenn ich mit&lt;br /&gt;
Qt bereits (gute) Erfahrung habe, aber die neue Politik unter Windows&lt;br /&gt;
behagt mir nicht - dir wird der Compiler vorgeschrieben, aber man wird&lt;br /&gt;
mit dem mingw alleine gelassen. Von der Seite her gibt&#039;s für mich&lt;br /&gt;
keinen Grund unbedingt Qt nehmen zu müssen. FLTK und Gtk lasse ich mal&lt;br /&gt;
ganz außen vor.&lt;br /&gt;
&lt;br /&gt;
Auch sollen viele Dinge in Fox besser gelöst sein, allerdings ist diese&lt;br /&gt;
auch jünger, so dass wohl auch einige GUI-Klassen geschrieben werden&lt;br /&gt;
müssen. Mal sehen, ob sich Cairo&lt;br /&gt;
(http://cairographics.org/introduction) einbinden lässt, dann hätte man&lt;br /&gt;
gleich PDF Wave Plot Export prints und bessere Screen Graphic (kann aber&lt;br /&gt;
auch Overkill sein). Jedoch sind diese Aussagen eben ungeprüft.&lt;br /&gt;
&lt;br /&gt;
= PCB =&lt;br /&gt;
&lt;br /&gt;
Hier muss Dirk schreiben :-)&lt;br /&gt;
&lt;br /&gt;
= Resumee =&lt;br /&gt;
&lt;br /&gt;
Keep-It-Simple ist ein Grundsatz hier. Je komplexer, desto schwerer zu beherrschen. Sicher hat jeder von Komplexität eine andere Vorstellung, aber wir arbeiten daran und hoffen ein nachbaufähiges, stabiles Gerät zu bekommen. Dennoch kommt man bei diesem Projekt um SMD-Löten mit 0,5 mm-Beinchen nicht umhin!&lt;br /&gt;
&lt;br /&gt;
= Und was soll das kosten? =&lt;br /&gt;
&lt;br /&gt;
Schwierig, da noch nicht alles feststeht - als Ziel steht aber im Forum mehr oder weniger ungeschrieben die 100&amp;amp;#8364; Marke einschließlich PCB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Literatur =&lt;br /&gt;
&lt;br /&gt;
* [http://web.mit.edu/6.111/www/s2005/HANDOUTS/LA.pdf] Agilent XYZs of Logic Analyzers&lt;br /&gt;
* [http://cp.literature.agilent.com/litweb/pdf/5988-9125EN.pdf] Agilent Logic Analyzer Probing Techniques for High-Speed Digital Systems &lt;br /&gt;
* [http://www.home.agilent.com/USeng/nav/-536898184.0/pc.html] Agilent Logic Analyzer Probing Solutions&lt;br /&gt;
* [http://www.designcon.com/2003/marketing/HP3-5.pdf] Logic Analyzer Probing Techniques for High-Speed Digital Systems (DesignCon 2003)&lt;br /&gt;
* [http://www.signalintegrity.com/Pubs/straight/probes.htm] Probing High-Speed Digital Designs (Electronic Design Magazine, March, 1997)&lt;br /&gt;
* [http://www.xilinx.com/bvdocs/appnotes/xapp368.pdf] Handheld Pocket Logic Analyzer (XApp368)&lt;br /&gt;
* [http://www.xilinx.com/bvdocs/appnotes/xapp369.pdf] Handheld 1553 Bus Data Analyzer (XApp369)&lt;br /&gt;
* [http://www.amateurfunkbasteln.de/pcla/pcla.html] PC-basierter 32-Kanal-Logik-Analysator&lt;br /&gt;
* [http://www.bitscope.com] bitscope &lt;br /&gt;
* [http://www.rockylogic.com/products/ant8spec.html] Kommerziell: Ant8 (mit fixer Treshold) und &lt;br /&gt;
* [http://www.rockylogic.com/products/ant16spec.html] Kommerziell: Ant16 (mit variabler Treshold)&lt;br /&gt;
* [http://www.nci-usa.com/default.htm] Kommerziell: GoLogic, mit guten Texten und Videos&lt;br /&gt;
* [http://www.pctestinstruments.com/] Kommerziell: LogicPort (34 Kanäle)&lt;br /&gt;
* [http://alternatezone.com/electronics/pcla.htm] PC LA&lt;br /&gt;
* [http://eebit.com/] FPGA-based Logic Analyzer&lt;br /&gt;
* [http://www.ethernut.de/en/xsvfexec/index.html] XSVF Executor&lt;br /&gt;
* [http://www.cypress.com/portal/server.pt?space=CommunityPage&amp;amp;control=SetCommunity&amp;amp;CommunityID=209&amp;amp;PageID=418&amp;amp;r_folder=Application%20Notes&amp;amp;r_title=Jitter%20in%20PLL%20Based%20Systems:%20Causes,%20Effects,%20and%20Solutions] Jitter in PLL Based Systems: Causes, Effects, and Solutions &lt;br /&gt;
&lt;br /&gt;
* [http://www.standardics.philips.com/packaging/handbook/pdf/pkgchapter5.pdf] SMD Mounting Methods&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Anhang A: Die CPLD/AVR Lösung (veraltet) =&lt;br /&gt;
&lt;br /&gt;
== Der CPLD und das Speicherinterface ==&lt;br /&gt;
&lt;br /&gt;
Nach einigen Hin- und Her hat sich der XC95144XL TQ144 als beste Option herausgestellt. Auch FPGAs waren kurz im Gespräch, aufgrund der sich im Gespräch herausstellenden Komplexität. Allerdings war die Komplexität des FPGA und der Preis auch gleichzeitig das KO-Kriterium dafür.&lt;br /&gt;
&lt;br /&gt;
Kurzinfo XC95144XL TQ144 [http://www.mhl.tuc.gr/data_books/Xilinx/Xc9500/95144XL.pdf]:&lt;br /&gt;
&lt;br /&gt;
* 144Macro, 3.3V, 117 I/O, TQFP144 für ca. 10&amp;amp;#8364; &lt;br /&gt;
&lt;br /&gt;
Dieser bietet genug I/O um:&lt;br /&gt;
&lt;br /&gt;
* 2x SRAM 256k x 16 (jeweils 18 AD, 16 DB, 3 Ctrl)&lt;br /&gt;
* 2x 8-bit-LA-Channel&lt;br /&gt;
* Ext. TriggerIn, TriggerOut&lt;br /&gt;
* SPI Bus zum AVR &lt;br /&gt;
* JTAG&lt;br /&gt;
&lt;br /&gt;
anschließen zu können.&lt;br /&gt;
&lt;br /&gt;
Der Grund für die 2 Speicherbänke liegen in den Möglichkeiten, sich den LA selbst zu konfigurieren für:&lt;br /&gt;
&lt;br /&gt;
* Interleave&lt;br /&gt;
* Speicherung eines Timestamp&lt;br /&gt;
* non-Interleave und non-Timestamp mit nur einem SRAM&lt;br /&gt;
&lt;br /&gt;
Beim Interleave werden zwei 16 Bit Samples im CPLD gelatcht und gemeinsam auf den nun 32 bit breiten Datenbus gelegt. Dabei sind die Adressen für die SRAMs folglich identisch. Damit liegt die Schreibrate beim SRAM bei der Hälfte des Sampleclocks, der entsprechend hoch gesetzt werden kann.&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung des 2x 256k x 16 Bit SRAM eröffnet sich aber weiterhin die Möglichkeit, den Transitional Timing Analysis Mode zu realisieren, d.h. nur Bit-Änderungen werden mit einem Timestamp gespeichert - also ideal für langsame Busse bei hohen Sampleraten. Hier kann man z.B. eine 16 bit Time-Stamp-Adresse (256k) mit einem 16 bit Pattern speichern, oder ein 24 bit Timestamps für 8 bit. Ein Interleave ist dann allerdings nicht mehr möglich. &lt;br /&gt;
&lt;br /&gt;
Als letze Möglichkeit kann man auf alles obige verzichten und nur einen SRAM bestücken. &lt;br /&gt;
&lt;br /&gt;
Der heißeste Kandidat für den Speicher ist derzeit die 61LV25616 (256k*16) asynchrone Serie (zB.[http://www.issi.com/pdf/61LV25616AL.pdf IS61LV25616]), da er gut verfügbar und preiswert sein soll. Bei asynchronen SRAM müssen wie eingangs erwähnt die Adressen und Daten in einem Latch zwischengespeichert werden. Bei einem synchronen SRAM werden die Adressen bei mit Flanke gespeichert, ebenso die Daten. Die Setup- und Hold-Zeiten gehen daher gegen Null... Außerdem muss man WR\ nicht toggeln, was wertvolle Zeit kostet, sondern es reicht, den Speichertakt anzulegen.&lt;br /&gt;
&lt;br /&gt;
Weitere Typen wären&lt;br /&gt;
&lt;br /&gt;
Asynchrone SRAM:&lt;br /&gt;
&lt;br /&gt;
* CY22393,CY22394,CY22395 [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy22393_4_5_5.pdf] mit Layout Hinweisen [http://www.cypress.com/portal/server.pt?space=CommunityPage&amp;amp;control=SetCommunity&amp;amp;CommunityID=209&amp;amp;PageID=418&amp;amp;r_folder=Application%20Notes&amp;amp;r_title=Layout%20Recommendations%20for%20the%20CY2239x%20Devices]&lt;br /&gt;
* AS7C34098-12TCN (256K x 16, 12ns) [http://www.alsc.com/pdf/sram.pdf/fa/AS7C4098.pdf] und AS7C31026B-12TCN (64k x 16, 12ns) Asynchroner SRAM bei Farnell&lt;br /&gt;
&lt;br /&gt;
Synchrone SRAM:&lt;br /&gt;
&lt;br /&gt;
* CY7C1327G (256k*18) [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy7c1327g_5.pdf]&lt;br /&gt;
* CY7C1327F (256k*18) [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy7c1327f_5.pdf]&lt;br /&gt;
* CY7C1327B (256k*18 Synchronous-Pipelined Cache RAM)[http://www.datasheetarchive.com/semiconductors/download.php?Datasheet=598266]&lt;br /&gt;
&lt;br /&gt;
Den CY7C1327B (TQFP100 256Kx18, 3.3V, 4ns ) gibt&#039;s zumindest bei R&amp;amp;S für 11,60&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
== Interface CPLD &amp;lt;-&amp;gt; uC ==&lt;br /&gt;
&lt;br /&gt;
Eine grundlegende Idee ist, dass der CPLD doppelt benutzt wird. Er enthält ja einen Addresszähler zum Schreiben des SRAMs. Dieser kann aber auch zum Lesen des SRAMs benutzt werden. Der SRAM wird immer sequentiell vom PLD geschrieben und gelesen.&lt;br /&gt;
&lt;br /&gt;
Die Daten, Statusinfos etc. werden per SPI vom AVR aus dem CPLD gelesen. Vorteil ist dabei, dass man nun auch z.B. 512 KiB SRAMs benutzen kann ohne dass der µC ein kompliziertes Memory Banking benutzen müsste.&lt;br /&gt;
&lt;br /&gt;
== Interface uC &amp;lt;-&amp;gt; Computer ==&lt;br /&gt;
&lt;br /&gt;
Da die Daten schnell im PC sein sollen, bietet sich USB an, also mit dem &lt;br /&gt;
[http://www.ftdichip.com/Documents/DataSheets/ds245b16.pdf FT245] &lt;br /&gt;
um schneller (2-3 Mbaud) als der &lt;br /&gt;
[http://www.ftdichip.com/Documents/DataSheets/ds232b17.pdf FT232]  (1 Mbaud) &lt;br /&gt;
die Daten zu versenden. FTDI bietet die Treiber für Windows/Linux kostenlos an.&lt;br /&gt;
&lt;br /&gt;
Eine Alternative ist der &lt;br /&gt;
[http://www.silabs.com/public/documents/tpub_doc/dshort/Microcontrollers/Interface/en/CP2102_short.pdf  CP2102], der weniger Bauelemente benötigt aber auch wesentlich schwerer zu löten ist.&lt;br /&gt;
&lt;br /&gt;
µC mit integrierten USB standen auch in der Disskusion. Aufgrund vieler Unwägbarkeiten, wie Beschaffung, Preis, HID Treiber etc. sind diese Ideen wieder verworfen worden.&lt;br /&gt;
&lt;br /&gt;
== Clock Rate Generierung ==&lt;br /&gt;
&lt;br /&gt;
Aufgrund seiner Bandbreite bietet sich die Generierung des Systemtaktes durch den CPLD an. Dieser benutzt einen 1/N-Teiler um den Sample-Takt zu generieren.&lt;br /&gt;
&lt;br /&gt;
Prinzipiell kann er auch gleichzeitig den Takt für den µC erzeugen - dieser wird also extern getaktet und man erhält dadurch Synchronität zwischen CPLD und µC und spart den Quarz am µC. Allerdings bietet sich auch ein eigener Quarz für den µC an. Man sieht - hier wird noch diskutiert.&lt;br /&gt;
&lt;br /&gt;
Zur Generierung des Mastertaktes bieten sich zwei Weg an:&lt;br /&gt;
* Quarz, bei 50 - 64 MHz dürfte da wegen Verfügbarkeit/Preis wohl Schluss sein, auch sind Obertonquarze nicht ganz unkritisch. Auch kann man dann nur noch durch Umlöten und Wecheln den Mastertakt ändern, falls es Probleme gibt.&lt;br /&gt;
* VCO/PLL ggf. per µC programmierbar, damit kann man dann echt die Grenzen des Designs austesten. Die Chips dazu gibt&#039;s bei Maxim/AD und den anderen üblichen Verdächtigen, stehen also noch nicht fest. Als aussichtsreichster Kandidat sticht derzeit der [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy22150_5.pdf CY22150] hervor, der mehrere synchrone Frequenzen mit einem einfachen Quarz erzeugen kann. Dadurch wird der Frequenzteiler im CPLD nicht mehr benötigt und hat wieder einige Macrozellen frei.&lt;br /&gt;
&lt;br /&gt;
Die Grenzen der Samplefrequenz liegen zum einem in den verwendeten Bauelementen (&amp;gt; 100 MHz), aber vielmehr wird der begrenzende Faktor das Layout und die Leiterplatte sein. Ein 4-Layer-PCB ist aus technischer Sicht sicher das Optimale, nur schaut der Geldbeutel danach sehr leer aus; auch wird ein Komparatoreingang ca. 45 Euro teurer werden als eine Lösung mit 74xxx.&lt;br /&gt;
&lt;br /&gt;
== Stromversorgung ==&lt;br /&gt;
&lt;br /&gt;
Tja, auch ein LA braucht Strom. Bei Verwendung eines USB kann dieses elegant gelöst werden, da dieser (nach Anforderungen an das OS) bis zu 500 mA liefern kann. Eine kurze worst-case &amp;quot;Stromrechnung&amp;quot; zeigt:&lt;br /&gt;
&lt;br /&gt;
* XC95144XL CPLD pauschal 150 mA lt. DB&lt;br /&gt;
* 61LV25616 SRAM 2x 320 mA&lt;br /&gt;
* ATmega ???&lt;br /&gt;
* FT245 ????&lt;br /&gt;
&lt;br /&gt;
mit MAX964 8 mA/Comparator x 16 kommen 128 mA hinzu.&lt;br /&gt;
&lt;br /&gt;
Die FTDI-Chips haben für Geräte, die über 100 mA ziehen (in diese Kategorie wird wohl der LA u.U. fallen), aber noch bus-powered sein sollen, einen Schaltausgang, an den z.B. ein p-Kanal-FET angeschlossen werden kann, der den stromhungrigen Teil der Schaltung erst nach der  Registrierung beim Computer einschaltet. Dazu hat er einen &amp;quot;sleep&amp;quot;-Ausgang, mit dem man den angeschlossenen AVR schlafen legen kann. In den FTDI-Docs bzw. Application Notes finden sich dazu genug Beispiele mit kompletten Schaltbildern. Allerdings ergibt die Überschlagsrechnung, dass ein externes Steckernetzteil notwendig wird.&lt;br /&gt;
&lt;br /&gt;
Einsetzbar wäre auch ein LM2575S-3.3 [http://www.national.com/ds/LM/LM1575.pdf] für 2,47&amp;amp;#8364; (Farnell), der sieht gut und einfach in der Handhabung aus im Falle einer externen Stromversorgung.&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
&lt;br /&gt;
=== AVR ===&lt;br /&gt;
Recht früh hat sich im Forum heraus kristallisiert, dass der AVR per Bootloader vom Computer her programmiert werden sollte. Hierdurch sind Firmware Updates sehr einfach möglich und verschiedene Bootloader sind verfügbar. Die Bootloader Option setzt damit einen AVR der ATmega-Serie vorraus.&lt;br /&gt;
&lt;br /&gt;
Der AVR braucht folgende Anschlüsse:&lt;br /&gt;
* JTAG (4 Pins)&lt;br /&gt;
* SPI (3 Pins + ~4 CS Leitungen)&lt;br /&gt;
* FTDI (12 Pins)&lt;br /&gt;
* LEDs (2 Pins)&lt;br /&gt;
&lt;br /&gt;
Demnach ist ein 40-poliger nötig. Es wird ein ATmega16 angesetzt.&lt;br /&gt;
&lt;br /&gt;
=== CPLD ===&lt;br /&gt;
&lt;br /&gt;
Die Programmierung des CPLD ist dagegen noch nicht konkret. Wünschenswert wäre es, ebenfalls seine Firmware über den Computer updaten zu können.&lt;br /&gt;
&lt;br /&gt;
Der Standardweg der Programmierung der Xilinx CPLD sieht einen JTAG Stiftsockel vor. Dann kann die Programmierung z.B. über ein Xilinx JTAG/Parallel Download Cable [http://www.xilinx.com/support/programr/jtag_cable.pdf] aus dem ISE/impact geschehen.&lt;br /&gt;
&lt;br /&gt;
Einen möglichen Weg stellt die XApp058 [http://direct.xilinx.com/bvdocs/appnotes/xapp058.pdf] dar, darin wird beschrieben, wie der CPLD mittels µC beschrieben wird. &lt;br /&gt;
&lt;br /&gt;
Dieses Thema wurde bereits im Forum &amp;quot;AVR Ethernet Platine&amp;quot; aufgegriffen. In diesem Thread [http://www.mikrocontroller.net/forum/read-1-138024.html#157356] kam man allerdings zu der Überzeugung, dass die XSVF Datei mit 45 kB für µC-Verhältnisse extrem groß ist und somit nur in einen ATmega128 (und größer) [http://www.atmel.com/dyn/products/devices.asp?family_id=607#760] reinpassen würde, da das SVF JTAG Protokoll riesige Datenbuffer im SRAM benötigt. Dies ist protokollbedingt - es wurden 10 kB für ein FPGA genannt. Dabei sind die Xilinx CPLD Speicherplatz-effizienter als welche von Altera. Leider sind die Xilinx CPLD eben nur über JTAG programmierbar. &lt;br /&gt;
&lt;br /&gt;
Allerdings wurde in diesem Zusammenhang auch auf den XSVF Executor [http://www.ethernut.de/en/xsvfexec/index.html] verwiesen.&lt;br /&gt;
Auch ist die Frage noch offen, inwiefern die XSVF Datei über die RS232/USB geladen werden kann, ebenso das Timing der JTAG Schnittstelle.&lt;br /&gt;
&lt;br /&gt;
Dies lässt sich z.B. ähnlich dem Projekt in der Codesammlung machen [http://www.mikrocontroller.net/forum/read-4-228557.html#233821]. Dann ist zum Programmieren des CPLDs nur eine Software auf dem PC nötig, die Daten werden über USB oder RS232 an den AVR gesandt und dort umgesetzt.&lt;br /&gt;
&lt;br /&gt;
Aufgrund der vielen offenen Fragen ist die schnellste und sicherste Lösung die Anbindung über den JTAG Stecker um den CPLD per JTAG/Parallel Download Cable zu programmieren. Zusätzlich wird eine JTAG-Verbindung zum AVR-Port eingerichtet, falls das Problem irgendwann später gelöst wird.&lt;br /&gt;
&lt;br /&gt;
Bisher existiert in VHDL für den CPLD LA Core:&lt;br /&gt;
&lt;br /&gt;
* Trigger (bit pattern, rising/falling/any edge) verifiziert mit TB&lt;br /&gt;
* SRAM Interface&lt;br /&gt;
&lt;br /&gt;
== PCB ==&lt;br /&gt;
&lt;br /&gt;
Dieses Thema kommt noch intensiv.&lt;br /&gt;
&lt;br /&gt;
Dabei sind u.a. die folgenden Application Notes nützlich:&lt;br /&gt;
&lt;br /&gt;
für AVR:&lt;br /&gt;
&lt;br /&gt;
* AVR040: EMC Design Considerations [http://www.atmel.com/dyn/resources/prod_documents/doc1619.pdf]&lt;br /&gt;
* AVR042: AVR Hardware Design Considerations [http://www.atmel.com/dyn/resources/prod_documents/doc2521.pdf]&lt;br /&gt;
&lt;br /&gt;
für CPLD:&lt;br /&gt;
&lt;br /&gt;
* Device Package User Guide [http://www.xilinx.com/bvdocs/userguides/ug112.pdf]&lt;br /&gt;
* XAPP112 - Designing With XC9500XL CPLDs [http://www.xilinx.com/bvdocs/appnotes/xapp112.pdf]&lt;br /&gt;
* XAPP114 - Understanding XC9500XL CPLD Power [http://www.xilinx.com/bvdocs/appnotes/xapp114.pdf]&lt;br /&gt;
* XAPP115 - Planning for High Speed XC9500XL Designs [http://www.xilinx.com/bvdocs/appnotes/xapp115.pdf]&lt;br /&gt;
* XAPP784 - Bulletproof CPLD Design Practices [http://www.xilinx.com/bvdocs/appnotes/xapp784.pdf]&lt;br /&gt;
&lt;br /&gt;
== Datenblätter, Bezugsquellen und Preise (allg.) ==&lt;br /&gt;
&lt;br /&gt;
... oder was bisher so zusammengetragen wurde.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &#039;&#039;&#039;IC&#039;&#039;&#039;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &#039;&#039;&#039;Gehäuse&#039;&#039;&#039;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &#039;&#039;&#039;Kommentar&#039;&#039;&#039;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &#039;&#039;&#039;Datenblatt/Appnotes&#039;&#039;&#039;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &#039;&#039;&#039;Bezugsquelle&#039;&#039;&#039;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &#039;&#039;&#039;Preis&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;CPLD&#039;&#039; / XC95144XL10TQ144&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TQFP144&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.mhl.tuc.gr/data_books/Xilinx/Xc9500/95144XL.pdf], [http://www.xilinx.com/xlnx/xweb/xil_publications_index.jsp?category=Publications/CPLD+Device+Families&amp;amp;iLanguageID=1]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.darisus.de/Elektonikshop/Framesets/Shopset1.php Darius.De]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | ca. 10&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;USB&#039;&#039; / CP1202&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.silabs.com/public/documents/tpub_doc/dshort/Microcontrollers/Interface/en/CP2102_short.pdf] &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;USB&#039;&#039; / FT232BM&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | LQFP-32&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Converter IC RS232/RS422 USB/Seriell Interface&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.ftdichip.com/Documents/DataSheets/ds232b17.pdf], [http://www.ftdichip.com/Documents/AppNotes.htm]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.Reichelt.de Reichelt.de]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 6,35&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;USB&#039;&#039; / FT245BM&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | LQFP-32&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | USB FIFO, parallel Interface&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.ftdichip.com/Documents/DataSheets/ds245b16.pdf], [http://www.ftdichip.com/Documents/AppNotes.htm]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.Reichelt.de Reichelt.de]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 6,45&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Comp&#039;&#039; / Max964 (Maxim)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | SO-16&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &#039;&#039;&#039;Quad&#039;&#039;&#039; Beyond-the-Rails Comparators, 4.5ns, 3V/5V&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://pdfserv.maxim-ic.com/en/ds/MAX961-MAX999.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Comp&#039;&#039; / AD8564 (Analog Devices)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TSSOP-16&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &#039;&#039;&#039;Quad&#039;&#039;&#039; 7 ns Single Supply 5V Comparator&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.analog.com/UploadedFiles/Data_Sheets/155150085AD8564_a.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.spoerle.de Spörle.de]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 8,80&amp;amp;#8364; Netto&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Comp&#039;&#039; / LT1715 (LT)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Dual 4ns, 5V/3V, Independent I/O Supplies&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1154,C1004,C1012,P1908,D2821]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Comp&#039;&#039; / LT1720/LT1721 (LT)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Dual/Quad 4.5ns, 3V, Rail-to-RailOut, Quad schlecht für&#039;s Layout&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1154,C1004,C1012,P1707,D3080]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Comp&#039;&#039; / TLV3502 (TI/BB) &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | SOIC-8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 4.5ns Rail-to-Rail, Dual High-Speed Comparator &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://focus.ti.com/lit/ds/symlink/tlv3502.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;ECL-Comp&#039;&#039; / Max9600 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Schwierig zu realisieren: 2 &amp;quot;Wandlungsstufen&amp;quot; notwendig. 1x Inputpegel -&amp;gt; ECL, 1x ECL -&amp;gt; Logikpegel CPLD&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://pdfserv.maxim-ic.com/en/ds/MAX9600-MAX9602.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DAC&#039;&#039; / TLV5626 (TI)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | SOIC-8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 8-Bit Dual, 3.3V, int. Uref 1.024V&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://focus.ti.com/lit/ds/symlink/tlv5626.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.farnell.de Farnell.De]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 5.29&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DAC&#039;&#039; / TLV5637 (TI)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | SOIC-8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 10-Bit Dual, 3.3V, int. Uref 1.024V&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://focus.ti.com/lit/ds/symlink/tlv5637.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.farnell.de Farnell.De]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 6.35&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DAC&#039;&#039; / TLV5638 (TI)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | SOIC-8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 12-Bit Dual, 3.3V, int. Uref 1.024V&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://focus.ti.com/lit/ds/symlink/tlv5638.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.farnell.de Farnell.De]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 7.44&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DAC&#039;&#039; / LTC1446L (LT)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | SO-8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Dual 12-Bit, 3.3V, int. Uref=2.5V&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1155,C1005,C1156,P1507,D1746]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.rsonline.de R&amp;amp;S (DE)]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 12.35&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Clk&#039;&#039; / CY22393,CY22394,CY22395&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy22393_4_5_5.pdf] ,[http://www.cypress.com/portal/server.pt?space=CommunityPage&amp;amp;control=SetCommunity&amp;amp;CommunityID=209&amp;amp;PageID=418&amp;amp;r_folder=Application%20Notes&amp;amp;r_title=Layout%20Recommendations%20for%20the%20CY2239x%20Devices]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Clk&#039;&#039; / ICD2053B &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.commtech-fastcom.com/data_sheets/icd2053b.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Clk&#039;&#039; / CY22150FC&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 16-lead TSSOP&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Taktgeber, Three-PLL, SPI progr. Taktgenerator&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy22150_5.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.rsonline.de R&amp;amp;S (DE)]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 3,94&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;SRAM&#039;&#039; / IC61LV25616&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TSOP-2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | asynchroner SRAM 256KB x 16&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://web.icsi.com.tw/domino/packinfo.nsf/4E09C79E58017C3448256F320003A56F/$FILE/22_61LV25616.Pdf],[http://www.icsi.com.tw/english/products/products-frame.asp?Title=Datasheet-Async%20SRAM&amp;amp;URL=http%3A//web.icsi.com.tw/English/Datasheets/ASYNCHRONOUSSTATICRAM.html] &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.glyn.de Glyn.De] ???&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | ??&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;SRAM&#039;&#039; / AS7C34098-12TCN &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TSOP, SOJ&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | asynchroner SRAM 256K x 16, 12ns&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.alsc.com/pdf/sram.pdf/fa/AS7C4098.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.farnell.de Farnell.De]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 13,17&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;SRAM&#039;&#039; / CY7C1327B&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TQFP100&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | synchr SRAM 256k x 18, 3.3V, 4ns&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.datasheetarchive.com/semiconductors/download.php?Datasheet=598266]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.rsonline.de R&amp;amp;S (DE)]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 11,60&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;SRAM&#039;&#039; / CY7C1327G&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TQFP100&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | synchr SRAM 256k x 18&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy7c1327g_5.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;SRAM&#039;&#039; / CY7C1327F&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TQFP100&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | synchr SRAM 256k x 18&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy7c1327f_5.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;SRAM&#039;&#039; / CY7C1351F-100AC&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TQFP100&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Burst, synchron, Durchfluss, NoBL, 4MB, 128Kx36, 3.3V&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy7c1351f_5.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.rsonline.de R&amp;amp;S (DE)]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 11,25&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;SRAM&#039;&#039; / CY7C1381B-100AC&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | TQFP100&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Burst, synchron, Durchfluss, 18MB, 512Kx36, 3.3V&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_2_1524_209_259_43/http%3B/sjapp20.mis.cypress.com%3B7001/publishedcontent/publish/design_resources/datasheets/contents/cy7c1381c_5.pdf]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [http://www.rsonline.de R&amp;amp;S (DE)]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 48,75&amp;amp;#8364;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;IC&#039;&#039; / Dummy&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | -&amp;amp;#8364;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Logic Analyzer Project|Hardware]]&lt;/div&gt;</summary>
		<author><name>80.146.250.2</name></author>
	</entry>
</feed>