Kleinere Änderungen
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 155 KiB |
Binary file not shown.
+14
-14
@@ -6,10 +6,10 @@ Dieses Projekt umfasst die Konzeptionierung und Implementierung eines IPs zur Be
|
||||
Die Verarbeitung erfolgt paketweise, wobei die Daten aus dem Speicher gelesen, verarbeitet und mit angehängter Prüfsumme wieder zurückgeschrieben werden.
|
||||
Der Speicherzugriff erfolgt über eine AXI-Master-Schnittstelle.
|
||||
|
||||
Nach Implementierung der Hardware erfolgt die Erstellung von Software, welche die Konfiguration und Steuerung des IP-Cores übernimmt.
|
||||
Nach Implementierung der Hardware erfolgt die Erstellung von Software, die die Konfiguration und Steuerung des IP-Cores übernimmt.
|
||||
Der Softwarepart dieser Arbeit besteht aus zwei Programmen.
|
||||
Beim ersten handelt es sich um ein C-Programm, welches ohne Betriebssystem auf dem Mikroprozessor des hier verwendeten Entwicklungsboards \cite{ZyboBoard} ausgeführt wird.
|
||||
Das zweite Programm wird im Kontext eines Linux Betriebssystems ausgeführt und beinhaltet die Implementierung eines ausführlichen Testprogramms, welches die Funktionalität des IP-Cores überprüft.
|
||||
Beim ersten handelt es sich um ein C-Programm, das ohne Betriebssystem auf dem Mikroprozessor des hier verwendeten Entwicklungsboards \cite{ZyboBoard} ausgeführt wird.
|
||||
Das zweite Programm wird im Kontext eines Linux Betriebssystems ausgeführt und beinhaltet die Implementierung eines ausführlichen Testprogramms, das die Funktionalität des IP-Cores überprüft.
|
||||
|
||||
\subsection{Anforderungen} \label{sec:Anforderungen}
|
||||
|
||||
@@ -29,7 +29,7 @@ Die Anforderungen an das Projekt und an das zu erstellende IP umfassen folgende
|
||||
|
||||
\subsection{CRC - Theoretische Grundlagen} \label{sec:CRCGrundlagen}
|
||||
|
||||
Der Cyclic Redundancy Check (CRC) ist ein Verfahren zur Fehlererkennung, welches in der Regel in digitalen Kommunikationssystemen eingesetzt wird.
|
||||
Der Cyclic Redundancy Check (CRC) ist ein Verfahren zur Fehlererkennung, das in der Regel in digitalen Kommunikationssystemen eingesetzt wird.
|
||||
Die CRC-Berechnung basiert auf der Division eines Datenwortes durch ein Generatorpolynom.
|
||||
Der Rest der Division ist die CRC-Prüfsumme.
|
||||
|
||||
@@ -53,7 +53,7 @@ Mit diesen Parametern lässt sich jeder standartisierte CRC-Algorithmus definier
|
||||
|
||||
\section{Konzept und Umsetzung des CRC-DMA-IP}
|
||||
|
||||
Im Rahmen dieses Projektes wurde ein IP-Block entwickelt, welcher die komplette CRC-DMA Funktionalität beinhaltet.
|
||||
Im Rahmen dieses Projektes wurde ein IP-Block entwickelt, der die komplette CRC-DMA Funktionalität beinhaltet.
|
||||
Dieser kann anschließend in ein größeres System eingebunden werden, um die CRC-Prüfsummen von Datenpaketen zu berechnen und diese wieder zurückzuschreiben.
|
||||
Die Einbindung in ein Gesamtsystem wird in Abschnitt~\ref{sec:Einbindung} beschrieben.
|
||||
|
||||
@@ -194,7 +194,7 @@ Die Schreib- und Leseburst sind in zwei separaten Prozessen bzw. endlichen Autom
|
||||
Daher kann die Komponente parallel Daten lesen und schreiben.
|
||||
|
||||
Des Weiteren hält diese Komponente alle AXIL-Register des IPs, wofür sie eine \emph{S\_AXIL} Schnittstelle besitzt.
|
||||
Die Register, welche zur Konfiguration der CRC-Berechnung dienen, sind als Ausgänge nach Außen geführt.
|
||||
Die Register, die zur Konfiguration der CRC-Berechnung dienen, sind als Ausgänge nach Außen geführt.
|
||||
|
||||
\subsubsection{CRC-Berechnungskomponente - axis\_crc}
|
||||
|
||||
@@ -211,7 +211,7 @@ Sie fließen in die Kombinatoriken der CRC-Berechnung ein.
|
||||
|
||||
Die Berechnung der CRC-Prüfsumme erfolgt wort-weise.
|
||||
Der Datenstrom von 32-Bit Worten wird über die \emph{S\_AXIS} Schnittstelle eingelesen und wieder über die \emph{M\_AXIS} Schnittstelle ausgegeben.
|
||||
Dabei kann maximal alle 3 Takte ein Wort eingelesen werden, welches in die Berechnung der CRC-Prüfsumme einfließt.
|
||||
Dabei kann maximal alle 3 Takte ein Wort eingelesen werden, das in die Berechnung der CRC-Prüfsumme einfließt.
|
||||
Das Ende eines Datenpaketes wird durch das \emph{S\_AXIS\_TLAST} Signal markiert.
|
||||
Wenn die Komponente dieses Signal erhält, beendet sie die CRC-Berechnung und gibt das berechnete CRC-Wort über die \emph{M\_AXIS} Schnittstelle aus.
|
||||
Die CRC-Prüfsumme wird dadurch an den Datenstrom des ursprünglichen Datenpakets angehängt.
|
||||
@@ -330,11 +330,11 @@ Daher liegt ein besonderes Augenmerk auf der Verifikation dieser Komponente.
|
||||
|
||||
\subsubsection{Referenzprogramm}
|
||||
|
||||
Zunächst wurde das C-Programm \emph{crc.c} geschrieben, welches CRC-Prüfsummen in Software berechnet.
|
||||
Zunächst wurde das C-Programm \emph{crc.c} geschrieben, das CRC-Prüfsummen in Software berechnet.
|
||||
Der CRC-Algorithmus wurde hauptsächlich mithilfe von Sunshine2k.de \cite{SunshineCrcErklärung} erstellt.
|
||||
Parallel wurden die Ergebnisse mit anderen CRC-Online Rechnern verglichen, um die Korrektheit der Berechnung zu überprüfen \cite{crcCalc}.
|
||||
|
||||
Kern dieses Programms ist die Funktion \texttt{uint32\_t calcCRC32(...)}, welche die CRC-Prüfsumme über ein Datenpaket berechnet.
|
||||
Kern dieses Programms ist die Funktion \texttt{uint32\_t calcCRC32(...)}, die die CRC-Prüfsumme über ein Datenpaket berechnet.
|
||||
Mithilfe dieser Funktion können CRC-Prüfsummen für beliebige Datenpakete und für eine beliebige Kombination an CRC-Parametern berechnet werden.
|
||||
|
||||
Neben dem testweise Berechnen von Prüfsummen werden in der \texttt{main}-Funktion auch die CRC-Prüfsummen für die Testbench der CRC-Berechnungskomponente berechnet.
|
||||
@@ -423,7 +423,7 @@ Die in dieser Arbeit erstellte CRC-Berechnungskomponente wurde mithilfe dieser T
|
||||
\label{fig:BlockschaltbildCRC_DMA_IP_Simulation}
|
||||
\end{figure}
|
||||
|
||||
Zur Simulation des gesamten CRC-DMA-IPs wird das Block-Design \emph{axi\_crc\_dma\_sim\_01} verwendet, welches in Abbildung~\ref{fig:BlockschaltbildCRC_DMA_IP_Simulation} dargestellt ist.
|
||||
Zur Simulation des gesamten CRC-DMA-IPs wird das Block-Design \emph{axi\_crc\_dma\_sim\_01} verwendet, das in Abbildung~\ref{fig:BlockschaltbildCRC_DMA_IP_Simulation} dargestellt ist.
|
||||
Das IP \emph{axil\_master\_with\_rom} ist ein AXIL-Master, der die nötige Konfiguration des CRC-DMA-IPs durchführt und den Vorgang anschließend startet.
|
||||
Er stammt aus dem IP-Verzeichnis dieser Vorlesung.
|
||||
Die AXIL-Schreibbefehle für den AXIL-Master sind im Stimuli-Script \emph{axi\_crc\_dma\_sim.stm} definiert.
|
||||
@@ -465,7 +465,7 @@ Zusätzlich wurden dabei verschiedene Konfigurationen des IPs getstest, um auch
|
||||
|
||||
Die Verifikation des Gesamtsystems erfolgt auf der Hardware.
|
||||
|
||||
Für die finale Verifikation des CRC-DMA-IPs bzw. des Gesamtsystems wurde das Testprogramm \texttt{CRC\_DMA.cpp} erstellt, welches im Kontext eines Linux Betriebssystems ausgeführt wird.
|
||||
Für die finale Verifikation des CRC-DMA-IPs bzw. des Gesamtsystems wurde das Testprogramm \texttt{CRC\_DMA.cpp} erstellt, das im Kontext eines Linux Betriebssystems ausgeführt wird.
|
||||
Das Testprogramm ist in mehrere Testläufe unterteilt.
|
||||
Der Ablauf eines Testlaufs ist wie folgt:
|
||||
\begin{enumerate}
|
||||
@@ -473,13 +473,13 @@ Der Ablauf eines Testlaufs ist wie folgt:
|
||||
\item Zufällige Datenpakete erzeugen mit einer zufälligen Paketanzahl und -größe
|
||||
\item Konfiguration der CRC-DMA-IPs
|
||||
\item Starten des CRC-DMA-IPs
|
||||
\item Berechnen der CRC-Prüfsummen in Software zur Verifikation
|
||||
\item Warten auf den Interrupt des IPs
|
||||
\item Berechnen der CRC-Prüfsummen in Software zur Verifikation
|
||||
\item Überprüfen der vom IP geschriebenen Daten und CRC-Prüfsummen
|
||||
\end{enumerate}
|
||||
|
||||
Die Anzahl der Testläufe wird dem Programm als Argument beim Ausführen übergeben.
|
||||
Die Ausgabe des Programms erfolgt sowohl über die Konsole als auch in eine Logdatei.
|
||||
Die Ausgabe des Programms erfolgt sowohl über die Konsole als auch in eine Logdatei, die automatisch erstellt wird.
|
||||
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
@@ -492,7 +492,7 @@ In Abbildung~\ref{fig:AusgabeTestprogramm} ist exemplarisch die Ausgabe des Test
|
||||
Zur Verifikation des CRC-DMA-IPs können nun mithilfe dieses Programms im großen Umfang CRC-Berechnungsvorgänge ausgeführt werden.
|
||||
Durch eine große Anzahl an Testläufen, kann so sichergestellt werden, dass, wenn das IP fehlerhaft ist, diese Fehler auch entdeckt werden.
|
||||
|
||||
Anbei dieser Projektarbeit befindet sich eine Logdatei des Testprogramms, welche die Ausgabe für 100 Testläufe enthält.
|
||||
Anbei dieser Projektarbeit befindet sich eine Logdatei des Testprogramms, die die Ausgabe für 100 Testläufe enthält.
|
||||
Ergebnis dieses Tests ist, dass bei insgesamt gelesenen Menge von ca. 100MB Daten keine Fehler aufgetreten sind.
|
||||
Alle Daten wurden korrekt in den Speicher geschrieben.
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
breaklines=true, % Automatischer Zeilenumbruch
|
||||
frame=single, % Rahmen um den Codeblock
|
||||
captionpos=b, % Position der Beschriftung
|
||||
morekeywords={uint32_t, uint16_t, uint8_t, size_t},
|
||||
morekeywords={uint32_t, uint16_t, uint8_t, size_t, CrcParameterSet, PCRC_DMA_Typedef, CRC_DMA_Typedef},
|
||||
}
|
||||
|
||||
%Zum Zusammenfügen von Spalten in tabular
|
||||
|
||||
+36
-31
@@ -14,7 +14,6 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "axi_crc_dma.h"
|
||||
#include "gip.h"
|
||||
|
||||
|
||||
// #define DEBUG
|
||||
@@ -38,7 +37,23 @@ uint32_t calcCRC32(
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int testRuns;
|
||||
// Testlaeufe, Paketgroesse und Paketanzahl
|
||||
int testRuns = TEST_RUNS;
|
||||
// int maxPacketSize = MAX_PACKET_SIZE;
|
||||
// int maxNumberPackets = MAX_NUMBER_PACKETS;
|
||||
|
||||
// Argumente auswerten
|
||||
if (argc > 1) {
|
||||
testRuns = atoi(argv[1]);
|
||||
}
|
||||
// if (argc > 2) {
|
||||
// maxPacketSize = atoi(argv[2]);
|
||||
// }
|
||||
// if (argc > 3) {
|
||||
// maxNumberPackets = atoi(argv[3]);
|
||||
// }
|
||||
|
||||
// Logdatei anlegen
|
||||
char logFileName[100];
|
||||
time_t now = time(NULL);
|
||||
struct tm *t = localtime(&now);
|
||||
@@ -51,13 +66,6 @@ int main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
testRuns = TEST_RUNS;
|
||||
}
|
||||
else {
|
||||
testRuns = atoi(argv[1]);
|
||||
}
|
||||
|
||||
// some established CRC32 Parameter sets. Source: https://reveng.sourceforge.io/crc-catalogue/ (13.02.2025)
|
||||
const CrcParameterSet CRC32_AIXM = {
|
||||
.Polynomial = 0x814141ab,
|
||||
@@ -110,9 +118,6 @@ int main(int argc, char** argv)
|
||||
PCRC_DMA_Typedef CRC = (PCRC_DMA_Typedef) mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fdCRC, 0);
|
||||
uint32_t* pMem = (uint32_t*) mmap(NULL, 0x20000000, PROT_READ | PROT_WRITE, MAP_SHARED, fdMem, 0);
|
||||
|
||||
// Interrupt zuruecksetzen
|
||||
CRC->InterruptStatus = 0;
|
||||
|
||||
// Physische Adressen anlegen
|
||||
uint32_t uio16PhysBase = 0x30000000; // UIO16 physical Baseaddress
|
||||
uint32_t* pDataPhy = (uint32_t*) uio16PhysBase;
|
||||
@@ -170,6 +175,21 @@ int main(int argc, char** argv)
|
||||
fprintf(logFile, "CRC-Berechnung in Hardware starten\n");
|
||||
CRC->Control |= (1<<0);
|
||||
|
||||
// Auf INT warten
|
||||
printf("Auf Interrupt warten...\n");
|
||||
fprintf(logFile, "Auf Interrupt warten...\n");
|
||||
int pending;
|
||||
read(fdCRC, (void*) &pending, 4);
|
||||
CRC->InterruptStatus = 0;
|
||||
write(fdCRC, (void*) &reenable, 4);
|
||||
printf("Interrupt erhalten\n");
|
||||
fprintf(logFile, "Interrupt erhalten\n");
|
||||
|
||||
// Hardwareergebnis in Array ablegen
|
||||
for (int p = 0; p < number_packets; p++) {
|
||||
crc_hw[p] = DataDest[p][packet_size];
|
||||
}
|
||||
|
||||
// CRC Berechnung in Software durchfuehren
|
||||
printf("CRC-Berechnung in Software durchfuehren\n");
|
||||
fprintf(logFile, "CRC-Berechnung in Software durchfuehren\n");
|
||||
@@ -187,21 +207,6 @@ int main(int argc, char** argv)
|
||||
// fprintf(logFile, "Packet %i:\t0x%08x\n", p, crc_sw[p]);
|
||||
}
|
||||
|
||||
// Auf INT warten
|
||||
printf("Auf Interrupt warten...\n");
|
||||
fprintf(logFile, "Auf Interrupt warten...\n");
|
||||
int pending;
|
||||
read(fdCRC, (void*) &pending, 4);
|
||||
CRC->InterruptStatus = 0;
|
||||
write(fdCRC, (void*) &reenable, 4);
|
||||
printf("Interrupt erhalten\n");
|
||||
fprintf(logFile, "Interrupt erhalten\n");
|
||||
|
||||
// Hardwareergebnis in Array ablegen
|
||||
for (int p = 0; p < number_packets; p++) {
|
||||
crc_hw[p] = DataDest[p][packet_size];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// data und DataDest komplett ausgeben
|
||||
printf("\ndata\tDataDest:\n");
|
||||
@@ -225,8 +230,8 @@ int main(int argc, char** argv)
|
||||
|
||||
// Daten und Ergebnisse vergleichen
|
||||
unsigned int wrongWords = 0; // Zaehler fuer Anzahl der fehlerhaften Worte im (Ziel-)Speicher
|
||||
printf("Daten und Ergebnisse vergleichen\n\n");
|
||||
fprintf(logFile, "Daten und Ergebnisse vergleichen\n\n");
|
||||
printf("Daten und Ergebnisse vergleichen:\n");
|
||||
fprintf(logFile, "Daten und Ergebnisse vergleichen:\n");
|
||||
bool allPaketsOK = true;
|
||||
for (int p = 0; p < number_packets; p++) {
|
||||
bool dataOK = true;
|
||||
@@ -272,8 +277,8 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
if (allPaketsOK) {
|
||||
printf("Alle Pakete OK\nTestdurchlauf erfolgreich abgeschlossen!\n");
|
||||
fprintf(logFile, "Alle Pakete OK\nTestdurchlauf erfolgreich abgeschlossen!\n");
|
||||
printf("Alle Pakete OK\nTestlauf erfolgreich abgeschlossen!\n");
|
||||
fprintf(logFile, "Alle Pakete OK\nTestlauf erfolgreich abgeschlossen!\n");
|
||||
} else {
|
||||
allTestrunsOK = false;
|
||||
printf("Ein oder mehrere Pakete nicht OK.\n");
|
||||
|
||||
Reference in New Issue
Block a user