Xilinx Microblaze MCS Workflow

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Gestartet von Benutzer:Fpgakuechle (Volker Urban)

Status: 2015-Feb-27 -> Material,Tips zur Fehlersuch und Screenshots sammeln

Der Artikel beschreibt wie der 32bit Softcore "microblaze MCS" in FPGA verwendet wird. Verwendet wird dabei die kostenfrei verfügbare "leichtgewichtige" MicroBlaze-mcs (µB-MCS) Variante aus dem coregenerator (ab ISE 13.4 (ab 01/2013) und Vivado) und nicht die kostenpflichtige MicroBlaze (ohne -MCS) Variante.

MicroBlaze und MicroBlaze MCS

Ablauf

Die Implementierung eines FPGA-Systems mit Softcore verläuft in folgenden Phasen:

  • Erstellung des FPGA-drumherum (Top-level design, pinassigments) und FPGA ohne microblaze-Core implementieren
  • Generierung des Softcore im CoreGenerator
  • Instanziierung Core, Script für bm referenz ausführen und FPGA mit microblaze-Core implementieren
  • Erstellung der compilerumgebung (board support package, libraries, linkerscript)
  • Erstellung und Kompilierung des Programms
  • Zusammenfügen programm-binarie mit FPGA-bitstream file

Benötigte Software

Es wird von Xilinx die FPGA Implementierungssoftware (ISE) und das Software Development Kit (SDK) benötigt. Nutzer der FPGA vor der 7. Generation (z.B. Spartan-3-Großfamilie, Spartan-6, Virtex-5/-6) müssen installieren:

  • ISE Design Suite: WebPack edition ODER
  • ISE Design Suite: Embedded edition

