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