Port Input Event FIFO

Funktion

Ein PortIn_F-Modul funktioniert sehr ähnlich wie ein PortIn Modul, ist aber zur Erfassung von Ereignissen mit einer Zeit die kleiner ist als die Periodendauer des SpartanMC System Taktes geeignet. Desshalb besitzt das Modul einen zusätzlichen Takt Eingang, dessen Periodendauer zum Erfassen der Ereignisse an den Dateneingängen des Moduls verwendet wird. Das Modul wurde zur Erfassung der interen Zustände des USB-Interfaces während eines Datentransfers eingesetzt. Die Verwendung kann im SVN unter:

spartanmc-projects/branches/tests/usb11/pp_speed/(external link)

eingesehen werden.

Ein PortIn_F-Modul umfasst bis zu 18 Eingänge, die ein Event bei steigender oder fallender Flanke am Eingang erzeugen können und damit auch einen Interupt auslösen. Die Eingänge eines Moduls können einzeln programmiert werden, indem das jeweils korrespondierende Bit des entsprechenden Steuerregisters verändert wird. Es muss mindestens ein Bit Interrupts auslösen, um den FIFO zu beschreiben.

Register


OffsetRegisterFunktionZugriff
0PIN_IN_F_DATDaten aus dem FIFO lesen und FIFOreadadr+1read
1PIN_IN_F_IEInterrupt Freigabe für jedes Bitread/write
2PIN_IN_F_EDGSELAuswahl der zu überwachenden Bitread/write
3PIN_IN_F_IR_STATUSInterrupt Status für jedes Bit aus dem FIFO lesenread
4PIN_IN_F_FFSTATEFIFO Status Bitsread


Das Datenregister PIN_IN_F_DAT list die Daten der Pins des Port-In-F-Moduls aus dem FIFO und inkrementiert die FIFO-Adresse.

Im Steuerregister PIN_IN_F_IE können für die einzelnen Pins des Port IN-F-Moduls Interrupts aktiviert werden. Bei einem Reset werden alle Bits mit Null initialisiert. Auf das Register kann lesend und schreibend zugegriffen werden.

Im Steuerregister PIN_IN_F_EDGSEL kann für die Pins des Port In-F-Moduls ausgewählt werden, ob sie bei einer Flanke einen Interrupt generieren sollen oder nicht. Bei einem Reset werden alle Bits mit Null (= keine Überwachung) initialisiert. Auf das Register kann lesend und schreibend zugegriffen werden.

Im Statusregister PIN_IN_F_IR_STATUS werden für die einzelnen Pins des Port In-F-Moduls der Zustände der Interruptsignale aus dem FIFO gelesen. Die FIFO-Adresse wird dabei nicht inkrementiert. Auf das Register kann nur lesend zugegriffen werden. Die Bits des Registers werden erst bei einem Lesen eines der anderen 3 Register gelöscht. Damit können auch sehr kurze Impulse erkannt werden. Die gesetzten Bits des Registers lösen nur dann Interrupt aus, wenn auch das Bit an der gleichen Position im PIN_IN_F_IE Register gesetzt sind.

Im FIFO Statusregisrer PIN_IN_F_FFSTATE sind die drei Bits zur Arbeit mit dem FIFO in den unteren 3 Bits angeordnet.

PIN_IN_F_FFSTATEBezeichnungFunktionen
Bit 0: PORT_IN_F_EMPTY ist gesetzt wenn der FIFO leer ist und löscht PORT_IN_F_OV.
Bit 1: PORT_IN_F_FULLwird gesetzt, wenn alle Speicherplätze belegt sind
Bit 2: PORT_IN_F_OVwird gesetzt, wenn der FIFO geschrieben werden soll aber PORT_IN_F_FULL schon gesetzt ist.
Bit 3 bis 17: nicht benutzt
|

port_in_f.h

#ifndef __PORT_IN_F_H
#define __PORT_IN_F_H

#ifndef __PORT_IN_H

#define PORT_INBIT_0    (1<<0)
#define PORT_INBIT_1    (1<<1)
#define PORT_INBIT_2    (1<<2)
#define PORT_INBIT_3    (1<<3)
#define PORT_INBIT_4    (1<<4)
#define PORT_INBIT_5    (1<<5)
#define PORT_INBIT_6    (1<<6)
#define PORT_INBIT_7    (1<<7)
#define PORT_INBIT_8    (1<<8)
#define PORT_INBIT_9    (1<<9)
#define PORT_INBIT_10   (1<<10)
#define PORT_INBIT_11   (1<<11)
#define PORT_INBIT_12   (1<<12)
#define PORT_INBIT_13   (1<<13)
#define PORT_INBIT_14   (1<<14)
#define PORT_INBIT_15   (1<<15)
#define PORT_INBIT_16   (1<<16)
#define PORT_INBIT_17   (1<<17)

#endif

#define PORT_IN_F_EMPTY (1<<0)
#define PORT_IN_F_FULL  (1<<1)
#define PORT_IN_F_OV    (1<<2)          // wenn FF_FULL set = 1, wenn FF_EMPTY set = 0

typedef struct port_in_f {
    volatile unsigned int data;         // (r)   (r = reset-interrupt)
    volatile unsigned int ie;           // (r/w) (r = reset-interrupt)
    volatile unsigned int edgsel;       // (r/w) (r = reset-interrupt)
    volatile unsigned int ir_stat;      // (r)
    volatile unsigned int ff_stat;      // (r)
} port_in_f_regs_t;

#endif


Konfiguration und Instanziierung


Bei der Instanziierung eines IO-Moduls gibt es zwei Parameter, die man einstellen muss: PORT_WIDTH und FIFO_DEPTH. PORT_WIDTH bezeichnet die Breite des jeweiligen Ports, sie kann von 1 Bit bis 18 Bit eingestellt werden. FIFO_DEPTH ist die Anzahl der Speicherplätze des FIFO. Sie wird automatisch immer auf die nächst größere 2er Potenz ausgerichtet. Der FIFO ist immer doppelt so breit wie PORT_WIDTH, da er die Daten der Register "data" und "ir_stat" für jedes Event puffert.

Die Interruptleitung des Moduls muss an den gewünschten Eingäng des Interruptkontrollers angeschlossen werden und die IO-Pins an die Ein- und Ausgänge des Top Level Moduls oder eines anderen internen Moduls. Beim Top Level Modul müssen diese dann noch den Pins des FPGA im jConfig zugeordnet werden (z.B. in der .ucf-Datei des ISE-Projekts).



SpartanMC