
Learn to design a USB CDC interface in VHDL from first principles, building a complete USB device from the ground up with a FIFO-based data path and hands-on hardware practice.
Outline the course roadmap by breaking the USB CDC design into transmitter, receiver, ROM, FIFOs, and a central state machine.
Develop a 16-bit CRC generator using a linear feedback shift register based on the USB16 polynomial, append the CRC to the message, and verify at the receiver.
Learn to implement a shift register in VHDL for an FPGA USB device from first principles.
Examine the USB transmitter top-level design, coordinating shift registers, a CRC generator, and glue logic with a state machine to drive the USB data lines.
Design a VHDL USB transmitter from a timing diagram, with a generic TX message bytes (default 16), CRC options, and an in-out USB DP/DM interface.
Implement a USB transmitter in VHDL by using a four-stage ring counter to generate TP1–TP4 timing pulses, with a PKG_USB package of constants and a USB sync field.
Explain a vhdl usb transmitter that drives data plus and data minus lines using five-state usb bit type (tri-state, se0, idle, 1, 0) gated by tp4 with resettable drive process.
Generate stuff bits after six consecutive 1s by monitoring the new bit, count 1s with a three-bit counter, reset on 0, and assert the stuff bit required flag on six.
Instantiates the data shift register in the USB transmitter VHDL, rotates right with peak index 16 and prepends an 8-bit sync field to the message.
Instantiate a 16-bit crc shift register in vhdl, rotate left so msb is transmitted first, and connect it via a port map with reset, clock, and crc result ready signals.
Instantiate usb crc16 generator in the transmit path, initialize lfsr on tx message ready, and feed bits from index 16 onward (excluding pid and sync) before loading crc.
Explore transmitter design in VHDL for FPGA USB devices. Build foundational skills from first principles to implement reliable transmitters.
Explore building and simulating a VHDL transmitter test bench in ModelSim, using 2008 syntax, and analyze waveform signals, CRC generation, and USB data flow.
Explore the USB receiver architecture, including a two-stage synchronizer, diff state and single-ended zero decoding, a reset detector, a bit sampler, and RX complete signaling for framing USB data.
Describe the rx bit sampler that extracts usb data bits from the diff stream using a timing diagram, delayed dif signals, and a two-bit counter to sample mid-bit.
Create a vhdl usb rx bit sampler with usb diff inputs, two delayed diff signals, an idle and receiving state machine, and bit extraction via previous state xor and invert.
Learn to generate the internal sampling clock in VHDL and reliably capture USB data bits, including SE0 end-of-reception handling with two-stage delays and stuff-bit discard.
Explore the four USB transfer types—control, interrupt, bulk (in and out), and isochronous—covering bidirectional enumeration, host polling, data throughput limits, and the no-retry behavior of isochronous transfers.
Study how USB transfers assemble from setup packets and data nodes for control transfers. Review bulk in and bulk out flows, data one and data zero toggling, and zero-length packets.
Explain how configurations, interfaces, and endpoints define a usb device's capabilities, including endpoint 0 enumeration, one active configuration at a time, and separate in and out endpoints for data.
Populate the VHDL ROM with the 18-byte device descriptor, detailing bLength, bDescriptorType, usb 2.0 bcd, bMaxPacketSize0, cdc class, vid/pid, iManufacturer, iProduct, iSerialNumber, and bNumConfigurations.
Describe the usb configuration descriptor, including its nine-byte length and total length 0x43. Define two interfaces, configuration value 1, i configuration 0, bm attributes 0x80, and max power 0x32.
Define and populate a string descriptor ROM in VHDL, detailing string indices, product name, and serial number with ASCII encoding, offsets, and zeros for unused locations.
Explains usb pids and brequests, showing how four-bit pids become eight-bit codes and outlining common usb tokens and standard device requests for full-speed usb devices.
Design a simple FIFO in VHDL to support FPGA USB device design, guided by first principles and practical buffering concepts.
Design a transmit FIFO for a USB device on an FPGA using VHDL, guided by first principles. Implement reliable data transmission through a concise, practical FIFO architecture.
Analyze how the 64-bit shift register acts as an 8-byte buffer to split incoming data, rotate by 8 bits, and write bytes into the simple FIFO via the DIN port.
Design the top level USB module that instantiates transmitter, receiver, FIFOs, descriptor ROM, and a reset generator that supports a state machine coordinating requests on the d+ and d- lines.
Define usb top-level ports, including data plus/minus and tx/rx fifo interfaces, to enable a usb cdc device with uart configuration (baud rate, data bits, stop bits, parity) and status signals.
Stage the VHDL top-level module for a USB device by declaring usb-top-level, generating a 48 mhz clock from 25 mhz via PLL, and defining tx/rx interfaces and dp/dm lines.
Instantiate the USB transmitter and descriptor ROM in a top-level VHDL file, map clocks, reset, and USB data lines, and size tx/rx buffers based on the endpoint size.
Explore how to build a central state machine and set up the framework for a USB device design in VHDL, guiding the FPGA implementation from first principles.
Learn how the central state machine handles control output transfers, decoding B requests and executing set address and set configuration, with CDC line coding and control line state considerations.
Explain the central state machine for usb control transfers, handling set control line state and set line coding via setup requests, out/in tokens, and direction-aware waits for control data.
Terminate a control transfer through the end control transfer state, detailing termination sequences for control input and control output transfers.
Design per-endpoint data PID toggling for endpoints 0, 1, and 2, tracking separate states and toggling on each host acknowledge. Reset endpoint 0 to data 1 at new control transaction.
Implement a VHDL state machine to handle USB control transfers, decoding host requests like get descriptor and get line coding, and coordinating acknowledge and error handling.
Formulates the get line coding response for a USB control transfer. Sends UART settings (baud rate, stop bits, parity, data bits) and a 16-bit CRC within a VHDL state machine.
Implement get requests in the USB CDC state machine for configuration, interface, and status, passing the b configuration value to the transmitter as 16 bits and returning a 16-bit status.
Explain how the getDescriptor request reads USB descriptors from the FPGA, using setup data to identify descriptor type and streaming descriptors from ROM in eight-byte packets during enumeration.
Explain how the VHDL central state machine handles get descriptor requests by decoding setup data, selecting device, configuration, or string descriptors from ROM, and computing addresses and sizes.
Design and analyze the central state machine that handles get descriptor requests for a USB device implemented in VHDL on an FPGA.
Describe how the central state machine handles the usb set line coding request, configuring uart baud rate, data bits, stop bits, and parity.
Decode usb pid tokens and route data for endpoint 1 bulk data and endpoint 2 notification within a central state machine for a usb cdc interface, including uart data handling.
Instantiate and wire the transmit and receive FIFOs for endpoint 1 in the FPGA, enabling USB data transfers between the PC and downstream interfaces by replacing UART with FIFOs.
Design and implement the central state machine to transmit data from endpoint 1 via the transmit FIFO to the host PC, handle acks, zero-length packets, CRC, endpoint 2 status.
Consolidate and debug a usb vhdl state machine by tidying case statements, fixing syntax errors, renaming constants, and implementing a negative acknowledge path for unsupported requests.
Declare the usb top-level vhdl with state machine types and signals, including 28 states, descriptor ROM, setup request data, token/data PIDs, and fifo control, for fpga embedding.
Learn the top-level test bench approach for a USB VHDL device, with DUT and test bench driver to simulate a host PC and verify USB transactions, then deploy on hardware.
Develop a USB test bench in VHDL by implementing token, setup data, data out, and acknowledge packet procedures; cover PID, bmRequest, bRequest, wValue, wIndex, wLength, and unconstrained data lengths.
Build a top-level USB VHDL test bench that instantiates the device under test with a test bench driver, drives reset and a 50 MHz clock for simulating USB with ModelSim.
Test hardware with VHDL hardware test fixture that loops RX FIFO to TX FIFO, validates USB interface via enumeration, and uses a PLL to derive 48 MHz from 25 MHz.
Test and verify our USB CDC FPGA design on real hardware, using Docklight for loopback and RTS/DTR control, programming with ByteBlaster, and validating enumeration.
Master debugging of an FPGA USB device design in VHDL using signal tap to monitor internal signals and identify timing and logic issues.
Build a working USB CDC device in VHDL, understand the protocol, state machines, and data paths, and connect enumeration, descriptors, and control transfers to FPGA logic.
Add USB connectivity to your FPGA project
USB is everywhere — from keyboards to mice to embedded devices and development tools to production hardware. Yet in many FPGA projects, USB is treated as a black box, hidden behind prebuilt IP cores or software libraries.
In this course, you’ll do something different: you’ll build a working USB CDC (virtual COM port) interface entirely in VHDL, gaining a deep, practical understanding of how USB works at the hardware level — not just how to use it.
Who This Course Is For
This course is designed for engineers, students, and hobbyists who already have a basic understanding of VHDL and want to move beyond simple demonstration projects.
It’s ideal if you:
Understand basic VHDL concepts such as signals, processes, and state machines
Want to learn how real communication interfaces are implemented in hardware
Are curious about how USB works beyond libraries and vendor IP cores
Want to design FPGA systems that interact directly with a PC
Are comfortable working at the register, protocol, and timing level
This course focuses on understanding and building a USB CDC interface from first principles, not on using prebuilt blocks or high-level abstractions.
Not for you if:
You are completely new to VHDL or digital design
You are looking for a plug-and-play USB solution
You only want to use vendor-provided USB IP cores
You expect minimal HDL code or a purely software-driven approach
What You Will Learn
By the end of this course, you will be able to:
Understand USB architecture at the hardware and protocol level
Implement a USB CDC interface entirely in VHDL
Create and manage USB descriptors and handle enumeration
Design bulk IN and OUT endpoints for data transfer
Build FIFO-based data paths between USB endpoints and FPGA logic
Debug USB communication using simulation and real hardware
Why This Course Is Different
Many USB tutorials rely on vendor IP cores or software stacks — this course does not.
Instead, you’ll:
Build everything in VHDL from the ground up
Understand what each block does and why it exists
Learn to debug protocol-level issues
Take away knowledge you can reuse on other projects or platforms
The goal isn’t just to make something work — it’s to understand why it works.
Practical Outcomes
You won’t just learn theory. You will:
Build a working USB CDC device in VHDL that appears as a virtual COM port on a PC
Exchange data between a PC and FPGA using TX and RX FIFOs
Develop a solid understanding of USB device architecture
Gain a reusable USB foundation adaptable to other device classes or custom protocols
Prepare for more advanced FPGA and embedded projects
Skills You’ll Take Away
After completing this course, you’ll have:
A deep understanding of USB devices at the protocol level
Practical experience designing medium-sized VHDL systems
A solid foundation for advanced topics such as Ethernet, ADC/DAC interfacing, and system-level FPGA design
Recommended Background
Before starting this course, you should be comfortable with:
Writing and simulating simple VHDL modules
Designing simple finite state machines
Understanding clocks, resets, and synchronous logic
Using an FPGA toolchain to build and program a design
If you’ve completed an introductory VHDL course, you are well prepared for this material.
Hardware Platform (FPGA Explorer Board)
This course uses a modern FPGA development platform based on a Cyclone 10 LP device, featuring USB, SDRAM, user I/O, and other peripherals suitable for real-world projects.
All lessons, examples, and exercises have been tested on this platform, letting you follow along step by step without needing additional hardware. Focus stays on learning VHDL and system design, not on hardware workarounds.
This same platform will be used in future courses covering:
Ethernet communication
ADC and DAC interfacing
Advanced FPGA system design
Search eBay for "FPGA Explorer Board". See "FPGA_Explorer_Board.pdf" for more details.
Search eBay for "Byte Blaster Programmer". - You will need this to program the FPGA.
Ready to move beyond basic VHDL and start building real interfaces?
Join the course and take the next step in your FPGA journey.