# cdbus_ip **Repository Path**: enjoyNow/cdbus_ip ## Basic Information - **Project Name**: cdbus_ip - **Description**: CDBUS Protocol and the IP Core for FPGA users - **Primary Language**: Verilog - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-05-30 - **Last Updated**: 2024-12-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [//]: # (IP Core for CDBUS Protocol) CDBUS IP Core ======================================= (This is an 8-bit version, please switch to the corresponding branch for the 32-bit version.) 1. [CDBUS Protocol](#cdbus-protocol) 2. [Block Diagram](#block-diagram) 3. [Registers](#registers) 4. [Interface](#interface) 5. [Examples](#examples) 6. [Simulation](#simulation) 7. [Ready To Use Devices](#ready-to-use-devices) 8. [License](#license) ## CDBUS Protocol CDBUS is a protocol for Asynchronous Serial Communication, it has a 3-byte header: `[src_addr, dst_addr, data_len]`, then user data, and finally 2 bytes of CRC. It's suitable for one-to-one communication, e.g. UART or RS232. In this case, the address for each side are usually carefully selected and fixed, e.g: `[0x55, 0xaa, data_len, ...]`, and the backward is: `[0xaa, 0x55, data_len, ...]`. The CDBUS protocol is more valuable for bus communication, e.g. RS485 or Single Line UART. In this case: ### Arbitration Mode (CDBUS-A) * It introduces an arbitration mechanism that automatically avoids conflicts like the CAN bus. * Support dual baud rate, provide high speed communication, maximum rate ≥ 10 Mbps. * Supports unicast, multicast and broadcast. * Max payload data size is 253 byte (you can increase it to 255 byte, but not recommended). * Hardware packing, unpacking, verification and filtering, save your time and CPU usage. * Backward compatible with traditional RS485 hardware (still retains arbitration function). The protocol example timing, include only one byte user data: (How long to enter idle and how long to allow sending can be set.) ![protocol](docs/img/protocol.svg) Tips: - When high-priority node send unimportant data, the transmission wait time (TX_PERMIT_LEN) can be dynamically increased. Arbitration example: arbitration ### Break Sync Mode (CDBUS-BS) In CDBUS-A mode, if the low-speed part takes a lot of time, it will be a communication efficiency bottleneck. In this case, single-rate peer-to-peer bus communication can be implemented by CDBUS-BS mode: - Configure different TX_PERMIT_LEN parameters for each node, and the difference should be sufficient to avoid conflicts. - If any node has pending tx frame before TX-permit point, then start sent at the TX-permit point. - Or wait for the idle time to exceed the MAX_IDLE_LEN, then send a break character to bring the bus out of idle mode. arbitration The CDBUS-BS mode is suitable for high-speed applications with few nodes and is also suitable for software implementation. ## Block Diagram block_diagram #### Operation operation ## Registers | Register Name | Addr | Access | Default | Description | Remarks | |-------------------|---------|--------|-----------------|-------------------------------|------------------------------------------------------| | VERSION | 0x00 | RD | 0x0a | Hardware version | | | SETTING | 0x02 | RD/WR | 0x10 | Configs | | | IDLE_WAIT_LEN | 0x04 | RD/WR | 0x0a | How long to enter idle | Bit 7~0 | | TX_PERMIT_LEN_L | 0x05 | RD/WR | 0x14 | How long to allow sending | Bit 7~0 | | TX_PERMIT_LEN_H | 0x06 | RD/WR | 0x00 | | Bit 9~8 | | MAX_IDLE_LEN_L | 0x07 | RD/WR | 0xc8 | Max idle for BS mode | Bit 7~0 | | MAX_IDLE_LEN_H | 0x08 | RD/WR | 0x00 | | Bit 9~8 | | TX_PRE_LEN | 0x09 | RD/WR | 0x01 | Active TX_EN before TX | Bit 1~0, not used in arbitration mode | | FILTER | 0x0b | RD/WR | 0xff | Set to local address | | | DIV_LS_L | 0x0c | RD/WR | 0x5a | Low-speed rate setting | Bit 7~0 | | DIV_LS_H | 0x0d | RD/WR | 0x01 | | Bit 15~8 | | DIV_HS_L | 0x0e | RD/WR | 0x5a | High-speed rate setting | If not use dual rate, set the same value as DIV_LS | | DIV_HS_H | 0x0f | RD/WR | 0x01 | | | | INT_FLAG | 0x10 | RD | n/a | Status | | | INT_MASK | 0x11 | RD/WR | 0x00 | Interrupt mask | | | RX | 0x14 | RD | n/a | Read RX page | | | TX | 0x15 | WR | n/a | Write TX page | | | RX_CTRL | 0x16 | WR | n/a | RX control | | | TX_CTRL | 0x17 | WR | n/a | TX control | | | RX_ADDR | 0x18 | RD/WR | 0x00 | RX page read pointer | Rarely used | | RX_PAGE_FLAG | 0x19 | RD | n/a | RX page flag | For debugging | | FILTER1 | 0x1a | RD/WR | 0xff | Multicast filter1 | | | FILTER2 | 0x1b | RD/WR | 0xff | Multicast filter2 | | **SETTING:** | FIELD | DESCRIPTION | |-------- |---------------------------------------------------| | [0] | Enable push-pull output for tx and tx_en pin | | [1] | Invert tx output | | [2] | CRC maintained by user | | [3] | Save broken frame | | [4] | Enable arbitration | | [5] | Break Sync mode | | [6] | Full duplex mode | | [4] | [5] | [6] | DESCRIPTION | |-----|-----|-----|---------------------------------| | 1 | 0 | 0 | CDBUS-A mode (default) | | 0 | 1 | 0 | CDBUS-BS mode | | 0 | 0 | 1 | Full-duplex mode | | 0 | 0 | 0 | Traditional half-duplex mode | **FILTERS:** Match from top to bottom: | SRC_ADDR | DST_ADDR | FILTER | FILTERn | Receive or drop | Remarks | |---------- |----------|--------------|------------------|-----------------|------------------| | not care | not care | 255 | not care | Receive | Promiscuous mode | | = FILTER | not care | != 255 | not care | Drop | Avoid loopback | | != FILTER | 255 | not care | not care | Receive | Broadcast | | != FILTER | != 255 | not care | any = DST_ADDR | Receive | Multicast | | != FILTER | != 255 | = DST_ADDR | not care | Receive | Unicast | | not care | != 255 | != DST_ADDR | all != DST_ADDR | Drop | | It is recommended to reserve the address from `0xe0` to `0xfe` as the multicast address. The default value 0xff of FILTERn means not enabled. **DIV_xx_x:** Baud rate divider value: DIV_xx[15:0] = sys_freq ÷ baud_rate − 1 **INT_FLAG:** | FIELD | DESCRIPTION | |-------- |----------------------------------------------| | [0] | 1: Bus in IDLE mode | | [1] | 1: RX page ready for read | | [2] | 1: Receive break character | | [3] | 1: RX lost: no empty page for RX | | [4] | 1: RX error: frame broken | | [5] | 1: TX page released by hardware | | [6] | 1: TX collision detected | | [7] | 1: TX error: tx is 0, but rx is 1 | **INT_MASK:** Output of irq = ((INT_FLAG & INT_MASK) != 0). **RX_CTRL:** | FIELD | DESCRIPTION | |-------- |-----------------------------| | [0] | Reset RX page read pointer | | [1] | Switch RX page | | [2] | Clear RX lost flag | | [3] | Clear RX error flag | | [4] | Reset RX block | | [5] | Clear RX break flag | **TX_CTRL:** | FIELD | DESCRIPTION | |-------- |-------------------------------------------------------------| | [0] | Reset TX page write pointer | | [1] | Switch TX page | | [2] | Clear TX collision flag | | [3] | Clear TX error flag | | [4] | Abort TX | | [5] | Send break character (for full-duplex and traditional mode) | **RX_PAGE_FLAG:** Value zero indicate the frame in current RX page is correct; Non-zero indicate the pointer of last received byte of the disturbed frame, include CRC. ## Interface ```verilog parameter DIV_LS = 346, // default: 115200 bps for 40MHz clk parameter DIV_HS = 346 input clk, // core clock input reset_n, // asynch active low reset input chip_select, // reduce ram_rx power consumption output irq, // interrupt output // avalon-mm slave interface, read and write without latency // support burst read and write (normally for REG_TX and REG_RX) input [4:0] csr_address, input csr_read, output [7:0] csr_readdata, input csr_write, input [7:0] csr_writedata, // connect to external PHY chip, e.g. MAX3485 input rx, output tx, output tx_en ``` ## Examples ```python # Configuration write(REG_SETTING, [0x11]) # Enable push-pull output # TX write(REG_TX, [0x0c, 0x0d, 0x01, 0xcd]) # Write frame without CRC while (read(REG_INT_FLAG) & 0x20) == 0: # Make sure we can successfully switch to the next page pass write(REG_TX_CTRL, [0x03]) # Trigger send by switching TX page # RX while (read(REG_INT_FLAG) & 0x02) == 0: # Wait for RX page ready pass header = read(REG_TX, len=3) data = read(REG_TX, len=header[2]) write(REG_RX_CTRL, [0x03]) # Finish read by switching RX page ``` ## Simulation Install `iverilog` (>= v10) and `cocotb`, goto `tests/` folder, then type the command: ```sh $ COCOTB=/path/to/cocotb make ``` Then you can checkout the waveform `cdbus.vcd` by GTKWave. ## Ready To Use Devices The CDCTL controller family uses the CDBUS IP Core, which provide SPI, I2C and PCIe peripheral interfaces. E.g. The tiny CDCTL-Bx module support SPI and I2C interfaces: cdctl_bx For more information, visit: http://dukelec.com ## License ``` This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Notice: The scope granted to MPL excludes the ASIC industry. The CDBUS protocol is royalty-free for everyone except chip manufacturers. Copyright (c) 2017 DUKELEC, All rights reserved. ```