Entwicklungsbeispiel
Im Folgenden werden die ersten 3 Phasen Spezifikation, -Kodierung und -Synthese einer ASIC Entwicklung anhand eines sehr einfachen Beispiels erläutert. Ziel ist es, eine digitale Schaltung für einen 4 Bit
Vorwärts/Rückwärts-Zähler zu erzeugen. Dieses Beispiel dient nur dazu die Phasen zu verdeutlichen und ist keinesfalls ein Beispiel für die Komplexität heutiger Designs. Die Größe des Zählers beträgt ca. 100 Gates, während sich
komplexe Designs in den Größenordnungen von mehreren Millionen Gates bewegen! Daher ist es auch nicht sinnvoll ein Layoutergebnis dieser Schaltung darzustellen, da selbst die kleinstmögliche Chipfläche eines ASICs mit dieser Zählerschaltung eigentlich fast leer wäre.
Phase 1: ASIC-Spezifikation Der Vorwärts/Rückwärts-Zähler soll folgendermaßen entwickelt werden.
4 Bit Zähler mit den Datenausgängen C0, C1, C2, C3. Dieser zählt von 0 bis 15 bzw. in entgegengesetzter Richtung.
Reset Eingang, setzt bei Reset=0 den Zähler auf den Wert 0 zurück
Clock Eingang; mit jedem Wechsel von Clock von 0 nach 1 zählt der Zähler
UpDown Eingang zur Festlegung der Zählrichtung; 1=Up; 0=Down
- Count Eingang, ist Count=1 wird mit jedem 0-1 Wechsel von Clock Wert des
Zählers um eins erhöht (Up), bzw. um eins erniedrigt (Down). Bei Count = 0 bleibt der alte Zählerstand erhalten
Bei einem Zählerüber- oder -unterlauf soll wieder bei 0 bzw. 15 weitergezählt werden
Phase 2: ASIC-Kodierung Der fogende Abschnitt in kursiv stellt den vollständigen VHDL Code des Zählers
dar, der oben spezifiziert worden ist. Um diesen auf seine vollständige und korrekte Implementierung zu prüfen, sind Simulationen notwendig.
library IEEE; use IEEE.std_logic_1164.all; -- import std_logic types
use IEEE.std_logic_arith.all; -- import add/sub of std_logic_vector
ENTITY counter_updown is PORT ( -- Counter Control Signals
clock : IN std_logic; -- counter clock
reset : IN std_logic; -- counter reset
updown : IN std_logic; -- count direction up/down
count : IN std_logic; -- count enable -- Counter Output Signals
c0, c1, c2, c3 : OUT std_logic); -- counter bit 0..3 END counter_updown;
ARCHITECTURE rtl OF counter_updown IS -- internal signal declaration SIGNAL counter : std_logic_vector(3 DOWNTO 0);
BEGIN
count_process : PROCESS -- This process builds the counter BEGIN
-- wait for rising edge of clock (0->1) WAIT UNTIL clock'EVENT AND clock = '1'; IF reset = '0' THEN -- set all counter bits to zero
counter <= (others => '0'); ELSE IF (count = '1') AND (updown = '1') THEN -- count up: n, n+1, n+2, ..., 15, 0, 1, ...
counter <= CONV_STD_LOGIC_VECTOR(UNSIGNED(counter) + 1, 4); ELSIF (count = '1') AND (updown = '0') THEN
-- count down: n, n-1, n-2, ..., 0, 15, 14, ... counter <= CONV_STD_LOGIC_VECTOR(UNSIGNED(counter) - 1, 4); ELSE
-- hold counter in the same value as before counter <= counter; END IF; END IF; END PROCESS;
-- Connect internal counter to outputs c0 <= counter(0); c1 <= counter(1);
c2 <= counter(2); c3 <= counter(3);
END rtl;
Testbench Der nachfolgende Code ist die VHDL Testbench unseres Zählers. Mit einer Testbench wird die
Funktionalität des Designs in allen Bereichen überprüft. Für den Zähler sind dieses die Funktionen Zähler auf 0 zurücksetzen, aufwärtszählen, abwärtszählen, pausieren (count=0). Beachtung gelegt
werden muß insbesondere auf die Übergänge von 15 nach 0 (aufwärts) bzw. von 0 nach 15 (abwärts). Die Testbench simuliert nun folgende Phasen: 1) starte mit einem Reset (Zähler = 0)
2) zähle 18 Takte aufwärts (1 ... 15, 0, 1, 2) 3) mache einen Takt lang eine Pause (count = 0)
4) zähle 11 Takte zurück (1, 0, 15 ... 8, 7) 5) beginne bei 1)
library IEEE; use IEEE.std_logic_1164.all;
ENTITY testbench IS END testbench;
ARCHITECTURE beh OF testbench IS
COMPONENT counter_updown -- component interface of 4 bit up/down counter PORT ( -- Counter Control Signals
clock : IN std_logic; -- counter clock reset : IN std_logic; -- counter reset
updown : IN std_logic; -- count direction up/down count : IN std_logic; -- count enable
-- Counter Output Signals c0 : OUT std_logic; -- counter bit 0
c1 : OUT std_logic; -- counter bit 1 c2 : OUT std_logic; -- counter bit 2
c3 : OUT std_logic); -- counter bit 3 end COMPONENT;
-- define all testbench signals (same names as counter)
signal c0, c1, c2, c3 : std_logic; signal clock, reset, updown, count : std_logic;
BEGIN
ctr : counter_updown -- connect 4 bit up/down conter with testbench signals
PORT MAP (clock, reset, updown, count, c0, c1, c2, c3);
ctr_proc : PROCESS -- generate control signals for different count sequences VARIABLE i : INTEGER;
BEGIN WAIT UNTIL clock'EVENT AND clock = '1'; reset <= '0'; WAIT UNTIL clock'EVENT AND clock = '1'; reset <= '1';
count <= '1'; -- start counting updown <= '1'; -- count up FOR i IN 1 TO 18 LOOP WAIT UNTIL clock'EVENT AND clock = '1';
END LOOP; count <= '0'; -- stop counting WAIT UNTIL clock'EVENT AND clock = '1'; updown <= '0'; -- count down
count <= '1'; -- start counting FOR i IN 1 TO 10 LOOP WAIT UNTIL clock'EVENT AND clock = '1'; END LOOP;
-- process continues endlessly with first line END PROCESS ctr_proc;
clk_proc : PROCESS (clock) -- generate counter clock -- periode is 200ns / 5 MHz BEGIN
IF clock'EVENT AND clock = '1' then clock <= '0' AFTER 100 NS; ELSE clock <= '1' AFTER 100 NS; END IF;
END PROCESS clk_proc;
END beh;
Simulation Die Ergebnisse der Testbenchsimulation werden folgendermaßen in einem Waveform Viewer
dargestellt. Das Signal `clock´ zeigt den kontinuierlich durchlaufenden Takt. `reset´, `updown´ und `count´ sind die Steuersignale des Zählers und `c0´, `c1,´ `c2´ und `c3´ die Zählerausgänge.
Beispielsweise wird hier deutlich, daß bei einem 'reset = 0' mit der nächsten steigenden `clock´- Flanke alle Zählerbits auf 0 gesetzt werden. Weiter: Ist 'count' auf 0 wird trotz steigender Flanke von
`clock´ der Zählerwert beibehalten.
Wer sich privat einmal mit VHDL-Design und Simulation beschäftigen möchte und einen Unix/Linux Rechner sein eigen nennt, findet auf folgenden Seiten bestimmt das richte und kostenlose Werkzeug.
www-asim.lip6.fr/recherche/alliance www.freehdl.seul.org www.ece.uc.edu/~paw/savant
Phase 3: ASIC-Synthese
Bei der ASIC-Synthese wird der verifizierte VHDL-Code zusammen mit den Constraints in die Synthese-Software eingelesen. Die Constraints definieren die
zeitlichen Randbedingungen (die Werte in dem Constraint-File sind in der Einheit ns angegeben). - create_clock definiert das Taktsignal mit der Periodenlänge von 200ns - set_input_delay definiert die Änderung des jeweiligen Signals mit einer
Verzögerung von 3ns nach der steigenden Flanke von clock
/* Constraints for 4-bit up/down counter */ /* Define Clock Frequency periode = 20ns (50MHz) */
create_clock -name CLK -period "200" -waveform {"0" "100"} {clock} /* Define Signal Delay */ set_input_delay 3 -clock CLK reset set_input_delay 3 -clock CLK updown
set_input_delay 3 -clock CLK count
Das Bild links zeigt die oben
aufgeführte ENTITY des Zählers, also alle Ein- und Ausgänge ohne das Innenleben des Zählers. Man erkennt auf der linken Seite alle spezifizierten Eingänge, auf der rechten Seite alle vier Ausgänge c0, c1, c2 und c3, die
den Wert des Zählers darstellen. Unten befindet sich die Schaltung des Zählers nach der Synthese. Links sind wieder die Eingänge und rechts
die Ausgänge zu erkennen. Die vier FlipFlops, die an dem unteren clock Eingangssignal angeschlossen sind, enthalten die 4 Bitwerte c0, c1, c2 und c3 des Zählers. Die anderen Elemente sind Logikgatter
UND, ODER und verschiedene Derivate, die aus dem aktuellen Zustand der FlipFlops und der 3 Steuereingänge count, reset und updown den neuen Zählerstand berechnen. Der neue Wert wird mit
der steigenden Flanke der clock in die FlipFlops übernommen.
|
Phase 4: ASIC-Layout Das ASIC-Layout wird in zwei Stufen durchgeführt. In der ersten Stufe werden zunächst alle
Schaltungselemente der Netzliste auf der Chipfläche, dem sogenannten Die (gesprochen: `Dai´) angeordnet. Die Positionen der Elemente wird mit z.T. komplizierten Algorithmen und Methoden
bestimmt bzw. berechnet. Ziel dabei ist es immer, die Länge (und damit die benutzte Fläche als auch die Laufzeiten) der einzelnen Verbindungen möglichst klein zu halten. Bei oftmals mehr als hunderttausenden
von Elementen und Verbindungen kann man sich leicht vorstellen, wie viel ein Rechner für eine gute Plazierung arbeiten muß. Der Die ist in 3 Bereiche aufgeteilt .
Core-Area
Dieser Bereich befindet sich in der Mitte des Dies (grau). In diesem wird die komplette Netzliste
ohne die Eingangs- und Ausgangs- Buffer angeordnet. Alle Eingangs- und Ausgangs- Buffer sind gegenüber der internen Elemente wesentlich größer, da diese einen relativ großen Strom liefern
müssen (Ausgänge) und gegen äußere elektrostatische Entladungen geschützt sind. Einige der
Eingangsbuffer können auch Pull-Up bzw. Pull-Down Widerstände beinhalten, die den Eingang in einem definierten Zustand halten, wenn der Eingang unbeschaltet (floating) ist.
IO- und Power-Ring Dieser Bereich (gelb/grün) beinhaltet die elektrische Stromversorgung (Power-Supply) der Eingangs- und Ausgangsbuffer auf dem IO-Ring und der umschlossenen Core-Area.
Durch die Anordnung der einzelnen Buffer auf den vier Seiten des IO-Rings wird festgelegt, welches Signal mit welchem Gehäuse-Pin verbunden wird.
Pad-Area Dieses ist der äußerste Bereich des Dies außerhalb des Power- und IO-Rings. In diesem befinden sich relativ große metallisierte Flächen (gelbe Flächen im roten Randbereich), Pads
genannt, über die der Die mit dem Gehäuse verbunden wird (Bonding). Jedes der Pads ist mit einem Eingangs- oder Ausgangsbuffer des IO-Rings verbunden.
Phase 5: ASIC-Produktion
Eine ausführliche Darstellung des Produktionsprozesses eines ASICs (aber auch aller anderen Halbleiter) befindet sich auf der Semiconductur Manufacturing Process
Seite. Hier wird in allen Schritten, angefangen bei der Erzeugung des Basismaterials für die Halbleiter, den Roh-Wafern über die Erzeugung der Masken, den Ätzvorgängen bis hin zum
Bonding und Packaging der Produktionsprozeß in seinen Abläufen beschrieben.
|