In het kader van twee workshops Systeem- en Software-engineering hebben twee jaargangen Ooti-studenten gewerkt aan de realisatie, optimalisatie en uitbreiding van een klantgestuurde opdracht. Het resultaat is een raamwerk waarmee vanuit Matlab/Simulink en een X-beschrijving volledig automatisch Handel-C-code is te genereren die de besturing implementeert op een Celoxica-bordje met daarop een Xilinx-FPGA met drie miljoen poorten. Medebedenker en technisch coach Herman Roebbers van Philips Tass vertelt over de ervaringen.
Aan het begin van het tweede en laatste jaar van de Eindhovense Ooti-opleiding krijgen de Technologisch Ontwerpers in Opleiding (Toio‘s) een klantgestuurde opdracht. Het doel hiervan is om ze ervaring op te laten doen met het projectmatig werken in de praktijk. De studenten moeten zelf het werk in kaart brengen en onderling verdelen. Ook moeten ze met de klant om tafel om ervoor te zorgen dat ze begrijpen wat de bedoeling is en hem duidelijk kunnen maken wat ze gaan doen en wanneer. Ten slotte moeten ze gezamenlijk afspreken in welke vorm de resultaten beschikbaar komen.
Omdat Ooti en Philips Tass meer wilden samenwerken, gingen ze op zoek naar een geschikt onderwerp. We kwamen tot overeenstemming dat het onderzoek zich moest richten op automatische codegeneratie, FPGA‘s, Handel-C, Matlab en Simulink. Het moest gaan over realtime regeling van een niet-triviaal mechanisch systeem. Omdat Océ wellicht ook geïnteresseerd zou zijn in deelname, hebben we contact gelegd met Océ‘er Lou Somers, die een dag per week op de TU Eindhoven onderzoek verricht. Hij wilde graag meewerken. Een geschikte testcase vonden we in de vorm van een automatisch documentinvoersysteem (Automatic Document Feeder, ADF).
De ADF is het deel van een kopieerapparaat dat papier van de stapel pakt en door de machine transporteert. Hierbij komt nogal wat kijken. Er zitten diverse motoren, schakelaars en sensoren in om het papiertransport in goede banen te leiden. De juiste motoren moeten op het juiste moment van de juiste spanningen worden voorzien anders raakt het papier verfrommeld of komt het er helemaal niet uit.
Toevallig stond er bij Océ een aangepaste machine die we helemaal digitaal konden besturen. Deze hebben we voor het project naar de Ooti-zaal op de TU-campus overgebracht. Het apparaat bevatte ook een werkende microcontrollerimplementatie van de beoogde functionaliteit, die we als referentie konden gebruiken. Om het project nog meer vaart te geven, namen we contact op met Esi om Matlab/Simulink-modellen te verkrijgen van de machine en de besturing. Dit was een essentiële voorwaarde voor succes. Alleen het maken van deze modellen zou anders het hele project hebben opgesoupeerd. Het centrale doel was om aan te tonen dat het mogelijk is om vanuit een omgeving op een hoger niveau (Matlab/Simulink) Handel-C te genereren en zo direct motorbesturingen op een FPGA te realiseren.
In het project werkten de Ooti-studenten ook samen met Celoxica en The Mathworks. Ze kregen eerst een cursus van een week over het wezen van Handel-C en FPGA. Ze hadden eerder in hun opleiding al eens met Matlab gewerkt, maar codegeneratie was nieuw voor ze.
X-files
Als je kijkt naar de opbouw van een systeembesturing, zoals die van de ADF, zijn daarin twee niveaus te onderscheiden: het regelen van de motorsnelheid en het bepalen van de gewenste snelheid en de aanstuurmomenten van de motoren. Voor het eerste stuk hebben de Ooti-studenten Matlab en Simulink ingezet als ontwerpmethode. Het tweede niveau realiseerden ze met een toestandsmachine, met daarin elementen als sensoren, motoren en andere actuatoren. Dit gedeelte heet ook wel Supervisory Control.
De beschrijving van de ADF-toestandsmachine leverde Océ aan in de vorm van een X-file. De oorspronkelijk informele syntaxis en semantiek van deze beschrijving zijn geformaliseerd om het proces van omzetting naar Handel-C eenduidig en dus automatisch te kunnen maken. Deze omzetter heet UtilX. Naast de Matlab/Simulink-modellen van de motoren waren ook de zogenaamde motorprofielen beschikbaar. Deze beschrijven hoe de motoraansturing in de tijd eruit moet zien om een gewenste prestatie te leveren.

