Arty-S7-50 MultiNet
Tuesday, June 2, 2020
The prototype of my simple FPGA based SoC with multiple Ethernet interfaces worked so well that I decided to create a PCB for it and increase the number of network interfaces from two to four. It also includes a special PMOD connector for a SD-Card to boot a firmware or Linux from. Also two of the Arty’s four existing PMODs are also still available for extensions. PMOD-C and PMOD-D are no longer available as their pins are used for some of the Ethernet PHY modules.
Due to I/O limitations the Seven Segment Display was removed from the original design.
The picture shows an assembled PCB on the Arty-S7-50. One PHY module still missing as I only have three modules at the moment.
The final schematic uses almost all available digital I/Os on the Arty-S7-50.
R1-R4 set the MDIO control address of the module. The first module has the default address 1, the next 3, 5 and the last has the address 7. When you boot into the LiteX BIOS the command ‘mdiod’ can be used to communicate and inspect the MDIO registers of a PHY. For example the command
litex> mdiod 3 2 MDIO dump @0x3: reg 0: 0x3100reg 1: 0x7869
dumps the first two addresses of the PHY with MDIO address 3 (which are the Basic Mode Control and Status registers - BMCR, BMSR). The status register for example shows the speed and if a link is present or not. An easy check to see if things are working is to inspect a PHYs status register and see if a link is present (a cable is connected) or not. This is indicated with bit 2 of the BMSR. A detailed description of all the registeres can be found in the datasheet.
In terms of software bare metal firmware access to the PHYs works. Linux (based on the Linux on the VexRiscV project) boots (from SD-Card or via TFTP netboot) but has problems accessing the network interfaces at the moment. Next steps would be to get Linux fully running.
litex> netboot Booting from network... Local IP : 10.0.0.50 Remote IP: 10.0.0.100 Fetching from: UDP/69 Downloaded 5336652 bytes from Image over TFTP to 0x40000000 Downloaded 4064768 bytes from rootfs.cpio over TFTP to 0x40800000 Downloaded 2852 bytes from rv32.dtb over TFTP to 0x41000000 Downloaded 9588 bytes from emulator.bin over TFTP to 0x41100000 Executing booted program at 0x41100000 --============= Liftoff! ===============-- VexRiscv Machine Mode software built May 30 2020 20:44:18 --========== Booting Linux =============-- [ 0.000000] No DTB passed to the kernel [ 0.000000] Linux version 5.0.13 (prinz@BigBang) (gcc version 8.4.0 (Buildroot 2020.05-rc1-00086-gaa13c9667c)) #1 Tue May 19 14:50:23 CEST 2020 [ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '') [ 0.000000] printk: bootconsole [sbi0] enabled [ 0.000000] Initial ramdisk at: 0x(ptrval) (8388608 bytes) [ 0.000000] Zone ranges: [ 0.000000] Normal [mem 0x0000000040000000-0x000000004fffffff] [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x0000000040000000-0x000000004fffffff] [ 0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000004fffffff] [ 0.000000] elf_hwcap is 0x1101 [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 65024 [ 0.000000] Kernel command line: mem=256M@0x40000000 rootwait console=liteuart earlycon=sbi root=/dev/ram0 init=/sbin/init swiotlb=32 [ 0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes) [ 0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes) [ 0.000000] Sorting __ex_table... [ 0.000000] Memory: 246452K/262144K available (4001K kernel code, 153K rwdata, 685K rodata, 148K init, 216K bss, 15692K reserved, 0K cma-reserved) [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 [ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0 [ 0.000000] irqchip: LiteX VexRiscv irqchip driver initialized. IE: 0, mask: 0x00000000, pending: 0x00000000 [ 0.000000] irqchip: LiteX VexRiscv irqchip settings: mask CSR 0x9c0, pending CSR 0xdc0 [ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x171024e7e0, max_idle_ns: 440795205315 ns [ 0.000215] sched_clock: 64 bits at 100MHz, resolution 10ns, wraps every 4398046511100ns [ 0.009390] Console: colour dummy device 80x25 [ 0.013298] Calibrating delay loop (skipped), value calculated using timer frequency.. 200.00 BogoMIPS (lpj=400000) [ 0.023218] pid_max: default: 32768 minimum: 301 [ 0.034333] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 0.040213] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 0.084646] devtmpfs: initialized [ 0.120577] random: get_random_bytes called from setup_net+0x4c/0x188 with crng_init=0 [ 0.131341] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns [ 0.140608] futex hash table entries: 256 (order: -1, 3072 bytes) [ 0.152974] NET: Registered protocol family 16 [ 0.318919] FPGA manager framework [ 0.335125] clocksource: Switched to clocksource riscv_clocksource [ 0.551670] NET: Registered protocol family 2 [ 0.565768] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes) [ 0.573047] TCP established hash table entries: 2048 (order: 1, 8192 bytes) [ 0.580088] TCP bind hash table entries: 2048 (order: 1, 8192 bytes) [ 0.585967] TCP: Hash tables configured (established 2048 bind 2048) [ 0.593862] UDP hash table entries: 256 (order: 0, 4096 bytes) [ 0.599082] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) [ 0.616278] Unpacking initramfs... [ 1.762329] Initramfs unpacking failed: junk in compressed archive [ 1.782066] workingset: timestamp_bits=30 max_order=16 bucket_order=0 [ 2.162628] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253) [ 2.169261] io scheduler mq-deadline registered [ 2.173625] io scheduler kyber registered [ 2.189828] LiteX SoC Controller driver initialized [ 3.494298] f0002000.serial: ttyLXU0 at MMIO 0xf0002000 (irq = 0, base_baud = 0) is a liteuart [ 3.507492] printk: console [liteuart0] enabled [ 3.507492] printk: console [liteuart0] enabled [ 3.515871] printk: bootconsole [sbi0] disabled [ 3.515871] printk: bootconsole [sbi0] disabled [ 3.550673] libphy: Fixed MDIO Bus: probed [ 3.555719] liteeth f0008000.mac: Failed to get IRQ, using polling [ 3.573997] liteeth f0008000.mac eth0: irq 0, mapped at a0004000 [ 3.581169] liteeth f0009000.mac: Failed to get IRQ, using polling [ 3.600128] liteeth f0009000.mac eth1: irq 0, mapped at a000b000 [ 3.607036] liteeth f000a000.mac: Failed to get IRQ, using polling [ 3.625874] liteeth f000a000.mac eth2: irq 0, mapped at a0013000 [ 3.635853] i2c /dev entries driver [ 3.689662] NET: Registered protocol family 10 [ 3.716595] Segment Routing with IPv6 [ 3.720653] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver [ 3.787657] Freeing unused kernel memory: 148K [ 3.790865] This architecture does not have kernel memory protection. [ 3.797877] Run /init as init process mount: mounting tmpfs on /dev/shm failed: Invalid argument mount: mounting tmpfs on /tmp failed: Invalid argument mount: mounting tmpfs on /run failed: Invalid argument Starting syslogd: OK Starting klogd: OK Running sysctl: OK Saving random seed: [ 6.156401] random: dd: uninitialized urandom read (512 bytes read) OK Starting network: OK Welcome to Buildroot buildroot login: root __ _ / / (_)__ __ ____ __ / /__/ / _ \/ // /\ \ / /____/_/_//_/\_,_//_\_\ / _ \/ _ \ __ _ __ _\___/_//_/ __ ___ _ / / (_) /____ | |/_/__| | / /____ __ / _ \(_)__ _____ __ / /__/ / __/ -_)> </___/ |/ / -_) \ // , _/ (_-</ __/ |/ / /____/_/\__/\__/_/|_| |___/\__/_\_\/_/|_/_/___/\__/|___/ 32-bit VexRiscv CPU with MMU integrated in a LiteX SoC login[75]: root login on 'console' root@buildroot:~# uname -a Linux buildroot 5.0.13 #1 Tue May 19 14:50:23 CEST 2020 riscv32 GNU/Linux root@buildroot:~#
All in all the project is quite useful even it this early stages. Having a simple platform, mainly for networking experiments, which makes it possible to change everything, from CPU type (select the type you want thanks to LiteX), implementing critical parts directly as co-design in FPGA, running bare metal applications up to booting an OS of your choice (Linux, ZephyrOS) is really useful. And all this without spending a fortune. The WaveShare modules for example only cost ~7,00 EUR.
The latest version of the project is available on github.