MezData-Logo Lösungen Button :ISP: Einführung in ABEL

OrginalDoku von Lattice als PDF (englisch)

Prinzipieller Aufbau einer Abel-Datei

Eine Abel-Datei ist eine Text-Datei mit der Endung abl, und beschreibt die Funktion einer logischen Schaltung.
Der Compiler erzeugt aus dieser Beschreibung eine Art Programm-Datei für den isp-Chip.
Zur Beschreibung einer Funktion können folgende Darstellungen verwendet werden:

Die ABEL-Datei ist in Abschnitte gegliedert, die jeweils mit einem Schlüsselwort eingeleitet werden.
Hier eine Kurzbeschreibung der Abschnitte:

Schlüsselwort Beschreibung des Abschnitts
MODULE name Kopf des Moduls, Compileranweisungen für das Modul
DECLARATIONS Die Ein- und Ausgänge des Moduls bzw. Chips werden deklariert (festgelegt und benannt)
EQUATIONS Beschreibung der Funktion durch Ausdrücke
TRUTH_TABLE Beschreibung der Funktion durch Wahrheitstabelle
STATE_DIAGRAMM Beschreibung der Funktion durch Zustandsdiagramm
TEST_VECTORS Festlegen von Test-Vektoren zur Überprüfung der Funktion
END Ende des Moduls

Kommentare in ABEL

Kommentare in der Datei werden mit " eingeleitet, Überlesen bis zum Ende der Zeile durch Compiler.

Operatoren in ABEL

Logische Operatoren Arithmetische Operatoren Vergleichende Operatoren
! NICHT

& UND aus = !(a & b) # (c & !d);

# ODER

$ XOR

!$ XNOR

- Subtraktion

+ Addition CTR = CTR + 1;

* Multiplikation (nicht bei Sets)

/ Division (nicht bei Sets)

== gleich

!= ungleich when (a == b) then CTR = 0;

< kleiner

<= kleiner gleich

> größer

>= größer gleich

Zuweisungen

= :=
bei Ausgängen ohne FF bei Ausgängen mit FF unter Verwendung von Dot-Extensions bei Ausgängen mit FF
y = a & b “Ausgang ohne FF, combinatorial ./.  ./. 
./. Qa.d = !Qa.q “Ausgang mit FF, registered Qa := !Qa “Ausgang mit FF, registered

Der MODULE Abschnitt

Hier stehen die Anweisungen für den Compiler, z.B.:

@dcset; "Don't-Care-Set: für max. Vereinfachung in der Funktionstabelle 

Der DECLARATIONS Abschnitt

Ein-und Ausgänge

Hinter DECLARATIONS sind die Namen aller verwendeten Eingänge, Ausgänge und internen Knoten anzugeben:

DECLARATIONS
  takt, reset PIN 11, 19;                      "Eingänge
  bit2..bit0	PIN 8, 9, 10 	ISTYPE'BUFFER,REG';	"Flipflop-Ausgänge
  Led		PIN 3               ISTYPE'BUFFER,COM'; "normaler Ausgang
  uebertrag	NODE;                              "interner Hilfsausgang

Sets = Zusammenfassung mehrerer Signale

Mehrere Signale können zu einem Set zusammen gefaßt werden.

CTR = [bit3, bit2, bit1, bit0];	

oder

CTR = [bit3..bit0];

nun ist z.B. möglich:

CTR.d = 0;  	   "Zähler beim nächsten Takt mit allen Flipflops null setzen.
CTR.clk = takt;	"alle Flipflops erhalten den gleichen Takt

Der EQUATIONS Abschnitt

Bedingung when .. then .. else

Nach wenn folgt eine Bedingung, die Wahr (1) oder Falsch (0) sein kann.

Nach then und else steht eine Anweisung oder
mehrere Anweisungen die mit { } eingeklammert werden und durch ; getrennt sind.
Else + Anweisungen kann man auch weglassen.

when (a==1) 	then y = 1;	 "wenn a gleich 1,	dann ist y =1 (andernfalls ist y = 0)
when (a==b)	 then y = 1; 	"wenn a gleich b,	dann ist y =1 (und x = 0)
	            else x = 1; 	"andernfalls ist x =1 (und y = 0)
when reset	then y = 1; 	  "wenn reset gleich 1 ist, dann ist y =1 (andernfalls ist y = 0)
when !a == b 	then 	{x = 0;	"zusammengehörende Klammen möglichst untereinander
		                   y = b;	"schreiben
			                 }
when !reset & a then	{x = 0;
		                    when b == a	then y = a;	"mehrere verschachtelte Bedingungen
				                              else y = b;	"sind auch möglich.
		                   }				"zusammengehörende then und else
	               else y = 0;				"untereinander schreiben

Falsch: when (a=1) then ... weil = eine Zuweisung ist.

Anmerkung: Innerhalb eines State_Diagramm die Bedingung if .. then .. else verwenden.

