openFPGALoader -b arty boards/Arty_A7-35/a35_fnet/a35_fnet.bitTo write the gateware to flash storage (used after reset / powercycling), add the flag
-f
. If openFPGALoader is just locally installed, the path to the SPI writing gateware is also needed:
OPENFPGALOADER_SOJ_DIR=<path-to-openFPGALoader>/spiOverJtag/ openFPGALoader -b arty boards/Arty_A7-35/a35_fnet/a35_fnet.bit -f
The Arty A7 board LEDs show some basic operation of Fakernet:
LD7 | LD6 | LD5 | LD4 | |
---|---|---|---|---|
Green | GPS PPS (only useful with Pmod GPS). |
GPS UART RX (only useful with Pmod GPS). |
Incoming packet count (low two bits). |
|
LD3 | LD2 | LD1 | LD0 | |
Red | Output ARP/ICMP/NTP. | Good NTP in. | Good ICMP in (ping). |
Good ARP in. |
Green | Output TCP. | Good TCP in. | Output UDP (register access). |
Good UDP in (register access). |
Blue | GPS PPS (only useful with Pmod GPS). |
Output of generated RARP/BOOTP/ NTP-query. |
Good RARP in. | Good BOOTP in. |
With 'good' is meant an incoming packet which passes all checks, and is intended for us, i.e. has the MAC and/or IP address of the Fakernet instance. The incoming packet count registers all packet starts from the PHY, i.e. regardless of destination or content.
The Arty A7 onboard USB-UART (serial) connection also emits single characters to mark the occurrence of some events which can be useful for debugging:
_
(underscore), every timeout tick, here
approximately 1.3 s. If this does not appear regularly, then
the serial connection is not working.a
Good ARP in.
i
Good ICMP in.
n
Good NTP in.
u
Good UDP (register access) in.
t
Good TCP in.
r
Good RARP in.
b
Good BOOTP in.
A
Output ARP/ICMP/NTP.
U
Output UDP (register access).
T
Output TCP.
The UART interface is available on the second port of the
onboard USB-UART interface, i.e. typically accessible via
/dev/ttyUSB1
on the PC (when no other USB serial
devices are attached). (The first is used to load gatewares.)
A good program for connecting
is kermit (often
found as packet ckermit).
kermit C-Kermit>set line /dev/ttyUSB1 C-Kermit>set carrier-watch off C-Kermit>set flow-control none C-Kermit>set speed 921600 /dev/ttyUSB1, 921600 bps C-Kermit>connect _PP____PP____PP____PP____PP_
To use the serial information for debugging, it should be left
running in a terminal while performing other tests that generate
traffic. The P
marks above would come when
Fakernet issues RARP and BOOTP request packets to configure a
dynamic IP address. After starting a process pinging the board,
it may look like this:
_aAiA_PPiA_iA_iAiA_iA_PPiA_iAiA_iA_iA_iAPPiA_iA_iA_iAiA_PPiA
The a
comes from the ARP query broadcast by the PC
to find the MAC address for the given IP
number. The following A
is the Fakernet response.
Each i
is then an ICMP echo request packet, with a
following A
marking the response. (Note:
the a
and i
will only be seen if the
ARP and ICMP requests are for the correct IP address. Without
an ARP response, the PC will not send any ICMP requests.)
By default Fakernet on the Arty board has a fixed IP address 192.168.1.192 (or .193, .194, or .195 set by SW0-SW1).
Ping (ICMP echo request and reply)
ping 192.168.1.192 PING 192.168.1.192 (192.168.1.192) 56(84) bytes of data. 64 bytes from 192.168.1.192: icmp_seq=1 ttl=63 time=0.134 ms 64 bytes from 192.168.1.192: icmp_seq=2 ttl=63 time=0.127 ms
TCP connection (the fnetctrl
program is part of the Fakernet source distribution):
client/fnetctrl 192.168.1.192 --tcp read: 59085454180352 (59085454.2 MB) 11788.1 kB/s [slow avg 11787.3 kB/s] read: 127195601436672 (127195601.4 MB) 11785.0 kB/s [slow avg 11785.7 kB/s]
UDP debug counters:
client/fnetctrl 192.168.1.192 --stat ... UDP: connected 00, active 00 Compiled: 2020-03-29 17:09:52 UTC TCP: connected Total counts: 25020628 (100.001 MHz +/- 0.062) Slow ticks: 781894 (32) (1.28 us) tcp_stat.base_seqno 0x96125884 = 2517784708 ; 11797440 tcp_stat.max_sent 0x 6824 = 26660 tcp_stat.filled 0x 1440 = 5184 tcp_stat.unsent 0x 4a0 = 1184 tcp_stat.unfilled 0x bc0 = 3008 tcp_stat.window_sz 0x fe00 = 65024 tcp_stat.rtt_trip 0x 5884 = 22660 tcp_astat.cur_off 0x fa0 = 4000 tcp_stat.same_ack 0x 0 = 0 tcp_stat.rtt_est 0x 137 = 311 = 398.1 us [ 0] idle_cnt 543097957 ; 23981922 [26] slow_tick 157647553 ; 781894 [27] timeout_tick 151 ; 1 [58] in_words_div_32 879305 ; 4591 bytes 56275520 ; 293824 [ 1] +-in_info.start_packet 877861 ; 4579 [ 3] | `-in_info.start_arp 22 ; 0 [ 4] | in_info.arp_our_ip 0 ; 0 [ 8] | in_info.good_arp 0 ; 0 [ 2] `-in_info.mac_for_us 877642 ; 4578 [ 5] in_info.start_ipv4 877644 ; 4578 [ 6] in_info.ip_hdr_ok 877716 ; 4578 [ 7] in_info.ip_for_us 877642 ; 4578 [ 9] +-in_info.start_icmp 0 ; 0 [12] | in_info.good_icmp 0 ; 0 [10] +-in_info.start_udp 93 ; 1 [15] | in_info.udp_arm 1 ; 0 [16] | in_info.udp_badactivearm 0 ; 0 [17] | in_info.udp_reset 1 ; 0 [18] | in_info.udp_badreset 0 ; 0 [19] | in_info.udp_disconnect 1 ; 0 [20] | in_info.udp_baddisconnect 0 ; 0 [21] | in_info.udp_regaccess 1 ; 0 [22] | +-in_info.udp_ra_otherip 1 ; 0 [23] | +-in_info.udp_ra_seqplus1 1 ; 0 [24] | +-in_info.udp_ra_repeat 0 ; 0 [25] | `-in_info.udp_ra_busy 0 ; 0 [60] | in_info.udp_regaccess_idp 89 ; 1 [61] | `-in_info.udp_ra_idp_busy 0 ; 0 [13] | in_info.good_udp 93 ; 1 [11] `-in_info.start_tcp 877549 ; 4577 [14] in_info.good_tcp 877542 ; 4577 [59] out_words_div_32 36713731 ; 192620 bytes 2349678784 ; 12327680 [44] out_info.packets 1746053 ; 9131 [33] +-out_info.arp_icmp 3 ; 0 [62] +-out_info.udp_idp 88 ; 1 [34] +-out_info.udp[0] 1 ; 0 [35] +-out_info.udp[1] 0 ; 0 [36] +-out_info.udp[2] 0 ; 0 [37] +-out_info.udp[3] 0 ; 0 [43] +-out_info.tcp 1745961 ; 9130 [55] tcp_state.got_syn 1 ; 0 [54] tcp_state.connected 1 ; 0 [49] tcp_state.got_ack 877539 ; 4577 [51] +-tcp_state.same_ack 26 ; 0 [52] +-tcp_state.twice_same_ack 0 ; 0 [48] tcp_state.did_repeat 25 ; 0 [53] tcp_state.abort_repeat 0 ; 0 [57] tcp_state.did_keepalive 0 ; 0 [47] +-tcp_state.start_meas_rtt 437369 ; 2285 [50] +-tcp_state.got_meas_rtt 437345 ; 2285 [56] +-tcp_state.new_rtt_est 27335 ; 143
UDP requests (100 register accesses / packet):
client/fnetctrl 192.168.1.192 --udp-flood=100 packets: 0, incr: 0 (0/s ; inf us/pkt) 0.00 MB/s, (to: 0, mf: 0, to_us: 36) packets: 38189, incr: 38189 (4022/s ; 248.6 us/pkt) 1.61 MB/s, (to: 0, mf: 0, to_us: 794) packets: 78375, incr: 40186 (4019/s ; 248.8 us/pkt) 1.61 MB/s, (to: 0, mf: 0, to_us: 874) packets: 118619, incr: 40244 (4024/s ; 248.5 us/pkt) 1.61 MB/s, (to: 0, mf: 0, to_us: 874) packets: 158932, incr: 40313 (4031/s ; 248.1 us/pkt) 1.61 MB/s, (to: 0, mf: 0, to_us: 838) packets: 199258, incr: 40326 (4033/s ; 248.0 us/pkt) 1.61 MB/s, (to: 0, mf: 0, to_us: 820) packets: 239573, incr: 40315 (4032/s ; 248.0 us/pkt) 1.61 MB/s, (to: 0, mf: 0, to_us: 820) packets: 279899, incr: 40326 (4033/s ; 248.0 us/pkt) 1.61 MB/s, (to: 0, mf: 0, to_us: 865) packets: 320314, incr: 40415 (4042/s ; 247.4 us/pkt) 1.62 MB/s, (to: 0, mf: 0, to_us: 839)
Generate TCP data with test pattern, verify on PC:
client/fnetctrl 192.168.1.192 --tcp-lcl-datagen=1 client/fnetctrl 192.168.1.192 --tcp-lcl-data-chance=100000000 client/fnetctrl 192.168.1.192 --tcp-lcl-data-valmask=8191 client/fnetctrl 192.168.1.192 --tcp=local
(or for simpler copy-paste:)
FNETIP=192.168.1.192 ; \ client/fnetctrl $FNETIP --tcp-lcl-datagen=1 ; \ client/fnetctrl $FNETIP --tcp-lcl-data-chance=100000000 ; \ client/fnetctrl $FNETIP --tcp-lcl-data-valmask=8191 ; \ client/fnetctrl $FNETIP --tcp=local
Read and decode some MDIO information:
client/fnetctrl 192.168.1.192 --mdio=1 PHY: OUI 08:00:17 v/model: 09 rev: 0 autoneg: on 100baseT/F ability: 100baseT/F 100baseT/H 10baseT/F 10baseT/H advertise: 100baseT/F 100baseT/H 10baseT/F 10baseT/H lp-advertise: 100baseT/F 100baseT/H 10baseT/F 10baseT/H
Only advertise 10baseT, and run TCP test:
(Note: it can take half a minute to complete auto-negotiation.)
client/fnetctrl 192.168.1.192 --mdio=1,adv10 client/fnetctrl 192.168.1.192 --mdio=1,autoneg_restart autoneg: on 10baseT/F client/fnetctrl 192.168.1.192 --tcp read: 10497600 (10.5 MB) 1184.8 kB/s [slow avg 1055.0 kB/s] mark:ffffffff
Disable auto-negotiation and disable duplex, and run TCP test:
client/fnetctrl 192.168.1.192 --mdio=1,autoneg_off client/fnetctrl 192.168.1.192 --mdio=1,-fixduplex autoneg: off 100baseT/H client/fnetctrl 192.168.1.192 --tcp read: 55731040 (55.7 MB) 9286.8 kB/s [slow avg 7208.4 kB/s] mark:ffffffff
Advertise all modes, enable and restart auto-negotiation, and run TCP test:
client/fnetctrl 192.168.1.192 --mdio=1,adv10/100 client/fnetctrl 192.168.1.192 --mdio=1,autoneg_restart autoneg: on 100baseT/F client/fnetctrl 192.168.1.192 --tcp read: 106576256 (106.6 MB) 11857.1 kB/s [slow avg 10602.7 kB/s] mark:ffffffff
By default Fakernet has a fixed IP address configured in the gateware. For the Arty board demo, this is 192.168.1.192 (or .193, .194, or .195 set by SW0-SW1).
Fakernet can also obtain a dynamic IP address by RARP, DHCP (or BOOTP). (BOOTP is normally disabled..)
The Arty A7 board does not have any way of retrieving the MAC address assigned by the manufacturer and printed on a label on the RJ45 8P8C connector. Therefore, the Arty A7 demo of Fakernet uses the DNA port of the Artix 7 FPGA. The DNA identifier is however not an EUI-48, and it is also not necessarily unique (may be same on 32 devices), so using it as a MAC address, which must be unique in a broadcast-domain, is at best a hack! The MAC address is taken as:
47..42 | 41..40 | 39..4 | 3..2 | 0..1 |
---|---|---|---|---|
DNA bits 41..36, | Fixed 10 (locally administered and unicast), |
DNA bits 35..0, | 00, | SW1, SW0. |
Some settings can be stored as text block in SPI flash, at an address offset beyond the gateware bitstream. The configuration options are parsed by the gateware at startup.
An easy way to write the settings is to create a file with the desired content an write to flash storage using openFPGALoader:
openFPGALoader -b arty -o 0x3c0000 my_arty_config.txt
If the gateware is also stored in flash, it does not need to be updated. The FPGA is restarted by openFPGALoader after the write and the gateware stored in flash is automatically loaded.
To read the configuration:
openFPGALoader -b arty -o 0x3c0000 --dump-flash --file-size 0x400 tmp_read_config.txt cat tmp_read_config.txt | sed -e "s/\(\xff\|\x00\)/\r/g"
Available configuration options:
fixed_ip = aaa.bbb.ccc.ddd # Fixed IP address (switch-configured address disabled). mac = aa:bb:cc:dd:ee:ff # MAC address (DNA-based hack not used).
NTP server with a Arty A7-35 board and GPS.
0.5 ns signal sampler with a Arty A7-35 board.
1 Gbps operation with a ALINX AX7101 board.
Last modified: Thu Jun 12 18:30:53 CEST 2021