C++ and VHDL Organization |
The basic digital control block (BDC) can be included in any FPGA image and provides a register interface via the SPI link between the BBB and the Fboard. The control block is based on previous efforts and looks a lot like the Prj 141 digital interface. The difference is that I wanted to simplify the programming model and allow each access to specify the register rather than needing a register access to control a selector for the next access to get to the target register. A basic block diagram is below.
VHDL ControlBlock Implementing Basic Digital Control Interface |
Each control block contains a set of 8 bit read/write registers, some 16 bit counters, and two GPIO units. Registers/counters can be added with each bit or set of bits interfacing with other application specific VHDL logic. Each GPIO unit has three registers (one for input, output, and direction of pins). The GPIO units connect directly with each of the 10 pin ports on the Fboard. Each of these registers has its data and read/write valid signals muxed based on a register id from a finite state machine.
This state machine conducts the read/write of a register based on an SPI command. The finite state machine has a register fifo with a 16 bit SPI slave. The state machine to process SPI commands operates at 96MHz (8x the XO on the F board using a DCM) and takes multiple clocks to read or write a register.
The SPI interface timing is specified to support a 20MHz SPI clock (for FPGA timing and layout only, the BBB even with the PRU will not exceed 16MHz with 9MHz being more realistic). The software is designed to clock 16 bits into the SPI register at the same time 16 bits are clocked out. The format of a SPI word is below.
-- Bit position
-- 1111 1100 0000 0000
-- 5432 1098 7654 3210
-- RWNN NNNN VVVV VVVV
-- Where:
-- R = 1 => read
-- W = 1 => write
-- N = register selector
-- V = 8 bit write value
The upper two bits select whether a read or write is conducted. In both cases the next 6 bits identify the register to be operated on. In the case of writes, the following 8 bits of value are written to the specified register. In the case of a read, these 8 bits are ignored, and the specified register is read (16bits) and saved in an internal register. On the next SPI access, while the new commands bits are being shifted in these 16 bits are being shifted out.
This might seem a bit counter intuitive, however, it keeps the finite state machine simple and extensible, focuses on single operation writes (8 bits of which is sufficient for my purposes) and allows streaming 16 bit reads with little overhead (e.g. for ADCs). It also allows 2^6 = 64 registers to be defined. The first 15 registers are dedicated to common operations like: a) FPGA image and version identification, b) Debug counters, c) LED control/signaling, and d) the two GPIO ports. The second set of 15 registers is dedicated to the application specific basics (for example the DDS frequency value). A 16 bit read fifo is used as the last register available.
Related:
This state machine conducts the read/write of a register based on an SPI command. The finite state machine has a register fifo with a 16 bit SPI slave. The state machine to process SPI commands operates at 96MHz (8x the XO on the F board using a DCM) and takes multiple clocks to read or write a register.
The SPI interface timing is specified to support a 20MHz SPI clock (for FPGA timing and layout only, the BBB even with the PRU will not exceed 16MHz with 9MHz being more realistic). The software is designed to clock 16 bits into the SPI register at the same time 16 bits are clocked out. The format of a SPI word is below.
-- Bit position
-- 1111 1100 0000 0000
-- 5432 1098 7654 3210
-- RWNN NNNN VVVV VVVV
-- Where:
-- R = 1 => read
-- W = 1 => write
-- N = register selector
-- V = 8 bit write value
The upper two bits select whether a read or write is conducted. In both cases the next 6 bits identify the register to be operated on. In the case of writes, the following 8 bits of value are written to the specified register. In the case of a read, these 8 bits are ignored, and the specified register is read (16bits) and saved in an internal register. On the next SPI access, while the new commands bits are being shifted in these 16 bits are being shifted out.
This might seem a bit counter intuitive, however, it keeps the finite state machine simple and extensible, focuses on single operation writes (8 bits of which is sufficient for my purposes) and allows streaming 16 bit reads with little overhead (e.g. for ADCs). It also allows 2^6 = 64 registers to be defined. The first 15 registers are dedicated to common operations like: a) FPGA image and version identification, b) Debug counters, c) LED control/signaling, and d) the two GPIO ports. The second set of 15 registers is dedicated to the application specific basics (for example the DDS frequency value). A 16 bit read fifo is used as the last register available.
Related:
Prj 145 - Beagle Bone Black Simple LX9 FPGA board (Part 1)
Prj 145 - BBB LX9 FPGA Board Design (Part 2)
Prj 145 - BBB LX9 FPGA Board Construction (Part 3)
Prj 145 - BBB LX9 JTAG Boundary Scan Utilities (Part 4)
Prj 145 - BBB LX9 C++ and VHDL (Part5)
Prj 145 - BBB LX9 FPGA Board Design (Part 2)
Prj 145 - BBB LX9 FPGA Board Construction (Part 3)
Prj 145 - BBB LX9 JTAG Boundary Scan Utilities (Part 4)
Prj 145 - BBB LX9 C++ and VHDL (Part5)
wow, nice design
ReplyDelete