Microchip CLB – erste Versuche zur „FPGA-Zelle“ im Achtbitter

Microchip erweitert das Achtbitter-Portfolio permanent um innovative Peripheriegeräte, die Entwicklern das Auslagern von Rechenaufgaben vom Kern an die Core Independent Peripherals erlauben. Mit dem PIC16F13145 steht eine logische Weiterentwicklung der CLC an – dieser Artikel wirft einen ersten Blick auf die als Configurable Logic Block bezeichnete Engine und vergleicht ihn mit der CLC.

Worum geht es hier

Mit der in der ersten Abbildung gezeigten CLC wagte Microchip den ersten Schritt in die Welt der „konfigurierbaren Logik“. Der blaue Block konnte dabei verschiedene Aufgaben übernehmen, die eine „Vermaschung“ der anliegenden Signale ohne Eingriff von Seiten des Rechenkerns erledigten.

Bildquelle: https://developerhelp.microchip.com/xwiki/bin/view/products/mcu-mpu/8bit-pic/peripherals/clc/

Ob der sehr rigiden Struktur war der Einsatzbereich des Moduls streng limitiert. Mit der CLB setzt Microchip stattdessen auf eine matrizierte Struktur, die – wie in der Abbildung gezeigt – bis zu 32 „flexible Funktionseinheiten“ zur Verfügung stellt.

Bildquelle: Microchip

Exkurs: Online-Bitstromgenerator

Microchip bietet unter der URL https://logic.microchip.com/clbsynthesizer/ ein im Browser lebendes Synthesewerkzeug an. Es ermöglicht die Generierung von Gatterschaltungen und ermöglicht auch ihre – teilweise – Verdrahtung mit Eingangs- und Ausgangssignalen.

Bildquelle: Autor

Über CLB Synthesizer → Save Design lässt sich eine .clb-Datei exportieren, die danach in verschiedenen anderen Werkzeugen ladbar ist. In der Praxis ist das System allerdings eher wenig nützlich, da die eigentliche Entwicklung in MPLAB erfolgt.

Erste Versuche und Beschaffung

Als der Autor die Arbeiten an diesem Artikel begann, waren die Bauteile nur als Samples bei Microchip verfügbar. Die Lieferung der drei PIC16F13145-I/SS erfolgte zollschonend aus Thailand mit einem Zwischenstop in Frankreich; im Moment ergibt eine OEMSecrets-Suche nach wie vor keine Lieferbarkeiten außerhalb von Microchip.

Bildquelle: https://www.oemsecrets.com/compare/PIC16F13145

Wie bei den Achtbittern üblich plant Microchip auch hier das Anbieten einer DIP-Variante. Im Datenblatt findet sich außerdem der hier tabellarisch
gezeigte Speisezettel.

Bildquelle: Microchip

Mit einem Adapter ist es problemlos möglich, eine primitive Entwicklungsplatine zu konstruieren. Wichtig ist vor Allem die Verwendung einer brandaktuellen Version von MPLab (hier 6.20), als Kommandogerät soll ein PicKit4 zum Einsatz kommen.
Nach dem erfolgreichen Abarbeiten des Projektgeneratorassistenten (man achte auf eine brandaktuelle Version von XC8) öffnen wir MCC und fügen in der Rubrik Device Resources das Modul CLB1 zum Projekt hinzu. Lohn der Mühen ist das Erscheinen der in der Abbildung gezeigten Oberfläche, die eine lokale Version des CLB Synthesizer einbindet.

Bildquelle: Autor

Für einen ersten Versuch bietet siich die Auswahl des Beispiels Invert a Signal an. Ein Doppelklick auf den Tabheader ermöglicht den Wechsel in den Vollschirmmodus, der dringend empfehlenswert ist.

Bildquelle: Autor

Nach einem Klick auf das unten links befindliche Synthesize-Steuerelement erscheint ein grüner Haken und eine Art Fortschrittsbalken, der über die „Menge“ der verbrauchten Logikblöcke informiert. Schließen Sie das CLB-Fenster danach, um im normalen Project Resources-Fenster weiterzuarbeiten. In der Pin Grid View-Anzeige scheinen die Ein- und Ausgangspins dann zur Ansteuerung bzw Zuweisung auf – die Aktualisierung erfolgt erst nach (!) dem Schließen des CLB-Fensters (!!!).

Bildquelle: Autor

Die vom Autor verwendete Belegung präsentiert sich wie in der Abbildung gezeigt.

Bildquelle: Autor

Betrachtung des Codes

