How Network Switches Work
Every time you open a web page, packets race through network switches that parse Ethernet frames, buffer data, arbitrate between ports, and route bytes to their destination — all in hardware, billions of times per second. Here we build one from scratch.
Detecting Ethernet Frames
Raw bytes arrive on a wire, but not every byte is a packet. An Ethernet frame starts with a preamble — a sequence of 0x55 bytes — followed by a Start-of-Frame Delimiter (SFD, 0xD5). The switch must detect this pattern to know when real data begins.
This circuit implements a small finite state machine with three states: Idle (0), Waiting for SFD (1), and In Frame (2). The state is stored in a register and updated each clock tick based on what byte arrives.
Set byteIn to 85 (0x55), toggle the valid switch, and tick — the state moves to 1 (waiting). Now set byteIn to 213 (0xD5) and tick again — the state jumps to 2 and the frameLed lights up: we’re in a frame.
Buffering Incoming Packets
Once the parser detects a frame, bytes need to go somewhere. The ingress buffer stores each incoming byte in a DualPortRAM. A write pointer register tracks the next free address and increments after each write.
Port A handles writes (the ingress side), while port B lets us read back any stored byte by address — this is how the forwarder will later fetch packet data for routing.
Set dataIn to any value, toggle writeCmd, and tick. The byte is written at the current pointer address, and the pointer advances. Change readAddr to read back previously stored bytes.
Fair Arbitration
When both ports have packets buffered and ready to send, someone has to decide who goes first. The arbiter implements a round-robin policy: it remembers which port was granted last and prefers the other one next time. If only one port is ready, it gets the grant immediately.
This is a purely combinational circuit — no clock needed. The lastPort input represents the last-granted port (0 or 1). Toggle port0_ready and port1_ready to see how the portDisplay and validLed respond.
Try both ports ready with lastPort = 0: port 1 wins. Change lastPort to 1: port 0 wins. Fair and simple.
Crossbar Routing
A real switch looks at the destination MAC address to decide where to forward each packet. Our simplified 2-port switch uses a static cross-over: anything from port 0 goes to port 1, and vice versa. This is the minimal useful routing — a 2-port crossbar.
The routing logic is just a comparator and a mux. If the source port equals 0, the Mux selects 1 as the destination (and the routedLed lights up). Otherwise, it selects 0.
Change sourcePort between 0 and 1 to see the destDisplay flip to the opposite port. This is instant — pure combinational logic.
Serializing the Output
Once the forwarder copies packet data into the egress buffer, the egress controller reads it back out one byte at a time. A read pointer register steps through the RAM addresses, outputting each byte with a valid signal.
The RAM is pre-loaded with 8 bytes of test data: 0xAA, 0xBB, 0xCC, etc. Toggle the enable switch and tick repeatedly to watch the pointer advance through the data. When the pointer reaches 7, the doneLed lights up — the packet is fully serialized.
In the full switch, this same mechanism operates on each output port independently — both ports can serialize their egress buffers simultaneously.
The Full 2-Port Switch
Everything we’ve built — frame detection, packet buffering, fair arbitration, crossbar routing, and byte serialization — comes together in one circuit. The full MiniSwitch2Port has two complete data paths, each with its own parser, ingress controller, and egress controller, connected through a shared arbiter and forwarder.
Click Send Packet on either port to inject a full Ethernet frame (preamble + 8 data bytes). The circuit parses the frame, buffers it, wins arbitration, routes it across the crossbar to the opposite port, and serializes it out. Watch the activity log to follow each byte through the pipeline.
Try sending on both ports to see the arbiter alternate fairly. Use Free Run to let the switch tick continuously, or Step to advance one clock cycle at a time.
This is a simplified but structurally accurate model of how real network switches work. Production switches use wider buses, deeper buffers, and more sophisticated routing tables — but the architecture is the same: parse, buffer, arbitrate, route, serialize.
The key insight is that a switch is not a computer running networking software. It’s a circuit that performs packet forwarding in hardware. Every stage runs concurrently: while one packet is being serialized out of port 0, another can be parsed and buffered on port 1. This pipeline parallelism is why hardware switches can forward millions of packets per second — far faster than any software router.