Mehr Info: Wie setzt Abel die Bedingung when..then..else in logische Gleichungen bzw. Schaltungen um?

Namen der internen D-Flipflop- Anschlüsse (Dot-Extensions)

DECLARATIONS  "********** Ein- und Ausgänge ***********************
  takt  PIN 11; "Takt vom Taktgernerator
  daten PIN 19; "Eingang Schalter1 heisst Daten
  reset PIN 18; "Eingang von Taster2 heisst Reset
  dff   PIN 10 ISTYPE'BUFFER,REG'; "REG bedeutet: internes D-Flipflop verwenden, 
                                   "das dff genannt wird und dessen Q-Ausgang 
                                   "mit Pin 10 verbunden wird.
EQUATIONS  "********** Funktionsgleichungen ***********************
  dff.d   = daten;  "D-Eing. des FFs mit Schalter Daten beeinflussen
  dff.ar  = reset;  "Reset-Eing. des FFs mit Taster Reset 
  dff.clk = takt;   "Takt des D-FF vom Taktgenerator

Mehr Info: Interne D-Flip-Flops

Mehr Info: Synchrone Zähler

Der TRUTH_TABLE Abschnitt

Hinter TRUTH_TABLE werden in ( ) die Ein- und Ausgangsnamen angegeben.
Darunter werden die gewünschten Ein- und Ausgangs-Bitkombinationen angegeben.
Nicht angegebene Eingangskombinationen werden als Don’t-Care behandelt, wenn @dcset angegeben wurde.
Innerhalb der Tabelle können auch einzelne Positionen mit .x. statt 0 oder 1 als Don’t-Care gesetzt werden.

DECLARATIONS
  a,b   PIN 16,18;	                    "Eingänge
  x,y,z PIN 3,4,5 ISTYPE'BUFFER,COM'; 	"Ausgänge ohne D-Flipflop

TRUTH_TABLE  (	[b,a] -> [x,y,z] )	"Eingänge -> Ausgänge
	              [0,0] -> [1,0,0];
	              [0,1] -> [1,1,0];
	              [1,0] -> [1,0,1];
	              [1,1] -> [0,0,0];

Für D-Flipflop-Schaltungen (Schaltwerke) gibt die Funktionstabelle die Zustände vor und nach dem Takt an:

DECLARATIONS
  en      PIN 16,18;	                   "Eingang
  qb,qa   PIN 3,4,5 ISTYPEBUFFER,REG’; "Ausgänge mit D-Flipflop

?****************** Beispiel: Zähler mit Freigabe 
TRUTH_TABLE  (	[en,qb,qa] -> [qb,qa] )	"vor dem Takt  ->  nach dem Takt
               [0 ,0 ,0 ] -> [0 ,0 ]; 	"weil a=0 ist, bleiben x und y wie sie sind
	              [0 ,0 ,1 ] -> [0 ,1 ];
	              [0 ,1 ,0 ] -> [1 ,0 ];
	              [0 ,1 ,1 ] -> [1 ,1 ];

	              [1 ,0 ,0 ] -> [0 ,1 ]; 	"weil a=1 ist, wird aus 00 nach dem Takt 01
	              [1 ,0 ,1 ] -> [1 ,0 ];
	              [1 ,1 ,0 ] -> [1 ,1 ];
	              [1 ,1 ,1 ] -> [0 ,0 ];

Der STATE_DIAGRAMM Abschnitt

Hinter STATE_DIAGRAMM werden die Register angegeben, mit denen die Zustände beschrieben bzw. unterschieden werden.
Anschließend werden hinter STATE die Zustände aufgeführt und angegeben, unter welchen Bedingungen ein anderer Zustand erreicht wird.

DECLARATIONS
  takt,start	PIN 11,19;				           "Eingänge
  Q1,Q0		PIN 9,10 ISTYPE 'BUFFER,REG';	"Zustands-Register

  Zustandsreg = [Q1,Q0];					 "Zusammenfassung
  S0 = 0; S1 = 1; S2 = 2;					"State-Werte

EQUATIONS
  Zustandreg.clk = takt;					 "Takt der Zustandsregister

STATE_DIAGRAMM Zustandsreg;
  STATE S0: if start then S1 else S0;			"wenn Start=1 dann zum State S1
  STATE S1: if start then S2 else S1;
  STATE S2: if start then S0 else S2;

Mehr Info: Synchrone Zähler

Der TEST_VECTORS Abschnitt

Simulation mit TEST_VECTORS

TEST_VECTORS ([takt ] -> [aus1,aus2]);	   "Eingänge -> Ausgänge
  @repeat 10  { [ .c. ] -> [.x. ,.x. ] ;}	".c. Taktimpulse an den Eingang
	                          ".x. Ausgänge sind don’t care, d.h. können sich beleibig ändern.
	                          "Das in { } stehende wird 10 mal wiederholt.