Driestappenplan
Het ontwikkelproces bevat de eis dat we op drie niveaus testen om voldoende vertrouwen in de oplossing te krijgen. Het uiteindelijke proces is te zien in Figuur 1. Als eerste is daar software-in-the-loop (Sil). Het interessante aspect hieraan is de cosimulatie. Het model van de motor simuleren we namelijk in Matlab/Simulink en de regelaar in de Handel-C-simulator. Beide zijn via een zogenaamde cosimulatie-interface aan elkaar gekoppeld. Zo is functionaliteit in de Handel-C-simulator vanuit Matlab/Simulink aan te roepen.
Als op die manier de regelfunctionaliteit is goedgekeurd, schuift het proces een niveau lager: hardware-in-the-loop (Hil). Hierbij executeren we het motormodel op een pc met een realtime besturingssysteem, in dit geval XPC. De implementatie van de regelaar draait op een FPGA en wordt aangesloten op XPC. De regelaar voldoet als hij de motor goed kan aansturen. Als ook dit is gedaan, kunnen we door naar de derde stap: het aansluiten op de echte ADF. Dit driestappenplan moet de garantie bieden dat er niets misgaat met de echte ADF. Er is er namelijk maar eentje en als die kapot gaat, betekent dat einde project.
Crash
Geen echt project zonder hindernissen. Oorspronkelijk was de gedachte om voor de codegeneratie van de regelaars gebruik te maken van Real-time Workshop, de codegenerator van Simulink. Dit lukte echter niet vanwege een verschil in benadering tussen de interpreterachtige structuur van de gegenereerde code en de gewenste statische FPGA-implementatie. Daarom hebben we gekozen om de Handel-C-code te genereren uit de Simulink MDL-file en de daarin gebruikte Matlab M-files. Dit zijn tekstbestanden met een eenvoudig te verwerken syntaxis. We pasten hier de MDL2HC-tool toe. Voor de Supervisory Control moesten we de code uiteindelijk zelf genereren vanuit de X-specificatie.
Ook interessant was het volgende probleem: de interface naar de ADF bestaat uit een aantal pulsbreedtegemoduleerde (PWM) kanalen en uit de documentvoeder komt een aantal pulsen die richting en snelheid van de motor aangeven. Om de XPC als ADF te kunnen aansturen voor de Hil-stap moet er een extra kaart in, die de PWM-signalen omvormt in analoge signalen. Tevens moeten we de snelheid van de motoren omzetten in series pulsen. Het bleek dat de kaart het PWM-signaal ongeveer één keer per seconde niet goed vertaalt, waardoor de XPC-software crashte. De leverancier weet van het probleem maar haalt zijn schouders op. Hij heeft nog een andere kaart die het probleem minder vaak vertoont. Of we die dan willen hebben? Uitkomst biedt de inspectie van het uitgelezen signaal. Als dat 0 is, gebruiken we de vorige waarde nog een keer.
Nog een tegenvaller was dat we de FPGA, de XPC en de ADF niet direct konden koppelen. Eerst moesten we een verloopstekker maken omdat er twee verschillende pluggen werden gebruikt. Een groter probleem was dat de FPGA op 3,3 volt werkt en de ADF en de XPC op 5 volt. Hiervoor moesten de studenten dus zelf een extra print maken. Aan de FPGA-kant biedt dit gelijk extra bescherming tegen verkeerd aansluiten. In zo‘n geval gaat misschien het conversieprintje stuk, maar niet de dure FPGA.
Macro De M- en MDL-files bevatten ’platte‘ tekst. Het MDL-bestand beschrijft uit welke blokjes het systeem bestaat en hoe deze met elkaar zijn verbonden. Ook staat er voor elk blokje in wat de waarden van de parameters zijn en op welk type operators het werkt (integer, drijvende of vaste komma). De definitie van de blokjes komt uit M-bestanden en bibliotheken. Alle gegevens zijn in een grote datastructuur opgeslagen van waaruit we voor ondersteunde blokjes stukjes voorbeeldcode kunnen genereren. Dit proces werkt met macro‘s die typeonafhankelijk zijn. Een generieke opteller ziet er dan bijvoorbeeld zo uit:

Het systeem is beschreven als een aantal communicerende processen volgens de Communicating Sequential Processes-theorie (CSP). Deze processen praten uitsluitend via kanalen met elkaar. In Handel-C ziet dat er dan zo uit:

