Durchblicker
von Benutzer:Fpgakuechle (Volker Urban)
Dieser Artikel beschreibt einen auf einen FPGA-Board realisierten Logic-analyzer. Im Unterschied zu ähnlichen Projekten wird kein PC zur Steuerung/Datendarstellung benötigt, die Zeitverläufe werden über ein an das Board angeschlossenen VGA-Monitor direkt ausgegeben.
Das Projekt ist noch in der Entwicklung, erste Ergebnisse können bereits gezeigt werden:
Systembeschreibung
Konzept
Sechszehn Signale werden permanent in dem FPGA-internen Speicher (xilinx 1 BRAM a 8kbit) aufgezeichnet. Für die Aufzeichnung langsame veränderliche Signale wie RS232/PS2-IF wird über einen Teiler ein sample-write enable erzeugt. Nach Auftritt eines Triggerevents endet das zyklische beschreiben nach 50% der Speicherkapazität. Damit sind die Signalwerte vor und während des Triggervents gesichert. Die Daten aus dem Samplespeicher werden im FPGA zu einem Waveformdiagramm aufbereitet und auf einem an das Board angeschlossenen VGA-Monitor dargestellt. Zur Auswertung sind zwei Vertikal-Cursor implementiert, der Bitvector "unter" dem Cursor und der Abstand zwischen den Cursor wird als hexadezimalzahl ausgegeben.
Das Triggerevent (Quelle: einer aus den 16 Kanälen oder externer Trigger, Flanke) und Modus (single, autotrigger, continous, force) ist frei wählbar. So erhält der Entwickler einen on-chip Logicanalyzer ähnlich Chipscope (Xilinx), Signaltap (Altera) oder CLAM (Actel) ohne das Lizenzengebühren anfallen oder ein spezieller JTAG-programmer nötig ist.
Erweiterungsoptionen
- Skalierung der Anzahl der aufgezeichneten Signale durch mehrfache Instanziierung des sig_record Modul und Einfügen eines multiplexers zum display Modul
- komplexe Triggerfunktionen durch Beschaltung des Eingangs externer Trigger
Bedienkonzept
Sampledarstellung
In jeder Spalte wird ein sample dargestellt, damit können 512 Samples auf 512 Spalten eines 800x600 dargestellt werden und der u.U. schwer lesbare Seitenrand wird ausgespart. Um den Wert einzelner sample bei dieser dichten Anordnung noch zu unterscheiden zu können wird der samplewert wie folgt dargestellt
t-1 | t | Beschreibung | Darstellung Signal | Darstellung Cursor |
'0' | '0' | konstant low | einzelnes Pixel unterer Rand | volle Länge mit Farbpixel unten |
'0' | '1' | auf High steigend | mehrere Pixel in unterer Hälfte | Halblang obere Hälfte, unten Farbpixel |
'1' | '0' | auf Low fallend | mehrere Pixel in oberer Hälfte | Halblang untere Hälfte, oben Farbpixel |
'1' | '1' | konstant high | einzelnes Pixel oberer Rand | volle Länge mit Farbpixel unten |
wobei t das Sample zu gegenwärtigen Zeitpunkt ist, t-1 das am vorhergehenden Samplezeitpunkt davor.
In mittleren Statuszeile wird der Signalwert als vierstellige Hexadecimal-Zahl angezeigt.
Bildschirmeinteilung
der Bildschirm ist in 18 horizontale Sektionen (Streifen) geteilt:
Nummer section (von oben) | Was | Darstellung |
1-8 | signal(0) bis signal(7) | Waveform + x-Raster |
9 | Werte unter Cursor 1 und 2 | 2xHex a 16 bit |
10-17 | signal(8) bis signal(15) | Waveform + x-Raster |
18 | Position Cursor 1 und 2 | 2xHex a 12 bit |
In der 800x600 Auflösung besteht jede Sektion aus 32 pixel, so dass real 18,75 Sektionenen angezeigt würden, die 0,75 werden der unteren Sektion (Cursor-Position) zugeschlagen. Für die 16 Signale sind 4 Farben möglich. Die Vertikala Aufteilung ist in der Datei display_pkg.vhd in der konstanten CONSTANT C_SECTION_POS definiert.
CONSTANT C_SECTION_POS : T_POS_SECTION :=
(CHANNEL, CHANNEL, CHANNEL, CHANNEL,
CHANNEL, CHANNEL, CHANNEL, CHANNEL,
STATUS_VALUE,
CHANNEL, CHANNEL, CHANNEL, CHANNEL,
CHANNEL, CHANNEL, CHANNEL, CHANNEL,
STATUS_CPOS);
Für einen Channel-Streifen ist die Anordnung im selben package in der Konstanten C_LINE_POS hinterlegt:
CONSTANT C_LINE_POS: T_LINE_SECTION :=(
EMPTY, CH_HI, CH_HI, CH_TRANS_FAL, CH_TRANS_FAL, CH_TRANS_FAL, CH_TRANS_FAL, CH_TRANS_FAL,
CH_TRANS_FAL, CH_TRANS_FAL, CH_TRANS_FAL, CH_TRANS_FAL, CH_TRANS_FAL, CH_TRANS_RIS, CH_TRANS_RIS, CH_TRANS_RIS,
CH_TRANS_RIS, CH_TRANS_RIS, CH_TRANS_RIS, CH_TRANS_RIS, CH_TRANS_RIS, CH_TRANS_RIS, CH_TRANS_RIS, CH_TRANS_RIS,
CH_LO, EMPTY, EMPTY, GRID_COARSE, GRID_COARSE, GRID_FINE, EMPTY, EMPTY);
Die beiden Elemente CH_HI hintereinander bewirken das High-Wertt durch einen doppelt breite Linie dargestellt wird. Bei GRID_COARSE (Grob-Skala) wird eine Zeitmarke aller 10 pixel gesetzt, für GRID_FINE (Fein-Skala) wird für jedes zweite Pixel ein Punkt gesetzt.
Zeichendarstellung
Die Position der Cursor und der Wert aller Signale wird als Hexadezimalzahl dargestellt. Für die Werte 10 -15 werden die Kleinbuchstaben a-f verwendet um Verwechslungen mit den Zahlzeichen auszuschließen. Die Cursorposition wird nicht als Dezimalzahl dargestellt um die Logikressourcen für die Umwandlung zur BCD-Darstellung einzusparen.
Liniencursor
Bei der dichten Darstellung von mehreren hundert Signalwechsel auf 16 Kanälen sind Liniencursor unverzichtbar. Zwei vertikale Punktlinien werden als solche Hilfslinien eingeblendet, eine davon ist als "aktiv" auswählbar. Der aktive Liniencursor kann schrittweise nach rechts und links verschoben werden, die Schrittweite ist dabei aus 1, 10 oder 100 Pixel wählbar. Überschreitet der Cursor einen Seitenrand wird er auf dem gegenüberliegende Seite positioniert.
Zwei vertikale Liniencursor sind definiert, die als Strichlinie dargestellt werden. Einer der beiden ist aktiv, d.h. er kann seitlich verschoben werden. Der aktive Cursor wird in einer Punkt-leer-Punkt Linie dargestellt, der inactive in einer Punkt-leer-leer-leer-Punkt Linie. Die Cursorlinie wird von der Signallinie überdeckt.
Die Position der Cursor und das Delta wird als Hexadezimal in der unteren Statuszeile angezeigt, die Statuszeilen in der Mitte zeigt den Signalwert aller 16 Kanäle an der Cursorposition als Hex-Zahl.
Als weitere Bedienelemente stehen ein Taster zum Auslösen eines Triggers (ForceTrigger) zur Verfügung und Schalter zur Auswahl des Triggermodus (RUN;auto|normal).
Bedienelemente
Das Modul button_map setzt Schalterstellungen o.ä. für den Logicanalyzer um. Da jedes Board unterschiedliche Bedienelemte aufweis, findet sich dieses Modul im /board_specific Zweig der Quellen. Daneben ist auch die Nutzung einer PC-Tastatur als Steuerkonsole denkbar, viele FPGA-boards bieten dafür USB oder PS/2 Buchsen.
Nexsys3
Das Board ist so ausgerichtet das die Kante mit den Schaltern und Knöpfen dem Bediener zugewandt ist: Geklammerte Funktionen sind noch nicht implementiert
Triggering Channel ++ | ||
CursLi | force Trigger | CursRe |
Triggering Channel -- |
S7 | S6 | S5 | S4 | S3 | S2 | S1 | S0 |
STOP | SINGLE | Auto-trigger | Step = 100 | Step = 1 | Cursor1 aktiv | ||
RUN | CONTINOUS | normal | Step = F(S1) | Step = 10 | Cursor2 aktiv |
Xilinx Starterkit Spartan3
t.b.d Die Belegung der Schalter kann von Nexsys3 übernommen werden. Buttons bietet diese Board nur 4 die in einer Reihe angeordnet sind. Die beiden rechts könnten die Cursorsteuerung übernehmen,
PC-Tastatur
Da eine PC-Tastatur bekanntlich nur Knöpfe aber keine Schalter bietet, muss eine "eingerastete Stellung" explizit signalisiert werden. Beispielsweise durch eine Statusanzeige auf dem VGA-Monitor, oder über leuchtende/nicht leuchtende LED's die den "Schaltern" zugeordnet sind.
Modulbeschreibung
Durchblicker Top
- sk_wrapper.vhd [3] Wrapper für Nexsys3 kit mit Testpatterngenerator (Binärzählrt, PRN-Generator)
Name | Type | Minimalbeschaltung | Beschreibung |
Takte | |||
vga_clock | std_logic | 40 MHz clock | Takt für VGA-Interface (800x600) |
sig_clock | std_logic | clock der Testsignale | Takt der Testsignale |
Testport | |||
sig_port_i | std_logic_vector(15 downto 0) | Testsignale | 16 Testsignale |
pow2_div_i | std_logic_vector(3 downto 0) | "0000" | Teiler 1:2**x (für langsame Signale |
Anzeige (VGA-Interafce & Cursor) | |||
hsync_o | std_logic | VGA-Port | Horizontaler Sync f. VGA-Display |
vsync_o | std_logic | VGA-Port | Vertikaler Sync f. VGA-Display |
pixel_o | std_logic_vector(7 downto 0) | VGA-Port | 8-bit Farbe f. VGA-Display |
posx_curs0_i | std_logic_vector(10 downto 0) | x"010" | X-Position Cursor 0 |
posx_curs1_i | std_logic_vector(10 downto 0) | x"100" | X-Position Cursor 1 |
cursor0_active_i | std_logic | '0' | Auswahl Aktiver (beweglicher) Cursor |
Triggercontrol | |||
trigger_ext_i | std_logic | '0' | externer Trigger |
sel_channel4trigger_i | std_logic_vector(4 downto 0) | "00000" | Auswahl trigger aus 16 testsignale oder ext. trigger |
force_trigger_i | std_logic | '0' | Zwang-Trigger (Taste) |
auto_trigger_i | std_logic | '1' | selbst generierte Trigger (Tot-zeit) |
edge_rising_i | std_logic | '1' | Trigger event bei steiegnder Flanke |
run_i | std_logic | '1' | auf trigger wartend |
single_trigger_i | std_logic | '0' | nach nächsten Trigger inaktiv |
Anzeige
Source Files:
Trigger Generierung
Source Files:
Sample-Speicher
Source Files:
Das Modul sig_record ist der Signalrekorder des Logikanalyzers. In diesem Modul wird ein FPGA-interner Speicherblock als DualPort RAM instanziiert und die Schreib- sowie Leseradresse generiert. Geschrieben werden die Signale der Messleitungen als 16bit Wort, der Leseport wird vom Anzeigemodul angesteuert. Auf der Leseseite wird immer nur ein Signal ausgelesen. Die beiden Datenports sind somit unterschiedlich breit, auf der Schreibseite 16 bit auf der Leseseite 1 bit. Da der Speicher ständig ausgelesen wird, wird das zyklische Schreiben der Pretriggersamples als "Störung" sichtbar, insbesonders bei normal trigger mode mit seltenen triggerevent oder force-trigger.
Der Speicherbklock wird als Core generiert, da die VHDL-Beschreibung des Blocks bedingt durch die unterschiedlichen Wortbreiten komplexer ist als eine direkte Beschreibung als array. Auch kann so Architekturabhängig der ideale Speicher eingebunden werden, gegebenfalls FPGA-externer Speicher.
Benutzer-Interface
Source File: board_specific/nexys3/src/button_map.vhd [11]
Ressourcenbedarf
Um nur den einen unbedingt nötigen BRAM zur verwenden und die gesamte andere Logik aus LUT's aufzubauen wurde im Synthesetool (XST) die Option -bram_utilization_ratio 1# gesetzt, Für einen den Spartan6 - LX16 im CSG324 Gehäuse mit Speedgrade 3 ergibt sich mit der ersten beta-Implementation (2013-07-13) damit:
Ressource | Anzahl | Prozent zu FPGA |
Slices-FF | 266 | 1% |
SLice-LUT | 344 | 3% |
Slices | 136 | 6% |
BRAM | 1 | 3% |
Das ist für diesen FPGA ein geringer Aufwand für ein deutliches Plus an debug-Funktionalität. Durch den kompletten Verzicht auf die HexaDez Ausgabe könnte etwas Logik gespärt werden, allerdings wird durch das Auszählen von bits das Analysieren von Businhalten mühsam.
Quellen
Sourcedepot
Die Quelldateien (VHDL, konfigurationsfile, scripte) liegen auf sourceforge.net, ebenso erfolgt das gesamte source-code handling (bug tracking etc) auf SF:
Board- und Architekturunabhängigen Files liegen im Verzeichnis /src; files für bestimmte boards im Verzeichniss /board_specific bspw für das Digilent nexys 3 Boord Spartan6 unter /board_specific/nexys3/. Für die Generierung eines Bit-Files in das Verzeichnis /board_specific/nexys3/script wechseln und dort make bit starten.
Datei | Verzeichniss | Beschreibung |
vga_controller_800_60.vhd | /src | Controlsig f. VGA-Monitor |
display_pkg.vhd | /src | Bildschirmaufteilung etc. |
charrom.vhd | /src | Zeichensatz 0-F |
display.vhd | /src | Waveforms zeichnen |
trigger_pkg.vhd | /src | Typen für triggermodule |
trigger.vhd | /src | Triggersteuerung |
sample_mem.vhd | /boardspecific/Nexsys3/ | embedded Speicherblock als recording mem |
sig_record_pkg.vhd | /src | bspw. Portdefiniton recording mem |
sig_record.vhd | /src | Speicherungcontroller |
durchblicker_pkg.vhd | /src | Platzhalter, derzeit ungenutzt |
durchblicker.vhd | /src | Top-entity embedded logic analyzer |
clk_ctrl.vhd | /boardspecific/Nexsys3/ | Takterzeugung (VGA_clk, signal_clk) |
button_map.vhd | /boardspecific/Nexsys3/ | Tasten des Evalboards zur Steuerung LA |
sk_wrapper.vhd | /boardspecific/Nexsys3/ | Gesamtdesign für starterkit |
Status
- 2013-06-30: freilaufender Trigger funktioniert Cursors können per buttons verschoben werden
- 2013-07-01: Ausgabe der Cursorposition in Hex
- 2013-07-05: Ausgabe der Signalwerte "unter" Cursor -> [12]
- 2013-07-10: Multiplexor zur Auswahl triggernder Kanal verdrahtet (Buttons Up/Down), Fixes in Anzeige
- 2013-07-13: Umschalter für normal trigger hinzu, timing opts
- 2013-08-29: H-Pegel als Doppellinie, Hervorhebung triggernder Kanal (rote Skala), timing opts vga_clk, minor bugfix
- next: bugfixing trigger
- next+: sample-enable divider per Taster einstellbar für langsame Signale
Bekannte Mängel
- Fehler im pretrigger
- veraltete Sampls nicht als ungültig erkennbar
- falsche Pegelwechsel an Ende (rechts)
- ...