nic_wishbone_slave
White Rabbit Switch NIC's spec
This NIC is in between the endpoints and the on-board Linux CPU of the White Rabbit Switch.
Operation
~~~~~~~
* There's a pool of n TX descriptors and a pool of n RX descriptors.
* In fact, we should have n for TX and m for RX since 32K / 1536 = 21.3. Anyway, to make things simple, first let's do n and n; we can fine-tune later on.
* Software keeps track of which buffers are marked to be used with the READY/EMPTY flags.
* Interrupts are useed by software to update the state, e.g. when frames are received or when a frame has been sent.
* Endianness: all multi-byte registers are Little Endian
Frame transmission
~~~~~~~~~~~~~~~
* Enable Transmission in the Control Register
* Store the frame in memory
* Fill in the corresponding descriptor from the TX pool
* Set READY bit to 1
* Interrupt arrives--if enabled-- and software updates stats reading the descriptor (READY has been set to 0 by the NIC).
Frame reception
~~~~~~~~~~~~~
* Enable Reception in the Control Register
* Initialize a descriptor from the RX descriptors pool. Mark it as EMPTY
* A frame is received and, if enabled, the NIC raises an interrupt
* With EMPTY set to 0, the frame can now be copied from the NIC's memory and stats can be updated
* Set READY bit to 1
Todo
~~~~
* Descriptors in RAM, not as registers. wbgen2 doesn't support this yet. Working on it.
Known issues
~~~~~~~~~~~
* Only 32-bit aligned addresses are supported
Contents:
1. Memory map summary
2. HDL symbol
3. Register description
3.1. NIC Control Register
3.2. NIC Status Register
3.3. SW_Reset
3.4. Interrupt disable register
3.5. Interrupt enable register
3.6. Interrupt mask register
3.7. Interrupt status register
4. Memory blocks
4.1. TX descriptors mem
4.2. RX descriptors mem
5. Interrupts
5.1. Receive Complete
5.2. Transmit Complete
5.3. Transmit Error
→
|
rst_n_i
|
|
NIC Control Register:
|
|
→
|
wb_clk_i
|
|
nic_cr_rx_en_o
|
→
|
⇒
|
wb_addr_i[6:0]
|
|
nic_cr_tx_en_o
|
→
|
⇒
|
wb_data_i[31:0]
|
|
|
|
⇐
|
wb_data_o[31:0]
|
|
NIC Status Register:
|
|
→
|
wb_cyc_i
|
|
nic_sr_bna_i
|
←
|
⇒
|
wb_sel_i[3:0]
|
|
nic_sr_rec_o
|
→
|
→
|
wb_stb_i
|
|
nic_sr_rec_i
|
←
|
→
|
wb_we_i
|
|
nic_sr_rec_load_o
|
→
|
←
|
wb_ack_o
|
|
nic_sr_tx_done_o
|
→
|
←
|
wb_irq_o
|
|
nic_sr_tx_done_i
|
←
|
|
|
|
nic_sr_tx_done_load_o
|
→
|
|
|
|
nic_sr_tx_error_o
|
→
|
|
|
|
nic_sr_tx_error_i
|
←
|
|
|
|
nic_sr_tx_error_load_o
|
→
|
|
|
|
nic_sr_cur_tx_desc_i[2:0]
|
⇐
|
|
|
|
nic_sr_cur_rx_desc_i[2:0]
|
⇐
|
|
|
|
|
|
|
|
|
SW_Reset:
|
|
|
|
|
nic_reset_o[31:0]
|
⇒
|
|
|
|
nic_reset_wr_o
|
→
|
|
|
|
|
|
|
|
|
Receive Complete:
|
|
|
|
|
irq_rcomp_i
|
←
|
|
|
|
irq_rcomp_ack_o
|
→
|
|
|
|
|
|
|
|
|
Transmit Complete:
|
|
|
|
|
irq_tcomp_i
|
←
|
|
|
|
irq_tcomp_ack_o
|
→
|
|
|
|
irq_tcomp_mask_o
|
→
|
|
|
|
|
|
|
|
|
Transmit Error:
|
|
|
|
|
irq_txerr_i
|
←
|
|
|
|
irq_txerr_ack_o
|
→
|
|
|
|
irq_txerr_mask_o
|
→
|
|
|
|
|
|
|
|
|
TX descriptors mem:
|
|
|
|
|
nic_dtx_addr_i[4:0]
|
⇐
|
|
|
|
nic_dtx_data_o[31:0]
|
⇒
|
|
|
|
nic_dtx_rd_i
|
←
|
|
|
|
nic_dtx_data_i[31:0]
|
⇐
|
|
|
|
nic_dtx_wr_i
|
←
|
|
|
|
|
|
|
|
|
RX descriptors mem:
|
|
|
|
|
nic_drx_addr_i[4:0]
|
⇐
|
|
|
|
nic_drx_data_o[31:0]
|
⇒
|
|
|
|
nic_drx_rd_i
|
←
|
|
|
|
nic_drx_data_i[31:0]
|
⇐
|
|
|
|
nic_drx_wr_i
|
←
|
HW prefix:
|
nic_cr
|
HW address:
|
0x0
|
C prefix:
|
CR
|
C offset:
|
0x0
|
31
|
30
|
29
|
28
|
27
|
26
|
25
|
24
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
23
|
22
|
21
|
20
|
19
|
18
|
17
|
16
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
15
|
14
|
13
|
12
|
11
|
10
|
9
|
8
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
-
|
-
|
-
|
-
|
-
|
-
|
TX_EN
|
RX_EN
|
-
RX_EN
[read/write]: Receive enable
Enables the NIC to receive data
-
TX_EN
[read/write]: Transmit enable
Enables the NIC to transmit data. When reset, the internal transmit pointer points to the first entry in the TX descriptor pool
HW prefix:
|
nic_sr
|
HW address:
|
0x1
|
C prefix:
|
SR
|
C offset:
|
0x4
|
31
|
30
|
29
|
28
|
27
|
26
|
25
|
24
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
23
|
22
|
21
|
20
|
19
|
18
|
17
|
16
|
-
|
-
|
-
|
-
|
-
|
CUR_RX_DESC[2:0]
|
|
|
15
|
14
|
13
|
12
|
11
|
10
|
9
|
8
|
-
|
-
|
-
|
-
|
-
|
CUR_TX_DESC[2:0]
|
|
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
-
|
-
|
-
|
-
|
TX_ERROR
|
TX_DONE
|
REC
|
BNA
|
-
BNA
[read-only]: Buffer Not Available
No buffers were available when receiving a packet.
-
REC
[read/write]: Frame Received
One or more frames have been received.
Cleared by writing a one to this bit
-
TX_DONE
[read/write]: Transmission done
read 1: All non-empty TX descriptors have been transmitted
read 0: Transmission in progress
write 1: Clears the flag
write 0: No effect
-
TX_ERROR
[read/write]: Transmission error
read 1: A TX error occured and the transmission was stopped. CUR_TX_DESC is pointing the TX descriptor for which the error occured
read 0: No TX error
write 1: Clears the flag
write 0: No effect
-
CUR_TX_DESC
[read-only]: Current TX descriptor
Index of the currently handled TX descriptor
-
CUR_RX_DESC
[read-only]: Current RX descriptor
Index of the currently handled RX descriptor
HW prefix:
|
nic_reset
|
HW address:
|
0x2
|
C prefix:
|
RESET
|
C offset:
|
0x8
|
Writing to this register resets the NIC, zeroing all registers and resetting the state of the module
31
|
30
|
29
|
28
|
27
|
26
|
25
|
24
|
RESET[31:24]
|
|
|
|
|
|
|
|
23
|
22
|
21
|
20
|
19
|
18
|
17
|
16
|
RESET[23:16]
|
|
|
|
|
|
|
|
15
|
14
|
13
|
12
|
11
|
10
|
9
|
8
|
RESET[15:8]
|
|
|
|
|
|
|
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
RESET[7:0]
|
|
|
|
|
|
|
|
-
RESET
[write-only]: Software reset
HW prefix:
|
nic_eic_idr
|
HW address:
|
0x8
|
C prefix:
|
EIC_IDR
|
C offset:
|
0x20
|
Writing 1 disables handling of the interrupt associated with corresponding bit. Writin 0 has no effect.
31
|
30
|
29
|
28
|
27
|
26
|
25
|
24
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
23
|
22
|
21
|
20
|
19
|
18
|
17
|
16
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
15
|
14
|
13
|
12
|
11
|
10
|
9
|
8
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
-
|
-
|
-
|
-
|
-
|
TXERR
|
TCOMP
|
RCOMP
|
-
RCOMP
[write-only]: Receive Complete
write 1: disable interrupt 'Receive Complete'
write 0: no effect
-
TCOMP
[write-only]: Transmit Complete
write 1: disable interrupt 'Transmit Complete'
write 0: no effect
-
TXERR
[write-only]: Transmit Error
write 1: disable interrupt 'Transmit Error'
write 0: no effect
HW prefix:
|
nic_eic_ier
|
HW address:
|
0x9
|
C prefix:
|
EIC_IER
|
C offset:
|
0x24
|
Writing 1 enables handling of the interrupt associated with corresponding bit. Writin 0 has no effect.
31
|
30
|
29
|
28
|
27
|
26
|
25
|
24
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
23
|
22
|
21
|
20
|
19
|
18
|
17
|
16
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
15
|
14
|
13
|
12
|
11
|
10
|
9
|
8
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
-
|
-
|
-
|
-
|
-
|
TXERR
|
TCOMP
|
RCOMP
|
-
RCOMP
[write-only]: Receive Complete
write 1: enable interrupt 'Receive Complete'
write 0: no effect
-
TCOMP
[write-only]: Transmit Complete
write 1: enable interrupt 'Transmit Complete'
write 0: no effect
-
TXERR
[write-only]: Transmit Error
write 1: enable interrupt 'Transmit Error'
write 0: no effect
HW prefix:
|
nic_eic_imr
|
HW address:
|
0xa
|
C prefix:
|
EIC_IMR
|
C offset:
|
0x28
|
Shows which interrupts are enabled. 1 means that the interrupt associated with the bitfield is enabled
31
|
30
|
29
|
28
|
27
|
26
|
25
|
24
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
23
|
22
|
21
|
20
|
19
|
18
|
17
|
16
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
15
|
14
|
13
|
12
|
11
|
10
|
9
|
8
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
-
|
-
|
-
|
-
|
-
|
TXERR
|
TCOMP
|
RCOMP
|
-
RCOMP
[read-only]: Receive Complete
read 1: interrupt 'Receive Complete' is enabled
read 0: interrupt 'Receive Complete' is disabled
-
TCOMP
[read-only]: Transmit Complete
read 1: interrupt 'Transmit Complete' is enabled
read 0: interrupt 'Transmit Complete' is disabled
-
TXERR
[read-only]: Transmit Error
read 1: interrupt 'Transmit Error' is enabled
read 0: interrupt 'Transmit Error' is disabled
HW prefix:
|
nic_eic_isr
|
HW address:
|
0xb
|
C prefix:
|
EIC_ISR
|
C offset:
|
0x2c
|
Each bit represents the state of corresponding interrupt. 1 means the interrupt is pending. Writing 1 to a bit clears the corresponding interrupt. Writing 0 has no effect.
31
|
30
|
29
|
28
|
27
|
26
|
25
|
24
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
23
|
22
|
21
|
20
|
19
|
18
|
17
|
16
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
15
|
14
|
13
|
12
|
11
|
10
|
9
|
8
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
-
|
-
|
-
|
-
|
-
|
TXERR
|
TCOMP
|
RCOMP
|
-
RCOMP
[read/write]: Receive Complete
read 1: interrupt 'Receive Complete' is pending
read 0: interrupt not pending
write 1: clear interrupt 'Receive Complete'
write 0: no effect
-
TCOMP
[read/write]: Transmit Complete
read 1: interrupt 'Transmit Complete' is pending
read 0: interrupt not pending
write 1: clear interrupt 'Transmit Complete'
write 0: no effect
-
TXERR
[read/write]: Transmit Error
read 1: interrupt 'Transmit Error' is pending
read 0: interrupt not pending
write 1: clear interrupt 'Transmit Error'
write 0: no effect
HW prefix:
|
nic_dtx
|
HW address:
|
0x20
|
C prefix:
|
DTX
|
C offset:
|
0x80
|
Size:
|
32 32-bit words
|
Data width:
|
32
|
Access (bus):
|
read/write
|
Access (device):
|
read/write
|
Mirrored:
|
no
|
Byte-addressable:
|
no
|
Peripheral port:
|
bus-synchronous
|
⇒
|
nic_dtx_addr_i[4:0]
|
|
nic_dtx_data_o[31:0]
|
⇒
|
→
|
nic_dtx_rd_i
|
|
|
|
⇒
|
nic_dtx_data_i[31:0]
|
|
|
|
→
|
nic_dtx_wr_i
|
|
|
|
HW prefix:
|
nic_drx
|
HW address:
|
0x40
|
C prefix:
|
DRX
|
C offset:
|
0x100
|
Size:
|
32 32-bit words
|
Data width:
|
32
|
Access (bus):
|
read/write
|
Access (device):
|
read/write
|
Mirrored:
|
no
|
Byte-addressable:
|
no
|
Peripheral port:
|
bus-synchronous
|
⇒
|
nic_drx_addr_i[4:0]
|
|
nic_drx_data_o[31:0]
|
⇒
|
→
|
nic_drx_rd_i
|
|
|
|
⇒
|
nic_drx_data_i[31:0]
|
|
|
|
→
|
nic_drx_wr_i
|
|
|
|
HW prefix:
|
nic_rcomp
|
C prefix:
|
RCOMP
|
Trigger:
|
high level
|
A frame has been stored in memory.
HW prefix:
|
nic_tcomp
|
C prefix:
|
TCOMP
|
Trigger:
|
high level
|
Frame successfully transmitted
HW prefix:
|
nic_txerr
|
C prefix:
|
TXERR
|
Trigger:
|
high level
|