Het is dus zaak om een Handel-C-macro te maken voor elke functie in Matlab/Simulink die je wilt kunnen genereren. Op die manier kun je snel een raamwerk opzetten. Voor alles wat in het project aan blokjes nodig bleek, hebben de Toio‘s een macro gebouwd. Dit resulteerde in ongeveer veertig standaard bouwblokjes. Om de volledige functionaliteit te realiseren, moesten ze nog een koppeling maken tussen de Supervisory Control en de motorbesturing. Dit is slechts een eenmalige actie.
De Toio‘s hebben een systeem gerealiseerd om vanuit Matlab/Simulink en een X-beschrijving volledig automatisch Handel-C-code aan te maken die de besturing implementeert op een Celoxica RC-203-bord. Dit genereren duurt ongeveer een kwartier. Tevens bevat het bord een Ethernet-interface waarover samples van de regeling naar buiten worden gestuurd voor logging om de kwaliteit te kunnen beoordelen. De Xilinx-FPGA is dan vrijwel vol. De besturing werkt op de echte ADF zoals gespecificeerd. Net zoals bij een echt project was het systeem precies op de dag van oplevering helemaal klaar.
Update
Het jaar erna kregen de Ooti‘ers dezelfde opdracht, maar met als extra eisen optimalisatie van de gegenereerde Handel-C-code en een visualisatiegereedschap om de afwijking tussen het model en de werkelijkheid te bepalen. Deze moesten ze tekenen in een grafische representatie van de papierloop. De studenten mochten zelf besluiten wat ze van hun voorgangers wensten te hergebruiken.
De ontwerpers in opleiding besloten MDL2HC gedeeltelijk te herschrijven en te hernoemen tot M-star (Figuur 2). Bij het updaten van de codegeneratie hanteerden ze een aantal richtlijnen. Het systeemgedrag moest hetzelfde blijven, de hiërarchie moest uit het Simulink-model, de codereductie moesten ze bereiken door transformatie van de oorspronkelijke structuur, volgens de regels van CSP, en waar mogelijk wilden ze de hardwareblokjes hergebruiken.
Over het algemeen zijn de systemen hiërarchisch ontworpen om het overzicht te houden. Dit introduceert echter subsystemen met ingangs- en uitgangspoorten, waardoor overhead ontstaat bij een naïeve implementatie. Door nu het model plat te slaan, kunnen we alle overhead verwijderen. De uitvoering hiervan is een bewerking voorafgaand aan de eigenlijke codegeneratie.
De transformatie houdt in dat we communicatie over een kanaal kunnen vervangen door een toekenning. Een klein voorbeeldje:

is equivalent aan

Nog een voorbeeldje:

is equivalent aan

is equivalent aan

Met deze regels in hun achterhoofd hebben de studenten de structuur van de Handel-C-macro‘s zodanig aangepast dat er geen loops meer in voorkomen en kanaalcommunicaties (waar mogelijk) zijn vervangen door toekenningen. Tevens zijn de macro‘s nu gedeeld zodat ze de hardwarefunctionaliteit kunnen delen. Dit heeft wel tot gevolg dat de voorheen impliciete scheduling (kanaalcommunicatie schedulet zichzelf) nu expliciet moet worden gemaakt. Dus moeten we de codegenerator uitbreiden met een scheduler om de volgorde van de toekenningen zo te regelen dat de semantiek niet verandert. De scheduler analyseert het communicatiepatroon en behoudt waar mogelijk het parallellisme (zonder de semantiek van de applicatie te wijzigen). Omdat verwerking nu sequentieel is, kunnen we de gedeelde macro‘s aanroepen zonder kans op conflicten en kunnen we de hardware eenvoudig hergebruiken.

Hoewel de tweede lichting Toio‘s maar een deel van de totale code anders genereerden, bereikten ze toch een reductie van meer dan 50 procent ten opzichte van het jaar ervoor. Dat betekent dat de herziene code zelf dus nóg veel efficiënter is geworden. Ondanks dat ze parallellisme reduceerden, bleef de systeemprestatie ruim voldoende. Ook het visualisatiestuk hebben ze goed ingevuld.
Zowel Ooti als Philips Tass is ervan overtuigd dat de combinatie Handel-C en FPGA‘s een toegevoegde waarde heeft. Beide technologieën krijgen een vaste plaats binnen het nieuwe curriculum van de opleiding, dat volgend jaar oktober van start gaat.