(Siehe http://www.xilinx.com/products/design-tools/ise-design-suite.html )

Nutzer der neueren 7er Reihe dagegen benötigen:

  • Vivado Design Suite Webpack edition (oder größer)

(Siehe http://www.xilinx.com/products/design-tools/vivado.html)

Beispiel

Es wird ein einfacher Core mit 3 Ausgangsport a 8,4 und 6 bit, einem Eingangsport zu 8bit sowie einem Festwert- (FIT) und ein programmierbarer Zähler (PIT) generiert.

Blockdiagramm Beispiel

Neben dem Core ist ein weitere Zähler -heartbeat- im Design. Die drei Ausgangsporst sind für das verwendete S3AN Starterkit verbunden mit dem Datenbus und den Steuerleitung des alphanumerischen Displays und den 6 LED rechts. Die LED Nr 8 wird von dem FPGA-Logiccounter zum blinken gebracht, LED nummero 7 vom toggle-signal des Festwertcounter. Damit lassen sich 3 Implementierungsziele detektieren.

  • Nix blinkt -> Totalversagen
  • LED Nr. 8 blinkt -> FPGA erfolgreich geladen und gestartet
  • LED 8 und 7 blinken: -> microblaze ist erfolgreich im FPGA implementiert, aber das Programm läuft nicht.
  • Aktivität auf allen 8 LED's -> Perfekt

FPGA-Implementierung und SoftCore-Generierung

FPGA-Gerüst

Es ist Empfehlenswert zuerst ein "Basis-FPGA" ohne µB fertigzustellen und zu testen. Hier wurde das zum Starterkit gehörige Demo adaptiert und somit war schon mal die Pinzuordnung und das Taktsystem fehlerfrei. Eine heartbeat-LED die im Sekundentakt blinkt grenzt den Fehler deutlich ein.


CoreGen

CoreGen starten (beispw. Programme -> Xilinx -> ISE 14.7 -> ISE Design tools -> 64bit tools -> coregen). Project für den benutzen FPGA aufsetzen (hier im Beispiel S3AN-700; package: FGG484; speedgrade 4; Verilog)

Im IP Catalog findet sich der MCE unter embedded Processing -> processors -> microblaze MCE :

CoreGen Auswahl microblaze MCS Core

Im Unterschied zum Screenshot sollte man den Speicher auf mindestens 8 kByte setzen. Die Angabe der Taktfrequenz ist nur für die Berechnung des Baudraten-Teilers für die UART wichtig. Benutzt man die UART nicht, ist dieser Wert (theoretisch?) für den Core bedeutungslos. Das Place&Route für den FPGA richtet sich nach der Taktvorgabe aus dem ucf-file. Die in den Karteikarten gezeigten Kürzel stehen für die einzigen "Peripherie-controllern" die für dem µB-MCS generiert werden können. Mit dem weiterhin kostenpflichten Platform Studio sind weitere Cores einfach hinzufügbar. Aber beim MCS muß man nicht komplett darauf verzichten da an dem IO-Bus selbtgeschriebene Komponenten angeschlossen werden können.

  • UART: feste Baudrate, Interrupt für RX
  • FIT: Fixed length timer -4 möglich
  • PIT: programmable Timer - 4 möglich
  • GPO: Generalpurpose Output-Port - 4 Ports mit jeweils 1-32 bit Breite Konfigurierbar
  • GPI: Generalpurpose Input-Port - 4 Ports mit jeweils 1-32 bit Breite Konfigurierbar
  • INT: External Interrupt Sources

Für die Treiber kann auch ein toggle output signal generiert werden das immer beim Erreichen der '0' invertiert wird.

CoreGen Settings für microblaze MCS Teil 1
CoreGen Settings für Fixed Timer
Liste Generierter Dateien

Mit

Coregen Hinweis nächste Schritte
Coregen Hinweis Tcl-script
Tcl-Console

Vorbereitung Synthese mit MCS core

Top-Level

wire heartbeat_s;
  
  wire  [7:0] GPO1_s;   //display data
  wire  [3:0] GPO2_s;   //display control
  wire  [6:0] GPO3_s;   // led's
  wire  [7:0] GPI1_s;  //switches
  
  wire FIT1_Toggle_s;
  
MikroBlaze_mcs microblaze_s3an_disp (
  .Clk(clk),                       // input Clk
  .Reset(rst),                     // input Reset
  .FIT1_Toggle(FIT1_Toggle_s),       // output fixed timer toggler (every 25M ticks)
  .FIT2_Interrupt(/*FIT2_Interrupt*/), // UNUSED - output FIT2_Interrupt
  .FIT2_Toggle(/*FIT2_Toggle*/),       // UNUSED - output FIT2_Toggle
  .PIT1_Interrupt(/*PIT1_Interrupt*/), // UNUSED - output PIT1_Interrupt
  .PIT1_Toggle(/*PIT1_Toggle*/),       // UNUSED - output PIT1_Toggle
  .GPO1(GPO1_s),                       // output [7 : 0] GPO1
  .GPO2(GPO2_s),                       // output [3 : 0] GPO2
  .GPO3(GPO3_s),                       // output [6 : 0] GPO3  
  .GPI1(GPI1_s),                       // input  [7 : 0] GPI1
  .GPI1_Interrupt(/*GPI1_Interrupt*/), // UNUSED - output GPI1_Interrupt
  .INTC_IRQ(/*INTC_IRQ*/)              // UNUSED - output INTC_IRQ
);

always @(posedge clk)
begin

 assign LCD_DB = GPO1_s[7:0];
 assign LCD_RW = GPO2_s[0];
 assign LCD_RS = GPO2_s[1];
 assign LCD_E  = GPO2_s[2];
end

heartbeat heartbeat(
   .clk(clk),
   .rst(rst),
   .heartbeat_o(heartbeat_s)
);

assign LED[7] = heartbeat_s;  
assign LED[6] = FIT1_Toggle_s; 
assign LED[5:0] = GPO3_s[5:0];


FPGA Implementierung

Am besten den FPGA mit den µB-MCS vor der Vorbereitung des SDK komplett implementieren und auf das Board laden. Es müßen die LED's 7 und 8 mit jeweils eigene Frequenz blinken. Wenn nicht, dann ist bei der Generierung und Instanziierung des Cores ein Fehler unterlaufen.

Jetzt, falls noch nicht geöffnet, ein Tcl Fenster öffnen (ISE:View->Panels->Tcl Console) dann erscheint unten eine schmale Zeile in der Tcl Kommandos eingegeben werden können, die Ausgabe erscheint in dem Fenster darüber.

Jetzt das vom coregen erzeugte tcl Script starten: source ../core/microblaze_mcs_setup.tcl . Dieses script fügt eine Option für das tool ngdbuild (Process "Translate") bei der Implementierung hinzu. Zur Überprüfung die Optionen anzeigen lassen mit Mausklick rechts auf "Translate" im Process-Fenster und "process properties" auswählen. Es findet sich jetzt in der Zeile "Other ... options" ein Eintrag beginnend mit "-bm" der auf eine ebenfalls von coregen erzeugtes *.bmm Datei zeigt.

Tcl-Console

Diese Datei am besten in einem Texteditor öffnen. wichtig ist hier der Pfad zu den RAM-Blöcken die das binary für den Softcore speichern werden. Der Teil ganz links ist der in ersten CoreGen-Fenster angegebene Instanz-name. Der muss auch mit dem Instanznamen im Top-file übereinstimmen, sonst bricht Translate ab. Entfernt man die grad erwähnte -bm Option wieder aus den "Process Properties" läuft zwar der Schritt Translate und alle Folgenden durch, aber es wird Probleme bei "Vereinigung von Programm-binarie und FPGA bitfile" geben -> die FPGA logic wird zwar funktionieren, aber es wird kein Programm auf dem Softcore laufen.

Generierung Compilerumgebung und microblaze-programm

Für die folgenden Schritte ist das Software development Kit (SDK) zu starten, das findet sich im Ordner EDK (Embedded Development Kit):

Startmenu mit Xilinx-tools

Das SDK fragt beim Start nach einem Verzeichniss für den workspace.

Dannach erscheint beim ersten Start ein Welcome-Screen. Diesen an besten wegklicken da er das fenster "project explorer" überdeckt. Jetzt müßen wir nacheinander 3 verschieden "typen" von "projekten" anlegen:

  • Hardware Platform spezification - eine beschreibung des systems aus microblaze, Programmspeicher und Peripherie.
Diese benötigt die Infos aus dem Coregenlauf
  • board support package - Header-dateien, linkerskripte mit kosntanten/ addressbereichen etc. passend zum mikrocontrollersystem
  • C/C++projekt die leere C-datei für das eigentliche Programm
New -> Projects

Hardware Platform Specification

File -> new -> project -> Xilinx -> Hardware Platform Specification

Der Projectname erscheint dann im project explorer. Der Autor wählte zur besseren Unterscheidbarkeit zu den anderen Projekttypen den suffix _hwp. in der Spalte hardwareproject-file ist das file aus den Coregen-lauf anzugeben, es findet sich daher in dem Verzeichniss Core.

Erstellung Hardware project

Ss hardware palltform settings.png

Erstellung Board support package

Nachdem die Infodateien für die Hardware des µB-MCE System generiert worden, werden nun dazu passende Header Dateien und Bibliotheken generiert. Die erstellten Dateien werden auch als "Board support package" bezeichnet. Dazu wird das Menü File -> New -> "Board Support package" audgewählt, dem Namen des support packages sollte man eine Endung wie _BSP anhängen. Im Feld "Target Hardware" trägt man die gerade erstellte Plattform ein, als Betriebssystem "OS" ist standalone eingetragen.

Aufsetzen board support package

Erstellung Programm

Ss sdk cproject settings.png
#include <xparameters.h>
#include <xiomodule.h>
#include <stdbool.h>

#define LED_DELAY 100000

int main()
{
	//instantiate IOs
	XIOModule GPIO;

	volatile u32 i = 0;

	//initialize IOs
	XIOModule_Initialize(&GPIO, XPAR_IOMODULE_0_DEVICE_ID);
	XIOModule_Start(&GPIO);

	//LED
	bool led_on = false;
	int run = 1;

	for (;;)
	{
		if (led_on) {XIOModule_DiscreteWrite(&GPIO, 3,run);
		             if (run == 0x20) run = 1; else run *= 2;}
		led_on = !led_on;
		for(i=0;i < LED_DELAY; ++i);
	}
}

Zusammenfügen FPGA bitstream und Executable zur downladbaren Datei

Im Menu "Xilinx Tools" den Punkt "Programm FPGA" auswählen und

Menu SDK program FPGA

anschließend das (beim CoreGen) angelegte *.bmm file, das compilierte Programm (*.elf) und das *.bit File des in der ISE generierten FPGA's auswählen und den Button "Program" drücken.

Auswahl *.bmm *.bit *.elf for programming

Jetzt wird mittels der Information über die genutztem BRAM-Blöcke aus der *.bmm-Datei im *.bit-File die Bereiche die die Initdaten für die BRAM-Speicherblöcke enthält mit dem Binary des Programms ausgetauscht und anschließend das FPGA programmiert.

Fehlersuche

Wenn möglich auch die beiden Zwischenergebnisse ("Gesamtdesign ohne MCS-Core instanziierung" und "Mit Core aber ohne Programm" am Board testen. Nur so lassen sich Fehler auf die Schritte im workflow zurückführen.

Bei Änderungen am Core versagt gelegentlich das automatische Update von BPS etc.. Deshalb bei Coreänderungen die obsoleten Projekte (Hardware project, BSP und C-projekt) löschen und den workflow ab Schritt "tcl.script" wiederholen.

Fehlermeldungen in die Eingabemaske von google kopieren und nach Antworten bei Xilinx oder Internetforen suchen. Das führt bei den oft verwirrenden Fehlermeldungen schnell zum Erfolg. So weist diese Meldung über Memory leaks:

ngdbuil error

eigentlich darauf hin, das der Instanzname des MCS-cores nicht stimmt. Der "Answer record" bei Xilinx http://www.xilinx.com/support/answers/51538.html erklärt wie man den korrekten Namen findet und in das BMM-file einträgt.


Literatur

Als Beispiel wird eine microblaze basierte UART-Verbindung zwischen PC und Nexsys2/3 board implementiert, verwendet wird die ISE 14.5.

Eine Englischsprachige Klickanleitung für das papilio-One board. Hier wird auch gezeigt wie UCF und top entity mit dem PlanAHead tool angelegt wird. Die Screenshost sind recht gut kommentiert.