{"id":13649302,"url":"https://github.com/ulixxe/usb_cdc","last_synced_at":"2025-04-22T14:31:19.491Z","repository":{"id":38006085,"uuid":"375122072","full_name":"ulixxe/usb_cdc","owner":"ulixxe","description":"Single/Multi-channel Full Speed USB interface for FPGA and ASIC designs","archived":false,"fork":false,"pushed_at":"2024-03-10T19:11:48.000Z","size":7405,"stargazers_count":147,"open_issues_count":0,"forks_count":10,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-05-18T20:26:55.053Z","etag":null,"topics":["asic","bootloader","cdc-acm","fomu","fpga","serial","tinyfpga-bx","usb","usb-cdc","usb-device","verilog"],"latest_commit_sha":null,"homepage":"","language":"Verilog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ulixxe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-08T19:26:17.000Z","updated_at":"2024-06-14T23:57:09.428Z","dependencies_parsed_at":"2024-06-14T23:57:09.031Z","dependency_job_id":"823b7471-5bfe-47cd-b1fa-b6b94e43b77b","html_url":"https://github.com/ulixxe/usb_cdc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulixxe%2Fusb_cdc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulixxe%2Fusb_cdc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulixxe%2Fusb_cdc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulixxe%2Fusb_cdc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ulixxe","download_url":"https://codeload.github.com/ulixxe/usb_cdc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250258931,"owners_count":21401000,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asic","bootloader","cdc-acm","fomu","fpga","serial","tinyfpga-bx","usb","usb-cdc","usb-device","verilog"],"created_at":"2024-08-02T01:04:56.128Z","updated_at":"2025-04-22T14:31:14.482Z","avatar_url":"https://github.com/ulixxe.png","language":"Verilog","funding_links":[],"categories":["Verilog","Digital Interfaces"],"sub_categories":["SerDes","Sensors"],"readme":"# USB\\_CDC verilog module\n\nUSB\\_CDC is a Verilog implementation of the Full Speed (12Mbit/s) USB communications device class (or USB CDC class). It implements the Abstract Control Model (ACM) subclass.\n\nUSB\\_CDC can be configured through CHANNELS parameter to implement from 1 to a maximum of 7 CDC channels.\n\nWindows 10 provides a built-in driver (Usbser.sys) for USB CDC devices.\nA USB\\_CDC device is automatically recognized by Windows 10 as a virtual COM port, and a serial port terminal application such as [CoolTerm](https://freeware.the-meiers.org/) can be used to communicate with it.\n\nmacOS and Linux provide built-in drivers for USB CDC ACM devices too.\nOn macOS, the virtual COM gets a name like `/dev/cu.usbmodem14601`, whereas, on Linux, it gets a name like `/dev/ttyACM0`. Linux requires that the user account belongs to the dialout group to grant permissions for virtual COM access.\n\nThe USB\\_CDC idea was born from the awesome [Luke Valenty's TinyFPGA](https://github.com/tinyfpga/TinyFPGA-BX) board. TinyFPGA uses a [\"bit-banged\" USB port](https://github.com/tinyfpga/TinyFPGA-Bootloader) implemented in the FPGA fabric for communication with the host PC.\nDavid Williams, with his [TinyFPGA-BX USB serial module](https://github.com/davidthings/tinyfpga_bx_usbserial), changed Luke's code to allow USB communication for FPGA designs.\nDavid's code uses the same clock for both USB internal stuff and data interface with FPGA application designs.\nInstead, USB\\_CDC aims to use a different asynchronous clock to allow a lower clock frequency for FPGA application designs.\n\nFurthermore, USB\\_CDC was designed from scratch. This allowed to:\n\n* keep FPGA resource utilization at the minimum and without the use of EBR memories.\n* manage properly both IN and OUT data flows with USB ACK/NAK handshake without data loss.\n\n## Applications\n* USB communication interface for microcontrollers and soft cores. USB\\_CDC takes little gate resources and no memories, leaving them for the CPU. See `soc` example.\n* Bootloaders. See the `bootloader` example for completely replacing the original TinyFPGA bootloader with one fully compatible with the `tinyprog` programmer.\n* Etc, it is up to your imagination.\n\n## Block Diagram and Pinout\n\n![](readme_files/usb_cdc.png)\n\n### Clocks\n* `clk_i`: clock with a frequency of 12MHz*BIT\\_SAMPLES\n* `app_clk_i`: asynchronous clock used if parameter `USE_APP_CLK = 1`\n\n### Reset\n* `rstn_i`: asynchronous reset, active low\n\n### FIFO out (from the USB host)\n* `out_data_o`: data (1 byte if CHANNELS=1, n bytes if CHANNELS=n)\n* `out_valid_o`: valid control signal (1 bit if CHANNEL=1, n bits if CHANNELS=n)\n* `out_ready_i`: ready control signal (1 bit if CHANNEL=1, n bits if CHANNELS=n)\n\n### FIFO in (to the USB host)\n* `in_data_i`: data (1 byte if CHANNELS=1, n bytes if CHANNELS=n)\n* `in_valid_i`: valid control signal (1 bit if CHANNEL=1, n bits if CHANNELS=n)\n* `in_ready_o`: ready control signal (1 bit if CHANNEL=1, n bits if CHANNELS=n)\n\n### USB I/O buffers\n* `dp_rx_i`: D+ input bit stream\n* `dn_rx_i`: D- input bit stream\n* `dp_tx_o`: D+ output bit stream\n* `dn_tx_o`: D- output bit stream\n* `tx_en_o`: D+/D- output enable\n* `dp_up_o`: 1.5k\u0026Omega; D+ pullup enable\n\n### USB device status\n* `frame_o`: last received USB frame number\n* `configured_o`: 1 if USB device is in configured state, 0 otherwise\n\n## FIFO interface\nUSB\\_CDC provides a FIFO interface to transfer data to/from FPGA application. Both `in_*` and `out_*` channels use the same transmission protocol.\n\n![](readme_files/fifo_timings.png)\n\nData is consumed on rising `app_clk` when both `valid` and `ready` signals are high (red up arrows on the picture). Tsetup and Thold depend on FPGA/ASIC technology.\n\nThe `valid` signal is high only when new data is available. After data is consumed and there is no new data available, the `valid` signal is asserted low.\n\n![](readme_files/fifo_protocol.png)\n\n\n## Verilog Configuration Parameters\nUSB\\_CDC has few Verilog parameters that allow customizing some module features.\n\n### VENDORID and PRODUCTID\nVENDORID and PRODUCTID define USB vendor ID (VID) and product ID (PID).  \nFor TinyFPGA: VID=0x1D50 and PID=0x6130.  \nFor Fomu: VID=0x1209 and PID=0x5BF0.  \nBy default, they are not defined (VENDORID=0x0000 and PRODUCTID=0x0000).\n\n### IN\\_BULK\\_MAXPACKETSIZE and OUT\\_BULK\\_MAXPACKETSIZE\nIN\\_BULK\\_MAXPACKETSIZE and OUT\\_BULK\\_MAXPACKETSIZE define maximum bulk data payload sizes for IN and OUT bulk transactions. The allowable full-speed values are only 8, 16, 32, and 64 bytes. The default value for both is 8.\n\n### CHANNELS\nCHANNELS defines how many CDC channels to implement. It is possible to implement from a minimum of 1 (default) to a maximum of 7 channels.\n\n### BIT\\_SAMPLES\nBIT\\_SAMPLES defines the number of samples taken on USB dp/dn lines for each bit. Full Speed USB has a bit rate of 12MHz, so the `clk` clock has to be BIT\\_SAMPLES times faster. For example, the default value of 4 needs a `clk` frequency of 48MHz (see the picture below). BIT\\_SAMPLES has to be \u0026ge; 4.\n\n![](readme_files/bit_samples.png)\n\n### USE\\_APP\\_CLK and APP\\_CLK\\_FREQ\n\nUSE\\_APP\\_CLK parameter configures if the FPGA application uses the same USB_CDC internal stuff clock (USE\\_APP\\_CLK = 0) or a different asynchronous one (USE\\_APP\\_CLK = 1). If  USE\\_APP\\_CLK = 0 then `app_clk` input is not used and can be connected to a constant value such as `1'b0`.\n\nWhen USE\\_APP\\_CLK = 1, APP\\_CLK\\_FREQ parameter defines the `app_clk` frequency in MHz.\n\n\nTo improve data throughput for lower `app_clk` frequencies, APP\\_CLK\\_FREQ parameter selects one of two different approaches to synchronize data that cross the two clock domains:\n\n* APP\\_CLK\\_FREQ \u0026le; 12. FPGA application can exchange data at every 1 or 2 `app_clk` cycles.\n\n* APP\\_CLK\\_FREQ \u003e 12. FPGA application can exchange data at an average of 2\\*2.5 `app_clk` cycles + 2\\*2.5 `clk` cycles.\n\n\nOverall, the USB Full-speed protocol caps data throughput to 1.5MB/s.\nSo, with freq(`clk`) \u0026ge; 48MHz, data throughput is 1.5MB/s if freq(`app_clk`) \u003e 1.5MHz, otherwise it is freq(`app_clk`) bytes.\n\n\n## Examples\nA few examples with complete implementation on both Fomu and TinyFPGA-BX are present in the `examples` directory. In addition, simulation testbenches are provided for each one.\n\n## Logic Resource Utilization\n\nThe USB\\_CDC code alone (with IN/OUT data in simple loopback configuration and all verilog parameters to default) shows the following logic resource utilization from iCEcube2:\n\n```\nLogic Resource Utilization:\n---------------------------\n    Total Logic Cells: 1158/7680\n        Combinational Logic Cells: 734      out of   7680      9.55729%\n        Sequential Logic Cells:    424      out of   7680      5.52083%\n        Logic Tiles:               212      out of   960       22.0833%\n    Registers: \n        Logic Registers:           424      out of   7680      5.52083%\n        IO Registers:              0        out of   1280      0\n    Block RAMs:                    0        out of   32        0%\n    Warm Boots:                    0        out of   1         0%\n    Pins:\n        Input Pins:                1        out of   63        1.5873%\n        Output Pins:               2        out of   63        3.1746%\n        InOut Pins:                2        out of   63        3.1746%\n    Global Buffers:                4        out of   8         50%\n    PLLs:                          1        out of   1         100%\n```\n\nThe clock timing summary is:\n\n```\n                   1::Clock Frequency Summary\n =====================================================================\nNumber of clocks: 1\nClock: clk_usb           | Frequency: 76.60 MHz  | Target: 48.01 MHz  |\n```\n\n## Directory Structure\n\n```\n.\n├── README.md                            --\u003e This file\n├── usb_cdc                              --\u003e USB_CDC verilog files\n│   ├── bulk_endp.v\n│   ├── ctrl_endp.v\n│   ├── in_fifo.v\n│   ├── out_fifo.v\n│   ├── phy_rx.v\n│   ├── phy_tx.v\n│   ├── sie.v\n│   └── usb_cdc.v\n└── examples                             --\u003e Example designs\n    ├── Fomu\n    │   :\n    │\n    └── TinyFPGA-BX\n        ├── hdl\n        │   ├── demo\n        │   │   ├── demo_fpga.vhd        --\u003e Top level (VHDL)\n        │   │   ├── demo.v               --\u003e Top level (verilog)\n        │   │   :\n        │   │\n        │   └── loopback\n        │       ├── loopback.v           --\u003e Top level (verilog)\n        │       :\n        │\n        ├── iCEcube2                     --\u003e iCEcube2 projects\n        │   ├── demo\n        │   │   ├── usb_cdc_sbt.project  --\u003e iCEcube2 project file\n        │   │   :\n        │   │\n        │   └── loopback\n        │       ├── usb_cdc_sbt.project  --\u003e iCEcube2 project file\n        │       :\n        │\n        ├── OSS_CAD_Suite                --\u003e OSS CAD Suite projects\n        │   ├── Makefile\n        │   ├── input\n        │   │   ├── demo\n        │   │   │   :\n        │   │   └── loopback\n        │   │       :\n        │   │\n        │   └── output\n        │       :\n        │\n        └── python                       --\u003e test files\n            └── demo\n                ├── run.py\n                :\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fulixxe%2Fusb_cdc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fulixxe%2Fusb_cdc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fulixxe%2Fusb_cdc/lists"}