Ist die Generation des Codes erfolgreich verlaufen, so entsteht im Unterordner MCC Generated Files die Struktur clb/src. In clbBitstream.s findet sich eine nach folgendem Schema aufgebaute Bitstromdatei:

1
GLOBAL _start_clb_config

2
GLOBAL _end_clb_config

3

4
PSECT clb_config,global,class=STRCODE,delta=2,noexec,split=0,merge=0,keep

5

6
_start_clb_config:

7
DW 0x0000

8
DW 0x0000

9
DW 0x0000

10
DW 0x0000

11
DW 0x0000

12
DW 0x0000

13
DW 0x0000

14
DW 0x0000

15
DW 0x0000

16
. . . .

Die eigentliche Logik findet sich in clb1.c – interessant ist vor Allem die folgende Methode, die sich um die Initialisierung des CLB kümmert:

1
void CLB1_Configure(uint16_t start_address)

2
{

3

4
uint16_t end_address;

5

6
end_address = start_address + 102;

7

8
// Set the bitstream address

9
CRC_SetScannerAddressLimit(start_address, end_address);

10

11
// Start CLB bitstream load

12
CRC_StartNvmScanner();

13

14
// Wait to complete

15
while (CRC_IsScannerBusy());

16

17
// Switch back to the CRC peripheral

18
CRC_StopNvmScanner();

19
}

Die Aktivierung der Lademethode erfolgt separat:

1
void CLB1_Initialize(void)

2
{

3
/* Disable CLB */

4
CLBCONbits.CLBEN = 0;

5

6
//Load the bitstream

7
CLB1_Configure((uint16_t) &start_clb_config);

8

9
/* CLK HFINTOSC; */

10
CLBCLK = 0x6;

11

12
/* OESEL0 0; OESEL1 0; */

13
CLBPPSCON1 = 0x0;

14

15
/* OESEL2 0; OESEL3 0; */

16
CLBPPSCON2 = 0x0;

17

18
/* OESEL4 0; OESEL5 0; */

19
CLBPPSCON3 = 0x0;

20

21
/* OESEL6 0; OESEL7 0; */

22
CLBPPSCON4 = 0x0;

23

24
// Clearing CLB1I0 IF flag.

25
PIR7bits.CLB1IF0 = 0;

26
// Disabled CLB1I0 CLB1 interrupt

27
PIE7bits.CLB1IE0 = 0;

28

29
// Clearing CLB1I1 IF flag.

30
PIR7bits.CLB1IF1 = 0;

31
// Disabled CLB1I1 CLB1 interrupt

32
PIE7bits.CLB1IE1 = 0;

33

34
// Clearing CLB1I2 IF flag.

35
PIR7bits.CLB1IF2 = 0;

36
// Disabled CLB1I2 CLB1 interrupt

37
PIE7bits.CLB1IE2 = 0;

38

39
// Clearing CLB1I3 IF flag.

40
PIR7bits.CLB1IF3 = 0;

41
// Disabled CLB1I3 CLB1 interrupt

42
PIE7bits.CLB1IE3 = 0;

43

44
/* EN enabled; */

45
CLBCON = 0x80;

46

47
}

Um den eigentlichen Aufruf kümmert sich dann folgende Methode:

1
void SYSTEM_Initialize(void)

2
{

3
CLOCK_Initialize();

4
CLB1_Initialize();

5
PIN_MANAGER_Initialize();

6
CRC_Initialize();

7
NVM_Initialize();

8
INTERRUPT_Initialize();

9
}

Ebenda finden sich auch einige Methoden, die die Kommunikation mit den 32 bit breiten „Steuerregistern“ ermöglichen. Aus Sicht der Recheneinheit stehen zwei Registergruppen aus je vier Kernregistern zur Verfügung, die wie in der Abbildung gezeigt mit den diversen Funktionseinheiten verdrahtet werden. Hier als Auszug eine der Beispielmethoden:

1
void CLB1_SWIN_Write8(uint8_t data)

2
{

3
//wait for CLBSWIN register to be synchronized

4
while (CLB1_IsCLBSWINBusy());

5

6
CLBSWINL = data;

7
}

Wie geht es weiter?

Nachdem wir uns die grundlegende Struktur eines CLB-basierten Projekts angesehen haben, ist es nun an der Zeit, in die Praxis überzugehen. Dies ist Thema eines Folgeartikels – über eventuelle Fragen und Testwünsche freut sich der Autor wie immer im Kommentarbereich.

Zuerst erschienen bei Mikrocontroller.net News

Quelle: Read More